1*9880d681SAndroid Build Coastguard Worker //===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This class prints an ARM MCInst to a .s file.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "ARMInstPrinter.h"
15*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/ARMAddressingModes.h"
16*9880d681SAndroid Build Coastguard Worker #include "MCTargetDesc/ARMBaseInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCRegisterInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
24*9880d681SAndroid Build Coastguard Worker using namespace llvm;
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "asm-printer"
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker #define PRINT_ALIAS_INSTR
29*9880d681SAndroid Build Coastguard Worker #include "ARMGenAsmWriter.inc"
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker /// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
32*9880d681SAndroid Build Coastguard Worker ///
33*9880d681SAndroid Build Coastguard Worker /// getSORegOffset returns an integer from 0-31, representing '32' as 0.
translateShiftImm(unsigned imm)34*9880d681SAndroid Build Coastguard Worker static unsigned translateShiftImm(unsigned imm) {
35*9880d681SAndroid Build Coastguard Worker // lsr #32 and asr #32 exist, but should be encoded as a 0.
36*9880d681SAndroid Build Coastguard Worker assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker if (imm == 0)
39*9880d681SAndroid Build Coastguard Worker return 32;
40*9880d681SAndroid Build Coastguard Worker return imm;
41*9880d681SAndroid Build Coastguard Worker }
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker /// Prints the shift value with an immediate value.
printRegImmShift(raw_ostream & O,ARM_AM::ShiftOpc ShOpc,unsigned ShImm,bool UseMarkup)44*9880d681SAndroid Build Coastguard Worker static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc,
45*9880d681SAndroid Build Coastguard Worker unsigned ShImm, bool UseMarkup) {
46*9880d681SAndroid Build Coastguard Worker if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm))
47*9880d681SAndroid Build Coastguard Worker return;
48*9880d681SAndroid Build Coastguard Worker O << ", ";
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker assert(!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0");
51*9880d681SAndroid Build Coastguard Worker O << getShiftOpcStr(ShOpc);
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker if (ShOpc != ARM_AM::rrx) {
54*9880d681SAndroid Build Coastguard Worker O << " ";
55*9880d681SAndroid Build Coastguard Worker if (UseMarkup)
56*9880d681SAndroid Build Coastguard Worker O << "<imm:";
57*9880d681SAndroid Build Coastguard Worker O << "#" << translateShiftImm(ShImm);
58*9880d681SAndroid Build Coastguard Worker if (UseMarkup)
59*9880d681SAndroid Build Coastguard Worker O << ">";
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker }
62*9880d681SAndroid Build Coastguard Worker
ARMInstPrinter(const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI)63*9880d681SAndroid Build Coastguard Worker ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
64*9880d681SAndroid Build Coastguard Worker const MCRegisterInfo &MRI)
65*9880d681SAndroid Build Coastguard Worker : MCInstPrinter(MAI, MII, MRI) {}
66*9880d681SAndroid Build Coastguard Worker
printRegName(raw_ostream & OS,unsigned RegNo) const67*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
68*9880d681SAndroid Build Coastguard Worker OS << markup("<reg:") << getRegisterName(RegNo) << markup(">");
69*9880d681SAndroid Build Coastguard Worker }
70*9880d681SAndroid Build Coastguard Worker
printInst(const MCInst * MI,raw_ostream & O,StringRef Annot,const MCSubtargetInfo & STI)71*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
72*9880d681SAndroid Build Coastguard Worker StringRef Annot, const MCSubtargetInfo &STI) {
73*9880d681SAndroid Build Coastguard Worker unsigned Opcode = MI->getOpcode();
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker switch (Opcode) {
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker // Check for MOVs and print canonical forms, instead.
78*9880d681SAndroid Build Coastguard Worker case ARM::MOVsr: {
79*9880d681SAndroid Build Coastguard Worker // FIXME: Thumb variants?
80*9880d681SAndroid Build Coastguard Worker const MCOperand &Dst = MI->getOperand(0);
81*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(1);
82*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(2);
83*9880d681SAndroid Build Coastguard Worker const MCOperand &MO3 = MI->getOperand(3);
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
86*9880d681SAndroid Build Coastguard Worker printSBitModifierOperand(MI, 6, STI, O);
87*9880d681SAndroid Build Coastguard Worker printPredicateOperand(MI, 4, STI, O);
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Worker O << '\t';
90*9880d681SAndroid Build Coastguard Worker printRegName(O, Dst.getReg());
91*9880d681SAndroid Build Coastguard Worker O << ", ";
92*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker O << ", ";
95*9880d681SAndroid Build Coastguard Worker printRegName(O, MO2.getReg());
96*9880d681SAndroid Build Coastguard Worker assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
97*9880d681SAndroid Build Coastguard Worker printAnnotation(O, Annot);
98*9880d681SAndroid Build Coastguard Worker return;
99*9880d681SAndroid Build Coastguard Worker }
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker case ARM::MOVsi: {
102*9880d681SAndroid Build Coastguard Worker // FIXME: Thumb variants?
103*9880d681SAndroid Build Coastguard Worker const MCOperand &Dst = MI->getOperand(0);
104*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(1);
105*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(2);
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()));
108*9880d681SAndroid Build Coastguard Worker printSBitModifierOperand(MI, 5, STI, O);
109*9880d681SAndroid Build Coastguard Worker printPredicateOperand(MI, 3, STI, O);
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker O << '\t';
112*9880d681SAndroid Build Coastguard Worker printRegName(O, Dst.getReg());
113*9880d681SAndroid Build Coastguard Worker O << ", ";
114*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
115*9880d681SAndroid Build Coastguard Worker
116*9880d681SAndroid Build Coastguard Worker if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx) {
117*9880d681SAndroid Build Coastguard Worker printAnnotation(O, Annot);
118*9880d681SAndroid Build Coastguard Worker return;
119*9880d681SAndroid Build Coastguard Worker }
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:") << "#"
122*9880d681SAndroid Build Coastguard Worker << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())) << markup(">");
123*9880d681SAndroid Build Coastguard Worker printAnnotation(O, Annot);
124*9880d681SAndroid Build Coastguard Worker return;
125*9880d681SAndroid Build Coastguard Worker }
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker // A8.6.123 PUSH
128*9880d681SAndroid Build Coastguard Worker case ARM::STMDB_UPD:
129*9880d681SAndroid Build Coastguard Worker case ARM::t2STMDB_UPD:
130*9880d681SAndroid Build Coastguard Worker if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
131*9880d681SAndroid Build Coastguard Worker // Should only print PUSH if there are at least two registers in the list.
132*9880d681SAndroid Build Coastguard Worker O << '\t' << "push";
133*9880d681SAndroid Build Coastguard Worker printPredicateOperand(MI, 2, STI, O);
134*9880d681SAndroid Build Coastguard Worker if (Opcode == ARM::t2STMDB_UPD)
135*9880d681SAndroid Build Coastguard Worker O << ".w";
136*9880d681SAndroid Build Coastguard Worker O << '\t';
137*9880d681SAndroid Build Coastguard Worker printRegisterList(MI, 4, STI, O);
138*9880d681SAndroid Build Coastguard Worker printAnnotation(O, Annot);
139*9880d681SAndroid Build Coastguard Worker return;
140*9880d681SAndroid Build Coastguard Worker } else
141*9880d681SAndroid Build Coastguard Worker break;
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker case ARM::STR_PRE_IMM:
144*9880d681SAndroid Build Coastguard Worker if (MI->getOperand(2).getReg() == ARM::SP &&
145*9880d681SAndroid Build Coastguard Worker MI->getOperand(3).getImm() == -4) {
146*9880d681SAndroid Build Coastguard Worker O << '\t' << "push";
147*9880d681SAndroid Build Coastguard Worker printPredicateOperand(MI, 4, STI, O);
148*9880d681SAndroid Build Coastguard Worker O << "\t{";
149*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(1).getReg());
150*9880d681SAndroid Build Coastguard Worker O << "}";
151*9880d681SAndroid Build Coastguard Worker printAnnotation(O, Annot);
152*9880d681SAndroid Build Coastguard Worker return;
153*9880d681SAndroid Build Coastguard Worker } else
154*9880d681SAndroid Build Coastguard Worker break;
155*9880d681SAndroid Build Coastguard Worker
156*9880d681SAndroid Build Coastguard Worker // A8.6.122 POP
157*9880d681SAndroid Build Coastguard Worker case ARM::LDMIA_UPD:
158*9880d681SAndroid Build Coastguard Worker case ARM::t2LDMIA_UPD:
159*9880d681SAndroid Build Coastguard Worker if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
160*9880d681SAndroid Build Coastguard Worker // Should only print POP if there are at least two registers in the list.
161*9880d681SAndroid Build Coastguard Worker O << '\t' << "pop";
162*9880d681SAndroid Build Coastguard Worker printPredicateOperand(MI, 2, STI, O);
163*9880d681SAndroid Build Coastguard Worker if (Opcode == ARM::t2LDMIA_UPD)
164*9880d681SAndroid Build Coastguard Worker O << ".w";
165*9880d681SAndroid Build Coastguard Worker O << '\t';
166*9880d681SAndroid Build Coastguard Worker printRegisterList(MI, 4, STI, O);
167*9880d681SAndroid Build Coastguard Worker printAnnotation(O, Annot);
168*9880d681SAndroid Build Coastguard Worker return;
169*9880d681SAndroid Build Coastguard Worker } else
170*9880d681SAndroid Build Coastguard Worker break;
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Worker case ARM::LDR_POST_IMM:
173*9880d681SAndroid Build Coastguard Worker if (MI->getOperand(2).getReg() == ARM::SP &&
174*9880d681SAndroid Build Coastguard Worker MI->getOperand(4).getImm() == 4) {
175*9880d681SAndroid Build Coastguard Worker O << '\t' << "pop";
176*9880d681SAndroid Build Coastguard Worker printPredicateOperand(MI, 5, STI, O);
177*9880d681SAndroid Build Coastguard Worker O << "\t{";
178*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(0).getReg());
179*9880d681SAndroid Build Coastguard Worker O << "}";
180*9880d681SAndroid Build Coastguard Worker printAnnotation(O, Annot);
181*9880d681SAndroid Build Coastguard Worker return;
182*9880d681SAndroid Build Coastguard Worker } else
183*9880d681SAndroid Build Coastguard Worker break;
184*9880d681SAndroid Build Coastguard Worker
185*9880d681SAndroid Build Coastguard Worker // A8.6.355 VPUSH
186*9880d681SAndroid Build Coastguard Worker case ARM::VSTMSDB_UPD:
187*9880d681SAndroid Build Coastguard Worker case ARM::VSTMDDB_UPD:
188*9880d681SAndroid Build Coastguard Worker if (MI->getOperand(0).getReg() == ARM::SP) {
189*9880d681SAndroid Build Coastguard Worker O << '\t' << "vpush";
190*9880d681SAndroid Build Coastguard Worker printPredicateOperand(MI, 2, STI, O);
191*9880d681SAndroid Build Coastguard Worker O << '\t';
192*9880d681SAndroid Build Coastguard Worker printRegisterList(MI, 4, STI, O);
193*9880d681SAndroid Build Coastguard Worker printAnnotation(O, Annot);
194*9880d681SAndroid Build Coastguard Worker return;
195*9880d681SAndroid Build Coastguard Worker } else
196*9880d681SAndroid Build Coastguard Worker break;
197*9880d681SAndroid Build Coastguard Worker
198*9880d681SAndroid Build Coastguard Worker // A8.6.354 VPOP
199*9880d681SAndroid Build Coastguard Worker case ARM::VLDMSIA_UPD:
200*9880d681SAndroid Build Coastguard Worker case ARM::VLDMDIA_UPD:
201*9880d681SAndroid Build Coastguard Worker if (MI->getOperand(0).getReg() == ARM::SP) {
202*9880d681SAndroid Build Coastguard Worker O << '\t' << "vpop";
203*9880d681SAndroid Build Coastguard Worker printPredicateOperand(MI, 2, STI, O);
204*9880d681SAndroid Build Coastguard Worker O << '\t';
205*9880d681SAndroid Build Coastguard Worker printRegisterList(MI, 4, STI, O);
206*9880d681SAndroid Build Coastguard Worker printAnnotation(O, Annot);
207*9880d681SAndroid Build Coastguard Worker return;
208*9880d681SAndroid Build Coastguard Worker } else
209*9880d681SAndroid Build Coastguard Worker break;
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker case ARM::tLDMIA: {
212*9880d681SAndroid Build Coastguard Worker bool Writeback = true;
213*9880d681SAndroid Build Coastguard Worker unsigned BaseReg = MI->getOperand(0).getReg();
214*9880d681SAndroid Build Coastguard Worker for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
215*9880d681SAndroid Build Coastguard Worker if (MI->getOperand(i).getReg() == BaseReg)
216*9880d681SAndroid Build Coastguard Worker Writeback = false;
217*9880d681SAndroid Build Coastguard Worker }
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Worker O << "\tldm";
220*9880d681SAndroid Build Coastguard Worker
221*9880d681SAndroid Build Coastguard Worker printPredicateOperand(MI, 1, STI, O);
222*9880d681SAndroid Build Coastguard Worker O << '\t';
223*9880d681SAndroid Build Coastguard Worker printRegName(O, BaseReg);
224*9880d681SAndroid Build Coastguard Worker if (Writeback)
225*9880d681SAndroid Build Coastguard Worker O << "!";
226*9880d681SAndroid Build Coastguard Worker O << ", ";
227*9880d681SAndroid Build Coastguard Worker printRegisterList(MI, 3, STI, O);
228*9880d681SAndroid Build Coastguard Worker printAnnotation(O, Annot);
229*9880d681SAndroid Build Coastguard Worker return;
230*9880d681SAndroid Build Coastguard Worker }
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Worker // Combine 2 GPRs from disassember into a GPRPair to match with instr def.
233*9880d681SAndroid Build Coastguard Worker // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
234*9880d681SAndroid Build Coastguard Worker // a single GPRPair reg operand is used in the .td file to replace the two
235*9880d681SAndroid Build Coastguard Worker // GPRs. However, when decoding them, the two GRPs cannot be automatically
236*9880d681SAndroid Build Coastguard Worker // expressed as a GPRPair, so we have to manually merge them.
237*9880d681SAndroid Build Coastguard Worker // FIXME: We would really like to be able to tablegen'erate this.
238*9880d681SAndroid Build Coastguard Worker case ARM::LDREXD:
239*9880d681SAndroid Build Coastguard Worker case ARM::STREXD:
240*9880d681SAndroid Build Coastguard Worker case ARM::LDAEXD:
241*9880d681SAndroid Build Coastguard Worker case ARM::STLEXD: {
242*9880d681SAndroid Build Coastguard Worker const MCRegisterClass &MRC = MRI.getRegClass(ARM::GPRRegClassID);
243*9880d681SAndroid Build Coastguard Worker bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD;
244*9880d681SAndroid Build Coastguard Worker unsigned Reg = MI->getOperand(isStore ? 1 : 0).getReg();
245*9880d681SAndroid Build Coastguard Worker if (MRC.contains(Reg)) {
246*9880d681SAndroid Build Coastguard Worker MCInst NewMI;
247*9880d681SAndroid Build Coastguard Worker MCOperand NewReg;
248*9880d681SAndroid Build Coastguard Worker NewMI.setOpcode(Opcode);
249*9880d681SAndroid Build Coastguard Worker
250*9880d681SAndroid Build Coastguard Worker if (isStore)
251*9880d681SAndroid Build Coastguard Worker NewMI.addOperand(MI->getOperand(0));
252*9880d681SAndroid Build Coastguard Worker NewReg = MCOperand::createReg(MRI.getMatchingSuperReg(
253*9880d681SAndroid Build Coastguard Worker Reg, ARM::gsub_0, &MRI.getRegClass(ARM::GPRPairRegClassID)));
254*9880d681SAndroid Build Coastguard Worker NewMI.addOperand(NewReg);
255*9880d681SAndroid Build Coastguard Worker
256*9880d681SAndroid Build Coastguard Worker // Copy the rest operands into NewMI.
257*9880d681SAndroid Build Coastguard Worker for (unsigned i = isStore ? 3 : 2; i < MI->getNumOperands(); ++i)
258*9880d681SAndroid Build Coastguard Worker NewMI.addOperand(MI->getOperand(i));
259*9880d681SAndroid Build Coastguard Worker printInstruction(&NewMI, STI, O);
260*9880d681SAndroid Build Coastguard Worker return;
261*9880d681SAndroid Build Coastguard Worker }
262*9880d681SAndroid Build Coastguard Worker break;
263*9880d681SAndroid Build Coastguard Worker }
264*9880d681SAndroid Build Coastguard Worker }
265*9880d681SAndroid Build Coastguard Worker
266*9880d681SAndroid Build Coastguard Worker if (!printAliasInstr(MI, STI, O))
267*9880d681SAndroid Build Coastguard Worker printInstruction(MI, STI, O);
268*9880d681SAndroid Build Coastguard Worker
269*9880d681SAndroid Build Coastguard Worker printAnnotation(O, Annot);
270*9880d681SAndroid Build Coastguard Worker }
271*9880d681SAndroid Build Coastguard Worker
printOperand(const MCInst * MI,unsigned OpNo,const MCSubtargetInfo & STI,raw_ostream & O)272*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
273*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI, raw_ostream &O) {
274*9880d681SAndroid Build Coastguard Worker const MCOperand &Op = MI->getOperand(OpNo);
275*9880d681SAndroid Build Coastguard Worker if (Op.isReg()) {
276*9880d681SAndroid Build Coastguard Worker unsigned Reg = Op.getReg();
277*9880d681SAndroid Build Coastguard Worker printRegName(O, Reg);
278*9880d681SAndroid Build Coastguard Worker } else if (Op.isImm()) {
279*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << '#' << formatImm(Op.getImm()) << markup(">");
280*9880d681SAndroid Build Coastguard Worker } else {
281*9880d681SAndroid Build Coastguard Worker assert(Op.isExpr() && "unknown operand kind in printOperand");
282*9880d681SAndroid Build Coastguard Worker const MCExpr *Expr = Op.getExpr();
283*9880d681SAndroid Build Coastguard Worker switch (Expr->getKind()) {
284*9880d681SAndroid Build Coastguard Worker case MCExpr::Binary:
285*9880d681SAndroid Build Coastguard Worker O << '#';
286*9880d681SAndroid Build Coastguard Worker Expr->print(O, &MAI);
287*9880d681SAndroid Build Coastguard Worker break;
288*9880d681SAndroid Build Coastguard Worker case MCExpr::Constant: {
289*9880d681SAndroid Build Coastguard Worker // If a symbolic branch target was added as a constant expression then
290*9880d681SAndroid Build Coastguard Worker // print that address in hex. And only print 32 unsigned bits for the
291*9880d681SAndroid Build Coastguard Worker // address.
292*9880d681SAndroid Build Coastguard Worker const MCConstantExpr *Constant = cast<MCConstantExpr>(Expr);
293*9880d681SAndroid Build Coastguard Worker int64_t TargetAddress;
294*9880d681SAndroid Build Coastguard Worker if (!Constant->evaluateAsAbsolute(TargetAddress)) {
295*9880d681SAndroid Build Coastguard Worker O << '#';
296*9880d681SAndroid Build Coastguard Worker Expr->print(O, &MAI);
297*9880d681SAndroid Build Coastguard Worker } else {
298*9880d681SAndroid Build Coastguard Worker O << "0x";
299*9880d681SAndroid Build Coastguard Worker O.write_hex(static_cast<uint32_t>(TargetAddress));
300*9880d681SAndroid Build Coastguard Worker }
301*9880d681SAndroid Build Coastguard Worker break;
302*9880d681SAndroid Build Coastguard Worker }
303*9880d681SAndroid Build Coastguard Worker default:
304*9880d681SAndroid Build Coastguard Worker // FIXME: Should we always treat this as if it is a constant literal and
305*9880d681SAndroid Build Coastguard Worker // prefix it with '#'?
306*9880d681SAndroid Build Coastguard Worker Expr->print(O, &MAI);
307*9880d681SAndroid Build Coastguard Worker break;
308*9880d681SAndroid Build Coastguard Worker }
309*9880d681SAndroid Build Coastguard Worker }
310*9880d681SAndroid Build Coastguard Worker }
311*9880d681SAndroid Build Coastguard Worker
printThumbLdrLabelOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)312*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum,
313*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
314*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
315*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
316*9880d681SAndroid Build Coastguard Worker if (MO1.isExpr()) {
317*9880d681SAndroid Build Coastguard Worker MO1.getExpr()->print(O, &MAI);
318*9880d681SAndroid Build Coastguard Worker return;
319*9880d681SAndroid Build Coastguard Worker }
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[pc, ";
322*9880d681SAndroid Build Coastguard Worker
323*9880d681SAndroid Build Coastguard Worker int32_t OffImm = (int32_t)MO1.getImm();
324*9880d681SAndroid Build Coastguard Worker bool isSub = OffImm < 0;
325*9880d681SAndroid Build Coastguard Worker
326*9880d681SAndroid Build Coastguard Worker // Special value for #-0. All others are normal.
327*9880d681SAndroid Build Coastguard Worker if (OffImm == INT32_MIN)
328*9880d681SAndroid Build Coastguard Worker OffImm = 0;
329*9880d681SAndroid Build Coastguard Worker if (isSub) {
330*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
331*9880d681SAndroid Build Coastguard Worker } else {
332*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
333*9880d681SAndroid Build Coastguard Worker }
334*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
335*9880d681SAndroid Build Coastguard Worker }
336*9880d681SAndroid Build Coastguard Worker
337*9880d681SAndroid Build Coastguard Worker // so_reg is a 4-operand unit corresponding to register forms of the A5.1
338*9880d681SAndroid Build Coastguard Worker // "Addressing Mode 1 - Data-processing operands" forms. This includes:
339*9880d681SAndroid Build Coastguard Worker // REG 0 0 - e.g. R5
340*9880d681SAndroid Build Coastguard Worker // REG REG 0,SH_OPC - e.g. R5, ROR R3
341*9880d681SAndroid Build Coastguard Worker // REG 0 IMM,SH_OPC - e.g. R5, LSL #3
printSORegRegOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)342*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum,
343*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
344*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
345*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
346*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum + 1);
347*9880d681SAndroid Build Coastguard Worker const MCOperand &MO3 = MI->getOperand(OpNum + 2);
348*9880d681SAndroid Build Coastguard Worker
349*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
350*9880d681SAndroid Build Coastguard Worker
351*9880d681SAndroid Build Coastguard Worker // Print the shift opc.
352*9880d681SAndroid Build Coastguard Worker ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
353*9880d681SAndroid Build Coastguard Worker O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
354*9880d681SAndroid Build Coastguard Worker if (ShOpc == ARM_AM::rrx)
355*9880d681SAndroid Build Coastguard Worker return;
356*9880d681SAndroid Build Coastguard Worker
357*9880d681SAndroid Build Coastguard Worker O << ' ';
358*9880d681SAndroid Build Coastguard Worker printRegName(O, MO2.getReg());
359*9880d681SAndroid Build Coastguard Worker assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
360*9880d681SAndroid Build Coastguard Worker }
361*9880d681SAndroid Build Coastguard Worker
printSORegImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)362*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum,
363*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
364*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
365*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
366*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum + 1);
367*9880d681SAndroid Build Coastguard Worker
368*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
369*9880d681SAndroid Build Coastguard Worker
370*9880d681SAndroid Build Coastguard Worker // Print the shift opc.
371*9880d681SAndroid Build Coastguard Worker printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
372*9880d681SAndroid Build Coastguard Worker ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
373*9880d681SAndroid Build Coastguard Worker }
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker //===--------------------------------------------------------------------===//
376*9880d681SAndroid Build Coastguard Worker // Addressing Mode #2
377*9880d681SAndroid Build Coastguard Worker //===--------------------------------------------------------------------===//
378*9880d681SAndroid Build Coastguard Worker
printAM2PreOrOffsetIndexOp(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)379*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
380*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
381*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
382*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(Op);
383*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(Op + 1);
384*9880d681SAndroid Build Coastguard Worker const MCOperand &MO3 = MI->getOperand(Op + 2);
385*9880d681SAndroid Build Coastguard Worker
386*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
387*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
388*9880d681SAndroid Build Coastguard Worker
389*9880d681SAndroid Build Coastguard Worker if (!MO2.getReg()) {
390*9880d681SAndroid Build Coastguard Worker if (ARM_AM::getAM2Offset(MO3.getImm())) { // Don't print +0.
391*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:") << "#"
392*9880d681SAndroid Build Coastguard Worker << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
393*9880d681SAndroid Build Coastguard Worker << ARM_AM::getAM2Offset(MO3.getImm()) << markup(">");
394*9880d681SAndroid Build Coastguard Worker }
395*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
396*9880d681SAndroid Build Coastguard Worker return;
397*9880d681SAndroid Build Coastguard Worker }
398*9880d681SAndroid Build Coastguard Worker
399*9880d681SAndroid Build Coastguard Worker O << ", ";
400*9880d681SAndroid Build Coastguard Worker O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()));
401*9880d681SAndroid Build Coastguard Worker printRegName(O, MO2.getReg());
402*9880d681SAndroid Build Coastguard Worker
403*9880d681SAndroid Build Coastguard Worker printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO3.getImm()),
404*9880d681SAndroid Build Coastguard Worker ARM_AM::getAM2Offset(MO3.getImm()), UseMarkup);
405*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
406*9880d681SAndroid Build Coastguard Worker }
407*9880d681SAndroid Build Coastguard Worker
printAddrModeTBB(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)408*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op,
409*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
410*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
411*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(Op);
412*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(Op + 1);
413*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
414*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
415*9880d681SAndroid Build Coastguard Worker O << ", ";
416*9880d681SAndroid Build Coastguard Worker printRegName(O, MO2.getReg());
417*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
418*9880d681SAndroid Build Coastguard Worker }
419*9880d681SAndroid Build Coastguard Worker
printAddrModeTBH(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)420*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op,
421*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
422*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
423*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(Op);
424*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(Op + 1);
425*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
426*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
427*9880d681SAndroid Build Coastguard Worker O << ", ";
428*9880d681SAndroid Build Coastguard Worker printRegName(O, MO2.getReg());
429*9880d681SAndroid Build Coastguard Worker O << ", lsl " << markup("<imm:") << "#1" << markup(">") << "]" << markup(">");
430*9880d681SAndroid Build Coastguard Worker }
431*9880d681SAndroid Build Coastguard Worker
printAddrMode2Operand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)432*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
433*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
434*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
435*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(Op);
436*9880d681SAndroid Build Coastguard Worker
437*9880d681SAndroid Build Coastguard Worker if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
438*9880d681SAndroid Build Coastguard Worker printOperand(MI, Op, STI, O);
439*9880d681SAndroid Build Coastguard Worker return;
440*9880d681SAndroid Build Coastguard Worker }
441*9880d681SAndroid Build Coastguard Worker
442*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
443*9880d681SAndroid Build Coastguard Worker const MCOperand &MO3 = MI->getOperand(Op + 2);
444*9880d681SAndroid Build Coastguard Worker unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
445*9880d681SAndroid Build Coastguard Worker assert(IdxMode != ARMII::IndexModePost && "Should be pre or offset index op");
446*9880d681SAndroid Build Coastguard Worker #endif
447*9880d681SAndroid Build Coastguard Worker
448*9880d681SAndroid Build Coastguard Worker printAM2PreOrOffsetIndexOp(MI, Op, STI, O);
449*9880d681SAndroid Build Coastguard Worker }
450*9880d681SAndroid Build Coastguard Worker
printAddrMode2OffsetOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)451*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
452*9880d681SAndroid Build Coastguard Worker unsigned OpNum,
453*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
454*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
455*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
456*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum + 1);
457*9880d681SAndroid Build Coastguard Worker
458*9880d681SAndroid Build Coastguard Worker if (!MO1.getReg()) {
459*9880d681SAndroid Build Coastguard Worker unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
460*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << '#'
461*9880d681SAndroid Build Coastguard Worker << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) << ImmOffs
462*9880d681SAndroid Build Coastguard Worker << markup(">");
463*9880d681SAndroid Build Coastguard Worker return;
464*9880d681SAndroid Build Coastguard Worker }
465*9880d681SAndroid Build Coastguard Worker
466*9880d681SAndroid Build Coastguard Worker O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()));
467*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
468*9880d681SAndroid Build Coastguard Worker
469*9880d681SAndroid Build Coastguard Worker printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO2.getImm()),
470*9880d681SAndroid Build Coastguard Worker ARM_AM::getAM2Offset(MO2.getImm()), UseMarkup);
471*9880d681SAndroid Build Coastguard Worker }
472*9880d681SAndroid Build Coastguard Worker
473*9880d681SAndroid Build Coastguard Worker //===--------------------------------------------------------------------===//
474*9880d681SAndroid Build Coastguard Worker // Addressing Mode #3
475*9880d681SAndroid Build Coastguard Worker //===--------------------------------------------------------------------===//
476*9880d681SAndroid Build Coastguard Worker
printAM3PreOrOffsetIndexOp(const MCInst * MI,unsigned Op,raw_ostream & O,bool AlwaysPrintImm0)477*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
478*9880d681SAndroid Build Coastguard Worker raw_ostream &O,
479*9880d681SAndroid Build Coastguard Worker bool AlwaysPrintImm0) {
480*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(Op);
481*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(Op + 1);
482*9880d681SAndroid Build Coastguard Worker const MCOperand &MO3 = MI->getOperand(Op + 2);
483*9880d681SAndroid Build Coastguard Worker
484*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << '[';
485*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
486*9880d681SAndroid Build Coastguard Worker
487*9880d681SAndroid Build Coastguard Worker if (MO2.getReg()) {
488*9880d681SAndroid Build Coastguard Worker O << ", " << getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()));
489*9880d681SAndroid Build Coastguard Worker printRegName(O, MO2.getReg());
490*9880d681SAndroid Build Coastguard Worker O << ']' << markup(">");
491*9880d681SAndroid Build Coastguard Worker return;
492*9880d681SAndroid Build Coastguard Worker }
493*9880d681SAndroid Build Coastguard Worker
494*9880d681SAndroid Build Coastguard Worker // If the op is sub we have to print the immediate even if it is 0
495*9880d681SAndroid Build Coastguard Worker unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
496*9880d681SAndroid Build Coastguard Worker ARM_AM::AddrOpc op = ARM_AM::getAM3Op(MO3.getImm());
497*9880d681SAndroid Build Coastguard Worker
498*9880d681SAndroid Build Coastguard Worker if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM::sub)) {
499*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(op) << ImmOffs
500*9880d681SAndroid Build Coastguard Worker << markup(">");
501*9880d681SAndroid Build Coastguard Worker }
502*9880d681SAndroid Build Coastguard Worker O << ']' << markup(">");
503*9880d681SAndroid Build Coastguard Worker }
504*9880d681SAndroid Build Coastguard Worker
505*9880d681SAndroid Build Coastguard Worker template <bool AlwaysPrintImm0>
printAddrMode3Operand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)506*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op,
507*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
508*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
509*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(Op);
510*9880d681SAndroid Build Coastguard Worker if (!MO1.isReg()) { // For label symbolic references.
511*9880d681SAndroid Build Coastguard Worker printOperand(MI, Op, STI, O);
512*9880d681SAndroid Build Coastguard Worker return;
513*9880d681SAndroid Build Coastguard Worker }
514*9880d681SAndroid Build Coastguard Worker
515*9880d681SAndroid Build Coastguard Worker assert(ARM_AM::getAM3IdxMode(MI->getOperand(Op + 2).getImm()) !=
516*9880d681SAndroid Build Coastguard Worker ARMII::IndexModePost &&
517*9880d681SAndroid Build Coastguard Worker "unexpected idxmode");
518*9880d681SAndroid Build Coastguard Worker printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0);
519*9880d681SAndroid Build Coastguard Worker }
520*9880d681SAndroid Build Coastguard Worker
printAddrMode3OffsetOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)521*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI,
522*9880d681SAndroid Build Coastguard Worker unsigned OpNum,
523*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
524*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
525*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
526*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum + 1);
527*9880d681SAndroid Build Coastguard Worker
528*9880d681SAndroid Build Coastguard Worker if (MO1.getReg()) {
529*9880d681SAndroid Build Coastguard Worker O << getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()));
530*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
531*9880d681SAndroid Build Coastguard Worker return;
532*9880d681SAndroid Build Coastguard Worker }
533*9880d681SAndroid Build Coastguard Worker
534*9880d681SAndroid Build Coastguard Worker unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
535*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << '#'
536*9880d681SAndroid Build Coastguard Worker << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) << ImmOffs
537*9880d681SAndroid Build Coastguard Worker << markup(">");
538*9880d681SAndroid Build Coastguard Worker }
539*9880d681SAndroid Build Coastguard Worker
printPostIdxImm8Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)540*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printPostIdxImm8Operand(const MCInst *MI, unsigned OpNum,
541*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
542*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
543*9880d681SAndroid Build Coastguard Worker const MCOperand &MO = MI->getOperand(OpNum);
544*9880d681SAndroid Build Coastguard Worker unsigned Imm = MO.getImm();
545*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff)
546*9880d681SAndroid Build Coastguard Worker << markup(">");
547*9880d681SAndroid Build Coastguard Worker }
548*9880d681SAndroid Build Coastguard Worker
printPostIdxRegOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)549*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printPostIdxRegOperand(const MCInst *MI, unsigned OpNum,
550*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
551*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
552*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
553*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum + 1);
554*9880d681SAndroid Build Coastguard Worker
555*9880d681SAndroid Build Coastguard Worker O << (MO2.getImm() ? "" : "-");
556*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
557*9880d681SAndroid Build Coastguard Worker }
558*9880d681SAndroid Build Coastguard Worker
printPostIdxImm8s4Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)559*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printPostIdxImm8s4Operand(const MCInst *MI, unsigned OpNum,
560*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
561*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
562*9880d681SAndroid Build Coastguard Worker const MCOperand &MO = MI->getOperand(OpNum);
563*9880d681SAndroid Build Coastguard Worker unsigned Imm = MO.getImm();
564*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2)
565*9880d681SAndroid Build Coastguard Worker << markup(">");
566*9880d681SAndroid Build Coastguard Worker }
567*9880d681SAndroid Build Coastguard Worker
printLdStmModeOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)568*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum,
569*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
570*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
571*9880d681SAndroid Build Coastguard Worker ARM_AM::AMSubMode Mode =
572*9880d681SAndroid Build Coastguard Worker ARM_AM::getAM4SubMode(MI->getOperand(OpNum).getImm());
573*9880d681SAndroid Build Coastguard Worker O << ARM_AM::getAMSubModeStr(Mode);
574*9880d681SAndroid Build Coastguard Worker }
575*9880d681SAndroid Build Coastguard Worker
576*9880d681SAndroid Build Coastguard Worker template <bool AlwaysPrintImm0>
printAddrMode5Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)577*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
578*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
579*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
580*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
581*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum + 1);
582*9880d681SAndroid Build Coastguard Worker
583*9880d681SAndroid Build Coastguard Worker if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
584*9880d681SAndroid Build Coastguard Worker printOperand(MI, OpNum, STI, O);
585*9880d681SAndroid Build Coastguard Worker return;
586*9880d681SAndroid Build Coastguard Worker }
587*9880d681SAndroid Build Coastguard Worker
588*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
589*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
590*9880d681SAndroid Build Coastguard Worker
591*9880d681SAndroid Build Coastguard Worker unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm());
592*9880d681SAndroid Build Coastguard Worker ARM_AM::AddrOpc Op = ARM_AM::getAM5Op(MO2.getImm());
593*9880d681SAndroid Build Coastguard Worker if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
594*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(Op)
595*9880d681SAndroid Build Coastguard Worker << ImmOffs * 4 << markup(">");
596*9880d681SAndroid Build Coastguard Worker }
597*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
598*9880d681SAndroid Build Coastguard Worker }
599*9880d681SAndroid Build Coastguard Worker
600*9880d681SAndroid Build Coastguard Worker template <bool AlwaysPrintImm0>
printAddrMode5FP16Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)601*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAddrMode5FP16Operand(const MCInst *MI, unsigned OpNum,
602*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
603*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
604*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
605*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum+1);
606*9880d681SAndroid Build Coastguard Worker
607*9880d681SAndroid Build Coastguard Worker if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
608*9880d681SAndroid Build Coastguard Worker printOperand(MI, OpNum, STI, O);
609*9880d681SAndroid Build Coastguard Worker return;
610*9880d681SAndroid Build Coastguard Worker }
611*9880d681SAndroid Build Coastguard Worker
612*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
613*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
614*9880d681SAndroid Build Coastguard Worker
615*9880d681SAndroid Build Coastguard Worker unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm());
616*9880d681SAndroid Build Coastguard Worker unsigned Op = ARM_AM::getAM5FP16Op(MO2.getImm());
617*9880d681SAndroid Build Coastguard Worker if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
618*9880d681SAndroid Build Coastguard Worker O << ", "
619*9880d681SAndroid Build Coastguard Worker << markup("<imm:")
620*9880d681SAndroid Build Coastguard Worker << "#"
621*9880d681SAndroid Build Coastguard Worker << ARM_AM::getAddrOpcStr(ARM_AM::getAM5FP16Op(MO2.getImm()))
622*9880d681SAndroid Build Coastguard Worker << ImmOffs * 2
623*9880d681SAndroid Build Coastguard Worker << markup(">");
624*9880d681SAndroid Build Coastguard Worker }
625*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
626*9880d681SAndroid Build Coastguard Worker }
627*9880d681SAndroid Build Coastguard Worker
printAddrMode6Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)628*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum,
629*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
630*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
631*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
632*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum + 1);
633*9880d681SAndroid Build Coastguard Worker
634*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
635*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
636*9880d681SAndroid Build Coastguard Worker if (MO2.getImm()) {
637*9880d681SAndroid Build Coastguard Worker O << ":" << (MO2.getImm() << 3);
638*9880d681SAndroid Build Coastguard Worker }
639*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
640*9880d681SAndroid Build Coastguard Worker }
641*9880d681SAndroid Build Coastguard Worker
printAddrMode7Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)642*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum,
643*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
644*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
645*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
646*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
647*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
648*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
649*9880d681SAndroid Build Coastguard Worker }
650*9880d681SAndroid Build Coastguard Worker
printAddrMode6OffsetOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)651*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
652*9880d681SAndroid Build Coastguard Worker unsigned OpNum,
653*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
654*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
655*9880d681SAndroid Build Coastguard Worker const MCOperand &MO = MI->getOperand(OpNum);
656*9880d681SAndroid Build Coastguard Worker if (MO.getReg() == 0)
657*9880d681SAndroid Build Coastguard Worker O << "!";
658*9880d681SAndroid Build Coastguard Worker else {
659*9880d681SAndroid Build Coastguard Worker O << ", ";
660*9880d681SAndroid Build Coastguard Worker printRegName(O, MO.getReg());
661*9880d681SAndroid Build Coastguard Worker }
662*9880d681SAndroid Build Coastguard Worker }
663*9880d681SAndroid Build Coastguard Worker
printBitfieldInvMaskImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)664*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,
665*9880d681SAndroid Build Coastguard Worker unsigned OpNum,
666*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
667*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
668*9880d681SAndroid Build Coastguard Worker const MCOperand &MO = MI->getOperand(OpNum);
669*9880d681SAndroid Build Coastguard Worker uint32_t v = ~MO.getImm();
670*9880d681SAndroid Build Coastguard Worker int32_t lsb = countTrailingZeros(v);
671*9880d681SAndroid Build Coastguard Worker int32_t width = (32 - countLeadingZeros(v)) - lsb;
672*9880d681SAndroid Build Coastguard Worker assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
673*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << '#' << lsb << markup(">") << ", " << markup("<imm:")
674*9880d681SAndroid Build Coastguard Worker << '#' << width << markup(">");
675*9880d681SAndroid Build Coastguard Worker }
676*9880d681SAndroid Build Coastguard Worker
printMemBOption(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)677*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
678*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
679*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
680*9880d681SAndroid Build Coastguard Worker unsigned val = MI->getOperand(OpNum).getImm();
681*9880d681SAndroid Build Coastguard Worker O << ARM_MB::MemBOptToString(val, STI.getFeatureBits()[ARM::HasV8Ops]);
682*9880d681SAndroid Build Coastguard Worker }
683*9880d681SAndroid Build Coastguard Worker
printInstSyncBOption(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)684*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
685*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
686*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
687*9880d681SAndroid Build Coastguard Worker unsigned val = MI->getOperand(OpNum).getImm();
688*9880d681SAndroid Build Coastguard Worker O << ARM_ISB::InstSyncBOptToString(val);
689*9880d681SAndroid Build Coastguard Worker }
690*9880d681SAndroid Build Coastguard Worker
printShiftImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)691*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
692*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
693*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
694*9880d681SAndroid Build Coastguard Worker unsigned ShiftOp = MI->getOperand(OpNum).getImm();
695*9880d681SAndroid Build Coastguard Worker bool isASR = (ShiftOp & (1 << 5)) != 0;
696*9880d681SAndroid Build Coastguard Worker unsigned Amt = ShiftOp & 0x1f;
697*9880d681SAndroid Build Coastguard Worker if (isASR) {
698*9880d681SAndroid Build Coastguard Worker O << ", asr " << markup("<imm:") << "#" << (Amt == 0 ? 32 : Amt)
699*9880d681SAndroid Build Coastguard Worker << markup(">");
700*9880d681SAndroid Build Coastguard Worker } else if (Amt) {
701*9880d681SAndroid Build Coastguard Worker O << ", lsl " << markup("<imm:") << "#" << Amt << markup(">");
702*9880d681SAndroid Build Coastguard Worker }
703*9880d681SAndroid Build Coastguard Worker }
704*9880d681SAndroid Build Coastguard Worker
printPKHLSLShiftImm(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)705*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum,
706*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
707*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
708*9880d681SAndroid Build Coastguard Worker unsigned Imm = MI->getOperand(OpNum).getImm();
709*9880d681SAndroid Build Coastguard Worker if (Imm == 0)
710*9880d681SAndroid Build Coastguard Worker return;
711*9880d681SAndroid Build Coastguard Worker assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
712*9880d681SAndroid Build Coastguard Worker O << ", lsl " << markup("<imm:") << "#" << Imm << markup(">");
713*9880d681SAndroid Build Coastguard Worker }
714*9880d681SAndroid Build Coastguard Worker
printPKHASRShiftImm(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)715*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum,
716*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
717*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
718*9880d681SAndroid Build Coastguard Worker unsigned Imm = MI->getOperand(OpNum).getImm();
719*9880d681SAndroid Build Coastguard Worker // A shift amount of 32 is encoded as 0.
720*9880d681SAndroid Build Coastguard Worker if (Imm == 0)
721*9880d681SAndroid Build Coastguard Worker Imm = 32;
722*9880d681SAndroid Build Coastguard Worker assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
723*9880d681SAndroid Build Coastguard Worker O << ", asr " << markup("<imm:") << "#" << Imm << markup(">");
724*9880d681SAndroid Build Coastguard Worker }
725*9880d681SAndroid Build Coastguard Worker
printRegisterList(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)726*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
727*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
728*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
729*9880d681SAndroid Build Coastguard Worker O << "{";
730*9880d681SAndroid Build Coastguard Worker for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
731*9880d681SAndroid Build Coastguard Worker if (i != OpNum)
732*9880d681SAndroid Build Coastguard Worker O << ", ";
733*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(i).getReg());
734*9880d681SAndroid Build Coastguard Worker }
735*9880d681SAndroid Build Coastguard Worker O << "}";
736*9880d681SAndroid Build Coastguard Worker }
737*9880d681SAndroid Build Coastguard Worker
printGPRPairOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)738*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum,
739*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
740*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
741*9880d681SAndroid Build Coastguard Worker unsigned Reg = MI->getOperand(OpNum).getReg();
742*9880d681SAndroid Build Coastguard Worker printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0));
743*9880d681SAndroid Build Coastguard Worker O << ", ";
744*9880d681SAndroid Build Coastguard Worker printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1));
745*9880d681SAndroid Build Coastguard Worker }
746*9880d681SAndroid Build Coastguard Worker
printSetendOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)747*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum,
748*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
749*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
750*9880d681SAndroid Build Coastguard Worker const MCOperand &Op = MI->getOperand(OpNum);
751*9880d681SAndroid Build Coastguard Worker if (Op.getImm())
752*9880d681SAndroid Build Coastguard Worker O << "be";
753*9880d681SAndroid Build Coastguard Worker else
754*9880d681SAndroid Build Coastguard Worker O << "le";
755*9880d681SAndroid Build Coastguard Worker }
756*9880d681SAndroid Build Coastguard Worker
printCPSIMod(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)757*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum,
758*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI, raw_ostream &O) {
759*9880d681SAndroid Build Coastguard Worker const MCOperand &Op = MI->getOperand(OpNum);
760*9880d681SAndroid Build Coastguard Worker O << ARM_PROC::IModToString(Op.getImm());
761*9880d681SAndroid Build Coastguard Worker }
762*9880d681SAndroid Build Coastguard Worker
printCPSIFlag(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)763*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum,
764*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI, raw_ostream &O) {
765*9880d681SAndroid Build Coastguard Worker const MCOperand &Op = MI->getOperand(OpNum);
766*9880d681SAndroid Build Coastguard Worker unsigned IFlags = Op.getImm();
767*9880d681SAndroid Build Coastguard Worker for (int i = 2; i >= 0; --i)
768*9880d681SAndroid Build Coastguard Worker if (IFlags & (1 << i))
769*9880d681SAndroid Build Coastguard Worker O << ARM_PROC::IFlagsToString(1 << i);
770*9880d681SAndroid Build Coastguard Worker
771*9880d681SAndroid Build Coastguard Worker if (IFlags == 0)
772*9880d681SAndroid Build Coastguard Worker O << "none";
773*9880d681SAndroid Build Coastguard Worker }
774*9880d681SAndroid Build Coastguard Worker
printMSRMaskOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)775*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
776*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
777*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
778*9880d681SAndroid Build Coastguard Worker const MCOperand &Op = MI->getOperand(OpNum);
779*9880d681SAndroid Build Coastguard Worker unsigned SpecRegRBit = Op.getImm() >> 4;
780*9880d681SAndroid Build Coastguard Worker unsigned Mask = Op.getImm() & 0xf;
781*9880d681SAndroid Build Coastguard Worker const FeatureBitset &FeatureBits = STI.getFeatureBits();
782*9880d681SAndroid Build Coastguard Worker
783*9880d681SAndroid Build Coastguard Worker if (FeatureBits[ARM::FeatureMClass]) {
784*9880d681SAndroid Build Coastguard Worker unsigned SYSm = Op.getImm();
785*9880d681SAndroid Build Coastguard Worker unsigned Opcode = MI->getOpcode();
786*9880d681SAndroid Build Coastguard Worker
787*9880d681SAndroid Build Coastguard Worker // For writes, handle extended mask bits if the DSP extension is present.
788*9880d681SAndroid Build Coastguard Worker if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSP]) {
789*9880d681SAndroid Build Coastguard Worker switch (SYSm) {
790*9880d681SAndroid Build Coastguard Worker case 0x400:
791*9880d681SAndroid Build Coastguard Worker O << "apsr_g";
792*9880d681SAndroid Build Coastguard Worker return;
793*9880d681SAndroid Build Coastguard Worker case 0xc00:
794*9880d681SAndroid Build Coastguard Worker O << "apsr_nzcvqg";
795*9880d681SAndroid Build Coastguard Worker return;
796*9880d681SAndroid Build Coastguard Worker case 0x401:
797*9880d681SAndroid Build Coastguard Worker O << "iapsr_g";
798*9880d681SAndroid Build Coastguard Worker return;
799*9880d681SAndroid Build Coastguard Worker case 0xc01:
800*9880d681SAndroid Build Coastguard Worker O << "iapsr_nzcvqg";
801*9880d681SAndroid Build Coastguard Worker return;
802*9880d681SAndroid Build Coastguard Worker case 0x402:
803*9880d681SAndroid Build Coastguard Worker O << "eapsr_g";
804*9880d681SAndroid Build Coastguard Worker return;
805*9880d681SAndroid Build Coastguard Worker case 0xc02:
806*9880d681SAndroid Build Coastguard Worker O << "eapsr_nzcvqg";
807*9880d681SAndroid Build Coastguard Worker return;
808*9880d681SAndroid Build Coastguard Worker case 0x403:
809*9880d681SAndroid Build Coastguard Worker O << "xpsr_g";
810*9880d681SAndroid Build Coastguard Worker return;
811*9880d681SAndroid Build Coastguard Worker case 0xc03:
812*9880d681SAndroid Build Coastguard Worker O << "xpsr_nzcvqg";
813*9880d681SAndroid Build Coastguard Worker return;
814*9880d681SAndroid Build Coastguard Worker }
815*9880d681SAndroid Build Coastguard Worker }
816*9880d681SAndroid Build Coastguard Worker
817*9880d681SAndroid Build Coastguard Worker // Handle the basic 8-bit mask.
818*9880d681SAndroid Build Coastguard Worker SYSm &= 0xff;
819*9880d681SAndroid Build Coastguard Worker
820*9880d681SAndroid Build Coastguard Worker if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) {
821*9880d681SAndroid Build Coastguard Worker // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
822*9880d681SAndroid Build Coastguard Worker // alias for MSR APSR_nzcvq.
823*9880d681SAndroid Build Coastguard Worker switch (SYSm) {
824*9880d681SAndroid Build Coastguard Worker case 0:
825*9880d681SAndroid Build Coastguard Worker O << "apsr_nzcvq";
826*9880d681SAndroid Build Coastguard Worker return;
827*9880d681SAndroid Build Coastguard Worker case 1:
828*9880d681SAndroid Build Coastguard Worker O << "iapsr_nzcvq";
829*9880d681SAndroid Build Coastguard Worker return;
830*9880d681SAndroid Build Coastguard Worker case 2:
831*9880d681SAndroid Build Coastguard Worker O << "eapsr_nzcvq";
832*9880d681SAndroid Build Coastguard Worker return;
833*9880d681SAndroid Build Coastguard Worker case 3:
834*9880d681SAndroid Build Coastguard Worker O << "xpsr_nzcvq";
835*9880d681SAndroid Build Coastguard Worker return;
836*9880d681SAndroid Build Coastguard Worker }
837*9880d681SAndroid Build Coastguard Worker }
838*9880d681SAndroid Build Coastguard Worker
839*9880d681SAndroid Build Coastguard Worker switch (SYSm) {
840*9880d681SAndroid Build Coastguard Worker default:
841*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unexpected mask value!");
842*9880d681SAndroid Build Coastguard Worker case 0:
843*9880d681SAndroid Build Coastguard Worker O << "apsr";
844*9880d681SAndroid Build Coastguard Worker return;
845*9880d681SAndroid Build Coastguard Worker case 1:
846*9880d681SAndroid Build Coastguard Worker O << "iapsr";
847*9880d681SAndroid Build Coastguard Worker return;
848*9880d681SAndroid Build Coastguard Worker case 2:
849*9880d681SAndroid Build Coastguard Worker O << "eapsr";
850*9880d681SAndroid Build Coastguard Worker return;
851*9880d681SAndroid Build Coastguard Worker case 3:
852*9880d681SAndroid Build Coastguard Worker O << "xpsr";
853*9880d681SAndroid Build Coastguard Worker return;
854*9880d681SAndroid Build Coastguard Worker case 5:
855*9880d681SAndroid Build Coastguard Worker O << "ipsr";
856*9880d681SAndroid Build Coastguard Worker return;
857*9880d681SAndroid Build Coastguard Worker case 6:
858*9880d681SAndroid Build Coastguard Worker O << "epsr";
859*9880d681SAndroid Build Coastguard Worker return;
860*9880d681SAndroid Build Coastguard Worker case 7:
861*9880d681SAndroid Build Coastguard Worker O << "iepsr";
862*9880d681SAndroid Build Coastguard Worker return;
863*9880d681SAndroid Build Coastguard Worker case 8:
864*9880d681SAndroid Build Coastguard Worker O << "msp";
865*9880d681SAndroid Build Coastguard Worker return;
866*9880d681SAndroid Build Coastguard Worker case 9:
867*9880d681SAndroid Build Coastguard Worker O << "psp";
868*9880d681SAndroid Build Coastguard Worker return;
869*9880d681SAndroid Build Coastguard Worker case 16:
870*9880d681SAndroid Build Coastguard Worker O << "primask";
871*9880d681SAndroid Build Coastguard Worker return;
872*9880d681SAndroid Build Coastguard Worker case 17:
873*9880d681SAndroid Build Coastguard Worker O << "basepri";
874*9880d681SAndroid Build Coastguard Worker return;
875*9880d681SAndroid Build Coastguard Worker case 18:
876*9880d681SAndroid Build Coastguard Worker O << "basepri_max";
877*9880d681SAndroid Build Coastguard Worker return;
878*9880d681SAndroid Build Coastguard Worker case 19:
879*9880d681SAndroid Build Coastguard Worker O << "faultmask";
880*9880d681SAndroid Build Coastguard Worker return;
881*9880d681SAndroid Build Coastguard Worker case 20:
882*9880d681SAndroid Build Coastguard Worker O << "control";
883*9880d681SAndroid Build Coastguard Worker return;
884*9880d681SAndroid Build Coastguard Worker case 10:
885*9880d681SAndroid Build Coastguard Worker O << "msplim";
886*9880d681SAndroid Build Coastguard Worker return;
887*9880d681SAndroid Build Coastguard Worker case 11:
888*9880d681SAndroid Build Coastguard Worker O << "psplim";
889*9880d681SAndroid Build Coastguard Worker return;
890*9880d681SAndroid Build Coastguard Worker case 0x88:
891*9880d681SAndroid Build Coastguard Worker O << "msp_ns";
892*9880d681SAndroid Build Coastguard Worker return;
893*9880d681SAndroid Build Coastguard Worker case 0x89:
894*9880d681SAndroid Build Coastguard Worker O << "psp_ns";
895*9880d681SAndroid Build Coastguard Worker return;
896*9880d681SAndroid Build Coastguard Worker case 0x8a:
897*9880d681SAndroid Build Coastguard Worker O << "msplim_ns";
898*9880d681SAndroid Build Coastguard Worker return;
899*9880d681SAndroid Build Coastguard Worker case 0x8b:
900*9880d681SAndroid Build Coastguard Worker O << "psplim_ns";
901*9880d681SAndroid Build Coastguard Worker return;
902*9880d681SAndroid Build Coastguard Worker case 0x90:
903*9880d681SAndroid Build Coastguard Worker O << "primask_ns";
904*9880d681SAndroid Build Coastguard Worker return;
905*9880d681SAndroid Build Coastguard Worker case 0x91:
906*9880d681SAndroid Build Coastguard Worker O << "basepri_ns";
907*9880d681SAndroid Build Coastguard Worker return;
908*9880d681SAndroid Build Coastguard Worker case 0x92:
909*9880d681SAndroid Build Coastguard Worker O << "basepri_max_ns";
910*9880d681SAndroid Build Coastguard Worker return;
911*9880d681SAndroid Build Coastguard Worker case 0x93:
912*9880d681SAndroid Build Coastguard Worker O << "faultmask_ns";
913*9880d681SAndroid Build Coastguard Worker return;
914*9880d681SAndroid Build Coastguard Worker case 0x94:
915*9880d681SAndroid Build Coastguard Worker O << "control_ns";
916*9880d681SAndroid Build Coastguard Worker return;
917*9880d681SAndroid Build Coastguard Worker case 0x98:
918*9880d681SAndroid Build Coastguard Worker O << "sp_ns";
919*9880d681SAndroid Build Coastguard Worker return;
920*9880d681SAndroid Build Coastguard Worker }
921*9880d681SAndroid Build Coastguard Worker }
922*9880d681SAndroid Build Coastguard Worker
923*9880d681SAndroid Build Coastguard Worker // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
924*9880d681SAndroid Build Coastguard Worker // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
925*9880d681SAndroid Build Coastguard Worker if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
926*9880d681SAndroid Build Coastguard Worker O << "APSR_";
927*9880d681SAndroid Build Coastguard Worker switch (Mask) {
928*9880d681SAndroid Build Coastguard Worker default:
929*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unexpected mask value!");
930*9880d681SAndroid Build Coastguard Worker case 4:
931*9880d681SAndroid Build Coastguard Worker O << "g";
932*9880d681SAndroid Build Coastguard Worker return;
933*9880d681SAndroid Build Coastguard Worker case 8:
934*9880d681SAndroid Build Coastguard Worker O << "nzcvq";
935*9880d681SAndroid Build Coastguard Worker return;
936*9880d681SAndroid Build Coastguard Worker case 12:
937*9880d681SAndroid Build Coastguard Worker O << "nzcvqg";
938*9880d681SAndroid Build Coastguard Worker return;
939*9880d681SAndroid Build Coastguard Worker }
940*9880d681SAndroid Build Coastguard Worker }
941*9880d681SAndroid Build Coastguard Worker
942*9880d681SAndroid Build Coastguard Worker if (SpecRegRBit)
943*9880d681SAndroid Build Coastguard Worker O << "SPSR";
944*9880d681SAndroid Build Coastguard Worker else
945*9880d681SAndroid Build Coastguard Worker O << "CPSR";
946*9880d681SAndroid Build Coastguard Worker
947*9880d681SAndroid Build Coastguard Worker if (Mask) {
948*9880d681SAndroid Build Coastguard Worker O << '_';
949*9880d681SAndroid Build Coastguard Worker if (Mask & 8)
950*9880d681SAndroid Build Coastguard Worker O << 'f';
951*9880d681SAndroid Build Coastguard Worker if (Mask & 4)
952*9880d681SAndroid Build Coastguard Worker O << 's';
953*9880d681SAndroid Build Coastguard Worker if (Mask & 2)
954*9880d681SAndroid Build Coastguard Worker O << 'x';
955*9880d681SAndroid Build Coastguard Worker if (Mask & 1)
956*9880d681SAndroid Build Coastguard Worker O << 'c';
957*9880d681SAndroid Build Coastguard Worker }
958*9880d681SAndroid Build Coastguard Worker }
959*9880d681SAndroid Build Coastguard Worker
printBankedRegOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)960*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum,
961*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
962*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
963*9880d681SAndroid Build Coastguard Worker uint32_t Banked = MI->getOperand(OpNum).getImm();
964*9880d681SAndroid Build Coastguard Worker uint32_t R = (Banked & 0x20) >> 5;
965*9880d681SAndroid Build Coastguard Worker uint32_t SysM = Banked & 0x1f;
966*9880d681SAndroid Build Coastguard Worker
967*9880d681SAndroid Build Coastguard Worker // Nothing much we can do about this, the encodings are specified in B9.2.3 of
968*9880d681SAndroid Build Coastguard Worker // the ARM ARM v7C, and are all over the shop.
969*9880d681SAndroid Build Coastguard Worker if (R) {
970*9880d681SAndroid Build Coastguard Worker O << "SPSR_";
971*9880d681SAndroid Build Coastguard Worker
972*9880d681SAndroid Build Coastguard Worker switch (SysM) {
973*9880d681SAndroid Build Coastguard Worker case 0x0e:
974*9880d681SAndroid Build Coastguard Worker O << "fiq";
975*9880d681SAndroid Build Coastguard Worker return;
976*9880d681SAndroid Build Coastguard Worker case 0x10:
977*9880d681SAndroid Build Coastguard Worker O << "irq";
978*9880d681SAndroid Build Coastguard Worker return;
979*9880d681SAndroid Build Coastguard Worker case 0x12:
980*9880d681SAndroid Build Coastguard Worker O << "svc";
981*9880d681SAndroid Build Coastguard Worker return;
982*9880d681SAndroid Build Coastguard Worker case 0x14:
983*9880d681SAndroid Build Coastguard Worker O << "abt";
984*9880d681SAndroid Build Coastguard Worker return;
985*9880d681SAndroid Build Coastguard Worker case 0x16:
986*9880d681SAndroid Build Coastguard Worker O << "und";
987*9880d681SAndroid Build Coastguard Worker return;
988*9880d681SAndroid Build Coastguard Worker case 0x1c:
989*9880d681SAndroid Build Coastguard Worker O << "mon";
990*9880d681SAndroid Build Coastguard Worker return;
991*9880d681SAndroid Build Coastguard Worker case 0x1e:
992*9880d681SAndroid Build Coastguard Worker O << "hyp";
993*9880d681SAndroid Build Coastguard Worker return;
994*9880d681SAndroid Build Coastguard Worker default:
995*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid banked SPSR register");
996*9880d681SAndroid Build Coastguard Worker }
997*9880d681SAndroid Build Coastguard Worker }
998*9880d681SAndroid Build Coastguard Worker
999*9880d681SAndroid Build Coastguard Worker assert(!R && "should have dealt with SPSR regs");
1000*9880d681SAndroid Build Coastguard Worker const char *RegNames[] = {
1001*9880d681SAndroid Build Coastguard Worker "r8_usr", "r9_usr", "r10_usr", "r11_usr", "r12_usr", "sp_usr", "lr_usr",
1002*9880d681SAndroid Build Coastguard Worker "", "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "sp_fiq",
1003*9880d681SAndroid Build Coastguard Worker "lr_fiq", "", "lr_irq", "sp_irq", "lr_svc", "sp_svc", "lr_abt",
1004*9880d681SAndroid Build Coastguard Worker "sp_abt", "lr_und", "sp_und", "", "", "", "",
1005*9880d681SAndroid Build Coastguard Worker "lr_mon", "sp_mon", "elr_hyp", "sp_hyp"};
1006*9880d681SAndroid Build Coastguard Worker const char *Name = RegNames[SysM];
1007*9880d681SAndroid Build Coastguard Worker assert(Name[0] && "invalid banked register operand");
1008*9880d681SAndroid Build Coastguard Worker
1009*9880d681SAndroid Build Coastguard Worker O << Name;
1010*9880d681SAndroid Build Coastguard Worker }
1011*9880d681SAndroid Build Coastguard Worker
printPredicateOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1012*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
1013*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1014*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1015*9880d681SAndroid Build Coastguard Worker ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
1016*9880d681SAndroid Build Coastguard Worker // Handle the undefined 15 CC value here for printing so we don't abort().
1017*9880d681SAndroid Build Coastguard Worker if ((unsigned)CC == 15)
1018*9880d681SAndroid Build Coastguard Worker O << "<und>";
1019*9880d681SAndroid Build Coastguard Worker else if (CC != ARMCC::AL)
1020*9880d681SAndroid Build Coastguard Worker O << ARMCondCodeToString(CC);
1021*9880d681SAndroid Build Coastguard Worker }
1022*9880d681SAndroid Build Coastguard Worker
printMandatoryPredicateOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1023*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI,
1024*9880d681SAndroid Build Coastguard Worker unsigned OpNum,
1025*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1026*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1027*9880d681SAndroid Build Coastguard Worker ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
1028*9880d681SAndroid Build Coastguard Worker O << ARMCondCodeToString(CC);
1029*9880d681SAndroid Build Coastguard Worker }
1030*9880d681SAndroid Build Coastguard Worker
printSBitModifierOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1031*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum,
1032*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1033*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1034*9880d681SAndroid Build Coastguard Worker if (MI->getOperand(OpNum).getReg()) {
1035*9880d681SAndroid Build Coastguard Worker assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
1036*9880d681SAndroid Build Coastguard Worker "Expect ARM CPSR register!");
1037*9880d681SAndroid Build Coastguard Worker O << 's';
1038*9880d681SAndroid Build Coastguard Worker }
1039*9880d681SAndroid Build Coastguard Worker }
1040*9880d681SAndroid Build Coastguard Worker
printNoHashImmediate(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1041*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum,
1042*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1043*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1044*9880d681SAndroid Build Coastguard Worker O << MI->getOperand(OpNum).getImm();
1045*9880d681SAndroid Build Coastguard Worker }
1046*9880d681SAndroid Build Coastguard Worker
printPImmediate(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1047*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum,
1048*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1049*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1050*9880d681SAndroid Build Coastguard Worker O << "p" << MI->getOperand(OpNum).getImm();
1051*9880d681SAndroid Build Coastguard Worker }
1052*9880d681SAndroid Build Coastguard Worker
printCImmediate(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1053*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum,
1054*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1055*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1056*9880d681SAndroid Build Coastguard Worker O << "c" << MI->getOperand(OpNum).getImm();
1057*9880d681SAndroid Build Coastguard Worker }
1058*9880d681SAndroid Build Coastguard Worker
printCoprocOptionImm(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1059*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printCoprocOptionImm(const MCInst *MI, unsigned OpNum,
1060*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1061*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1062*9880d681SAndroid Build Coastguard Worker O << "{" << MI->getOperand(OpNum).getImm() << "}";
1063*9880d681SAndroid Build Coastguard Worker }
1064*9880d681SAndroid Build Coastguard Worker
printPCLabel(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1065*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
1066*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI, raw_ostream &O) {
1067*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
1068*9880d681SAndroid Build Coastguard Worker }
1069*9880d681SAndroid Build Coastguard Worker
1070*9880d681SAndroid Build Coastguard Worker template <unsigned scale>
printAdrLabelOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1071*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum,
1072*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1073*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1074*9880d681SAndroid Build Coastguard Worker const MCOperand &MO = MI->getOperand(OpNum);
1075*9880d681SAndroid Build Coastguard Worker
1076*9880d681SAndroid Build Coastguard Worker if (MO.isExpr()) {
1077*9880d681SAndroid Build Coastguard Worker MO.getExpr()->print(O, &MAI);
1078*9880d681SAndroid Build Coastguard Worker return;
1079*9880d681SAndroid Build Coastguard Worker }
1080*9880d681SAndroid Build Coastguard Worker
1081*9880d681SAndroid Build Coastguard Worker int32_t OffImm = (int32_t)MO.getImm() << scale;
1082*9880d681SAndroid Build Coastguard Worker
1083*9880d681SAndroid Build Coastguard Worker O << markup("<imm:");
1084*9880d681SAndroid Build Coastguard Worker if (OffImm == INT32_MIN)
1085*9880d681SAndroid Build Coastguard Worker O << "#-0";
1086*9880d681SAndroid Build Coastguard Worker else if (OffImm < 0)
1087*9880d681SAndroid Build Coastguard Worker O << "#-" << -OffImm;
1088*9880d681SAndroid Build Coastguard Worker else
1089*9880d681SAndroid Build Coastguard Worker O << "#" << OffImm;
1090*9880d681SAndroid Build Coastguard Worker O << markup(">");
1091*9880d681SAndroid Build Coastguard Worker }
1092*9880d681SAndroid Build Coastguard Worker
printThumbS4ImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1093*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
1094*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1095*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1096*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4)
1097*9880d681SAndroid Build Coastguard Worker << markup(">");
1098*9880d681SAndroid Build Coastguard Worker }
1099*9880d681SAndroid Build Coastguard Worker
printThumbSRImm(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1100*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum,
1101*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1102*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1103*9880d681SAndroid Build Coastguard Worker unsigned Imm = MI->getOperand(OpNum).getImm();
1104*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << "#" << formatImm((Imm == 0 ? 32 : Imm))
1105*9880d681SAndroid Build Coastguard Worker << markup(">");
1106*9880d681SAndroid Build Coastguard Worker }
1107*9880d681SAndroid Build Coastguard Worker
printThumbITMask(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1108*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum,
1109*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1110*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1111*9880d681SAndroid Build Coastguard Worker // (3 - the number of trailing zeros) is the number of then / else.
1112*9880d681SAndroid Build Coastguard Worker unsigned Mask = MI->getOperand(OpNum).getImm();
1113*9880d681SAndroid Build Coastguard Worker unsigned Firstcond = MI->getOperand(OpNum - 1).getImm();
1114*9880d681SAndroid Build Coastguard Worker unsigned CondBit0 = Firstcond & 1;
1115*9880d681SAndroid Build Coastguard Worker unsigned NumTZ = countTrailingZeros(Mask);
1116*9880d681SAndroid Build Coastguard Worker assert(NumTZ <= 3 && "Invalid IT mask!");
1117*9880d681SAndroid Build Coastguard Worker for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
1118*9880d681SAndroid Build Coastguard Worker bool T = ((Mask >> Pos) & 1) == CondBit0;
1119*9880d681SAndroid Build Coastguard Worker if (T)
1120*9880d681SAndroid Build Coastguard Worker O << 't';
1121*9880d681SAndroid Build Coastguard Worker else
1122*9880d681SAndroid Build Coastguard Worker O << 'e';
1123*9880d681SAndroid Build Coastguard Worker }
1124*9880d681SAndroid Build Coastguard Worker }
1125*9880d681SAndroid Build Coastguard Worker
printThumbAddrModeRROperand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)1126*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op,
1127*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1128*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1129*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(Op);
1130*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(Op + 1);
1131*9880d681SAndroid Build Coastguard Worker
1132*9880d681SAndroid Build Coastguard Worker if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
1133*9880d681SAndroid Build Coastguard Worker printOperand(MI, Op, STI, O);
1134*9880d681SAndroid Build Coastguard Worker return;
1135*9880d681SAndroid Build Coastguard Worker }
1136*9880d681SAndroid Build Coastguard Worker
1137*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
1138*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
1139*9880d681SAndroid Build Coastguard Worker if (unsigned RegNum = MO2.getReg()) {
1140*9880d681SAndroid Build Coastguard Worker O << ", ";
1141*9880d681SAndroid Build Coastguard Worker printRegName(O, RegNum);
1142*9880d681SAndroid Build Coastguard Worker }
1143*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
1144*9880d681SAndroid Build Coastguard Worker }
1145*9880d681SAndroid Build Coastguard Worker
printThumbAddrModeImm5SOperand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O,unsigned Scale)1146*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI,
1147*9880d681SAndroid Build Coastguard Worker unsigned Op,
1148*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1149*9880d681SAndroid Build Coastguard Worker raw_ostream &O,
1150*9880d681SAndroid Build Coastguard Worker unsigned Scale) {
1151*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(Op);
1152*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(Op + 1);
1153*9880d681SAndroid Build Coastguard Worker
1154*9880d681SAndroid Build Coastguard Worker if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
1155*9880d681SAndroid Build Coastguard Worker printOperand(MI, Op, STI, O);
1156*9880d681SAndroid Build Coastguard Worker return;
1157*9880d681SAndroid Build Coastguard Worker }
1158*9880d681SAndroid Build Coastguard Worker
1159*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
1160*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
1161*9880d681SAndroid Build Coastguard Worker if (unsigned ImmOffs = MO2.getImm()) {
1162*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:") << "#" << formatImm(ImmOffs * Scale)
1163*9880d681SAndroid Build Coastguard Worker << markup(">");
1164*9880d681SAndroid Build Coastguard Worker }
1165*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
1166*9880d681SAndroid Build Coastguard Worker }
1167*9880d681SAndroid Build Coastguard Worker
printThumbAddrModeImm5S1Operand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)1168*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI,
1169*9880d681SAndroid Build Coastguard Worker unsigned Op,
1170*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1171*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1172*9880d681SAndroid Build Coastguard Worker printThumbAddrModeImm5SOperand(MI, Op, STI, O, 1);
1173*9880d681SAndroid Build Coastguard Worker }
1174*9880d681SAndroid Build Coastguard Worker
printThumbAddrModeImm5S2Operand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)1175*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI,
1176*9880d681SAndroid Build Coastguard Worker unsigned Op,
1177*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1178*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1179*9880d681SAndroid Build Coastguard Worker printThumbAddrModeImm5SOperand(MI, Op, STI, O, 2);
1180*9880d681SAndroid Build Coastguard Worker }
1181*9880d681SAndroid Build Coastguard Worker
printThumbAddrModeImm5S4Operand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)1182*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI,
1183*9880d681SAndroid Build Coastguard Worker unsigned Op,
1184*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1185*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1186*9880d681SAndroid Build Coastguard Worker printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
1187*9880d681SAndroid Build Coastguard Worker }
1188*9880d681SAndroid Build Coastguard Worker
printThumbAddrModeSPOperand(const MCInst * MI,unsigned Op,const MCSubtargetInfo & STI,raw_ostream & O)1189*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op,
1190*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1191*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1192*9880d681SAndroid Build Coastguard Worker printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
1193*9880d681SAndroid Build Coastguard Worker }
1194*9880d681SAndroid Build Coastguard Worker
1195*9880d681SAndroid Build Coastguard Worker // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
1196*9880d681SAndroid Build Coastguard Worker // register with shift forms.
1197*9880d681SAndroid Build Coastguard Worker // REG 0 0 - e.g. R5
1198*9880d681SAndroid Build Coastguard Worker // REG IMM, SH_OPC - e.g. R5, LSL #3
printT2SOOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1199*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
1200*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1201*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1202*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
1203*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1204*9880d681SAndroid Build Coastguard Worker
1205*9880d681SAndroid Build Coastguard Worker unsigned Reg = MO1.getReg();
1206*9880d681SAndroid Build Coastguard Worker printRegName(O, Reg);
1207*9880d681SAndroid Build Coastguard Worker
1208*9880d681SAndroid Build Coastguard Worker // Print the shift opc.
1209*9880d681SAndroid Build Coastguard Worker assert(MO2.isImm() && "Not a valid t2_so_reg value!");
1210*9880d681SAndroid Build Coastguard Worker printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
1211*9880d681SAndroid Build Coastguard Worker ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
1212*9880d681SAndroid Build Coastguard Worker }
1213*9880d681SAndroid Build Coastguard Worker
1214*9880d681SAndroid Build Coastguard Worker template <bool AlwaysPrintImm0>
printAddrModeImm12Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1215*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum,
1216*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1217*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1218*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
1219*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1220*9880d681SAndroid Build Coastguard Worker
1221*9880d681SAndroid Build Coastguard Worker if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
1222*9880d681SAndroid Build Coastguard Worker printOperand(MI, OpNum, STI, O);
1223*9880d681SAndroid Build Coastguard Worker return;
1224*9880d681SAndroid Build Coastguard Worker }
1225*9880d681SAndroid Build Coastguard Worker
1226*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
1227*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
1228*9880d681SAndroid Build Coastguard Worker
1229*9880d681SAndroid Build Coastguard Worker int32_t OffImm = (int32_t)MO2.getImm();
1230*9880d681SAndroid Build Coastguard Worker bool isSub = OffImm < 0;
1231*9880d681SAndroid Build Coastguard Worker // Special value for #-0. All others are normal.
1232*9880d681SAndroid Build Coastguard Worker if (OffImm == INT32_MIN)
1233*9880d681SAndroid Build Coastguard Worker OffImm = 0;
1234*9880d681SAndroid Build Coastguard Worker if (isSub) {
1235*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
1236*9880d681SAndroid Build Coastguard Worker } else if (AlwaysPrintImm0 || OffImm > 0) {
1237*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
1238*9880d681SAndroid Build Coastguard Worker }
1239*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
1240*9880d681SAndroid Build Coastguard Worker }
1241*9880d681SAndroid Build Coastguard Worker
1242*9880d681SAndroid Build Coastguard Worker template <bool AlwaysPrintImm0>
printT2AddrModeImm8Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1243*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
1244*9880d681SAndroid Build Coastguard Worker unsigned OpNum,
1245*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1246*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1247*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
1248*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1249*9880d681SAndroid Build Coastguard Worker
1250*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
1251*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
1252*9880d681SAndroid Build Coastguard Worker
1253*9880d681SAndroid Build Coastguard Worker int32_t OffImm = (int32_t)MO2.getImm();
1254*9880d681SAndroid Build Coastguard Worker bool isSub = OffImm < 0;
1255*9880d681SAndroid Build Coastguard Worker // Don't print +0.
1256*9880d681SAndroid Build Coastguard Worker if (OffImm == INT32_MIN)
1257*9880d681SAndroid Build Coastguard Worker OffImm = 0;
1258*9880d681SAndroid Build Coastguard Worker if (isSub) {
1259*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
1260*9880d681SAndroid Build Coastguard Worker } else if (AlwaysPrintImm0 || OffImm > 0) {
1261*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
1262*9880d681SAndroid Build Coastguard Worker }
1263*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
1264*9880d681SAndroid Build Coastguard Worker }
1265*9880d681SAndroid Build Coastguard Worker
1266*9880d681SAndroid Build Coastguard Worker template <bool AlwaysPrintImm0>
printT2AddrModeImm8s4Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1267*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
1268*9880d681SAndroid Build Coastguard Worker unsigned OpNum,
1269*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1270*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1271*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
1272*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1273*9880d681SAndroid Build Coastguard Worker
1274*9880d681SAndroid Build Coastguard Worker if (!MO1.isReg()) { // For label symbolic references.
1275*9880d681SAndroid Build Coastguard Worker printOperand(MI, OpNum, STI, O);
1276*9880d681SAndroid Build Coastguard Worker return;
1277*9880d681SAndroid Build Coastguard Worker }
1278*9880d681SAndroid Build Coastguard Worker
1279*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
1280*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
1281*9880d681SAndroid Build Coastguard Worker
1282*9880d681SAndroid Build Coastguard Worker int32_t OffImm = (int32_t)MO2.getImm();
1283*9880d681SAndroid Build Coastguard Worker bool isSub = OffImm < 0;
1284*9880d681SAndroid Build Coastguard Worker
1285*9880d681SAndroid Build Coastguard Worker assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
1286*9880d681SAndroid Build Coastguard Worker
1287*9880d681SAndroid Build Coastguard Worker // Don't print +0.
1288*9880d681SAndroid Build Coastguard Worker if (OffImm == INT32_MIN)
1289*9880d681SAndroid Build Coastguard Worker OffImm = 0;
1290*9880d681SAndroid Build Coastguard Worker if (isSub) {
1291*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
1292*9880d681SAndroid Build Coastguard Worker } else if (AlwaysPrintImm0 || OffImm > 0) {
1293*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
1294*9880d681SAndroid Build Coastguard Worker }
1295*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
1296*9880d681SAndroid Build Coastguard Worker }
1297*9880d681SAndroid Build Coastguard Worker
printT2AddrModeImm0_1020s4Operand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1298*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand(
1299*9880d681SAndroid Build Coastguard Worker const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1300*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1301*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
1302*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1303*9880d681SAndroid Build Coastguard Worker
1304*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
1305*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
1306*9880d681SAndroid Build Coastguard Worker if (MO2.getImm()) {
1307*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:") << "#" << formatImm(MO2.getImm() * 4)
1308*9880d681SAndroid Build Coastguard Worker << markup(">");
1309*9880d681SAndroid Build Coastguard Worker }
1310*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
1311*9880d681SAndroid Build Coastguard Worker }
1312*9880d681SAndroid Build Coastguard Worker
printT2AddrModeImm8OffsetOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1313*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(
1314*9880d681SAndroid Build Coastguard Worker const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1315*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1316*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
1317*9880d681SAndroid Build Coastguard Worker int32_t OffImm = (int32_t)MO1.getImm();
1318*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:");
1319*9880d681SAndroid Build Coastguard Worker if (OffImm == INT32_MIN)
1320*9880d681SAndroid Build Coastguard Worker O << "#-0";
1321*9880d681SAndroid Build Coastguard Worker else if (OffImm < 0)
1322*9880d681SAndroid Build Coastguard Worker O << "#-" << -OffImm;
1323*9880d681SAndroid Build Coastguard Worker else
1324*9880d681SAndroid Build Coastguard Worker O << "#" << OffImm;
1325*9880d681SAndroid Build Coastguard Worker O << markup(">");
1326*9880d681SAndroid Build Coastguard Worker }
1327*9880d681SAndroid Build Coastguard Worker
printT2AddrModeImm8s4OffsetOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1328*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(
1329*9880d681SAndroid Build Coastguard Worker const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1330*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1331*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
1332*9880d681SAndroid Build Coastguard Worker int32_t OffImm = (int32_t)MO1.getImm();
1333*9880d681SAndroid Build Coastguard Worker
1334*9880d681SAndroid Build Coastguard Worker assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
1335*9880d681SAndroid Build Coastguard Worker
1336*9880d681SAndroid Build Coastguard Worker O << ", " << markup("<imm:");
1337*9880d681SAndroid Build Coastguard Worker if (OffImm == INT32_MIN)
1338*9880d681SAndroid Build Coastguard Worker O << "#-0";
1339*9880d681SAndroid Build Coastguard Worker else if (OffImm < 0)
1340*9880d681SAndroid Build Coastguard Worker O << "#-" << -OffImm;
1341*9880d681SAndroid Build Coastguard Worker else
1342*9880d681SAndroid Build Coastguard Worker O << "#" << OffImm;
1343*9880d681SAndroid Build Coastguard Worker O << markup(">");
1344*9880d681SAndroid Build Coastguard Worker }
1345*9880d681SAndroid Build Coastguard Worker
printT2AddrModeSoRegOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1346*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
1347*9880d681SAndroid Build Coastguard Worker unsigned OpNum,
1348*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1349*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1350*9880d681SAndroid Build Coastguard Worker const MCOperand &MO1 = MI->getOperand(OpNum);
1351*9880d681SAndroid Build Coastguard Worker const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1352*9880d681SAndroid Build Coastguard Worker const MCOperand &MO3 = MI->getOperand(OpNum + 2);
1353*9880d681SAndroid Build Coastguard Worker
1354*9880d681SAndroid Build Coastguard Worker O << markup("<mem:") << "[";
1355*9880d681SAndroid Build Coastguard Worker printRegName(O, MO1.getReg());
1356*9880d681SAndroid Build Coastguard Worker
1357*9880d681SAndroid Build Coastguard Worker assert(MO2.getReg() && "Invalid so_reg load / store address!");
1358*9880d681SAndroid Build Coastguard Worker O << ", ";
1359*9880d681SAndroid Build Coastguard Worker printRegName(O, MO2.getReg());
1360*9880d681SAndroid Build Coastguard Worker
1361*9880d681SAndroid Build Coastguard Worker unsigned ShAmt = MO3.getImm();
1362*9880d681SAndroid Build Coastguard Worker if (ShAmt) {
1363*9880d681SAndroid Build Coastguard Worker assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
1364*9880d681SAndroid Build Coastguard Worker O << ", lsl " << markup("<imm:") << "#" << ShAmt << markup(">");
1365*9880d681SAndroid Build Coastguard Worker }
1366*9880d681SAndroid Build Coastguard Worker O << "]" << markup(">");
1367*9880d681SAndroid Build Coastguard Worker }
1368*9880d681SAndroid Build Coastguard Worker
printFPImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1369*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
1370*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1371*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1372*9880d681SAndroid Build Coastguard Worker const MCOperand &MO = MI->getOperand(OpNum);
1373*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << '#' << ARM_AM::getFPImmFloat(MO.getImm())
1374*9880d681SAndroid Build Coastguard Worker << markup(">");
1375*9880d681SAndroid Build Coastguard Worker }
1376*9880d681SAndroid Build Coastguard Worker
printNEONModImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1377*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,
1378*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1379*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1380*9880d681SAndroid Build Coastguard Worker unsigned EncodedImm = MI->getOperand(OpNum).getImm();
1381*9880d681SAndroid Build Coastguard Worker unsigned EltBits;
1382*9880d681SAndroid Build Coastguard Worker uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
1383*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << "#0x";
1384*9880d681SAndroid Build Coastguard Worker O.write_hex(Val);
1385*9880d681SAndroid Build Coastguard Worker O << markup(">");
1386*9880d681SAndroid Build Coastguard Worker }
1387*9880d681SAndroid Build Coastguard Worker
printImmPlusOneOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1388*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum,
1389*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1390*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1391*9880d681SAndroid Build Coastguard Worker unsigned Imm = MI->getOperand(OpNum).getImm();
1392*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << "#" << formatImm(Imm + 1) << markup(">");
1393*9880d681SAndroid Build Coastguard Worker }
1394*9880d681SAndroid Build Coastguard Worker
printRotImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1395*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum,
1396*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1397*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1398*9880d681SAndroid Build Coastguard Worker unsigned Imm = MI->getOperand(OpNum).getImm();
1399*9880d681SAndroid Build Coastguard Worker if (Imm == 0)
1400*9880d681SAndroid Build Coastguard Worker return;
1401*9880d681SAndroid Build Coastguard Worker assert(Imm <= 3 && "illegal ror immediate!");
1402*9880d681SAndroid Build Coastguard Worker O << ", ror " << markup("<imm:") << "#" << 8 * Imm << markup(">");
1403*9880d681SAndroid Build Coastguard Worker }
1404*9880d681SAndroid Build Coastguard Worker
printModImmOperand(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1405*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printModImmOperand(const MCInst *MI, unsigned OpNum,
1406*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1407*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1408*9880d681SAndroid Build Coastguard Worker MCOperand Op = MI->getOperand(OpNum);
1409*9880d681SAndroid Build Coastguard Worker
1410*9880d681SAndroid Build Coastguard Worker // Support for fixups (MCFixup)
1411*9880d681SAndroid Build Coastguard Worker if (Op.isExpr())
1412*9880d681SAndroid Build Coastguard Worker return printOperand(MI, OpNum, STI, O);
1413*9880d681SAndroid Build Coastguard Worker
1414*9880d681SAndroid Build Coastguard Worker unsigned Bits = Op.getImm() & 0xFF;
1415*9880d681SAndroid Build Coastguard Worker unsigned Rot = (Op.getImm() & 0xF00) >> 7;
1416*9880d681SAndroid Build Coastguard Worker
1417*9880d681SAndroid Build Coastguard Worker bool PrintUnsigned = false;
1418*9880d681SAndroid Build Coastguard Worker switch (MI->getOpcode()) {
1419*9880d681SAndroid Build Coastguard Worker case ARM::MOVi:
1420*9880d681SAndroid Build Coastguard Worker // Movs to PC should be treated unsigned
1421*9880d681SAndroid Build Coastguard Worker PrintUnsigned = (MI->getOperand(OpNum - 1).getReg() == ARM::PC);
1422*9880d681SAndroid Build Coastguard Worker break;
1423*9880d681SAndroid Build Coastguard Worker case ARM::MSRi:
1424*9880d681SAndroid Build Coastguard Worker // Movs to special registers should be treated unsigned
1425*9880d681SAndroid Build Coastguard Worker PrintUnsigned = true;
1426*9880d681SAndroid Build Coastguard Worker break;
1427*9880d681SAndroid Build Coastguard Worker }
1428*9880d681SAndroid Build Coastguard Worker
1429*9880d681SAndroid Build Coastguard Worker int32_t Rotated = ARM_AM::rotr32(Bits, Rot);
1430*9880d681SAndroid Build Coastguard Worker if (ARM_AM::getSOImmVal(Rotated) == Op.getImm()) {
1431*9880d681SAndroid Build Coastguard Worker // #rot has the least possible value
1432*9880d681SAndroid Build Coastguard Worker O << "#" << markup("<imm:");
1433*9880d681SAndroid Build Coastguard Worker if (PrintUnsigned)
1434*9880d681SAndroid Build Coastguard Worker O << static_cast<uint32_t>(Rotated);
1435*9880d681SAndroid Build Coastguard Worker else
1436*9880d681SAndroid Build Coastguard Worker O << Rotated;
1437*9880d681SAndroid Build Coastguard Worker O << markup(">");
1438*9880d681SAndroid Build Coastguard Worker return;
1439*9880d681SAndroid Build Coastguard Worker }
1440*9880d681SAndroid Build Coastguard Worker
1441*9880d681SAndroid Build Coastguard Worker // Explicit #bits, #rot implied
1442*9880d681SAndroid Build Coastguard Worker O << "#" << markup("<imm:") << Bits << markup(">") << ", #" << markup("<imm:")
1443*9880d681SAndroid Build Coastguard Worker << Rot << markup(">");
1444*9880d681SAndroid Build Coastguard Worker }
1445*9880d681SAndroid Build Coastguard Worker
printFBits16(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1446*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum,
1447*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI, raw_ostream &O) {
1448*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << "#" << 16 - MI->getOperand(OpNum).getImm()
1449*9880d681SAndroid Build Coastguard Worker << markup(">");
1450*9880d681SAndroid Build Coastguard Worker }
1451*9880d681SAndroid Build Coastguard Worker
printFBits32(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1452*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum,
1453*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI, raw_ostream &O) {
1454*9880d681SAndroid Build Coastguard Worker O << markup("<imm:") << "#" << 32 - MI->getOperand(OpNum).getImm()
1455*9880d681SAndroid Build Coastguard Worker << markup(">");
1456*9880d681SAndroid Build Coastguard Worker }
1457*9880d681SAndroid Build Coastguard Worker
printVectorIndex(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1458*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
1459*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1460*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1461*9880d681SAndroid Build Coastguard Worker O << "[" << MI->getOperand(OpNum).getImm() << "]";
1462*9880d681SAndroid Build Coastguard Worker }
1463*9880d681SAndroid Build Coastguard Worker
printVectorListOne(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1464*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum,
1465*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1466*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1467*9880d681SAndroid Build Coastguard Worker O << "{";
1468*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg());
1469*9880d681SAndroid Build Coastguard Worker O << "}";
1470*9880d681SAndroid Build Coastguard Worker }
1471*9880d681SAndroid Build Coastguard Worker
printVectorListTwo(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1472*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum,
1473*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1474*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1475*9880d681SAndroid Build Coastguard Worker unsigned Reg = MI->getOperand(OpNum).getReg();
1476*9880d681SAndroid Build Coastguard Worker unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1477*9880d681SAndroid Build Coastguard Worker unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
1478*9880d681SAndroid Build Coastguard Worker O << "{";
1479*9880d681SAndroid Build Coastguard Worker printRegName(O, Reg0);
1480*9880d681SAndroid Build Coastguard Worker O << ", ";
1481*9880d681SAndroid Build Coastguard Worker printRegName(O, Reg1);
1482*9880d681SAndroid Build Coastguard Worker O << "}";
1483*9880d681SAndroid Build Coastguard Worker }
1484*9880d681SAndroid Build Coastguard Worker
printVectorListTwoSpaced(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1485*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum,
1486*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1487*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1488*9880d681SAndroid Build Coastguard Worker unsigned Reg = MI->getOperand(OpNum).getReg();
1489*9880d681SAndroid Build Coastguard Worker unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1490*9880d681SAndroid Build Coastguard Worker unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
1491*9880d681SAndroid Build Coastguard Worker O << "{";
1492*9880d681SAndroid Build Coastguard Worker printRegName(O, Reg0);
1493*9880d681SAndroid Build Coastguard Worker O << ", ";
1494*9880d681SAndroid Build Coastguard Worker printRegName(O, Reg1);
1495*9880d681SAndroid Build Coastguard Worker O << "}";
1496*9880d681SAndroid Build Coastguard Worker }
1497*9880d681SAndroid Build Coastguard Worker
printVectorListThree(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1498*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum,
1499*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1500*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1501*9880d681SAndroid Build Coastguard Worker // Normally, it's not safe to use register enum values directly with
1502*9880d681SAndroid Build Coastguard Worker // addition to get the next register, but for VFP registers, the
1503*9880d681SAndroid Build Coastguard Worker // sort order is guaranteed because they're all of the form D<n>.
1504*9880d681SAndroid Build Coastguard Worker O << "{";
1505*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg());
1506*9880d681SAndroid Build Coastguard Worker O << ", ";
1507*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1508*9880d681SAndroid Build Coastguard Worker O << ", ";
1509*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1510*9880d681SAndroid Build Coastguard Worker O << "}";
1511*9880d681SAndroid Build Coastguard Worker }
1512*9880d681SAndroid Build Coastguard Worker
printVectorListFour(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1513*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum,
1514*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1515*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1516*9880d681SAndroid Build Coastguard Worker // Normally, it's not safe to use register enum values directly with
1517*9880d681SAndroid Build Coastguard Worker // addition to get the next register, but for VFP registers, the
1518*9880d681SAndroid Build Coastguard Worker // sort order is guaranteed because they're all of the form D<n>.
1519*9880d681SAndroid Build Coastguard Worker O << "{";
1520*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg());
1521*9880d681SAndroid Build Coastguard Worker O << ", ";
1522*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1523*9880d681SAndroid Build Coastguard Worker O << ", ";
1524*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1525*9880d681SAndroid Build Coastguard Worker O << ", ";
1526*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 3);
1527*9880d681SAndroid Build Coastguard Worker O << "}";
1528*9880d681SAndroid Build Coastguard Worker }
1529*9880d681SAndroid Build Coastguard Worker
printVectorListOneAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1530*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI,
1531*9880d681SAndroid Build Coastguard Worker unsigned OpNum,
1532*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1533*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1534*9880d681SAndroid Build Coastguard Worker O << "{";
1535*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg());
1536*9880d681SAndroid Build Coastguard Worker O << "[]}";
1537*9880d681SAndroid Build Coastguard Worker }
1538*9880d681SAndroid Build Coastguard Worker
printVectorListTwoAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1539*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI,
1540*9880d681SAndroid Build Coastguard Worker unsigned OpNum,
1541*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1542*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1543*9880d681SAndroid Build Coastguard Worker unsigned Reg = MI->getOperand(OpNum).getReg();
1544*9880d681SAndroid Build Coastguard Worker unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1545*9880d681SAndroid Build Coastguard Worker unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
1546*9880d681SAndroid Build Coastguard Worker O << "{";
1547*9880d681SAndroid Build Coastguard Worker printRegName(O, Reg0);
1548*9880d681SAndroid Build Coastguard Worker O << "[], ";
1549*9880d681SAndroid Build Coastguard Worker printRegName(O, Reg1);
1550*9880d681SAndroid Build Coastguard Worker O << "[]}";
1551*9880d681SAndroid Build Coastguard Worker }
1552*9880d681SAndroid Build Coastguard Worker
printVectorListThreeAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1553*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListThreeAllLanes(const MCInst *MI,
1554*9880d681SAndroid Build Coastguard Worker unsigned OpNum,
1555*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1556*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1557*9880d681SAndroid Build Coastguard Worker // Normally, it's not safe to use register enum values directly with
1558*9880d681SAndroid Build Coastguard Worker // addition to get the next register, but for VFP registers, the
1559*9880d681SAndroid Build Coastguard Worker // sort order is guaranteed because they're all of the form D<n>.
1560*9880d681SAndroid Build Coastguard Worker O << "{";
1561*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg());
1562*9880d681SAndroid Build Coastguard Worker O << "[], ";
1563*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1564*9880d681SAndroid Build Coastguard Worker O << "[], ";
1565*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1566*9880d681SAndroid Build Coastguard Worker O << "[]}";
1567*9880d681SAndroid Build Coastguard Worker }
1568*9880d681SAndroid Build Coastguard Worker
printVectorListFourAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1569*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI,
1570*9880d681SAndroid Build Coastguard Worker unsigned OpNum,
1571*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1572*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1573*9880d681SAndroid Build Coastguard Worker // Normally, it's not safe to use register enum values directly with
1574*9880d681SAndroid Build Coastguard Worker // addition to get the next register, but for VFP registers, the
1575*9880d681SAndroid Build Coastguard Worker // sort order is guaranteed because they're all of the form D<n>.
1576*9880d681SAndroid Build Coastguard Worker O << "{";
1577*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg());
1578*9880d681SAndroid Build Coastguard Worker O << "[], ";
1579*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1580*9880d681SAndroid Build Coastguard Worker O << "[], ";
1581*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1582*9880d681SAndroid Build Coastguard Worker O << "[], ";
1583*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 3);
1584*9880d681SAndroid Build Coastguard Worker O << "[]}";
1585*9880d681SAndroid Build Coastguard Worker }
1586*9880d681SAndroid Build Coastguard Worker
printVectorListTwoSpacedAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1587*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListTwoSpacedAllLanes(
1588*9880d681SAndroid Build Coastguard Worker const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1589*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1590*9880d681SAndroid Build Coastguard Worker unsigned Reg = MI->getOperand(OpNum).getReg();
1591*9880d681SAndroid Build Coastguard Worker unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1592*9880d681SAndroid Build Coastguard Worker unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
1593*9880d681SAndroid Build Coastguard Worker O << "{";
1594*9880d681SAndroid Build Coastguard Worker printRegName(O, Reg0);
1595*9880d681SAndroid Build Coastguard Worker O << "[], ";
1596*9880d681SAndroid Build Coastguard Worker printRegName(O, Reg1);
1597*9880d681SAndroid Build Coastguard Worker O << "[]}";
1598*9880d681SAndroid Build Coastguard Worker }
1599*9880d681SAndroid Build Coastguard Worker
printVectorListThreeSpacedAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1600*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListThreeSpacedAllLanes(
1601*9880d681SAndroid Build Coastguard Worker const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1602*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1603*9880d681SAndroid Build Coastguard Worker // Normally, it's not safe to use register enum values directly with
1604*9880d681SAndroid Build Coastguard Worker // addition to get the next register, but for VFP registers, the
1605*9880d681SAndroid Build Coastguard Worker // sort order is guaranteed because they're all of the form D<n>.
1606*9880d681SAndroid Build Coastguard Worker O << "{";
1607*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg());
1608*9880d681SAndroid Build Coastguard Worker O << "[], ";
1609*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1610*9880d681SAndroid Build Coastguard Worker O << "[], ";
1611*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1612*9880d681SAndroid Build Coastguard Worker O << "[]}";
1613*9880d681SAndroid Build Coastguard Worker }
1614*9880d681SAndroid Build Coastguard Worker
printVectorListFourSpacedAllLanes(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1615*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListFourSpacedAllLanes(
1616*9880d681SAndroid Build Coastguard Worker const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1617*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1618*9880d681SAndroid Build Coastguard Worker // Normally, it's not safe to use register enum values directly with
1619*9880d681SAndroid Build Coastguard Worker // addition to get the next register, but for VFP registers, the
1620*9880d681SAndroid Build Coastguard Worker // sort order is guaranteed because they're all of the form D<n>.
1621*9880d681SAndroid Build Coastguard Worker O << "{";
1622*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg());
1623*9880d681SAndroid Build Coastguard Worker O << "[], ";
1624*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1625*9880d681SAndroid Build Coastguard Worker O << "[], ";
1626*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1627*9880d681SAndroid Build Coastguard Worker O << "[], ";
1628*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 6);
1629*9880d681SAndroid Build Coastguard Worker O << "[]}";
1630*9880d681SAndroid Build Coastguard Worker }
1631*9880d681SAndroid Build Coastguard Worker
printVectorListThreeSpaced(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1632*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI,
1633*9880d681SAndroid Build Coastguard Worker unsigned OpNum,
1634*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1635*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1636*9880d681SAndroid Build Coastguard Worker // Normally, it's not safe to use register enum values directly with
1637*9880d681SAndroid Build Coastguard Worker // addition to get the next register, but for VFP registers, the
1638*9880d681SAndroid Build Coastguard Worker // sort order is guaranteed because they're all of the form D<n>.
1639*9880d681SAndroid Build Coastguard Worker O << "{";
1640*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg());
1641*9880d681SAndroid Build Coastguard Worker O << ", ";
1642*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1643*9880d681SAndroid Build Coastguard Worker O << ", ";
1644*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1645*9880d681SAndroid Build Coastguard Worker O << "}";
1646*9880d681SAndroid Build Coastguard Worker }
1647*9880d681SAndroid Build Coastguard Worker
printVectorListFourSpaced(const MCInst * MI,unsigned OpNum,const MCSubtargetInfo & STI,raw_ostream & O)1648*9880d681SAndroid Build Coastguard Worker void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI, unsigned OpNum,
1649*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
1650*9880d681SAndroid Build Coastguard Worker raw_ostream &O) {
1651*9880d681SAndroid Build Coastguard Worker // Normally, it's not safe to use register enum values directly with
1652*9880d681SAndroid Build Coastguard Worker // addition to get the next register, but for VFP registers, the
1653*9880d681SAndroid Build Coastguard Worker // sort order is guaranteed because they're all of the form D<n>.
1654*9880d681SAndroid Build Coastguard Worker O << "{";
1655*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg());
1656*9880d681SAndroid Build Coastguard Worker O << ", ";
1657*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1658*9880d681SAndroid Build Coastguard Worker O << ", ";
1659*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1660*9880d681SAndroid Build Coastguard Worker O << ", ";
1661*9880d681SAndroid Build Coastguard Worker printRegName(O, MI->getOperand(OpNum).getReg() + 6);
1662*9880d681SAndroid Build Coastguard Worker O << "}";
1663*9880d681SAndroid Build Coastguard Worker }
1664