1 //===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This class prints an ARM MCInst to a .s file.
12 //===----------------------------------------------------------------------===//
14 #include "ARMInstPrinter.h"
15 #include "MCTargetDesc/ARMAddressingModes.h"
16 #include "MCTargetDesc/ARMBaseInfo.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/MC/SubtargetFeature.h"
24 #include "llvm/Support/Casting.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/Support/MathExtras.h"
27 #include "llvm/Support/raw_ostream.h"
34 #define DEBUG_TYPE "asm-printer"
36 #define PRINT_ALIAS_INSTR
37 #include "ARMGenAsmWriter.inc"
39 /// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
41 /// getSORegOffset returns an integer from 0-31, representing '32' as 0.
42 static unsigned translateShiftImm(unsigned imm) {
43 // lsr #32 and asr #32 exist, but should be encoded as a 0.
44 assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
51 /// Prints the shift value with an immediate value.
52 static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc,
53 unsigned ShImm, bool UseMarkup) {
54 if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm))
58 assert(!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0");
59 O << getShiftOpcStr(ShOpc);
61 if (ShOpc != ARM_AM::rrx) {
65 O << "#" << translateShiftImm(ShImm);
71 ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
72 const MCRegisterInfo &MRI)
73 : MCInstPrinter(MAI, MII, MRI) {}
75 void ARMInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
76 OS << markup("<reg:") << getRegisterName(RegNo) << markup(">");
79 void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
80 StringRef Annot, const MCSubtargetInfo &STI) {
81 unsigned Opcode = MI->getOpcode();
84 // Check for MOVs and print canonical forms, instead.
86 // FIXME: Thumb variants?
87 const MCOperand &Dst = MI->getOperand(0);
88 const MCOperand &MO1 = MI->getOperand(1);
89 const MCOperand &MO2 = MI->getOperand(2);
90 const MCOperand &MO3 = MI->getOperand(3);
92 O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
93 printSBitModifierOperand(MI, 6, STI, O);
94 printPredicateOperand(MI, 4, STI, O);
97 printRegName(O, Dst.getReg());
99 printRegName(O, MO1.getReg());
102 printRegName(O, MO2.getReg());
103 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
104 printAnnotation(O, Annot);
109 // FIXME: Thumb variants?
110 const MCOperand &Dst = MI->getOperand(0);
111 const MCOperand &MO1 = MI->getOperand(1);
112 const MCOperand &MO2 = MI->getOperand(2);
114 O << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO2.getImm()));
115 printSBitModifierOperand(MI, 5, STI, O);
116 printPredicateOperand(MI, 3, STI, O);
119 printRegName(O, Dst.getReg());
121 printRegName(O, MO1.getReg());
123 if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx) {
124 printAnnotation(O, Annot);
128 O << ", " << markup("<imm:") << "#"
129 << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm())) << markup(">");
130 printAnnotation(O, Annot);
136 case ARM::t2STMDB_UPD:
137 if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
138 // Should only print PUSH if there are at least two registers in the list.
140 printPredicateOperand(MI, 2, STI, O);
141 if (Opcode == ARM::t2STMDB_UPD)
144 printRegisterList(MI, 4, STI, O);
145 printAnnotation(O, Annot);
150 case ARM::STR_PRE_IMM:
151 if (MI->getOperand(2).getReg() == ARM::SP &&
152 MI->getOperand(3).getImm() == -4) {
154 printPredicateOperand(MI, 4, STI, O);
156 printRegName(O, MI->getOperand(1).getReg());
158 printAnnotation(O, Annot);
165 case ARM::t2LDMIA_UPD:
166 if (MI->getOperand(0).getReg() == ARM::SP && MI->getNumOperands() > 5) {
167 // Should only print POP if there are at least two registers in the list.
169 printPredicateOperand(MI, 2, STI, O);
170 if (Opcode == ARM::t2LDMIA_UPD)
173 printRegisterList(MI, 4, STI, O);
174 printAnnotation(O, Annot);
179 case ARM::LDR_POST_IMM:
180 if (MI->getOperand(2).getReg() == ARM::SP &&
181 MI->getOperand(4).getImm() == 4) {
183 printPredicateOperand(MI, 5, STI, O);
185 printRegName(O, MI->getOperand(0).getReg());
187 printAnnotation(O, Annot);
193 case ARM::VSTMSDB_UPD:
194 case ARM::VSTMDDB_UPD:
195 if (MI->getOperand(0).getReg() == ARM::SP) {
196 O << '\t' << "vpush";
197 printPredicateOperand(MI, 2, STI, O);
199 printRegisterList(MI, 4, STI, O);
200 printAnnotation(O, Annot);
206 case ARM::VLDMSIA_UPD:
207 case ARM::VLDMDIA_UPD:
208 if (MI->getOperand(0).getReg() == ARM::SP) {
210 printPredicateOperand(MI, 2, STI, O);
212 printRegisterList(MI, 4, STI, O);
213 printAnnotation(O, Annot);
219 bool Writeback = true;
220 unsigned BaseReg = MI->getOperand(0).getReg();
221 for (unsigned i = 3; i < MI->getNumOperands(); ++i) {
222 if (MI->getOperand(i).getReg() == BaseReg)
228 printPredicateOperand(MI, 1, STI, O);
230 printRegName(O, BaseReg);
234 printRegisterList(MI, 3, STI, O);
235 printAnnotation(O, Annot);
239 // Combine 2 GPRs from disassember into a GPRPair to match with instr def.
240 // ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
241 // a single GPRPair reg operand is used in the .td file to replace the two
242 // GPRs. However, when decoding them, the two GRPs cannot be automatically
243 // expressed as a GPRPair, so we have to manually merge them.
244 // FIXME: We would really like to be able to tablegen'erate this.
249 const MCRegisterClass &MRC = MRI.getRegClass(ARM::GPRRegClassID);
250 bool isStore = Opcode == ARM::STREXD || Opcode == ARM::STLEXD;
251 unsigned Reg = MI->getOperand(isStore ? 1 : 0).getReg();
252 if (MRC.contains(Reg)) {
255 NewMI.setOpcode(Opcode);
258 NewMI.addOperand(MI->getOperand(0));
259 NewReg = MCOperand::createReg(MRI.getMatchingSuperReg(
260 Reg, ARM::gsub_0, &MRI.getRegClass(ARM::GPRPairRegClassID)));
261 NewMI.addOperand(NewReg);
263 // Copy the rest operands into NewMI.
264 for (unsigned i = isStore ? 3 : 2; i < MI->getNumOperands(); ++i)
265 NewMI.addOperand(MI->getOperand(i));
266 printInstruction(&NewMI, STI, O);
273 if (!printAliasInstr(MI, STI, O))
274 printInstruction(MI, STI, O);
276 printAnnotation(O, Annot);
279 void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
280 const MCSubtargetInfo &STI, raw_ostream &O) {
281 const MCOperand &Op = MI->getOperand(OpNo);
283 unsigned Reg = Op.getReg();
284 printRegName(O, Reg);
285 } else if (Op.isImm()) {
286 O << markup("<imm:") << '#' << formatImm(Op.getImm()) << markup(">");
288 assert(Op.isExpr() && "unknown operand kind in printOperand");
289 const MCExpr *Expr = Op.getExpr();
290 switch (Expr->getKind()) {
293 Expr->print(O, &MAI);
295 case MCExpr::Constant: {
296 // If a symbolic branch target was added as a constant expression then
297 // print that address in hex. And only print 32 unsigned bits for the
299 const MCConstantExpr *Constant = cast<MCConstantExpr>(Expr);
300 int64_t TargetAddress;
301 if (!Constant->evaluateAsAbsolute(TargetAddress)) {
303 Expr->print(O, &MAI);
306 O.write_hex(static_cast<uint32_t>(TargetAddress));
311 // FIXME: Should we always treat this as if it is a constant literal and
312 // prefix it with '#'?
313 Expr->print(O, &MAI);
319 void ARMInstPrinter::printThumbLdrLabelOperand(const MCInst *MI, unsigned OpNum,
320 const MCSubtargetInfo &STI,
322 const MCOperand &MO1 = MI->getOperand(OpNum);
324 MO1.getExpr()->print(O, &MAI);
328 O << markup("<mem:") << "[pc, ";
330 int32_t OffImm = (int32_t)MO1.getImm();
331 bool isSub = OffImm < 0;
333 // Special value for #-0. All others are normal.
334 if (OffImm == INT32_MIN)
337 O << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
339 O << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
341 O << "]" << markup(">");
344 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
345 // "Addressing Mode 1 - Data-processing operands" forms. This includes:
347 // REG REG 0,SH_OPC - e.g. R5, ROR R3
348 // REG 0 IMM,SH_OPC - e.g. R5, LSL #3
349 void ARMInstPrinter::printSORegRegOperand(const MCInst *MI, unsigned OpNum,
350 const MCSubtargetInfo &STI,
352 const MCOperand &MO1 = MI->getOperand(OpNum);
353 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
354 const MCOperand &MO3 = MI->getOperand(OpNum + 2);
356 printRegName(O, MO1.getReg());
358 // Print the shift opc.
359 ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
360 O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
361 if (ShOpc == ARM_AM::rrx)
365 printRegName(O, MO2.getReg());
366 assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
369 void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum,
370 const MCSubtargetInfo &STI,
372 const MCOperand &MO1 = MI->getOperand(OpNum);
373 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
375 printRegName(O, MO1.getReg());
377 // Print the shift opc.
378 printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
379 ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
382 //===--------------------------------------------------------------------===//
383 // Addressing Mode #2
384 //===--------------------------------------------------------------------===//
386 void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
387 const MCSubtargetInfo &STI,
389 const MCOperand &MO1 = MI->getOperand(Op);
390 const MCOperand &MO2 = MI->getOperand(Op + 1);
391 const MCOperand &MO3 = MI->getOperand(Op + 2);
393 O << markup("<mem:") << "[";
394 printRegName(O, MO1.getReg());
397 if (ARM_AM::getAM2Offset(MO3.getImm())) { // Don't print +0.
398 O << ", " << markup("<imm:") << "#"
399 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
400 << ARM_AM::getAM2Offset(MO3.getImm()) << markup(">");
402 O << "]" << markup(">");
407 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()));
408 printRegName(O, MO2.getReg());
410 printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO3.getImm()),
411 ARM_AM::getAM2Offset(MO3.getImm()), UseMarkup);
412 O << "]" << markup(">");
415 void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op,
416 const MCSubtargetInfo &STI,
418 const MCOperand &MO1 = MI->getOperand(Op);
419 const MCOperand &MO2 = MI->getOperand(Op + 1);
420 O << markup("<mem:") << "[";
421 printRegName(O, MO1.getReg());
423 printRegName(O, MO2.getReg());
424 O << "]" << markup(">");
427 void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op,
428 const MCSubtargetInfo &STI,
430 const MCOperand &MO1 = MI->getOperand(Op);
431 const MCOperand &MO2 = MI->getOperand(Op + 1);
432 O << markup("<mem:") << "[";
433 printRegName(O, MO1.getReg());
435 printRegName(O, MO2.getReg());
436 O << ", lsl " << markup("<imm:") << "#1" << markup(">") << "]" << markup(">");
439 void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
440 const MCSubtargetInfo &STI,
442 const MCOperand &MO1 = MI->getOperand(Op);
444 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
445 printOperand(MI, Op, STI, O);
450 const MCOperand &MO3 = MI->getOperand(Op + 2);
451 unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
452 assert(IdxMode != ARMII::IndexModePost && "Should be pre or offset index op");
455 printAM2PreOrOffsetIndexOp(MI, Op, STI, O);
458 void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
460 const MCSubtargetInfo &STI,
462 const MCOperand &MO1 = MI->getOperand(OpNum);
463 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
466 unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
467 O << markup("<imm:") << '#'
468 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm())) << ImmOffs
473 O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()));
474 printRegName(O, MO1.getReg());
476 printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO2.getImm()),
477 ARM_AM::getAM2Offset(MO2.getImm()), UseMarkup);
480 //===--------------------------------------------------------------------===//
481 // Addressing Mode #3
482 //===--------------------------------------------------------------------===//
484 void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
486 bool AlwaysPrintImm0) {
487 const MCOperand &MO1 = MI->getOperand(Op);
488 const MCOperand &MO2 = MI->getOperand(Op + 1);
489 const MCOperand &MO3 = MI->getOperand(Op + 2);
491 O << markup("<mem:") << '[';
492 printRegName(O, MO1.getReg());
495 O << ", " << getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()));
496 printRegName(O, MO2.getReg());
497 O << ']' << markup(">");
501 // If the op is sub we have to print the immediate even if it is 0
502 unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm());
503 ARM_AM::AddrOpc op = ARM_AM::getAM3Op(MO3.getImm());
505 if (AlwaysPrintImm0 || ImmOffs || (op == ARM_AM::sub)) {
506 O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(op) << ImmOffs
509 O << ']' << markup(">");
512 template <bool AlwaysPrintImm0>
513 void ARMInstPrinter::printAddrMode3Operand(const MCInst *MI, unsigned Op,
514 const MCSubtargetInfo &STI,
516 const MCOperand &MO1 = MI->getOperand(Op);
517 if (!MO1.isReg()) { // For label symbolic references.
518 printOperand(MI, Op, STI, O);
522 assert(ARM_AM::getAM3IdxMode(MI->getOperand(Op + 2).getImm()) !=
523 ARMII::IndexModePost &&
524 "unexpected idxmode");
525 printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0);
528 void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst *MI,
530 const MCSubtargetInfo &STI,
532 const MCOperand &MO1 = MI->getOperand(OpNum);
533 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
536 O << getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()));
537 printRegName(O, MO1.getReg());
541 unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
542 O << markup("<imm:") << '#'
543 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm())) << ImmOffs
547 void ARMInstPrinter::printPostIdxImm8Operand(const MCInst *MI, unsigned OpNum,
548 const MCSubtargetInfo &STI,
550 const MCOperand &MO = MI->getOperand(OpNum);
551 unsigned Imm = MO.getImm();
552 O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << (Imm & 0xff)
556 void ARMInstPrinter::printPostIdxRegOperand(const MCInst *MI, unsigned OpNum,
557 const MCSubtargetInfo &STI,
559 const MCOperand &MO1 = MI->getOperand(OpNum);
560 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
562 O << (MO2.getImm() ? "" : "-");
563 printRegName(O, MO1.getReg());
566 void ARMInstPrinter::printPostIdxImm8s4Operand(const MCInst *MI, unsigned OpNum,
567 const MCSubtargetInfo &STI,
569 const MCOperand &MO = MI->getOperand(OpNum);
570 unsigned Imm = MO.getImm();
571 O << markup("<imm:") << '#' << ((Imm & 256) ? "" : "-") << ((Imm & 0xff) << 2)
575 void ARMInstPrinter::printLdStmModeOperand(const MCInst *MI, unsigned OpNum,
576 const MCSubtargetInfo &STI,
578 ARM_AM::AMSubMode Mode =
579 ARM_AM::getAM4SubMode(MI->getOperand(OpNum).getImm());
580 O << ARM_AM::getAMSubModeStr(Mode);
583 template <bool AlwaysPrintImm0>
584 void ARMInstPrinter::printAddrMode5Operand(const MCInst *MI, unsigned OpNum,
585 const MCSubtargetInfo &STI,
587 const MCOperand &MO1 = MI->getOperand(OpNum);
588 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
590 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
591 printOperand(MI, OpNum, STI, O);
595 O << markup("<mem:") << "[";
596 printRegName(O, MO1.getReg());
598 unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm());
599 ARM_AM::AddrOpc Op = ARM_AM::getAM5Op(MO2.getImm());
600 if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
601 O << ", " << markup("<imm:") << "#" << ARM_AM::getAddrOpcStr(Op)
602 << ImmOffs * 4 << markup(">");
604 O << "]" << markup(">");
607 template <bool AlwaysPrintImm0>
608 void ARMInstPrinter::printAddrMode5FP16Operand(const MCInst *MI, unsigned OpNum,
609 const MCSubtargetInfo &STI,
611 const MCOperand &MO1 = MI->getOperand(OpNum);
612 const MCOperand &MO2 = MI->getOperand(OpNum+1);
614 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
615 printOperand(MI, OpNum, STI, O);
619 O << markup("<mem:") << "[";
620 printRegName(O, MO1.getReg());
622 unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm());
623 unsigned Op = ARM_AM::getAM5FP16Op(MO2.getImm());
624 if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM::sub) {
628 << ARM_AM::getAddrOpcStr(ARM_AM::getAM5FP16Op(MO2.getImm()))
632 O << "]" << markup(">");
635 void ARMInstPrinter::printAddrMode6Operand(const MCInst *MI, unsigned OpNum,
636 const MCSubtargetInfo &STI,
638 const MCOperand &MO1 = MI->getOperand(OpNum);
639 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
641 O << markup("<mem:") << "[";
642 printRegName(O, MO1.getReg());
644 O << ":" << (MO2.getImm() << 3);
646 O << "]" << markup(">");
649 void ARMInstPrinter::printAddrMode7Operand(const MCInst *MI, unsigned OpNum,
650 const MCSubtargetInfo &STI,
652 const MCOperand &MO1 = MI->getOperand(OpNum);
653 O << markup("<mem:") << "[";
654 printRegName(O, MO1.getReg());
655 O << "]" << markup(">");
658 void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst *MI,
660 const MCSubtargetInfo &STI,
662 const MCOperand &MO = MI->getOperand(OpNum);
663 if (MO.getReg() == 0)
667 printRegName(O, MO.getReg());
671 void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,
673 const MCSubtargetInfo &STI,
675 const MCOperand &MO = MI->getOperand(OpNum);
676 uint32_t v = ~MO.getImm();
677 int32_t lsb = countTrailingZeros(v);
678 int32_t width = (32 - countLeadingZeros(v)) - lsb;
679 assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
680 O << markup("<imm:") << '#' << lsb << markup(">") << ", " << markup("<imm:")
681 << '#' << width << markup(">");
684 void ARMInstPrinter::printMemBOption(const MCInst *MI, unsigned OpNum,
685 const MCSubtargetInfo &STI,
687 unsigned val = MI->getOperand(OpNum).getImm();
688 O << ARM_MB::MemBOptToString(val, STI.getFeatureBits()[ARM::HasV8Ops]);
691 void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
692 const MCSubtargetInfo &STI,
694 unsigned val = MI->getOperand(OpNum).getImm();
695 O << ARM_ISB::InstSyncBOptToString(val);
698 void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
699 const MCSubtargetInfo &STI,
701 unsigned ShiftOp = MI->getOperand(OpNum).getImm();
702 bool isASR = (ShiftOp & (1 << 5)) != 0;
703 unsigned Amt = ShiftOp & 0x1f;
705 O << ", asr " << markup("<imm:") << "#" << (Amt == 0 ? 32 : Amt)
708 O << ", lsl " << markup("<imm:") << "#" << Amt << markup(">");
712 void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum,
713 const MCSubtargetInfo &STI,
715 unsigned Imm = MI->getOperand(OpNum).getImm();
718 assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
719 O << ", lsl " << markup("<imm:") << "#" << Imm << markup(">");
722 void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum,
723 const MCSubtargetInfo &STI,
725 unsigned Imm = MI->getOperand(OpNum).getImm();
726 // A shift amount of 32 is encoded as 0.
729 assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
730 O << ", asr " << markup("<imm:") << "#" << Imm << markup(">");
733 void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
734 const MCSubtargetInfo &STI,
736 assert(std::is_sorted(MI->begin() + OpNum, MI->end(),
737 [&](const MCOperand &LHS, const MCOperand &RHS) {
738 return MRI.getEncodingValue(LHS.getReg()) <
739 MRI.getEncodingValue(RHS.getReg());
743 for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
746 printRegName(O, MI->getOperand(i).getReg());
751 void ARMInstPrinter::printGPRPairOperand(const MCInst *MI, unsigned OpNum,
752 const MCSubtargetInfo &STI,
754 unsigned Reg = MI->getOperand(OpNum).getReg();
755 printRegName(O, MRI.getSubReg(Reg, ARM::gsub_0));
757 printRegName(O, MRI.getSubReg(Reg, ARM::gsub_1));
760 void ARMInstPrinter::printSetendOperand(const MCInst *MI, unsigned OpNum,
761 const MCSubtargetInfo &STI,
763 const MCOperand &Op = MI->getOperand(OpNum);
770 void ARMInstPrinter::printCPSIMod(const MCInst *MI, unsigned OpNum,
771 const MCSubtargetInfo &STI, raw_ostream &O) {
772 const MCOperand &Op = MI->getOperand(OpNum);
773 O << ARM_PROC::IModToString(Op.getImm());
776 void ARMInstPrinter::printCPSIFlag(const MCInst *MI, unsigned OpNum,
777 const MCSubtargetInfo &STI, raw_ostream &O) {
778 const MCOperand &Op = MI->getOperand(OpNum);
779 unsigned IFlags = Op.getImm();
780 for (int i = 2; i >= 0; --i)
781 if (IFlags & (1 << i))
782 O << ARM_PROC::IFlagsToString(1 << i);
788 void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
789 const MCSubtargetInfo &STI,
791 const MCOperand &Op = MI->getOperand(OpNum);
792 unsigned SpecRegRBit = Op.getImm() >> 4;
793 unsigned Mask = Op.getImm() & 0xf;
794 const FeatureBitset &FeatureBits = STI.getFeatureBits();
796 if (FeatureBits[ARM::FeatureMClass]) {
797 unsigned SYSm = Op.getImm();
798 unsigned Opcode = MI->getOpcode();
800 // For writes, handle extended mask bits if the DSP extension is present.
801 if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSP]) {
830 // Handle the basic 8-bit mask.
833 if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) {
834 // ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
835 // alias for MSR APSR_nzcvq.
854 llvm_unreachable("Unexpected mask value!");
922 O << "basepri_max_ns";
936 // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
937 // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
938 if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
942 llvm_unreachable("Unexpected mask value!");
973 void ARMInstPrinter::printBankedRegOperand(const MCInst *MI, unsigned OpNum,
974 const MCSubtargetInfo &STI,
976 uint32_t Banked = MI->getOperand(OpNum).getImm();
977 uint32_t R = (Banked & 0x20) >> 5;
978 uint32_t SysM = Banked & 0x1f;
980 // Nothing much we can do about this, the encodings are specified in B9.2.3 of
981 // the ARM ARM v7C, and are all over the shop.
1008 llvm_unreachable("Invalid banked SPSR register");
1012 assert(!R && "should have dealt with SPSR regs");
1013 const char *RegNames[] = {
1014 "r8_usr", "r9_usr", "r10_usr", "r11_usr", "r12_usr", "sp_usr", "lr_usr",
1015 "", "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "sp_fiq",
1016 "lr_fiq", "", "lr_irq", "sp_irq", "lr_svc", "sp_svc", "lr_abt",
1017 "sp_abt", "lr_und", "sp_und", "", "", "", "",
1018 "lr_mon", "sp_mon", "elr_hyp", "sp_hyp"};
1019 const char *Name = RegNames[SysM];
1020 assert(Name[0] && "invalid banked register operand");
1025 void ARMInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
1026 const MCSubtargetInfo &STI,
1028 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
1029 // Handle the undefined 15 CC value here for printing so we don't abort().
1030 if ((unsigned)CC == 15)
1032 else if (CC != ARMCC::AL)
1033 O << ARMCondCodeToString(CC);
1036 void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst *MI,
1038 const MCSubtargetInfo &STI,
1040 ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
1041 O << ARMCondCodeToString(CC);
1044 void ARMInstPrinter::printSBitModifierOperand(const MCInst *MI, unsigned OpNum,
1045 const MCSubtargetInfo &STI,
1047 if (MI->getOperand(OpNum).getReg()) {
1048 assert(MI->getOperand(OpNum).getReg() == ARM::CPSR &&
1049 "Expect ARM CPSR register!");
1054 void ARMInstPrinter::printNoHashImmediate(const MCInst *MI, unsigned OpNum,
1055 const MCSubtargetInfo &STI,
1057 O << MI->getOperand(OpNum).getImm();
1060 void ARMInstPrinter::printPImmediate(const MCInst *MI, unsigned OpNum,
1061 const MCSubtargetInfo &STI,
1063 O << "p" << MI->getOperand(OpNum).getImm();
1066 void ARMInstPrinter::printCImmediate(const MCInst *MI, unsigned OpNum,
1067 const MCSubtargetInfo &STI,
1069 O << "c" << MI->getOperand(OpNum).getImm();
1072 void ARMInstPrinter::printCoprocOptionImm(const MCInst *MI, unsigned OpNum,
1073 const MCSubtargetInfo &STI,
1075 O << "{" << MI->getOperand(OpNum).getImm() << "}";
1078 void ARMInstPrinter::printPCLabel(const MCInst *MI, unsigned OpNum,
1079 const MCSubtargetInfo &STI, raw_ostream &O) {
1080 llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
1083 template <unsigned scale>
1084 void ARMInstPrinter::printAdrLabelOperand(const MCInst *MI, unsigned OpNum,
1085 const MCSubtargetInfo &STI,
1087 const MCOperand &MO = MI->getOperand(OpNum);
1090 MO.getExpr()->print(O, &MAI);
1094 int32_t OffImm = (int32_t)MO.getImm() << scale;
1096 O << markup("<imm:");
1097 if (OffImm == INT32_MIN)
1099 else if (OffImm < 0)
1100 O << "#-" << -OffImm;
1106 void ARMInstPrinter::printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum,
1107 const MCSubtargetInfo &STI,
1109 O << markup("<imm:") << "#" << formatImm(MI->getOperand(OpNum).getImm() * 4)
1113 void ARMInstPrinter::printThumbSRImm(const MCInst *MI, unsigned OpNum,
1114 const MCSubtargetInfo &STI,
1116 unsigned Imm = MI->getOperand(OpNum).getImm();
1117 O << markup("<imm:") << "#" << formatImm((Imm == 0 ? 32 : Imm))
1121 void ARMInstPrinter::printThumbITMask(const MCInst *MI, unsigned OpNum,
1122 const MCSubtargetInfo &STI,
1124 // (3 - the number of trailing zeros) is the number of then / else.
1125 unsigned Mask = MI->getOperand(OpNum).getImm();
1126 unsigned Firstcond = MI->getOperand(OpNum - 1).getImm();
1127 unsigned CondBit0 = Firstcond & 1;
1128 unsigned NumTZ = countTrailingZeros(Mask);
1129 assert(NumTZ <= 3 && "Invalid IT mask!");
1130 for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
1131 bool T = ((Mask >> Pos) & 1) == CondBit0;
1139 void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst *MI, unsigned Op,
1140 const MCSubtargetInfo &STI,
1142 const MCOperand &MO1 = MI->getOperand(Op);
1143 const MCOperand &MO2 = MI->getOperand(Op + 1);
1145 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
1146 printOperand(MI, Op, STI, O);
1150 O << markup("<mem:") << "[";
1151 printRegName(O, MO1.getReg());
1152 if (unsigned RegNum = MO2.getReg()) {
1154 printRegName(O, RegNum);
1156 O << "]" << markup(">");
1159 void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst *MI,
1161 const MCSubtargetInfo &STI,
1164 const MCOperand &MO1 = MI->getOperand(Op);
1165 const MCOperand &MO2 = MI->getOperand(Op + 1);
1167 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
1168 printOperand(MI, Op, STI, O);
1172 O << markup("<mem:") << "[";
1173 printRegName(O, MO1.getReg());
1174 if (unsigned ImmOffs = MO2.getImm()) {
1175 O << ", " << markup("<imm:") << "#" << formatImm(ImmOffs * Scale)
1178 O << "]" << markup(">");
1181 void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst *MI,
1183 const MCSubtargetInfo &STI,
1185 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 1);
1188 void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst *MI,
1190 const MCSubtargetInfo &STI,
1192 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 2);
1195 void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst *MI,
1197 const MCSubtargetInfo &STI,
1199 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
1202 void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst *MI, unsigned Op,
1203 const MCSubtargetInfo &STI,
1205 printThumbAddrModeImm5SOperand(MI, Op, STI, O, 4);
1208 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
1209 // register with shift forms.
1210 // REG 0 0 - e.g. R5
1211 // REG IMM, SH_OPC - e.g. R5, LSL #3
1212 void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
1213 const MCSubtargetInfo &STI,
1215 const MCOperand &MO1 = MI->getOperand(OpNum);
1216 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1218 unsigned Reg = MO1.getReg();
1219 printRegName(O, Reg);
1221 // Print the shift opc.
1222 assert(MO2.isImm() && "Not a valid t2_so_reg value!");
1223 printRegImmShift(O, ARM_AM::getSORegShOp(MO2.getImm()),
1224 ARM_AM::getSORegOffset(MO2.getImm()), UseMarkup);
1227 template <bool AlwaysPrintImm0>
1228 void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum,
1229 const MCSubtargetInfo &STI,
1231 const MCOperand &MO1 = MI->getOperand(OpNum);
1232 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1234 if (!MO1.isReg()) { // FIXME: This is for CP entries, but isn't right.
1235 printOperand(MI, OpNum, STI, O);
1239 O << markup("<mem:") << "[";
1240 printRegName(O, MO1.getReg());
1242 int32_t OffImm = (int32_t)MO2.getImm();
1243 bool isSub = OffImm < 0;
1244 // Special value for #-0. All others are normal.
1245 if (OffImm == INT32_MIN)
1248 O << ", " << markup("<imm:") << "#-" << formatImm(-OffImm) << markup(">");
1249 } else if (AlwaysPrintImm0 || OffImm > 0) {
1250 O << ", " << markup("<imm:") << "#" << formatImm(OffImm) << markup(">");
1252 O << "]" << markup(">");
1255 template <bool AlwaysPrintImm0>
1256 void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst *MI,
1258 const MCSubtargetInfo &STI,
1260 const MCOperand &MO1 = MI->getOperand(OpNum);
1261 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1263 O << markup("<mem:") << "[";
1264 printRegName(O, MO1.getReg());
1266 int32_t OffImm = (int32_t)MO2.getImm();
1267 bool isSub = OffImm < 0;
1269 if (OffImm == INT32_MIN)
1272 O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
1273 } else if (AlwaysPrintImm0 || OffImm > 0) {
1274 O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
1276 O << "]" << markup(">");
1279 template <bool AlwaysPrintImm0>
1280 void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst *MI,
1282 const MCSubtargetInfo &STI,
1284 const MCOperand &MO1 = MI->getOperand(OpNum);
1285 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1287 if (!MO1.isReg()) { // For label symbolic references.
1288 printOperand(MI, OpNum, STI, O);
1292 O << markup("<mem:") << "[";
1293 printRegName(O, MO1.getReg());
1295 int32_t OffImm = (int32_t)MO2.getImm();
1296 bool isSub = OffImm < 0;
1298 assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
1301 if (OffImm == INT32_MIN)
1304 O << ", " << markup("<imm:") << "#-" << -OffImm << markup(">");
1305 } else if (AlwaysPrintImm0 || OffImm > 0) {
1306 O << ", " << markup("<imm:") << "#" << OffImm << markup(">");
1308 O << "]" << markup(">");
1311 void ARMInstPrinter::printT2AddrModeImm0_1020s4Operand(
1312 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1314 const MCOperand &MO1 = MI->getOperand(OpNum);
1315 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1317 O << markup("<mem:") << "[";
1318 printRegName(O, MO1.getReg());
1320 O << ", " << markup("<imm:") << "#" << formatImm(MO2.getImm() * 4)
1323 O << "]" << markup(">");
1326 void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(
1327 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1329 const MCOperand &MO1 = MI->getOperand(OpNum);
1330 int32_t OffImm = (int32_t)MO1.getImm();
1331 O << ", " << markup("<imm:");
1332 if (OffImm == INT32_MIN)
1334 else if (OffImm < 0)
1335 O << "#-" << -OffImm;
1341 void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(
1342 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1344 const MCOperand &MO1 = MI->getOperand(OpNum);
1345 int32_t OffImm = (int32_t)MO1.getImm();
1347 assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
1349 O << ", " << markup("<imm:");
1350 if (OffImm == INT32_MIN)
1352 else if (OffImm < 0)
1353 O << "#-" << -OffImm;
1359 void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst *MI,
1361 const MCSubtargetInfo &STI,
1363 const MCOperand &MO1 = MI->getOperand(OpNum);
1364 const MCOperand &MO2 = MI->getOperand(OpNum + 1);
1365 const MCOperand &MO3 = MI->getOperand(OpNum + 2);
1367 O << markup("<mem:") << "[";
1368 printRegName(O, MO1.getReg());
1370 assert(MO2.getReg() && "Invalid so_reg load / store address!");
1372 printRegName(O, MO2.getReg());
1374 unsigned ShAmt = MO3.getImm();
1376 assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
1377 O << ", lsl " << markup("<imm:") << "#" << ShAmt << markup(">");
1379 O << "]" << markup(">");
1382 void ARMInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNum,
1383 const MCSubtargetInfo &STI,
1385 const MCOperand &MO = MI->getOperand(OpNum);
1386 O << markup("<imm:") << '#' << ARM_AM::getFPImmFloat(MO.getImm())
1390 void ARMInstPrinter::printNEONModImmOperand(const MCInst *MI, unsigned OpNum,
1391 const MCSubtargetInfo &STI,
1393 unsigned EncodedImm = MI->getOperand(OpNum).getImm();
1395 uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
1396 O << markup("<imm:") << "#0x";
1401 void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum,
1402 const MCSubtargetInfo &STI,
1404 unsigned Imm = MI->getOperand(OpNum).getImm();
1405 O << markup("<imm:") << "#" << formatImm(Imm + 1) << markup(">");
1408 void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum,
1409 const MCSubtargetInfo &STI,
1411 unsigned Imm = MI->getOperand(OpNum).getImm();
1414 assert(Imm <= 3 && "illegal ror immediate!");
1415 O << ", ror " << markup("<imm:") << "#" << 8 * Imm << markup(">");
1418 void ARMInstPrinter::printModImmOperand(const MCInst *MI, unsigned OpNum,
1419 const MCSubtargetInfo &STI,
1421 MCOperand Op = MI->getOperand(OpNum);
1423 // Support for fixups (MCFixup)
1425 return printOperand(MI, OpNum, STI, O);
1427 unsigned Bits = Op.getImm() & 0xFF;
1428 unsigned Rot = (Op.getImm() & 0xF00) >> 7;
1430 bool PrintUnsigned = false;
1431 switch (MI->getOpcode()) {
1433 // Movs to PC should be treated unsigned
1434 PrintUnsigned = (MI->getOperand(OpNum - 1).getReg() == ARM::PC);
1437 // Movs to special registers should be treated unsigned
1438 PrintUnsigned = true;
1442 int32_t Rotated = ARM_AM::rotr32(Bits, Rot);
1443 if (ARM_AM::getSOImmVal(Rotated) == Op.getImm()) {
1444 // #rot has the least possible value
1445 O << "#" << markup("<imm:");
1447 O << static_cast<uint32_t>(Rotated);
1454 // Explicit #bits, #rot implied
1455 O << "#" << markup("<imm:") << Bits << markup(">") << ", #" << markup("<imm:")
1456 << Rot << markup(">");
1459 void ARMInstPrinter::printFBits16(const MCInst *MI, unsigned OpNum,
1460 const MCSubtargetInfo &STI, raw_ostream &O) {
1461 O << markup("<imm:") << "#" << 16 - MI->getOperand(OpNum).getImm()
1465 void ARMInstPrinter::printFBits32(const MCInst *MI, unsigned OpNum,
1466 const MCSubtargetInfo &STI, raw_ostream &O) {
1467 O << markup("<imm:") << "#" << 32 - MI->getOperand(OpNum).getImm()
1471 void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
1472 const MCSubtargetInfo &STI,
1474 O << "[" << MI->getOperand(OpNum).getImm() << "]";
1477 void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum,
1478 const MCSubtargetInfo &STI,
1481 printRegName(O, MI->getOperand(OpNum).getReg());
1485 void ARMInstPrinter::printVectorListTwo(const MCInst *MI, unsigned OpNum,
1486 const MCSubtargetInfo &STI,
1488 unsigned Reg = MI->getOperand(OpNum).getReg();
1489 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1490 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
1492 printRegName(O, Reg0);
1494 printRegName(O, Reg1);
1498 void ARMInstPrinter::printVectorListTwoSpaced(const MCInst *MI, unsigned OpNum,
1499 const MCSubtargetInfo &STI,
1501 unsigned Reg = MI->getOperand(OpNum).getReg();
1502 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1503 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
1505 printRegName(O, Reg0);
1507 printRegName(O, Reg1);
1511 void ARMInstPrinter::printVectorListThree(const MCInst *MI, unsigned OpNum,
1512 const MCSubtargetInfo &STI,
1514 // Normally, it's not safe to use register enum values directly with
1515 // addition to get the next register, but for VFP registers, the
1516 // sort order is guaranteed because they're all of the form D<n>.
1518 printRegName(O, MI->getOperand(OpNum).getReg());
1520 printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1522 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1526 void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum,
1527 const MCSubtargetInfo &STI,
1529 // Normally, it's not safe to use register enum values directly with
1530 // addition to get the next register, but for VFP registers, the
1531 // sort order is guaranteed because they're all of the form D<n>.
1533 printRegName(O, MI->getOperand(OpNum).getReg());
1535 printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1537 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1539 printRegName(O, MI->getOperand(OpNum).getReg() + 3);
1543 void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI,
1545 const MCSubtargetInfo &STI,
1548 printRegName(O, MI->getOperand(OpNum).getReg());
1552 void ARMInstPrinter::printVectorListTwoAllLanes(const MCInst *MI,
1554 const MCSubtargetInfo &STI,
1556 unsigned Reg = MI->getOperand(OpNum).getReg();
1557 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1558 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_1);
1560 printRegName(O, Reg0);
1562 printRegName(O, Reg1);
1566 void ARMInstPrinter::printVectorListThreeAllLanes(const MCInst *MI,
1568 const MCSubtargetInfo &STI,
1570 // Normally, it's not safe to use register enum values directly with
1571 // addition to get the next register, but for VFP registers, the
1572 // sort order is guaranteed because they're all of the form D<n>.
1574 printRegName(O, MI->getOperand(OpNum).getReg());
1576 printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1578 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1582 void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI,
1584 const MCSubtargetInfo &STI,
1586 // Normally, it's not safe to use register enum values directly with
1587 // addition to get the next register, but for VFP registers, the
1588 // sort order is guaranteed because they're all of the form D<n>.
1590 printRegName(O, MI->getOperand(OpNum).getReg());
1592 printRegName(O, MI->getOperand(OpNum).getReg() + 1);
1594 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1596 printRegName(O, MI->getOperand(OpNum).getReg() + 3);
1600 void ARMInstPrinter::printVectorListTwoSpacedAllLanes(
1601 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1603 unsigned Reg = MI->getOperand(OpNum).getReg();
1604 unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
1605 unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
1607 printRegName(O, Reg0);
1609 printRegName(O, Reg1);
1613 void ARMInstPrinter::printVectorListThreeSpacedAllLanes(
1614 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1616 // Normally, it's not safe to use register enum values directly with
1617 // addition to get the next register, but for VFP registers, the
1618 // sort order is guaranteed because they're all of the form D<n>.
1620 printRegName(O, MI->getOperand(OpNum).getReg());
1622 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1624 printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1628 void ARMInstPrinter::printVectorListFourSpacedAllLanes(
1629 const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI,
1631 // Normally, it's not safe to use register enum values directly with
1632 // addition to get the next register, but for VFP registers, the
1633 // sort order is guaranteed because they're all of the form D<n>.
1635 printRegName(O, MI->getOperand(OpNum).getReg());
1637 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1639 printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1641 printRegName(O, MI->getOperand(OpNum).getReg() + 6);
1645 void ARMInstPrinter::printVectorListThreeSpaced(const MCInst *MI,
1647 const MCSubtargetInfo &STI,
1649 // Normally, it's not safe to use register enum values directly with
1650 // addition to get the next register, but for VFP registers, the
1651 // sort order is guaranteed because they're all of the form D<n>.
1653 printRegName(O, MI->getOperand(OpNum).getReg());
1655 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1657 printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1661 void ARMInstPrinter::printVectorListFourSpaced(const MCInst *MI, unsigned OpNum,
1662 const MCSubtargetInfo &STI,
1664 // Normally, it's not safe to use register enum values directly with
1665 // addition to get the next register, but for VFP registers, the
1666 // sort order is guaranteed because they're all of the form D<n>.
1668 printRegName(O, MI->getOperand(OpNum).getReg());
1670 printRegName(O, MI->getOperand(OpNum).getReg() + 2);
1672 printRegName(O, MI->getOperand(OpNum).getReg() + 4);
1674 printRegName(O, MI->getOperand(OpNum).getReg() + 6);