ARMInstPrinter.cpp revision 519020adf1cf57e2e93cc4fd49c385c47f7ff0f7
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
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
219void 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
237void 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
257void 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
285void 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
310void 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
318void 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
326void 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
345void 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
372void 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
392void 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
413void 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
425void 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
443void 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
451void 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
459void 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
468void 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
475void 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
497void 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
510void 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
516void 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
526void 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
537void 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
543void 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
554void 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
563void 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
573void 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
583void 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
592void 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
598void 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
607void 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
640void 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
647void 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
654void 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
663void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum,
664                                          raw_ostream &O) {
665  O << MI->getOperand(OpNum).getImm();
666}
667
668void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum,
669                                          raw_ostream &O) {
670  O << "p" << MI->getOperand(OpNum).getImm();
671}
672
673void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum,
674                                          raw_ostream &O) {
675  O << "c" << MI->getOperand(OpNum).getImm();
676}
677
678void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
679                                  raw_ostream &O) {
680  llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
681}
682
683void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
684                                            raw_ostream &O) {
685  O << "#" << MI->getOperand(OpNum).getImm() * 4;
686}
687
688void 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
694void 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
710void 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
726void 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
744void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI,
745                                                     unsigned Op,
746                                                     raw_ostream &O) {
747  printThumbAddrModeImm5SOperand(MI, Op, O, 1);
748}
749
750void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI,
751                                                     unsigned Op,
752                                                     raw_ostream &O) {
753  printThumbAddrModeImm5SOperand(MI, Op, O, 2);
754}
755
756void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI,
757                                                     unsigned Op,
758                                                     raw_ostream &O) {
759  printThumbAddrModeImm5SOperand(MI, Op, O, 4);
760}
761
762void 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
771void 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
787void 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
811void 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
830void 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
847void 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
859void 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
871void 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
886void 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
906void 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
923void 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
941void 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
949void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum,
950                                            raw_ostream &O) {
951  unsigned Imm = MI->getOperand(OpNum).getImm();
952  O << "#" << Imm + 1;
953}
954
955void 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}
968