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 #define DEBUG_TYPE "asm-printer"
15 #include "ARMBaseInfo.h"
16 #include "ARMInstPrinter.h"
17 #include "ARMAddressingModes.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/Support/raw_ostream.h"
25 #define GET_INSTRUCTION_NAME
26 #include "ARMGenAsmWriter.inc"
28 StringRef
ARMInstPrinter::getOpcodeName(unsigned Opcode
) const {
29 return getInstructionName(Opcode
);
32 void ARMInstPrinter::printRegName(raw_ostream
&OS
, unsigned RegNo
) const {
33 OS
<< getRegisterName(RegNo
);
36 void ARMInstPrinter::printInst(const MCInst
*MI
, raw_ostream
&O
) {
37 unsigned Opcode
= MI
->getOpcode();
39 // Check for MOVs and print canonical forms, instead.
40 if (Opcode
== ARM::MOVs
) {
41 // FIXME: Thumb variants?
42 const MCOperand
&Dst
= MI
->getOperand(0);
43 const MCOperand
&MO1
= MI
->getOperand(1);
44 const MCOperand
&MO2
= MI
->getOperand(2);
45 const MCOperand
&MO3
= MI
->getOperand(3);
47 O
<< '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3
.getImm()));
48 printSBitModifierOperand(MI
, 6, O
);
49 printPredicateOperand(MI
, 4, O
);
51 O
<< '\t' << getRegisterName(Dst
.getReg())
52 << ", " << getRegisterName(MO1
.getReg());
54 if (ARM_AM::getSORegShOp(MO3
.getImm()) == ARM_AM::rrx
)
60 O
<< getRegisterName(MO2
.getReg());
61 assert(ARM_AM::getSORegOffset(MO3
.getImm()) == 0);
63 O
<< "#" << ARM_AM::getSORegOffset(MO3
.getImm());
69 if ((Opcode
== ARM::STMDB_UPD
|| Opcode
== ARM::t2STMDB_UPD
) &&
70 MI
->getOperand(0).getReg() == ARM::SP
) {
72 printPredicateOperand(MI
, 2, O
);
73 if (Opcode
== ARM::t2STMDB_UPD
)
76 printRegisterList(MI
, 4, O
);
81 if ((Opcode
== ARM::LDMIA_UPD
|| Opcode
== ARM::t2LDMIA_UPD
) &&
82 MI
->getOperand(0).getReg() == ARM::SP
) {
84 printPredicateOperand(MI
, 2, O
);
85 if (Opcode
== ARM::t2LDMIA_UPD
)
88 printRegisterList(MI
, 4, O
);
93 if ((Opcode
== ARM::VSTMSDB_UPD
|| Opcode
== ARM::VSTMDDB_UPD
) &&
94 MI
->getOperand(0).getReg() == ARM::SP
) {
96 printPredicateOperand(MI
, 2, O
);
98 printRegisterList(MI
, 4, O
);
103 if ((Opcode
== ARM::VLDMSIA_UPD
|| Opcode
== ARM::VLDMDIA_UPD
) &&
104 MI
->getOperand(0).getReg() == ARM::SP
) {
106 printPredicateOperand(MI
, 2, O
);
108 printRegisterList(MI
, 4, O
);
112 printInstruction(MI
, O
);
115 void ARMInstPrinter::printOperand(const MCInst
*MI
, unsigned OpNo
,
117 const MCOperand
&Op
= MI
->getOperand(OpNo
);
119 unsigned Reg
= Op
.getReg();
120 O
<< getRegisterName(Reg
);
121 } else if (Op
.isImm()) {
122 O
<< '#' << Op
.getImm();
124 assert(Op
.isExpr() && "unknown operand kind in printOperand");
129 static void printSOImm(raw_ostream
&O
, int64_t V
, raw_ostream
*CommentStream
,
130 const MCAsmInfo
*MAI
) {
131 // Break it up into two parts that make up a shifter immediate.
132 V
= ARM_AM::getSOImmVal(V
);
133 assert(V
!= -1 && "Not a valid so_imm value!");
135 unsigned Imm
= ARM_AM::getSOImmValImm(V
);
136 unsigned Rot
= ARM_AM::getSOImmValRot(V
);
138 // Print low-level immediate formation info, per
139 // A5.2.3: Data-processing (immediate), and
140 // A5.2.4: Modified immediate constants in ARM instructions
142 O
<< "#" << Imm
<< ", #" << Rot
;
143 // Pretty printed version.
145 *CommentStream
<< (int)ARM_AM::rotr32(Imm
, Rot
) << "\n";
152 /// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
153 /// immediate in bits 0-7.
154 void ARMInstPrinter::printSOImmOperand(const MCInst
*MI
, unsigned OpNum
,
156 const MCOperand
&MO
= MI
->getOperand(OpNum
);
157 assert(MO
.isImm() && "Not a valid so_imm value!");
158 printSOImm(O
, MO
.getImm(), CommentStream
, &MAI
);
161 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
162 // "Addressing Mode 1 - Data-processing operands" forms. This includes:
164 // REG REG 0,SH_OPC - e.g. R5, ROR R3
165 // REG 0 IMM,SH_OPC - e.g. R5, LSL #3
166 void ARMInstPrinter::printSORegOperand(const MCInst
*MI
, unsigned OpNum
,
168 const MCOperand
&MO1
= MI
->getOperand(OpNum
);
169 const MCOperand
&MO2
= MI
->getOperand(OpNum
+1);
170 const MCOperand
&MO3
= MI
->getOperand(OpNum
+2);
172 O
<< getRegisterName(MO1
.getReg());
174 // Print the shift opc.
175 ARM_AM::ShiftOpc ShOpc
= ARM_AM::getSORegShOp(MO3
.getImm());
176 O
<< ", " << ARM_AM::getShiftOpcStr(ShOpc
);
178 O
<< ' ' << getRegisterName(MO2
.getReg());
179 assert(ARM_AM::getSORegOffset(MO3
.getImm()) == 0);
180 } else if (ShOpc
!= ARM_AM::rrx
) {
181 O
<< " #" << ARM_AM::getSORegOffset(MO3
.getImm());
185 //===--------------------------------------------------------------------===//
186 // Addressing Mode #2
187 //===--------------------------------------------------------------------===//
189 void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst
*MI
, unsigned Op
,
191 const MCOperand
&MO1
= MI
->getOperand(Op
);
192 const MCOperand
&MO2
= MI
->getOperand(Op
+1);
193 const MCOperand
&MO3
= MI
->getOperand(Op
+2);
195 O
<< "[" << getRegisterName(MO1
.getReg());
198 if (ARM_AM::getAM2Offset(MO3
.getImm())) // Don't print +0.
200 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3
.getImm()))
201 << ARM_AM::getAM2Offset(MO3
.getImm());
207 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3
.getImm()))
208 << getRegisterName(MO2
.getReg());
210 if (unsigned ShImm
= ARM_AM::getAM2Offset(MO3
.getImm()))
212 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3
.getImm()))
217 void ARMInstPrinter::printAM2PostIndexOp(const MCInst
*MI
, unsigned Op
,
219 const MCOperand
&MO1
= MI
->getOperand(Op
);
220 const MCOperand
&MO2
= MI
->getOperand(Op
+1);
221 const MCOperand
&MO3
= MI
->getOperand(Op
+2);
223 O
<< "[" << getRegisterName(MO1
.getReg()) << "], ";
226 unsigned ImmOffs
= ARM_AM::getAM2Offset(MO3
.getImm());
228 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3
.getImm()))
233 O
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3
.getImm()))
234 << getRegisterName(MO2
.getReg());
236 if (unsigned ShImm
= ARM_AM::getAM2Offset(MO3
.getImm()))
238 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3
.getImm()))
242 void ARMInstPrinter::printAddrMode2Operand(const MCInst
*MI
, unsigned Op
,
244 const MCOperand
&MO1
= MI
->getOperand(Op
);
246 if (!MO1
.isReg()) { // FIXME: This is for CP entries, but isn't right.
247 printOperand(MI
, Op
, O
);
251 const MCOperand
&MO3
= MI
->getOperand(Op
+2);
252 unsigned IdxMode
= ARM_AM::getAM2IdxMode(MO3
.getImm());
254 if (IdxMode
== ARMII::IndexModePost
) {
255 printAM2PostIndexOp(MI
, Op
, O
);
258 printAM2PreOrOffsetIndexOp(MI
, Op
, O
);
261 void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst
*MI
,
264 const MCOperand
&MO1
= MI
->getOperand(OpNum
);
265 const MCOperand
&MO2
= MI
->getOperand(OpNum
+1);
268 unsigned ImmOffs
= ARM_AM::getAM2Offset(MO2
.getImm());
270 << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2
.getImm()))
275 O
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2
.getImm()))
276 << getRegisterName(MO1
.getReg());
278 if (unsigned ShImm
= ARM_AM::getAM2Offset(MO2
.getImm()))
280 << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2
.getImm()))
284 //===--------------------------------------------------------------------===//
285 // Addressing Mode #3
286 //===--------------------------------------------------------------------===//
288 void ARMInstPrinter::printAM3PostIndexOp(const MCInst
*MI
, unsigned Op
,
290 const MCOperand
&MO1
= MI
->getOperand(Op
);
291 const MCOperand
&MO2
= MI
->getOperand(Op
+1);
292 const MCOperand
&MO3
= MI
->getOperand(Op
+2);
294 O
<< "[" << getRegisterName(MO1
.getReg()) << "], ";
297 O
<< (char)ARM_AM::getAM3Op(MO3
.getImm())
298 << getRegisterName(MO2
.getReg());
302 unsigned ImmOffs
= ARM_AM::getAM3Offset(MO3
.getImm());
304 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3
.getImm()))
308 void ARMInstPrinter::printAM3PreOrOffsetIndexOp(const MCInst
*MI
, unsigned Op
,
310 const MCOperand
&MO1
= MI
->getOperand(Op
);
311 const MCOperand
&MO2
= MI
->getOperand(Op
+1);
312 const MCOperand
&MO3
= MI
->getOperand(Op
+2);
314 O
<< '[' << getRegisterName(MO1
.getReg());
317 O
<< ", " << (char)ARM_AM::getAM3Op(MO3
.getImm())
318 << getRegisterName(MO2
.getReg()) << ']';
322 if (unsigned ImmOffs
= ARM_AM::getAM3Offset(MO3
.getImm()))
324 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3
.getImm()))
329 void ARMInstPrinter::printAddrMode3Operand(const MCInst
*MI
, unsigned Op
,
331 const MCOperand
&MO3
= MI
->getOperand(Op
+2);
332 unsigned IdxMode
= ARM_AM::getAM3IdxMode(MO3
.getImm());
334 if (IdxMode
== ARMII::IndexModePost
) {
335 printAM3PostIndexOp(MI
, Op
, O
);
338 printAM3PreOrOffsetIndexOp(MI
, Op
, O
);
341 void ARMInstPrinter::printAddrMode3OffsetOperand(const MCInst
*MI
,
344 const MCOperand
&MO1
= MI
->getOperand(OpNum
);
345 const MCOperand
&MO2
= MI
->getOperand(OpNum
+1);
348 O
<< (char)ARM_AM::getAM3Op(MO2
.getImm())
349 << getRegisterName(MO1
.getReg());
353 unsigned ImmOffs
= ARM_AM::getAM3Offset(MO2
.getImm());
355 << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2
.getImm()))
359 void ARMInstPrinter::printLdStmModeOperand(const MCInst
*MI
, unsigned OpNum
,
361 ARM_AM::AMSubMode Mode
= ARM_AM::getAM4SubMode(MI
->getOperand(OpNum
)
363 O
<< ARM_AM::getAMSubModeStr(Mode
);
366 void ARMInstPrinter::printAddrMode5Operand(const MCInst
*MI
, unsigned OpNum
,
368 const MCOperand
&MO1
= MI
->getOperand(OpNum
);
369 const MCOperand
&MO2
= MI
->getOperand(OpNum
+1);
371 if (!MO1
.isReg()) { // FIXME: This is for CP entries, but isn't right.
372 printOperand(MI
, OpNum
, O
);
376 O
<< "[" << getRegisterName(MO1
.getReg());
378 if (unsigned ImmOffs
= ARM_AM::getAM5Offset(MO2
.getImm())) {
380 << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2
.getImm()))
386 void ARMInstPrinter::printAddrMode6Operand(const MCInst
*MI
, unsigned OpNum
,
388 const MCOperand
&MO1
= MI
->getOperand(OpNum
);
389 const MCOperand
&MO2
= MI
->getOperand(OpNum
+1);
391 O
<< "[" << getRegisterName(MO1
.getReg());
393 // FIXME: Both darwin as and GNU as violate ARM docs here.
394 O
<< ", :" << (MO2
.getImm() << 3);
399 void ARMInstPrinter::printAddrMode7Operand(const MCInst
*MI
, unsigned OpNum
,
401 const MCOperand
&MO1
= MI
->getOperand(OpNum
);
402 O
<< "[" << getRegisterName(MO1
.getReg()) << "]";
405 void ARMInstPrinter::printAddrMode6OffsetOperand(const MCInst
*MI
,
408 const MCOperand
&MO
= MI
->getOperand(OpNum
);
409 if (MO
.getReg() == 0)
412 O
<< ", " << getRegisterName(MO
.getReg());
415 void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst
*MI
,
418 const MCOperand
&MO
= MI
->getOperand(OpNum
);
419 uint32_t v
= ~MO
.getImm();
420 int32_t lsb
= CountTrailingZeros_32(v
);
421 int32_t width
= (32 - CountLeadingZeros_32 (v
)) - lsb
;
422 assert(MO
.isImm() && "Not a valid bf_inv_mask_imm value!");
423 O
<< '#' << lsb
<< ", #" << width
;
426 void ARMInstPrinter::printMemBOption(const MCInst
*MI
, unsigned OpNum
,
428 unsigned val
= MI
->getOperand(OpNum
).getImm();
429 O
<< ARM_MB::MemBOptToString(val
);
432 void ARMInstPrinter::printShiftImmOperand(const MCInst
*MI
, unsigned OpNum
,
434 unsigned ShiftOp
= MI
->getOperand(OpNum
).getImm();
435 ARM_AM::ShiftOpc Opc
= ARM_AM::getSORegShOp(ShiftOp
);
437 case ARM_AM::no_shift
:
446 assert(0 && "unexpected shift opcode for shift immediate operand");
448 O
<< ARM_AM::getSORegOffset(ShiftOp
);
451 void ARMInstPrinter::printRegisterList(const MCInst
*MI
, unsigned OpNum
,
454 for (unsigned i
= OpNum
, e
= MI
->getNumOperands(); i
!= e
; ++i
) {
455 if (i
!= OpNum
) O
<< ", ";
456 O
<< getRegisterName(MI
->getOperand(i
).getReg());
461 void ARMInstPrinter::printSetendOperand(const MCInst
*MI
, unsigned OpNum
,
463 const MCOperand
&Op
= MI
->getOperand(OpNum
);
470 void ARMInstPrinter::printCPSIMod(const MCInst
*MI
, unsigned OpNum
,
472 const MCOperand
&Op
= MI
->getOperand(OpNum
);
473 O
<< ARM_PROC::IModToString(Op
.getImm());
476 void ARMInstPrinter::printCPSIFlag(const MCInst
*MI
, unsigned OpNum
,
478 const MCOperand
&Op
= MI
->getOperand(OpNum
);
479 unsigned IFlags
= Op
.getImm();
480 for (int i
=2; i
>= 0; --i
)
481 if (IFlags
& (1 << i
))
482 O
<< ARM_PROC::IFlagsToString(1 << i
);
485 void ARMInstPrinter::printMSRMaskOperand(const MCInst
*MI
, unsigned OpNum
,
487 const MCOperand
&Op
= MI
->getOperand(OpNum
);
488 unsigned SpecRegRBit
= Op
.getImm() >> 4;
489 unsigned Mask
= Op
.getImm() & 0xf;
498 if (Mask
& 8) O
<< 'f';
499 if (Mask
& 4) O
<< 's';
500 if (Mask
& 2) O
<< 'x';
501 if (Mask
& 1) O
<< 'c';
505 void ARMInstPrinter::printPredicateOperand(const MCInst
*MI
, unsigned OpNum
,
507 ARMCC::CondCodes CC
= (ARMCC::CondCodes
)MI
->getOperand(OpNum
).getImm();
509 O
<< ARMCondCodeToString(CC
);
512 void ARMInstPrinter::printMandatoryPredicateOperand(const MCInst
*MI
,
515 ARMCC::CondCodes CC
= (ARMCC::CondCodes
)MI
->getOperand(OpNum
).getImm();
516 O
<< ARMCondCodeToString(CC
);
519 void ARMInstPrinter::printSBitModifierOperand(const MCInst
*MI
, unsigned OpNum
,
521 if (MI
->getOperand(OpNum
).getReg()) {
522 assert(MI
->getOperand(OpNum
).getReg() == ARM::CPSR
&&
523 "Expect ARM CPSR register!");
528 void ARMInstPrinter::printNoHashImmediate(const MCInst
*MI
, unsigned OpNum
,
530 O
<< MI
->getOperand(OpNum
).getImm();
533 void ARMInstPrinter::printPImmediate(const MCInst
*MI
, unsigned OpNum
,
535 O
<< "p" << MI
->getOperand(OpNum
).getImm();
538 void ARMInstPrinter::printCImmediate(const MCInst
*MI
, unsigned OpNum
,
540 O
<< "c" << MI
->getOperand(OpNum
).getImm();
543 void ARMInstPrinter::printPCLabel(const MCInst
*MI
, unsigned OpNum
,
545 llvm_unreachable("Unhandled PC-relative pseudo-instruction!");
548 void ARMInstPrinter::printThumbS4ImmOperand(const MCInst
*MI
, unsigned OpNum
,
550 O
<< "#" << MI
->getOperand(OpNum
).getImm() * 4;
553 void ARMInstPrinter::printThumbITMask(const MCInst
*MI
, unsigned OpNum
,
555 // (3 - the number of trailing zeros) is the number of then / else.
556 unsigned Mask
= MI
->getOperand(OpNum
).getImm();
557 unsigned CondBit0
= Mask
>> 4 & 1;
558 unsigned NumTZ
= CountTrailingZeros_32(Mask
);
559 assert(NumTZ
<= 3 && "Invalid IT mask!");
560 for (unsigned Pos
= 3, e
= NumTZ
; Pos
> e
; --Pos
) {
561 bool T
= ((Mask
>> Pos
) & 1) == CondBit0
;
569 void ARMInstPrinter::printThumbAddrModeRROperand(const MCInst
*MI
, unsigned Op
,
571 const MCOperand
&MO1
= MI
->getOperand(Op
);
572 const MCOperand
&MO2
= MI
->getOperand(Op
+ 1);
574 if (!MO1
.isReg()) { // FIXME: This is for CP entries, but isn't right.
575 printOperand(MI
, Op
, O
);
579 O
<< "[" << getRegisterName(MO1
.getReg());
580 if (unsigned RegNum
= MO2
.getReg())
581 O
<< ", " << getRegisterName(RegNum
);
585 void ARMInstPrinter::printThumbAddrModeImm5SOperand(const MCInst
*MI
,
589 const MCOperand
&MO1
= MI
->getOperand(Op
);
590 const MCOperand
&MO2
= MI
->getOperand(Op
+ 1);
592 if (!MO1
.isReg()) { // FIXME: This is for CP entries, but isn't right.
593 printOperand(MI
, Op
, O
);
597 O
<< "[" << getRegisterName(MO1
.getReg());
598 if (unsigned ImmOffs
= MO2
.getImm())
599 O
<< ", #" << ImmOffs
* Scale
;
603 void ARMInstPrinter::printThumbAddrModeImm5S1Operand(const MCInst
*MI
,
606 printThumbAddrModeImm5SOperand(MI
, Op
, O
, 1);
609 void ARMInstPrinter::printThumbAddrModeImm5S2Operand(const MCInst
*MI
,
612 printThumbAddrModeImm5SOperand(MI
, Op
, O
, 2);
615 void ARMInstPrinter::printThumbAddrModeImm5S4Operand(const MCInst
*MI
,
618 printThumbAddrModeImm5SOperand(MI
, Op
, O
, 4);
621 void ARMInstPrinter::printThumbAddrModeSPOperand(const MCInst
*MI
, unsigned Op
,
623 printThumbAddrModeImm5SOperand(MI
, Op
, O
, 4);
626 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
627 // register with shift forms.
629 // REG IMM, SH_OPC - e.g. R5, LSL #3
630 void ARMInstPrinter::printT2SOOperand(const MCInst
*MI
, unsigned OpNum
,
632 const MCOperand
&MO1
= MI
->getOperand(OpNum
);
633 const MCOperand
&MO2
= MI
->getOperand(OpNum
+1);
635 unsigned Reg
= MO1
.getReg();
636 O
<< getRegisterName(Reg
);
638 // Print the shift opc.
639 assert(MO2
.isImm() && "Not a valid t2_so_reg value!");
640 ARM_AM::ShiftOpc ShOpc
= ARM_AM::getSORegShOp(MO2
.getImm());
641 O
<< ", " << ARM_AM::getShiftOpcStr(ShOpc
);
642 if (ShOpc
!= ARM_AM::rrx
)
643 O
<< " #" << ARM_AM::getSORegOffset(MO2
.getImm());
646 void ARMInstPrinter::printAddrModeImm12Operand(const MCInst
*MI
, unsigned OpNum
,
648 const MCOperand
&MO1
= MI
->getOperand(OpNum
);
649 const MCOperand
&MO2
= MI
->getOperand(OpNum
+1);
651 if (!MO1
.isReg()) { // FIXME: This is for CP entries, but isn't right.
652 printOperand(MI
, OpNum
, O
);
656 O
<< "[" << getRegisterName(MO1
.getReg());
658 int32_t OffImm
= (int32_t)MO2
.getImm();
659 bool isSub
= OffImm
< 0;
660 // Special value for #-0. All others are normal.
661 if (OffImm
== INT32_MIN
)
664 O
<< ", #-" << -OffImm
;
666 O
<< ", #" << OffImm
;
670 void ARMInstPrinter::printT2AddrModeImm8Operand(const MCInst
*MI
,
673 const MCOperand
&MO1
= MI
->getOperand(OpNum
);
674 const MCOperand
&MO2
= MI
->getOperand(OpNum
+1);
676 O
<< "[" << getRegisterName(MO1
.getReg());
678 int32_t OffImm
= (int32_t)MO2
.getImm();
681 O
<< ", #-" << -OffImm
;
683 O
<< ", #" << OffImm
;
687 void ARMInstPrinter::printT2AddrModeImm8s4Operand(const MCInst
*MI
,
690 const MCOperand
&MO1
= MI
->getOperand(OpNum
);
691 const MCOperand
&MO2
= MI
->getOperand(OpNum
+1);
693 O
<< "[" << getRegisterName(MO1
.getReg());
695 int32_t OffImm
= (int32_t)MO2
.getImm() / 4;
698 O
<< ", #-" << -OffImm
* 4;
700 O
<< ", #" << OffImm
* 4;
704 void ARMInstPrinter::printT2AddrModeImm8OffsetOperand(const MCInst
*MI
,
707 const MCOperand
&MO1
= MI
->getOperand(OpNum
);
708 int32_t OffImm
= (int32_t)MO1
.getImm();
711 O
<< "#-" << -OffImm
;
716 void ARMInstPrinter::printT2AddrModeImm8s4OffsetOperand(const MCInst
*MI
,
719 const MCOperand
&MO1
= MI
->getOperand(OpNum
);
720 int32_t OffImm
= (int32_t)MO1
.getImm() / 4;
723 O
<< "#-" << -OffImm
* 4;
725 O
<< "#" << OffImm
* 4;
728 void ARMInstPrinter::printT2AddrModeSoRegOperand(const MCInst
*MI
,
731 const MCOperand
&MO1
= MI
->getOperand(OpNum
);
732 const MCOperand
&MO2
= MI
->getOperand(OpNum
+1);
733 const MCOperand
&MO3
= MI
->getOperand(OpNum
+2);
735 O
<< "[" << getRegisterName(MO1
.getReg());
737 assert(MO2
.getReg() && "Invalid so_reg load / store address!");
738 O
<< ", " << getRegisterName(MO2
.getReg());
740 unsigned ShAmt
= MO3
.getImm();
742 assert(ShAmt
<= 3 && "Not a valid Thumb2 addressing mode!");
743 O
<< ", lsl #" << ShAmt
;
748 void ARMInstPrinter::printVFPf32ImmOperand(const MCInst
*MI
, unsigned OpNum
,
750 const MCOperand
&MO
= MI
->getOperand(OpNum
);
753 O
<< (float)MO
.getFPImm();
760 FPUnion
.I
= MO
.getImm();
765 void ARMInstPrinter::printVFPf64ImmOperand(const MCInst
*MI
, unsigned OpNum
,
767 const MCOperand
&MO
= MI
->getOperand(OpNum
);
772 // We expect the binary encoding of a floating point number here.
778 FPUnion
.I
= MO
.getImm();
783 void ARMInstPrinter::printNEONModImmOperand(const MCInst
*MI
, unsigned OpNum
,
785 unsigned EncodedImm
= MI
->getOperand(OpNum
).getImm();
787 uint64_t Val
= ARM_AM::decodeNEONModImm(EncodedImm
, EltBits
);
788 O
<< "#0x" << utohexstr(Val
);