Combine both VMOVDRR(VMOVRRD) and VMOVRRD(VMOVDRR), instead of just doing one
[oota-llvm.git] / lib / Target / ARM / AsmPrinter / ARMInstPrinter.cpp
1 //===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This class prints an ARM MCInst to a .s file.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "asm-printer"
15 #include "ARMBaseInfo.h"
16 #include "ARMInstPrinter.h"
17 #include "ARMAddressingModes.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/Support/raw_ostream.h"
23 using namespace llvm;
24
25 // Include the auto-generated portion of the assembly writer.
26 #define MachineInstr MCInst
27 #define ARMAsmPrinter ARMInstPrinter  // FIXME: REMOVE.
28 #include "ARMGenAsmWriter.inc"
29 #undef MachineInstr
30 #undef ARMAsmPrinter
31
32 static unsigned getDPRSuperRegForSPR(unsigned Reg) {
33   switch (Reg) {
34   default:
35     assert(0 && "Unexpected register enum");
36   case ARM::S0:  case ARM::S1:  return ARM::D0;
37   case ARM::S2:  case ARM::S3:  return ARM::D1;
38   case ARM::S4:  case ARM::S5:  return ARM::D2;
39   case ARM::S6:  case ARM::S7:  return ARM::D3;
40   case ARM::S8:  case ARM::S9:  return ARM::D4;
41   case ARM::S10: case ARM::S11: return ARM::D5;
42   case ARM::S12: case ARM::S13: return ARM::D6;
43   case ARM::S14: case ARM::S15: return ARM::D7;
44   case ARM::S16: case ARM::S17: return ARM::D8;
45   case ARM::S18: case ARM::S19: return ARM::D9;
46   case ARM::S20: case ARM::S21: return ARM::D10;
47   case ARM::S22: case ARM::S23: return ARM::D11;
48   case ARM::S24: case ARM::S25: return ARM::D12;
49   case ARM::S26: case ARM::S27: return ARM::D13;
50   case ARM::S28: case ARM::S29: return ARM::D14;
51   case ARM::S30: case ARM::S31: return ARM::D15;
52   }
53 }
54
55 void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
56   // Check for MOVs and print canonical forms, instead.
57   if (MI->getOpcode() == ARM::MOVs) {
58     // FIXME: Thumb variants?
59     const MCOperand &Dst = MI->getOperand(0);
60     const MCOperand &MO1 = MI->getOperand(1);
61     const MCOperand &MO2 = MI->getOperand(2);
62     const MCOperand &MO3 = MI->getOperand(3);
63
64     O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
65     printSBitModifierOperand(MI, 6, O);
66     printPredicateOperand(MI, 4, O);
67
68     O << '\t' << getRegisterName(Dst.getReg())
69       << ", " << getRegisterName(MO1.getReg());
70
71     if (ARM_AM::getSORegShOp(MO3.getImm()) == ARM_AM::rrx)
72       return;
73
74     O << ", ";
75
76     if (MO2.getReg()) {
77       O << getRegisterName(MO2.getReg());
78       assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
79     } else {
80       O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
81     }
82     return;
83   }
84
85   // A8.6.123 PUSH
86   if ((MI->getOpcode() == ARM::STM_UPD || MI->getOpcode() == ARM::t2STM_UPD) &&
87       MI->getOperand(0).getReg() == ARM::SP) {
88     const MCOperand &MO1 = MI->getOperand(2);
89     if (ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::db) {
90       O << '\t' << "push";
91       printPredicateOperand(MI, 3, O);
92       O << '\t';
93       printRegisterList(MI, 5, O);
94       return;
95     }
96   }
97
98   // A8.6.122 POP
99   if ((MI->getOpcode() == ARM::LDM_UPD || MI->getOpcode() == ARM::t2LDM_UPD) &&
100       MI->getOperand(0).getReg() == ARM::SP) {
101     const MCOperand &MO1 = MI->getOperand(2);
102     if (ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::ia) {
103       O << '\t' << "pop";
104       printPredicateOperand(MI, 3, O);
105       O << '\t';
106       printRegisterList(MI, 5, O);
107       return;
108     }
109   }
110
111   // A8.6.355 VPUSH
112   if ((MI->getOpcode() == ARM::VSTMS_UPD || MI->getOpcode() ==ARM::VSTMD_UPD) &&
113       MI->getOperand(0).getReg() == ARM::SP) {
114     const MCOperand &MO1 = MI->getOperand(2);
115     if (ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::db) {
116       O << '\t' << "vpush";
117       printPredicateOperand(MI, 3, O);
118       O << '\t';
119       printRegisterList(MI, 5, O);
120       return;
121     }
122   }
123
124   // A8.6.354 VPOP
125   if ((MI->getOpcode() == ARM::VLDMS_UPD || MI->getOpcode() ==ARM::VLDMD_UPD) &&
126       MI->getOperand(0).getReg() == ARM::SP) {
127     const MCOperand &MO1 = MI->getOperand(2);
128     if (ARM_AM::getAM4SubMode(MO1.getImm()) == ARM_AM::ia) {
129       O << '\t' << "vpop";
130       printPredicateOperand(MI, 3, O);
131       O << '\t';
132       printRegisterList(MI, 5, O);
133       return;
134     }
135   }
136
137   printInstruction(MI, O);
138  }
139
140 void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
141                                   raw_ostream &O, const char *Modifier) {
142   const MCOperand &Op = MI->getOperand(OpNo);
143   if (Op.isReg()) {
144     unsigned Reg = Op.getReg();
145     if (Modifier && strcmp(Modifier, "lane") == 0) {
146       unsigned RegNum = getARMRegisterNumbering(Reg);
147       unsigned DReg = getDPRSuperRegForSPR(Reg);
148       O << getRegisterName(DReg) << '[' << (RegNum & 1) << ']';
149     } else {
150       O << getRegisterName(Reg);
151     }
152   } else if (Op.isImm()) {
153     assert((Modifier && !strcmp(Modifier, "call")) ||
154            ((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported"));
155     O << '#' << Op.getImm();
156   } else {
157     if (Modifier && Modifier[0] != 0 && strcmp(Modifier, "call") != 0)
158       llvm_unreachable("Unsupported modifier");
159     assert(Op.isExpr() && "unknown operand kind in printOperand");
160     O << *Op.getExpr();
161   }
162 }
163
164 static void printSOImm(raw_ostream &O, int64_t V, raw_ostream *CommentStream,
165                        const MCAsmInfo *MAI) {
166   // Break it up into two parts that make up a shifter immediate.
167   V = ARM_AM::getSOImmVal(V);
168   assert(V != -1 && "Not a valid so_imm value!");
169
170   unsigned Imm = ARM_AM::getSOImmValImm(V);
171   unsigned Rot = ARM_AM::getSOImmValRot(V);
172
173   // Print low-level immediate formation info, per
174   // A5.1.3: "Data-processing operands - Immediate".
175   if (Rot) {
176     O << "#" << Imm << ", " << Rot;
177     // Pretty printed version.
178     if (CommentStream)
179       *CommentStream << (int)ARM_AM::rotr32(Imm, Rot) << "\n";
180   } else {
181     O << "#" << Imm;
182   }
183 }
184
185
186 /// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
187 /// immediate in bits 0-7.
188 void ARMInstPrinter::printSOImmOperand(const MCInst *MI, unsigned OpNum,
189                                        raw_ostream &O) {
190   const MCOperand &MO = MI->getOperand(OpNum);
191   assert(MO.isImm() && "Not a valid so_imm value!");
192   printSOImm(O, MO.getImm(), CommentStream, &MAI);
193 }
194
195 /// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
196 /// followed by an 'orr' to materialize.
197 void ARMInstPrinter::printSOImm2PartOperand(const MCInst *MI, unsigned OpNum,
198                                             raw_ostream &O) {
199   // FIXME: REMOVE this method.
200   abort();
201 }
202
203 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
204 // "Addressing Mode 1 - Data-processing operands" forms.  This includes:
205 //    REG 0   0           - e.g. R5
206 //    REG REG 0,SH_OPC    - e.g. R5, ROR R3
207 //    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
208 void ARMInstPrinter::printSORegOperand(const MCInst *MI, unsigned OpNum,
209                                        raw_ostream &O) {
210   const MCOperand &MO1 = MI->getOperand(OpNum);
211   const MCOperand &MO2 = MI->getOperand(OpNum+1);
212   const MCOperand &MO3 = MI->getOperand(OpNum+2);
213
214   O << getRegisterName(MO1.getReg());
215
216   // Print the shift opc.
217   ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
218   O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
219   if (MO2.getReg()) {
220     O << ' ' << getRegisterName(MO2.getReg());
221     assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
222   } else if (ShOpc != ARM_AM::rrx) {
223     O << " #" << ARM_AM::getSORegOffset(MO3.getImm());
224   }
225 }
226
227
228 void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
229                                            raw_ostream &O) {
230   const MCOperand &MO1 = MI->getOperand(Op);
231   const MCOperand &MO2 = MI->getOperand(Op+1);
232   const MCOperand &MO3 = MI->getOperand(Op+2);
233
234   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
235     printOperand(MI, Op, O);
236     return;
237   }
238
239   O << "[" << getRegisterName(MO1.getReg());
240
241   if (!MO2.getReg()) {
242     if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
243       O << ", #"
244         << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
245         << ARM_AM::getAM2Offset(MO3.getImm());
246     O << "]";
247     return;
248   }
249
250   O << ", "
251     << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
252     << getRegisterName(MO2.getReg());
253
254   if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
255     O << ", "
256     << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
257     << " #" << ShImm;
258   O << "]";
259 }
260
261 void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
262                                                  unsigned OpNum,
263                                                  raw_ostream &O) {
264   const MCOperand &MO1 = MI->getOperand(OpNum);
265   const MCOperand &MO2 = MI->getOperand(OpNum+1);
266
267   if (!MO1.getReg()) {
268     unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
269     O << '#'
270       << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
271       << ImmOffs;
272     return;
273   }
274
275   O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
276     << getRegisterName(MO1.getReg());
277
278   if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
279     O << ", "
280     << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
281     << " #" << ShImm;
282 }
283
284 void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned OpNum,
285                                            raw_ostream &O) {
286   const MCOperand &MO1 = MI->getOperand(OpNum);
287   const MCOperand &MO2 = MI->getOperand(OpNum+1);
288   const MCOperand &MO3 = MI->getOperand(OpNum+2);
289
290   O << '[' << getRegisterName(MO1.getReg());
291
292   if (MO2.getReg()) {
293     O << ", " << (char)ARM_AM::getAM3Op(MO3.getImm())
294       << getRegisterName(MO2.getReg()) << ']';
295     return;
296   }
297
298   if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
299     O << ", #"
300       << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
301       << ImmOffs;
302   O << ']';
303 }
304
305 void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI,
306                                                  unsigned OpNum,
307                                                  raw_ostream &O) {
308   const MCOperand &MO1 = MI->getOperand(OpNum);
309   const MCOperand &MO2 = MI->getOperand(OpNum+1);
310
311   if (MO1.getReg()) {
312     O << (char)ARM_AM::getAM3Op(MO2.getImm())
313     << getRegisterName(MO1.getReg());
314     return;
315   }
316
317   unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
318   O << '#'
319     << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()))
320     << ImmOffs;
321 }
322
323
324 void ARMInstPrinter::printAddrMode4Operand(const MCInst *MI, unsigned OpNum,
325                                            raw_ostream &O,
326                                            const char *Modifier) {
327   const MCOperand &MO2 = MI->getOperand(OpNum+1);
328   ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
329   if (Modifier && strcmp(Modifier, "submode") == 0) {
330     O << ARM_AM::getAMSubModeStr(Mode);
331   } else if (Modifier && strcmp(Modifier, "wide") == 0) {
332     ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
333     if (Mode == ARM_AM::ia)
334       O << ".w";
335   } else {
336     printOperand(MI, OpNum, O);
337   }
338 }
339
340 void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
341                                            raw_ostream &O,
342                                            const char *Modifier) {
343   const MCOperand &MO1 = MI->getOperand(OpNum);
344   const MCOperand &MO2 = MI->getOperand(OpNum+1);
345
346   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
347     printOperand(MI, OpNum, O);
348     return;
349   }
350
351   O << "[" << getRegisterName(MO1.getReg());
352
353   if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
354     O << ", #"
355       << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
356       << ImmOffs*4;
357   }
358   O << "]";
359 }
360
361 void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum,
362                                            raw_ostream &O) {
363   const MCOperand &MO1 = MI->getOperand(OpNum);
364   const MCOperand &MO2 = MI->getOperand(OpNum+1);
365
366   O << "[" << getRegisterName(MO1.getReg());
367   if (MO2.getImm()) {
368     // FIXME: Both darwin as and GNU as violate ARM docs here.
369     O << ", :" << (MO2.getImm() << 3);
370   }
371   O << "]";
372 }
373
374 void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
375                                                  unsigned OpNum,
376                                                  raw_ostream &O) {
377   const MCOperand &MO = MI->getOperand(OpNum);
378   if (MO.getReg() == 0)
379     O << "!";
380   else
381     O << ", " << getRegisterName(MO.getReg());
382 }
383
384 void ARMInstPrinter::printAddrModePCOperand(const MCInst *MI, unsigned OpNum,
385                                             raw_ostream &O,
386                                             const char *Modifier) {
387   // All instructions using addrmodepc are pseudos and should have been
388   // handled explicitly in printInstructionThroughMCStreamer(). If one got
389   // here, it wasn't, so something's wrong.
390   llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
391 }
392
393 void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,
394                                                     unsigned OpNum,
395                                                     raw_ostream &O) {
396   const MCOperand &MO = MI->getOperand(OpNum);
397   uint32_t v = ~MO.getImm();
398   int32_t lsb = CountTrailingZeros_32(v);
399   int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
400   assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
401   O << '#' << lsb << ", #" << width;
402 }
403
404 void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
405                                      raw_ostream &O) {
406   unsigned val = MI->getOperand(OpNum).getImm();
407   O << ARM_MB::MemBOptToString(val);
408 }
409
410 void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
411                                           raw_ostream &O) {
412   unsigned ShiftOp = MI->getOperand(OpNum).getImm();
413   ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
414   switch (Opc) {
415   case ARM_AM::no_shift:
416     return;
417   case ARM_AM::lsl:
418     O << ", lsl #";
419     break;
420   case ARM_AM::asr:
421     O << ", asr #";
422     break;
423   default:
424     assert(0 && "unexpected shift opcode for shift immediate operand");
425   }
426   O << ARM_AM::getSORegOffset(ShiftOp);
427 }
428
429 void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
430                                        raw_ostream &O) {
431   O << "{";
432   for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
433     if (i != OpNum) O << ", ";
434     O << getRegisterName(MI->getOperand(i).getReg());
435   }
436   O << "}";
437 }
438
439 void ARMInstPrinter::printCPSOptionOperand(const MCInst *MI, unsigned OpNum,
440                                            raw_ostream &O) {
441   const MCOperand &Op = MI->getOperand(OpNum);
442   unsigned option = Op.getImm();
443   unsigned mode = option & 31;
444   bool changemode = option >> 5 & 1;
445   unsigned AIF = option >> 6 & 7;
446   unsigned imod = option >> 9 & 3;
447   if (imod == 2)
448     O << "ie";
449   else if (imod == 3)
450     O << "id";
451   O << '\t';
452   if (imod > 1) {
453     if (AIF & 4) O << 'a';
454     if (AIF & 2) O << 'i';
455     if (AIF & 1) O << 'f';
456     if (AIF > 0 && changemode) O << ", ";
457   }
458   if (changemode)
459     O << '#' << mode;
460 }
461
462 void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
463                                          raw_ostream &O) {
464   const MCOperand &Op = MI->getOperand(OpNum);
465   unsigned Mask = Op.getImm();
466   if (Mask) {
467     O << '_';
468     if (Mask & 8) O << 'f';
469     if (Mask & 4) O << 's';
470     if (Mask & 2) O << 'x';
471     if (Mask & 1) O << 'c';
472   }
473 }
474
475 void ARMInstPrinter::printNegZeroOperand(const MCInst *MI, unsigned OpNum,
476                                          raw_ostream &O) {
477   const MCOperand &Op = MI->getOperand(OpNum);
478   O << '#';
479   if (Op.getImm() < 0)
480     O << '-' << (-Op.getImm() - 1);
481   else
482     O << Op.getImm();
483 }
484
485 void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
486                                            raw_ostream &O) {
487   ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
488   if (CC != ARMCC::AL)
489     O << ARMCondCodeToString(CC);
490 }
491
492 void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI,
493                                                     unsigned OpNum,
494                                                     raw_ostream &O) {
495   ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
496   O << ARMCondCodeToString(CC);
497 }
498
499 void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum,
500                                               raw_ostream &O) {
501   if (MI->getOperand(OpNum).getReg()) {
502     assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
503            "Expect ARM CPSR register!");
504     O << 's';
505   }
506 }
507
508
509
510 void ARMInstPrinter::printCPInstOperand(const MCInst *MI, unsigned OpNum,
511                                         raw_ostream &O,
512                                         const char *Modifier) {
513   // FIXME: remove this.
514   abort();
515 }
516
517 void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum,
518                                           raw_ostream &O) {
519   O << MI->getOperand(OpNum).getImm();
520 }
521
522
523 void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
524                                   raw_ostream &O) {
525   llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
526 }
527
528 void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
529                                             raw_ostream &O) {
530   O << "#" <<  MI->getOperand(OpNum).getImm() * 4;
531 }
532
533 void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum,
534                                       raw_ostream &O) {
535   // (3 - the number of trailing zeros) is the number of then / else.
536   unsigned Mask = MI->getOperand(OpNum).getImm();
537   unsigned CondBit0 = Mask >> 4 & 1;
538   unsigned NumTZ = CountTrailingZeros_32(Mask);
539   assert(NumTZ <= 3 && "Invalid IT mask!");
540   for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
541     bool T = ((Mask >> Pos) & 1) == CondBit0;
542     if (T)
543       O << 't';
544     else
545       O << 'e';
546   }
547 }
548
549 void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op,
550                                                  raw_ostream &O) {
551   const MCOperand &MO1 = MI->getOperand(Op);
552   const MCOperand &MO2 = MI->getOperand(Op+1);
553   O << "[" << getRegisterName(MO1.getReg());
554   O << ", " << getRegisterName(MO2.getReg()) << "]";
555 }
556
557 void ARMInstPrinter::printThumbAddrModeRI5Operand(const MCInst *MI, unsigned Op,
558                                                   raw_ostream &O,
559                                                   unsigned Scale) {
560   const MCOperand &MO1 = MI->getOperand(Op);
561   const MCOperand &MO2 = MI->getOperand(Op+1);
562   const MCOperand &MO3 = MI->getOperand(Op+2);
563
564   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
565     printOperand(MI, Op, O);
566     return;
567   }
568
569   O << "[" << getRegisterName(MO1.getReg());
570   if (MO3.getReg())
571     O << ", " << getRegisterName(MO3.getReg());
572   else if (unsigned ImmOffs = MO2.getImm())
573     O << ", #" << ImmOffs * Scale;
574   O << "]";
575 }
576
577 void ARMInstPrinter::printThumbAddrModeS1Operand(const MCInst *MI, unsigned Op,
578                                                  raw_ostream &O) {
579   printThumbAddrModeRI5Operand(MI, Op, O, 1);
580 }
581
582 void ARMInstPrinter::printThumbAddrModeS2Operand(const MCInst *MI, unsigned Op,
583                                                  raw_ostream &O) {
584   printThumbAddrModeRI5Operand(MI, Op, O, 2);
585 }
586
587 void ARMInstPrinter::printThumbAddrModeS4Operand(const MCInst *MI, unsigned Op,
588                                                  raw_ostream &O) {
589   printThumbAddrModeRI5Operand(MI, Op, O, 4);
590 }
591
592 void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op,
593                                                  raw_ostream &O) {
594   const MCOperand &MO1 = MI->getOperand(Op);
595   const MCOperand &MO2 = MI->getOperand(Op+1);
596   O << "[" << getRegisterName(MO1.getReg());
597   if (unsigned ImmOffs = MO2.getImm())
598     O << ", #" << ImmOffs*4;
599   O << "]";
600 }
601
602 void ARMInstPrinter::printTBAddrMode(const MCInst *MI, unsigned OpNum,
603                                      raw_ostream &O) {
604   O << "[pc, " << getRegisterName(MI->getOperand(OpNum).getReg());
605   if (MI->getOpcode() == ARM::t2TBH)
606     O << ", lsl #1";
607   O << ']';
608 }
609
610 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
611 // register with shift forms.
612 // REG 0   0           - e.g. R5
613 // REG IMM, SH_OPC     - e.g. R5, LSL #3
614 void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
615                                       raw_ostream &O) {
616   const MCOperand &MO1 = MI->getOperand(OpNum);
617   const MCOperand &MO2 = MI->getOperand(OpNum+1);
618
619   unsigned Reg = MO1.getReg();
620   O << getRegisterName(Reg);
621
622   // Print the shift opc.
623   assert(MO2.isImm() && "Not a valid t2_so_reg value!");
624   ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm());
625   O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
626   if (ShOpc != ARM_AM::rrx)
627     O << " #" << ARM_AM::getSORegOffset(MO2.getImm());
628 }
629
630 void ARMInstPrinter::printT2AddrModeImm12Operand(const MCInst *MI,
631                                                  unsigned OpNum,
632                                                  raw_ostream &O) {
633   const MCOperand &MO1 = MI->getOperand(OpNum);
634   const MCOperand &MO2 = MI->getOperand(OpNum+1);
635
636   O << "[" << getRegisterName(MO1.getReg());
637
638   unsigned OffImm = MO2.getImm();
639   if (OffImm)  // Don't print +0.
640     O << ", #" << OffImm;
641   O << "]";
642 }
643
644 void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
645                                                 unsigned OpNum,
646                                                 raw_ostream &O) {
647   const MCOperand &MO1 = MI->getOperand(OpNum);
648   const MCOperand &MO2 = MI->getOperand(OpNum+1);
649
650   O << "[" << getRegisterName(MO1.getReg());
651
652   int32_t OffImm = (int32_t)MO2.getImm();
653   // Don't print +0.
654   if (OffImm < 0)
655     O << ", #-" << -OffImm;
656   else if (OffImm > 0)
657     O << ", #" << OffImm;
658   O << "]";
659 }
660
661 void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
662                                                   unsigned OpNum,
663                                                   raw_ostream &O) {
664   const MCOperand &MO1 = MI->getOperand(OpNum);
665   const MCOperand &MO2 = MI->getOperand(OpNum+1);
666
667   O << "[" << getRegisterName(MO1.getReg());
668
669   int32_t OffImm = (int32_t)MO2.getImm() / 4;
670   // Don't print +0.
671   if (OffImm < 0)
672     O << ", #-" << -OffImm * 4;
673   else if (OffImm > 0)
674     O << ", #" << OffImm * 4;
675   O << "]";
676 }
677
678 void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst *MI,
679                                                       unsigned OpNum,
680                                                       raw_ostream &O) {
681   const MCOperand &MO1 = MI->getOperand(OpNum);
682   int32_t OffImm = (int32_t)MO1.getImm();
683   // Don't print +0.
684   if (OffImm < 0)
685     O << "#-" << -OffImm;
686   else if (OffImm > 0)
687     O << "#" << OffImm;
688 }
689
690 void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI,
691                                                         unsigned OpNum,
692                                                         raw_ostream &O) {
693   const MCOperand &MO1 = MI->getOperand(OpNum);
694   int32_t OffImm = (int32_t)MO1.getImm() / 4;
695   // Don't print +0.
696   if (OffImm < 0)
697     O << "#-" << -OffImm * 4;
698   else if (OffImm > 0)
699     O << "#" << OffImm * 4;
700 }
701
702 void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
703                                                  unsigned OpNum,
704                                                  raw_ostream &O) {
705   const MCOperand &MO1 = MI->getOperand(OpNum);
706   const MCOperand &MO2 = MI->getOperand(OpNum+1);
707   const MCOperand &MO3 = MI->getOperand(OpNum+2);
708
709   O << "[" << getRegisterName(MO1.getReg());
710
711   assert(MO2.getReg() && "Invalid so_reg load / store address!");
712   O << ", " << getRegisterName(MO2.getReg());
713
714   unsigned ShAmt = MO3.getImm();
715   if (ShAmt) {
716     assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
717     O << ", lsl #" << ShAmt;
718   }
719   O << "]";
720 }
721
722 void ARMInstPrinter::printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum,
723                                            raw_ostream &O) {
724   O << '#' << (float)MI->getOperand(OpNum).getFPImm();
725 }
726
727 void ARMInstPrinter::printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum,
728                                            raw_ostream &O) {
729   O << '#' << MI->getOperand(OpNum).getFPImm();
730 }
731
732 void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,
733                                             raw_ostream &O) {
734   unsigned EncodedImm = MI->getOperand(OpNum).getImm();
735   unsigned EltBits;
736   uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
737   O << "#0x" << utohexstr(Val);
738 }
739
740 void ARMInstPrinter::PrintSpecial(const MCInst *MI, raw_ostream &O,
741                                   const char *Kind) {
742   if (strcmp(Kind, "comment") == 0)
743     O << "@";
744   else
745     abort();
746 }