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;
109 // Utilities for 32-bit Thumb instructions.
111 // Extract imm4: Inst{19-16}.
112 static inline unsigned getImm4(uint32_t insn) {
113 return slice(insn, 19, 16);
116 // Extract imm3: Inst{14-12}.
117 static inline unsigned getImm3(uint32_t insn) {
118 return slice(insn, 14, 12);
121 // Extract imm8: Inst{7-0}.
122 static inline unsigned getImm8(uint32_t insn) {
123 return slice(insn, 7, 0);
126 // A8.6.61 LDRB (immediate, Thumb) and friends
129 static inline int decodeImm8(uint32_t insn) {
130 int Offset = getImm8(insn);
131 return slice(insn, 9, 9) ? Offset : -Offset;
134 // Extract imm12: Inst{11-0}.
135 static inline unsigned getImm12(uint32_t insn) {
136 return slice(insn, 11, 0);
139 // A8.6.63 LDRB (literal) and friends
142 static inline int decodeImm12(uint32_t insn) {
143 int Offset = getImm12(insn);
144 return slice(insn, 23, 23) ? Offset : -Offset;
147 // Extract imm2: Inst{7-6}.
148 static inline unsigned getImm2(uint32_t insn) {
149 return slice(insn, 7, 6);
152 // For BFI, BFC, t2SBFX, and t2UBFX.
153 // Extract lsb: Inst{14-12:7-6}.
154 static inline unsigned getLsb(uint32_t insn) {
155 return getImm3(insn) << 2 | getImm2(insn);
159 // Extract msb: Inst{4-0}.
160 static inline unsigned getMsb(uint32_t insn) {
161 return slice(insn, 4, 0);
164 // For t2SBFX and t2UBFX.
165 // Extract widthminus1: Inst{4-0}.
166 static inline unsigned getWidthMinus1(uint32_t insn) {
167 return slice(insn, 4, 0);
170 // For t2ADDri12 and t2SUBri12.
171 // imm12 = i:imm3:imm8;
172 static inline unsigned getIImm3Imm8(uint32_t insn) {
173 return slice(insn, 26, 26) << 11 | getImm3(insn) << 8 | getImm8(insn);
176 // For t2MOVi16 and t2MOVTi16.
177 // imm16 = imm4:i:imm3:imm8;
178 static inline unsigned getImm16(uint32_t insn) {
179 return getImm4(insn) << 12 | slice(insn, 26, 26) << 11 |
180 getImm3(insn) << 8 | getImm8(insn);
183 // Inst{5-4} encodes the shift type.
184 static inline unsigned getShiftTypeBits(uint32_t insn) {
185 return slice(insn, 5, 4);
188 // Inst{14-12}:Inst{7-6} encodes the imm5 shift amount.
189 static inline unsigned getShiftAmtBits(uint32_t insn) {
190 return getImm3(insn) << 2 | getImm2(insn);
194 // Encoding T1 ARMv6T2, ARMv7
195 // LLVM-specific encoding for #<lsb> and #<width>
196 static inline uint32_t getBitfieldInvMask(uint32_t insn) {
197 uint32_t lsb = getImm3(insn) << 2 | getImm2(insn);
198 uint32_t msb = getMsb(insn);
200 assert(lsb <= msb && "Encoding error: lsb > msb");
201 for (uint32_t i = lsb; i <= msb; ++i)
206 // A8.4 Shifts applied to a register
207 // A8.4.1 Constant shifts
208 // A8.4.3 Pseudocode details of instruction-specified shifts and rotates
210 // decodeImmShift() returns the shift amount and the the shift opcode.
211 // Note that, as of Jan-06-2010, LLVM does not support rrx shifted operands yet.
212 static inline unsigned decodeImmShift(unsigned bits2, unsigned imm5,
213 ARM_AM::ShiftOpc &ShOp) {
215 assert(imm5 < 32 && "Invalid imm5 argument");
217 default: assert(0 && "No such value");
223 return (imm5 == 0 ? 32 : imm5);
226 return (imm5 == 0 ? 32 : imm5);
228 ShOp = (imm5 == 0 ? ARM_AM::rrx : ARM_AM::ror);
229 return (imm5 == 0 ? 1 : imm5);
233 // A6.3.2 Modified immediate constants in Thumb instructions
235 // ThumbExpandImm() returns the modified immediate constant given an imm12 for
236 // Thumb data-processing instructions with modified immediate.
237 // See also A6.3.1 Data-processing (modified immediate).
238 static inline unsigned ThumbExpandImm(unsigned imm12) {
239 assert(imm12 <= 0xFFF && "Invalid imm12 argument");
241 // If the leading two bits is 0b00, the modified immediate constant is
242 // obtained by splatting the low 8 bits into the first byte, every other byte,
243 // or every byte of a 32-bit value.
245 // Otherwise, a rotate right of '1':imm12<6:0> by the amount imm12<11:7> is
248 if (slice(imm12, 11, 10) == 0) {
249 unsigned short control = slice(imm12, 9, 8);
250 unsigned imm8 = slice(imm12, 7, 0);
253 assert(0 && "No such value");
258 return imm8 << 16 | imm8;
260 return imm8 << 24 | imm8 << 8;
262 return imm8 << 24 | imm8 << 16 | imm8 << 8 | imm8;
265 // A rotate is required.
266 unsigned Val = 1 << 7 | slice(imm12, 6, 0);
267 unsigned Amt = slice(imm12, 11, 7);
268 return ARM_AM::rotr32(Val, Amt);
272 static inline int decodeImm32_B_EncodingT3(uint32_t insn) {
273 bool S = slice(insn, 26, 26);
274 bool J1 = slice(insn, 13, 13);
275 bool J2 = slice(insn, 11, 11);
276 unsigned Imm21 = slice(insn, 21, 16) << 12 | slice(insn, 10, 0) << 1;
277 if (S) Imm21 |= 1 << 20;
278 if (J2) Imm21 |= 1 << 19;
279 if (J1) Imm21 |= 1 << 18;
281 return SignExtend32<21>(Imm21);
284 static inline int decodeImm32_B_EncodingT4(uint32_t insn) {
285 unsigned S = slice(insn, 26, 26);
286 bool I1 = slice(insn, 13, 13) == S;
287 bool I2 = slice(insn, 11, 11) == S;
288 unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 0) << 1;
289 if (S) Imm25 |= 1 << 24;
290 if (I1) Imm25 |= 1 << 23;
291 if (I2) Imm25 |= 1 << 22;
293 return SignExtend32<25>(Imm25);
296 static inline int decodeImm32_BL(uint32_t insn) {
297 unsigned S = slice(insn, 26, 26);
298 bool I1 = slice(insn, 13, 13) == S;
299 bool I2 = slice(insn, 11, 11) == S;
300 unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 0) << 1;
301 if (S) Imm25 |= 1 << 24;
302 if (I1) Imm25 |= 1 << 23;
303 if (I2) Imm25 |= 1 << 22;
305 return SignExtend32<25>(Imm25);
308 static inline int decodeImm32_BLX(uint32_t insn) {
309 unsigned S = slice(insn, 26, 26);
310 bool I1 = slice(insn, 13, 13) == S;
311 bool I2 = slice(insn, 11, 11) == S;
312 unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 1) << 2;
313 if (S) Imm25 |= 1 << 24;
314 if (I1) Imm25 |= 1 << 23;
315 if (I2) Imm25 |= 1 << 22;
317 return SignExtend32<25>(Imm25);
320 // See, for example, A8.6.221 SXTAB16.
321 static inline unsigned decodeRotate(uint32_t insn) {
322 unsigned rotate = slice(insn, 5, 4);
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 TargetOperandInfo *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");
397 MI.addOperand(MCOperand::CreateImm(UseRt ? getT1Imm8(insn)
398 : (Imm3 ? getT1Imm3(insn)
399 : getT1Imm5(insn))));
406 // A6.2.2 Data-processing
408 // tCMPr, tTST, tCMN: tRd tRn
409 // tMVN, tRSB: tRd CPSR tRn
410 // Others: tRd CPSR tRd(TIED_TO) tRn
411 static bool DisassembleThumb1DP(MCInst &MI, unsigned Opcode, uint32_t insn,
412 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
414 const TargetInstrDesc &TID = ARMInsts[Opcode];
415 const TargetOperandInfo *OpInfo = TID.OpInfo;
416 unsigned &OpIdx = NumOpsAdded;
420 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
421 (OpInfo[1].RegClass == ARM::CCRRegClassID
422 || OpInfo[1].RegClass == ARM::tGPRRegClassID)
423 && "Invalid arguments");
425 // Add the destination operand.
426 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
430 // Check whether the next operand to be added is a CCR Register.
431 if (OpInfo[OpIdx].RegClass == ARM::CCRRegClassID) {
432 assert(OpInfo[OpIdx].isOptionalDef() && "Optional def operand expected");
433 MI.addOperand(MCOperand::CreateReg(B->InITBlock() ? 0 : ARM::CPSR));
437 // We have either { tRd(TIED_TO), tRn } or { tRn } remaining.
438 // Process the TIED_TO operand first.
440 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
441 && "Thumb reg operand expected");
443 if ((Idx = TID.getOperandConstraint(OpIdx, TOI::TIED_TO)) != -1) {
444 // The reg operand is tied to the first reg operand.
445 MI.addOperand(MI.getOperand(Idx));
449 // Process possible next reg operand.
450 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
452 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
460 // A6.2.3 Special data instructions and branch and exchange
462 // tADDhirr: Rd Rd(TIED_TO) Rm
464 // tMOVr, tMOVgpr2gpr, tMOVgpr2tgpr, tMOVtgpr2gpr: Rd|tRd Rm|tRn
465 // tBX_RET: 0 operand
466 // tBX_RET_vararg: Rm
468 static bool DisassembleThumb1Special(MCInst &MI, unsigned Opcode, uint32_t insn,
469 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
471 // tBX_RET has 0 operand.
475 // BX/BLX has 1 reg operand: Rm.
477 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
483 const TargetInstrDesc &TID = ARMInsts[Opcode];
484 const TargetOperandInfo *OpInfo = TID.OpInfo;
485 unsigned &OpIdx = NumOpsAdded;
489 // Add the destination operand.
490 unsigned RegClass = OpInfo[OpIdx].RegClass;
491 MI.addOperand(MCOperand::CreateReg(
492 getRegisterEnum(B, RegClass,
493 IsGPR(RegClass) ? getT1Rd(insn)
497 // We have either { Rd(TIED_TO), Rm } or { Rm|tRn } remaining.
498 // Process the TIED_TO operand first.
500 assert(OpIdx < NumOps && "More operands expected");
502 if ((Idx = TID.getOperandConstraint(OpIdx, TOI::TIED_TO)) != -1) {
503 // The reg operand is tied to the first reg operand.
504 MI.addOperand(MI.getOperand(Idx));
508 // The next reg operand is either Rm or tRn.
509 assert(OpIdx < NumOps && "More operands expected");
510 RegClass = OpInfo[OpIdx].RegClass;
511 MI.addOperand(MCOperand::CreateReg(
512 getRegisterEnum(B, RegClass,
513 IsGPR(RegClass) ? getT1Rm(insn)
520 // A8.6.59 LDR (literal)
522 // tLDRpci: tRt imm8*4
523 static bool DisassembleThumb1LdPC(MCInst &MI, unsigned Opcode, uint32_t insn,
524 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
526 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
527 if (!OpInfo) return false;
529 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
530 (OpInfo[1].RegClass == 0 &&
531 !OpInfo[1].isPredicate() &&
532 !OpInfo[1].isOptionalDef())
533 && "Invalid arguments");
535 // Add the destination operand.
536 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
539 // And the (imm8 << 2) operand.
540 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn) << 2));
547 // Thumb specific addressing modes (see ARMInstrThumb.td):
549 // t_addrmode_rr := reg + reg
551 // t_addrmode_s4 := reg + reg
554 // t_addrmode_s2 := reg + reg
557 // t_addrmode_s1 := reg + reg
560 // t_addrmode_sp := sp + imm8 * 4
563 // A6.2.4 Load/store single data item
565 // Load/Store Register (reg|imm): tRd tRn imm5 tRm
566 // Load Register Signed Byte|Halfword: tRd tRn tRm
567 static bool DisassembleThumb1LdSt(unsigned opA, MCInst &MI, unsigned Opcode,
568 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
570 const TargetInstrDesc &TID = ARMInsts[Opcode];
571 const TargetOperandInfo *OpInfo = TID.OpInfo;
572 unsigned &OpIdx = NumOpsAdded;
574 // Table A6-5 16-bit Thumb Load/store instructions
575 // opA = 0b0101 for STR/LDR (register) and friends.
576 // Otherwise, we have STR/LDR (immediate) and friends.
577 bool Imm5 = (opA != 5);
580 && OpInfo[0].RegClass == ARM::tGPRRegClassID
581 && OpInfo[1].RegClass == ARM::tGPRRegClassID
582 && "Expect >= 2 operands and first two as thumb reg operands");
584 // Add the destination reg and the base reg.
585 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
587 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
591 // We have either { imm5, tRm } or { tRm } remaining.
592 // Process the imm5 first. Note that STR/LDR (register) should skip the imm5
593 // offset operand for t_addrmode_s[1|2|4].
595 assert(OpIdx < NumOps && "More operands expected");
597 if (OpInfo[OpIdx].RegClass == 0 && !OpInfo[OpIdx].isPredicate() &&
598 !OpInfo[OpIdx].isOptionalDef()) {
600 MI.addOperand(MCOperand::CreateImm(Imm5 ? getT1Imm5(insn) : 0));
604 // The next reg operand is tRm, the offset.
605 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
606 && "Thumb reg operand expected");
607 MI.addOperand(MCOperand::CreateReg(
609 : getRegisterEnum(B, ARM::tGPRRegClassID,
616 // A6.2.4 Load/store single data item
618 // Load/Store Register SP relative: tRt ARM::SP imm8
619 static bool DisassembleThumb1LdStSP(MCInst &MI, unsigned Opcode, uint32_t insn,
620 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
622 assert((Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi)
623 && "Invalid opcode");
625 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
626 if (!OpInfo) return false;
628 assert(NumOps >= 3 &&
629 OpInfo[0].RegClass == ARM::tGPRRegClassID &&
630 OpInfo[1].RegClass == ARM::GPRRegClassID &&
631 (OpInfo[2].RegClass == 0 &&
632 !OpInfo[2].isPredicate() &&
633 !OpInfo[2].isOptionalDef())
634 && "Invalid arguments");
636 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
638 MI.addOperand(MCOperand::CreateReg(ARM::SP));
639 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
644 // Table A6-1 16-bit Thumb instruction encoding
647 // tADDrPCi: tRt imm8
648 static bool DisassembleThumb1AddPCi(MCInst &MI, unsigned Opcode, uint32_t insn,
649 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
651 assert(Opcode == ARM::tADDrPCi && "Invalid opcode");
653 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
654 if (!OpInfo) return false;
656 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
657 (OpInfo[1].RegClass == 0 &&
658 !OpInfo[1].isPredicate() &&
659 !OpInfo[1].isOptionalDef())
660 && "Invalid arguments");
662 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
664 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
669 // Table A6-1 16-bit Thumb instruction encoding
670 // A8.6.8 ADD (SP plus immediate)
672 // tADDrSPi: tRt ARM::SP imm8
673 static bool DisassembleThumb1AddSPi(MCInst &MI, unsigned Opcode, uint32_t insn,
674 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
676 assert(Opcode == ARM::tADDrSPi && "Invalid opcode");
678 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
679 if (!OpInfo) return false;
681 assert(NumOps >= 3 &&
682 OpInfo[0].RegClass == ARM::tGPRRegClassID &&
683 OpInfo[1].RegClass == ARM::GPRRegClassID &&
684 (OpInfo[2].RegClass == 0 &&
685 !OpInfo[2].isPredicate() &&
686 !OpInfo[2].isOptionalDef())
687 && "Invalid arguments");
689 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
691 MI.addOperand(MCOperand::CreateReg(ARM::SP));
692 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
697 // tPUSH, tPOP: Pred-Imm Pred-CCR register_list
699 // where register_list = low registers + [lr] for PUSH or
700 // low registers + [pc] for POP
702 // "low registers" is specified by Inst{7-0}
703 // lr|pc is specified by Inst{8}
704 static bool DisassembleThumb1PushPop(MCInst &MI, unsigned Opcode, uint32_t insn,
705 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
707 assert((Opcode == ARM::tPUSH || Opcode == ARM::tPOP) && "Invalid opcode");
709 unsigned &OpIdx = NumOpsAdded;
711 // Handling the two predicate operands before the reglist.
712 MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
713 MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
716 // Fill the variadic part of reglist.
717 unsigned RegListBits = slice(insn, 8, 8) << (Opcode == ARM::tPUSH ? 14 : 15)
719 for (unsigned i = 0; i < 16; ++i) {
720 if ((RegListBits >> i) & 1) {
721 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
730 // A6.2.5 Miscellaneous 16-bit instructions
731 // Delegate to DisassembleThumb1PushPop() for tPUSH & tPOP.
733 // tADDspi, tSUBspi: ARM::SP ARM::SP(TIED_TO) imm7
734 // t2IT: firstcond=Inst{7-4} mask=Inst{3-0}
735 // tCBNZ, tCBZ: tRd imm6*2
737 // tNOP, tSEV, tYIELD, tWFE, tWFI:
738 // no operand (except predicate pair)
739 // tSETENDBE, tSETENDLE, :
742 static bool DisassembleThumb1Misc(MCInst &MI, unsigned Opcode, uint32_t insn,
743 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
748 if (Opcode == ARM::tPUSH || Opcode == ARM::tPOP)
749 return DisassembleThumb1PushPop(MI, Opcode, insn, NumOps, NumOpsAdded, B);
751 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
753 // Predicate operands are handled elsewhere.
755 OpInfo[0].isPredicate() && OpInfo[1].isPredicate() &&
756 OpInfo[0].RegClass == 0 && OpInfo[1].RegClass == ARM::CCRRegClassID) {
760 if (Opcode == ARM::tADDspi || Opcode == ARM::tSUBspi) {
761 // Special case handling for tADDspi and tSUBspi.
762 // A8.6.8 ADD (SP plus immediate) & A8.6.215 SUB (SP minus immediate)
763 MI.addOperand(MCOperand::CreateReg(ARM::SP));
764 MI.addOperand(MCOperand::CreateReg(ARM::SP));
765 MI.addOperand(MCOperand::CreateImm(getT1Imm7(insn)));
770 if (Opcode == ARM::t2IT) {
771 // Special case handling for If-Then.
773 // Tag the (firstcond[0] bit << 4) along with mask.
776 MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 4)));
778 // firstcond[0] and mask
779 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
784 if (Opcode == ARM::tBKPT) {
785 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn))); // breakpoint value
790 // CPS has a singleton $opt operand that contains the following information:
791 // opt{4-0} = don't care
792 // opt{5} = 0 (false)
793 // opt{8-6} = AIF from Inst{2-0}
794 // opt{10-9} = 1:imod from Inst{4} with 0b10 as enable and 0b11 as disable
795 if (Opcode == ARM::tCPS) {
796 unsigned Option = slice(insn, 2, 0) << 6 | slice(insn, 4, 4) << 9 | 1 << 10;
797 MI.addOperand(MCOperand::CreateImm(Option));
802 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
803 (OpInfo[1].RegClass==0 || OpInfo[1].RegClass==ARM::tGPRRegClassID)
804 && "Expect >=2 operands");
806 // Add the destination operand.
807 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
810 if (OpInfo[1].RegClass == ARM::tGPRRegClassID) {
811 // Two register instructions.
812 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
816 assert((Opcode == ARM::tCBNZ || Opcode == ARM::tCBZ) && "Invalid opcode");
817 MI.addOperand(MCOperand::CreateImm(getT1Imm6(insn) * 2));
825 // A8.6.53 LDM / LDMIA
826 // A8.6.189 STM / STMIA
828 // tLDM_UPD/tSTM_UPD: tRt tRt AM4ModeImm Pred-Imm Pred-CCR register_list
829 // tLDM: tRt AM4ModeImm Pred-Imm Pred-CCR register_list
830 static bool DisassembleThumb1LdStMul(bool Ld, MCInst &MI, unsigned Opcode,
831 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
833 assert((Opcode == ARM::tLDM || Opcode == ARM::tLDM_UPD ||
834 Opcode == ARM::tSTM_UPD) && "Invalid opcode");
836 unsigned &OpIdx = NumOpsAdded;
838 unsigned tRt = getT1tRt(insn);
839 unsigned RegListBits = slice(insn, 7, 0);
843 // WB register, if necessary.
844 if (Opcode == ARM::tLDM_UPD || Opcode == ARM::tSTM_UPD) {
845 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
850 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
854 // A8.6.53 LDM / LDMIA / LDMFD - Encoding T1
855 MI.addOperand(MCOperand::CreateImm(ARM_AM::getAM4ModeImm(ARM_AM::ia)));
858 // Handling the two predicate operands before the reglist.
859 MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
860 MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
863 // Fill the variadic part of reglist.
864 for (unsigned i = 0; i < 8; ++i) {
865 if ((RegListBits >> i) & 1) {
866 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
875 static bool DisassembleThumb1LdMul(MCInst &MI, unsigned Opcode, uint32_t insn,
876 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
877 return DisassembleThumb1LdStMul(true, MI, Opcode, insn, NumOps, NumOpsAdded,
881 static bool DisassembleThumb1StMul(MCInst &MI, unsigned Opcode, uint32_t insn,
882 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
883 return DisassembleThumb1LdStMul(false, MI, Opcode, insn, NumOps, NumOpsAdded,
887 // A8.6.16 B Encoding T1
888 // cond = Inst{11-8} & imm8 = Inst{7-0}
889 // imm32 = SignExtend(imm8:'0', 32)
891 // tBcc: offset Pred-Imm Pred-CCR
892 // tSVC: imm8 Pred-Imm Pred-CCR
893 // tTRAP: 0 operand (early return)
894 static bool DisassembleThumb1CondBr(MCInst &MI, unsigned Opcode, uint32_t insn,
895 unsigned short NumOps, unsigned &NumOpsAdded, BO) {
897 if (Opcode == ARM::tTRAP)
900 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
901 if (!OpInfo) return false;
903 assert(NumOps == 3 && OpInfo[0].RegClass == 0 &&
904 OpInfo[1].isPredicate() && OpInfo[2].RegClass == ARM::CCRRegClassID
905 && "Exactly 3 operands expected");
907 unsigned Imm8 = getT1Imm8(insn);
908 MI.addOperand(MCOperand::CreateImm(
909 Opcode == ARM::tBcc ? SignExtend32<9>(Imm8 << 1) + 4
912 // Predicate operands by ARMBasicMCBuilder::TryPredicateAndSBitModifier().
918 // A8.6.16 B Encoding T2
919 // imm11 = Inst{10-0}
920 // imm32 = SignExtend(imm11:'0', 32)
923 static bool DisassembleThumb1Br(MCInst &MI, unsigned Opcode, uint32_t insn,
924 unsigned short NumOps, unsigned &NumOpsAdded, BO) {
926 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
927 if (!OpInfo) return false;
929 assert(NumOps == 1 && OpInfo[0].RegClass == 0 && "1 imm operand expected");
931 unsigned Imm11 = getT1Imm11(insn);
933 // When executing a Thumb instruction, PC reads as the address of the current
934 // instruction plus 4. The assembler subtracts 4 from the difference between
935 // the branch instruction and the target address, disassembler has to add 4 to
937 MI.addOperand(MCOperand::CreateImm(SignExtend32<12>(Imm11 << 1) + 4));
945 // See A6.2 16-bit Thumb instruction encoding for instruction classes
946 // corresponding to op.
948 // Table A6-1 16-bit Thumb instruction encoding (abridged)
949 // op Instruction or instruction class
950 // ------ --------------------------------------------------------------------
951 // 00xxxx Shift (immediate), add, subtract, move, and compare on page A6-7
952 // 010000 Data-processing on page A6-8
953 // 010001 Special data instructions and branch and exchange on page A6-9
954 // 01001x Load from Literal Pool, see LDR (literal) on page A8-122
955 // 0101xx Load/store single data item on page A6-10
958 // 10100x Generate PC-relative address, see ADR on page A8-32
959 // 10101x Generate SP-relative address, see ADD (SP plus immediate) on page A8-28
960 // 1011xx Miscellaneous 16-bit instructions on page A6-11
961 // 11000x Store multiple registers, see STM / STMIA / STMEA on page A8-374
962 // 11001x Load multiple registers, see LDM / LDMIA / LDMFD on page A8-110 a
963 // 1101xx Conditional branch, and Supervisor Call on page A6-13
964 // 11100x Unconditional Branch, see B on page A8-44
966 static bool DisassembleThumb1(uint16_t op, MCInst &MI, unsigned Opcode,
967 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
969 unsigned op1 = slice(op, 5, 4);
970 unsigned op2 = slice(op, 3, 2);
971 unsigned op3 = slice(op, 1, 0);
972 unsigned opA = slice(op, 5, 2);
975 // A6.2.1 Shift (immediate), add, subtract, move, and compare
976 return DisassembleThumb1General(MI, Opcode, insn, NumOps, NumOpsAdded, B);
982 // A6.2.2 Data-processing
983 return DisassembleThumb1DP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
985 // A6.2.3 Special data instructions and branch and exchange
986 return DisassembleThumb1Special(MI, Opcode, insn, NumOps, NumOpsAdded,
989 // A8.6.59 LDR (literal)
990 return DisassembleThumb1LdPC(MI, Opcode, insn, NumOps, NumOpsAdded, B);
994 // A6.2.4 Load/store single data item
995 return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
1003 // A6.2.4 Load/store single data item
1004 return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
1007 // A6.2.4 Load/store single data item
1008 return DisassembleThumb1LdStSP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1012 return DisassembleThumb1AddPCi(MI, Opcode, insn, NumOps, NumOpsAdded,
1015 // A8.6.8 ADD (SP plus immediate)
1016 return DisassembleThumb1AddSPi(MI, Opcode, insn, NumOps, NumOpsAdded,
1020 // A6.2.5 Miscellaneous 16-bit instructions
1021 return DisassembleThumb1Misc(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1028 // A8.6.189 STM / STMIA / STMEA
1029 return DisassembleThumb1StMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1031 // A8.6.53 LDM / LDMIA / LDMFD
1032 return DisassembleThumb1LdMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1035 // A6.2.6 Conditional branch, and Supervisor Call
1036 return DisassembleThumb1CondBr(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1038 // Unconditional Branch, see B on page A8-44
1039 return DisassembleThumb1Br(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1041 assert(0 && "Unreachable code");
1046 assert(0 && "Unreachable code");
1053 ///////////////////////////////////////////////
1055 // Thumb2 instruction disassembly functions. //
1057 ///////////////////////////////////////////////
1059 ///////////////////////////////////////////////////////////
1061 // Note: the register naming follows the ARM convention! //
1063 ///////////////////////////////////////////////////////////
1065 static inline bool Thumb2SRSOpcode(unsigned Opcode) {
1069 case ARM::t2SRSDBW: case ARM::t2SRSDB:
1070 case ARM::t2SRSIAW: case ARM::t2SRSIA:
1075 static inline bool Thumb2RFEOpcode(unsigned Opcode) {
1079 case ARM::t2RFEDBW: case ARM::t2RFEDB:
1080 case ARM::t2RFEIAW: case ARM::t2RFEIA:
1085 // t2SRS[IA|DB]W/t2SRS[IA|DB]: mode_imm = Inst{4-0}
1086 static bool DisassembleThumb2SRS(MCInst &MI, unsigned Opcode, uint32_t insn,
1087 unsigned short NumOps, unsigned &NumOpsAdded) {
1088 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
1093 // t2RFE[IA|DB]W/t2RFE[IA|DB]: Rn
1094 static bool DisassembleThumb2RFE(MCInst &MI, unsigned Opcode, uint32_t insn,
1095 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1096 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1102 static bool DisassembleThumb2LdStMul(MCInst &MI, unsigned Opcode, uint32_t insn,
1103 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1105 if (Thumb2SRSOpcode(Opcode))
1106 return DisassembleThumb2SRS(MI, Opcode, insn, NumOps, NumOpsAdded);
1108 if (Thumb2RFEOpcode(Opcode))
1109 return DisassembleThumb2RFE(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1111 assert((Opcode == ARM::t2LDM || Opcode == ARM::t2LDM_UPD ||
1112 Opcode == ARM::t2STM || Opcode == ARM::t2STM_UPD)
1113 && "Invalid opcode");
1114 assert(NumOps >= 5 && "Thumb2 LdStMul expects NumOps >= 5");
1116 unsigned &OpIdx = NumOpsAdded;
1120 unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
1122 // Writeback to base.
1123 if (Opcode == ARM::t2LDM_UPD || Opcode == ARM::t2STM_UPD) {
1124 MI.addOperand(MCOperand::CreateReg(Base));
1128 MI.addOperand(MCOperand::CreateReg(Base));
1131 ARM_AM::AMSubMode SubMode = getAMSubModeForBits(getPUBits(insn));
1132 MI.addOperand(MCOperand::CreateImm(ARM_AM::getAM4ModeImm(SubMode)));
1135 // Handling the two predicate operands before the reglist.
1136 MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
1137 MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
1140 // Fill the variadic part of reglist.
1141 unsigned RegListBits = insn & ((1 << 16) - 1);
1142 for (unsigned i = 0; i < 16; ++i) {
1143 if ((RegListBits >> i) & 1) {
1144 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1154 // t2LDREXD: Rd Rs Rn
1155 // t2LDREXB, t2LDREXH: Rd Rn
1156 // t2STREX: Rs Rd Rn
1157 // t2STREXD: Rm Rd Rs Rn
1158 // t2STREXB, t2STREXH: Rm Rd Rn
1159 static bool DisassembleThumb2LdStEx(MCInst &MI, unsigned Opcode, uint32_t insn,
1160 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1162 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1163 if (!OpInfo) return false;
1165 unsigned &OpIdx = NumOpsAdded;
1170 && OpInfo[0].RegClass == ARM::GPRRegClassID
1171 && OpInfo[1].RegClass == ARM::GPRRegClassID
1172 && "Expect >=2 operands and first two as reg operands");
1174 bool isStore = (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH);
1175 bool isSW = (Opcode == ARM::t2LDREX || Opcode == ARM::t2STREX);
1176 bool isDW = (Opcode == ARM::t2LDREXD || Opcode == ARM::t2STREXD);
1178 // Add the destination operand for store.
1180 MI.addOperand(MCOperand::CreateReg(
1181 getRegisterEnum(B, ARM::GPRRegClassID,
1182 isSW ? decodeRs(insn) : decodeRm(insn))));
1186 // Source operand for store and destination operand for load.
1187 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1191 // Thumb2 doubleword complication: with an extra source/destination operand.
1193 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1198 // Finally add the pointer operand.
1199 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1206 // LLVM, as of Jan-05-2010, does not output <Rt2>, i.e., Rs, in the asm.
1207 // Whereas the ARM Arch. Manual does not require that t2 = t+1 like in ARM ISA.
1209 // t2LDRDi8: Rd Rs Rn imm8s4 (offset mode)
1210 // t2LDRDpci: Rd Rs imm8s4 (Not decoded, prefer the generic t2LDRDi8 version)
1211 // t2STRDi8: Rd Rs Rn imm8s4 (offset mode)
1213 // Ditto for t2LDRD_PRE, t2LDRD_POST, t2STRD_PRE, t2STRD_POST, which are for
1214 // disassembly only and do not have a tied_to writeback base register operand.
1215 static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned Opcode,
1216 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1218 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1219 if (!OpInfo) return false;
1222 && OpInfo[0].RegClass == ARM::GPRRegClassID
1223 && OpInfo[1].RegClass == ARM::GPRRegClassID
1224 && OpInfo[2].RegClass == ARM::GPRRegClassID
1225 && OpInfo[3].RegClass == 0
1226 && "Expect >= 4 operands and first 3 as reg operands");
1228 // Add the <Rt> <Rt2> operands.
1229 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1231 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1233 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1236 // Finally add (+/-)imm8*4, depending on the U bit.
1237 int Offset = getImm8(insn) * 4;
1238 if (getUBit(insn) == 0)
1240 MI.addOperand(MCOperand::CreateImm(Offset));
1246 // PC-based defined for Codegen, which do not get decoded by design:
1248 // t2TBB, t2TBH: Rm immDontCare immDontCare
1250 // Generic version defined for disassembly:
1252 // t2TBBgen, t2TBHgen: Rn Rm Pred-Imm Pred-CCR
1253 static bool DisassembleThumb2TB(MCInst &MI, unsigned Opcode,
1254 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1256 assert(NumOps >= 2 && "Expect >= 2 operands");
1258 // The generic version of TBB/TBH needs a base register.
1259 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1261 // Add the index register.
1262 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1269 static inline bool Thumb2ShiftOpcode(unsigned Opcode) {
1273 case ARM::t2MOVCClsl: case ARM::t2MOVCClsr:
1274 case ARM::t2MOVCCasr: case ARM::t2MOVCCror:
1275 case ARM::t2LSLri: case ARM::t2LSRri:
1276 case ARM::t2ASRri: case ARM::t2RORri:
1281 // A6.3.11 Data-processing (shifted register)
1283 // Two register operands (Rn=0b1111 no 1st operand reg): Rs Rm
1284 // Two register operands (Rs=0b1111 no dst operand reg): Rn Rm
1285 // Three register operands: Rs Rn Rm
1286 // Three register operands: (Rn=0b1111 Conditional Move) Rs Ro(TIED_TO) Rm
1288 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
1289 // register with shift forms: (Rm, ConstantShiftSpecifier).
1290 // Constant shift specifier: Imm = (ShOp | ShAmt<<3).
1292 // There are special instructions, like t2MOVsra_flag and t2MOVsrl_flag, which
1293 // only require two register operands: Rd, Rm in ARM Reference Manual terms, and
1294 // nothing else, because the shift amount is already specified.
1295 // Similar case holds for t2MOVrx, t2ADDrr, ..., etc.
1296 static bool DisassembleThumb2DPSoReg(MCInst &MI, unsigned Opcode, uint32_t insn,
1297 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1299 const TargetInstrDesc &TID = ARMInsts[Opcode];
1300 const TargetOperandInfo *OpInfo = TID.OpInfo;
1301 unsigned &OpIdx = NumOpsAdded;
1303 // Special case handling.
1304 if (Opcode == ARM::t2BR_JT) {
1306 && OpInfo[0].RegClass == ARM::GPRRegClassID
1307 && OpInfo[1].RegClass == ARM::GPRRegClassID
1308 && OpInfo[2].RegClass == 0
1309 && OpInfo[3].RegClass == 0
1310 && "Exactlt 4 operands expect and first two as reg operands");
1311 // Only need to populate the src reg operand.
1312 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1314 MI.addOperand(MCOperand::CreateReg(0));
1315 MI.addOperand(MCOperand::CreateImm(0));
1316 MI.addOperand(MCOperand::CreateImm(0));
1324 && OpInfo[0].RegClass == ARM::GPRRegClassID
1325 && OpInfo[1].RegClass == ARM::GPRRegClassID
1326 && "Expect >= 2 operands and first two as reg operands");
1328 bool ThreeReg = (NumOps > 2 && OpInfo[2].RegClass == ARM::GPRRegClassID);
1329 bool NoDstReg = (decodeRs(insn) == 0xF);
1331 // Build the register operands, followed by the constant shift specifier.
1333 MI.addOperand(MCOperand::CreateReg(
1334 getRegisterEnum(B, ARM::GPRRegClassID,
1335 NoDstReg ? decodeRn(insn) : decodeRs(insn))));
1340 if ((Idx = TID.getOperandConstraint(OpIdx, TOI::TIED_TO)) != -1) {
1341 // Process tied_to operand constraint.
1342 MI.addOperand(MI.getOperand(Idx));
1344 assert(!NoDstReg && "Internal error");
1345 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1351 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1355 if (NumOps == OpIdx)
1358 if (OpInfo[OpIdx].RegClass == 0 && !OpInfo[OpIdx].isPredicate()
1359 && !OpInfo[OpIdx].isOptionalDef()) {
1361 if (Thumb2ShiftOpcode(Opcode))
1362 MI.addOperand(MCOperand::CreateImm(getShiftAmtBits(insn)));
1364 // Build the constant shift specifier operand.
1365 unsigned bits2 = getShiftTypeBits(insn);
1366 unsigned imm5 = getShiftAmtBits(insn);
1367 ARM_AM::ShiftOpc ShOp = ARM_AM::no_shift;
1368 unsigned ShAmt = decodeImmShift(bits2, imm5, ShOp);
1370 // PKHBT/PKHTB are special in that we need the decodeImmShift() call to
1371 // decode the shift amount from raw imm5 and bits2, but we DO NOT need
1372 // to encode the ShOp, as it's in the asm string already.
1373 if (Opcode == ARM::t2PKHBT || Opcode == ARM::t2PKHTB)
1374 MI.addOperand(MCOperand::CreateImm(ShAmt));
1376 MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShAmt)));
1384 // A6.3.1 Data-processing (modified immediate)
1386 // Two register operands: Rs Rn ModImm
1387 // One register operands (Rs=0b1111 no explicit dest reg): Rn ModImm
1388 // One register operands (Rn=0b1111 no explicit src reg): Rs ModImm - {t2MOVi, t2MVNi}
1390 // ModImm = ThumbExpandImm(i:imm3:imm8)
1391 static bool DisassembleThumb2DPModImm(MCInst &MI, unsigned Opcode,
1392 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1394 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1395 unsigned &OpIdx = NumOpsAdded;
1399 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::GPRRegClassID
1400 && "Expect >= 2 operands and first one as reg operand");
1402 bool TwoReg = (OpInfo[1].RegClass == ARM::GPRRegClassID);
1403 bool NoDstReg = (decodeRs(insn) == 0xF);
1405 // Build the register operands, followed by the modified immediate.
1407 MI.addOperand(MCOperand::CreateReg(
1408 getRegisterEnum(B, ARM::GPRRegClassID,
1409 NoDstReg ? decodeRn(insn) : decodeRs(insn))));
1413 assert(!NoDstReg && "Internal error");
1414 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1419 // The modified immediate operand should come next.
1420 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == 0 &&
1421 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()
1422 && "Pure imm operand expected");
1425 // A6.3.2 Modified immediate constants in Thumb instructions
1426 unsigned imm12 = getIImm3Imm8(insn);
1427 MI.addOperand(MCOperand::CreateImm(ThumbExpandImm(imm12)));
1433 static inline bool Thumb2SaturateOpcode(unsigned Opcode) {
1435 case ARM::t2SSATlsl: case ARM::t2SSATasr: case ARM::t2SSAT16:
1436 case ARM::t2USATlsl: case ARM::t2USATasr: case ARM::t2USAT16:
1443 static inline unsigned decodeThumb2SaturatePos(unsigned Opcode, uint32_t insn) {
1445 case ARM::t2SSATlsl:
1446 case ARM::t2SSATasr:
1447 return slice(insn, 4, 0) + 1;
1449 return slice(insn, 3, 0) + 1;
1450 case ARM::t2USATlsl:
1451 case ARM::t2USATasr:
1452 return slice(insn, 4, 0);
1454 return slice(insn, 3, 0);
1456 assert(0 && "Invalid opcode passed in");
1461 // A6.3.3 Data-processing (plain binary immediate)
1463 // o t2ADDri12, t2SUBri12: Rs Rn imm12
1464 // o t2LEApcrel (ADR): Rs imm12
1465 // o t2BFC (BFC): Rs Ro(TIED_TO) bf_inv_mask_imm
1466 // o t2BFI (BFI) (Currently not defined in LLVM as of Jan-07-2010)
1467 // o t2MOVi16: Rs imm16
1468 // o t2MOVTi16: Rs imm16
1469 // o t2SBFX (SBFX): Rs Rn lsb width
1470 // o t2UBFX (UBFX): Rs Rn lsb width
1471 // o t2BFI (BFI): Rs Rn lsb width
1473 // [Signed|Unsigned] Saturate [16]
1475 // o t2SSAT[lsl|asr], t2USAT[lsl|asr]: Rs sat_pos Rn shamt
1476 // o t2SSAT16, t2USAT16: Rs sat_pos Rn
1477 static bool DisassembleThumb2DPBinImm(MCInst &MI, unsigned Opcode,
1478 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1480 const TargetInstrDesc &TID = ARMInsts[Opcode];
1481 const TargetOperandInfo *OpInfo = TID.OpInfo;
1482 unsigned &OpIdx = NumOpsAdded;
1486 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::GPRRegClassID
1487 && "Expect >= 2 operands and first one as reg operand");
1489 bool TwoReg = (OpInfo[1].RegClass == ARM::GPRRegClassID);
1491 // Build the register operand(s), followed by the immediate(s).
1493 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1497 // t2SSAT/t2SSAT16/t2USAT/t2USAT16 has imm operand after Rd.
1498 if (Thumb2SaturateOpcode(Opcode)) {
1499 MI.addOperand(MCOperand::CreateImm(decodeThumb2SaturatePos(Opcode, insn)));
1501 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1504 if (Opcode == ARM::t2SSAT16 || Opcode == ARM::t2USAT16) {
1509 // For SSAT operand reg (Rn) has been disassembled above.
1510 // Now disassemble the shift amount.
1512 // Inst{14-12:7-6} encodes the imm5 shift amount.
1513 unsigned ShAmt = slice(insn, 14, 12) << 2 | slice(insn, 7, 6);
1515 MI.addOperand(MCOperand::CreateImm(ShAmt));
1522 assert(NumOps >= 3 && "Expect >= 3 operands");
1524 if ((Idx = TID.getOperandConstraint(OpIdx, TOI::TIED_TO)) != -1) {
1525 // Process tied_to operand constraint.
1526 MI.addOperand(MI.getOperand(Idx));
1528 // Add src reg operand.
1529 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1535 assert(OpInfo[OpIdx].RegClass == 0 && !OpInfo[OpIdx].isPredicate()
1536 && !OpInfo[OpIdx].isOptionalDef()
1537 && "Pure imm operand expected");
1539 // Pre-increment OpIdx.
1542 if (Opcode == ARM::t2ADDri12 || Opcode == ARM::t2SUBri12
1543 || Opcode == ARM::t2LEApcrel)
1544 MI.addOperand(MCOperand::CreateImm(getIImm3Imm8(insn)));
1545 else if (Opcode == ARM::t2MOVi16 || Opcode == ARM::t2MOVTi16)
1546 MI.addOperand(MCOperand::CreateImm(getImm16(insn)));
1547 else if (Opcode == ARM::t2BFC)
1548 MI.addOperand(MCOperand::CreateImm(getBitfieldInvMask(insn)));
1550 // Handle the case of: lsb width
1551 assert((Opcode == ARM::t2SBFX || Opcode == ARM::t2UBFX ||
1552 Opcode == ARM::t2BFI) && "Invalid opcode");
1553 MI.addOperand(MCOperand::CreateImm(getLsb(insn)));
1554 if (Opcode == ARM::t2BFI) {
1555 assert(getMsb(insn) >= getLsb(insn) && "Encoding error");
1556 MI.addOperand(MCOperand::CreateImm(getMsb(insn) - getLsb(insn) + 1));
1558 MI.addOperand(MCOperand::CreateImm(getWidthMinus1(insn) + 1));
1566 // A6.3.4 Table A6-15 Miscellaneous control instructions
1570 static inline bool t2MiscCtrlInstr(uint32_t insn) {
1571 if (slice(insn, 31, 20) == 0xf3b && slice(insn, 15, 14) == 2 &&
1572 slice(insn, 12, 12) == 0)
1578 // A6.3.4 Branches and miscellaneous control
1581 // Branches: t2B, t2Bcc -> imm operand
1583 // Branches: t2TPsoft -> no operand
1585 // A8.6.23 BL, BLX (immediate)
1586 // Branches (defined in ARMInstrThumb.td): tBLr9, tBLXi_r9 -> imm operand
1591 // Miscellaneous control: t2Int_MemBarrierV7 (and its t2DMB variants),
1592 // t2Int_SyncBarrierV7 (and its t2DSB varianst), t2ISBsy, t2CLREX
1593 // -> no operand (except pred-imm pred-ccr for CLREX, memory barrier variants)
1595 // Hint: t2NOP, t2YIELD, t2WFE, t2WFI, t2SEV
1596 // -> no operand (except pred-imm pred-ccr)
1598 // t2DBG -> imm4 = Inst{3-0}
1600 // t2MRS/t2MRSsys -> Rs
1601 // t2MSR/t2MSRsys -> Rn mask=Inst{11-8}
1602 // t2SMC -> imm4 = Inst{19-16}
1603 static bool DisassembleThumb2BrMiscCtrl(MCInst &MI, unsigned Opcode,
1604 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1609 if (t2MiscCtrlInstr(insn))
1624 // CPS has a singleton $opt operand that contains the following information:
1625 // opt{4-0} = mode from Inst{4-0}
1626 // opt{5} = changemode from Inst{8}
1627 // opt{8-6} = AIF from Inst{7-5}
1628 // opt{10-9} = imod from Inst{10-9} with 0b10 as enable and 0b11 as disable
1629 if (Opcode == ARM::t2CPS) {
1630 unsigned Option = slice(insn, 4, 0) | slice(insn, 8, 8) << 5 |
1631 slice(insn, 7, 5) << 6 | slice(insn, 10, 9) << 9;
1632 MI.addOperand(MCOperand::CreateImm(Option));
1637 // DBG has its option specified in Inst{3-0}.
1638 if (Opcode == ARM::t2DBG) {
1639 MI.addOperand(MCOperand::CreateImm(slice(insn, 3, 0)));
1644 // MRS and MRSsys take one GPR reg Rs.
1645 if (Opcode == ARM::t2MRS || Opcode == ARM::t2MRSsys) {
1646 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1651 // BXJ takes one GPR reg Rn.
1652 if (Opcode == ARM::t2BXJ) {
1653 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1658 // MSR and MSRsys take one GPR reg Rn, followed by the mask.
1659 if (Opcode == ARM::t2MSR || Opcode == ARM::t2MSRsys || Opcode == ARM::t2BXJ) {
1660 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1662 MI.addOperand(MCOperand::CreateImm(slice(insn, 11, 8)));
1667 if (Opcode == ARM::t2SMC) {
1668 MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 16)));
1673 // Add the imm operand.
1678 assert(0 && "Unreachable code");
1681 Offset = decodeImm32_B_EncodingT4(insn);
1684 Offset = decodeImm32_B_EncodingT3(insn);
1687 Offset = decodeImm32_BL(insn);
1690 Offset = decodeImm32_BLX(insn);
1693 // When executing a Thumb instruction, PC reads as the address of the current
1694 // instruction plus 4. The assembler subtracts 4 from the difference between
1695 // the branch instruction and the target address, disassembler has to add 4 to
1697 MI.addOperand(MCOperand::CreateImm(Offset + 4));
1704 static inline bool Thumb2PreloadOpcode(unsigned Opcode) {
1708 case ARM::t2PLDi12: case ARM::t2PLDi8: case ARM::t2PLDpci:
1709 case ARM::t2PLDr: case ARM::t2PLDs:
1710 case ARM::t2PLDWi12: case ARM::t2PLDWi8: case ARM::t2PLDWpci:
1711 case ARM::t2PLDWr: case ARM::t2PLDWs:
1712 case ARM::t2PLIi12: case ARM::t2PLIi8: case ARM::t2PLIpci:
1713 case ARM::t2PLIr: case ARM::t2PLIs:
1718 static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned Opcode, uint32_t insn,
1719 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1721 // Preload Data/Instruction requires either 2 or 3 operands.
1722 // t2PLDi12, t2PLDi8, t2PLDpci: Rn [+/-]imm12/imm8
1724 // t2PLDs: Rn Rm imm2=Inst{5-4}
1725 // Same pattern applies for t2PLDW* and t2PLI*.
1727 const TargetInstrDesc &TID = ARMInsts[Opcode];
1728 const TargetOperandInfo *OpInfo = TID.OpInfo;
1729 unsigned &OpIdx = NumOpsAdded;
1733 assert(NumOps >= 2 &&
1734 OpInfo[0].RegClass == ARM::GPRRegClassID &&
1735 "Expect >= 2 operands and first one as reg operand");
1737 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1741 if (OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) {
1742 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1745 assert(OpInfo[OpIdx].RegClass == 0 && !OpInfo[OpIdx].isPredicate()
1746 && !OpInfo[OpIdx].isOptionalDef()
1747 && "Pure imm operand expected");
1749 if (Opcode == ARM::t2PLDpci || Opcode == ARM::t2PLDWpci ||
1750 Opcode == ARM::t2PLIpci) {
1751 bool Negative = slice(insn, 23, 23) == 0;
1752 unsigned Imm12 = getImm12(insn);
1753 Offset = Negative ? -1 - Imm12 : 1 * Imm12;
1754 } else if (Opcode == ARM::t2PLDi8 || Opcode == ARM::t2PLDWi8 ||
1755 Opcode == ARM::t2PLIi8) {
1756 // A8.6.117 Encoding T2: add = FALSE
1757 unsigned Imm8 = getImm8(insn);
1759 } else // The i12 forms. See, for example, A8.6.117 Encoding T1.
1760 Offset = decodeImm12(insn);
1761 MI.addOperand(MCOperand::CreateImm(Offset));
1765 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass == 0 &&
1766 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
1767 // Fills in the shift amount for t2PLDs, t2PLDWs, t2PLIs.
1768 MI.addOperand(MCOperand::CreateImm(slice(insn, 5, 4)));
1775 // A8.6.63 LDRB (literal)
1776 // A8.6.79 LDRSB (literal)
1777 // A8.6.75 LDRH (literal)
1778 // A8.6.83 LDRSH (literal)
1779 // A8.6.59 LDR (literal)
1781 // These instrs calculate an address from the PC value and an immediate offset.
1782 // Rd Rn=PC (+/-)imm12 (+ if Inst{23} == 0b1)
1783 static bool DisassembleThumb2Ldpci(MCInst &MI, unsigned Opcode,
1784 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1786 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1787 if (!OpInfo) return false;
1789 assert(NumOps >= 2 &&
1790 OpInfo[0].RegClass == ARM::GPRRegClassID &&
1791 OpInfo[1].RegClass == 0 &&
1792 "Expect >= 2 operands, first as reg, and second as imm operand");
1794 // Build the register operand, followed by the (+/-)imm12 immediate.
1796 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1799 MI.addOperand(MCOperand::CreateImm(decodeImm12(insn)));
1806 // A6.3.10 Store single data item
1807 // A6.3.9 Load byte, memory hints
1808 // A6.3.8 Load halfword, memory hints
1813 // t2LDRi12: Rd Rn (+)imm12
1814 // t2LDRi8: Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
1815 // t2LDRs: Rd Rn Rm ConstantShiftSpecifier (see also DisassembleThumb2DPSoReg)
1816 // t2LDR_POST: Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
1817 // t2LDR_PRE: Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
1819 // t2STRi12: Rd Rn (+)imm12
1820 // t2STRi8: Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
1821 // t2STRs: Rd Rn Rm ConstantShiftSpecifier (see also DisassembleThumb2DPSoReg)
1822 // t2STR_POST: Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
1823 // t2STR_PRE: Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
1825 // Note that for indexed modes, the Rn(TIED_TO) operand needs to be populated
1826 // correctly, as LLVM AsmPrinter depends on it. For indexed stores, the first
1827 // operand is Rn; for all the other instructions, Rd is the first operand.
1829 // Delegates to DisassembleThumb2PreLoad() for preload data/instruction.
1830 // Delegates to DisassembleThumb2Ldpci() for load * literal operations.
1831 static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, unsigned Opcode,
1832 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1834 unsigned Rn = decodeRn(insn);
1836 if (Thumb2PreloadOpcode(Opcode))
1837 return DisassembleThumb2PreLoad(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1839 // See, for example, A6.3.7 Load word: Table A6-18 Load word.
1840 if (Load && Rn == 15)
1841 return DisassembleThumb2Ldpci(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1843 const TargetInstrDesc &TID = ARMInsts[Opcode];
1844 const TargetOperandInfo *OpInfo = TID.OpInfo;
1845 unsigned &OpIdx = NumOpsAdded;
1849 assert(NumOps >= 3 &&
1850 OpInfo[0].RegClass == ARM::GPRRegClassID &&
1851 OpInfo[1].RegClass == ARM::GPRRegClassID &&
1852 "Expect >= 3 operands and first two as reg operands");
1854 bool ThreeReg = (OpInfo[2].RegClass == ARM::GPRRegClassID);
1855 bool TIED_TO = ThreeReg && TID.getOperandConstraint(2, TOI::TIED_TO) != -1;
1856 bool Imm12 = !ThreeReg && slice(insn, 23, 23) == 1; // ARMInstrThumb2.td
1858 // Build the register operands, followed by the immediate.
1859 unsigned R0, R1, R2 = 0;
1860 unsigned Rd = decodeRd(insn);
1863 if (!Load && TIED_TO) {
1873 Imm = decodeImm8(insn);
1875 R2 = decodeRm(insn);
1876 // See, for example, A8.6.64 LDRB (register).
1877 // And ARMAsmPrinter::printT2AddrModeSoRegOperand().
1878 // LSL is the default shift opc, and LLVM does not expect it to be encoded
1879 // as part of the immediate operand.
1880 // Imm = ARM_AM::getSORegOpc(ARM_AM::lsl, slice(insn, 5, 4));
1881 Imm = slice(insn, 5, 4);
1885 Imm = getImm12(insn);
1887 Imm = decodeImm8(insn);
1890 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1893 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1898 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1903 assert(OpInfo[OpIdx].RegClass == 0 && !OpInfo[OpIdx].isPredicate()
1904 && !OpInfo[OpIdx].isOptionalDef()
1905 && "Pure imm operand expected");
1907 MI.addOperand(MCOperand::CreateImm(Imm));
1913 // A6.3.12 Data-processing (register)
1915 // Two register operands [rotate]: Rs Rm [rotation(= (rotate:'000'))]
1916 // Three register operands only: Rs Rn Rm
1917 // Three register operands [rotate]: Rs Rn Rm [rotation(= (rotate:'000'))]
1919 // Parallel addition and subtraction 32-bit Thumb instructions: Rs Rn Rm
1921 // Miscellaneous operations: Rs [Rn] Rm
1922 static bool DisassembleThumb2DPReg(MCInst &MI, unsigned Opcode, uint32_t insn,
1923 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1925 const TargetInstrDesc &TID = ARMInsts[Opcode];
1926 const TargetOperandInfo *OpInfo = TID.OpInfo;
1927 unsigned &OpIdx = NumOpsAdded;
1931 assert(NumOps >= 2 &&
1932 OpInfo[0].RegClass == ARM::GPRRegClassID &&
1933 OpInfo[1].RegClass == ARM::GPRRegClassID &&
1934 "Expect >= 2 operands and first two as reg operands");
1936 // Build the register operands, followed by the optional rotation amount.
1938 bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass == ARM::GPRRegClassID;
1940 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1945 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1950 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1954 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass == 0
1955 && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
1956 // Add the rotation amount immediate.
1957 MI.addOperand(MCOperand::CreateImm(decodeRotate(insn)));
1964 // A6.3.16 Multiply, multiply accumulate, and absolute difference
1966 // t2MLA, t2MLS, t2SMMLA, t2SMMLS: Rs Rn Rm Ra=Inst{15-12}
1967 // t2MUL, t2SMMUL: Rs Rn Rm
1968 // t2SMLA[BB|BT|TB|TT|WB|WT]: Rs Rn Rm Ra=Inst{15-12}
1969 // t2SMUL[BB|BT|TB|TT|WB|WT]: Rs Rn Rm
1971 // Dual halfword multiply: t2SMUAD[X], t2SMUSD[X], t2SMLAD[X], t2SMLSD[X]:
1972 // Rs Rn Rm Ra=Inst{15-12}
1974 // Unsigned Sum of Absolute Differences [and Accumulate]
1975 // Rs Rn Rm [Ra=Inst{15-12}]
1976 static bool DisassembleThumb2Mul(MCInst &MI, unsigned Opcode, uint32_t insn,
1977 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1979 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1981 assert(NumOps >= 3 &&
1982 OpInfo[0].RegClass == ARM::GPRRegClassID &&
1983 OpInfo[1].RegClass == ARM::GPRRegClassID &&
1984 OpInfo[2].RegClass == ARM::GPRRegClassID &&
1985 "Expect >= 3 operands and first three as reg operands");
1987 // Build the register operands.
1989 bool FourReg = NumOps > 3 && OpInfo[3].RegClass == ARM::GPRRegClassID;
1991 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1994 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1997 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
2001 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
2004 NumOpsAdded = FourReg ? 4 : 3;
2009 // A6.3.17 Long multiply, long multiply accumulate, and divide
2011 // t2SMULL, t2UMULL, t2SMLAL, t2UMLAL, t2UMAAL: RdLo RdHi Rn Rm
2012 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2014 // Halfword multiple accumulate long: t2SMLAL<x><y>: RdLo RdHi Rn Rm
2015 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2017 // Dual halfword multiple: t2SMLALD[X], t2SMLSLD[X]: RdLo RdHi Rn Rm
2018 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2020 // Signed/Unsigned divide: t2SDIV, t2UDIV: Rs Rn Rm
2021 static bool DisassembleThumb2LongMul(MCInst &MI, unsigned Opcode, uint32_t insn,
2022 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2024 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
2026 assert(NumOps >= 3 &&
2027 OpInfo[0].RegClass == ARM::GPRRegClassID &&
2028 OpInfo[1].RegClass == ARM::GPRRegClassID &&
2029 OpInfo[2].RegClass == ARM::GPRRegClassID &&
2030 "Expect >= 3 operands and first three as reg operands");
2032 bool FourReg = NumOps > 3 && OpInfo[3].RegClass == ARM::GPRRegClassID;
2034 // Build the register operands.
2037 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
2040 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
2043 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
2046 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
2057 // See A6.3 32-bit Thumb instruction encoding for instruction classes
2058 // corresponding to (op1, op2, op).
2060 // Table A6-9 32-bit Thumb instruction encoding
2061 // op1 op2 op Instruction class, see
2062 // --- ------- -- ------------------------------------------------------------
2063 // 01 00xx0xx - Load/store multiple on page A6-23
2064 // 00xx1xx - Load/store dual, load/store exclusive, table branch on page A6-24
2065 // 01xxxxx - Data-processing (shifted register) on page A6-31
2066 // 1xxxxxx - Coprocessor instructions on page A6-40
2067 // 10 x0xxxxx 0 Data-processing (modified immediate) on page A6-15
2068 // x1xxxxx 0 Data-processing (plain binary immediate) on page A6-19
2069 // - 1 Branches and miscellaneous control on page A6-20
2070 // 11 000xxx0 - Store single data item on page A6-30
2071 // 001xxx0 - Advanced SIMD element or structure load/store instructions on page A7-27
2072 // 00xx001 - Load byte, memory hints on page A6-28
2073 // 00xx011 - Load halfword, memory hints on page A6-26
2074 // 00xx101 - Load word on page A6-25
2075 // 00xx111 - UNDEFINED
2076 // 010xxxx - Data-processing (register) on page A6-33
2077 // 0110xxx - Multiply, multiply accumulate, and absolute difference on page A6-38
2078 // 0111xxx - Long multiply, long multiply accumulate, and divide on page A6-39
2079 // 1xxxxxx - Coprocessor instructions on page A6-40
2081 static bool DisassembleThumb2(uint16_t op1, uint16_t op2, uint16_t op,
2082 MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps,
2083 unsigned &NumOpsAdded, BO B) {
2087 if (slice(op2, 6, 5) == 0) {
2088 if (slice(op2, 2, 2) == 0) {
2089 // Load/store multiple.
2090 return DisassembleThumb2LdStMul(MI, Opcode, insn, NumOps, NumOpsAdded,
2094 // Load/store dual, load/store exclusive, table branch, otherwise.
2095 assert(slice(op2, 2, 2) == 1 && "Encoding error");
2096 if ((ARM::t2LDREX <= Opcode && Opcode <= ARM::t2LDREXH) ||
2097 (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH)) {
2098 // Load/store exclusive.
2099 return DisassembleThumb2LdStEx(MI, Opcode, insn, NumOps, NumOpsAdded,
2102 if (Opcode == ARM::t2LDRDi8 ||
2103 Opcode == ARM::t2LDRD_PRE || Opcode == ARM::t2LDRD_POST ||
2104 Opcode == ARM::t2STRDi8 ||
2105 Opcode == ARM::t2STRD_PRE || Opcode == ARM::t2STRD_POST) {
2107 return DisassembleThumb2LdStDual(MI, Opcode, insn, NumOps, NumOpsAdded,
2110 if (Opcode == ARM::t2TBBgen || Opcode == ARM::t2TBHgen) {
2112 return DisassembleThumb2TB(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2114 } else if (slice(op2, 6, 5) == 1) {
2115 // Data-processing (shifted register).
2116 return DisassembleThumb2DPSoReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2119 // FIXME: A6.3.18 Coprocessor instructions
2120 // But see ThumbDisassembler::getInstruction().
2125 if (slice(op2, 5, 5) == 0) {
2126 // Data-processing (modified immediate)
2127 return DisassembleThumb2DPModImm(MI, Opcode, insn, NumOps, NumOpsAdded,
2130 // Data-processing (plain binary immediate)
2131 return DisassembleThumb2DPBinImm(MI, Opcode, insn, NumOps, NumOpsAdded,
2135 // Branches and miscellaneous control on page A6-20.
2136 return DisassembleThumb2BrMiscCtrl(MI, Opcode, insn, NumOps, NumOpsAdded,
2142 switch (slice(op2, 6, 5)) {
2144 // Load/store instructions...
2145 if (slice(op2, 0, 0) == 0) {
2146 if (slice(op2, 4, 4) == 0) {
2147 // Store single data item on page A6-30
2148 return DisassembleThumb2LdSt(false, MI,Opcode,insn,NumOps,NumOpsAdded,
2151 // FIXME: Advanced SIMD element or structure load/store instructions.
2152 // But see ThumbDisassembler::getInstruction().
2156 // Table A6-9 32-bit Thumb instruction encoding: Load byte|halfword|word
2157 return DisassembleThumb2LdSt(true, MI,Opcode,insn,NumOps,NumOpsAdded, B);
2161 if (slice(op2, 4, 4) == 0) {
2162 // A6.3.12 Data-processing (register)
2163 return DisassembleThumb2DPReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2164 } else if (slice(op2, 3, 3) == 0) {
2165 // A6.3.16 Multiply, multiply accumulate, and absolute difference
2166 return DisassembleThumb2Mul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2168 // A6.3.17 Long multiply, long multiply accumulate, and divide
2169 return DisassembleThumb2LongMul(MI, Opcode, insn, NumOps, NumOpsAdded,
2174 // FIXME: A6.3.18 Coprocessor instructions
2175 // But see ThumbDisassembler::getInstruction().
2182 assert(0 && "Encoding error for Thumb2 instruction!");
2189 static bool DisassembleThumbFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
2190 unsigned short NumOps, unsigned &NumOpsAdded, BO Builder) {
2192 uint16_t HalfWord = slice(insn, 31, 16);
2194 if (HalfWord == 0) {
2195 // A6.2 16-bit Thumb instruction encoding
2197 uint16_t op = slice(insn, 15, 10);
2198 return DisassembleThumb1(op, MI, Opcode, insn, NumOps, NumOpsAdded,
2202 unsigned bits15_11 = slice(HalfWord, 15, 11);
2204 // A6.1 Thumb instruction set encoding
2205 if (!(bits15_11 == 0x1D || bits15_11 == 0x1E || bits15_11 == 0x1F)) {
2206 assert("Bits[15:11] first halfword of Thumb2 instruction is out of range");
2210 // A6.3 32-bit Thumb instruction encoding
2212 uint16_t op1 = slice(HalfWord, 12, 11);
2213 uint16_t op2 = slice(HalfWord, 10, 4);
2214 uint16_t op = slice(insn, 15, 15);
2216 return DisassembleThumb2(op1, op2, op, MI, Opcode, insn, NumOps, NumOpsAdded,