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