ARM PKH shift ammount operand printing tweaks.
[oota-llvm.git] / lib / Target / ARM / InstPrinter / 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 #define GET_INSTRUCTION_NAME
26 #include "ARMGenAsmWriter.inc"
27
28 StringRef ARMInstPrinter::getOpcodeName(unsigned Opcode) const {
29   return getInstructionName(Opcode);
30 }
31
32 void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
33   OS << getRegisterName(RegNo);
34 }
35
36 void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
37   unsigned Opcode = MI->getOpcode();
38
39   // Check for MOVs and print canonical forms, instead.
40   if (Opcode == ARM::MOVs) {
41     // FIXME: Thumb variants?
42     const MCOperand &Dst = MI->getOperand(0);
43     const MCOperand &MO1 = MI->getOperand(1);
44     const MCOperand &MO2 = MI->getOperand(2);
45     const MCOperand &MO3 = MI->getOperand(3);
46
47     O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
48     printSBitModifierOperand(MI, 6, O);
49     printPredicateOperand(MI, 4, O);
50
51     O << '\t' << getRegisterName(Dst.getReg())
52       << ", " << getRegisterName(MO1.getReg());
53
54     if (ARM_AM::getSORegShOp(MO3.getImm()) == ARM_AM::rrx)
55       return;
56
57     O << ", ";
58
59     if (MO2.getReg()) {
60       O << getRegisterName(MO2.getReg());
61       assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
62     } else {
63       O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
64     }
65     return;
66   }
67
68   // A8.6.123 PUSH
69   if ((Opcode == ARM::STMDB_UPD || Opcode == ARM::t2STMDB_UPD) &&
70       MI->getOperand(0).getReg() == ARM::SP) {
71     O << '\t' << "push";
72     printPredicateOperand(MI, 2, O);
73     if (Opcode == ARM::t2STMDB_UPD)
74       O << ".w";
75     O << '\t';
76     printRegisterList(MI, 4, O);
77     return;
78   }
79
80   // A8.6.122 POP
81   if ((Opcode == ARM::LDMIA_UPD || Opcode == ARM::t2LDMIA_UPD) &&
82       MI->getOperand(0).getReg() == ARM::SP) {
83     O << '\t' << "pop";
84     printPredicateOperand(MI, 2, O);
85     if (Opcode == ARM::t2LDMIA_UPD)
86       O << ".w";
87     O << '\t';
88     printRegisterList(MI, 4, O);
89     return;
90   }
91
92   // A8.6.355 VPUSH
93   if ((Opcode == ARM::VSTMSDB_UPD || Opcode == ARM::VSTMDDB_UPD) &&
94       MI->getOperand(0).getReg() == ARM::SP) {
95     O << '\t' << "vpush";
96     printPredicateOperand(MI, 2, O);
97     O << '\t';
98     printRegisterList(MI, 4, O);
99     return;
100   }
101
102   // A8.6.354 VPOP
103   if ((Opcode == ARM::VLDMSIA_UPD || Opcode == ARM::VLDMDIA_UPD) &&
104       MI->getOperand(0).getReg() == ARM::SP) {
105     O << '\t' << "vpop";
106     printPredicateOperand(MI, 2, O);
107     O << '\t';
108     printRegisterList(MI, 4, O);
109     return;
110   }
111
112   if (Opcode == ARM::tLDMIA || Opcode == ARM::tSTMIA) {
113     bool Writeback = true;
114     unsigned BaseReg = MI->getOperand(0).getReg();
115     for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
116       if (MI->getOperand(i).getReg() == BaseReg)
117         Writeback = false;
118     }
119
120     if (Opcode == ARM::tLDMIA)
121       O << "\tldmia";
122     else if (Opcode == ARM::tSTMIA)
123       O << "\tstmia";
124     else
125       llvm_unreachable("Unknown opcode!");
126
127     printPredicateOperand(MI, 1, O);
128     O << '\t' << getRegisterName(BaseReg);
129     if (Writeback) O << "!";
130     O << ", ";
131     printRegisterList(MI, 3, O);
132     return;
133   }
134
135   printInstruction(MI, O);
136 }
137
138 void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
139                                   raw_ostream &O) {
140   const MCOperand &Op = MI->getOperand(OpNo);
141   if (Op.isReg()) {
142     unsigned Reg = Op.getReg();
143     O << getRegisterName(Reg);
144   } else if (Op.isImm()) {
145     O << '#' << Op.getImm();
146   } else {
147     assert(Op.isExpr() && "unknown operand kind in printOperand");
148     O << *Op.getExpr();
149   }
150 }
151
152 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
153 // "Addressing Mode 1 - Data-processing operands" forms.  This includes:
154 //    REG 0   0           - e.g. R5
155 //    REG REG 0,SH_OPC    - e.g. R5, ROR R3
156 //    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
157 void ARMInstPrinter::printSORegOperand(const MCInst *MI, unsigned OpNum,
158                                        raw_ostream &O) {
159   const MCOperand &MO1 = MI->getOperand(OpNum);
160   const MCOperand &MO2 = MI->getOperand(OpNum+1);
161   const MCOperand &MO3 = MI->getOperand(OpNum+2);
162
163   O << getRegisterName(MO1.getReg());
164
165   // Print the shift opc.
166   ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
167   O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
168   if (ShOpc == ARM_AM::rrx)
169     return;
170   if (MO2.getReg()) {
171     O << ' ' << getRegisterName(MO2.getReg());
172     assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
173   } else if (ShOpc != ARM_AM::rrx) {
174     O << " #" << ARM_AM::getSORegOffset(MO3.getImm());
175   }
176 }
177
178 //===--------------------------------------------------------------------===//
179 // Addressing Mode #2
180 //===--------------------------------------------------------------------===//
181
182 void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
183                                                 raw_ostream &O) {
184   const MCOperand &MO1 = MI->getOperand(Op);
185   const MCOperand &MO2 = MI->getOperand(Op+1);
186   const MCOperand &MO3 = MI->getOperand(Op+2);
187
188   O << "[" << getRegisterName(MO1.getReg());
189
190   if (!MO2.getReg()) {
191     if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
192       O << ", #"
193         << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
194         << ARM_AM::getAM2Offset(MO3.getImm());
195     O << "]";
196     return;
197   }
198
199   O << ", "
200     << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
201     << getRegisterName(MO2.getReg());
202
203   if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
204     O << ", "
205     << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
206     << " #" << ShImm;
207   O << "]";
208 }
209
210 void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op,
211                                          raw_ostream &O) {
212   const MCOperand &MO1 = MI->getOperand(Op);
213   const MCOperand &MO2 = MI->getOperand(Op+1);
214   const MCOperand &MO3 = MI->getOperand(Op+2);
215
216   O << "[" << getRegisterName(MO1.getReg()) << "], ";
217
218   if (!MO2.getReg()) {
219     unsigned ImmOffs = ARM_AM::getAM2Offset(MO3.getImm());
220     O << '#'
221       << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
222       << ImmOffs;
223     return;
224   }
225
226   O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
227     << getRegisterName(MO2.getReg());
228
229   if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
230     O << ", "
231     << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
232     << " #" << ShImm;
233 }
234
235 void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
236                                            raw_ostream &O) {
237   const MCOperand &MO1 = MI->getOperand(Op);
238
239   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
240     printOperand(MI, Op, O);
241     return;
242   }
243
244   const MCOperand &MO3 = MI->getOperand(Op+2);
245   unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
246
247   if (IdxMode == ARMII::IndexModePost) {
248     printAM2PostIndexOp(MI, Op, O);
249     return;
250   }
251   printAM2PreOrOffsetIndexOp(MI, Op, O);
252 }
253
254 void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
255                                                  unsigned OpNum,
256                                                  raw_ostream &O) {
257   const MCOperand &MO1 = MI->getOperand(OpNum);
258   const MCOperand &MO2 = MI->getOperand(OpNum+1);
259
260   if (!MO1.getReg()) {
261     unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
262     O << '#'
263       << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
264       << ImmOffs;
265     return;
266   }
267
268   O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
269     << getRegisterName(MO1.getReg());
270
271   if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
272     O << ", "
273     << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
274     << " #" << ShImm;
275 }
276
277 //===--------------------------------------------------------------------===//
278 // Addressing Mode #3
279 //===--------------------------------------------------------------------===//
280
281 void ARMInstPrinter::printAM3PostIndexOp(const MCInst *MI, unsigned Op,
282                                          raw_ostream &O) {
283   const MCOperand &MO1 = MI->getOperand(Op);
284   const MCOperand &MO2 = MI->getOperand(Op+1);
285   const MCOperand &MO3 = MI->getOperand(Op+2);
286
287   O << "[" << getRegisterName(MO1.getReg()) << "], ";
288
289   if (MO2.getReg()) {
290     O << (char)ARM_AM::getAM3Op(MO3.getImm())
291     << getRegisterName(MO2.getReg());
292     return;
293   }
294
295   unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
296   O << '#'
297     << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
298     << ImmOffs;
299 }
300
301 void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
302                                                 raw_ostream &O) {
303   const MCOperand &MO1 = MI->getOperand(Op);
304   const MCOperand &MO2 = MI->getOperand(Op+1);
305   const MCOperand &MO3 = MI->getOperand(Op+2);
306
307   O << '[' << getRegisterName(MO1.getReg());
308
309   if (MO2.getReg()) {
310     O << ", " << (char)ARM_AM::getAM3Op(MO3.getImm())
311       << getRegisterName(MO2.getReg()) << ']';
312     return;
313   }
314
315   if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
316     O << ", #"
317       << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
318       << ImmOffs;
319   O << ']';
320 }
321
322 void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op,
323                                            raw_ostream &O) {
324   const MCOperand &MO3 = MI->getOperand(Op+2);
325   unsigned IdxMode = ARM_AM::getAM3IdxMode(MO3.getImm());
326
327   if (IdxMode == ARMII::IndexModePost) {
328     printAM3PostIndexOp(MI, Op, O);
329     return;
330   }
331   printAM3PreOrOffsetIndexOp(MI, Op, O);
332 }
333
334 void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI,
335                                                  unsigned OpNum,
336                                                  raw_ostream &O) {
337   const MCOperand &MO1 = MI->getOperand(OpNum);
338   const MCOperand &MO2 = MI->getOperand(OpNum+1);
339
340   if (MO1.getReg()) {
341     O << (char)ARM_AM::getAM3Op(MO2.getImm())
342     << getRegisterName(MO1.getReg());
343     return;
344   }
345
346   unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
347   O << '#'
348     << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()))
349     << ImmOffs;
350 }
351
352 void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum,
353                                            raw_ostream &O) {
354   ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MI->getOperand(OpNum)
355                                                  .getImm());
356   O << ARM_AM::getAMSubModeStr(Mode);
357 }
358
359 void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
360                                            raw_ostream &O) {
361   const MCOperand &MO1 = MI->getOperand(OpNum);
362   const MCOperand &MO2 = MI->getOperand(OpNum+1);
363
364   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
365     printOperand(MI, OpNum, O);
366     return;
367   }
368
369   O << "[" << getRegisterName(MO1.getReg());
370
371   if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
372     O << ", #"
373       << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
374       << ImmOffs * 4;
375   }
376   O << "]";
377 }
378
379 void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum,
380                                            raw_ostream &O) {
381   const MCOperand &MO1 = MI->getOperand(OpNum);
382   const MCOperand &MO2 = MI->getOperand(OpNum+1);
383
384   O << "[" << getRegisterName(MO1.getReg());
385   if (MO2.getImm()) {
386     // FIXME: Both darwin as and GNU as violate ARM docs here.
387     O << ", :" << (MO2.getImm() << 3);
388   }
389   O << "]";
390 }
391
392 void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum,
393                                            raw_ostream &O) {
394   const MCOperand &MO1 = MI->getOperand(OpNum);
395   O << "[" << getRegisterName(MO1.getReg()) << "]";
396 }
397
398 void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
399                                                  unsigned OpNum,
400                                                  raw_ostream &O) {
401   const MCOperand &MO = MI->getOperand(OpNum);
402   if (MO.getReg() == 0)
403     O << "!";
404   else
405     O << ", " << getRegisterName(MO.getReg());
406 }
407
408 void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,
409                                                     unsigned OpNum,
410                                                     raw_ostream &O) {
411   const MCOperand &MO = MI->getOperand(OpNum);
412   uint32_t v = ~MO.getImm();
413   int32_t lsb = CountTrailingZeros_32(v);
414   int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
415   assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
416   O << '#' << lsb << ", #" << width;
417 }
418
419 void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
420                                      raw_ostream &O) {
421   unsigned val = MI->getOperand(OpNum).getImm();
422   O << ARM_MB::MemBOptToString(val);
423 }
424
425 void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
426                                           raw_ostream &O) {
427   unsigned ShiftOp = MI->getOperand(OpNum).getImm();
428   ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
429   switch (Opc) {
430   case ARM_AM::no_shift:
431     return;
432   case ARM_AM::lsl:
433     O << ", lsl #";
434     break;
435   case ARM_AM::asr:
436     O << ", asr #";
437     break;
438   default:
439     assert(0 && "unexpected shift opcode for shift immediate operand");
440   }
441   O << ARM_AM::getSORegOffset(ShiftOp);
442 }
443
444 void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum,
445                                          raw_ostream &O) {
446   unsigned Imm = MI->getOperand(OpNum).getImm();
447   if (Imm == 0)
448     return;
449   assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
450   O << ", lsl #" << Imm;
451 }
452
453 void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum,
454                                          raw_ostream &O) {
455   unsigned Imm = MI->getOperand(OpNum).getImm();
456   // A shift amount of 32 is encoded as 0.
457   if (Imm == 0)
458     Imm = 32;
459   assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
460   O << ", asr #" << Imm;
461 }
462
463 void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
464                                        raw_ostream &O) {
465   O << "{";
466   for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
467     if (i != OpNum) O << ", ";
468     O << getRegisterName(MI->getOperand(i).getReg());
469   }
470   O << "}";
471 }
472
473 void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum,
474                                         raw_ostream &O) {
475   const MCOperand &Op = MI->getOperand(OpNum);
476   if (Op.getImm())
477     O << "be";
478   else
479     O << "le";
480 }
481
482 void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum,
483                                   raw_ostream &O) {
484   const MCOperand &Op = MI->getOperand(OpNum);
485   O << ARM_PROC::IModToString(Op.getImm());
486 }
487
488 void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum,
489                                    raw_ostream &O) {
490   const MCOperand &Op = MI->getOperand(OpNum);
491   unsigned IFlags = Op.getImm();
492   for (int i=2; i >= 0; --i)
493     if (IFlags & (1 << i))
494       O << ARM_PROC::IFlagsToString(1 << i);
495 }
496
497 void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
498                                          raw_ostream &O) {
499   const MCOperand &Op = MI->getOperand(OpNum);
500   unsigned SpecRegRBit = Op.getImm() >> 4;
501   unsigned Mask = Op.getImm() & 0xf;
502
503   // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
504   // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
505   if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
506     O << "APSR_";
507     switch (Mask) {
508     default: assert(0);
509     case 4:  O << "g"; return;
510     case 8:  O << "nzcvq"; return;
511     case 12: O << "nzcvqg"; return;
512     }
513     llvm_unreachable("Unexpected mask value!");
514   }
515
516   if (SpecRegRBit)
517     O << "SPSR";
518   else
519     O << "CPSR";
520
521   if (Mask) {
522     O << '_';
523     if (Mask & 8) O << 'f';
524     if (Mask & 4) O << 's';
525     if (Mask & 2) O << 'x';
526     if (Mask & 1) O << 'c';
527   }
528 }
529
530 void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
531                                            raw_ostream &O) {
532   ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
533   if (CC != ARMCC::AL)
534     O << ARMCondCodeToString(CC);
535 }
536
537 void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI,
538                                                     unsigned OpNum,
539                                                     raw_ostream &O) {
540   ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
541   O << ARMCondCodeToString(CC);
542 }
543
544 void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum,
545                                               raw_ostream &O) {
546   if (MI->getOperand(OpNum).getReg()) {
547     assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
548            "Expect ARM CPSR register!");
549     O << 's';
550   }
551 }
552
553 void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum,
554                                           raw_ostream &O) {
555   O << MI->getOperand(OpNum).getImm();
556 }
557
558 void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum,
559                                           raw_ostream &O) {
560   O << "p" << MI->getOperand(OpNum).getImm();
561 }
562
563 void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum,
564                                           raw_ostream &O) {
565   O << "c" << MI->getOperand(OpNum).getImm();
566 }
567
568 void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
569                                   raw_ostream &O) {
570   llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
571 }
572
573 void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
574                                             raw_ostream &O) {
575   O << "#" <<  MI->getOperand(OpNum).getImm() * 4;
576 }
577
578 void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum,
579                                       raw_ostream &O) {
580   // (3 - the number of trailing zeros) is the number of then / else.
581   unsigned Mask = MI->getOperand(OpNum).getImm();
582   unsigned CondBit0 = Mask >> 4 & 1;
583   unsigned NumTZ = CountTrailingZeros_32(Mask);
584   assert(NumTZ <= 3 && "Invalid IT mask!");
585   for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
586     bool T = ((Mask >> Pos) & 1) == CondBit0;
587     if (T)
588       O << 't';
589     else
590       O << 'e';
591   }
592 }
593
594 void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op,
595                                                  raw_ostream &O) {
596   const MCOperand &MO1 = MI->getOperand(Op);
597   const MCOperand &MO2 = MI->getOperand(Op + 1);
598
599   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
600     printOperand(MI, Op, O);
601     return;
602   }
603
604   O << "[" << getRegisterName(MO1.getReg());
605   if (unsigned RegNum = MO2.getReg())
606     O << ", " << getRegisterName(RegNum);
607   O << "]";
608 }
609
610 void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI,
611                                                     unsigned Op,
612                                                     raw_ostream &O,
613                                                     unsigned Scale) {
614   const MCOperand &MO1 = MI->getOperand(Op);
615   const MCOperand &MO2 = MI->getOperand(Op + 1);
616
617   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
618     printOperand(MI, Op, O);
619     return;
620   }
621
622   O << "[" << getRegisterName(MO1.getReg());
623   if (unsigned ImmOffs = MO2.getImm())
624     O << ", #" << ImmOffs * Scale;
625   O << "]";
626 }
627
628 void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI,
629                                                      unsigned Op,
630                                                      raw_ostream &O) {
631   printThumbAddrModeImm5SOperand(MI, Op, O, 1);
632 }
633
634 void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI,
635                                                      unsigned Op,
636                                                      raw_ostream &O) {
637   printThumbAddrModeImm5SOperand(MI, Op, O, 2);
638 }
639
640 void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI,
641                                                      unsigned Op,
642                                                      raw_ostream &O) {
643   printThumbAddrModeImm5SOperand(MI, Op, O, 4);
644 }
645
646 void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op,
647                                                  raw_ostream &O) {
648   printThumbAddrModeImm5SOperand(MI, Op, O, 4);
649 }
650
651 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
652 // register with shift forms.
653 // REG 0   0           - e.g. R5
654 // REG IMM, SH_OPC     - e.g. R5, LSL #3
655 void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
656                                       raw_ostream &O) {
657   const MCOperand &MO1 = MI->getOperand(OpNum);
658   const MCOperand &MO2 = MI->getOperand(OpNum+1);
659
660   unsigned Reg = MO1.getReg();
661   O << getRegisterName(Reg);
662
663   // Print the shift opc.
664   assert(MO2.isImm() && "Not a valid t2_so_reg value!");
665   ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm());
666   O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
667   if (ShOpc != ARM_AM::rrx)
668     O << " #" << ARM_AM::getSORegOffset(MO2.getImm());
669 }
670
671 void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum,
672                                                raw_ostream &O) {
673   const MCOperand &MO1 = MI->getOperand(OpNum);
674   const MCOperand &MO2 = MI->getOperand(OpNum+1);
675
676   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
677     printOperand(MI, OpNum, O);
678     return;
679   }
680
681   O << "[" << getRegisterName(MO1.getReg());
682
683   int32_t OffImm = (int32_t)MO2.getImm();
684   bool isSub = OffImm < 0;
685   // Special value for #-0. All others are normal.
686   if (OffImm == INT32_MIN)
687     OffImm = 0;
688   if (isSub)
689     O << ", #-" << -OffImm;
690   else if (OffImm > 0)
691     O << ", #" << OffImm;
692   O << "]";
693 }
694
695 void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
696                                                 unsigned OpNum,
697                                                 raw_ostream &O) {
698   const MCOperand &MO1 = MI->getOperand(OpNum);
699   const MCOperand &MO2 = MI->getOperand(OpNum+1);
700
701   O << "[" << getRegisterName(MO1.getReg());
702
703   int32_t OffImm = (int32_t)MO2.getImm();
704   // Don't print +0.
705   if (OffImm < 0)
706     O << ", #-" << -OffImm;
707   else if (OffImm > 0)
708     O << ", #" << OffImm;
709   O << "]";
710 }
711
712 void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
713                                                   unsigned OpNum,
714                                                   raw_ostream &O) {
715   const MCOperand &MO1 = MI->getOperand(OpNum);
716   const MCOperand &MO2 = MI->getOperand(OpNum+1);
717
718   O << "[" << getRegisterName(MO1.getReg());
719
720   int32_t OffImm = (int32_t)MO2.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   O << "]";
727 }
728
729 void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst *MI,
730                                                       unsigned OpNum,
731                                                       raw_ostream &O) {
732   const MCOperand &MO1 = MI->getOperand(OpNum);
733   int32_t OffImm = (int32_t)MO1.getImm();
734   // Don't print +0.
735   if (OffImm < 0)
736     O << "#-" << -OffImm;
737   else if (OffImm > 0)
738     O << "#" << OffImm;
739 }
740
741 void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst *MI,
742                                                         unsigned OpNum,
743                                                         raw_ostream &O) {
744   const MCOperand &MO1 = MI->getOperand(OpNum);
745   int32_t OffImm = (int32_t)MO1.getImm() / 4;
746   // Don't print +0.
747   if (OffImm < 0)
748     O << "#-" << -OffImm * 4;
749   else if (OffImm > 0)
750     O << "#" << OffImm * 4;
751 }
752
753 void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
754                                                  unsigned OpNum,
755                                                  raw_ostream &O) {
756   const MCOperand &MO1 = MI->getOperand(OpNum);
757   const MCOperand &MO2 = MI->getOperand(OpNum+1);
758   const MCOperand &MO3 = MI->getOperand(OpNum+2);
759
760   O << "[" << getRegisterName(MO1.getReg());
761
762   assert(MO2.getReg() && "Invalid so_reg load / store address!");
763   O << ", " << getRegisterName(MO2.getReg());
764
765   unsigned ShAmt = MO3.getImm();
766   if (ShAmt) {
767     assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
768     O << ", lsl #" << ShAmt;
769   }
770   O << "]";
771 }
772
773 void ARMInstPrinter::printVFPf32ImmOperand(const MCInst *MI, unsigned OpNum,
774                                            raw_ostream &O) {
775   const MCOperand &MO = MI->getOperand(OpNum);
776   O << '#';
777   if (MO.isFPImm()) {
778     O << (float)MO.getFPImm();
779   } else {
780     union {
781       uint32_t I;
782       float F;
783     } FPUnion;
784
785     FPUnion.I = MO.getImm();
786     O << FPUnion.F;
787   }
788 }
789
790 void ARMInstPrinter::printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum,
791                                            raw_ostream &O) {
792   const MCOperand &MO = MI->getOperand(OpNum);
793   O << '#';
794   if (MO.isFPImm()) {
795     O << MO.getFPImm();
796   } else {
797     // We expect the binary encoding of a floating point number here.
798     union {
799       uint64_t I;
800       double D;
801     } FPUnion;
802
803     FPUnion.I = MO.getImm();
804     O << FPUnion.D;
805   }
806 }
807
808 void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,
809                                             raw_ostream &O) {
810   unsigned EncodedImm = MI->getOperand(OpNum).getImm();
811   unsigned EltBits;
812   uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
813   O << "#0x" << utohexstr(Val);
814 }