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