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 // See, for example, A8.6.221 SXTAB16.
327 static inline unsigned decodeRotate(uint32_t insn) {
328 unsigned rotate = slice(insn, 5, 4);
332 ///////////////////////////////////////////////
334 // Thumb1 instruction disassembly functions. //
336 ///////////////////////////////////////////////
338 // See "Utilities for 16-bit Thumb instructions" for register naming convention.
340 // A6.2.1 Shift (immediate), add, subtract, move, and compare
342 // shift immediate: tRd CPSR tRn imm5
343 // add/sub register: tRd CPSR tRn tRm
344 // add/sub 3-bit immediate: tRd CPSR tRn imm3
345 // add/sub 8-bit immediate: tRt CPSR tRt(TIED_TO) imm8
346 // mov/cmp immediate: tRt [CPSR] imm8 (CPSR present for mov)
350 static bool DisassembleThumb1General(MCInst &MI, unsigned Opcode, uint32_t insn,
351 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
353 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
354 unsigned &OpIdx = NumOpsAdded;
358 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID
359 && "Invalid arguments");
361 bool Imm3 = (Opcode == ARM::tADDi3 || Opcode == ARM::tSUBi3);
363 // Use Rt implies use imm8.
364 bool UseRt = (Opcode == ARM::tADDi8 || Opcode == ARM::tSUBi8 ||
365 Opcode == ARM::tMOVi8 || Opcode == ARM::tCMPi8);
367 // Add the destination operand.
368 MI.addOperand(MCOperand::CreateReg(
369 getRegisterEnum(B, ARM::tGPRRegClassID,
370 UseRt ? getT1tRt(insn) : getT1tRd(insn))));
373 // Check whether the next operand to be added is a CCR Register.
374 if (OpInfo[OpIdx].RegClass == ARM::CCRRegClassID) {
375 assert(OpInfo[OpIdx].isOptionalDef() && "Optional def operand expected");
376 MI.addOperand(MCOperand::CreateReg(B->InITBlock() ? 0 : ARM::CPSR));
380 // Check whether the next operand to be added is a Thumb1 Register.
381 assert(OpIdx < NumOps && "More operands expected");
382 if (OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
383 // For UseRt, the reg operand is tied to the first reg operand.
384 MI.addOperand(MCOperand::CreateReg(
385 getRegisterEnum(B, ARM::tGPRRegClassID,
386 UseRt ? getT1tRt(insn) : getT1tRn(insn))));
390 // Special case for tMOVSr.
394 // The next available operand is either a reg operand or an imm operand.
395 if (OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
396 // Three register operand instructions.
397 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
400 assert(OpInfo[OpIdx].RegClass < 0 &&
401 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()
402 && "Pure imm operand expected");
405 Imm = getT1Imm8(insn);
407 Imm = getT1Imm3(insn);
409 Imm = getT1Imm5(insn);
410 ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 12, 11));
411 getImmShiftSE(ShOp, Imm);
413 MI.addOperand(MCOperand::CreateImm(Imm));
420 // A6.2.2 Data-processing
422 // tCMPr, tTST, tCMN: tRd tRn
423 // tMVN, tRSB: tRd CPSR tRn
424 // Others: tRd CPSR tRd(TIED_TO) tRn
425 static bool DisassembleThumb1DP(MCInst &MI, unsigned Opcode, uint32_t insn,
426 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
428 const TargetInstrDesc &TID = ARMInsts[Opcode];
429 const TargetOperandInfo *OpInfo = TID.OpInfo;
430 unsigned &OpIdx = NumOpsAdded;
434 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
435 (OpInfo[1].RegClass == ARM::CCRRegClassID
436 || OpInfo[1].RegClass == ARM::tGPRRegClassID)
437 && "Invalid arguments");
439 // Add the destination operand.
440 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
444 // Check whether the next operand to be added is a CCR Register.
445 if (OpInfo[OpIdx].RegClass == ARM::CCRRegClassID) {
446 assert(OpInfo[OpIdx].isOptionalDef() && "Optional def operand expected");
447 MI.addOperand(MCOperand::CreateReg(B->InITBlock() ? 0 : ARM::CPSR));
451 // We have either { tRd(TIED_TO), tRn } or { tRn } remaining.
452 // Process the TIED_TO operand first.
454 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
455 && "Thumb reg operand expected");
457 if ((Idx = TID.getOperandConstraint(OpIdx, TOI::TIED_TO)) != -1) {
458 // The reg operand is tied to the first reg operand.
459 MI.addOperand(MI.getOperand(Idx));
463 // Process possible next reg operand.
464 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
466 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
474 // A6.2.3 Special data instructions and branch and exchange
476 // tADDhirr: Rd Rd(TIED_TO) Rm
478 // tMOVr, tMOVgpr2gpr, tMOVgpr2tgpr, tMOVtgpr2gpr: Rd|tRd Rm|tRn
479 // tBX_RET: 0 operand
480 // tBX_RET_vararg: Rm
482 static bool DisassembleThumb1Special(MCInst &MI, unsigned Opcode, uint32_t insn,
483 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
485 // tBX_RET has 0 operand.
489 // BX/BLX has 1 reg operand: Rm.
490 if (Opcode == ARM::tBLXr_r9 || Opcode == ARM::tBX_Rm) {
491 // Handling the two predicate operands before the reg operand.
492 if (!B->DoPredicateOperands(MI, Opcode, insn, NumOps))
494 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
500 const TargetInstrDesc &TID = ARMInsts[Opcode];
501 const TargetOperandInfo *OpInfo = TID.OpInfo;
502 unsigned &OpIdx = NumOpsAdded;
506 // Add the destination operand.
507 unsigned RegClass = OpInfo[OpIdx].RegClass;
508 MI.addOperand(MCOperand::CreateReg(
509 getRegisterEnum(B, RegClass,
510 IsGPR(RegClass) ? getT1Rd(insn)
514 // We have either { Rd(TIED_TO), Rm } or { Rm|tRn } remaining.
515 // Process the TIED_TO operand first.
517 assert(OpIdx < NumOps && "More operands expected");
519 if ((Idx = TID.getOperandConstraint(OpIdx, TOI::TIED_TO)) != -1) {
520 // The reg operand is tied to the first reg operand.
521 MI.addOperand(MI.getOperand(Idx));
525 // The next reg operand is either Rm or tRn.
526 assert(OpIdx < NumOps && "More operands expected");
527 RegClass = OpInfo[OpIdx].RegClass;
528 MI.addOperand(MCOperand::CreateReg(
529 getRegisterEnum(B, RegClass,
530 IsGPR(RegClass) ? getT1Rm(insn)
537 // A8.6.59 LDR (literal)
539 // tLDRpci: tRt imm8*4
540 static bool DisassembleThumb1LdPC(MCInst &MI, unsigned Opcode, uint32_t insn,
541 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
543 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
544 if (!OpInfo) return false;
546 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
547 (OpInfo[1].RegClass < 0 &&
548 !OpInfo[1].isPredicate() &&
549 !OpInfo[1].isOptionalDef())
550 && "Invalid arguments");
552 // Add the destination operand.
553 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
556 // And the (imm8 << 2) operand.
557 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn) << 2));
564 // Thumb specific addressing modes (see ARMInstrThumb.td):
566 // t_addrmode_rr := reg + reg
568 // t_addrmode_s4 := reg + reg
571 // t_addrmode_s2 := reg + reg
574 // t_addrmode_s1 := reg + reg
577 // t_addrmode_sp := sp + imm8 * 4
580 // A8.6.63 LDRB (literal)
581 // A8.6.79 LDRSB (literal)
582 // A8.6.75 LDRH (literal)
583 // A8.6.83 LDRSH (literal)
584 // A8.6.59 LDR (literal)
586 // These instrs calculate an address from the PC value and an immediate offset.
587 // Rd Rn=PC (+/-)imm12 (+ if Inst{23} == 0b1)
588 static bool DisassembleThumb2Ldpci(MCInst &MI, unsigned Opcode,
589 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
591 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
592 if (!OpInfo) return false;
594 assert(NumOps >= 2 &&
595 OpInfo[0].RegClass == ARM::GPRRegClassID &&
596 OpInfo[1].RegClass < 0 &&
597 "Expect >= 2 operands, first as reg, and second as imm operand");
599 // Build the register operand, followed by the (+/-)imm12 immediate.
601 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
604 MI.addOperand(MCOperand::CreateImm(decodeImm12(insn)));
612 // A6.2.4 Load/store single data item
614 // Load/Store Register (reg|imm): tRd tRn imm5|tRm
615 // Load Register Signed Byte|Halfword: tRd tRn tRm
616 static bool DisassembleThumb1LdSt(unsigned opA, MCInst &MI, unsigned Opcode,
617 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
619 const TargetInstrDesc &TID = ARMInsts[Opcode];
620 const TargetOperandInfo *OpInfo = TID.OpInfo;
621 unsigned &OpIdx = NumOpsAdded;
624 && OpInfo[0].RegClass == ARM::tGPRRegClassID
625 && OpInfo[1].RegClass == ARM::tGPRRegClassID
626 && "Expect >= 2 operands and first two as thumb reg operands");
628 // Add the destination reg and the base reg.
629 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
631 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
635 // We have either { imm5 } or { tRm } remaining.
636 // Note that STR/LDR (register) should skip the imm5 offset operand for
637 // t_addrmode_s[1|2|4].
639 assert(OpIdx < NumOps && "More operands expected");
641 if (OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate() &&
642 !OpInfo[OpIdx].isOptionalDef()) {
643 // Table A6-5 16-bit Thumb Load/store instructions
644 // opA = 0b0101 for STR/LDR (register) and friends.
645 // Otherwise, we have STR/LDR (immediate) and friends.
646 assert(opA != 5 && "Immediate operand expected for this opcode");
647 MI.addOperand(MCOperand::CreateImm(getT1Imm5(insn)));
650 // The next reg operand is tRm, the offset.
651 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
652 && "Thumb reg operand expected");
653 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
660 // A6.2.4 Load/store single data item
662 // Load/Store Register SP relative: tRt ARM::SP imm8
663 static bool DisassembleThumb1LdStSP(MCInst &MI, unsigned Opcode, uint32_t insn,
664 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
666 assert((Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi)
667 && "Unexpected opcode");
669 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
670 if (!OpInfo) return false;
672 assert(NumOps >= 3 &&
673 OpInfo[0].RegClass == ARM::tGPRRegClassID &&
674 OpInfo[1].RegClass == ARM::GPRRegClassID &&
675 (OpInfo[2].RegClass < 0 &&
676 !OpInfo[2].isPredicate() &&
677 !OpInfo[2].isOptionalDef())
678 && "Invalid arguments");
680 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
682 MI.addOperand(MCOperand::CreateReg(ARM::SP));
683 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
688 // Table A6-1 16-bit Thumb instruction encoding
691 // tADDrPCi: tRt imm8
692 static bool DisassembleThumb1AddPCi(MCInst &MI, unsigned Opcode, uint32_t insn,
693 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
695 assert(Opcode == ARM::tADDrPCi && "Unexpected opcode");
697 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
698 if (!OpInfo) return false;
700 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
701 (OpInfo[1].RegClass < 0 &&
702 !OpInfo[1].isPredicate() &&
703 !OpInfo[1].isOptionalDef())
704 && "Invalid arguments");
706 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
708 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
713 // Table A6-1 16-bit Thumb instruction encoding
714 // A8.6.8 ADD (SP plus immediate)
716 // tADDrSPi: tRt ARM::SP imm8
717 static bool DisassembleThumb1AddSPi(MCInst &MI, unsigned Opcode, uint32_t insn,
718 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
720 assert(Opcode == ARM::tADDrSPi && "Unexpected opcode");
722 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
723 if (!OpInfo) return false;
725 assert(NumOps >= 3 &&
726 OpInfo[0].RegClass == ARM::tGPRRegClassID &&
727 OpInfo[1].RegClass == ARM::GPRRegClassID &&
728 (OpInfo[2].RegClass < 0 &&
729 !OpInfo[2].isPredicate() &&
730 !OpInfo[2].isOptionalDef())
731 && "Invalid arguments");
733 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
735 MI.addOperand(MCOperand::CreateReg(ARM::SP));
736 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
741 // tPUSH, tPOP: Pred-Imm Pred-CCR register_list
743 // where register_list = low registers + [lr] for PUSH or
744 // low registers + [pc] for POP
746 // "low registers" is specified by Inst{7-0}
747 // lr|pc is specified by Inst{8}
748 static bool DisassembleThumb1PushPop(MCInst &MI, unsigned Opcode, uint32_t insn,
749 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
751 assert((Opcode == ARM::tPUSH || Opcode == ARM::tPOP) && "Unexpected opcode");
753 unsigned &OpIdx = NumOpsAdded;
755 // Handling the two predicate operands before the reglist.
756 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
759 DEBUG(errs() << "Expected predicate operands not found.\n");
763 unsigned RegListBits = slice(insn, 8, 8) << (Opcode == ARM::tPUSH ? 14 : 15)
766 // Fill the variadic part of reglist.
767 for (unsigned i = 0; i < 16; ++i) {
768 if ((RegListBits >> i) & 1) {
769 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
778 // A6.2.5 Miscellaneous 16-bit instructions
779 // Delegate to DisassembleThumb1PushPop() for tPUSH & tPOP.
781 // tADDspi, tSUBspi: ARM::SP ARM::SP(TIED_TO) imm7
782 // t2IT: firstcond=Inst{7-4} mask=Inst{3-0}
783 // tCBNZ, tCBZ: tRd imm6*2
785 // tNOP, tSEV, tYIELD, tWFE, tWFI:
786 // no operand (except predicate pair)
787 // tSETENDBE, tSETENDLE, :
790 static bool DisassembleThumb1Misc(MCInst &MI, unsigned Opcode, uint32_t insn,
791 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
796 if (Opcode == ARM::tPUSH || Opcode == ARM::tPOP)
797 return DisassembleThumb1PushPop(MI, Opcode, insn, NumOps, NumOpsAdded, B);
799 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
801 // Predicate operands are handled elsewhere.
803 OpInfo[0].isPredicate() && OpInfo[1].isPredicate() &&
804 OpInfo[0].RegClass < 0 && OpInfo[1].RegClass == ARM::CCRRegClassID) {
808 if (Opcode == ARM::tADDspi || Opcode == ARM::tSUBspi) {
809 // Special case handling for tADDspi and tSUBspi.
810 // A8.6.8 ADD (SP plus immediate) & A8.6.215 SUB (SP minus immediate)
811 MI.addOperand(MCOperand::CreateReg(ARM::SP));
812 MI.addOperand(MCOperand::CreateReg(ARM::SP));
813 MI.addOperand(MCOperand::CreateImm(getT1Imm7(insn)));
818 if (Opcode == ARM::t2IT) {
819 // Special case handling for If-Then.
821 // Tag the (firstcond[0] bit << 4) along with mask.
824 MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 4)));
826 // firstcond[0] and mask
827 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
832 if (Opcode == ARM::tBKPT) {
833 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn))); // breakpoint value
838 // CPS has a singleton $opt operand that contains the following information:
839 // The first op would be 0b10 as enable and 0b11 as disable in regular ARM,
840 // but in Thumb it's is 0 as enable and 1 as disable. So map it to ARM's
841 // default one. The second get the AIF flags from Inst{2-0}.
842 if (Opcode == ARM::tCPS) {
843 MI.addOperand(MCOperand::CreateImm(2 + slice(insn, 4, 4)));
844 MI.addOperand(MCOperand::CreateImm(slice(insn, 2, 0)));
849 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
850 (OpInfo[1].RegClass < 0 || OpInfo[1].RegClass==ARM::tGPRRegClassID)
851 && "Expect >=2 operands");
853 // Add the destination operand.
854 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
857 if (OpInfo[1].RegClass == ARM::tGPRRegClassID) {
858 // Two register instructions.
859 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
863 assert((Opcode == ARM::tCBNZ || Opcode == ARM::tCBZ) &&"Unexpected opcode");
864 MI.addOperand(MCOperand::CreateImm(getT1Imm6(insn) * 2));
872 // A8.6.53 LDM / LDMIA
873 // A8.6.189 STM / STMIA
875 // tLDMIA_UPD/tSTMIA_UPD: tRt tRt AM4ModeImm Pred-Imm Pred-CCR register_list
876 // tLDMIA: tRt AM4ModeImm Pred-Imm Pred-CCR register_list
877 static bool DisassembleThumb1LdStMul(bool Ld, MCInst &MI, unsigned Opcode,
878 uint32_t insn, unsigned short NumOps,
879 unsigned &NumOpsAdded, BO B) {
880 assert((Opcode == ARM::tLDMIA || Opcode == ARM::tLDMIA_UPD ||
881 Opcode == ARM::tSTMIA_UPD) && "Unexpected opcode");
883 unsigned tRt = getT1tRt(insn);
886 // WB register, if necessary.
887 if (Opcode == ARM::tLDMIA_UPD || Opcode == ARM::tSTMIA_UPD) {
888 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
893 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
897 // Handling the two predicate operands before the reglist.
898 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps)) {
901 DEBUG(errs() << "Expected predicate operands not found.\n");
905 unsigned RegListBits = slice(insn, 7, 0);
906 if (BitCount(RegListBits) < 1) {
907 DEBUG(errs() << "if BitCount(registers) < 1 then UNPREDICTABLE\n");
911 // Fill the variadic part of reglist.
912 for (unsigned i = 0; i < 8; ++i)
913 if ((RegListBits >> i) & 1) {
914 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
922 static bool DisassembleThumb1LdMul(MCInst &MI, unsigned Opcode, uint32_t insn,
923 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
924 return DisassembleThumb1LdStMul(true, MI, Opcode, insn, NumOps, NumOpsAdded,
928 static bool DisassembleThumb1StMul(MCInst &MI, unsigned Opcode, uint32_t insn,
929 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
930 return DisassembleThumb1LdStMul(false, MI, Opcode, insn, NumOps, NumOpsAdded,
934 // A8.6.16 B Encoding T1
935 // cond = Inst{11-8} & imm8 = Inst{7-0}
936 // imm32 = SignExtend(imm8:'0', 32)
938 // tBcc: offset Pred-Imm Pred-CCR
939 // tSVC: imm8 Pred-Imm Pred-CCR
940 // tTRAP: 0 operand (early return)
941 static bool DisassembleThumb1CondBr(MCInst &MI, unsigned Opcode, uint32_t insn,
942 unsigned short NumOps, unsigned &NumOpsAdded, BO) {
944 if (Opcode == ARM::tTRAP)
947 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
948 if (!OpInfo) return false;
950 assert(NumOps == 3 && OpInfo[0].RegClass < 0 &&
951 OpInfo[1].isPredicate() && OpInfo[2].RegClass == ARM::CCRRegClassID
952 && "Exactly 3 operands expected");
954 unsigned Imm8 = getT1Imm8(insn);
955 MI.addOperand(MCOperand::CreateImm(
956 Opcode == ARM::tBcc ? SignExtend32<9>(Imm8 << 1) + 4
959 // Predicate operands by ARMBasicMCBuilder::TryPredicateAndSBitModifier().
960 // But note that for tBcc, if cond = '1110' then UNDEFINED.
961 if (Opcode == ARM::tBcc && slice(insn, 11, 8) == 14) {
962 DEBUG(errs() << "if cond = '1110' then UNDEFINED\n");
970 // A8.6.16 B Encoding T2
971 // imm11 = Inst{10-0}
972 // imm32 = SignExtend(imm11:'0', 32)
975 static bool DisassembleThumb1Br(MCInst &MI, unsigned Opcode, uint32_t insn,
976 unsigned short NumOps, unsigned &NumOpsAdded, BO) {
978 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
979 if (!OpInfo) return false;
981 assert(NumOps == 1 && OpInfo[0].RegClass < 0 && "1 imm operand expected");
983 unsigned Imm11 = getT1Imm11(insn);
985 MI.addOperand(MCOperand::CreateImm(SignExtend32<12>(Imm11 << 1)));
993 // See A6.2 16-bit Thumb instruction encoding for instruction classes
994 // corresponding to op.
996 // Table A6-1 16-bit Thumb instruction encoding (abridged)
997 // op Instruction or instruction class
998 // ------ --------------------------------------------------------------------
999 // 00xxxx Shift (immediate), add, subtract, move, and compare on page A6-7
1000 // 010000 Data-processing on page A6-8
1001 // 010001 Special data instructions and branch and exchange on page A6-9
1002 // 01001x Load from Literal Pool, see LDR (literal) on page A8-122
1003 // 0101xx Load/store single data item on page A6-10
1006 // 10100x Generate PC-relative address, see ADR on page A8-32
1007 // 10101x Generate SP-relative address, see ADD (SP plus immediate) on
1009 // 1011xx Miscellaneous 16-bit instructions on page A6-11
1010 // 11000x Store multiple registers, see STM / STMIA / STMEA on page A8-374
1011 // 11001x Load multiple registers, see LDM / LDMIA / LDMFD on page A8-110 a
1012 // 1101xx Conditional branch, and Supervisor Call on page A6-13
1013 // 11100x Unconditional Branch, see B on page A8-44
1015 static bool DisassembleThumb1(uint16_t op, MCInst &MI, unsigned Opcode,
1016 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1018 unsigned op1 = slice(op, 5, 4);
1019 unsigned op2 = slice(op, 3, 2);
1020 unsigned op3 = slice(op, 1, 0);
1021 unsigned opA = slice(op, 5, 2);
1024 // A6.2.1 Shift (immediate), add, subtract, move, and compare
1025 return DisassembleThumb1General(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1031 // A6.2.2 Data-processing
1032 return DisassembleThumb1DP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1034 // A6.2.3 Special data instructions and branch and exchange
1035 return DisassembleThumb1Special(MI, Opcode, insn, NumOps, NumOpsAdded,
1038 // A8.6.59 LDR (literal)
1039 return DisassembleThumb1LdPC(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1043 // A6.2.4 Load/store single data item
1044 return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
1052 // A6.2.4 Load/store single data item
1053 return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
1056 // A6.2.4 Load/store single data item
1057 return DisassembleThumb1LdStSP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1061 return DisassembleThumb1AddPCi(MI, Opcode, insn, NumOps, NumOpsAdded,
1064 // A8.6.8 ADD (SP plus immediate)
1065 return DisassembleThumb1AddSPi(MI, Opcode, insn, NumOps, NumOpsAdded,
1069 // A6.2.5 Miscellaneous 16-bit instructions
1070 return DisassembleThumb1Misc(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1077 // A8.6.189 STM / STMIA / STMEA
1078 return DisassembleThumb1StMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1080 // A8.6.53 LDM / LDMIA / LDMFD
1081 return DisassembleThumb1LdMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1084 // A6.2.6 Conditional branch, and Supervisor Call
1085 return DisassembleThumb1CondBr(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1087 // Unconditional Branch, see B on page A8-44
1088 return DisassembleThumb1Br(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1090 assert(0 && "Unreachable code");
1095 assert(0 && "Unreachable code");
1102 ///////////////////////////////////////////////
1104 // Thumb2 instruction disassembly functions. //
1106 ///////////////////////////////////////////////
1108 ///////////////////////////////////////////////////////////
1110 // Note: the register naming follows the ARM convention! //
1112 ///////////////////////////////////////////////////////////
1114 static inline bool Thumb2SRSOpcode(unsigned Opcode) {
1118 case ARM::t2SRSDBW: case ARM::t2SRSDB:
1119 case ARM::t2SRSIAW: case ARM::t2SRSIA:
1124 static inline bool Thumb2RFEOpcode(unsigned Opcode) {
1128 case ARM::t2RFEDBW: case ARM::t2RFEDB:
1129 case ARM::t2RFEIAW: case ARM::t2RFEIA:
1134 // t2SRS[IA|DB]W/t2SRS[IA|DB]: mode_imm = Inst{4-0}
1135 static bool DisassembleThumb2SRS(MCInst &MI, unsigned Opcode, uint32_t insn,
1136 unsigned short NumOps, unsigned &NumOpsAdded) {
1137 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
1142 // t2RFE[IA|DB]W/t2RFE[IA|DB]: Rn
1143 static bool DisassembleThumb2RFE(MCInst &MI, unsigned Opcode, uint32_t insn,
1144 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1145 unsigned Rn = decodeRn(insn);
1147 DEBUG(errs() << "if n == 15 then UNPREDICTABLE\n");
1150 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,ARM::GPRRegClassID,Rn)));
1155 static bool DisassembleThumb2LdStMul(MCInst &MI, unsigned Opcode, uint32_t insn,
1156 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1158 if (Thumb2SRSOpcode(Opcode))
1159 return DisassembleThumb2SRS(MI, Opcode, insn, NumOps, NumOpsAdded);
1161 if (Thumb2RFEOpcode(Opcode))
1162 return DisassembleThumb2RFE(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1164 assert((Opcode == ARM::t2LDMIA || Opcode == ARM::t2LDMIA_UPD ||
1165 Opcode == ARM::t2LDMDB || Opcode == ARM::t2LDMDB_UPD ||
1166 Opcode == ARM::t2STMIA || Opcode == ARM::t2STMIA_UPD ||
1167 Opcode == ARM::t2STMDB || Opcode == ARM::t2STMDB_UPD)
1168 && "Unexpected opcode");
1169 assert(NumOps >= 4 && "Thumb2 LdStMul expects NumOps >= 4");
1173 unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
1175 // Writeback to base.
1176 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD ||
1177 Opcode == ARM::t2STMIA_UPD || Opcode == ARM::t2STMDB_UPD) {
1178 MI.addOperand(MCOperand::CreateReg(Base));
1182 MI.addOperand(MCOperand::CreateReg(Base));
1185 // Handling the two predicate operands before the reglist.
1186 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps)) {
1189 DEBUG(errs() << "Expected predicate operands not found.\n");
1193 unsigned RegListBits = insn & ((1 << 16) - 1);
1195 // Fill the variadic part of reglist.
1196 for (unsigned i = 0; i < 16; ++i)
1197 if ((RegListBits >> i) & 1) {
1198 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1207 // t2LDREXD: Rd Rs Rn
1208 // t2LDREXB, t2LDREXH: Rd Rn
1209 // t2STREX: Rs Rd Rn
1210 // t2STREXD: Rm Rd Rs Rn
1211 // t2STREXB, t2STREXH: Rm Rd Rn
1212 static bool DisassembleThumb2LdStEx(MCInst &MI, unsigned Opcode, uint32_t insn,
1213 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1215 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1216 if (!OpInfo) return false;
1218 unsigned &OpIdx = NumOpsAdded;
1223 && OpInfo[0].RegClass > 0
1224 && OpInfo[1].RegClass > 0
1225 && "Expect >=2 operands and first two as reg operands");
1227 bool isStore = (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH);
1228 bool isSW = (Opcode == ARM::t2LDREX || Opcode == ARM::t2STREX);
1229 bool isDW = (Opcode == ARM::t2LDREXD || Opcode == ARM::t2STREXD);
1231 // Add the destination operand for store.
1233 MI.addOperand(MCOperand::CreateReg(
1234 getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1235 isSW ? decodeRs(insn) : decodeRm(insn))));
1239 // Source operand for store and destination operand for load.
1240 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1244 // Thumb2 doubleword complication: with an extra source/destination operand.
1246 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
1251 // Finally add the pointer operand.
1252 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1259 // t2LDRDi8: Rd Rs Rn imm8s4 (offset mode)
1260 // t2LDRDpci: Rd Rs imm8s4 (Not decoded, prefer the generic t2LDRDi8 version)
1261 // t2STRDi8: Rd Rs Rn imm8s4 (offset mode)
1263 // Ditto for t2LDRD_PRE, t2LDRD_POST, t2STRD_PRE, t2STRD_POST, which are for
1264 // disassembly only and do not have a tied_to writeback base register operand.
1265 static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned Opcode,
1266 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1268 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1269 if (!OpInfo) return false;
1272 && OpInfo[0].RegClass > 0
1273 && OpInfo[0].RegClass == OpInfo[1].RegClass
1274 && OpInfo[2].RegClass > 0
1275 && OpInfo[3].RegClass < 0
1276 && "Expect >= 4 operands and first 3 as reg operands");
1278 // Add the <Rt> <Rt2> operands.
1279 unsigned RegClassPair = OpInfo[0].RegClass;
1280 unsigned RegClassBase = OpInfo[2].RegClass;
1282 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
1284 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
1286 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassBase,
1289 // Finally add (+/-)imm8*4, depending on the U bit.
1290 int Offset = getImm8(insn) * 4;
1291 if (getUBit(insn) == 0)
1293 MI.addOperand(MCOperand::CreateImm(Offset));
1299 // t2TBB, t2TBH: Rn Rm Pred-Imm Pred-CCR
1300 static bool DisassembleThumb2TB(MCInst &MI, unsigned Opcode,
1301 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1303 assert(NumOps >= 2 && "Expect >= 2 operands");
1305 // The generic version of TBB/TBH needs a base register.
1306 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1308 // Add the index register.
1309 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1316 static inline bool Thumb2ShiftOpcode(unsigned Opcode) {
1320 case ARM::t2MOVCClsl: case ARM::t2MOVCClsr:
1321 case ARM::t2MOVCCasr: case ARM::t2MOVCCror:
1322 case ARM::t2LSLri: case ARM::t2LSRri:
1323 case ARM::t2ASRri: case ARM::t2RORri:
1328 // A6.3.11 Data-processing (shifted register)
1330 // Two register operands (Rn=0b1111 no 1st operand reg): Rs Rm
1331 // Two register operands (Rs=0b1111 no dst operand reg): Rn Rm
1332 // Three register operands: Rs Rn Rm
1333 // Three register operands: (Rn=0b1111 Conditional Move) Rs Ro(TIED_TO) Rm
1335 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
1336 // register with shift forms: (Rm, ConstantShiftSpecifier).
1337 // Constant shift specifier: Imm = (ShOp | ShAmt<<3).
1339 // There are special instructions, like t2MOVsra_flag and t2MOVsrl_flag, which
1340 // only require two register operands: Rd, Rm in ARM Reference Manual terms, and
1341 // nothing else, because the shift amount is already specified.
1342 // Similar case holds for t2MOVrx, t2ADDrr, ..., etc.
1343 static bool DisassembleThumb2DPSoReg(MCInst &MI, unsigned Opcode, uint32_t insn,
1344 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1346 const TargetInstrDesc &TID = ARMInsts[Opcode];
1347 const TargetOperandInfo *OpInfo = TID.OpInfo;
1348 unsigned &OpIdx = NumOpsAdded;
1350 // Special case handling.
1351 if (Opcode == ARM::t2BR_JT) {
1353 && OpInfo[0].RegClass == ARM::GPRRegClassID
1354 && OpInfo[1].RegClass == ARM::GPRRegClassID
1355 && OpInfo[2].RegClass < 0
1356 && OpInfo[3].RegClass < 0
1357 && "Exactly 4 operands expect and first two as reg operands");
1358 // Only need to populate the src reg operand.
1359 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1361 MI.addOperand(MCOperand::CreateReg(0));
1362 MI.addOperand(MCOperand::CreateImm(0));
1363 MI.addOperand(MCOperand::CreateImm(0));
1371 && (OpInfo[0].RegClass == ARM::GPRRegClassID ||
1372 OpInfo[0].RegClass == ARM::rGPRRegClassID)
1373 && (OpInfo[1].RegClass == ARM::GPRRegClassID ||
1374 OpInfo[1].RegClass == ARM::rGPRRegClassID)
1375 && "Expect >= 2 operands and first two as reg operands");
1377 bool ThreeReg = (NumOps > 2 && (OpInfo[2].RegClass == ARM::GPRRegClassID ||
1378 OpInfo[2].RegClass == ARM::rGPRRegClassID));
1379 bool NoDstReg = (decodeRs(insn) == 0xF);
1381 // Build the register operands, followed by the constant shift specifier.
1383 MI.addOperand(MCOperand::CreateReg(
1384 getRegisterEnum(B, OpInfo[0].RegClass,
1385 NoDstReg ? decodeRn(insn) : decodeRs(insn))));
1390 if ((Idx = TID.getOperandConstraint(OpIdx, TOI::TIED_TO)) != -1) {
1391 // Process tied_to operand constraint.
1392 MI.addOperand(MI.getOperand(Idx));
1394 } else if (!NoDstReg) {
1395 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[1].RegClass,
1399 DEBUG(errs() << "Thumb2 encoding error: d==15 for three-reg operands.\n");
1404 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1408 if (NumOps == OpIdx)
1411 if (OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
1412 && !OpInfo[OpIdx].isOptionalDef()) {
1414 if (Thumb2ShiftOpcode(Opcode)) {
1415 unsigned Imm = getShiftAmtBits(insn);
1416 ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 5, 4));
1417 getImmShiftSE(ShOp, Imm);
1418 MI.addOperand(MCOperand::CreateImm(Imm));
1420 // Build the constant shift specifier operand.
1421 unsigned bits2 = getShiftTypeBits(insn);
1422 unsigned imm5 = getShiftAmtBits(insn);
1423 ARM_AM::ShiftOpc ShOp = ARM_AM::no_shift;
1424 unsigned ShAmt = decodeImmShift(bits2, imm5, ShOp);
1425 MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShAmt)));
1433 // A6.3.1 Data-processing (modified immediate)
1435 // Two register operands: Rs Rn ModImm
1436 // One register operands (Rs=0b1111 no explicit dest reg): Rn ModImm
1437 // One register operands (Rn=0b1111 no explicit src reg): Rs ModImm -
1440 // ModImm = ThumbExpandImm(i:imm3:imm8)
1441 static bool DisassembleThumb2DPModImm(MCInst &MI, unsigned Opcode,
1442 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1444 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1445 unsigned &OpIdx = NumOpsAdded;
1449 unsigned RdRegClassID = OpInfo[0].RegClass;
1450 assert(NumOps >= 2 && (RdRegClassID == ARM::GPRRegClassID ||
1451 RdRegClassID == ARM::rGPRRegClassID)
1452 && "Expect >= 2 operands and first one as reg operand");
1454 unsigned RnRegClassID = OpInfo[1].RegClass;
1455 bool TwoReg = (RnRegClassID == ARM::GPRRegClassID
1456 || RnRegClassID == ARM::rGPRRegClassID);
1457 bool NoDstReg = (decodeRs(insn) == 0xF);
1459 // Build the register operands, followed by the modified immediate.
1461 MI.addOperand(MCOperand::CreateReg(
1462 getRegisterEnum(B, RdRegClassID,
1463 NoDstReg ? decodeRn(insn) : decodeRs(insn))));
1468 DEBUG(errs()<<"Thumb2 encoding error: d==15 for DPModImm 2-reg instr.\n");
1471 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
1476 // The modified immediate operand should come next.
1477 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0 &&
1478 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()
1479 && "Pure imm operand expected");
1482 // A6.3.2 Modified immediate constants in Thumb instructions
1483 unsigned imm12 = getIImm3Imm8(insn);
1484 MI.addOperand(MCOperand::CreateImm(ThumbExpandImm(imm12)));
1490 static inline bool Thumb2SaturateOpcode(unsigned Opcode) {
1492 case ARM::t2SSAT: case ARM::t2SSAT16:
1493 case ARM::t2USAT: case ARM::t2USAT16:
1500 /// DisassembleThumb2Sat - Disassemble Thumb2 saturate instructions:
1501 /// o t2SSAT, t2USAT: Rs sat_pos Rn shamt
1502 /// o t2SSAT16, t2USAT16: Rs sat_pos Rn
1503 static bool DisassembleThumb2Sat(MCInst &MI, unsigned Opcode, uint32_t insn,
1504 unsigned &NumOpsAdded, BO B) {
1505 const TargetInstrDesc &TID = ARMInsts[Opcode];
1506 NumOpsAdded = TID.getNumOperands() - 2; // ignore predicate operands
1508 // Disassemble the register def.
1509 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
1512 unsigned Pos = slice(insn, 4, 0);
1513 if (Opcode == ARM::t2SSAT || Opcode == ARM::t2SSAT16)
1515 MI.addOperand(MCOperand::CreateImm(Pos));
1517 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
1520 if (NumOpsAdded == 4) {
1521 ARM_AM::ShiftOpc Opc = (slice(insn, 21, 21) != 0 ?
1522 ARM_AM::asr : ARM_AM::lsl);
1523 // Inst{14-12:7-6} encodes the imm5 shift amount.
1524 unsigned ShAmt = slice(insn, 14, 12) << 2 | slice(insn, 7, 6);
1526 if (Opc == ARM_AM::asr)
1529 Opc = ARM_AM::no_shift;
1531 MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(Opc, ShAmt)));
1536 // A6.3.3 Data-processing (plain binary immediate)
1538 // o t2ADDri12, t2SUBri12: Rs Rn imm12
1539 // o t2LEApcrel (ADR): Rs imm12
1540 // o t2BFC (BFC): Rs Ro(TIED_TO) bf_inv_mask_imm
1541 // o t2BFI (BFI) (Currently not defined in LLVM as of Jan-07-2010)
1542 // o t2MOVi16: Rs imm16
1543 // o t2MOVTi16: Rs imm16
1544 // o t2SBFX (SBFX): Rs Rn lsb width
1545 // o t2UBFX (UBFX): Rs Rn lsb width
1546 // o t2BFI (BFI): Rs Rn lsb width
1547 static bool DisassembleThumb2DPBinImm(MCInst &MI, unsigned Opcode,
1548 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1550 const TargetInstrDesc &TID = ARMInsts[Opcode];
1551 const TargetOperandInfo *OpInfo = TID.OpInfo;
1552 unsigned &OpIdx = NumOpsAdded;
1556 unsigned RdRegClassID = OpInfo[0].RegClass;
1557 assert(NumOps >= 2 && (RdRegClassID == ARM::GPRRegClassID ||
1558 RdRegClassID == ARM::rGPRRegClassID)
1559 && "Expect >= 2 operands and first one as reg operand");
1561 unsigned RnRegClassID = OpInfo[1].RegClass;
1562 bool TwoReg = (RnRegClassID == ARM::GPRRegClassID
1563 || RnRegClassID == ARM::rGPRRegClassID);
1565 // Build the register operand(s), followed by the immediate(s).
1567 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RdRegClassID,
1572 assert(NumOps >= 3 && "Expect >= 3 operands");
1574 if ((Idx = TID.getOperandConstraint(OpIdx, TOI::TIED_TO)) != -1) {
1575 // Process tied_to operand constraint.
1576 MI.addOperand(MI.getOperand(Idx));
1578 // Add src reg operand.
1579 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
1585 if (Opcode == ARM::t2BFI) {
1586 // Add val reg operand.
1587 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
1592 assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
1593 && !OpInfo[OpIdx].isOptionalDef()
1594 && "Pure imm operand expected");
1596 // Pre-increment OpIdx.
1599 if (Opcode == ARM::t2ADDri12 || Opcode == ARM::t2SUBri12
1600 || Opcode == ARM::t2LEApcrel)
1601 MI.addOperand(MCOperand::CreateImm(getIImm3Imm8(insn)));
1602 else if (Opcode == ARM::t2MOVi16 || Opcode == ARM::t2MOVTi16) {
1603 if (!B->tryAddingSymbolicOperand(getImm16(insn), 4, MI))
1604 MI.addOperand(MCOperand::CreateImm(getImm16(insn)));
1605 } else if (Opcode == ARM::t2BFC || Opcode == ARM::t2BFI) {
1607 if (getBitfieldInvMask(insn, mask))
1608 MI.addOperand(MCOperand::CreateImm(mask));
1612 // Handle the case of: lsb width
1613 assert((Opcode == ARM::t2SBFX || Opcode == ARM::t2UBFX)
1614 && "Unexpected opcode");
1615 MI.addOperand(MCOperand::CreateImm(getLsb(insn)));
1616 MI.addOperand(MCOperand::CreateImm(getWidthMinus1(insn) + 1));
1624 // A6.3.4 Table A6-15 Miscellaneous control instructions
1628 static inline bool t2MiscCtrlInstr(uint32_t insn) {
1629 if (slice(insn, 31, 20) == 0xf3b && slice(insn, 15, 14) == 2 &&
1630 slice(insn, 12, 12) == 0)
1636 // A6.3.4 Branches and miscellaneous control
1639 // Branches: t2B, t2Bcc -> imm operand
1641 // Branches: t2TPsoft -> no operand
1643 // A8.6.23 BL, BLX (immediate)
1644 // Branches (defined in ARMInstrThumb.td): tBLr9, tBLXi_r9 -> imm operand
1649 // Miscellaneous control:
1650 // -> no operand (except pred-imm pred-ccr for CLREX, memory barrier variants)
1652 // Hint: t2NOP, t2YIELD, t2WFE, t2WFI, t2SEV
1653 // -> no operand (except pred-imm pred-ccr)
1655 // t2DBG -> imm4 = Inst{3-0}
1657 // t2MRS/t2MRSsys -> Rs
1658 // t2MSR/t2MSRsys -> Rn mask=Inst{11-8}
1659 // t2SMC -> imm4 = Inst{19-16}
1660 static bool DisassembleThumb2BrMiscCtrl(MCInst &MI, unsigned Opcode,
1661 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1666 if (Opcode == ARM::t2DMB || Opcode == ARM::t2DSB) {
1667 // Inst{3-0} encodes the memory barrier option for the variants.
1668 unsigned opt = slice(insn, 3, 0);
1670 case ARM_MB::SY: case ARM_MB::ST:
1671 case ARM_MB::ISH: case ARM_MB::ISHST:
1672 case ARM_MB::NSH: case ARM_MB::NSHST:
1673 case ARM_MB::OSH: case ARM_MB::OSHST:
1674 MI.addOperand(MCOperand::CreateImm(opt));
1682 if (t2MiscCtrlInstr(insn))
1697 // FIXME: To enable correct asm parsing and disasm of CPS we need 3 different
1698 // opcodes which match the same real instruction. This is needed since there's
1699 // no current handling of optional arguments. Fix here when a better handling
1700 // of optional arguments is implemented.
1701 if (Opcode == ARM::t2CPS3p) {
1702 MI.addOperand(MCOperand::CreateImm(slice(insn, 10, 9))); // imod
1703 MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 5))); // iflags
1704 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
1708 if (Opcode == ARM::t2CPS2p) {
1709 MI.addOperand(MCOperand::CreateImm(slice(insn, 10, 9))); // imod
1710 MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 5))); // iflags
1714 if (Opcode == ARM::t2CPS1p) {
1715 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
1720 // DBG has its option specified in Inst{3-0}.
1721 if (Opcode == ARM::t2DBG) {
1722 MI.addOperand(MCOperand::CreateImm(slice(insn, 3, 0)));
1727 // MRS and MRSsys take one GPR reg Rs.
1728 if (Opcode == ARM::t2MRS || Opcode == ARM::t2MRSsys) {
1729 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1734 // BXJ takes one GPR reg Rn.
1735 if (Opcode == ARM::t2BXJ) {
1736 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1741 // MSR take a mask, followed by one GPR reg Rn. The mask contains the R Bit in
1742 // bit 4, and the special register fields in bits 3-0.
1743 if (Opcode == ARM::t2MSR) {
1744 MI.addOperand(MCOperand::CreateImm(slice(insn, 20, 20) << 4 /* R Bit */ |
1745 slice(insn, 11, 8) /* Special Reg */));
1746 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1752 if (Opcode == ARM::t2SMC) {
1753 MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 16)));
1758 // Some instructions have predicate operands first before the immediate.
1759 if (Opcode == ARM::tBLXi_r9 || Opcode == ARM::tBLr9) {
1760 // Handling the two predicate operands before the imm operand.
1761 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
1764 DEBUG(errs() << "Expected predicate operands not found.\n");
1769 // Add the imm operand.
1774 assert(0 && "Unexpected opcode");
1777 Offset = decodeImm32_B_EncodingT4(insn);
1780 Offset = decodeImm32_B_EncodingT3(insn);
1783 Offset = decodeImm32_BL(insn);
1786 Offset = decodeImm32_BLX(insn);
1790 if (!B->tryAddingSymbolicOperand(Offset + B->getBuilderAddress() + 4, 4, MI))
1791 MI.addOperand(MCOperand::CreateImm(Offset));
1793 // This is an increment as some predicate operands may have been added first.
1799 static inline bool Thumb2PreloadOpcode(unsigned Opcode) {
1803 case ARM::t2PLDi12: case ARM::t2PLDi8:
1805 case ARM::t2PLDWi12: case ARM::t2PLDWi8:
1807 case ARM::t2PLIi12: case ARM::t2PLIi8:
1813 static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned Opcode, uint32_t insn,
1814 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1816 // Preload Data/Instruction requires either 2 or 3 operands.
1817 // t2PLDi12, t2PLDi8, t2PLDpci: Rn [+/-]imm12/imm8
1819 // t2PLDs: Rn Rm imm2=Inst{5-4}
1820 // Same pattern applies for t2PLDW* and t2PLI*.
1822 const TargetInstrDesc &TID = ARMInsts[Opcode];
1823 const TargetOperandInfo *OpInfo = TID.OpInfo;
1824 unsigned &OpIdx = NumOpsAdded;
1828 assert(NumOps >= 2 &&
1829 OpInfo[0].RegClass == ARM::GPRRegClassID &&
1830 "Expect >= 2 operands and first one as reg operand");
1832 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1836 if (OpInfo[OpIdx].RegClass == ARM::rGPRRegClassID) {
1837 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1840 assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
1841 && !OpInfo[OpIdx].isOptionalDef()
1842 && "Pure imm operand expected");
1844 if (Opcode == ARM::t2PLDi8 || Opcode == ARM::t2PLDWi8 ||
1845 Opcode == ARM::t2PLIi8) {
1846 // A8.6.117 Encoding T2: add = FALSE
1847 unsigned Imm8 = getImm8(insn);
1850 // The i12 forms. See, for example, A8.6.117 Encoding T1.
1851 // Note that currently t2PLDi12 also handles the previously named t2PLDpci
1852 // opcode, that's why we use decodeImm12(insn) which returns +/- imm12.
1853 Offset = decodeImm12(insn);
1855 MI.addOperand(MCOperand::CreateImm(Offset));
1859 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0 &&
1860 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
1861 // Fills in the shift amount for t2PLDs, t2PLDWs, t2PLIs.
1862 MI.addOperand(MCOperand::CreateImm(slice(insn, 5, 4)));
1869 static bool BadRegsThumb2LdSt(unsigned Opcode, uint32_t insn, bool Load,
1870 unsigned R0, unsigned R1, unsigned R2, bool UseRm, bool WB) {
1872 // Inst{22-21} encodes the data item transferred for load/store.
1873 // For single word, it is encoded as ob10.
1874 bool Word = (slice(insn, 22, 21) == 2);
1876 if (UseRm && BadReg(R2)) {
1877 DEBUG(errs() << "if BadReg(m) then UNPREDICTABLE\n");
1882 if (!Word && R0 == 13) {
1883 DEBUG(errs() << "if t == 13 then UNPREDICTABLE\n");
1887 if (WB && R0 == R1) {
1888 DEBUG(errs() << "if wback && n == t then UNPREDICTABLE\n");
1891 if ((WB && R0 == 15) || (!WB && R1 == 15)) {
1892 DEBUG(errs() << "if Rn == '1111' then UNDEFINED\n");
1896 if ((WB && R1 == 15) || (!WB && R0 == 15)) {
1897 DEBUG(errs() << "if t == 15 then UNPREDICTABLE\n");
1901 if ((WB && BadReg(R1)) || (!WB && BadReg(R0))) {
1902 DEBUG(errs() << "if BadReg(t) then UNPREDICTABLE\n");
1910 // A6.3.10 Store single data item
1911 // A6.3.9 Load byte, memory hints
1912 // A6.3.8 Load halfword, memory hints
1917 // t2LDRi12: Rd Rn (+)imm12
1918 // t2LDRi8: Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
1919 // t2LDRs: Rd Rn Rm ConstantShiftSpecifier (see also
1920 // DisassembleThumb2DPSoReg)
1921 // t2LDR_POST: Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
1922 // t2LDR_PRE: Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
1924 // t2STRi12: Rd Rn (+)imm12
1925 // t2STRi8: Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
1926 // t2STRs: Rd Rn Rm ConstantShiftSpecifier (see also
1927 // DisassembleThumb2DPSoReg)
1928 // t2STR_POST: Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
1929 // t2STR_PRE: Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
1931 // Note that for indexed modes, the Rn(TIED_TO) operand needs to be populated
1932 // correctly, as LLVM AsmPrinter depends on it. For indexed stores, the first
1933 // operand is Rn; for all the other instructions, Rd is the first operand.
1935 // Delegates to DisassembleThumb2PreLoad() for preload data/instruction.
1936 // Delegates to DisassembleThumb2Ldpci() for load * literal operations.
1937 static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, unsigned Opcode,
1938 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1940 unsigned Rn = decodeRn(insn);
1942 if (Thumb2PreloadOpcode(Opcode))
1943 return DisassembleThumb2PreLoad(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1945 // See, for example, A6.3.7 Load word: Table A6-18 Load word.
1946 if (Load && Rn == 15)
1947 return DisassembleThumb2Ldpci(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1948 const TargetInstrDesc &TID = ARMInsts[Opcode];
1949 const TargetOperandInfo *OpInfo = TID.OpInfo;
1950 unsigned &OpIdx = NumOpsAdded;
1954 assert(NumOps >= 3 &&
1955 OpInfo[0].RegClass == ARM::GPRRegClassID &&
1956 OpInfo[1].RegClass == ARM::GPRRegClassID &&
1957 "Expect >= 3 operands and first two as reg operands");
1959 bool ThreeReg = (OpInfo[2].RegClass > 0);
1960 bool TIED_TO = ThreeReg && TID.getOperandConstraint(2, TOI::TIED_TO) != -1;
1961 bool Imm12 = !ThreeReg && slice(insn, 23, 23) == 1; // ARMInstrThumb2.td
1963 // Build the register operands, followed by the immediate.
1964 unsigned R0, R1, R2 = 0;
1965 unsigned Rd = decodeRd(insn);
1968 if (!Load && TIED_TO) {
1978 Imm = decodeImm8(insn);
1980 R2 = decodeRm(insn);
1981 // See, for example, A8.6.64 LDRB (register).
1982 // And ARMAsmPrinter::printT2AddrModeSoRegOperand().
1983 // LSL is the default shift opc, and LLVM does not expect it to be encoded
1984 // as part of the immediate operand.
1985 // Imm = ARM_AM::getSORegOpc(ARM_AM::lsl, slice(insn, 5, 4));
1986 Imm = slice(insn, 5, 4);
1990 Imm = getImm12(insn);
1992 Imm = decodeImm8(insn);
1995 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1998 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
2003 // This could be an offset register or a TIED_TO register.
2004 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
2009 if (BadRegsThumb2LdSt(Opcode, insn, Load, R0, R1, R2, ThreeReg & !TIED_TO,
2013 assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
2014 && !OpInfo[OpIdx].isOptionalDef()
2015 && "Pure imm operand expected");
2017 MI.addOperand(MCOperand::CreateImm(Imm));
2023 // A6.3.12 Data-processing (register)
2025 // Two register operands [rotate]: Rs Rm [rotation(= (rotate:'000'))]
2026 // Three register operands only: Rs Rn Rm
2027 // Three register operands [rotate]: Rs Rn Rm [rotation(= (rotate:'000'))]
2029 // Parallel addition and subtraction 32-bit Thumb instructions: Rs Rn Rm
2031 // Miscellaneous operations: Rs [Rn] Rm
2032 static bool DisassembleThumb2DPReg(MCInst &MI, unsigned Opcode, uint32_t insn,
2033 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2035 const TargetInstrDesc &TID = ARMInsts[Opcode];
2036 const TargetOperandInfo *OpInfo = TID.OpInfo;
2037 unsigned &OpIdx = NumOpsAdded;
2041 assert(NumOps >= 2 &&
2042 OpInfo[0].RegClass > 0 &&
2043 OpInfo[1].RegClass > 0 &&
2044 "Expect >= 2 operands and first two as reg operands");
2046 // Build the register operands, followed by the optional rotation amount.
2048 bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass > 0;
2050 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
2055 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
2060 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
2064 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0
2065 && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
2066 // Add the rotation amount immediate.
2067 MI.addOperand(MCOperand::CreateImm(decodeRotate(insn)));
2074 // A6.3.16 Multiply, multiply accumulate, and absolute difference
2076 // t2MLA, t2MLS, t2SMMLA, t2SMMLS: Rs Rn Rm Ra=Inst{15-12}
2077 // t2MUL, t2SMMUL: Rs Rn Rm
2078 // t2SMLA[BB|BT|TB|TT|WB|WT]: Rs Rn Rm Ra=Inst{15-12}
2079 // t2SMUL[BB|BT|TB|TT|WB|WT]: Rs Rn Rm
2081 // Dual halfword multiply: t2SMUAD[X], t2SMUSD[X], t2SMLAD[X], t2SMLSD[X]:
2082 // Rs Rn Rm Ra=Inst{15-12}
2084 // Unsigned Sum of Absolute Differences [and Accumulate]
2085 // Rs Rn Rm [Ra=Inst{15-12}]
2086 static bool DisassembleThumb2Mul(MCInst &MI, unsigned Opcode, uint32_t insn,
2087 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2089 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
2091 assert(NumOps >= 3 &&
2092 OpInfo[0].RegClass == ARM::rGPRRegClassID &&
2093 OpInfo[1].RegClass == ARM::rGPRRegClassID &&
2094 OpInfo[2].RegClass == ARM::rGPRRegClassID &&
2095 "Expect >= 3 operands and first three as reg operands");
2097 // Build the register operands.
2099 bool FourReg = NumOps > 3 && OpInfo[3].RegClass == ARM::rGPRRegClassID;
2101 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2104 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2107 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2111 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2114 NumOpsAdded = FourReg ? 4 : 3;
2119 // A6.3.17 Long multiply, long multiply accumulate, and divide
2121 // t2SMULL, t2UMULL, t2SMLAL, t2UMLAL, t2UMAAL: RdLo RdHi Rn Rm
2122 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2124 // Halfword multiple accumulate long: t2SMLAL<x><y>: RdLo RdHi Rn Rm
2125 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2127 // Dual halfword multiple: t2SMLALD[X], t2SMLSLD[X]: RdLo RdHi Rn Rm
2128 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2130 // Signed/Unsigned divide: t2SDIV, t2UDIV: Rs Rn Rm
2131 static bool DisassembleThumb2LongMul(MCInst &MI, unsigned Opcode, uint32_t insn,
2132 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2134 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
2136 assert(NumOps >= 3 &&
2137 OpInfo[0].RegClass == ARM::rGPRRegClassID &&
2138 OpInfo[1].RegClass == ARM::rGPRRegClassID &&
2139 OpInfo[2].RegClass == ARM::rGPRRegClassID &&
2140 "Expect >= 3 operands and first three as reg operands");
2142 bool FourReg = NumOps > 3 && OpInfo[3].RegClass == ARM::rGPRRegClassID;
2144 // Build the register operands.
2147 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2150 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2153 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2156 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2167 // See A6.3 32-bit Thumb instruction encoding for instruction classes
2168 // corresponding to (op1, op2, op).
2170 // Table A6-9 32-bit Thumb instruction encoding
2171 // op1 op2 op Instruction class, see
2172 // --- ------- -- -----------------------------------------------------------
2173 // 01 00xx0xx - Load/store multiple on page A6-23
2174 // 00xx1xx - Load/store dual, load/store exclusive, table branch on
2176 // 01xxxxx - Data-processing (shifted register) on page A6-31
2177 // 1xxxxxx - Coprocessor instructions on page A6-40
2178 // 10 x0xxxxx 0 Data-processing (modified immediate) on page A6-15
2179 // x1xxxxx 0 Data-processing (plain binary immediate) on page A6-19
2180 // - 1 Branches and miscellaneous control on page A6-20
2181 // 11 000xxx0 - Store single data item on page A6-30
2182 // 001xxx0 - Advanced SIMD element or structure load/store instructions
2184 // 00xx001 - Load byte, memory hints on page A6-28
2185 // 00xx011 - Load halfword, memory hints on page A6-26
2186 // 00xx101 - Load word on page A6-25
2187 // 00xx111 - UNDEFINED
2188 // 010xxxx - Data-processing (register) on page A6-33
2189 // 0110xxx - Multiply, multiply accumulate, and absolute difference on
2191 // 0111xxx - Long multiply, long multiply accumulate, and divide on
2193 // 1xxxxxx - Coprocessor instructions on page A6-40
2195 static bool DisassembleThumb2(uint16_t op1, uint16_t op2, uint16_t op,
2196 MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps,
2197 unsigned &NumOpsAdded, BO B) {
2201 if (slice(op2, 6, 5) == 0) {
2202 if (slice(op2, 2, 2) == 0) {
2203 // Load/store multiple.
2204 return DisassembleThumb2LdStMul(MI, Opcode, insn, NumOps, NumOpsAdded,
2208 // Load/store dual, load/store exclusive, table branch, otherwise.
2209 assert(slice(op2, 2, 2) == 1 && "Thumb2 encoding error!");
2210 if ((ARM::t2LDREX <= Opcode && Opcode <= ARM::t2LDREXH) ||
2211 (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH)) {
2212 // Load/store exclusive.
2213 return DisassembleThumb2LdStEx(MI, Opcode, insn, NumOps, NumOpsAdded,
2216 if (Opcode == ARM::t2LDRDi8 ||
2217 Opcode == ARM::t2LDRD_PRE || Opcode == ARM::t2LDRD_POST ||
2218 Opcode == ARM::t2STRDi8 ||
2219 Opcode == ARM::t2STRD_PRE || Opcode == ARM::t2STRD_POST) {
2221 return DisassembleThumb2LdStDual(MI, Opcode, insn, NumOps, NumOpsAdded,
2224 if (Opcode == ARM::t2TBB || Opcode == ARM::t2TBH) {
2226 return DisassembleThumb2TB(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2228 } else if (slice(op2, 6, 5) == 1) {
2229 // Data-processing (shifted register).
2230 return DisassembleThumb2DPSoReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2233 // FIXME: A6.3.18 Coprocessor instructions
2234 // But see ThumbDisassembler::getInstruction().
2239 if (slice(op2, 5, 5) == 0)
2240 // Data-processing (modified immediate)
2241 return DisassembleThumb2DPModImm(MI, Opcode, insn, NumOps, NumOpsAdded,
2243 if (Thumb2SaturateOpcode(Opcode))
2244 return DisassembleThumb2Sat(MI, Opcode, insn, NumOpsAdded, B);
2246 // Data-processing (plain binary immediate)
2247 return DisassembleThumb2DPBinImm(MI, Opcode, insn, NumOps, NumOpsAdded,
2250 // Branches and miscellaneous control on page A6-20.
2251 return DisassembleThumb2BrMiscCtrl(MI, Opcode, insn, NumOps, NumOpsAdded,
2254 switch (slice(op2, 6, 5)) {
2256 // Load/store instructions...
2257 if (slice(op2, 0, 0) == 0) {
2258 if (slice(op2, 4, 4) == 0) {
2259 // Store single data item on page A6-30
2260 return DisassembleThumb2LdSt(false, MI,Opcode,insn,NumOps,NumOpsAdded,
2263 // FIXME: Advanced SIMD element or structure load/store instructions.
2264 // But see ThumbDisassembler::getInstruction().
2268 // Table A6-9 32-bit Thumb instruction encoding: Load byte|halfword|word
2269 return DisassembleThumb2LdSt(true, MI, Opcode, insn, NumOps,
2274 if (slice(op2, 4, 4) == 0) {
2275 // A6.3.12 Data-processing (register)
2276 return DisassembleThumb2DPReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2277 } else if (slice(op2, 3, 3) == 0) {
2278 // A6.3.16 Multiply, multiply accumulate, and absolute difference
2279 return DisassembleThumb2Mul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2281 // A6.3.17 Long multiply, long multiply accumulate, and divide
2282 return DisassembleThumb2LongMul(MI, Opcode, insn, NumOps, NumOpsAdded,
2287 // FIXME: A6.3.18 Coprocessor instructions
2288 // But see ThumbDisassembler::getInstruction().
2295 assert(0 && "Thumb2 encoding error!");
2302 static bool DisassembleThumbFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
2303 unsigned short NumOps, unsigned &NumOpsAdded, BO Builder) {
2305 uint16_t HalfWord = slice(insn, 31, 16);
2307 if (HalfWord == 0) {
2308 // A6.2 16-bit Thumb instruction encoding
2310 uint16_t op = slice(insn, 15, 10);
2311 return DisassembleThumb1(op, MI, Opcode, insn, NumOps, NumOpsAdded,
2315 unsigned bits15_11 = slice(HalfWord, 15, 11);
2317 // A6.1 Thumb instruction set encoding
2318 if (!(bits15_11 == 0x1D || bits15_11 == 0x1E || bits15_11 == 0x1F)) {
2319 assert("Bits[15:11] first halfword of Thumb2 instruction is out of range");
2323 // A6.3 32-bit Thumb instruction encoding
2325 uint16_t op1 = slice(HalfWord, 12, 11);
2326 uint16_t op2 = slice(HalfWord, 10, 4);
2327 uint16_t op = slice(insn, 15, 15);
2329 return DisassembleThumb2(op1, op2, op, MI, Opcode, insn, NumOps, NumOpsAdded,