1 //===- ThumbDisassemblerCore.h - Thumb disassembler helpers -----*- C++ -*-===//
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 file is part of the ARM Disassembler.
11 // It contains code for disassembling a Thumb instr. It is to be included by
12 // ARMDisassemblerCore.cpp because it contains the static DisassembleThumbFrm()
13 // function which acts as the dispatcher to disassemble a Thumb instruction.
15 //===----------------------------------------------------------------------===//
17 ///////////////////////////////
19 // Utility Functions //
21 ///////////////////////////////
23 // Utilities for 16-bit Thumb instructions.
25 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
27 [ tRm ] [ tRn ] [ tRd ]
40 // Extract tRt: Inst{10-8}.
41 static inline unsigned getT1tRt(uint32_t insn) {
42 return slice(insn, 10, 8);
45 // Extract tRm: Inst{8-6}.
46 static inline unsigned getT1tRm(uint32_t insn) {
47 return slice(insn, 8, 6);
50 // Extract tRn: Inst{5-3}.
51 static inline unsigned getT1tRn(uint32_t insn) {
52 return slice(insn, 5, 3);
55 // Extract tRd: Inst{2-0}.
56 static inline unsigned getT1tRd(uint32_t insn) {
57 return slice(insn, 2, 0);
60 // Extract [D:Rd]: Inst{7:2-0}.
61 static inline unsigned getT1Rd(uint32_t insn) {
62 return slice(insn, 7, 7) << 3 | slice(insn, 2, 0);
65 // Extract Rm: Inst{6-3}.
66 static inline unsigned getT1Rm(uint32_t insn) {
67 return slice(insn, 6, 3);
70 // Extract imm3: Inst{8-6}.
71 static inline unsigned getT1Imm3(uint32_t insn) {
72 return slice(insn, 8, 6);
75 // Extract imm5: Inst{10-6}.
76 static inline unsigned getT1Imm5(uint32_t insn) {
77 return slice(insn, 10, 6);
80 // Extract i:imm5: Inst{9:7-3}.
81 static inline unsigned getT1Imm6(uint32_t insn) {
82 return slice(insn, 9, 9) << 5 | slice(insn, 7, 3);
85 // Extract imm7: Inst{6-0}.
86 static inline unsigned getT1Imm7(uint32_t insn) {
87 return slice(insn, 6, 0);
90 // Extract imm8: Inst{7-0}.
91 static inline unsigned getT1Imm8(uint32_t insn) {
92 return slice(insn, 7, 0);
95 // Extract imm11: Inst{10-0}.
96 static inline unsigned getT1Imm11(uint32_t insn) {
97 return slice(insn, 10, 0);
100 // Extract cond: Inst{11-8}.
101 static inline unsigned getT1Cond(uint32_t insn) {
102 return slice(insn, 11, 8);
105 static inline bool IsGPR(unsigned RegClass) {
106 return RegClass == ARM::GPRRegClassID || RegClass == ARM::rGPRRegClassID;
109 // Utilities for 32-bit Thumb instructions.
111 static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; }
113 // Extract imm4: Inst{19-16}.
114 static inline unsigned getImm4(uint32_t insn) {
115 return slice(insn, 19, 16);
118 // Extract imm3: Inst{14-12}.
119 static inline unsigned getImm3(uint32_t insn) {
120 return slice(insn, 14, 12);
123 // Extract imm8: Inst{7-0}.
124 static inline unsigned getImm8(uint32_t insn) {
125 return slice(insn, 7, 0);
128 // A8.6.61 LDRB (immediate, Thumb) and friends
131 static inline int decodeImm8(uint32_t insn) {
132 int Offset = getImm8(insn);
133 return slice(insn, 9, 9) ? Offset : -Offset;
136 // Extract imm12: Inst{11-0}.
137 static inline unsigned getImm12(uint32_t insn) {
138 return slice(insn, 11, 0);
141 // A8.6.63 LDRB (literal) and friends
144 static inline int decodeImm12(uint32_t insn) {
145 int Offset = getImm12(insn);
146 return slice(insn, 23, 23) ? Offset : -Offset;
149 // Extract imm2: Inst{7-6}.
150 static inline unsigned getImm2(uint32_t insn) {
151 return slice(insn, 7, 6);
154 // For BFI, BFC, t2SBFX, and t2UBFX.
155 // Extract lsb: Inst{14-12:7-6}.
156 static inline unsigned getLsb(uint32_t insn) {
157 return getImm3(insn) << 2 | getImm2(insn);
161 // Extract msb: Inst{4-0}.
162 static inline unsigned getMsb(uint32_t insn) {
163 return slice(insn, 4, 0);
166 // For t2SBFX and t2UBFX.
167 // Extract widthminus1: Inst{4-0}.
168 static inline unsigned getWidthMinus1(uint32_t insn) {
169 return slice(insn, 4, 0);
172 // For t2ADDri12 and t2SUBri12.
173 // imm12 = i:imm3:imm8;
174 static inline unsigned getIImm3Imm8(uint32_t insn) {
175 return slice(insn, 26, 26) << 11 | getImm3(insn) << 8 | getImm8(insn);
178 // For t2MOVi16 and t2MOVTi16.
179 // imm16 = imm4:i:imm3:imm8;
180 static inline unsigned getImm16(uint32_t insn) {
181 return getImm4(insn) << 12 | slice(insn, 26, 26) << 11 |
182 getImm3(insn) << 8 | getImm8(insn);
185 // Inst{5-4} encodes the shift type.
186 static inline unsigned getShiftTypeBits(uint32_t insn) {
187 return slice(insn, 5, 4);
190 // Inst{14-12}:Inst{7-6} encodes the imm5 shift amount.
191 static inline unsigned getShiftAmtBits(uint32_t insn) {
192 return getImm3(insn) << 2 | getImm2(insn);
196 // Encoding T1 ARMv6T2, ARMv7
197 // LLVM-specific encoding for #<lsb> and #<width>
198 static inline bool getBitfieldInvMask(uint32_t insn, uint32_t &mask) {
199 uint32_t lsb = getImm3(insn) << 2 | getImm2(insn);
200 uint32_t msb = getMsb(insn);
203 DEBUG(errs() << "Encoding error: msb < lsb\n");
206 for (uint32_t i = lsb; i <= msb; ++i)
212 // A8.4 Shifts applied to a register
213 // A8.4.1 Constant shifts
214 // A8.4.3 Pseudocode details of instruction-specified shifts and rotates
216 // decodeImmShift() returns the shift amount and the the shift opcode.
217 // Note that, as of Jan-06-2010, LLVM does not support rrx shifted operands yet.
218 static inline unsigned decodeImmShift(unsigned bits2, unsigned imm5,
219 ARM_AM::ShiftOpc &ShOp) {
221 assert(imm5 < 32 && "Invalid imm5 argument");
223 default: assert(0 && "No such value");
225 ShOp = (imm5 == 0 ? ARM_AM::no_shift : ARM_AM::lsl);
229 return (imm5 == 0 ? 32 : imm5);
232 return (imm5 == 0 ? 32 : imm5);
234 ShOp = (imm5 == 0 ? ARM_AM::rrx : ARM_AM::ror);
235 return (imm5 == 0 ? 1 : imm5);
239 // A6.3.2 Modified immediate constants in Thumb instructions
241 // ThumbExpandImm() returns the modified immediate constant given an imm12 for
242 // Thumb data-processing instructions with modified immediate.
243 // See also A6.3.1 Data-processing (modified immediate).
244 static inline unsigned ThumbExpandImm(unsigned imm12) {
245 assert(imm12 <= 0xFFF && "Invalid imm12 argument");
247 // If the leading two bits is 0b00, the modified immediate constant is
248 // obtained by splatting the low 8 bits into the first byte, every other byte,
249 // or every byte of a 32-bit value.
251 // Otherwise, a rotate right of '1':imm12<6:0> by the amount imm12<11:7> is
254 if (slice(imm12, 11, 10) == 0) {
255 unsigned short control = slice(imm12, 9, 8);
256 unsigned imm8 = slice(imm12, 7, 0);
259 assert(0 && "No such value");
264 return imm8 << 16 | imm8;
266 return imm8 << 24 | imm8 << 8;
268 return imm8 << 24 | imm8 << 16 | imm8 << 8 | imm8;
271 // A rotate is required.
272 unsigned Val = 1 << 7 | slice(imm12, 6, 0);
273 unsigned Amt = slice(imm12, 11, 7);
274 return ARM_AM::rotr32(Val, Amt);
278 static inline int decodeImm32_B_EncodingT3(uint32_t insn) {
279 bool S = slice(insn, 26, 26);
280 bool J1 = slice(insn, 13, 13);
281 bool J2 = slice(insn, 11, 11);
282 unsigned Imm21 = slice(insn, 21, 16) << 12 | slice(insn, 10, 0) << 1;
283 if (S) Imm21 |= 1 << 20;
284 if (J2) Imm21 |= 1 << 19;
285 if (J1) Imm21 |= 1 << 18;
287 return SignExtend32<21>(Imm21);
290 static inline int decodeImm32_B_EncodingT4(uint32_t insn) {
291 unsigned S = slice(insn, 26, 26);
292 bool I1 = slice(insn, 13, 13) == S;
293 bool I2 = slice(insn, 11, 11) == S;
294 unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 0) << 1;
295 if (S) Imm25 |= 1 << 24;
296 if (I1) Imm25 |= 1 << 23;
297 if (I2) Imm25 |= 1 << 22;
299 return SignExtend32<25>(Imm25);
302 static inline int decodeImm32_BL(uint32_t insn) {
303 unsigned S = slice(insn, 26, 26);
304 bool I1 = slice(insn, 13, 13) == S;
305 bool I2 = slice(insn, 11, 11) == S;
306 unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 0) << 1;
307 if (S) Imm25 |= 1 << 24;
308 if (I1) Imm25 |= 1 << 23;
309 if (I2) Imm25 |= 1 << 22;
311 return SignExtend32<25>(Imm25);
314 static inline int decodeImm32_BLX(uint32_t insn) {
315 unsigned S = slice(insn, 26, 26);
316 bool I1 = slice(insn, 13, 13) == S;
317 bool I2 = slice(insn, 11, 11) == S;
318 unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 1) << 2;
319 if (S) Imm25 |= 1 << 24;
320 if (I1) Imm25 |= 1 << 23;
321 if (I2) Imm25 |= 1 << 22;
323 return SignExtend32<25>(Imm25);
326 ///////////////////////////////////////////////
328 // Thumb1 instruction disassembly functions. //
330 ///////////////////////////////////////////////
332 // See "Utilities for 16-bit Thumb instructions" for register naming convention.
334 // A6.2.1 Shift (immediate), add, subtract, move, and compare
336 // shift immediate: tRd CPSR tRn imm5
337 // add/sub register: tRd CPSR tRn tRm
338 // add/sub 3-bit immediate: tRd CPSR tRn imm3
339 // add/sub 8-bit immediate: tRt CPSR tRt(TIED_TO) imm8
340 // mov/cmp immediate: tRt [CPSR] imm8 (CPSR present for mov)
344 static bool DisassembleThumb1General(MCInst &MI, unsigned Opcode, uint32_t insn,
345 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
347 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
348 unsigned &OpIdx = NumOpsAdded;
352 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID
353 && "Invalid arguments");
355 bool Imm3 = (Opcode == ARM::tADDi3 || Opcode == ARM::tSUBi3);
357 // Use Rt implies use imm8.
358 bool UseRt = (Opcode == ARM::tADDi8 || Opcode == ARM::tSUBi8 ||
359 Opcode == ARM::tMOVi8 || Opcode == ARM::tCMPi8);
361 // Add the destination operand.
362 MI.addOperand(MCOperand::CreateReg(
363 getRegisterEnum(B, ARM::tGPRRegClassID,
364 UseRt ? getT1tRt(insn) : getT1tRd(insn))));
367 // Check whether the next operand to be added is a CCR Register.
368 if (OpInfo[OpIdx].RegClass == ARM::CCRRegClassID) {
369 assert(OpInfo[OpIdx].isOptionalDef() && "Optional def operand expected");
370 MI.addOperand(MCOperand::CreateReg(B->InITBlock() ? 0 : ARM::CPSR));
374 // Check whether the next operand to be added is a Thumb1 Register.
375 assert(OpIdx < NumOps && "More operands expected");
376 if (OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
377 // For UseRt, the reg operand is tied to the first reg operand.
378 MI.addOperand(MCOperand::CreateReg(
379 getRegisterEnum(B, ARM::tGPRRegClassID,
380 UseRt ? getT1tRt(insn) : getT1tRn(insn))));
384 // Special case for tMOVSr.
388 // The next available operand is either a reg operand or an imm operand.
389 if (OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
390 // Three register operand instructions.
391 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
394 assert(OpInfo[OpIdx].RegClass < 0 &&
395 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()
396 && "Pure imm operand expected");
399 Imm = getT1Imm8(insn);
401 Imm = getT1Imm3(insn);
403 Imm = getT1Imm5(insn);
404 ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 12, 11));
405 getImmShiftSE(ShOp, Imm);
407 MI.addOperand(MCOperand::CreateImm(Imm));
414 // A6.2.2 Data-processing
416 // tCMPr, tTST, tCMN: tRd tRn
417 // tMVN, tRSB: tRd CPSR tRn
418 // Others: tRd CPSR tRd(TIED_TO) tRn
419 static bool DisassembleThumb1DP(MCInst &MI, unsigned Opcode, uint32_t insn,
420 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
422 const MCInstrDesc &MCID = ARMInsts[Opcode];
423 const MCOperandInfo *OpInfo = MCID.OpInfo;
424 unsigned &OpIdx = NumOpsAdded;
428 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
429 (OpInfo[1].RegClass == ARM::CCRRegClassID
430 || OpInfo[1].RegClass == ARM::tGPRRegClassID)
431 && "Invalid arguments");
433 // Add the destination operand.
434 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
438 // Check whether the next operand to be added is a CCR Register.
439 if (OpInfo[OpIdx].RegClass == ARM::CCRRegClassID) {
440 assert(OpInfo[OpIdx].isOptionalDef() && "Optional def operand expected");
441 MI.addOperand(MCOperand::CreateReg(B->InITBlock() ? 0 : ARM::CPSR));
445 // We have either { tRd(TIED_TO), tRn } or { tRn } remaining.
446 // Process the TIED_TO operand first.
448 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
449 && "Thumb reg operand expected");
451 if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
452 // The reg operand is tied to the first reg operand.
453 MI.addOperand(MI.getOperand(Idx));
457 // Process possible next reg operand.
458 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
460 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
468 // A6.2.3 Special data instructions and branch and exchange
470 // tADDhirr: Rd Rd(TIED_TO) Rm
472 // tMOVr, tMOVgpr2gpr, tMOVgpr2tgpr, tMOVtgpr2gpr: Rd|tRd Rm|tRn
474 // tBX_RET: 0 operand
475 // tBX_RET_vararg: Rm
478 static bool DisassembleThumb1Special(MCInst &MI, unsigned Opcode, uint32_t insn,
479 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
481 // tBX_RET has 0 operand.
485 // BX/BLX/tBRIND (indirect branch, i.e, mov pc, Rm) has 1 reg operand: Rm.
486 if (Opcode==ARM::tBLXr || Opcode==ARM::tBX || Opcode==ARM::tBRIND) {
487 if (Opcode == ARM::tBLXr) {
488 // Handling the two predicate operands before the reg operand.
489 if (!B->DoPredicateOperands(MI, Opcode, insn, NumOps))
494 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
498 if (Opcode == ARM::tBX) {
499 // Handling the two predicate operands after the reg operand.
500 if (!B->DoPredicateOperands(MI, Opcode, insn, NumOps))
508 const MCInstrDesc &MCID = ARMInsts[Opcode];
509 const MCOperandInfo *OpInfo = MCID.OpInfo;
510 unsigned &OpIdx = NumOpsAdded;
514 // Add the destination operand.
515 unsigned RegClass = OpInfo[OpIdx].RegClass;
516 MI.addOperand(MCOperand::CreateReg(
517 getRegisterEnum(B, RegClass,
518 IsGPR(RegClass) ? getT1Rd(insn)
522 // We have either { Rd(TIED_TO), Rm } or { Rm|tRn } remaining.
523 // Process the TIED_TO operand first.
525 assert(OpIdx < NumOps && "More operands expected");
527 if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
528 // The reg operand is tied to the first reg operand.
529 MI.addOperand(MI.getOperand(Idx));
533 // The next reg operand is either Rm or tRn.
534 assert(OpIdx < NumOps && "More operands expected");
535 RegClass = OpInfo[OpIdx].RegClass;
536 MI.addOperand(MCOperand::CreateReg(
537 getRegisterEnum(B, RegClass,
538 IsGPR(RegClass) ? getT1Rm(insn)
545 // A8.6.59 LDR (literal)
547 // tLDRpci: tRt imm8*4
548 static bool DisassembleThumb1LdPC(MCInst &MI, unsigned Opcode, uint32_t insn,
549 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
551 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
552 if (!OpInfo) return false;
554 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
555 (OpInfo[1].RegClass < 0 &&
556 !OpInfo[1].isPredicate() &&
557 !OpInfo[1].isOptionalDef())
558 && "Invalid arguments");
560 // Add the destination operand.
561 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
564 // And the (imm8 << 2) operand.
565 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn) << 2));
572 // Thumb specific addressing modes (see ARMInstrThumb.td):
574 // t_addrmode_rr := reg + reg
576 // t_addrmode_s4 := reg + reg
579 // t_addrmode_s2 := reg + reg
582 // t_addrmode_s1 := reg + reg
585 // t_addrmode_sp := sp + imm8 * 4
588 // A8.6.63 LDRB (literal)
589 // A8.6.79 LDRSB (literal)
590 // A8.6.75 LDRH (literal)
591 // A8.6.83 LDRSH (literal)
592 // A8.6.59 LDR (literal)
594 // These instrs calculate an address from the PC value and an immediate offset.
595 // Rd Rn=PC (+/-)imm12 (+ if Inst{23} == 0b1)
596 static bool DisassembleThumb2Ldpci(MCInst &MI, unsigned Opcode,
597 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
599 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
600 if (!OpInfo) return false;
602 assert(NumOps >= 2 &&
603 OpInfo[0].RegClass == ARM::GPRRegClassID &&
604 OpInfo[1].RegClass < 0 &&
605 "Expect >= 2 operands, first as reg, and second as imm operand");
607 // Build the register operand, followed by the (+/-)imm12 immediate.
609 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
612 MI.addOperand(MCOperand::CreateImm(decodeImm12(insn)));
620 // A6.2.4 Load/store single data item
622 // Load/Store Register (reg|imm): tRd tRn imm5|tRm
623 // Load Register Signed Byte|Halfword: tRd tRn tRm
624 static bool DisassembleThumb1LdSt(unsigned opA, MCInst &MI, unsigned Opcode,
625 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
627 const MCInstrDesc &MCID = ARMInsts[Opcode];
628 const MCOperandInfo *OpInfo = MCID.OpInfo;
629 unsigned &OpIdx = NumOpsAdded;
632 && OpInfo[0].RegClass == ARM::tGPRRegClassID
633 && OpInfo[1].RegClass == ARM::tGPRRegClassID
634 && "Expect >= 2 operands and first two as thumb reg operands");
636 // Add the destination reg and the base reg.
637 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
639 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
643 // We have either { imm5 } or { tRm } remaining.
644 // Note that STR/LDR (register) should skip the imm5 offset operand for
645 // t_addrmode_s[1|2|4].
647 assert(OpIdx < NumOps && "More operands expected");
649 if (OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate() &&
650 !OpInfo[OpIdx].isOptionalDef()) {
651 // Table A6-5 16-bit Thumb Load/store instructions
652 // opA = 0b0101 for STR/LDR (register) and friends.
653 // Otherwise, we have STR/LDR (immediate) and friends.
654 assert(opA != 5 && "Immediate operand expected for this opcode");
655 MI.addOperand(MCOperand::CreateImm(getT1Imm5(insn)));
658 // The next reg operand is tRm, the offset.
659 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
660 && "Thumb reg operand expected");
661 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
668 // A6.2.4 Load/store single data item
670 // Load/Store Register SP relative: tRt ARM::SP imm8
671 static bool DisassembleThumb1LdStSP(MCInst &MI, unsigned Opcode, uint32_t insn,
672 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
674 assert((Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi)
675 && "Unexpected opcode");
677 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
678 if (!OpInfo) return false;
680 assert(NumOps >= 3 &&
681 OpInfo[0].RegClass == ARM::tGPRRegClassID &&
682 OpInfo[1].RegClass == ARM::GPRRegClassID &&
683 (OpInfo[2].RegClass < 0 &&
684 !OpInfo[2].isPredicate() &&
685 !OpInfo[2].isOptionalDef())
686 && "Invalid arguments");
688 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
690 MI.addOperand(MCOperand::CreateReg(ARM::SP));
691 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
696 // Table A6-1 16-bit Thumb instruction encoding
699 // tADDrPCi: tRt imm8
700 static bool DisassembleThumb1AddPCi(MCInst &MI, unsigned Opcode, uint32_t insn,
701 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
703 assert(Opcode == ARM::tADDrPCi && "Unexpected opcode");
705 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
706 if (!OpInfo) return false;
708 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
709 (OpInfo[1].RegClass < 0 &&
710 !OpInfo[1].isPredicate() &&
711 !OpInfo[1].isOptionalDef())
712 && "Invalid arguments");
714 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
716 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
721 // Table A6-1 16-bit Thumb instruction encoding
722 // A8.6.8 ADD (SP plus immediate)
724 // tADDrSPi: tRt ARM::SP imm8
725 static bool DisassembleThumb1AddSPi(MCInst &MI, unsigned Opcode, uint32_t insn,
726 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
728 assert(Opcode == ARM::tADDrSPi && "Unexpected opcode");
730 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
731 if (!OpInfo) return false;
733 assert(NumOps >= 3 &&
734 OpInfo[0].RegClass == ARM::tGPRRegClassID &&
735 OpInfo[1].RegClass == ARM::GPRRegClassID &&
736 (OpInfo[2].RegClass < 0 &&
737 !OpInfo[2].isPredicate() &&
738 !OpInfo[2].isOptionalDef())
739 && "Invalid arguments");
741 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
743 MI.addOperand(MCOperand::CreateReg(ARM::SP));
744 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
749 // tPUSH, tPOP: Pred-Imm Pred-CCR register_list
751 // where register_list = low registers + [lr] for PUSH or
752 // low registers + [pc] for POP
754 // "low registers" is specified by Inst{7-0}
755 // lr|pc is specified by Inst{8}
756 static bool DisassembleThumb1PushPop(MCInst &MI, unsigned Opcode, uint32_t insn,
757 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
759 assert((Opcode == ARM::tPUSH || Opcode == ARM::tPOP) && "Unexpected opcode");
761 unsigned &OpIdx = NumOpsAdded;
763 // Handling the two predicate operands before the reglist.
764 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
767 DEBUG(errs() << "Expected predicate operands not found.\n");
771 unsigned RegListBits = slice(insn, 8, 8) << (Opcode == ARM::tPUSH ? 14 : 15)
774 // Fill the variadic part of reglist.
775 for (unsigned i = 0; i < 16; ++i) {
776 if ((RegListBits >> i) & 1) {
777 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
786 // A6.2.5 Miscellaneous 16-bit instructions
787 // Delegate to DisassembleThumb1PushPop() for tPUSH & tPOP.
789 // tADDspi, tSUBspi: ARM::SP ARM::SP(TIED_TO) imm7
790 // t2IT: firstcond=Inst{7-4} mask=Inst{3-0}
791 // tCBNZ, tCBZ: tRd imm6*2
793 // tNOP, tSEV, tYIELD, tWFE, tWFI:
794 // no operand (except predicate pair)
797 static bool DisassembleThumb1Misc(MCInst &MI, unsigned Opcode, uint32_t insn,
798 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
803 if (Opcode == ARM::tPUSH || Opcode == ARM::tPOP)
804 return DisassembleThumb1PushPop(MI, Opcode, insn, NumOps, NumOpsAdded, B);
806 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
808 // Predicate operands are handled elsewhere.
810 OpInfo[0].isPredicate() && OpInfo[1].isPredicate() &&
811 OpInfo[0].RegClass < 0 && OpInfo[1].RegClass == ARM::CCRRegClassID) {
815 if (Opcode == ARM::tADDspi || Opcode == ARM::tSUBspi) {
816 // Special case handling for tADDspi and tSUBspi.
817 // A8.6.8 ADD (SP plus immediate) & A8.6.215 SUB (SP minus immediate)
818 MI.addOperand(MCOperand::CreateReg(ARM::SP));
819 MI.addOperand(MCOperand::CreateReg(ARM::SP));
820 MI.addOperand(MCOperand::CreateImm(getT1Imm7(insn)));
825 if (Opcode == ARM::t2IT) {
826 // Special case handling for If-Then.
828 // Tag the (firstcond[0] bit << 4) along with mask.
831 MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 4)));
833 // firstcond[0] and mask
834 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
839 if (Opcode == ARM::tBKPT) {
840 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn))); // breakpoint value
845 // CPS has a singleton $opt operand that contains the following information:
846 // The first op would be 0b10 as enable and 0b11 as disable in regular ARM,
847 // but in Thumb it's is 0 as enable and 1 as disable. So map it to ARM's
848 // default one. The second get the AIF flags from Inst{2-0}.
849 if (Opcode == ARM::tCPS) {
850 MI.addOperand(MCOperand::CreateImm(2 + slice(insn, 4, 4)));
851 MI.addOperand(MCOperand::CreateImm(slice(insn, 2, 0)));
856 if (Opcode == ARM::tSETEND) {
857 MI.addOperand(MCOperand::CreateImm(slice(insn, 3, 1)));
862 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
863 (OpInfo[1].RegClass < 0 || OpInfo[1].RegClass==ARM::tGPRRegClassID)
864 && "Expect >=2 operands");
866 // Add the destination operand.
867 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
870 if (OpInfo[1].RegClass == ARM::tGPRRegClassID) {
871 // Two register instructions.
872 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
876 assert((Opcode == ARM::tCBNZ || Opcode == ARM::tCBZ) &&"Unexpected opcode");
877 MI.addOperand(MCOperand::CreateImm(getT1Imm6(insn) * 2));
885 // A8.6.53 LDM / LDMIA
886 // A8.6.189 STM / STMIA
888 // tLDMIA_UPD/tSTMIA_UPD: tRt tRt AM4ModeImm Pred-Imm Pred-CCR register_list
889 // tLDMIA: tRt AM4ModeImm Pred-Imm Pred-CCR register_list
890 static bool DisassembleThumb1LdStMul(bool Ld, MCInst &MI, unsigned Opcode,
891 uint32_t insn, unsigned short NumOps,
892 unsigned &NumOpsAdded, BO B) {
893 assert((Opcode == ARM::tLDMIA || Opcode == ARM::tSTMIA) &&
894 "Unexpected opcode");
896 unsigned tRt = getT1tRt(insn);
899 // WB register, if necessary.
900 if (Opcode == ARM::tLDMIA_UPD || Opcode == ARM::tSTMIA_UPD) {
901 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
906 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
910 // Handling the two predicate operands before the reglist.
911 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps)) {
914 DEBUG(errs() << "Expected predicate operands not found.\n");
918 unsigned RegListBits = slice(insn, 7, 0);
919 if (BitCount(RegListBits) < 1) {
920 DEBUG(errs() << "if BitCount(registers) < 1 then UNPREDICTABLE\n");
924 // Fill the variadic part of reglist.
925 for (unsigned i = 0; i < 8; ++i)
926 if ((RegListBits >> i) & 1) {
927 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
935 static bool DisassembleThumb1LdMul(MCInst &MI, unsigned Opcode, uint32_t insn,
936 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
937 return DisassembleThumb1LdStMul(true, MI, Opcode, insn, NumOps, NumOpsAdded,
941 static bool DisassembleThumb1StMul(MCInst &MI, unsigned Opcode, uint32_t insn,
942 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
943 return DisassembleThumb1LdStMul(false, MI, Opcode, insn, NumOps, NumOpsAdded,
947 // A8.6.16 B Encoding T1
948 // cond = Inst{11-8} & imm8 = Inst{7-0}
949 // imm32 = SignExtend(imm8:'0', 32)
951 // tBcc: offset Pred-Imm Pred-CCR
952 // tSVC: imm8 Pred-Imm Pred-CCR
953 // tTRAP: 0 operand (early return)
954 static bool DisassembleThumb1CondBr(MCInst &MI, unsigned Opcode, uint32_t insn,
955 unsigned short NumOps, unsigned &NumOpsAdded, BO) {
957 if (Opcode == ARM::tTRAP)
960 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
961 if (!OpInfo) return false;
963 assert(NumOps == 3 && OpInfo[0].RegClass < 0 &&
964 OpInfo[1].isPredicate() && OpInfo[2].RegClass == ARM::CCRRegClassID
965 && "Exactly 3 operands expected");
967 unsigned Imm8 = getT1Imm8(insn);
968 MI.addOperand(MCOperand::CreateImm(
969 Opcode == ARM::tBcc ? SignExtend32<9>(Imm8 << 1)
972 // Predicate operands by ARMBasicMCBuilder::TryPredicateAndSBitModifier().
973 // But note that for tBcc, if cond = '1110' then UNDEFINED.
974 if (Opcode == ARM::tBcc && slice(insn, 11, 8) == 14) {
975 DEBUG(errs() << "if cond = '1110' then UNDEFINED\n");
983 // A8.6.16 B Encoding T2
984 // imm11 = Inst{10-0}
985 // imm32 = SignExtend(imm11:'0', 32)
988 static bool DisassembleThumb1Br(MCInst &MI, unsigned Opcode, uint32_t insn,
989 unsigned short NumOps, unsigned &NumOpsAdded, BO) {
991 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
992 if (!OpInfo) return false;
994 assert(NumOps == 1 && OpInfo[0].RegClass < 0 && "1 imm operand expected");
996 unsigned Imm11 = getT1Imm11(insn);
998 MI.addOperand(MCOperand::CreateImm(SignExtend32<12>(Imm11 << 1)));
1006 // See A6.2 16-bit Thumb instruction encoding for instruction classes
1007 // corresponding to op.
1009 // Table A6-1 16-bit Thumb instruction encoding (abridged)
1010 // op Instruction or instruction class
1011 // ------ --------------------------------------------------------------------
1012 // 00xxxx Shift (immediate), add, subtract, move, and compare on page A6-7
1013 // 010000 Data-processing on page A6-8
1014 // 010001 Special data instructions and branch and exchange on page A6-9
1015 // 01001x Load from Literal Pool, see LDR (literal) on page A8-122
1016 // 0101xx Load/store single data item on page A6-10
1019 // 10100x Generate PC-relative address, see ADR on page A8-32
1020 // 10101x Generate SP-relative address, see ADD (SP plus immediate) on
1022 // 1011xx Miscellaneous 16-bit instructions on page A6-11
1023 // 11000x Store multiple registers, see STM / STMIA / STMEA on page A8-374
1024 // 11001x Load multiple registers, see LDM / LDMIA / LDMFD on page A8-110 a
1025 // 1101xx Conditional branch, and Supervisor Call on page A6-13
1026 // 11100x Unconditional Branch, see B on page A8-44
1028 static bool DisassembleThumb1(uint16_t op, MCInst &MI, unsigned Opcode,
1029 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1031 unsigned op1 = slice(op, 5, 4);
1032 unsigned op2 = slice(op, 3, 2);
1033 unsigned op3 = slice(op, 1, 0);
1034 unsigned opA = slice(op, 5, 2);
1037 // A6.2.1 Shift (immediate), add, subtract, move, and compare
1038 return DisassembleThumb1General(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1044 // A6.2.2 Data-processing
1045 return DisassembleThumb1DP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1047 // A6.2.3 Special data instructions and branch and exchange
1048 return DisassembleThumb1Special(MI, Opcode, insn, NumOps, NumOpsAdded,
1051 // A8.6.59 LDR (literal)
1052 return DisassembleThumb1LdPC(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1056 // A6.2.4 Load/store single data item
1057 return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
1065 // A6.2.4 Load/store single data item
1066 return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
1069 // A6.2.4 Load/store single data item
1070 return DisassembleThumb1LdStSP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1074 return DisassembleThumb1AddPCi(MI, Opcode, insn, NumOps, NumOpsAdded,
1077 // A8.6.8 ADD (SP plus immediate)
1078 return DisassembleThumb1AddSPi(MI, Opcode, insn, NumOps, NumOpsAdded,
1082 // A6.2.5 Miscellaneous 16-bit instructions
1083 return DisassembleThumb1Misc(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1090 // A8.6.189 STM / STMIA / STMEA
1091 return DisassembleThumb1StMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1093 // A8.6.53 LDM / LDMIA / LDMFD
1094 return DisassembleThumb1LdMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1097 // A6.2.6 Conditional branch, and Supervisor Call
1098 return DisassembleThumb1CondBr(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1100 // Unconditional Branch, see B on page A8-44
1101 return DisassembleThumb1Br(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1103 assert(0 && "Unreachable code");
1108 assert(0 && "Unreachable code");
1115 ///////////////////////////////////////////////
1117 // Thumb2 instruction disassembly functions. //
1119 ///////////////////////////////////////////////
1121 ///////////////////////////////////////////////////////////
1123 // Note: the register naming follows the ARM convention! //
1125 ///////////////////////////////////////////////////////////
1127 static inline bool Thumb2SRSOpcode(unsigned Opcode) {
1131 case ARM::t2SRSDBW: case ARM::t2SRSDB:
1132 case ARM::t2SRSIAW: case ARM::t2SRSIA:
1137 static inline bool Thumb2RFEOpcode(unsigned Opcode) {
1141 case ARM::t2RFEDBW: case ARM::t2RFEDB:
1142 case ARM::t2RFEIAW: case ARM::t2RFEIA:
1147 // t2SRS[IA|DB]W/t2SRS[IA|DB]: mode_imm = Inst{4-0}
1148 static bool DisassembleThumb2SRS(MCInst &MI, unsigned Opcode, uint32_t insn,
1149 unsigned short NumOps, unsigned &NumOpsAdded) {
1150 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
1155 // t2RFE[IA|DB]W/t2RFE[IA|DB]: Rn
1156 static bool DisassembleThumb2RFE(MCInst &MI, unsigned Opcode, uint32_t insn,
1157 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1158 unsigned Rn = decodeRn(insn);
1160 DEBUG(errs() << "if n == 15 then UNPREDICTABLE\n");
1163 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,ARM::GPRRegClassID,Rn)));
1168 static bool DisassembleThumb2LdStMul(MCInst &MI, unsigned Opcode, uint32_t insn,
1169 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1171 if (Thumb2SRSOpcode(Opcode))
1172 return DisassembleThumb2SRS(MI, Opcode, insn, NumOps, NumOpsAdded);
1174 if (Thumb2RFEOpcode(Opcode))
1175 return DisassembleThumb2RFE(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1177 assert((Opcode == ARM::t2LDMIA || Opcode == ARM::t2LDMIA_UPD ||
1178 Opcode == ARM::t2LDMDB || Opcode == ARM::t2LDMDB_UPD ||
1179 Opcode == ARM::t2STMIA || Opcode == ARM::t2STMIA_UPD ||
1180 Opcode == ARM::t2STMDB || Opcode == ARM::t2STMDB_UPD)
1181 && "Unexpected opcode");
1182 assert(NumOps >= 4 && "Thumb2 LdStMul expects NumOps >= 4");
1186 unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
1188 // Writeback to base.
1189 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD ||
1190 Opcode == ARM::t2STMIA_UPD || Opcode == ARM::t2STMDB_UPD) {
1191 MI.addOperand(MCOperand::CreateReg(Base));
1195 MI.addOperand(MCOperand::CreateReg(Base));
1198 // Handling the two predicate operands before the reglist.
1199 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps)) {
1202 DEBUG(errs() << "Expected predicate operands not found.\n");
1206 unsigned RegListBits = insn & ((1 << 16) - 1);
1208 // Fill the variadic part of reglist.
1209 for (unsigned i = 0; i < 16; ++i)
1210 if ((RegListBits >> i) & 1) {
1211 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1220 // t2LDREXD: Rd Rs Rn
1221 // t2LDREXB, t2LDREXH: Rd Rn
1222 // t2STREX: Rs Rd Rn
1223 // t2STREXD: Rm Rd Rs Rn
1224 // t2STREXB, t2STREXH: Rm Rd Rn
1225 static bool DisassembleThumb2LdStEx(MCInst &MI, unsigned Opcode, uint32_t insn,
1226 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1228 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1229 if (!OpInfo) return false;
1231 unsigned &OpIdx = NumOpsAdded;
1236 && OpInfo[0].RegClass > 0
1237 && OpInfo[1].RegClass > 0
1238 && "Expect >=2 operands and first two as reg operands");
1240 bool isStore = (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH);
1241 bool isSW = (Opcode == ARM::t2LDREX || Opcode == ARM::t2STREX);
1242 bool isDW = (Opcode == ARM::t2LDREXD || Opcode == ARM::t2STREXD);
1244 unsigned Rt = decodeRd(insn);
1245 unsigned Rt2 = decodeRs(insn); // But note that this is Rd for t2STREX.
1246 unsigned Rd = decodeRm(insn);
1247 unsigned Rn = decodeRn(insn);
1249 // Some sanity checking first.
1251 // if d == n || d == t then UNPREDICTABLE
1252 // if d == n || d == t || d == t2 then UNPREDICTABLE
1254 if (Rd == Rn || Rd == Rt || Rd == Rt2) {
1255 DEBUG(errs() << "if d == n || d == t || d == t2 then UNPREDICTABLE\n");
1260 if (Rt2 == Rn || Rt2 == Rt) {
1261 DEBUG(errs() << "if d == n || d == t then UNPREDICTABLE\n");
1265 if (Rd == Rn || Rd == Rt) {
1266 DEBUG(errs() << "if d == n || d == t then UNPREDICTABLE\n");
1274 // if t == t2 then UNPREDICTABLE
1275 if (isDW && Rt == Rt2) {
1276 DEBUG(errs() << "if t == t2 then UNPREDICTABLE\n");
1281 // Add the destination operand for store.
1283 MI.addOperand(MCOperand::CreateReg(
1284 getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1289 // Source operand for store and destination operand for load.
1290 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1294 // Thumb2 doubleword complication: with an extra source/destination operand.
1296 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
1301 // Finally add the pointer operand.
1302 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1309 // t2LDRDi8: Rd Rs Rn imm8s4 (offset mode)
1310 // t2LDRDpci: Rd Rs imm8s4 (Not decoded, prefer the generic t2LDRDi8 version)
1311 // t2STRDi8: Rd Rs Rn imm8s4 (offset mode)
1313 // Ditto for t2LDRD_PRE, t2LDRD_POST, t2STRD_PRE, t2STRD_POST, which are for
1314 // disassembly only and do not have a tied_to writeback base register operand.
1315 static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned Opcode,
1316 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1318 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1319 if (!OpInfo) return false;
1321 // Thumnb allows for specifying Rt and Rt2, unlike ARM (which has Rt2==Rt+1).
1322 unsigned Rt = decodeRd(insn);
1323 unsigned Rt2 = decodeRs(insn);
1324 unsigned Rn = decodeRn(insn);
1326 // Some sanity checking first.
1328 // A8.6.67 LDRD (literal) has its W bit as (0).
1329 if (Opcode == ARM::t2LDRDi8 || Opcode == ARM::t2LDRD_PRE || Opcode == ARM::t2LDRD_POST) {
1330 if (Rn == 15 && slice(insn, 21, 21) != 0)
1333 // For Dual Store, PC cannot be used as the base register.
1335 DEBUG(errs() << "if n == 15 then UNPREDICTABLE\n");
1340 DEBUG(errs() << "if t == t2 then UNPREDICTABLE\n");
1343 if (Opcode != ARM::t2LDRDi8 && Opcode != ARM::t2STRDi8) {
1344 if (Rn == Rt || Rn == Rt2) {
1345 DEBUG(errs() << "if wback && (n == t || n == t2) then UNPREDICTABLE\n");
1350 // Add the <Rt> <Rt2> operands.
1351 unsigned RegClassPair = OpInfo[0].RegClass;
1352 unsigned RegClassBase = OpInfo[2].RegClass;
1354 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
1356 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
1358 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassBase,
1361 switch (MI.getOpcode()) {
1362 case ARM::t2LDRD_PRE:
1363 case ARM::t2LDRD_POST:
1364 case ARM::t2STRD_PRE:
1365 case ARM::t2STRD_POST:
1366 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassBase,
1373 // Finally add (+/-)imm8*4, depending on the U bit.
1374 int Offset = getImm8(insn) * 4;
1375 if (getUBit(insn) == 0)
1377 MI.addOperand(MCOperand::CreateImm(Offset));
1378 NumOpsAdded = Added;
1383 // t2TBB, t2TBH: Rn Rm Pred-Imm Pred-CCR
1384 static bool DisassembleThumb2TB(MCInst &MI, unsigned Opcode,
1385 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1387 assert(NumOps >= 2 && "Expect >= 2 operands");
1389 // The generic version of TBB/TBH needs a base register.
1390 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1392 // Add the index register.
1393 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1400 static inline bool Thumb2ShiftOpcode(unsigned Opcode) {
1404 case ARM::t2MOVCClsl: case ARM::t2MOVCClsr:
1405 case ARM::t2MOVCCasr: case ARM::t2MOVCCror:
1406 case ARM::t2LSLri: case ARM::t2LSRri:
1407 case ARM::t2ASRri: case ARM::t2RORri:
1412 // A6.3.11 Data-processing (shifted register)
1414 // Two register operands (Rn=0b1111 no 1st operand reg): Rs Rm
1415 // Two register operands (Rs=0b1111 no dst operand reg): Rn Rm
1416 // Three register operands: Rs Rn Rm
1417 // Three register operands: (Rn=0b1111 Conditional Move) Rs Ro(TIED_TO) Rm
1419 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
1420 // register with shift forms: (Rm, ConstantShiftSpecifier).
1421 // Constant shift specifier: Imm = (ShOp | ShAmt<<3).
1423 // There are special instructions, like t2MOVsra_flag and t2MOVsrl_flag, which
1424 // only require two register operands: Rd, Rm in ARM Reference Manual terms, and
1425 // nothing else, because the shift amount is already specified.
1426 // Similar case holds for t2MOVrx, t2ADDrr, ..., etc.
1427 static bool DisassembleThumb2DPSoReg(MCInst &MI, unsigned Opcode, uint32_t insn,
1428 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1430 const MCInstrDesc &MCID = ARMInsts[Opcode];
1431 const MCOperandInfo *OpInfo = MCID.OpInfo;
1432 unsigned &OpIdx = NumOpsAdded;
1434 // Special case handling.
1435 if (Opcode == ARM::t2BR_JT) {
1437 && OpInfo[0].RegClass == ARM::GPRRegClassID
1438 && OpInfo[1].RegClass == ARM::GPRRegClassID
1439 && OpInfo[2].RegClass < 0
1440 && OpInfo[3].RegClass < 0
1441 && "Exactly 4 operands expect and first two as reg operands");
1442 // Only need to populate the src reg operand.
1443 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1445 MI.addOperand(MCOperand::CreateReg(0));
1446 MI.addOperand(MCOperand::CreateImm(0));
1447 MI.addOperand(MCOperand::CreateImm(0));
1455 && (OpInfo[0].RegClass == ARM::GPRRegClassID ||
1456 OpInfo[0].RegClass == ARM::rGPRRegClassID)
1457 && (OpInfo[1].RegClass == ARM::GPRRegClassID ||
1458 OpInfo[1].RegClass == ARM::rGPRRegClassID)
1459 && "Expect >= 2 operands and first two as reg operands");
1461 bool ThreeReg = (NumOps > 2 && (OpInfo[2].RegClass == ARM::GPRRegClassID ||
1462 OpInfo[2].RegClass == ARM::rGPRRegClassID));
1463 bool NoDstReg = (decodeRs(insn) == 0xF);
1465 // Build the register operands, followed by the constant shift specifier.
1467 MI.addOperand(MCOperand::CreateReg(
1468 getRegisterEnum(B, OpInfo[0].RegClass,
1469 NoDstReg ? decodeRn(insn) : decodeRs(insn))));
1474 if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
1475 // Process tied_to operand constraint.
1476 MI.addOperand(MI.getOperand(Idx));
1478 } else if (!NoDstReg) {
1479 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[1].RegClass,
1483 DEBUG(errs() << "Thumb2 encoding error: d==15 for three-reg operands.\n");
1488 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1492 if (NumOps == OpIdx)
1495 if (OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
1496 && !OpInfo[OpIdx].isOptionalDef()) {
1498 if (Thumb2ShiftOpcode(Opcode)) {
1499 unsigned Imm = getShiftAmtBits(insn);
1500 ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 5, 4));
1501 getImmShiftSE(ShOp, Imm);
1502 MI.addOperand(MCOperand::CreateImm(Imm));
1504 // Build the constant shift specifier operand.
1505 unsigned imm5 = getShiftAmtBits(insn);
1506 // The PKHBT/PKHTB instructions have an implied shift type and so just
1507 // use a plain immediate for the amount.
1508 if (Opcode == ARM::t2PKHBT || Opcode == ARM::t2PKHTB)
1509 MI.addOperand(MCOperand::CreateImm(imm5));
1511 ARM_AM::ShiftOpc ShOp = ARM_AM::no_shift;
1512 unsigned bits2 = getShiftTypeBits(insn);
1513 unsigned ShAmt = decodeImmShift(bits2, imm5, ShOp);
1514 MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShAmt)));
1523 // A6.3.1 Data-processing (modified immediate)
1525 // Two register operands: Rs Rn ModImm
1526 // One register operands (Rs=0b1111 no explicit dest reg): Rn ModImm
1527 // One register operands (Rn=0b1111 no explicit src reg): Rs ModImm -
1530 // ModImm = ThumbExpandImm(i:imm3:imm8)
1531 static bool DisassembleThumb2DPModImm(MCInst &MI, unsigned Opcode,
1532 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1534 const MCInstrDesc &MCID = ARMInsts[Opcode];
1535 const MCOperandInfo *OpInfo = MCID.OpInfo;
1536 unsigned &OpIdx = NumOpsAdded;
1540 unsigned RdRegClassID = OpInfo[0].RegClass;
1541 assert(NumOps >= 2 && (RdRegClassID == ARM::GPRRegClassID ||
1542 RdRegClassID == ARM::rGPRRegClassID)
1543 && "Expect >= 2 operands and first one as reg operand");
1545 unsigned RnRegClassID = OpInfo[1].RegClass;
1546 bool TwoReg = (RnRegClassID == ARM::GPRRegClassID
1547 || RnRegClassID == ARM::rGPRRegClassID);
1548 bool NoDstReg = (decodeRs(insn) == 0xF);
1550 // Build the register operands, followed by the modified immediate.
1552 MI.addOperand(MCOperand::CreateReg(
1553 getRegisterEnum(B, RdRegClassID,
1554 NoDstReg ? decodeRn(insn) : decodeRs(insn))));
1559 DEBUG(errs()<<"Thumb2 encoding error: d==15 for DPModImm 2-reg instr.\n");
1563 if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
1564 // The reg operand is tied to the first reg operand.
1565 MI.addOperand(MI.getOperand(Idx));
1567 // Add second reg operand.
1568 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
1574 // The modified immediate operand should come next.
1575 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0 &&
1576 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()
1577 && "Pure imm operand expected");
1580 // A6.3.2 Modified immediate constants in Thumb instructions
1581 unsigned imm12 = getIImm3Imm8(insn);
1582 MI.addOperand(MCOperand::CreateImm(ThumbExpandImm(imm12)));
1588 static inline bool Thumb2SaturateOpcode(unsigned Opcode) {
1590 case ARM::t2SSAT: case ARM::t2SSAT16:
1591 case ARM::t2USAT: case ARM::t2USAT16:
1598 /// DisassembleThumb2Sat - Disassemble Thumb2 saturate instructions:
1599 /// o t2SSAT, t2USAT: Rs sat_pos Rn shamt
1600 /// o t2SSAT16, t2USAT16: Rs sat_pos Rn
1601 static bool DisassembleThumb2Sat(MCInst &MI, unsigned Opcode, uint32_t insn,
1602 unsigned &NumOpsAdded, BO B) {
1603 const MCInstrDesc &MCID = ARMInsts[Opcode];
1604 NumOpsAdded = MCID.getNumOperands() - 2; // ignore predicate operands
1606 // Disassemble the register def.
1607 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
1610 unsigned Pos = slice(insn, 4, 0);
1611 MI.addOperand(MCOperand::CreateImm(Pos));
1613 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
1616 if (NumOpsAdded == 4) {
1617 // Inst{6} encodes the shift type.
1618 bool isASR = slice(insn, 6, 6);
1619 // Inst{11-7} encodes the imm5 shift amount.
1620 unsigned ShAmt = slice(insn, 11, 7);
1621 MI.addOperand(MCOperand::CreateImm(isASR << 5 | ShAmt));
1626 // A6.3.3 Data-processing (plain binary immediate)
1628 // o t2ADDri12, t2SUBri12: Rs Rn imm12
1629 // o t2LEApcrel (ADR): Rs imm12
1630 // o t2BFC (BFC): Rs Ro(TIED_TO) bf_inv_mask_imm
1631 // o t2BFI (BFI): Rs Ro(TIED_TO) Rn bf_inv_mask_imm
1632 // o t2MOVi16: Rs imm16
1633 // o t2MOVTi16: Rs imm16
1634 // o t2SBFX (SBFX): Rs Rn lsb width
1635 // o t2UBFX (UBFX): Rs Rn lsb width
1636 // o t2BFI (BFI): Rs Rn lsb width
1637 static bool DisassembleThumb2DPBinImm(MCInst &MI, unsigned Opcode,
1638 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1640 const MCInstrDesc &MCID = ARMInsts[Opcode];
1641 const MCOperandInfo *OpInfo = MCID.OpInfo;
1642 unsigned &OpIdx = NumOpsAdded;
1646 unsigned RdRegClassID = OpInfo[0].RegClass;
1647 assert(NumOps >= 2 && (RdRegClassID == ARM::GPRRegClassID ||
1648 RdRegClassID == ARM::rGPRRegClassID)
1649 && "Expect >= 2 operands and first one as reg operand");
1651 unsigned RnRegClassID = OpInfo[1].RegClass;
1652 bool TwoReg = (RnRegClassID == ARM::GPRRegClassID
1653 || RnRegClassID == ARM::rGPRRegClassID);
1655 // Build the register operand(s), followed by the immediate(s).
1657 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RdRegClassID,
1662 assert(NumOps >= 3 && "Expect >= 3 operands");
1664 if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
1665 // Process tied_to operand constraint.
1666 MI.addOperand(MI.getOperand(Idx));
1668 // Add src reg operand.
1669 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
1675 if (Opcode == ARM::t2BFI) {
1676 // Add val reg operand.
1677 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
1682 assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
1683 && !OpInfo[OpIdx].isOptionalDef()
1684 && "Pure imm operand expected");
1686 // Pre-increment OpIdx.
1689 if (Opcode == ARM::t2ADDri12 || Opcode == ARM::t2SUBri12
1690 || Opcode == ARM::t2LEApcrel)
1691 MI.addOperand(MCOperand::CreateImm(getIImm3Imm8(insn)));
1692 else if (Opcode == ARM::t2MOVi16 || Opcode == ARM::t2MOVTi16) {
1693 if (!B->tryAddingSymbolicOperand(getImm16(insn), 4, MI))
1694 MI.addOperand(MCOperand::CreateImm(getImm16(insn)));
1695 } else if (Opcode == ARM::t2BFC || Opcode == ARM::t2BFI) {
1697 if (getBitfieldInvMask(insn, mask))
1698 MI.addOperand(MCOperand::CreateImm(mask));
1702 // Handle the case of: lsb width
1703 assert((Opcode == ARM::t2SBFX || Opcode == ARM::t2UBFX)
1704 && "Unexpected opcode");
1705 MI.addOperand(MCOperand::CreateImm(getLsb(insn)));
1706 MI.addOperand(MCOperand::CreateImm(getWidthMinus1(insn)));
1714 // A6.3.4 Table A6-15 Miscellaneous control instructions
1718 static inline bool t2MiscCtrlInstr(uint32_t insn) {
1719 if (slice(insn, 31, 20) == 0xf3b && slice(insn, 15, 14) == 2 &&
1720 slice(insn, 12, 12) == 0)
1726 // A6.3.4 Branches and miscellaneous control
1729 // Branches: t2B, t2Bcc -> imm operand
1731 // Branches: t2TPsoft -> no operand
1733 // A8.6.23 BL, BLX (immediate)
1734 // Branches (defined in ARMInstrThumb.td): tBL, tBLXi -> imm operand
1739 // Miscellaneous control:
1740 // -> no operand (except pred-imm pred-ccr for CLREX, memory barrier variants)
1742 // Hint: t2NOP, t2YIELD, t2WFE, t2WFI, t2SEV
1743 // -> no operand (except pred-imm pred-ccr)
1745 // t2DBG -> imm4 = Inst{3-0}
1747 // t2MRS/t2MRSsys -> Rs
1748 // t2MSR/t2MSRsys -> Rn mask=Inst{11-8}
1749 // t2SMC -> imm4 = Inst{19-16}
1750 static bool DisassembleThumb2BrMiscCtrl(MCInst &MI, unsigned Opcode,
1751 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1756 if (Opcode == ARM::t2DMB || Opcode == ARM::t2DSB) {
1757 // Inst{3-0} encodes the memory barrier option for the variants.
1758 unsigned opt = slice(insn, 3, 0);
1760 case ARM_MB::SY: case ARM_MB::ST:
1761 case ARM_MB::ISH: case ARM_MB::ISHST:
1762 case ARM_MB::NSH: case ARM_MB::NSHST:
1763 case ARM_MB::OSH: case ARM_MB::OSHST:
1764 MI.addOperand(MCOperand::CreateImm(opt));
1772 if (t2MiscCtrlInstr(insn))
1787 // FIXME: To enable correct asm parsing and disasm of CPS we need 3 different
1788 // opcodes which match the same real instruction. This is needed since there's
1789 // no current handling of optional arguments. Fix here when a better handling
1790 // of optional arguments is implemented.
1791 if (Opcode == ARM::t2CPS3p) {
1792 MI.addOperand(MCOperand::CreateImm(slice(insn, 10, 9))); // imod
1793 MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 5))); // iflags
1794 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
1798 if (Opcode == ARM::t2CPS2p) {
1799 MI.addOperand(MCOperand::CreateImm(slice(insn, 10, 9))); // imod
1800 MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 5))); // iflags
1804 if (Opcode == ARM::t2CPS1p) {
1805 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
1810 // DBG has its option specified in Inst{3-0}.
1811 if (Opcode == ARM::t2DBG) {
1812 MI.addOperand(MCOperand::CreateImm(slice(insn, 3, 0)));
1817 // MRS and MRSsys take one GPR reg Rs.
1818 if (Opcode == ARM::t2MRS || Opcode == ARM::t2MRSsys) {
1819 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1824 // BXJ takes one GPR reg Rn.
1825 if (Opcode == ARM::t2BXJ) {
1826 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1831 // MSR take a mask, followed by one GPR reg Rn. The mask contains the R Bit in
1832 // bit 4, and the special register fields in bits 3-0.
1833 if (Opcode == ARM::t2MSR) {
1834 MI.addOperand(MCOperand::CreateImm(slice(insn, 20, 20) << 4 /* R Bit */ |
1835 slice(insn, 11, 8) /* Special Reg */));
1836 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1842 if (Opcode == ARM::t2SMC) {
1843 MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 16)));
1848 // Some instructions have predicate operands first before the immediate.
1849 if (Opcode == ARM::tBLXi || Opcode == ARM::tBL) {
1850 // Handling the two predicate operands before the imm operand.
1851 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
1854 DEBUG(errs() << "Expected predicate operands not found.\n");
1859 // Add the imm operand.
1864 assert(0 && "Unexpected opcode");
1867 Offset = decodeImm32_B_EncodingT4(insn);
1870 Offset = decodeImm32_B_EncodingT3(insn);
1873 Offset = decodeImm32_BL(insn);
1876 Offset = decodeImm32_BLX(insn);
1880 if (!B->tryAddingSymbolicOperand(Offset + B->getBuilderAddress() + 4, 4, MI))
1881 MI.addOperand(MCOperand::CreateImm(Offset));
1883 // This is an increment as some predicate operands may have been added first.
1889 static inline bool Thumb2PreloadOpcode(unsigned Opcode) {
1893 case ARM::t2PLDi12: case ARM::t2PLDi8:
1895 case ARM::t2PLDWi12: case ARM::t2PLDWi8:
1897 case ARM::t2PLIi12: case ARM::t2PLIi8:
1903 static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned Opcode, uint32_t insn,
1904 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1906 // Preload Data/Instruction requires either 2 or 3 operands.
1907 // t2PLDi12, t2PLDi8, t2PLDpci: Rn [+/-]imm12/imm8
1909 // t2PLDs: Rn Rm imm2=Inst{5-4}
1910 // Same pattern applies for t2PLDW* and t2PLI*.
1912 const MCInstrDesc &MCID = ARMInsts[Opcode];
1913 const MCOperandInfo *OpInfo = MCID.OpInfo;
1914 unsigned &OpIdx = NumOpsAdded;
1918 assert(NumOps >= 2 &&
1919 OpInfo[0].RegClass == ARM::GPRRegClassID &&
1920 "Expect >= 2 operands and first one as reg operand");
1922 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1926 if (OpInfo[OpIdx].RegClass == ARM::rGPRRegClassID) {
1927 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1930 assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
1931 && !OpInfo[OpIdx].isOptionalDef()
1932 && "Pure imm operand expected");
1934 if (Opcode == ARM::t2PLDi8 || Opcode == ARM::t2PLDWi8 ||
1935 Opcode == ARM::t2PLIi8) {
1936 // A8.6.117 Encoding T2: add = FALSE
1937 unsigned Imm8 = getImm8(insn);
1940 // The i12 forms. See, for example, A8.6.117 Encoding T1.
1941 // Note that currently t2PLDi12 also handles the previously named t2PLDpci
1942 // opcode, that's why we use decodeImm12(insn) which returns +/- imm12.
1943 Offset = decodeImm12(insn);
1945 MI.addOperand(MCOperand::CreateImm(Offset));
1949 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0 &&
1950 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
1951 // Fills in the shift amount for t2PLDs, t2PLDWs, t2PLIs.
1952 MI.addOperand(MCOperand::CreateImm(slice(insn, 5, 4)));
1959 static bool BadRegsThumb2LdSt(unsigned Opcode, uint32_t insn, bool Load,
1960 unsigned R0, unsigned R1, unsigned R2, bool UseRm, bool WB) {
1962 // Inst{22-21} encodes the data item transferred for load/store.
1963 // For single word, it is encoded as ob10.
1964 bool Word = (slice(insn, 22, 21) == 2);
1965 bool Half = (slice(insn, 22, 21) == 1);
1966 bool Byte = (slice(insn, 22, 21) == 0);
1968 if (UseRm && BadReg(R2)) {
1969 DEBUG(errs() << "if BadReg(m) then UNPREDICTABLE\n");
1974 if (!Word && R0 == 13) {
1975 DEBUG(errs() << "if t == 13 then UNPREDICTABLE\n");
1979 if (WB && R0 == 15 && slice(insn, 10, 8) == 3) {
1980 // A8.6.78 LDRSB (immediate) Encoding T2 (errata markup 8.0)
1981 DEBUG(errs() << "if t == 15 && PUW == '011' then UNPREDICTABLE\n");
1985 // A6.3.8 Load halfword, memory hints
1989 // A8.6.82 LDRSH (immediate) Encoding T2
1990 DEBUG(errs() << "if WB && n == t then UNPREDICTABLE\n");
1993 if (R0 == 15 && slice(insn, 10, 8) == 3) {
1994 // A8.6.82 LDRSH (immediate) Encoding T2 (errata markup 8.0)
1995 DEBUG(errs() << "if t == 15 && PUW == '011' then UNPREDICTABLE\n");
1999 if (Opcode == ARM::t2LDRHi8 || Opcode == ARM::t2LDRSHi8) {
2000 if (R0 == 15 && slice(insn, 10, 8) == 4) {
2001 // A8.6.82 LDRSH (immediate) Encoding T2
2002 DEBUG(errs() << "if Rt == '1111' and PUW == '100' then SEE"
2003 << " \"Unallocated memory hints\"\n");
2008 // A8.6.82 LDRSH (immediate) Encoding T1
2009 DEBUG(errs() << "if Rt == '1111' then SEE"
2010 << " \"Unallocated memory hints\"\n");
2017 if (WB && R0 == R1) {
2018 DEBUG(errs() << "if wback && n == t then UNPREDICTABLE\n");
2021 if ((WB && R0 == 15) || (!WB && R1 == 15)) {
2022 DEBUG(errs() << "if Rn == '1111' then UNDEFINED\n");
2026 if ((WB && R1 == 15) || (!WB && R0 == 15)) {
2027 DEBUG(errs() << "if t == 15 then UNPREDICTABLE\n");
2031 if ((WB && BadReg(R1)) || (!WB && BadReg(R0))) {
2032 DEBUG(errs() << "if BadReg(t) then UNPREDICTABLE\n");
2040 // A6.3.10 Store single data item
2041 // A6.3.9 Load byte, memory hints
2042 // A6.3.8 Load halfword, memory hints
2047 // t2LDRi12: Rd Rn (+)imm12
2048 // t2LDRi8: Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
2049 // t2LDRs: Rd Rn Rm ConstantShiftSpecifier (see also
2050 // DisassembleThumb2DPSoReg)
2051 // t2LDR_POST: Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
2052 // t2LDR_PRE: Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
2054 // t2STRi12: Rd Rn (+)imm12
2055 // t2STRi8: Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
2056 // t2STRs: Rd Rn Rm ConstantShiftSpecifier (see also
2057 // DisassembleThumb2DPSoReg)
2058 // t2STR_POST: Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
2059 // t2STR_PRE: Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
2061 // Note that for indexed modes, the Rn(TIED_TO) operand needs to be populated
2062 // correctly, as LLVM AsmPrinter depends on it. For indexed stores, the first
2063 // operand is Rn; for all the other instructions, Rd is the first operand.
2065 // Delegates to DisassembleThumb2PreLoad() for preload data/instruction.
2066 // Delegates to DisassembleThumb2Ldpci() for load * literal operations.
2067 static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, unsigned Opcode,
2068 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2070 unsigned Rn = decodeRn(insn);
2072 if (Thumb2PreloadOpcode(Opcode))
2073 return DisassembleThumb2PreLoad(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2075 // See, for example, A6.3.7 Load word: Table A6-18 Load word.
2076 if (Load && Rn == 15)
2077 return DisassembleThumb2Ldpci(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2078 const MCInstrDesc &MCID = ARMInsts[Opcode];
2079 const MCOperandInfo *OpInfo = MCID.OpInfo;
2080 unsigned &OpIdx = NumOpsAdded;
2084 assert(NumOps >= 3 &&
2085 OpInfo[0].RegClass > 0 &&
2086 OpInfo[1].RegClass > 0 &&
2087 "Expect >= 3 operands and first two as reg operands");
2089 bool ThreeReg = (OpInfo[2].RegClass > 0);
2090 bool TIED_TO = ThreeReg && MCID.getOperandConstraint(2, MCOI::TIED_TO) != -1;
2091 bool Imm12 = !ThreeReg && slice(insn, 23, 23) == 1; // ARMInstrThumb2.td
2093 // Build the register operands, followed by the immediate.
2094 unsigned R0 = 0, R1 = 0, R2 = 0;
2095 unsigned Rd = decodeRd(insn);
2098 if (!Load && TIED_TO) {
2108 Imm = decodeImm8(insn);
2110 R2 = decodeRm(insn);
2111 // See, for example, A8.6.64 LDRB (register).
2112 // And ARMAsmPrinter::printT2AddrModeSoRegOperand().
2113 // LSL is the default shift opc, and LLVM does not expect it to be encoded
2114 // as part of the immediate operand.
2115 // Imm = ARM_AM::getSORegOpc(ARM_AM::lsl, slice(insn, 5, 4));
2116 Imm = slice(insn, 5, 4);
2120 Imm = getImm12(insn);
2122 Imm = decodeImm8(insn);
2125 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
2128 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
2133 // This could be an offset register or a TIED_TO register.
2134 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
2139 if (BadRegsThumb2LdSt(Opcode, insn, Load, R0, R1, R2, ThreeReg & !TIED_TO,
2143 assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
2144 && !OpInfo[OpIdx].isOptionalDef()
2145 && "Pure imm operand expected");
2147 MI.addOperand(MCOperand::CreateImm(Imm));
2153 // A6.3.12 Data-processing (register)
2155 // Two register operands [rotate]: Rs Rm [rotation(= (rotate:'000'))]
2156 // Three register operands only: Rs Rn Rm
2157 // Three register operands [rotate]: Rs Rn Rm [rotation(= (rotate:'000'))]
2159 // Parallel addition and subtraction 32-bit Thumb instructions: Rs Rn Rm
2161 // Miscellaneous operations: Rs [Rn] Rm
2162 static bool DisassembleThumb2DPReg(MCInst &MI, unsigned Opcode, uint32_t insn,
2163 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2165 const MCInstrDesc &MCID = ARMInsts[Opcode];
2166 const MCOperandInfo *OpInfo = MCID.OpInfo;
2167 unsigned &OpIdx = NumOpsAdded;
2171 assert(NumOps >= 2 &&
2172 OpInfo[0].RegClass > 0 &&
2173 OpInfo[1].RegClass > 0 &&
2174 "Expect >= 2 operands and first two as reg operands");
2176 // Build the register operands, followed by the optional rotation amount.
2178 bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass > 0;
2180 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
2185 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
2190 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
2194 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0
2195 && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
2196 // Add the rotation amount immediate.
2197 MI.addOperand(MCOperand::CreateImm(slice(insn, 5, 4)));
2204 // A6.3.16 Multiply, multiply accumulate, and absolute difference
2206 // t2MLA, t2MLS, t2SMMLA, t2SMMLS: Rs Rn Rm Ra=Inst{15-12}
2207 // t2MUL, t2SMMUL: Rs Rn Rm
2208 // t2SMLA[BB|BT|TB|TT|WB|WT]: Rs Rn Rm Ra=Inst{15-12}
2209 // t2SMUL[BB|BT|TB|TT|WB|WT]: Rs Rn Rm
2211 // Dual halfword multiply: t2SMUAD[X], t2SMUSD[X], t2SMLAD[X], t2SMLSD[X]:
2212 // Rs Rn Rm Ra=Inst{15-12}
2214 // Unsigned Sum of Absolute Differences [and Accumulate]
2215 // Rs Rn Rm [Ra=Inst{15-12}]
2216 static bool DisassembleThumb2Mul(MCInst &MI, unsigned Opcode, uint32_t insn,
2217 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2219 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
2221 assert(NumOps >= 3 &&
2222 OpInfo[0].RegClass == ARM::rGPRRegClassID &&
2223 OpInfo[1].RegClass == ARM::rGPRRegClassID &&
2224 OpInfo[2].RegClass == ARM::rGPRRegClassID &&
2225 "Expect >= 3 operands and first three as reg operands");
2227 // Build the register operands.
2229 bool FourReg = NumOps > 3 && OpInfo[3].RegClass == ARM::rGPRRegClassID;
2231 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2234 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2237 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2241 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2244 NumOpsAdded = FourReg ? 4 : 3;
2249 // A6.3.17 Long multiply, long multiply accumulate, and divide
2251 // t2SMULL, t2UMULL, t2SMLAL, t2UMLAL, t2UMAAL: RdLo RdHi Rn Rm
2252 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2254 // Halfword multiple accumulate long: t2SMLAL<x><y>: RdLo RdHi Rn Rm
2255 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2257 // Dual halfword multiple: t2SMLALD[X], t2SMLSLD[X]: RdLo RdHi Rn Rm
2258 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2260 // Signed/Unsigned divide: t2SDIV, t2UDIV: Rs Rn Rm
2261 static bool DisassembleThumb2LongMul(MCInst &MI, unsigned Opcode, uint32_t insn,
2262 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2264 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
2266 assert(NumOps >= 3 &&
2267 OpInfo[0].RegClass == ARM::rGPRRegClassID &&
2268 OpInfo[1].RegClass == ARM::rGPRRegClassID &&
2269 OpInfo[2].RegClass == ARM::rGPRRegClassID &&
2270 "Expect >= 3 operands and first three as reg operands");
2272 bool FourReg = NumOps > 3 && OpInfo[3].RegClass == ARM::rGPRRegClassID;
2274 // Build the register operands.
2277 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2280 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2283 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2286 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2297 // See A6.3 32-bit Thumb instruction encoding for instruction classes
2298 // corresponding to (op1, op2, op).
2300 // Table A6-9 32-bit Thumb instruction encoding
2301 // op1 op2 op Instruction class, see
2302 // --- ------- -- -----------------------------------------------------------
2303 // 01 00xx0xx - Load/store multiple on page A6-23
2304 // 00xx1xx - Load/store dual, load/store exclusive, table branch on
2306 // 01xxxxx - Data-processing (shifted register) on page A6-31
2307 // 1xxxxxx - Coprocessor instructions on page A6-40
2308 // 10 x0xxxxx 0 Data-processing (modified immediate) on page A6-15
2309 // x1xxxxx 0 Data-processing (plain binary immediate) on page A6-19
2310 // - 1 Branches and miscellaneous control on page A6-20
2311 // 11 000xxx0 - Store single data item on page A6-30
2312 // 001xxx0 - Advanced SIMD element or structure load/store instructions
2314 // 00xx001 - Load byte, memory hints on page A6-28
2315 // 00xx011 - Load halfword, memory hints on page A6-26
2316 // 00xx101 - Load word on page A6-25
2317 // 00xx111 - UNDEFINED
2318 // 010xxxx - Data-processing (register) on page A6-33
2319 // 0110xxx - Multiply, multiply accumulate, and absolute difference on
2321 // 0111xxx - Long multiply, long multiply accumulate, and divide on
2323 // 1xxxxxx - Coprocessor instructions on page A6-40
2325 static bool DisassembleThumb2(uint16_t op1, uint16_t op2, uint16_t op,
2326 MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps,
2327 unsigned &NumOpsAdded, BO B) {
2331 if (slice(op2, 6, 5) == 0) {
2332 if (slice(op2, 2, 2) == 0) {
2333 // Load/store multiple.
2334 return DisassembleThumb2LdStMul(MI, Opcode, insn, NumOps, NumOpsAdded,
2338 // Load/store dual, load/store exclusive, table branch, otherwise.
2339 assert(slice(op2, 2, 2) == 1 && "Thumb2 encoding error!");
2340 if ((ARM::t2LDREX <= Opcode && Opcode <= ARM::t2LDREXH) ||
2341 (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH)) {
2342 // Load/store exclusive.
2343 return DisassembleThumb2LdStEx(MI, Opcode, insn, NumOps, NumOpsAdded,
2346 if (Opcode == ARM::t2LDRDi8 ||
2347 Opcode == ARM::t2LDRD_PRE || Opcode == ARM::t2LDRD_POST ||
2348 Opcode == ARM::t2STRDi8 ||
2349 Opcode == ARM::t2STRD_PRE || Opcode == ARM::t2STRD_POST) {
2351 return DisassembleThumb2LdStDual(MI, Opcode, insn, NumOps, NumOpsAdded,
2354 if (Opcode == ARM::t2TBB || Opcode == ARM::t2TBH) {
2356 return DisassembleThumb2TB(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2358 } else if (slice(op2, 6, 5) == 1) {
2359 // Data-processing (shifted register).
2360 return DisassembleThumb2DPSoReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2363 // FIXME: A6.3.18 Coprocessor instructions
2364 // But see ThumbDisassembler::getInstruction().
2369 if (slice(op2, 5, 5) == 0)
2370 // Data-processing (modified immediate)
2371 return DisassembleThumb2DPModImm(MI, Opcode, insn, NumOps, NumOpsAdded,
2373 if (Thumb2SaturateOpcode(Opcode))
2374 return DisassembleThumb2Sat(MI, Opcode, insn, NumOpsAdded, B);
2376 // Data-processing (plain binary immediate)
2377 return DisassembleThumb2DPBinImm(MI, Opcode, insn, NumOps, NumOpsAdded,
2380 // Branches and miscellaneous control on page A6-20.
2381 return DisassembleThumb2BrMiscCtrl(MI, Opcode, insn, NumOps, NumOpsAdded,
2384 switch (slice(op2, 6, 5)) {
2386 // Load/store instructions...
2387 if (slice(op2, 0, 0) == 0) {
2388 if (slice(op2, 4, 4) == 0) {
2389 // Store single data item on page A6-30
2390 return DisassembleThumb2LdSt(false, MI,Opcode,insn,NumOps,NumOpsAdded,
2393 // FIXME: Advanced SIMD element or structure load/store instructions.
2394 // But see ThumbDisassembler::getInstruction().
2398 // Table A6-9 32-bit Thumb instruction encoding: Load byte|halfword|word
2399 return DisassembleThumb2LdSt(true, MI, Opcode, insn, NumOps,
2404 if (slice(op2, 4, 4) == 0) {
2405 // A6.3.12 Data-processing (register)
2406 return DisassembleThumb2DPReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2407 } else if (slice(op2, 3, 3) == 0) {
2408 // A6.3.16 Multiply, multiply accumulate, and absolute difference
2409 return DisassembleThumb2Mul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2411 // A6.3.17 Long multiply, long multiply accumulate, and divide
2412 return DisassembleThumb2LongMul(MI, Opcode, insn, NumOps, NumOpsAdded,
2417 // FIXME: A6.3.18 Coprocessor instructions
2418 // But see ThumbDisassembler::getInstruction().
2425 assert(0 && "Thumb2 encoding error!");
2432 static bool DisassembleThumbFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
2433 unsigned short NumOps, unsigned &NumOpsAdded, BO Builder) {
2435 uint16_t HalfWord = slice(insn, 31, 16);
2437 if (HalfWord == 0) {
2438 // A6.2 16-bit Thumb instruction encoding
2440 uint16_t op = slice(insn, 15, 10);
2441 return DisassembleThumb1(op, MI, Opcode, insn, NumOps, NumOpsAdded,
2445 unsigned bits15_11 = slice(HalfWord, 15, 11);
2447 // A6.1 Thumb instruction set encoding
2448 if (!(bits15_11 == 0x1D || bits15_11 == 0x1E || bits15_11 == 0x1F)) {
2449 assert("Bits[15:11] first halfword of Thumb2 instruction is out of range");
2453 // A6.3 32-bit Thumb instruction encoding
2455 uint16_t op1 = slice(HalfWord, 12, 11);
2456 uint16_t op2 = slice(HalfWord, 10, 4);
2457 uint16_t op = slice(insn, 15, 15);
2459 return DisassembleThumb2(op1, op2, op, MI, Opcode, insn, NumOps, NumOpsAdded,