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 // 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 bool getBitfieldInvMask(uint32_t insn, uint32_t &mask) {
197 uint32_t lsb = getImm3(insn) << 2 | getImm2(insn);
198 uint32_t msb = getMsb(insn);
201 DEBUG(errs() << "Encoding error: msb < lsb\n");
204 for (uint32_t i = lsb; i <= msb; ++i)
210 // A8.4 Shifts applied to a register
211 // A8.4.1 Constant shifts
212 // A8.4.3 Pseudocode details of instruction-specified shifts and rotates
214 // decodeImmShift() returns the shift amount and the the shift opcode.
215 // Note that, as of Jan-06-2010, LLVM does not support rrx shifted operands yet.
216 static inline unsigned decodeImmShift(unsigned bits2, unsigned imm5,
217 ARM_AM::ShiftOpc &ShOp) {
219 assert(imm5 < 32 && "Invalid imm5 argument");
221 default: assert(0 && "No such value");
223 ShOp = (imm5 == 0 ? ARM_AM::no_shift : ARM_AM::lsl);
227 return (imm5 == 0 ? 32 : imm5);
230 return (imm5 == 0 ? 32 : imm5);
232 ShOp = (imm5 == 0 ? ARM_AM::rrx : ARM_AM::ror);
233 return (imm5 == 0 ? 1 : imm5);
237 // A6.3.2 Modified immediate constants in Thumb instructions
239 // ThumbExpandImm() returns the modified immediate constant given an imm12 for
240 // Thumb data-processing instructions with modified immediate.
241 // See also A6.3.1 Data-processing (modified immediate).
242 static inline unsigned ThumbExpandImm(unsigned imm12) {
243 assert(imm12 <= 0xFFF && "Invalid imm12 argument");
245 // If the leading two bits is 0b00, the modified immediate constant is
246 // obtained by splatting the low 8 bits into the first byte, every other byte,
247 // or every byte of a 32-bit value.
249 // Otherwise, a rotate right of '1':imm12<6:0> by the amount imm12<11:7> is
252 if (slice(imm12, 11, 10) == 0) {
253 unsigned short control = slice(imm12, 9, 8);
254 unsigned imm8 = slice(imm12, 7, 0);
257 assert(0 && "No such value");
262 return imm8 << 16 | imm8;
264 return imm8 << 24 | imm8 << 8;
266 return imm8 << 24 | imm8 << 16 | imm8 << 8 | imm8;
269 // A rotate is required.
270 unsigned Val = 1 << 7 | slice(imm12, 6, 0);
271 unsigned Amt = slice(imm12, 11, 7);
272 return ARM_AM::rotr32(Val, Amt);
276 static inline int decodeImm32_B_EncodingT3(uint32_t insn) {
277 bool S = slice(insn, 26, 26);
278 bool J1 = slice(insn, 13, 13);
279 bool J2 = slice(insn, 11, 11);
280 unsigned Imm21 = slice(insn, 21, 16) << 12 | slice(insn, 10, 0) << 1;
281 if (S) Imm21 |= 1 << 20;
282 if (J2) Imm21 |= 1 << 19;
283 if (J1) Imm21 |= 1 << 18;
285 return SignExtend32<21>(Imm21);
288 static inline int decodeImm32_B_EncodingT4(uint32_t insn) {
289 unsigned S = slice(insn, 26, 26);
290 bool I1 = slice(insn, 13, 13) == S;
291 bool I2 = slice(insn, 11, 11) == S;
292 unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 0) << 1;
293 if (S) Imm25 |= 1 << 24;
294 if (I1) Imm25 |= 1 << 23;
295 if (I2) Imm25 |= 1 << 22;
297 return SignExtend32<25>(Imm25);
300 static inline int decodeImm32_BL(uint32_t insn) {
301 unsigned S = slice(insn, 26, 26);
302 bool I1 = slice(insn, 13, 13) == S;
303 bool I2 = slice(insn, 11, 11) == S;
304 unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 0) << 1;
305 if (S) Imm25 |= 1 << 24;
306 if (I1) Imm25 |= 1 << 23;
307 if (I2) Imm25 |= 1 << 22;
309 return SignExtend32<25>(Imm25);
312 static inline int decodeImm32_BLX(uint32_t insn) {
313 unsigned S = slice(insn, 26, 26);
314 bool I1 = slice(insn, 13, 13) == S;
315 bool I2 = slice(insn, 11, 11) == S;
316 unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 1) << 2;
317 if (S) Imm25 |= 1 << 24;
318 if (I1) Imm25 |= 1 << 23;
319 if (I2) Imm25 |= 1 << 22;
321 return SignExtend32<25>(Imm25);
324 // See, for example, A8.6.221 SXTAB16.
325 static inline unsigned decodeRotate(uint32_t insn) {
326 unsigned rotate = slice(insn, 5, 4);
330 ///////////////////////////////////////////////
332 // Thumb1 instruction disassembly functions. //
334 ///////////////////////////////////////////////
336 // See "Utilities for 16-bit Thumb instructions" for register naming convention.
338 // A6.2.1 Shift (immediate), add, subtract, move, and compare
340 // shift immediate: tRd CPSR tRn imm5
341 // add/sub register: tRd CPSR tRn tRm
342 // add/sub 3-bit immediate: tRd CPSR tRn imm3
343 // add/sub 8-bit immediate: tRt CPSR tRt(TIED_TO) imm8
344 // mov/cmp immediate: tRt [CPSR] imm8 (CPSR present for mov)
348 static bool DisassembleThumb1General(MCInst &MI, unsigned Opcode, uint32_t insn,
349 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
351 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
352 unsigned &OpIdx = NumOpsAdded;
356 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID
357 && "Invalid arguments");
359 bool Imm3 = (Opcode == ARM::tADDi3 || Opcode == ARM::tSUBi3);
361 // Use Rt implies use imm8.
362 bool UseRt = (Opcode == ARM::tADDi8 || Opcode == ARM::tSUBi8 ||
363 Opcode == ARM::tMOVi8 || Opcode == ARM::tCMPi8);
365 // Add the destination operand.
366 MI.addOperand(MCOperand::CreateReg(
367 getRegisterEnum(B, ARM::tGPRRegClassID,
368 UseRt ? getT1tRt(insn) : getT1tRd(insn))));
371 // Check whether the next operand to be added is a CCR Register.
372 if (OpInfo[OpIdx].RegClass == ARM::CCRRegClassID) {
373 assert(OpInfo[OpIdx].isOptionalDef() && "Optional def operand expected");
374 MI.addOperand(MCOperand::CreateReg(B->InITBlock() ? 0 : ARM::CPSR));
378 // Check whether the next operand to be added is a Thumb1 Register.
379 assert(OpIdx < NumOps && "More operands expected");
380 if (OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
381 // For UseRt, the reg operand is tied to the first reg operand.
382 MI.addOperand(MCOperand::CreateReg(
383 getRegisterEnum(B, ARM::tGPRRegClassID,
384 UseRt ? getT1tRt(insn) : getT1tRn(insn))));
388 // Special case for tMOVSr.
392 // The next available operand is either a reg operand or an imm operand.
393 if (OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
394 // Three register operand instructions.
395 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
398 assert(OpInfo[OpIdx].RegClass < 0 &&
399 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()
400 && "Pure imm operand expected");
401 MI.addOperand(MCOperand::CreateImm(UseRt ? getT1Imm8(insn)
402 : (Imm3 ? getT1Imm3(insn)
403 : getT1Imm5(insn))));
410 // A6.2.2 Data-processing
412 // tCMPr, tTST, tCMN: tRd tRn
413 // tMVN, tRSB: tRd CPSR tRn
414 // Others: tRd CPSR tRd(TIED_TO) tRn
415 static bool DisassembleThumb1DP(MCInst &MI, unsigned Opcode, uint32_t insn,
416 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
418 const TargetInstrDesc &TID = ARMInsts[Opcode];
419 const TargetOperandInfo *OpInfo = TID.OpInfo;
420 unsigned &OpIdx = NumOpsAdded;
424 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
425 (OpInfo[1].RegClass == ARM::CCRRegClassID
426 || OpInfo[1].RegClass == ARM::tGPRRegClassID)
427 && "Invalid arguments");
429 // Add the destination operand.
430 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
434 // Check whether the next operand to be added is a CCR Register.
435 if (OpInfo[OpIdx].RegClass == ARM::CCRRegClassID) {
436 assert(OpInfo[OpIdx].isOptionalDef() && "Optional def operand expected");
437 MI.addOperand(MCOperand::CreateReg(B->InITBlock() ? 0 : ARM::CPSR));
441 // We have either { tRd(TIED_TO), tRn } or { tRn } remaining.
442 // Process the TIED_TO operand first.
444 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
445 && "Thumb reg operand expected");
447 if ((Idx = TID.getOperandConstraint(OpIdx, TOI::TIED_TO)) != -1) {
448 // The reg operand is tied to the first reg operand.
449 MI.addOperand(MI.getOperand(Idx));
453 // Process possible next reg operand.
454 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
456 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
464 // A6.2.3 Special data instructions and branch and exchange
466 // tADDhirr: Rd Rd(TIED_TO) Rm
468 // tMOVr, tMOVgpr2gpr, tMOVgpr2tgpr, tMOVtgpr2gpr: Rd|tRd Rm|tRn
469 // tBX_RET: 0 operand
470 // tBX_RET_vararg: Rm
472 static bool DisassembleThumb1Special(MCInst &MI, unsigned Opcode, uint32_t insn,
473 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
475 // tBX_RET has 0 operand.
479 // BX/BLX has 1 reg operand: Rm.
481 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
487 const TargetInstrDesc &TID = ARMInsts[Opcode];
488 const TargetOperandInfo *OpInfo = TID.OpInfo;
489 unsigned &OpIdx = NumOpsAdded;
493 // Add the destination operand.
494 unsigned RegClass = OpInfo[OpIdx].RegClass;
495 MI.addOperand(MCOperand::CreateReg(
496 getRegisterEnum(B, RegClass,
497 IsGPR(RegClass) ? getT1Rd(insn)
501 // We have either { Rd(TIED_TO), Rm } or { Rm|tRn } remaining.
502 // Process the TIED_TO operand first.
504 assert(OpIdx < NumOps && "More operands expected");
506 if ((Idx = TID.getOperandConstraint(OpIdx, TOI::TIED_TO)) != -1) {
507 // The reg operand is tied to the first reg operand.
508 MI.addOperand(MI.getOperand(Idx));
512 // The next reg operand is either Rm or tRn.
513 assert(OpIdx < NumOps && "More operands expected");
514 RegClass = OpInfo[OpIdx].RegClass;
515 MI.addOperand(MCOperand::CreateReg(
516 getRegisterEnum(B, RegClass,
517 IsGPR(RegClass) ? getT1Rm(insn)
524 // A8.6.59 LDR (literal)
526 // tLDRpci: tRt imm8*4
527 static bool DisassembleThumb1LdPC(MCInst &MI, unsigned Opcode, uint32_t insn,
528 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
530 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
531 if (!OpInfo) return false;
533 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
534 (OpInfo[1].RegClass < 0 &&
535 !OpInfo[1].isPredicate() &&
536 !OpInfo[1].isOptionalDef())
537 && "Invalid arguments");
539 // Add the destination operand.
540 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
543 // And the (imm8 << 2) operand.
544 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn) << 2));
551 // Thumb specific addressing modes (see ARMInstrThumb.td):
553 // t_addrmode_rr := reg + reg
555 // t_addrmode_s4 := reg + reg
558 // t_addrmode_s2 := reg + reg
561 // t_addrmode_s1 := reg + reg
564 // t_addrmode_sp := sp + imm8 * 4
567 // A8.6.63 LDRB (literal)
568 // A8.6.79 LDRSB (literal)
569 // A8.6.75 LDRH (literal)
570 // A8.6.83 LDRSH (literal)
571 // A8.6.59 LDR (literal)
573 // These instrs calculate an address from the PC value and an immediate offset.
574 // Rd Rn=PC (+/-)imm12 (+ if Inst{23} == 0b1)
575 static bool DisassembleThumb2Ldpci(MCInst &MI, unsigned Opcode,
576 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
578 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
579 if (!OpInfo) return false;
581 assert(NumOps >= 2 &&
582 OpInfo[0].RegClass == ARM::GPRRegClassID &&
583 OpInfo[1].RegClass < 0 &&
584 "Expect >= 2 operands, first as reg, and second as imm operand");
586 // Build the register operand, followed by the (+/-)imm12 immediate.
588 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
591 MI.addOperand(MCOperand::CreateImm(decodeImm12(insn)));
599 // A6.2.4 Load/store single data item
601 // Load/Store Register (reg|imm): tRd tRn imm5|tRm
602 // Load Register Signed Byte|Halfword: tRd tRn tRm
603 static bool DisassembleThumb1LdSt(unsigned opA, MCInst &MI, unsigned Opcode,
604 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
606 const TargetInstrDesc &TID = ARMInsts[Opcode];
607 const TargetOperandInfo *OpInfo = TID.OpInfo;
608 unsigned &OpIdx = NumOpsAdded;
611 && OpInfo[0].RegClass == ARM::tGPRRegClassID
612 && OpInfo[1].RegClass == ARM::tGPRRegClassID
613 && "Expect >= 2 operands and first two as thumb reg operands");
615 // Add the destination reg and the base reg.
616 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
618 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
622 // We have either { imm5 } or { tRm } remaining.
623 // Note that STR/LDR (register) should skip the imm5 offset operand for
624 // t_addrmode_s[1|2|4].
626 assert(OpIdx < NumOps && "More operands expected");
628 if (OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate() &&
629 !OpInfo[OpIdx].isOptionalDef()) {
630 // Table A6-5 16-bit Thumb Load/store instructions
631 // opA = 0b0101 for STR/LDR (register) and friends.
632 // Otherwise, we have STR/LDR (immediate) and friends.
633 assert(opA != 5 && "Immediate operand expected for this opcode");
634 MI.addOperand(MCOperand::CreateImm(getT1Imm5(insn)));
637 // The next reg operand is tRm, the offset.
638 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
639 && "Thumb reg operand expected");
640 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
647 // A6.2.4 Load/store single data item
649 // Load/Store Register SP relative: tRt ARM::SP imm8
650 static bool DisassembleThumb1LdStSP(MCInst &MI, unsigned Opcode, uint32_t insn,
651 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
653 assert((Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi)
654 && "Unexpected opcode");
656 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
657 if (!OpInfo) return false;
659 assert(NumOps >= 3 &&
660 OpInfo[0].RegClass == ARM::tGPRRegClassID &&
661 OpInfo[1].RegClass == ARM::GPRRegClassID &&
662 (OpInfo[2].RegClass < 0 &&
663 !OpInfo[2].isPredicate() &&
664 !OpInfo[2].isOptionalDef())
665 && "Invalid arguments");
667 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
669 MI.addOperand(MCOperand::CreateReg(ARM::SP));
670 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
675 // Table A6-1 16-bit Thumb instruction encoding
678 // tADDrPCi: tRt imm8
679 static bool DisassembleThumb1AddPCi(MCInst &MI, unsigned Opcode, uint32_t insn,
680 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
682 assert(Opcode == ARM::tADDrPCi && "Unexpected opcode");
684 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
685 if (!OpInfo) return false;
687 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
688 (OpInfo[1].RegClass < 0 &&
689 !OpInfo[1].isPredicate() &&
690 !OpInfo[1].isOptionalDef())
691 && "Invalid arguments");
693 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
695 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
700 // Table A6-1 16-bit Thumb instruction encoding
701 // A8.6.8 ADD (SP plus immediate)
703 // tADDrSPi: tRt ARM::SP imm8
704 static bool DisassembleThumb1AddSPi(MCInst &MI, unsigned Opcode, uint32_t insn,
705 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
707 assert(Opcode == ARM::tADDrSPi && "Unexpected opcode");
709 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
710 if (!OpInfo) return false;
712 assert(NumOps >= 3 &&
713 OpInfo[0].RegClass == ARM::tGPRRegClassID &&
714 OpInfo[1].RegClass == ARM::GPRRegClassID &&
715 (OpInfo[2].RegClass < 0 &&
716 !OpInfo[2].isPredicate() &&
717 !OpInfo[2].isOptionalDef())
718 && "Invalid arguments");
720 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
722 MI.addOperand(MCOperand::CreateReg(ARM::SP));
723 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
728 // tPUSH, tPOP: Pred-Imm Pred-CCR register_list
730 // where register_list = low registers + [lr] for PUSH or
731 // low registers + [pc] for POP
733 // "low registers" is specified by Inst{7-0}
734 // lr|pc is specified by Inst{8}
735 static bool DisassembleThumb1PushPop(MCInst &MI, unsigned Opcode, uint32_t insn,
736 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
738 assert((Opcode == ARM::tPUSH || Opcode == ARM::tPOP) && "Unexpected opcode");
740 unsigned &OpIdx = NumOpsAdded;
742 // Handling the two predicate operands before the reglist.
743 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
746 DEBUG(errs() << "Expected predicate operands not found.\n");
750 unsigned RegListBits = slice(insn, 8, 8) << (Opcode == ARM::tPUSH ? 14 : 15)
753 // Fill the variadic part of reglist.
754 for (unsigned i = 0; i < 16; ++i) {
755 if ((RegListBits >> i) & 1) {
756 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
765 // A6.2.5 Miscellaneous 16-bit instructions
766 // Delegate to DisassembleThumb1PushPop() for tPUSH & tPOP.
768 // tADDspi, tSUBspi: ARM::SP ARM::SP(TIED_TO) imm7
769 // t2IT: firstcond=Inst{7-4} mask=Inst{3-0}
770 // tCBNZ, tCBZ: tRd imm6*2
772 // tNOP, tSEV, tYIELD, tWFE, tWFI:
773 // no operand (except predicate pair)
774 // tSETENDBE, tSETENDLE, :
777 static bool DisassembleThumb1Misc(MCInst &MI, unsigned Opcode, uint32_t insn,
778 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
783 if (Opcode == ARM::tPUSH || Opcode == ARM::tPOP)
784 return DisassembleThumb1PushPop(MI, Opcode, insn, NumOps, NumOpsAdded, B);
786 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
788 // Predicate operands are handled elsewhere.
790 OpInfo[0].isPredicate() && OpInfo[1].isPredicate() &&
791 OpInfo[0].RegClass < 0 && OpInfo[1].RegClass == ARM::CCRRegClassID) {
795 if (Opcode == ARM::tADDspi || Opcode == ARM::tSUBspi) {
796 // Special case handling for tADDspi and tSUBspi.
797 // A8.6.8 ADD (SP plus immediate) & A8.6.215 SUB (SP minus immediate)
798 MI.addOperand(MCOperand::CreateReg(ARM::SP));
799 MI.addOperand(MCOperand::CreateReg(ARM::SP));
800 MI.addOperand(MCOperand::CreateImm(getT1Imm7(insn)));
805 if (Opcode == ARM::t2IT) {
806 // Special case handling for If-Then.
808 // Tag the (firstcond[0] bit << 4) along with mask.
811 MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 4)));
813 // firstcond[0] and mask
814 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
819 if (Opcode == ARM::tBKPT) {
820 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn))); // breakpoint value
825 // CPS has a singleton $opt operand that contains the following information:
826 // The first op would be 0b10 as enable and 0b11 as disable in regular ARM,
827 // but in Thumb it's is 0 as enable and 1 as disable. So map it to ARM's
828 // default one. The second get the AIF flags from Inst{2-0}.
829 if (Opcode == ARM::tCPS) {
830 MI.addOperand(MCOperand::CreateImm(2 + slice(insn, 4, 4)));
831 MI.addOperand(MCOperand::CreateImm(slice(insn, 2, 0)));
836 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
837 (OpInfo[1].RegClass < 0 || OpInfo[1].RegClass==ARM::tGPRRegClassID)
838 && "Expect >=2 operands");
840 // Add the destination operand.
841 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
844 if (OpInfo[1].RegClass == ARM::tGPRRegClassID) {
845 // Two register instructions.
846 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
850 assert((Opcode == ARM::tCBNZ || Opcode == ARM::tCBZ) &&"Unexpected opcode");
851 MI.addOperand(MCOperand::CreateImm(getT1Imm6(insn) * 2));
859 // A8.6.53 LDM / LDMIA
860 // A8.6.189 STM / STMIA
862 // tLDMIA_UPD/tSTMIA_UPD: tRt tRt AM4ModeImm Pred-Imm Pred-CCR register_list
863 // tLDMIA: tRt AM4ModeImm Pred-Imm Pred-CCR register_list
864 static bool DisassembleThumb1LdStMul(bool Ld, MCInst &MI, unsigned Opcode,
865 uint32_t insn, unsigned short NumOps,
866 unsigned &NumOpsAdded, BO B) {
867 assert((Opcode == ARM::tLDMIA || Opcode == ARM::tLDMIA_UPD ||
868 Opcode == ARM::tSTMIA_UPD) && "Unexpected opcode");
870 unsigned tRt = getT1tRt(insn);
873 // WB register, if necessary.
874 if (Opcode == ARM::tLDMIA_UPD || Opcode == ARM::tSTMIA_UPD) {
875 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
880 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
884 // Handling the two predicate operands before the reglist.
885 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps)) {
888 DEBUG(errs() << "Expected predicate operands not found.\n");
892 unsigned RegListBits = slice(insn, 7, 0);
894 // Fill the variadic part of reglist.
895 for (unsigned i = 0; i < 8; ++i)
896 if ((RegListBits >> i) & 1) {
897 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
905 static bool DisassembleThumb1LdMul(MCInst &MI, unsigned Opcode, uint32_t insn,
906 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
907 return DisassembleThumb1LdStMul(true, MI, Opcode, insn, NumOps, NumOpsAdded,
911 static bool DisassembleThumb1StMul(MCInst &MI, unsigned Opcode, uint32_t insn,
912 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
913 return DisassembleThumb1LdStMul(false, MI, Opcode, insn, NumOps, NumOpsAdded,
917 // A8.6.16 B Encoding T1
918 // cond = Inst{11-8} & imm8 = Inst{7-0}
919 // imm32 = SignExtend(imm8:'0', 32)
921 // tBcc: offset Pred-Imm Pred-CCR
922 // tSVC: imm8 Pred-Imm Pred-CCR
923 // tTRAP: 0 operand (early return)
924 static bool DisassembleThumb1CondBr(MCInst &MI, unsigned Opcode, uint32_t insn,
925 unsigned short NumOps, unsigned &NumOpsAdded, BO) {
927 if (Opcode == ARM::tTRAP)
930 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
931 if (!OpInfo) return false;
933 assert(NumOps == 3 && OpInfo[0].RegClass < 0 &&
934 OpInfo[1].isPredicate() && OpInfo[2].RegClass == ARM::CCRRegClassID
935 && "Exactly 3 operands expected");
937 unsigned Imm8 = getT1Imm8(insn);
938 MI.addOperand(MCOperand::CreateImm(
939 Opcode == ARM::tBcc ? SignExtend32<9>(Imm8 << 1) + 4
942 // Predicate operands by ARMBasicMCBuilder::TryPredicateAndSBitModifier().
948 // A8.6.16 B Encoding T2
949 // imm11 = Inst{10-0}
950 // imm32 = SignExtend(imm11:'0', 32)
953 static bool DisassembleThumb1Br(MCInst &MI, unsigned Opcode, uint32_t insn,
954 unsigned short NumOps, unsigned &NumOpsAdded, BO) {
956 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
957 if (!OpInfo) return false;
959 assert(NumOps == 1 && OpInfo[0].RegClass < 0 && "1 imm operand expected");
961 unsigned Imm11 = getT1Imm11(insn);
963 MI.addOperand(MCOperand::CreateImm(SignExtend32<12>(Imm11 << 1)));
971 // See A6.2 16-bit Thumb instruction encoding for instruction classes
972 // corresponding to op.
974 // Table A6-1 16-bit Thumb instruction encoding (abridged)
975 // op Instruction or instruction class
976 // ------ --------------------------------------------------------------------
977 // 00xxxx Shift (immediate), add, subtract, move, and compare on page A6-7
978 // 010000 Data-processing on page A6-8
979 // 010001 Special data instructions and branch and exchange on page A6-9
980 // 01001x Load from Literal Pool, see LDR (literal) on page A8-122
981 // 0101xx Load/store single data item on page A6-10
984 // 10100x Generate PC-relative address, see ADR on page A8-32
985 // 10101x Generate SP-relative address, see ADD (SP plus immediate) on
987 // 1011xx Miscellaneous 16-bit instructions on page A6-11
988 // 11000x Store multiple registers, see STM / STMIA / STMEA on page A8-374
989 // 11001x Load multiple registers, see LDM / LDMIA / LDMFD on page A8-110 a
990 // 1101xx Conditional branch, and Supervisor Call on page A6-13
991 // 11100x Unconditional Branch, see B on page A8-44
993 static bool DisassembleThumb1(uint16_t op, MCInst &MI, unsigned Opcode,
994 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
996 unsigned op1 = slice(op, 5, 4);
997 unsigned op2 = slice(op, 3, 2);
998 unsigned op3 = slice(op, 1, 0);
999 unsigned opA = slice(op, 5, 2);
1002 // A6.2.1 Shift (immediate), add, subtract, move, and compare
1003 return DisassembleThumb1General(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1009 // A6.2.2 Data-processing
1010 return DisassembleThumb1DP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1012 // A6.2.3 Special data instructions and branch and exchange
1013 return DisassembleThumb1Special(MI, Opcode, insn, NumOps, NumOpsAdded,
1016 // A8.6.59 LDR (literal)
1017 return DisassembleThumb1LdPC(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1021 // A6.2.4 Load/store single data item
1022 return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
1030 // A6.2.4 Load/store single data item
1031 return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
1034 // A6.2.4 Load/store single data item
1035 return DisassembleThumb1LdStSP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1039 return DisassembleThumb1AddPCi(MI, Opcode, insn, NumOps, NumOpsAdded,
1042 // A8.6.8 ADD (SP plus immediate)
1043 return DisassembleThumb1AddSPi(MI, Opcode, insn, NumOps, NumOpsAdded,
1047 // A6.2.5 Miscellaneous 16-bit instructions
1048 return DisassembleThumb1Misc(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1055 // A8.6.189 STM / STMIA / STMEA
1056 return DisassembleThumb1StMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1058 // A8.6.53 LDM / LDMIA / LDMFD
1059 return DisassembleThumb1LdMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1062 // A6.2.6 Conditional branch, and Supervisor Call
1063 return DisassembleThumb1CondBr(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1065 // Unconditional Branch, see B on page A8-44
1066 return DisassembleThumb1Br(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1068 assert(0 && "Unreachable code");
1073 assert(0 && "Unreachable code");
1080 ///////////////////////////////////////////////
1082 // Thumb2 instruction disassembly functions. //
1084 ///////////////////////////////////////////////
1086 ///////////////////////////////////////////////////////////
1088 // Note: the register naming follows the ARM convention! //
1090 ///////////////////////////////////////////////////////////
1092 static inline bool Thumb2SRSOpcode(unsigned Opcode) {
1096 case ARM::t2SRSDBW: case ARM::t2SRSDB:
1097 case ARM::t2SRSIAW: case ARM::t2SRSIA:
1102 static inline bool Thumb2RFEOpcode(unsigned Opcode) {
1106 case ARM::t2RFEDBW: case ARM::t2RFEDB:
1107 case ARM::t2RFEIAW: case ARM::t2RFEIA:
1112 // t2SRS[IA|DB]W/t2SRS[IA|DB]: mode_imm = Inst{4-0}
1113 static bool DisassembleThumb2SRS(MCInst &MI, unsigned Opcode, uint32_t insn,
1114 unsigned short NumOps, unsigned &NumOpsAdded) {
1115 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
1120 // t2RFE[IA|DB]W/t2RFE[IA|DB]: Rn
1121 static bool DisassembleThumb2RFE(MCInst &MI, unsigned Opcode, uint32_t insn,
1122 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1123 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1129 static bool DisassembleThumb2LdStMul(MCInst &MI, unsigned Opcode, uint32_t insn,
1130 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1132 if (Thumb2SRSOpcode(Opcode))
1133 return DisassembleThumb2SRS(MI, Opcode, insn, NumOps, NumOpsAdded);
1135 if (Thumb2RFEOpcode(Opcode))
1136 return DisassembleThumb2RFE(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1138 assert((Opcode == ARM::t2LDMIA || Opcode == ARM::t2LDMIA_UPD ||
1139 Opcode == ARM::t2LDMDB || Opcode == ARM::t2LDMDB_UPD ||
1140 Opcode == ARM::t2STMIA || Opcode == ARM::t2STMIA_UPD ||
1141 Opcode == ARM::t2STMDB || Opcode == ARM::t2STMDB_UPD)
1142 && "Unexpected opcode");
1143 assert(NumOps >= 4 && "Thumb2 LdStMul expects NumOps >= 4");
1147 unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
1149 // Writeback to base.
1150 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD ||
1151 Opcode == ARM::t2STMIA_UPD || Opcode == ARM::t2STMDB_UPD) {
1152 MI.addOperand(MCOperand::CreateReg(Base));
1156 MI.addOperand(MCOperand::CreateReg(Base));
1159 // Handling the two predicate operands before the reglist.
1160 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps)) {
1163 DEBUG(errs() << "Expected predicate operands not found.\n");
1167 unsigned RegListBits = insn & ((1 << 16) - 1);
1169 // Fill the variadic part of reglist.
1170 for (unsigned i = 0; i < 16; ++i)
1171 if ((RegListBits >> i) & 1) {
1172 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1181 // t2LDREXD: Rd Rs Rn
1182 // t2LDREXB, t2LDREXH: Rd Rn
1183 // t2STREX: Rs Rd Rn
1184 // t2STREXD: Rm Rd Rs Rn
1185 // t2STREXB, t2STREXH: Rm Rd Rn
1186 static bool DisassembleThumb2LdStEx(MCInst &MI, unsigned Opcode, uint32_t insn,
1187 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1189 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1190 if (!OpInfo) return false;
1192 unsigned &OpIdx = NumOpsAdded;
1197 && OpInfo[0].RegClass > 0
1198 && OpInfo[1].RegClass > 0
1199 && "Expect >=2 operands and first two as reg operands");
1201 bool isStore = (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH);
1202 bool isSW = (Opcode == ARM::t2LDREX || Opcode == ARM::t2STREX);
1203 bool isDW = (Opcode == ARM::t2LDREXD || Opcode == ARM::t2STREXD);
1205 // Add the destination operand for store.
1207 MI.addOperand(MCOperand::CreateReg(
1208 getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1209 isSW ? decodeRs(insn) : decodeRm(insn))));
1213 // Source operand for store and destination operand for load.
1214 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1218 // Thumb2 doubleword complication: with an extra source/destination operand.
1220 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
1225 // Finally add the pointer operand.
1226 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1233 // t2LDRDi8: Rd Rs Rn imm8s4 (offset mode)
1234 // t2LDRDpci: Rd Rs imm8s4 (Not decoded, prefer the generic t2LDRDi8 version)
1235 // t2STRDi8: Rd Rs Rn imm8s4 (offset mode)
1237 // Ditto for t2LDRD_PRE, t2LDRD_POST, t2STRD_PRE, t2STRD_POST, which are for
1238 // disassembly only and do not have a tied_to writeback base register operand.
1239 static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned Opcode,
1240 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1242 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1243 if (!OpInfo) return false;
1246 && OpInfo[0].RegClass > 0
1247 && OpInfo[0].RegClass == OpInfo[1].RegClass
1248 && OpInfo[2].RegClass > 0
1249 && OpInfo[3].RegClass < 0
1250 && "Expect >= 4 operands and first 3 as reg operands");
1252 // Add the <Rt> <Rt2> operands.
1253 unsigned RegClassPair = OpInfo[0].RegClass;
1254 unsigned RegClassBase = OpInfo[2].RegClass;
1256 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
1258 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
1260 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassBase,
1263 // Finally add (+/-)imm8*4, depending on the U bit.
1264 int Offset = getImm8(insn) * 4;
1265 if (getUBit(insn) == 0)
1267 MI.addOperand(MCOperand::CreateImm(Offset));
1273 // t2TBB, t2TBH: Rn Rm Pred-Imm Pred-CCR
1274 static bool DisassembleThumb2TB(MCInst &MI, unsigned Opcode,
1275 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1277 assert(NumOps >= 2 && "Expect >= 2 operands");
1279 // The generic version of TBB/TBH needs a base register.
1280 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1282 // Add the index register.
1283 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1290 static inline bool Thumb2ShiftOpcode(unsigned Opcode) {
1294 case ARM::t2MOVCClsl: case ARM::t2MOVCClsr:
1295 case ARM::t2MOVCCasr: case ARM::t2MOVCCror:
1296 case ARM::t2LSLri: case ARM::t2LSRri:
1297 case ARM::t2ASRri: case ARM::t2RORri:
1302 // A6.3.11 Data-processing (shifted register)
1304 // Two register operands (Rn=0b1111 no 1st operand reg): Rs Rm
1305 // Two register operands (Rs=0b1111 no dst operand reg): Rn Rm
1306 // Three register operands: Rs Rn Rm
1307 // Three register operands: (Rn=0b1111 Conditional Move) Rs Ro(TIED_TO) Rm
1309 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
1310 // register with shift forms: (Rm, ConstantShiftSpecifier).
1311 // Constant shift specifier: Imm = (ShOp | ShAmt<<3).
1313 // There are special instructions, like t2MOVsra_flag and t2MOVsrl_flag, which
1314 // only require two register operands: Rd, Rm in ARM Reference Manual terms, and
1315 // nothing else, because the shift amount is already specified.
1316 // Similar case holds for t2MOVrx, t2ADDrr, ..., etc.
1317 static bool DisassembleThumb2DPSoReg(MCInst &MI, unsigned Opcode, uint32_t insn,
1318 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1320 const TargetInstrDesc &TID = ARMInsts[Opcode];
1321 const TargetOperandInfo *OpInfo = TID.OpInfo;
1322 unsigned &OpIdx = NumOpsAdded;
1324 // Special case handling.
1325 if (Opcode == ARM::t2BR_JT) {
1327 && OpInfo[0].RegClass == ARM::GPRRegClassID
1328 && OpInfo[1].RegClass == ARM::GPRRegClassID
1329 && OpInfo[2].RegClass < 0
1330 && OpInfo[3].RegClass < 0
1331 && "Exactly 4 operands expect and first two as reg operands");
1332 // Only need to populate the src reg operand.
1333 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1335 MI.addOperand(MCOperand::CreateReg(0));
1336 MI.addOperand(MCOperand::CreateImm(0));
1337 MI.addOperand(MCOperand::CreateImm(0));
1345 && (OpInfo[0].RegClass == ARM::GPRRegClassID ||
1346 OpInfo[0].RegClass == ARM::rGPRRegClassID)
1347 && (OpInfo[1].RegClass == ARM::GPRRegClassID ||
1348 OpInfo[1].RegClass == ARM::rGPRRegClassID)
1349 && "Expect >= 2 operands and first two as reg operands");
1351 bool ThreeReg = (NumOps > 2 && (OpInfo[2].RegClass == ARM::GPRRegClassID ||
1352 OpInfo[2].RegClass == ARM::rGPRRegClassID));
1353 bool NoDstReg = (decodeRs(insn) == 0xF);
1355 // Build the register operands, followed by the constant shift specifier.
1357 MI.addOperand(MCOperand::CreateReg(
1358 getRegisterEnum(B, OpInfo[0].RegClass,
1359 NoDstReg ? decodeRn(insn) : decodeRs(insn))));
1364 if ((Idx = TID.getOperandConstraint(OpIdx, TOI::TIED_TO)) != -1) {
1365 // Process tied_to operand constraint.
1366 MI.addOperand(MI.getOperand(Idx));
1368 } else if (!NoDstReg) {
1369 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[1].RegClass,
1373 DEBUG(errs() << "Thumb2 encoding error: d==15 for three-reg operands.\n");
1378 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1382 if (NumOps == OpIdx)
1385 if (OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
1386 && !OpInfo[OpIdx].isOptionalDef()) {
1388 if (Thumb2ShiftOpcode(Opcode))
1389 MI.addOperand(MCOperand::CreateImm(getShiftAmtBits(insn)));
1391 // Build the constant shift specifier operand.
1392 unsigned bits2 = getShiftTypeBits(insn);
1393 unsigned imm5 = getShiftAmtBits(insn);
1394 ARM_AM::ShiftOpc ShOp = ARM_AM::no_shift;
1395 unsigned ShAmt = decodeImmShift(bits2, imm5, ShOp);
1396 MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShAmt)));
1404 // A6.3.1 Data-processing (modified immediate)
1406 // Two register operands: Rs Rn ModImm
1407 // One register operands (Rs=0b1111 no explicit dest reg): Rn ModImm
1408 // One register operands (Rn=0b1111 no explicit src reg): Rs ModImm -
1411 // ModImm = ThumbExpandImm(i:imm3:imm8)
1412 static bool DisassembleThumb2DPModImm(MCInst &MI, unsigned Opcode,
1413 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1415 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1416 unsigned &OpIdx = NumOpsAdded;
1420 unsigned RdRegClassID = OpInfo[0].RegClass;
1421 assert(NumOps >= 2 && (RdRegClassID == ARM::GPRRegClassID ||
1422 RdRegClassID == ARM::rGPRRegClassID)
1423 && "Expect >= 2 operands and first one as reg operand");
1425 unsigned RnRegClassID = OpInfo[1].RegClass;
1426 bool TwoReg = (RnRegClassID == ARM::GPRRegClassID
1427 || RnRegClassID == ARM::rGPRRegClassID);
1428 bool NoDstReg = (decodeRs(insn) == 0xF);
1430 // Build the register operands, followed by the modified immediate.
1432 MI.addOperand(MCOperand::CreateReg(
1433 getRegisterEnum(B, RdRegClassID,
1434 NoDstReg ? decodeRn(insn) : decodeRs(insn))));
1439 DEBUG(errs()<<"Thumb2 encoding error: d==15 for DPModImm 2-reg instr.\n");
1442 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
1447 // The modified immediate operand should come next.
1448 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0 &&
1449 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()
1450 && "Pure imm operand expected");
1453 // A6.3.2 Modified immediate constants in Thumb instructions
1454 unsigned imm12 = getIImm3Imm8(insn);
1455 MI.addOperand(MCOperand::CreateImm(ThumbExpandImm(imm12)));
1461 static inline bool Thumb2SaturateOpcode(unsigned Opcode) {
1463 case ARM::t2SSAT: case ARM::t2SSAT16:
1464 case ARM::t2USAT: case ARM::t2USAT16:
1471 /// DisassembleThumb2Sat - Disassemble Thumb2 saturate instructions:
1472 /// o t2SSAT, t2USAT: Rs sat_pos Rn shamt
1473 /// o t2SSAT16, t2USAT16: Rs sat_pos Rn
1474 static bool DisassembleThumb2Sat(MCInst &MI, unsigned Opcode, uint32_t insn,
1475 unsigned &NumOpsAdded, BO B) {
1476 const TargetInstrDesc &TID = ARMInsts[Opcode];
1477 NumOpsAdded = TID.getNumOperands() - 2; // ignore predicate operands
1479 // Disassemble the register def.
1480 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
1483 unsigned Pos = slice(insn, 4, 0);
1484 if (Opcode == ARM::t2SSAT || Opcode == ARM::t2SSAT16)
1486 MI.addOperand(MCOperand::CreateImm(Pos));
1488 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
1491 if (NumOpsAdded == 4) {
1492 ARM_AM::ShiftOpc Opc = (slice(insn, 21, 21) != 0 ?
1493 ARM_AM::asr : ARM_AM::lsl);
1494 // Inst{14-12:7-6} encodes the imm5 shift amount.
1495 unsigned ShAmt = slice(insn, 14, 12) << 2 | slice(insn, 7, 6);
1497 if (Opc == ARM_AM::asr)
1500 Opc = ARM_AM::no_shift;
1502 MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(Opc, ShAmt)));
1507 // A6.3.3 Data-processing (plain binary immediate)
1509 // o t2ADDri12, t2SUBri12: Rs Rn imm12
1510 // o t2LEApcrel (ADR): Rs imm12
1511 // o t2BFC (BFC): Rs Ro(TIED_TO) bf_inv_mask_imm
1512 // o t2BFI (BFI) (Currently not defined in LLVM as of Jan-07-2010)
1513 // o t2MOVi16: Rs imm16
1514 // o t2MOVTi16: Rs imm16
1515 // o t2SBFX (SBFX): Rs Rn lsb width
1516 // o t2UBFX (UBFX): Rs Rn lsb width
1517 // o t2BFI (BFI): Rs Rn lsb width
1518 static bool DisassembleThumb2DPBinImm(MCInst &MI, unsigned Opcode,
1519 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1521 const TargetInstrDesc &TID = ARMInsts[Opcode];
1522 const TargetOperandInfo *OpInfo = TID.OpInfo;
1523 unsigned &OpIdx = NumOpsAdded;
1527 unsigned RdRegClassID = OpInfo[0].RegClass;
1528 assert(NumOps >= 2 && (RdRegClassID == ARM::GPRRegClassID ||
1529 RdRegClassID == ARM::rGPRRegClassID)
1530 && "Expect >= 2 operands and first one as reg operand");
1532 unsigned RnRegClassID = OpInfo[1].RegClass;
1533 bool TwoReg = (RnRegClassID == ARM::GPRRegClassID
1534 || RnRegClassID == ARM::rGPRRegClassID);
1536 // Build the register operand(s), followed by the immediate(s).
1538 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RdRegClassID,
1543 assert(NumOps >= 3 && "Expect >= 3 operands");
1545 if ((Idx = TID.getOperandConstraint(OpIdx, TOI::TIED_TO)) != -1) {
1546 // Process tied_to operand constraint.
1547 MI.addOperand(MI.getOperand(Idx));
1549 // Add src reg operand.
1550 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
1556 if (Opcode == ARM::t2BFI) {
1557 // Add val reg operand.
1558 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
1563 assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
1564 && !OpInfo[OpIdx].isOptionalDef()
1565 && "Pure imm operand expected");
1567 // Pre-increment OpIdx.
1570 if (Opcode == ARM::t2ADDri12 || Opcode == ARM::t2SUBri12
1571 || Opcode == ARM::t2LEApcrel)
1572 MI.addOperand(MCOperand::CreateImm(getIImm3Imm8(insn)));
1573 else if (Opcode == ARM::t2MOVi16 || Opcode == ARM::t2MOVTi16) {
1574 if (!B->tryAddingSymbolicOperand(getImm16(insn), 4, MI))
1575 MI.addOperand(MCOperand::CreateImm(getImm16(insn)));
1576 } else if (Opcode == ARM::t2BFC || Opcode == ARM::t2BFI) {
1578 if (getBitfieldInvMask(insn, mask))
1579 MI.addOperand(MCOperand::CreateImm(mask));
1583 // Handle the case of: lsb width
1584 assert((Opcode == ARM::t2SBFX || Opcode == ARM::t2UBFX)
1585 && "Unexpected opcode");
1586 MI.addOperand(MCOperand::CreateImm(getLsb(insn)));
1587 MI.addOperand(MCOperand::CreateImm(getWidthMinus1(insn) + 1));
1595 // A6.3.4 Table A6-15 Miscellaneous control instructions
1599 static inline bool t2MiscCtrlInstr(uint32_t insn) {
1600 if (slice(insn, 31, 20) == 0xf3b && slice(insn, 15, 14) == 2 &&
1601 slice(insn, 12, 12) == 0)
1607 // A6.3.4 Branches and miscellaneous control
1610 // Branches: t2B, t2Bcc -> imm operand
1612 // Branches: t2TPsoft -> no operand
1614 // A8.6.23 BL, BLX (immediate)
1615 // Branches (defined in ARMInstrThumb.td): tBLr9, tBLXi_r9 -> imm operand
1620 // Miscellaneous control:
1621 // -> no operand (except pred-imm pred-ccr for CLREX, memory barrier variants)
1623 // Hint: t2NOP, t2YIELD, t2WFE, t2WFI, t2SEV
1624 // -> no operand (except pred-imm pred-ccr)
1626 // t2DBG -> imm4 = Inst{3-0}
1628 // t2MRS/t2MRSsys -> Rs
1629 // t2MSR/t2MSRsys -> Rn mask=Inst{11-8}
1630 // t2SMC -> imm4 = Inst{19-16}
1631 static bool DisassembleThumb2BrMiscCtrl(MCInst &MI, unsigned Opcode,
1632 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1637 if (Opcode == ARM::t2DMB || Opcode == ARM::t2DSB) {
1638 // Inst{3-0} encodes the memory barrier option for the variants.
1639 unsigned opt = slice(insn, 3, 0);
1641 case ARM_MB::SY: case ARM_MB::ST:
1642 case ARM_MB::ISH: case ARM_MB::ISHST:
1643 case ARM_MB::NSH: case ARM_MB::NSHST:
1644 case ARM_MB::OSH: case ARM_MB::OSHST:
1645 MI.addOperand(MCOperand::CreateImm(opt));
1653 if (t2MiscCtrlInstr(insn))
1668 // FIXME: To enable correct asm parsing and disasm of CPS we need 3 different
1669 // opcodes which match the same real instruction. This is needed since there's
1670 // no current handling of optional arguments. Fix here when a better handling
1671 // of optional arguments is implemented.
1672 if (Opcode == ARM::t2CPS3p) {
1673 MI.addOperand(MCOperand::CreateImm(slice(insn, 10, 9))); // imod
1674 MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 5))); // iflags
1675 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
1679 if (Opcode == ARM::t2CPS2p) {
1680 MI.addOperand(MCOperand::CreateImm(slice(insn, 10, 9))); // imod
1681 MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 5))); // iflags
1685 if (Opcode == ARM::t2CPS1p) {
1686 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
1691 // DBG has its option specified in Inst{3-0}.
1692 if (Opcode == ARM::t2DBG) {
1693 MI.addOperand(MCOperand::CreateImm(slice(insn, 3, 0)));
1698 // MRS and MRSsys take one GPR reg Rs.
1699 if (Opcode == ARM::t2MRS || Opcode == ARM::t2MRSsys) {
1700 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1705 // BXJ takes one GPR reg Rn.
1706 if (Opcode == ARM::t2BXJ) {
1707 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1712 // MSR take a mask, followed by one GPR reg Rn. The mask contains the R Bit in
1713 // bit 4, and the special register fields in bits 3-0.
1714 if (Opcode == ARM::t2MSR) {
1715 MI.addOperand(MCOperand::CreateImm(slice(insn, 20, 20) << 4 /* R Bit */ |
1716 slice(insn, 11, 8) /* Special Reg */));
1717 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1723 if (Opcode == ARM::t2SMC) {
1724 MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 16)));
1729 // Some instructions have predicate operands first before the immediate.
1730 if (Opcode == ARM::tBLXi_r9 || Opcode == ARM::tBLr9) {
1731 // Handling the two predicate operands before the imm operand.
1732 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
1735 DEBUG(errs() << "Expected predicate operands not found.\n");
1740 // Add the imm operand.
1745 assert(0 && "Unexpected opcode");
1748 Offset = decodeImm32_B_EncodingT4(insn);
1751 Offset = decodeImm32_B_EncodingT3(insn);
1754 Offset = decodeImm32_BL(insn);
1757 Offset = decodeImm32_BLX(insn);
1761 if (!B->tryAddingSymbolicOperand(Offset + B->getBuilderAddress() + 4, 4, MI))
1762 MI.addOperand(MCOperand::CreateImm(Offset));
1764 // This is an increment as some predicate operands may have been added first.
1770 static inline bool Thumb2PreloadOpcode(unsigned Opcode) {
1774 case ARM::t2PLDi12: case ARM::t2PLDi8:
1776 case ARM::t2PLDWi12: case ARM::t2PLDWi8:
1778 case ARM::t2PLIi12: case ARM::t2PLIi8:
1784 static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned Opcode, uint32_t insn,
1785 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1787 // Preload Data/Instruction requires either 2 or 3 operands.
1788 // t2PLDi12, t2PLDi8, t2PLDpci: Rn [+/-]imm12/imm8
1790 // t2PLDs: Rn Rm imm2=Inst{5-4}
1791 // Same pattern applies for t2PLDW* and t2PLI*.
1793 const TargetInstrDesc &TID = ARMInsts[Opcode];
1794 const TargetOperandInfo *OpInfo = TID.OpInfo;
1795 unsigned &OpIdx = NumOpsAdded;
1799 assert(NumOps >= 2 &&
1800 OpInfo[0].RegClass == ARM::GPRRegClassID &&
1801 "Expect >= 2 operands and first one as reg operand");
1803 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1807 if (OpInfo[OpIdx].RegClass == ARM::rGPRRegClassID) {
1808 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1811 assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
1812 && !OpInfo[OpIdx].isOptionalDef()
1813 && "Pure imm operand expected");
1815 if (Opcode == ARM::t2PLDi8 || Opcode == ARM::t2PLDWi8 ||
1816 Opcode == ARM::t2PLIi8) {
1817 // A8.6.117 Encoding T2: add = FALSE
1818 unsigned Imm8 = getImm8(insn);
1821 // The i12 forms. See, for example, A8.6.117 Encoding T1.
1822 // Note that currently t2PLDi12 also handles the previously named t2PLDpci
1823 // opcode, that's why we use decodeImm12(insn) which returns +/- imm12.
1824 Offset = decodeImm12(insn);
1826 MI.addOperand(MCOperand::CreateImm(Offset));
1830 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0 &&
1831 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
1832 // Fills in the shift amount for t2PLDs, t2PLDWs, t2PLIs.
1833 MI.addOperand(MCOperand::CreateImm(slice(insn, 5, 4)));
1840 // A6.3.10 Store single data item
1841 // A6.3.9 Load byte, memory hints
1842 // A6.3.8 Load halfword, memory hints
1847 // t2LDRi12: Rd Rn (+)imm12
1848 // t2LDRi8: Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
1849 // t2LDRs: Rd Rn Rm ConstantShiftSpecifier (see also
1850 // DisassembleThumb2DPSoReg)
1851 // t2LDR_POST: Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
1852 // t2LDR_PRE: Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
1854 // t2STRi12: Rd Rn (+)imm12
1855 // t2STRi8: Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
1856 // t2STRs: Rd Rn Rm ConstantShiftSpecifier (see also
1857 // DisassembleThumb2DPSoReg)
1858 // t2STR_POST: Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
1859 // t2STR_PRE: Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
1861 // Note that for indexed modes, the Rn(TIED_TO) operand needs to be populated
1862 // correctly, as LLVM AsmPrinter depends on it. For indexed stores, the first
1863 // operand is Rn; for all the other instructions, Rd is the first operand.
1865 // Delegates to DisassembleThumb2PreLoad() for preload data/instruction.
1866 // Delegates to DisassembleThumb2Ldpci() for load * literal operations.
1867 static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, unsigned Opcode,
1868 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1870 unsigned Rn = decodeRn(insn);
1872 if (Thumb2PreloadOpcode(Opcode))
1873 return DisassembleThumb2PreLoad(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1875 // See, for example, A6.3.7 Load word: Table A6-18 Load word.
1876 if (Load && Rn == 15)
1877 return DisassembleThumb2Ldpci(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1878 const TargetInstrDesc &TID = ARMInsts[Opcode];
1879 const TargetOperandInfo *OpInfo = TID.OpInfo;
1880 unsigned &OpIdx = NumOpsAdded;
1884 assert(NumOps >= 3 &&
1885 OpInfo[0].RegClass == ARM::GPRRegClassID &&
1886 OpInfo[1].RegClass == ARM::GPRRegClassID &&
1887 "Expect >= 3 operands and first two as reg operands");
1889 bool ThreeReg = (OpInfo[2].RegClass > 0);
1890 bool TIED_TO = ThreeReg && TID.getOperandConstraint(2, TOI::TIED_TO) != -1;
1891 bool Imm12 = !ThreeReg && slice(insn, 23, 23) == 1; // ARMInstrThumb2.td
1893 // Build the register operands, followed by the immediate.
1894 unsigned R0, R1, R2 = 0;
1895 unsigned Rd = decodeRd(insn);
1898 if (!Load && TIED_TO) {
1908 Imm = decodeImm8(insn);
1910 R2 = decodeRm(insn);
1911 // See, for example, A8.6.64 LDRB (register).
1912 // And ARMAsmPrinter::printT2AddrModeSoRegOperand().
1913 // LSL is the default shift opc, and LLVM does not expect it to be encoded
1914 // as part of the immediate operand.
1915 // Imm = ARM_AM::getSORegOpc(ARM_AM::lsl, slice(insn, 5, 4));
1916 Imm = slice(insn, 5, 4);
1920 Imm = getImm12(insn);
1922 Imm = decodeImm8(insn);
1925 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1928 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1933 // This could be an offset register or a TIED_TO register.
1934 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
1939 assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
1940 && !OpInfo[OpIdx].isOptionalDef()
1941 && "Pure imm operand expected");
1943 MI.addOperand(MCOperand::CreateImm(Imm));
1949 // A6.3.12 Data-processing (register)
1951 // Two register operands [rotate]: Rs Rm [rotation(= (rotate:'000'))]
1952 // Three register operands only: Rs Rn Rm
1953 // Three register operands [rotate]: Rs Rn Rm [rotation(= (rotate:'000'))]
1955 // Parallel addition and subtraction 32-bit Thumb instructions: Rs Rn Rm
1957 // Miscellaneous operations: Rs [Rn] Rm
1958 static bool DisassembleThumb2DPReg(MCInst &MI, unsigned Opcode, uint32_t insn,
1959 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1961 const TargetInstrDesc &TID = ARMInsts[Opcode];
1962 const TargetOperandInfo *OpInfo = TID.OpInfo;
1963 unsigned &OpIdx = NumOpsAdded;
1967 assert(NumOps >= 2 &&
1968 OpInfo[0].RegClass > 0 &&
1969 OpInfo[1].RegClass > 0 &&
1970 "Expect >= 2 operands and first two as reg operands");
1972 // Build the register operands, followed by the optional rotation amount.
1974 bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass > 0;
1976 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1981 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
1986 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1990 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0
1991 && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
1992 // Add the rotation amount immediate.
1993 MI.addOperand(MCOperand::CreateImm(decodeRotate(insn)));
2000 // A6.3.16 Multiply, multiply accumulate, and absolute difference
2002 // t2MLA, t2MLS, t2SMMLA, t2SMMLS: Rs Rn Rm Ra=Inst{15-12}
2003 // t2MUL, t2SMMUL: Rs Rn Rm
2004 // t2SMLA[BB|BT|TB|TT|WB|WT]: Rs Rn Rm Ra=Inst{15-12}
2005 // t2SMUL[BB|BT|TB|TT|WB|WT]: Rs Rn Rm
2007 // Dual halfword multiply: t2SMUAD[X], t2SMUSD[X], t2SMLAD[X], t2SMLSD[X]:
2008 // Rs Rn Rm Ra=Inst{15-12}
2010 // Unsigned Sum of Absolute Differences [and Accumulate]
2011 // Rs Rn Rm [Ra=Inst{15-12}]
2012 static bool DisassembleThumb2Mul(MCInst &MI, unsigned Opcode, uint32_t insn,
2013 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2015 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
2017 assert(NumOps >= 3 &&
2018 OpInfo[0].RegClass == ARM::rGPRRegClassID &&
2019 OpInfo[1].RegClass == ARM::rGPRRegClassID &&
2020 OpInfo[2].RegClass == ARM::rGPRRegClassID &&
2021 "Expect >= 3 operands and first three as reg operands");
2023 // Build the register operands.
2025 bool FourReg = NumOps > 3 && OpInfo[3].RegClass == ARM::rGPRRegClassID;
2027 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2030 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2033 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2037 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2040 NumOpsAdded = FourReg ? 4 : 3;
2045 // A6.3.17 Long multiply, long multiply accumulate, and divide
2047 // t2SMULL, t2UMULL, t2SMLAL, t2UMLAL, t2UMAAL: RdLo RdHi Rn Rm
2048 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2050 // Halfword multiple accumulate long: t2SMLAL<x><y>: RdLo RdHi Rn Rm
2051 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2053 // Dual halfword multiple: t2SMLALD[X], t2SMLSLD[X]: RdLo RdHi Rn Rm
2054 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2056 // Signed/Unsigned divide: t2SDIV, t2UDIV: Rs Rn Rm
2057 static bool DisassembleThumb2LongMul(MCInst &MI, unsigned Opcode, uint32_t insn,
2058 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2060 const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
2062 assert(NumOps >= 3 &&
2063 OpInfo[0].RegClass == ARM::rGPRRegClassID &&
2064 OpInfo[1].RegClass == ARM::rGPRRegClassID &&
2065 OpInfo[2].RegClass == ARM::rGPRRegClassID &&
2066 "Expect >= 3 operands and first three as reg operands");
2068 bool FourReg = NumOps > 3 && OpInfo[3].RegClass == ARM::rGPRRegClassID;
2070 // Build the register operands.
2073 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2076 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2079 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2082 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2093 // See A6.3 32-bit Thumb instruction encoding for instruction classes
2094 // corresponding to (op1, op2, op).
2096 // Table A6-9 32-bit Thumb instruction encoding
2097 // op1 op2 op Instruction class, see
2098 // --- ------- -- -----------------------------------------------------------
2099 // 01 00xx0xx - Load/store multiple on page A6-23
2100 // 00xx1xx - Load/store dual, load/store exclusive, table branch on
2102 // 01xxxxx - Data-processing (shifted register) on page A6-31
2103 // 1xxxxxx - Coprocessor instructions on page A6-40
2104 // 10 x0xxxxx 0 Data-processing (modified immediate) on page A6-15
2105 // x1xxxxx 0 Data-processing (plain binary immediate) on page A6-19
2106 // - 1 Branches and miscellaneous control on page A6-20
2107 // 11 000xxx0 - Store single data item on page A6-30
2108 // 001xxx0 - Advanced SIMD element or structure load/store instructions
2110 // 00xx001 - Load byte, memory hints on page A6-28
2111 // 00xx011 - Load halfword, memory hints on page A6-26
2112 // 00xx101 - Load word on page A6-25
2113 // 00xx111 - UNDEFINED
2114 // 010xxxx - Data-processing (register) on page A6-33
2115 // 0110xxx - Multiply, multiply accumulate, and absolute difference on
2117 // 0111xxx - Long multiply, long multiply accumulate, and divide on
2119 // 1xxxxxx - Coprocessor instructions on page A6-40
2121 static bool DisassembleThumb2(uint16_t op1, uint16_t op2, uint16_t op,
2122 MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps,
2123 unsigned &NumOpsAdded, BO B) {
2127 if (slice(op2, 6, 5) == 0) {
2128 if (slice(op2, 2, 2) == 0) {
2129 // Load/store multiple.
2130 return DisassembleThumb2LdStMul(MI, Opcode, insn, NumOps, NumOpsAdded,
2134 // Load/store dual, load/store exclusive, table branch, otherwise.
2135 assert(slice(op2, 2, 2) == 1 && "Thumb2 encoding error!");
2136 if ((ARM::t2LDREX <= Opcode && Opcode <= ARM::t2LDREXH) ||
2137 (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH)) {
2138 // Load/store exclusive.
2139 return DisassembleThumb2LdStEx(MI, Opcode, insn, NumOps, NumOpsAdded,
2142 if (Opcode == ARM::t2LDRDi8 ||
2143 Opcode == ARM::t2LDRD_PRE || Opcode == ARM::t2LDRD_POST ||
2144 Opcode == ARM::t2STRDi8 ||
2145 Opcode == ARM::t2STRD_PRE || Opcode == ARM::t2STRD_POST) {
2147 return DisassembleThumb2LdStDual(MI, Opcode, insn, NumOps, NumOpsAdded,
2150 if (Opcode == ARM::t2TBB || Opcode == ARM::t2TBH) {
2152 return DisassembleThumb2TB(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2154 } else if (slice(op2, 6, 5) == 1) {
2155 // Data-processing (shifted register).
2156 return DisassembleThumb2DPSoReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2159 // FIXME: A6.3.18 Coprocessor instructions
2160 // But see ThumbDisassembler::getInstruction().
2165 if (slice(op2, 5, 5) == 0)
2166 // Data-processing (modified immediate)
2167 return DisassembleThumb2DPModImm(MI, Opcode, insn, NumOps, NumOpsAdded,
2169 if (Thumb2SaturateOpcode(Opcode))
2170 return DisassembleThumb2Sat(MI, Opcode, insn, NumOpsAdded, B);
2172 // Data-processing (plain binary immediate)
2173 return DisassembleThumb2DPBinImm(MI, Opcode, insn, NumOps, NumOpsAdded,
2176 // Branches and miscellaneous control on page A6-20.
2177 return DisassembleThumb2BrMiscCtrl(MI, Opcode, insn, NumOps, NumOpsAdded,
2180 switch (slice(op2, 6, 5)) {
2182 // Load/store instructions...
2183 if (slice(op2, 0, 0) == 0) {
2184 if (slice(op2, 4, 4) == 0) {
2185 // Store single data item on page A6-30
2186 return DisassembleThumb2LdSt(false, MI,Opcode,insn,NumOps,NumOpsAdded,
2189 // FIXME: Advanced SIMD element or structure load/store instructions.
2190 // But see ThumbDisassembler::getInstruction().
2194 // Table A6-9 32-bit Thumb instruction encoding: Load byte|halfword|word
2195 return DisassembleThumb2LdSt(true, MI, Opcode, insn, NumOps,
2200 if (slice(op2, 4, 4) == 0) {
2201 // A6.3.12 Data-processing (register)
2202 return DisassembleThumb2DPReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2203 } else if (slice(op2, 3, 3) == 0) {
2204 // A6.3.16 Multiply, multiply accumulate, and absolute difference
2205 return DisassembleThumb2Mul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2207 // A6.3.17 Long multiply, long multiply accumulate, and divide
2208 return DisassembleThumb2LongMul(MI, Opcode, insn, NumOps, NumOpsAdded,
2213 // FIXME: A6.3.18 Coprocessor instructions
2214 // But see ThumbDisassembler::getInstruction().
2221 assert(0 && "Thumb2 encoding error!");
2228 static bool DisassembleThumbFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
2229 unsigned short NumOps, unsigned &NumOpsAdded, BO Builder) {
2231 uint16_t HalfWord = slice(insn, 31, 16);
2233 if (HalfWord == 0) {
2234 // A6.2 16-bit Thumb instruction encoding
2236 uint16_t op = slice(insn, 15, 10);
2237 return DisassembleThumb1(op, MI, Opcode, insn, NumOps, NumOpsAdded,
2241 unsigned bits15_11 = slice(HalfWord, 15, 11);
2243 // A6.1 Thumb instruction set encoding
2244 if (!(bits15_11 == 0x1D || bits15_11 == 0x1E || bits15_11 == 0x1F)) {
2245 assert("Bits[15:11] first halfword of Thumb2 instruction is out of range");
2249 // A6.3 32-bit Thumb instruction encoding
2251 uint16_t op1 = slice(HalfWord, 12, 11);
2252 uint16_t op2 = slice(HalfWord, 10, 4);
2253 uint16_t op = slice(insn, 15, 15);
2255 return DisassembleThumb2(op1, op2, op, MI, Opcode, insn, NumOps, NumOpsAdded,