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