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