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