Use BranchProbability instead of floating points in IfConverter.
[llvm/stm8.git] / lib / Target / ARM / Disassembler / ThumbDisassemblerCore.h
blob834c6f65295db561e6546b94618bb9540c118873
1 //===- ThumbDisassemblerCore.h - Thumb disassembler helpers -----*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
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 ///////////////////////////////
18 // //
19 // Utility Functions //
20 // //
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
26 [ tRt ]
27 [ tRm ] [ tRn ] [ tRd ]
28 D [ Rm ] [ Rd ]
30 [ imm3]
31 [ imm5 ]
32 i [ imm5 ]
33 [ imm7 ]
34 [ imm8 ]
35 [ imm11 ]
37 [ cond ]
40 // Extract tRt: Inst{10-8}.
41 static inline unsigned getT1tRt(uint32_t insn) {
42 return slice(insn, 10, 8);
45 // Extract tRm: Inst{8-6}.
46 static inline unsigned getT1tRm(uint32_t insn) {
47 return slice(insn, 8, 6);
50 // Extract tRn: Inst{5-3}.
51 static inline unsigned getT1tRn(uint32_t insn) {
52 return slice(insn, 5, 3);
55 // Extract tRd: Inst{2-0}.
56 static inline unsigned getT1tRd(uint32_t insn) {
57 return slice(insn, 2, 0);
60 // Extract [D:Rd]: Inst{7:2-0}.
61 static inline unsigned getT1Rd(uint32_t insn) {
62 return slice(insn, 7, 7) << 3 | slice(insn, 2, 0);
65 // Extract Rm: Inst{6-3}.
66 static inline unsigned getT1Rm(uint32_t insn) {
67 return slice(insn, 6, 3);
70 // Extract imm3: Inst{8-6}.
71 static inline unsigned getT1Imm3(uint32_t insn) {
72 return slice(insn, 8, 6);
75 // Extract imm5: Inst{10-6}.
76 static inline unsigned getT1Imm5(uint32_t insn) {
77 return slice(insn, 10, 6);
80 // Extract i:imm5: Inst{9:7-3}.
81 static inline unsigned getT1Imm6(uint32_t insn) {
82 return slice(insn, 9, 9) << 5 | slice(insn, 7, 3);
85 // Extract imm7: Inst{6-0}.
86 static inline unsigned getT1Imm7(uint32_t insn) {
87 return slice(insn, 6, 0);
90 // Extract imm8: Inst{7-0}.
91 static inline unsigned getT1Imm8(uint32_t insn) {
92 return slice(insn, 7, 0);
95 // Extract imm11: Inst{10-0}.
96 static inline unsigned getT1Imm11(uint32_t insn) {
97 return slice(insn, 10, 0);
100 // Extract cond: Inst{11-8}.
101 static inline unsigned getT1Cond(uint32_t insn) {
102 return slice(insn, 11, 8);
105 static inline bool IsGPR(unsigned RegClass) {
106 return RegClass == ARM::GPRRegClassID || RegClass == ARM::rGPRRegClassID;
109 // Utilities for 32-bit Thumb instructions.
111 static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; }
113 // Extract imm4: Inst{19-16}.
114 static inline unsigned getImm4(uint32_t insn) {
115 return slice(insn, 19, 16);
118 // Extract imm3: Inst{14-12}.
119 static inline unsigned getImm3(uint32_t insn) {
120 return slice(insn, 14, 12);
123 // Extract imm8: Inst{7-0}.
124 static inline unsigned getImm8(uint32_t insn) {
125 return slice(insn, 7, 0);
128 // A8.6.61 LDRB (immediate, Thumb) and friends
129 // +/-: Inst{9}
130 // imm8: Inst{7-0}
131 static inline int decodeImm8(uint32_t insn) {
132 int Offset = getImm8(insn);
133 return slice(insn, 9, 9) ? Offset : -Offset;
136 // Extract imm12: Inst{11-0}.
137 static inline unsigned getImm12(uint32_t insn) {
138 return slice(insn, 11, 0);
141 // A8.6.63 LDRB (literal) and friends
142 // +/-: Inst{23}
143 // imm12: Inst{11-0}
144 static inline int decodeImm12(uint32_t insn) {
145 int Offset = getImm12(insn);
146 return slice(insn, 23, 23) ? Offset : -Offset;
149 // Extract imm2: Inst{7-6}.
150 static inline unsigned getImm2(uint32_t insn) {
151 return slice(insn, 7, 6);
154 // For BFI, BFC, t2SBFX, and t2UBFX.
155 // Extract lsb: Inst{14-12:7-6}.
156 static inline unsigned getLsb(uint32_t insn) {
157 return getImm3(insn) << 2 | getImm2(insn);
160 // For BFI and BFC.
161 // Extract msb: Inst{4-0}.
162 static inline unsigned getMsb(uint32_t insn) {
163 return slice(insn, 4, 0);
166 // For t2SBFX and t2UBFX.
167 // Extract widthminus1: Inst{4-0}.
168 static inline unsigned getWidthMinus1(uint32_t insn) {
169 return slice(insn, 4, 0);
172 // For t2ADDri12 and t2SUBri12.
173 // imm12 = i:imm3:imm8;
174 static inline unsigned getIImm3Imm8(uint32_t insn) {
175 return slice(insn, 26, 26) << 11 | getImm3(insn) << 8 | getImm8(insn);
178 // For t2MOVi16 and t2MOVTi16.
179 // imm16 = imm4:i:imm3:imm8;
180 static inline unsigned getImm16(uint32_t insn) {
181 return getImm4(insn) << 12 | slice(insn, 26, 26) << 11 |
182 getImm3(insn) << 8 | getImm8(insn);
185 // Inst{5-4} encodes the shift type.
186 static inline unsigned getShiftTypeBits(uint32_t insn) {
187 return slice(insn, 5, 4);
190 // Inst{14-12}:Inst{7-6} encodes the imm5 shift amount.
191 static inline unsigned getShiftAmtBits(uint32_t insn) {
192 return getImm3(insn) << 2 | getImm2(insn);
195 // A8.6.17 BFC
196 // Encoding T1 ARMv6T2, ARMv7
197 // LLVM-specific encoding for #<lsb> and #<width>
198 static inline bool getBitfieldInvMask(uint32_t insn, uint32_t &mask) {
199 uint32_t lsb = getImm3(insn) << 2 | getImm2(insn);
200 uint32_t msb = getMsb(insn);
201 uint32_t Val = 0;
202 if (msb < lsb) {
203 DEBUG(errs() << "Encoding error: msb < lsb\n");
204 return false;
206 for (uint32_t i = lsb; i <= msb; ++i)
207 Val |= (1 << i);
208 mask = ~Val;
209 return true;
212 // A8.4 Shifts applied to a register
213 // A8.4.1 Constant shifts
214 // A8.4.3 Pseudocode details of instruction-specified shifts and rotates
216 // decodeImmShift() returns the shift amount and the the shift opcode.
217 // Note that, as of Jan-06-2010, LLVM does not support rrx shifted operands yet.
218 static inline unsigned decodeImmShift(unsigned bits2, unsigned imm5,
219 ARM_AM::ShiftOpc &ShOp) {
221 assert(imm5 < 32 && "Invalid imm5 argument");
222 switch (bits2) {
223 default: assert(0 && "No such value");
224 case 0:
225 ShOp = (imm5 == 0 ? ARM_AM::no_shift : ARM_AM::lsl);
226 return imm5;
227 case 1:
228 ShOp = ARM_AM::lsr;
229 return (imm5 == 0 ? 32 : imm5);
230 case 2:
231 ShOp = ARM_AM::asr;
232 return (imm5 == 0 ? 32 : imm5);
233 case 3:
234 ShOp = (imm5 == 0 ? ARM_AM::rrx : ARM_AM::ror);
235 return (imm5 == 0 ? 1 : imm5);
239 // A6.3.2 Modified immediate constants in Thumb instructions
241 // ThumbExpandImm() returns the modified immediate constant given an imm12 for
242 // Thumb data-processing instructions with modified immediate.
243 // See also A6.3.1 Data-processing (modified immediate).
244 static inline unsigned ThumbExpandImm(unsigned imm12) {
245 assert(imm12 <= 0xFFF && "Invalid imm12 argument");
247 // If the leading two bits is 0b00, the modified immediate constant is
248 // obtained by splatting the low 8 bits into the first byte, every other byte,
249 // or every byte of a 32-bit value.
251 // Otherwise, a rotate right of '1':imm12<6:0> by the amount imm12<11:7> is
252 // performed.
254 if (slice(imm12, 11, 10) == 0) {
255 unsigned short control = slice(imm12, 9, 8);
256 unsigned imm8 = slice(imm12, 7, 0);
257 switch (control) {
258 default:
259 assert(0 && "No such value");
260 return 0;
261 case 0:
262 return imm8;
263 case 1:
264 return imm8 << 16 | imm8;
265 case 2:
266 return imm8 << 24 | imm8 << 8;
267 case 3:
268 return imm8 << 24 | imm8 << 16 | imm8 << 8 | imm8;
270 } else {
271 // A rotate is required.
272 unsigned Val = 1 << 7 | slice(imm12, 6, 0);
273 unsigned Amt = slice(imm12, 11, 7);
274 return ARM_AM::rotr32(Val, Amt);
278 static inline int decodeImm32_B_EncodingT3(uint32_t insn) {
279 bool S = slice(insn, 26, 26);
280 bool J1 = slice(insn, 13, 13);
281 bool J2 = slice(insn, 11, 11);
282 unsigned Imm21 = slice(insn, 21, 16) << 12 | slice(insn, 10, 0) << 1;
283 if (S) Imm21 |= 1 << 20;
284 if (J2) Imm21 |= 1 << 19;
285 if (J1) Imm21 |= 1 << 18;
287 return SignExtend32<21>(Imm21);
290 static inline int decodeImm32_B_EncodingT4(uint32_t insn) {
291 unsigned S = slice(insn, 26, 26);
292 bool I1 = slice(insn, 13, 13) == S;
293 bool I2 = slice(insn, 11, 11) == S;
294 unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 0) << 1;
295 if (S) Imm25 |= 1 << 24;
296 if (I1) Imm25 |= 1 << 23;
297 if (I2) Imm25 |= 1 << 22;
299 return SignExtend32<25>(Imm25);
302 static inline int decodeImm32_BL(uint32_t insn) {
303 unsigned S = slice(insn, 26, 26);
304 bool I1 = slice(insn, 13, 13) == S;
305 bool I2 = slice(insn, 11, 11) == S;
306 unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 0) << 1;
307 if (S) Imm25 |= 1 << 24;
308 if (I1) Imm25 |= 1 << 23;
309 if (I2) Imm25 |= 1 << 22;
311 return SignExtend32<25>(Imm25);
314 static inline int decodeImm32_BLX(uint32_t insn) {
315 unsigned S = slice(insn, 26, 26);
316 bool I1 = slice(insn, 13, 13) == S;
317 bool I2 = slice(insn, 11, 11) == S;
318 unsigned Imm25 = slice(insn, 25, 16) << 12 | slice(insn, 10, 1) << 2;
319 if (S) Imm25 |= 1 << 24;
320 if (I1) Imm25 |= 1 << 23;
321 if (I2) Imm25 |= 1 << 22;
323 return SignExtend32<25>(Imm25);
326 // See, for example, A8.6.221 SXTAB16.
327 static inline unsigned decodeRotate(uint32_t insn) {
328 unsigned rotate = slice(insn, 5, 4);
329 return rotate << 3;
332 ///////////////////////////////////////////////
333 // //
334 // Thumb1 instruction disassembly functions. //
335 // //
336 ///////////////////////////////////////////////
338 // See "Utilities for 16-bit Thumb instructions" for register naming convention.
340 // A6.2.1 Shift (immediate), add, subtract, move, and compare
342 // shift immediate: tRd CPSR tRn imm5
343 // add/sub register: tRd CPSR tRn tRm
344 // add/sub 3-bit immediate: tRd CPSR tRn imm3
345 // add/sub 8-bit immediate: tRt CPSR tRt(TIED_TO) imm8
346 // mov/cmp immediate: tRt [CPSR] imm8 (CPSR present for mov)
348 // Special case:
349 // tMOVSr: tRd tRn
350 static bool DisassembleThumb1General(MCInst &MI, unsigned Opcode, uint32_t insn,
351 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
353 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
354 unsigned &OpIdx = NumOpsAdded;
356 OpIdx = 0;
358 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID
359 && "Invalid arguments");
361 bool Imm3 = (Opcode == ARM::tADDi3 || Opcode == ARM::tSUBi3);
363 // Use Rt implies use imm8.
364 bool UseRt = (Opcode == ARM::tADDi8 || Opcode == ARM::tSUBi8 ||
365 Opcode == ARM::tMOVi8 || Opcode == ARM::tCMPi8);
367 // Add the destination operand.
368 MI.addOperand(MCOperand::CreateReg(
369 getRegisterEnum(B, ARM::tGPRRegClassID,
370 UseRt ? getT1tRt(insn) : getT1tRd(insn))));
371 ++OpIdx;
373 // Check whether the next operand to be added is a CCR Register.
374 if (OpInfo[OpIdx].RegClass == ARM::CCRRegClassID) {
375 assert(OpInfo[OpIdx].isOptionalDef() && "Optional def operand expected");
376 MI.addOperand(MCOperand::CreateReg(B->InITBlock() ? 0 : ARM::CPSR));
377 ++OpIdx;
380 // Check whether the next operand to be added is a Thumb1 Register.
381 assert(OpIdx < NumOps && "More operands expected");
382 if (OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
383 // For UseRt, the reg operand is tied to the first reg operand.
384 MI.addOperand(MCOperand::CreateReg(
385 getRegisterEnum(B, ARM::tGPRRegClassID,
386 UseRt ? getT1tRt(insn) : getT1tRn(insn))));
387 ++OpIdx;
390 // Special case for tMOVSr.
391 if (OpIdx == NumOps)
392 return true;
394 // The next available operand is either a reg operand or an imm operand.
395 if (OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
396 // Three register operand instructions.
397 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
398 getT1tRm(insn))));
399 } else {
400 assert(OpInfo[OpIdx].RegClass < 0 &&
401 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()
402 && "Pure imm operand expected");
403 unsigned Imm = 0;
404 if (UseRt)
405 Imm = getT1Imm8(insn);
406 else if (Imm3)
407 Imm = getT1Imm3(insn);
408 else {
409 Imm = getT1Imm5(insn);
410 ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 12, 11));
411 getImmShiftSE(ShOp, Imm);
413 MI.addOperand(MCOperand::CreateImm(Imm));
415 ++OpIdx;
417 return true;
420 // A6.2.2 Data-processing
422 // tCMPr, tTST, tCMN: tRd tRn
423 // tMVN, tRSB: tRd CPSR tRn
424 // Others: tRd CPSR tRd(TIED_TO) tRn
425 static bool DisassembleThumb1DP(MCInst &MI, unsigned Opcode, uint32_t insn,
426 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
428 const MCInstrDesc &MCID = ARMInsts[Opcode];
429 const MCOperandInfo *OpInfo = MCID.OpInfo;
430 unsigned &OpIdx = NumOpsAdded;
432 OpIdx = 0;
434 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
435 (OpInfo[1].RegClass == ARM::CCRRegClassID
436 || OpInfo[1].RegClass == ARM::tGPRRegClassID)
437 && "Invalid arguments");
439 // Add the destination operand.
440 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
441 getT1tRd(insn))));
442 ++OpIdx;
444 // Check whether the next operand to be added is a CCR Register.
445 if (OpInfo[OpIdx].RegClass == ARM::CCRRegClassID) {
446 assert(OpInfo[OpIdx].isOptionalDef() && "Optional def operand expected");
447 MI.addOperand(MCOperand::CreateReg(B->InITBlock() ? 0 : ARM::CPSR));
448 ++OpIdx;
451 // We have either { tRd(TIED_TO), tRn } or { tRn } remaining.
452 // Process the TIED_TO operand first.
454 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
455 && "Thumb reg operand expected");
456 int Idx;
457 if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
458 // The reg operand is tied to the first reg operand.
459 MI.addOperand(MI.getOperand(Idx));
460 ++OpIdx;
463 // Process possible next reg operand.
464 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
465 // Add tRn operand.
466 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
467 getT1tRn(insn))));
468 ++OpIdx;
471 return true;
474 // A6.2.3 Special data instructions and branch and exchange
476 // tADDhirr: Rd Rd(TIED_TO) Rm
477 // tCMPhir: Rd Rm
478 // tMOVr, tMOVgpr2gpr, tMOVgpr2tgpr, tMOVtgpr2gpr: Rd|tRd Rm|tRn
479 // tBX: Rm
480 // tBX_RET: 0 operand
481 // tBX_RET_vararg: Rm
482 // tBLXr_r9: Rm
483 // tBRIND: Rm
484 static bool DisassembleThumb1Special(MCInst &MI, unsigned Opcode, uint32_t insn,
485 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
487 // tBX_RET has 0 operand.
488 if (NumOps == 0)
489 return true;
491 // BX/BLX/tBRIND (indirect branch, i.e, mov pc, Rm) has 1 reg operand: Rm.
492 if (Opcode==ARM::tBLXr_r9 || Opcode==ARM::tBX || Opcode==ARM::tBRIND) {
493 if (Opcode == ARM::tBLXr_r9) {
494 // Handling the two predicate operands before the reg operand.
495 if (!B->DoPredicateOperands(MI, Opcode, insn, NumOps))
496 return false;
497 NumOpsAdded += 2;
500 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
501 getT1Rm(insn))));
502 NumOpsAdded += 1;
504 if (Opcode == ARM::tBX) {
505 // Handling the two predicate operands after the reg operand.
506 if (!B->DoPredicateOperands(MI, Opcode, insn, NumOps))
507 return false;
508 NumOpsAdded += 2;
511 return true;
514 const MCInstrDesc &MCID = ARMInsts[Opcode];
515 const MCOperandInfo *OpInfo = MCID.OpInfo;
516 unsigned &OpIdx = NumOpsAdded;
518 OpIdx = 0;
520 // Add the destination operand.
521 unsigned RegClass = OpInfo[OpIdx].RegClass;
522 MI.addOperand(MCOperand::CreateReg(
523 getRegisterEnum(B, RegClass,
524 IsGPR(RegClass) ? getT1Rd(insn)
525 : getT1tRd(insn))));
526 ++OpIdx;
528 // We have either { Rd(TIED_TO), Rm } or { Rm|tRn } remaining.
529 // Process the TIED_TO operand first.
531 assert(OpIdx < NumOps && "More operands expected");
532 int Idx;
533 if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
534 // The reg operand is tied to the first reg operand.
535 MI.addOperand(MI.getOperand(Idx));
536 ++OpIdx;
539 // The next reg operand is either Rm or tRn.
540 assert(OpIdx < NumOps && "More operands expected");
541 RegClass = OpInfo[OpIdx].RegClass;
542 MI.addOperand(MCOperand::CreateReg(
543 getRegisterEnum(B, RegClass,
544 IsGPR(RegClass) ? getT1Rm(insn)
545 : getT1tRn(insn))));
546 ++OpIdx;
548 return true;
551 // A8.6.59 LDR (literal)
553 // tLDRpci: tRt imm8*4
554 static bool DisassembleThumb1LdPC(MCInst &MI, unsigned Opcode, uint32_t insn,
555 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
557 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
558 if (!OpInfo) return false;
560 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
561 (OpInfo[1].RegClass < 0 &&
562 !OpInfo[1].isPredicate() &&
563 !OpInfo[1].isOptionalDef())
564 && "Invalid arguments");
566 // Add the destination operand.
567 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
568 getT1tRt(insn))));
570 // And the (imm8 << 2) operand.
571 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn) << 2));
573 NumOpsAdded = 2;
575 return true;
578 // Thumb specific addressing modes (see ARMInstrThumb.td):
580 // t_addrmode_rr := reg + reg
582 // t_addrmode_s4 := reg + reg
583 // reg + imm5 * 4
585 // t_addrmode_s2 := reg + reg
586 // reg + imm5 * 2
588 // t_addrmode_s1 := reg + reg
589 // reg + imm5
591 // t_addrmode_sp := sp + imm8 * 4
594 // A8.6.63 LDRB (literal)
595 // A8.6.79 LDRSB (literal)
596 // A8.6.75 LDRH (literal)
597 // A8.6.83 LDRSH (literal)
598 // A8.6.59 LDR (literal)
600 // These instrs calculate an address from the PC value and an immediate offset.
601 // Rd Rn=PC (+/-)imm12 (+ if Inst{23} == 0b1)
602 static bool DisassembleThumb2Ldpci(MCInst &MI, unsigned Opcode,
603 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
605 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
606 if (!OpInfo) return false;
608 assert(NumOps >= 2 &&
609 OpInfo[0].RegClass == ARM::GPRRegClassID &&
610 OpInfo[1].RegClass < 0 &&
611 "Expect >= 2 operands, first as reg, and second as imm operand");
613 // Build the register operand, followed by the (+/-)imm12 immediate.
615 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
616 decodeRd(insn))));
618 MI.addOperand(MCOperand::CreateImm(decodeImm12(insn)));
620 NumOpsAdded = 2;
622 return true;
626 // A6.2.4 Load/store single data item
628 // Load/Store Register (reg|imm): tRd tRn imm5|tRm
629 // Load Register Signed Byte|Halfword: tRd tRn tRm
630 static bool DisassembleThumb1LdSt(unsigned opA, MCInst &MI, unsigned Opcode,
631 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
633 const MCInstrDesc &MCID = ARMInsts[Opcode];
634 const MCOperandInfo *OpInfo = MCID.OpInfo;
635 unsigned &OpIdx = NumOpsAdded;
637 assert(NumOps >= 2
638 && OpInfo[0].RegClass == ARM::tGPRRegClassID
639 && OpInfo[1].RegClass == ARM::tGPRRegClassID
640 && "Expect >= 2 operands and first two as thumb reg operands");
642 // Add the destination reg and the base reg.
643 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
644 getT1tRd(insn))));
645 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
646 getT1tRn(insn))));
647 OpIdx = 2;
649 // We have either { imm5 } or { tRm } remaining.
650 // Note that STR/LDR (register) should skip the imm5 offset operand for
651 // t_addrmode_s[1|2|4].
653 assert(OpIdx < NumOps && "More operands expected");
655 if (OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate() &&
656 !OpInfo[OpIdx].isOptionalDef()) {
657 // Table A6-5 16-bit Thumb Load/store instructions
658 // opA = 0b0101 for STR/LDR (register) and friends.
659 // Otherwise, we have STR/LDR (immediate) and friends.
660 assert(opA != 5 && "Immediate operand expected for this opcode");
661 MI.addOperand(MCOperand::CreateImm(getT1Imm5(insn)));
662 ++OpIdx;
663 } else {
664 // The next reg operand is tRm, the offset.
665 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
666 && "Thumb reg operand expected");
667 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
668 getT1tRm(insn))));
669 ++OpIdx;
671 return true;
674 // A6.2.4 Load/store single data item
676 // Load/Store Register SP relative: tRt ARM::SP imm8
677 static bool DisassembleThumb1LdStSP(MCInst &MI, unsigned Opcode, uint32_t insn,
678 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
680 assert((Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi)
681 && "Unexpected opcode");
683 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
684 if (!OpInfo) return false;
686 assert(NumOps >= 3 &&
687 OpInfo[0].RegClass == ARM::tGPRRegClassID &&
688 OpInfo[1].RegClass == ARM::GPRRegClassID &&
689 (OpInfo[2].RegClass < 0 &&
690 !OpInfo[2].isPredicate() &&
691 !OpInfo[2].isOptionalDef())
692 && "Invalid arguments");
694 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
695 getT1tRt(insn))));
696 MI.addOperand(MCOperand::CreateReg(ARM::SP));
697 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
698 NumOpsAdded = 3;
699 return true;
702 // Table A6-1 16-bit Thumb instruction encoding
703 // A8.6.10 ADR
705 // tADDrPCi: tRt imm8
706 static bool DisassembleThumb1AddPCi(MCInst &MI, unsigned Opcode, uint32_t insn,
707 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
709 assert(Opcode == ARM::tADDrPCi && "Unexpected opcode");
711 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
712 if (!OpInfo) return false;
714 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
715 (OpInfo[1].RegClass < 0 &&
716 !OpInfo[1].isPredicate() &&
717 !OpInfo[1].isOptionalDef())
718 && "Invalid arguments");
720 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
721 getT1tRt(insn))));
722 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
723 NumOpsAdded = 2;
724 return true;
727 // Table A6-1 16-bit Thumb instruction encoding
728 // A8.6.8 ADD (SP plus immediate)
730 // tADDrSPi: tRt ARM::SP imm8
731 static bool DisassembleThumb1AddSPi(MCInst &MI, unsigned Opcode, uint32_t insn,
732 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
734 assert(Opcode == ARM::tADDrSPi && "Unexpected opcode");
736 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
737 if (!OpInfo) return false;
739 assert(NumOps >= 3 &&
740 OpInfo[0].RegClass == ARM::tGPRRegClassID &&
741 OpInfo[1].RegClass == ARM::GPRRegClassID &&
742 (OpInfo[2].RegClass < 0 &&
743 !OpInfo[2].isPredicate() &&
744 !OpInfo[2].isOptionalDef())
745 && "Invalid arguments");
747 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
748 getT1tRt(insn))));
749 MI.addOperand(MCOperand::CreateReg(ARM::SP));
750 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
751 NumOpsAdded = 3;
752 return true;
755 // tPUSH, tPOP: Pred-Imm Pred-CCR register_list
757 // where register_list = low registers + [lr] for PUSH or
758 // low registers + [pc] for POP
760 // "low registers" is specified by Inst{7-0}
761 // lr|pc is specified by Inst{8}
762 static bool DisassembleThumb1PushPop(MCInst &MI, unsigned Opcode, uint32_t insn,
763 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
765 assert((Opcode == ARM::tPUSH || Opcode == ARM::tPOP) && "Unexpected opcode");
767 unsigned &OpIdx = NumOpsAdded;
769 // Handling the two predicate operands before the reglist.
770 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
771 OpIdx += 2;
772 else {
773 DEBUG(errs() << "Expected predicate operands not found.\n");
774 return false;
777 unsigned RegListBits = slice(insn, 8, 8) << (Opcode == ARM::tPUSH ? 14 : 15)
778 | slice(insn, 7, 0);
780 // Fill the variadic part of reglist.
781 for (unsigned i = 0; i < 16; ++i) {
782 if ((RegListBits >> i) & 1) {
783 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
784 i)));
785 ++OpIdx;
789 return true;
792 // A6.2.5 Miscellaneous 16-bit instructions
793 // Delegate to DisassembleThumb1PushPop() for tPUSH & tPOP.
795 // tADDspi, tSUBspi: ARM::SP ARM::SP(TIED_TO) imm7
796 // t2IT: firstcond=Inst{7-4} mask=Inst{3-0}
797 // tCBNZ, tCBZ: tRd imm6*2
798 // tBKPT: imm8
799 // tNOP, tSEV, tYIELD, tWFE, tWFI:
800 // no operand (except predicate pair)
801 // tSETENDBE, tSETENDLE, :
802 // no operand
803 // Others: tRd tRn
804 static bool DisassembleThumb1Misc(MCInst &MI, unsigned Opcode, uint32_t insn,
805 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
807 if (NumOps == 0)
808 return true;
810 if (Opcode == ARM::tPUSH || Opcode == ARM::tPOP)
811 return DisassembleThumb1PushPop(MI, Opcode, insn, NumOps, NumOpsAdded, B);
813 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
815 // Predicate operands are handled elsewhere.
816 if (NumOps == 2 &&
817 OpInfo[0].isPredicate() && OpInfo[1].isPredicate() &&
818 OpInfo[0].RegClass < 0 && OpInfo[1].RegClass == ARM::CCRRegClassID) {
819 return true;
822 if (Opcode == ARM::tADDspi || Opcode == ARM::tSUBspi) {
823 // Special case handling for tADDspi and tSUBspi.
824 // A8.6.8 ADD (SP plus immediate) & A8.6.215 SUB (SP minus immediate)
825 MI.addOperand(MCOperand::CreateReg(ARM::SP));
826 MI.addOperand(MCOperand::CreateReg(ARM::SP));
827 MI.addOperand(MCOperand::CreateImm(getT1Imm7(insn)));
828 NumOpsAdded = 3;
829 return true;
832 if (Opcode == ARM::t2IT) {
833 // Special case handling for If-Then.
834 // A8.6.50 IT
835 // Tag the (firstcond[0] bit << 4) along with mask.
837 // firstcond
838 MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 4)));
840 // firstcond[0] and mask
841 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
842 NumOpsAdded = 2;
843 return true;
846 if (Opcode == ARM::tBKPT) {
847 MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn))); // breakpoint value
848 NumOpsAdded = 1;
849 return true;
852 // CPS has a singleton $opt operand that contains the following information:
853 // The first op would be 0b10 as enable and 0b11 as disable in regular ARM,
854 // but in Thumb it's is 0 as enable and 1 as disable. So map it to ARM's
855 // default one. The second get the AIF flags from Inst{2-0}.
856 if (Opcode == ARM::tCPS) {
857 MI.addOperand(MCOperand::CreateImm(2 + slice(insn, 4, 4)));
858 MI.addOperand(MCOperand::CreateImm(slice(insn, 2, 0)));
859 NumOpsAdded = 2;
860 return true;
863 assert(NumOps >= 2 && OpInfo[0].RegClass == ARM::tGPRRegClassID &&
864 (OpInfo[1].RegClass < 0 || OpInfo[1].RegClass==ARM::tGPRRegClassID)
865 && "Expect >=2 operands");
867 // Add the destination operand.
868 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
869 getT1tRd(insn))));
871 if (OpInfo[1].RegClass == ARM::tGPRRegClassID) {
872 // Two register instructions.
873 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
874 getT1tRn(insn))));
875 } else {
876 // CBNZ, CBZ
877 assert((Opcode == ARM::tCBNZ || Opcode == ARM::tCBZ) &&"Unexpected opcode");
878 MI.addOperand(MCOperand::CreateImm(getT1Imm6(insn) * 2));
881 NumOpsAdded = 2;
883 return true;
886 // A8.6.53 LDM / LDMIA
887 // A8.6.189 STM / STMIA
889 // tLDMIA_UPD/tSTMIA_UPD: tRt tRt AM4ModeImm Pred-Imm Pred-CCR register_list
890 // tLDMIA: tRt AM4ModeImm Pred-Imm Pred-CCR register_list
891 static bool DisassembleThumb1LdStMul(bool Ld, MCInst &MI, unsigned Opcode,
892 uint32_t insn, unsigned short NumOps,
893 unsigned &NumOpsAdded, BO B) {
894 assert((Opcode == ARM::tLDMIA || Opcode == ARM::tLDMIA_UPD ||
895 Opcode == ARM::tSTMIA_UPD) && "Unexpected opcode");
897 unsigned tRt = getT1tRt(insn);
898 NumOpsAdded = 0;
900 // WB register, if necessary.
901 if (Opcode == ARM::tLDMIA_UPD || Opcode == ARM::tSTMIA_UPD) {
902 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
903 tRt)));
904 ++NumOpsAdded;
907 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
908 tRt)));
909 ++NumOpsAdded;
911 // Handling the two predicate operands before the reglist.
912 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps)) {
913 NumOpsAdded += 2;
914 } else {
915 DEBUG(errs() << "Expected predicate operands not found.\n");
916 return false;
919 unsigned RegListBits = slice(insn, 7, 0);
920 if (BitCount(RegListBits) < 1) {
921 DEBUG(errs() << "if BitCount(registers) < 1 then UNPREDICTABLE\n");
922 return false;
925 // Fill the variadic part of reglist.
926 for (unsigned i = 0; i < 8; ++i)
927 if ((RegListBits >> i) & 1) {
928 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
929 i)));
930 ++NumOpsAdded;
933 return true;
936 static bool DisassembleThumb1LdMul(MCInst &MI, unsigned Opcode, uint32_t insn,
937 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
938 return DisassembleThumb1LdStMul(true, MI, Opcode, insn, NumOps, NumOpsAdded,
942 static bool DisassembleThumb1StMul(MCInst &MI, unsigned Opcode, uint32_t insn,
943 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
944 return DisassembleThumb1LdStMul(false, MI, Opcode, insn, NumOps, NumOpsAdded,
948 // A8.6.16 B Encoding T1
949 // cond = Inst{11-8} & imm8 = Inst{7-0}
950 // imm32 = SignExtend(imm8:'0', 32)
952 // tBcc: offset Pred-Imm Pred-CCR
953 // tSVC: imm8 Pred-Imm Pred-CCR
954 // tTRAP: 0 operand (early return)
955 static bool DisassembleThumb1CondBr(MCInst &MI, unsigned Opcode, uint32_t insn,
956 unsigned short NumOps, unsigned &NumOpsAdded, BO) {
958 if (Opcode == ARM::tTRAP)
959 return true;
961 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
962 if (!OpInfo) return false;
964 assert(NumOps == 3 && OpInfo[0].RegClass < 0 &&
965 OpInfo[1].isPredicate() && OpInfo[2].RegClass == ARM::CCRRegClassID
966 && "Exactly 3 operands expected");
968 unsigned Imm8 = getT1Imm8(insn);
969 MI.addOperand(MCOperand::CreateImm(
970 Opcode == ARM::tBcc ? SignExtend32<9>(Imm8 << 1)
971 : (int)Imm8));
973 // Predicate operands by ARMBasicMCBuilder::TryPredicateAndSBitModifier().
974 // But note that for tBcc, if cond = '1110' then UNDEFINED.
975 if (Opcode == ARM::tBcc && slice(insn, 11, 8) == 14) {
976 DEBUG(errs() << "if cond = '1110' then UNDEFINED\n");
977 return false;
979 NumOpsAdded = 1;
981 return true;
984 // A8.6.16 B Encoding T2
985 // imm11 = Inst{10-0}
986 // imm32 = SignExtend(imm11:'0', 32)
988 // tB: offset
989 static bool DisassembleThumb1Br(MCInst &MI, unsigned Opcode, uint32_t insn,
990 unsigned short NumOps, unsigned &NumOpsAdded, BO) {
992 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
993 if (!OpInfo) return false;
995 assert(NumOps == 1 && OpInfo[0].RegClass < 0 && "1 imm operand expected");
997 unsigned Imm11 = getT1Imm11(insn);
999 MI.addOperand(MCOperand::CreateImm(SignExtend32<12>(Imm11 << 1)));
1001 NumOpsAdded = 1;
1003 return true;
1007 // See A6.2 16-bit Thumb instruction encoding for instruction classes
1008 // corresponding to op.
1010 // Table A6-1 16-bit Thumb instruction encoding (abridged)
1011 // op Instruction or instruction class
1012 // ------ --------------------------------------------------------------------
1013 // 00xxxx Shift (immediate), add, subtract, move, and compare on page A6-7
1014 // 010000 Data-processing on page A6-8
1015 // 010001 Special data instructions and branch and exchange on page A6-9
1016 // 01001x Load from Literal Pool, see LDR (literal) on page A8-122
1017 // 0101xx Load/store single data item on page A6-10
1018 // 011xxx
1019 // 100xxx
1020 // 10100x Generate PC-relative address, see ADR on page A8-32
1021 // 10101x Generate SP-relative address, see ADD (SP plus immediate) on
1022 // page A8-28
1023 // 1011xx Miscellaneous 16-bit instructions on page A6-11
1024 // 11000x Store multiple registers, see STM / STMIA / STMEA on page A8-374
1025 // 11001x Load multiple registers, see LDM / LDMIA / LDMFD on page A8-110 a
1026 // 1101xx Conditional branch, and Supervisor Call on page A6-13
1027 // 11100x Unconditional Branch, see B on page A8-44
1029 static bool DisassembleThumb1(uint16_t op, MCInst &MI, unsigned Opcode,
1030 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1032 unsigned op1 = slice(op, 5, 4);
1033 unsigned op2 = slice(op, 3, 2);
1034 unsigned op3 = slice(op, 1, 0);
1035 unsigned opA = slice(op, 5, 2);
1036 switch (op1) {
1037 case 0:
1038 // A6.2.1 Shift (immediate), add, subtract, move, and compare
1039 return DisassembleThumb1General(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1040 case 1:
1041 switch (op2) {
1042 case 0:
1043 switch (op3) {
1044 case 0:
1045 // A6.2.2 Data-processing
1046 return DisassembleThumb1DP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1047 case 1:
1048 // A6.2.3 Special data instructions and branch and exchange
1049 return DisassembleThumb1Special(MI, Opcode, insn, NumOps, NumOpsAdded,
1051 default:
1052 // A8.6.59 LDR (literal)
1053 return DisassembleThumb1LdPC(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1055 break;
1056 default:
1057 // A6.2.4 Load/store single data item
1058 return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
1060 break;
1062 break;
1063 case 2:
1064 switch (op2) {
1065 case 0:
1066 // A6.2.4 Load/store single data item
1067 return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
1069 case 1:
1070 // A6.2.4 Load/store single data item
1071 return DisassembleThumb1LdStSP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1072 case 2:
1073 if (op3 <= 1) {
1074 // A8.6.10 ADR
1075 return DisassembleThumb1AddPCi(MI, Opcode, insn, NumOps, NumOpsAdded,
1077 } else {
1078 // A8.6.8 ADD (SP plus immediate)
1079 return DisassembleThumb1AddSPi(MI, Opcode, insn, NumOps, NumOpsAdded,
1082 default:
1083 // A6.2.5 Miscellaneous 16-bit instructions
1084 return DisassembleThumb1Misc(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1086 break;
1087 case 3:
1088 switch (op2) {
1089 case 0:
1090 if (op3 <= 1) {
1091 // A8.6.189 STM / STMIA / STMEA
1092 return DisassembleThumb1StMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1093 } else {
1094 // A8.6.53 LDM / LDMIA / LDMFD
1095 return DisassembleThumb1LdMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1097 case 1:
1098 // A6.2.6 Conditional branch, and Supervisor Call
1099 return DisassembleThumb1CondBr(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1100 case 2:
1101 // Unconditional Branch, see B on page A8-44
1102 return DisassembleThumb1Br(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1103 default:
1104 assert(0 && "Unreachable code");
1105 break;
1107 break;
1108 default:
1109 assert(0 && "Unreachable code");
1110 break;
1113 return false;
1116 ///////////////////////////////////////////////
1117 // //
1118 // Thumb2 instruction disassembly functions. //
1119 // //
1120 ///////////////////////////////////////////////
1122 ///////////////////////////////////////////////////////////
1123 // //
1124 // Note: the register naming follows the ARM convention! //
1125 // //
1126 ///////////////////////////////////////////////////////////
1128 static inline bool Thumb2SRSOpcode(unsigned Opcode) {
1129 switch (Opcode) {
1130 default:
1131 return false;
1132 case ARM::t2SRSDBW: case ARM::t2SRSDB:
1133 case ARM::t2SRSIAW: case ARM::t2SRSIA:
1134 return true;
1138 static inline bool Thumb2RFEOpcode(unsigned Opcode) {
1139 switch (Opcode) {
1140 default:
1141 return false;
1142 case ARM::t2RFEDBW: case ARM::t2RFEDB:
1143 case ARM::t2RFEIAW: case ARM::t2RFEIA:
1144 return true;
1148 // t2SRS[IA|DB]W/t2SRS[IA|DB]: mode_imm = Inst{4-0}
1149 static bool DisassembleThumb2SRS(MCInst &MI, unsigned Opcode, uint32_t insn,
1150 unsigned short NumOps, unsigned &NumOpsAdded) {
1151 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
1152 NumOpsAdded = 1;
1153 return true;
1156 // t2RFE[IA|DB]W/t2RFE[IA|DB]: Rn
1157 static bool DisassembleThumb2RFE(MCInst &MI, unsigned Opcode, uint32_t insn,
1158 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1159 unsigned Rn = decodeRn(insn);
1160 if (Rn == 15) {
1161 DEBUG(errs() << "if n == 15 then UNPREDICTABLE\n");
1162 return false;
1164 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,ARM::GPRRegClassID,Rn)));
1165 NumOpsAdded = 1;
1166 return true;
1169 static bool DisassembleThumb2LdStMul(MCInst &MI, unsigned Opcode, uint32_t insn,
1170 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1172 if (Thumb2SRSOpcode(Opcode))
1173 return DisassembleThumb2SRS(MI, Opcode, insn, NumOps, NumOpsAdded);
1175 if (Thumb2RFEOpcode(Opcode))
1176 return DisassembleThumb2RFE(MI, Opcode, insn, NumOps, NumOpsAdded, B);
1178 assert((Opcode == ARM::t2LDMIA || Opcode == ARM::t2LDMIA_UPD ||
1179 Opcode == ARM::t2LDMDB || Opcode == ARM::t2LDMDB_UPD ||
1180 Opcode == ARM::t2STMIA || Opcode == ARM::t2STMIA_UPD ||
1181 Opcode == ARM::t2STMDB || Opcode == ARM::t2STMDB_UPD)
1182 && "Unexpected opcode");
1183 assert(NumOps >= 4 && "Thumb2 LdStMul expects NumOps >= 4");
1185 NumOpsAdded = 0;
1187 unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
1189 // Writeback to base.
1190 if (Opcode == ARM::t2LDMIA_UPD || Opcode == ARM::t2LDMDB_UPD ||
1191 Opcode == ARM::t2STMIA_UPD || Opcode == ARM::t2STMDB_UPD) {
1192 MI.addOperand(MCOperand::CreateReg(Base));
1193 ++NumOpsAdded;
1196 MI.addOperand(MCOperand::CreateReg(Base));
1197 ++NumOpsAdded;
1199 // Handling the two predicate operands before the reglist.
1200 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps)) {
1201 NumOpsAdded += 2;
1202 } else {
1203 DEBUG(errs() << "Expected predicate operands not found.\n");
1204 return false;
1207 unsigned RegListBits = insn & ((1 << 16) - 1);
1209 // Fill the variadic part of reglist.
1210 for (unsigned i = 0; i < 16; ++i)
1211 if ((RegListBits >> i) & 1) {
1212 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1213 i)));
1214 ++NumOpsAdded;
1217 return true;
1220 // t2LDREX: Rd Rn
1221 // t2LDREXD: Rd Rs Rn
1222 // t2LDREXB, t2LDREXH: Rd Rn
1223 // t2STREX: Rs Rd Rn
1224 // t2STREXD: Rm Rd Rs Rn
1225 // t2STREXB, t2STREXH: Rm Rd Rn
1226 static bool DisassembleThumb2LdStEx(MCInst &MI, unsigned Opcode, uint32_t insn,
1227 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1229 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1230 if (!OpInfo) return false;
1232 unsigned &OpIdx = NumOpsAdded;
1234 OpIdx = 0;
1236 assert(NumOps >= 2
1237 && OpInfo[0].RegClass > 0
1238 && OpInfo[1].RegClass > 0
1239 && "Expect >=2 operands and first two as reg operands");
1241 bool isStore = (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH);
1242 bool isSW = (Opcode == ARM::t2LDREX || Opcode == ARM::t2STREX);
1243 bool isDW = (Opcode == ARM::t2LDREXD || Opcode == ARM::t2STREXD);
1245 unsigned Rt = decodeRd(insn);
1246 unsigned Rt2 = decodeRs(insn); // But note that this is Rd for t2STREX.
1247 unsigned Rd = decodeRm(insn);
1248 unsigned Rn = decodeRn(insn);
1250 // Some sanity checking first.
1251 if (isStore) {
1252 // if d == n || d == t then UNPREDICTABLE
1253 // if d == n || d == t || d == t2 then UNPREDICTABLE
1254 if (isDW) {
1255 if (Rd == Rn || Rd == Rt || Rd == Rt2) {
1256 DEBUG(errs() << "if d == n || d == t || d == t2 then UNPREDICTABLE\n");
1257 return false;
1259 } else {
1260 if (isSW) {
1261 if (Rt2 == Rn || Rt2 == Rt) {
1262 DEBUG(errs() << "if d == n || d == t then UNPREDICTABLE\n");
1263 return false;
1265 } else {
1266 if (Rd == Rn || Rd == Rt) {
1267 DEBUG(errs() << "if d == n || d == t then UNPREDICTABLE\n");
1268 return false;
1272 } else {
1273 // Load
1274 // A8.6.71 LDREXD
1275 // if t == t2 then UNPREDICTABLE
1276 if (isDW && Rt == Rt2) {
1277 DEBUG(errs() << "if t == t2 then UNPREDICTABLE\n");
1278 return false;
1282 // Add the destination operand for store.
1283 if (isStore) {
1284 MI.addOperand(MCOperand::CreateReg(
1285 getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1286 isSW ? Rt2 : Rd)));
1287 ++OpIdx;
1290 // Source operand for store and destination operand for load.
1291 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1292 Rt)));
1293 ++OpIdx;
1295 // Thumb2 doubleword complication: with an extra source/destination operand.
1296 if (isDW) {
1297 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
1298 Rt2)));
1299 ++OpIdx;
1302 // Finally add the pointer operand.
1303 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1304 Rn)));
1305 ++OpIdx;
1307 return true;
1310 // t2LDRDi8: Rd Rs Rn imm8s4 (offset mode)
1311 // t2LDRDpci: Rd Rs imm8s4 (Not decoded, prefer the generic t2LDRDi8 version)
1312 // t2STRDi8: Rd Rs Rn imm8s4 (offset mode)
1314 // Ditto for t2LDRD_PRE, t2LDRD_POST, t2STRD_PRE, t2STRD_POST, which are for
1315 // disassembly only and do not have a tied_to writeback base register operand.
1316 static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned Opcode,
1317 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1319 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
1320 if (!OpInfo) return false;
1322 assert(NumOps >= 4
1323 && OpInfo[0].RegClass > 0
1324 && OpInfo[0].RegClass == OpInfo[1].RegClass
1325 && OpInfo[2].RegClass > 0
1326 && OpInfo[3].RegClass < 0
1327 && "Expect >= 4 operands and first 3 as reg operands");
1329 // Thumnb allows for specifying Rt and Rt2, unlike ARM (which has Rt2==Rt+1).
1330 unsigned Rt = decodeRd(insn);
1331 unsigned Rt2 = decodeRs(insn);
1332 unsigned Rn = decodeRn(insn);
1334 // Some sanity checking first.
1336 // A8.6.67 LDRD (literal) has its W bit as (0).
1337 if (Opcode == ARM::t2LDRDi8 || Opcode == ARM::t2LDRD_PRE || Opcode == ARM::t2LDRD_POST) {
1338 if (Rn == 15 && slice(insn, 21, 21) != 0)
1339 return false;
1340 } else {
1341 // For Dual Store, PC cannot be used as the base register.
1342 if (Rn == 15) {
1343 DEBUG(errs() << "if n == 15 then UNPREDICTABLE\n");
1344 return false;
1347 if (Rt == Rt2) {
1348 DEBUG(errs() << "if t == t2 then UNPREDICTABLE\n");
1349 return false;
1351 if (Opcode != ARM::t2LDRDi8 && Opcode != ARM::t2STRDi8) {
1352 if (Rn == Rt || Rn == Rt2) {
1353 DEBUG(errs() << "if wback && (n == t || n == t2) then UNPREDICTABLE\n");
1354 return false;
1358 // Add the <Rt> <Rt2> operands.
1359 unsigned RegClassPair = OpInfo[0].RegClass;
1360 unsigned RegClassBase = OpInfo[2].RegClass;
1362 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
1363 decodeRd(insn))));
1364 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassPair,
1365 decodeRs(insn))));
1366 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassBase,
1367 decodeRn(insn))));
1369 // Finally add (+/-)imm8*4, depending on the U bit.
1370 int Offset = getImm8(insn) * 4;
1371 if (getUBit(insn) == 0)
1372 Offset = -Offset;
1373 MI.addOperand(MCOperand::CreateImm(Offset));
1374 NumOpsAdded = 4;
1376 return true;
1379 // t2TBB, t2TBH: Rn Rm Pred-Imm Pred-CCR
1380 static bool DisassembleThumb2TB(MCInst &MI, unsigned Opcode,
1381 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1383 assert(NumOps >= 2 && "Expect >= 2 operands");
1385 // The generic version of TBB/TBH needs a base register.
1386 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1387 decodeRn(insn))));
1388 // Add the index register.
1389 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1390 decodeRm(insn))));
1391 NumOpsAdded = 2;
1393 return true;
1396 static inline bool Thumb2ShiftOpcode(unsigned Opcode) {
1397 switch (Opcode) {
1398 default:
1399 return false;
1400 case ARM::t2MOVCClsl: case ARM::t2MOVCClsr:
1401 case ARM::t2MOVCCasr: case ARM::t2MOVCCror:
1402 case ARM::t2LSLri: case ARM::t2LSRri:
1403 case ARM::t2ASRri: case ARM::t2RORri:
1404 return true;
1408 // A6.3.11 Data-processing (shifted register)
1410 // Two register operands (Rn=0b1111 no 1st operand reg): Rs Rm
1411 // Two register operands (Rs=0b1111 no dst operand reg): Rn Rm
1412 // Three register operands: Rs Rn Rm
1413 // Three register operands: (Rn=0b1111 Conditional Move) Rs Ro(TIED_TO) Rm
1415 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
1416 // register with shift forms: (Rm, ConstantShiftSpecifier).
1417 // Constant shift specifier: Imm = (ShOp | ShAmt<<3).
1419 // There are special instructions, like t2MOVsra_flag and t2MOVsrl_flag, which
1420 // only require two register operands: Rd, Rm in ARM Reference Manual terms, and
1421 // nothing else, because the shift amount is already specified.
1422 // Similar case holds for t2MOVrx, t2ADDrr, ..., etc.
1423 static bool DisassembleThumb2DPSoReg(MCInst &MI, unsigned Opcode, uint32_t insn,
1424 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1426 const MCInstrDesc &MCID = ARMInsts[Opcode];
1427 const MCOperandInfo *OpInfo = MCID.OpInfo;
1428 unsigned &OpIdx = NumOpsAdded;
1430 // Special case handling.
1431 if (Opcode == ARM::t2BR_JT) {
1432 assert(NumOps == 4
1433 && OpInfo[0].RegClass == ARM::GPRRegClassID
1434 && OpInfo[1].RegClass == ARM::GPRRegClassID
1435 && OpInfo[2].RegClass < 0
1436 && OpInfo[3].RegClass < 0
1437 && "Exactly 4 operands expect and first two as reg operands");
1438 // Only need to populate the src reg operand.
1439 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1440 decodeRm(insn))));
1441 MI.addOperand(MCOperand::CreateReg(0));
1442 MI.addOperand(MCOperand::CreateImm(0));
1443 MI.addOperand(MCOperand::CreateImm(0));
1444 NumOpsAdded = 4;
1445 return true;
1448 OpIdx = 0;
1450 assert(NumOps >= 2
1451 && (OpInfo[0].RegClass == ARM::GPRRegClassID ||
1452 OpInfo[0].RegClass == ARM::rGPRRegClassID)
1453 && (OpInfo[1].RegClass == ARM::GPRRegClassID ||
1454 OpInfo[1].RegClass == ARM::rGPRRegClassID)
1455 && "Expect >= 2 operands and first two as reg operands");
1457 bool ThreeReg = (NumOps > 2 && (OpInfo[2].RegClass == ARM::GPRRegClassID ||
1458 OpInfo[2].RegClass == ARM::rGPRRegClassID));
1459 bool NoDstReg = (decodeRs(insn) == 0xF);
1461 // Build the register operands, followed by the constant shift specifier.
1463 MI.addOperand(MCOperand::CreateReg(
1464 getRegisterEnum(B, OpInfo[0].RegClass,
1465 NoDstReg ? decodeRn(insn) : decodeRs(insn))));
1466 ++OpIdx;
1468 if (ThreeReg) {
1469 int Idx;
1470 if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
1471 // Process tied_to operand constraint.
1472 MI.addOperand(MI.getOperand(Idx));
1473 ++OpIdx;
1474 } else if (!NoDstReg) {
1475 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[1].RegClass,
1476 decodeRn(insn))));
1477 ++OpIdx;
1478 } else {
1479 DEBUG(errs() << "Thumb2 encoding error: d==15 for three-reg operands.\n");
1480 return false;
1484 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
1485 decodeRm(insn))));
1486 ++OpIdx;
1488 if (NumOps == OpIdx)
1489 return true;
1491 if (OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
1492 && !OpInfo[OpIdx].isOptionalDef()) {
1494 if (Thumb2ShiftOpcode(Opcode)) {
1495 unsigned Imm = getShiftAmtBits(insn);
1496 ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 5, 4));
1497 getImmShiftSE(ShOp, Imm);
1498 MI.addOperand(MCOperand::CreateImm(Imm));
1499 } else {
1500 // Build the constant shift specifier operand.
1501 unsigned bits2 = getShiftTypeBits(insn);
1502 unsigned imm5 = getShiftAmtBits(insn);
1503 ARM_AM::ShiftOpc ShOp = ARM_AM::no_shift;
1504 unsigned ShAmt = decodeImmShift(bits2, imm5, ShOp);
1505 MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShAmt)));
1507 ++OpIdx;
1510 return true;
1513 // A6.3.1 Data-processing (modified immediate)
1515 // Two register operands: Rs Rn ModImm
1516 // One register operands (Rs=0b1111 no explicit dest reg): Rn ModImm
1517 // One register operands (Rn=0b1111 no explicit src reg): Rs ModImm -
1518 // {t2MOVi, t2MVNi}
1520 // ModImm = ThumbExpandImm(i:imm3:imm8)
1521 static bool DisassembleThumb2DPModImm(MCInst &MI, unsigned Opcode,
1522 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1524 const MCInstrDesc &MCID = ARMInsts[Opcode];
1525 const MCOperandInfo *OpInfo = MCID.OpInfo;
1526 unsigned &OpIdx = NumOpsAdded;
1528 OpIdx = 0;
1530 unsigned RdRegClassID = OpInfo[0].RegClass;
1531 assert(NumOps >= 2 && (RdRegClassID == ARM::GPRRegClassID ||
1532 RdRegClassID == ARM::rGPRRegClassID)
1533 && "Expect >= 2 operands and first one as reg operand");
1535 unsigned RnRegClassID = OpInfo[1].RegClass;
1536 bool TwoReg = (RnRegClassID == ARM::GPRRegClassID
1537 || RnRegClassID == ARM::rGPRRegClassID);
1538 bool NoDstReg = (decodeRs(insn) == 0xF);
1540 // Build the register operands, followed by the modified immediate.
1542 MI.addOperand(MCOperand::CreateReg(
1543 getRegisterEnum(B, RdRegClassID,
1544 NoDstReg ? decodeRn(insn) : decodeRs(insn))));
1545 ++OpIdx;
1547 if (TwoReg) {
1548 if (NoDstReg) {
1549 DEBUG(errs()<<"Thumb2 encoding error: d==15 for DPModImm 2-reg instr.\n");
1550 return false;
1552 int Idx;
1553 if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
1554 // The reg operand is tied to the first reg operand.
1555 MI.addOperand(MI.getOperand(Idx));
1556 } else {
1557 // Add second reg operand.
1558 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
1559 decodeRn(insn))));
1561 ++OpIdx;
1564 // The modified immediate operand should come next.
1565 assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0 &&
1566 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()
1567 && "Pure imm operand expected");
1569 // i:imm3:imm8
1570 // A6.3.2 Modified immediate constants in Thumb instructions
1571 unsigned imm12 = getIImm3Imm8(insn);
1572 MI.addOperand(MCOperand::CreateImm(ThumbExpandImm(imm12)));
1573 ++OpIdx;
1575 return true;
1578 static inline bool Thumb2SaturateOpcode(unsigned Opcode) {
1579 switch (Opcode) {
1580 case ARM::t2SSAT: case ARM::t2SSAT16:
1581 case ARM::t2USAT: case ARM::t2USAT16:
1582 return true;
1583 default:
1584 return false;
1588 /// DisassembleThumb2Sat - Disassemble Thumb2 saturate instructions:
1589 /// o t2SSAT, t2USAT: Rs sat_pos Rn shamt
1590 /// o t2SSAT16, t2USAT16: Rs sat_pos Rn
1591 static bool DisassembleThumb2Sat(MCInst &MI, unsigned Opcode, uint32_t insn,
1592 unsigned &NumOpsAdded, BO B) {
1593 const MCInstrDesc &MCID = ARMInsts[Opcode];
1594 NumOpsAdded = MCID.getNumOperands() - 2; // ignore predicate operands
1596 // Disassemble the register def.
1597 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
1598 decodeRs(insn))));
1600 unsigned Pos = slice(insn, 4, 0);
1601 if (Opcode == ARM::t2SSAT || Opcode == ARM::t2SSAT16)
1602 Pos += 1;
1603 MI.addOperand(MCOperand::CreateImm(Pos));
1605 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
1606 decodeRn(insn))));
1608 if (NumOpsAdded == 4) {
1609 ARM_AM::ShiftOpc Opc = (slice(insn, 21, 21) != 0 ?
1610 ARM_AM::asr : ARM_AM::lsl);
1611 // Inst{14-12:7-6} encodes the imm5 shift amount.
1612 unsigned ShAmt = slice(insn, 14, 12) << 2 | slice(insn, 7, 6);
1613 if (ShAmt == 0) {
1614 if (Opc == ARM_AM::asr)
1615 ShAmt = 32;
1616 else
1617 Opc = ARM_AM::no_shift;
1619 MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(Opc, ShAmt)));
1621 return true;
1624 // A6.3.3 Data-processing (plain binary immediate)
1626 // o t2ADDri12, t2SUBri12: Rs Rn imm12
1627 // o t2LEApcrel (ADR): Rs imm12
1628 // o t2BFC (BFC): Rs Ro(TIED_TO) bf_inv_mask_imm
1629 // o t2BFI (BFI): Rs Ro(TIED_TO) Rn bf_inv_mask_imm
1630 // o t2MOVi16: Rs imm16
1631 // o t2MOVTi16: Rs imm16
1632 // o t2SBFX (SBFX): Rs Rn lsb width
1633 // o t2UBFX (UBFX): Rs Rn lsb width
1634 // o t2BFI (BFI): Rs Rn lsb width
1635 static bool DisassembleThumb2DPBinImm(MCInst &MI, unsigned Opcode,
1636 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1638 const MCInstrDesc &MCID = ARMInsts[Opcode];
1639 const MCOperandInfo *OpInfo = MCID.OpInfo;
1640 unsigned &OpIdx = NumOpsAdded;
1642 OpIdx = 0;
1644 unsigned RdRegClassID = OpInfo[0].RegClass;
1645 assert(NumOps >= 2 && (RdRegClassID == ARM::GPRRegClassID ||
1646 RdRegClassID == ARM::rGPRRegClassID)
1647 && "Expect >= 2 operands and first one as reg operand");
1649 unsigned RnRegClassID = OpInfo[1].RegClass;
1650 bool TwoReg = (RnRegClassID == ARM::GPRRegClassID
1651 || RnRegClassID == ARM::rGPRRegClassID);
1653 // Build the register operand(s), followed by the immediate(s).
1655 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RdRegClassID,
1656 decodeRs(insn))));
1657 ++OpIdx;
1659 if (TwoReg) {
1660 assert(NumOps >= 3 && "Expect >= 3 operands");
1661 int Idx;
1662 if ((Idx = MCID.getOperandConstraint(OpIdx, MCOI::TIED_TO)) != -1) {
1663 // Process tied_to operand constraint.
1664 MI.addOperand(MI.getOperand(Idx));
1665 } else {
1666 // Add src reg operand.
1667 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
1668 decodeRn(insn))));
1670 ++OpIdx;
1673 if (Opcode == ARM::t2BFI) {
1674 // Add val reg operand.
1675 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
1676 decodeRn(insn))));
1677 ++OpIdx;
1680 assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
1681 && !OpInfo[OpIdx].isOptionalDef()
1682 && "Pure imm operand expected");
1684 // Pre-increment OpIdx.
1685 ++OpIdx;
1687 if (Opcode == ARM::t2ADDri12 || Opcode == ARM::t2SUBri12
1688 || Opcode == ARM::t2LEApcrel)
1689 MI.addOperand(MCOperand::CreateImm(getIImm3Imm8(insn)));
1690 else if (Opcode == ARM::t2MOVi16 || Opcode == ARM::t2MOVTi16) {
1691 if (!B->tryAddingSymbolicOperand(getImm16(insn), 4, MI))
1692 MI.addOperand(MCOperand::CreateImm(getImm16(insn)));
1693 } else if (Opcode == ARM::t2BFC || Opcode == ARM::t2BFI) {
1694 uint32_t mask = 0;
1695 if (getBitfieldInvMask(insn, mask))
1696 MI.addOperand(MCOperand::CreateImm(mask));
1697 else
1698 return false;
1699 } else {
1700 // Handle the case of: lsb width
1701 assert((Opcode == ARM::t2SBFX || Opcode == ARM::t2UBFX)
1702 && "Unexpected opcode");
1703 MI.addOperand(MCOperand::CreateImm(getLsb(insn)));
1704 MI.addOperand(MCOperand::CreateImm(getWidthMinus1(insn) + 1));
1706 ++OpIdx;
1709 return true;
1712 // A6.3.4 Table A6-15 Miscellaneous control instructions
1713 // A8.6.41 DMB
1714 // A8.6.42 DSB
1715 // A8.6.49 ISB
1716 static inline bool t2MiscCtrlInstr(uint32_t insn) {
1717 if (slice(insn, 31, 20) == 0xf3b && slice(insn, 15, 14) == 2 &&
1718 slice(insn, 12, 12) == 0)
1719 return true;
1721 return false;
1724 // A6.3.4 Branches and miscellaneous control
1726 // A8.6.16 B
1727 // Branches: t2B, t2Bcc -> imm operand
1729 // Branches: t2TPsoft -> no operand
1731 // A8.6.23 BL, BLX (immediate)
1732 // Branches (defined in ARMInstrThumb.td): tBLr9, tBLXi_r9 -> imm operand
1734 // A8.6.26
1735 // t2BXJ -> Rn
1737 // Miscellaneous control:
1738 // -> no operand (except pred-imm pred-ccr for CLREX, memory barrier variants)
1740 // Hint: t2NOP, t2YIELD, t2WFE, t2WFI, t2SEV
1741 // -> no operand (except pred-imm pred-ccr)
1743 // t2DBG -> imm4 = Inst{3-0}
1745 // t2MRS/t2MRSsys -> Rs
1746 // t2MSR/t2MSRsys -> Rn mask=Inst{11-8}
1747 // t2SMC -> imm4 = Inst{19-16}
1748 static bool DisassembleThumb2BrMiscCtrl(MCInst &MI, unsigned Opcode,
1749 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1751 if (NumOps == 0)
1752 return true;
1754 if (Opcode == ARM::t2DMB || Opcode == ARM::t2DSB) {
1755 // Inst{3-0} encodes the memory barrier option for the variants.
1756 unsigned opt = slice(insn, 3, 0);
1757 switch (opt) {
1758 case ARM_MB::SY: case ARM_MB::ST:
1759 case ARM_MB::ISH: case ARM_MB::ISHST:
1760 case ARM_MB::NSH: case ARM_MB::NSHST:
1761 case ARM_MB::OSH: case ARM_MB::OSHST:
1762 MI.addOperand(MCOperand::CreateImm(opt));
1763 NumOpsAdded = 1;
1764 return true;
1765 default:
1766 return false;
1770 if (t2MiscCtrlInstr(insn))
1771 return true;
1773 switch (Opcode) {
1774 case ARM::t2CLREX:
1775 case ARM::t2NOP:
1776 case ARM::t2YIELD:
1777 case ARM::t2WFE:
1778 case ARM::t2WFI:
1779 case ARM::t2SEV:
1780 return true;
1781 default:
1782 break;
1785 // FIXME: To enable correct asm parsing and disasm of CPS we need 3 different
1786 // opcodes which match the same real instruction. This is needed since there's
1787 // no current handling of optional arguments. Fix here when a better handling
1788 // of optional arguments is implemented.
1789 if (Opcode == ARM::t2CPS3p) {
1790 MI.addOperand(MCOperand::CreateImm(slice(insn, 10, 9))); // imod
1791 MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 5))); // iflags
1792 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
1793 NumOpsAdded = 3;
1794 return true;
1796 if (Opcode == ARM::t2CPS2p) {
1797 MI.addOperand(MCOperand::CreateImm(slice(insn, 10, 9))); // imod
1798 MI.addOperand(MCOperand::CreateImm(slice(insn, 7, 5))); // iflags
1799 NumOpsAdded = 2;
1800 return true;
1802 if (Opcode == ARM::t2CPS1p) {
1803 MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0))); // mode
1804 NumOpsAdded = 1;
1805 return true;
1808 // DBG has its option specified in Inst{3-0}.
1809 if (Opcode == ARM::t2DBG) {
1810 MI.addOperand(MCOperand::CreateImm(slice(insn, 3, 0)));
1811 NumOpsAdded = 1;
1812 return true;
1815 // MRS and MRSsys take one GPR reg Rs.
1816 if (Opcode == ARM::t2MRS || Opcode == ARM::t2MRSsys) {
1817 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1818 decodeRs(insn))));
1819 NumOpsAdded = 1;
1820 return true;
1822 // BXJ takes one GPR reg Rn.
1823 if (Opcode == ARM::t2BXJ) {
1824 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1825 decodeRn(insn))));
1826 NumOpsAdded = 1;
1827 return true;
1829 // MSR take a mask, followed by one GPR reg Rn. The mask contains the R Bit in
1830 // bit 4, and the special register fields in bits 3-0.
1831 if (Opcode == ARM::t2MSR) {
1832 MI.addOperand(MCOperand::CreateImm(slice(insn, 20, 20) << 4 /* R Bit */ |
1833 slice(insn, 11, 8) /* Special Reg */));
1834 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1835 decodeRn(insn))));
1836 NumOpsAdded = 2;
1837 return true;
1839 // SMC take imm4.
1840 if (Opcode == ARM::t2SMC) {
1841 MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 16)));
1842 NumOpsAdded = 1;
1843 return true;
1846 // Some instructions have predicate operands first before the immediate.
1847 if (Opcode == ARM::tBLXi_r9 || Opcode == ARM::tBLr9) {
1848 // Handling the two predicate operands before the imm operand.
1849 if (B->DoPredicateOperands(MI, Opcode, insn, NumOps))
1850 NumOpsAdded += 2;
1851 else {
1852 DEBUG(errs() << "Expected predicate operands not found.\n");
1853 return false;
1857 // Add the imm operand.
1858 int Offset = 0;
1860 switch (Opcode) {
1861 default:
1862 assert(0 && "Unexpected opcode");
1863 return false;
1864 case ARM::t2B:
1865 Offset = decodeImm32_B_EncodingT4(insn);
1866 break;
1867 case ARM::t2Bcc:
1868 Offset = decodeImm32_B_EncodingT3(insn);
1869 break;
1870 case ARM::tBLr9:
1871 Offset = decodeImm32_BL(insn);
1872 break;
1873 case ARM::tBLXi_r9:
1874 Offset = decodeImm32_BLX(insn);
1875 break;
1878 if (!B->tryAddingSymbolicOperand(Offset + B->getBuilderAddress() + 4, 4, MI))
1879 MI.addOperand(MCOperand::CreateImm(Offset));
1881 // This is an increment as some predicate operands may have been added first.
1882 NumOpsAdded += 1;
1884 return true;
1887 static inline bool Thumb2PreloadOpcode(unsigned Opcode) {
1888 switch (Opcode) {
1889 default:
1890 return false;
1891 case ARM::t2PLDi12: case ARM::t2PLDi8:
1892 case ARM::t2PLDs:
1893 case ARM::t2PLDWi12: case ARM::t2PLDWi8:
1894 case ARM::t2PLDWs:
1895 case ARM::t2PLIi12: case ARM::t2PLIi8:
1896 case ARM::t2PLIs:
1897 return true;
1901 static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned Opcode, uint32_t insn,
1902 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
1904 // Preload Data/Instruction requires either 2 or 3 operands.
1905 // t2PLDi12, t2PLDi8, t2PLDpci: Rn [+/-]imm12/imm8
1906 // t2PLDr: Rn Rm
1907 // t2PLDs: Rn Rm imm2=Inst{5-4}
1908 // Same pattern applies for t2PLDW* and t2PLI*.
1910 const MCInstrDesc &MCID = ARMInsts[Opcode];
1911 const MCOperandInfo *OpInfo = MCID.OpInfo;
1912 unsigned &OpIdx = NumOpsAdded;
1914 OpIdx = 0;
1916 assert(NumOps >= 2 &&
1917 OpInfo[0].RegClass == ARM::GPRRegClassID &&
1918 "Expect >= 2 operands and first one as reg operand");
1920 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1921 decodeRn(insn))));
1922 ++OpIdx;
1924 if (OpInfo[OpIdx].RegClass == ARM::rGPRRegClassID) {
1925 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
1926 decodeRm(insn))));
1927 } else {
1928 assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
1929 && !OpInfo[OpIdx].isOptionalDef()
1930 && "Pure imm operand expected");
1931 int Offset = 0;
1932 if (Opcode == ARM::t2PLDi8 || Opcode == ARM::t2PLDWi8 ||
1933 Opcode == ARM::t2PLIi8) {
1934 // A8.6.117 Encoding T2: add = FALSE
1935 unsigned Imm8 = getImm8(insn);
1936 Offset = -1 * Imm8;
1937 } else {
1938 // The i12 forms. See, for example, A8.6.117 Encoding T1.
1939 // Note that currently t2PLDi12 also handles the previously named t2PLDpci
1940 // opcode, that's why we use decodeImm12(insn) which returns +/- imm12.
1941 Offset = decodeImm12(insn);
1943 MI.addOperand(MCOperand::CreateImm(Offset));
1945 ++OpIdx;
1947 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0 &&
1948 !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
1949 // Fills in the shift amount for t2PLDs, t2PLDWs, t2PLIs.
1950 MI.addOperand(MCOperand::CreateImm(slice(insn, 5, 4)));
1951 ++OpIdx;
1954 return true;
1957 static bool BadRegsThumb2LdSt(unsigned Opcode, uint32_t insn, bool Load,
1958 unsigned R0, unsigned R1, unsigned R2, bool UseRm, bool WB) {
1960 // Inst{22-21} encodes the data item transferred for load/store.
1961 // For single word, it is encoded as ob10.
1962 bool Word = (slice(insn, 22, 21) == 2);
1963 bool Half = (slice(insn, 22, 21) == 1);
1964 bool Byte = (slice(insn, 22, 21) == 0);
1966 if (UseRm && BadReg(R2)) {
1967 DEBUG(errs() << "if BadReg(m) then UNPREDICTABLE\n");
1968 return true;
1971 if (Load) {
1972 if (!Word && R0 == 13) {
1973 DEBUG(errs() << "if t == 13 then UNPREDICTABLE\n");
1974 return true;
1976 if (Byte) {
1977 if (WB && R0 == 15 && slice(insn, 10, 8) == 3) {
1978 // A8.6.78 LDRSB (immediate) Encoding T2 (errata markup 8.0)
1979 DEBUG(errs() << "if t == 15 && PUW == '011' then UNPREDICTABLE\n");
1980 return true;
1983 // A6.3.8 Load halfword, memory hints
1984 if (Half) {
1985 if (WB) {
1986 if (R0 == R1) {
1987 // A8.6.82 LDRSH (immediate) Encoding T2
1988 DEBUG(errs() << "if WB && n == t then UNPREDICTABLE\n");
1989 return true;
1991 if (R0 == 15 && slice(insn, 10, 8) == 3) {
1992 // A8.6.82 LDRSH (immediate) Encoding T2 (errata markup 8.0)
1993 DEBUG(errs() << "if t == 15 && PUW == '011' then UNPREDICTABLE\n");
1994 return true;
1996 } else {
1997 if (Opcode == ARM::t2LDRHi8 || Opcode == ARM::t2LDRSHi8) {
1998 if (R0 == 15 && slice(insn, 10, 8) == 4) {
1999 // A8.6.82 LDRSH (immediate) Encoding T2
2000 DEBUG(errs() << "if Rt == '1111' and PUW == '100' then SEE"
2001 << " \"Unallocated memory hints\"\n");
2002 return true;
2004 } else {
2005 if (R0 == 15) {
2006 // A8.6.82 LDRSH (immediate) Encoding T1
2007 DEBUG(errs() << "if Rt == '1111' then SEE"
2008 << " \"Unallocated memory hints\"\n");
2009 return true;
2014 } else {
2015 if (WB && R0 == R1) {
2016 DEBUG(errs() << "if wback && n == t then UNPREDICTABLE\n");
2017 return true;
2019 if ((WB && R0 == 15) || (!WB && R1 == 15)) {
2020 DEBUG(errs() << "if Rn == '1111' then UNDEFINED\n");
2021 return true;
2023 if (Word) {
2024 if ((WB && R1 == 15) || (!WB && R0 == 15)) {
2025 DEBUG(errs() << "if t == 15 then UNPREDICTABLE\n");
2026 return true;
2028 } else {
2029 if ((WB && BadReg(R1)) || (!WB && BadReg(R0))) {
2030 DEBUG(errs() << "if BadReg(t) then UNPREDICTABLE\n");
2031 return true;
2035 return false;
2038 // A6.3.10 Store single data item
2039 // A6.3.9 Load byte, memory hints
2040 // A6.3.8 Load halfword, memory hints
2041 // A6.3.7 Load word
2043 // For example,
2045 // t2LDRi12: Rd Rn (+)imm12
2046 // t2LDRi8: Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
2047 // t2LDRs: Rd Rn Rm ConstantShiftSpecifier (see also
2048 // DisassembleThumb2DPSoReg)
2049 // t2LDR_POST: Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
2050 // t2LDR_PRE: Rd Rn Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
2052 // t2STRi12: Rd Rn (+)imm12
2053 // t2STRi8: Rd Rn (+/-)imm8 (+ if Inst{9} == 0b1)
2054 // t2STRs: Rd Rn Rm ConstantShiftSpecifier (see also
2055 // DisassembleThumb2DPSoReg)
2056 // t2STR_POST: Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
2057 // t2STR_PRE: Rn Rd Rn(TIED_TO) (+/-)imm8 (+ if Inst{9} == 0b1)
2059 // Note that for indexed modes, the Rn(TIED_TO) operand needs to be populated
2060 // correctly, as LLVM AsmPrinter depends on it. For indexed stores, the first
2061 // operand is Rn; for all the other instructions, Rd is the first operand.
2063 // Delegates to DisassembleThumb2PreLoad() for preload data/instruction.
2064 // Delegates to DisassembleThumb2Ldpci() for load * literal operations.
2065 static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, unsigned Opcode,
2066 uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2068 unsigned Rn = decodeRn(insn);
2070 if (Thumb2PreloadOpcode(Opcode))
2071 return DisassembleThumb2PreLoad(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2073 // See, for example, A6.3.7 Load word: Table A6-18 Load word.
2074 if (Load && Rn == 15)
2075 return DisassembleThumb2Ldpci(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2076 const MCInstrDesc &MCID = ARMInsts[Opcode];
2077 const MCOperandInfo *OpInfo = MCID.OpInfo;
2078 unsigned &OpIdx = NumOpsAdded;
2080 OpIdx = 0;
2082 assert(NumOps >= 3 &&
2083 OpInfo[0].RegClass > 0 &&
2084 OpInfo[1].RegClass > 0 &&
2085 "Expect >= 3 operands and first two as reg operands");
2087 bool ThreeReg = (OpInfo[2].RegClass > 0);
2088 bool TIED_TO = ThreeReg && MCID.getOperandConstraint(2, MCOI::TIED_TO) != -1;
2089 bool Imm12 = !ThreeReg && slice(insn, 23, 23) == 1; // ARMInstrThumb2.td
2091 // Build the register operands, followed by the immediate.
2092 unsigned R0 = 0, R1 = 0, R2 = 0;
2093 unsigned Rd = decodeRd(insn);
2094 int Imm = 0;
2096 if (!Load && TIED_TO) {
2097 R0 = Rn;
2098 R1 = Rd;
2099 } else {
2100 R0 = Rd;
2101 R1 = Rn;
2103 if (ThreeReg) {
2104 if (TIED_TO) {
2105 R2 = Rn;
2106 Imm = decodeImm8(insn);
2107 } else {
2108 R2 = decodeRm(insn);
2109 // See, for example, A8.6.64 LDRB (register).
2110 // And ARMAsmPrinter::printT2AddrModeSoRegOperand().
2111 // LSL is the default shift opc, and LLVM does not expect it to be encoded
2112 // as part of the immediate operand.
2113 // Imm = ARM_AM::getSORegOpc(ARM_AM::lsl, slice(insn, 5, 4));
2114 Imm = slice(insn, 5, 4);
2116 } else {
2117 if (Imm12)
2118 Imm = getImm12(insn);
2119 else
2120 Imm = decodeImm8(insn);
2123 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
2124 R0)));
2125 ++OpIdx;
2126 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
2127 R1)));
2128 ++OpIdx;
2130 if (ThreeReg) {
2131 // This could be an offset register or a TIED_TO register.
2132 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
2133 R2)));
2134 ++OpIdx;
2137 if (BadRegsThumb2LdSt(Opcode, insn, Load, R0, R1, R2, ThreeReg & !TIED_TO,
2138 TIED_TO))
2139 return false;
2141 assert(OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate()
2142 && !OpInfo[OpIdx].isOptionalDef()
2143 && "Pure imm operand expected");
2145 MI.addOperand(MCOperand::CreateImm(Imm));
2146 ++OpIdx;
2148 return true;
2151 // A6.3.12 Data-processing (register)
2153 // Two register operands [rotate]: Rs Rm [rotation(= (rotate:'000'))]
2154 // Three register operands only: Rs Rn Rm
2155 // Three register operands [rotate]: Rs Rn Rm [rotation(= (rotate:'000'))]
2157 // Parallel addition and subtraction 32-bit Thumb instructions: Rs Rn Rm
2159 // Miscellaneous operations: Rs [Rn] Rm
2160 static bool DisassembleThumb2DPReg(MCInst &MI, unsigned Opcode, uint32_t insn,
2161 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2163 const MCInstrDesc &MCID = ARMInsts[Opcode];
2164 const MCOperandInfo *OpInfo = MCID.OpInfo;
2165 unsigned &OpIdx = NumOpsAdded;
2167 OpIdx = 0;
2169 assert(NumOps >= 2 &&
2170 OpInfo[0].RegClass > 0 &&
2171 OpInfo[1].RegClass > 0 &&
2172 "Expect >= 2 operands and first two as reg operands");
2174 // Build the register operands, followed by the optional rotation amount.
2176 bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass > 0;
2178 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
2179 decodeRs(insn))));
2180 ++OpIdx;
2182 if (ThreeReg) {
2183 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B,OpInfo[OpIdx].RegClass,
2184 decodeRn(insn))));
2185 ++OpIdx;
2188 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
2189 decodeRm(insn))));
2190 ++OpIdx;
2192 if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0
2193 && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
2194 // Add the rotation amount immediate.
2195 MI.addOperand(MCOperand::CreateImm(decodeRotate(insn)));
2196 ++OpIdx;
2199 return true;
2202 // A6.3.16 Multiply, multiply accumulate, and absolute difference
2204 // t2MLA, t2MLS, t2SMMLA, t2SMMLS: Rs Rn Rm Ra=Inst{15-12}
2205 // t2MUL, t2SMMUL: Rs Rn Rm
2206 // t2SMLA[BB|BT|TB|TT|WB|WT]: Rs Rn Rm Ra=Inst{15-12}
2207 // t2SMUL[BB|BT|TB|TT|WB|WT]: Rs Rn Rm
2209 // Dual halfword multiply: t2SMUAD[X], t2SMUSD[X], t2SMLAD[X], t2SMLSD[X]:
2210 // Rs Rn Rm Ra=Inst{15-12}
2212 // Unsigned Sum of Absolute Differences [and Accumulate]
2213 // Rs Rn Rm [Ra=Inst{15-12}]
2214 static bool DisassembleThumb2Mul(MCInst &MI, unsigned Opcode, uint32_t insn,
2215 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2217 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
2219 assert(NumOps >= 3 &&
2220 OpInfo[0].RegClass == ARM::rGPRRegClassID &&
2221 OpInfo[1].RegClass == ARM::rGPRRegClassID &&
2222 OpInfo[2].RegClass == ARM::rGPRRegClassID &&
2223 "Expect >= 3 operands and first three as reg operands");
2225 // Build the register operands.
2227 bool FourReg = NumOps > 3 && OpInfo[3].RegClass == ARM::rGPRRegClassID;
2229 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2230 decodeRs(insn))));
2232 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2233 decodeRn(insn))));
2235 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2236 decodeRm(insn))));
2238 if (FourReg)
2239 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2240 decodeRd(insn))));
2242 NumOpsAdded = FourReg ? 4 : 3;
2244 return true;
2247 // A6.3.17 Long multiply, long multiply accumulate, and divide
2249 // t2SMULL, t2UMULL, t2SMLAL, t2UMLAL, t2UMAAL: RdLo RdHi Rn Rm
2250 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2252 // Halfword multiple accumulate long: t2SMLAL<x><y>: RdLo RdHi Rn Rm
2253 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2255 // Dual halfword multiple: t2SMLALD[X], t2SMLSLD[X]: RdLo RdHi Rn Rm
2256 // where RdLo = Inst{15-12} and RdHi = Inst{11-8}
2258 // Signed/Unsigned divide: t2SDIV, t2UDIV: Rs Rn Rm
2259 static bool DisassembleThumb2LongMul(MCInst &MI, unsigned Opcode, uint32_t insn,
2260 unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
2262 const MCOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
2264 assert(NumOps >= 3 &&
2265 OpInfo[0].RegClass == ARM::rGPRRegClassID &&
2266 OpInfo[1].RegClass == ARM::rGPRRegClassID &&
2267 OpInfo[2].RegClass == ARM::rGPRRegClassID &&
2268 "Expect >= 3 operands and first three as reg operands");
2270 bool FourReg = NumOps > 3 && OpInfo[3].RegClass == ARM::rGPRRegClassID;
2272 // Build the register operands.
2274 if (FourReg)
2275 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2276 decodeRd(insn))));
2278 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2279 decodeRs(insn))));
2281 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2282 decodeRn(insn))));
2284 MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
2285 decodeRm(insn))));
2287 if (FourReg)
2288 NumOpsAdded = 4;
2289 else
2290 NumOpsAdded = 3;
2292 return true;
2295 // See A6.3 32-bit Thumb instruction encoding for instruction classes
2296 // corresponding to (op1, op2, op).
2298 // Table A6-9 32-bit Thumb instruction encoding
2299 // op1 op2 op Instruction class, see
2300 // --- ------- -- -----------------------------------------------------------
2301 // 01 00xx0xx - Load/store multiple on page A6-23
2302 // 00xx1xx - Load/store dual, load/store exclusive, table branch on
2303 // page A6-24
2304 // 01xxxxx - Data-processing (shifted register) on page A6-31
2305 // 1xxxxxx - Coprocessor instructions on page A6-40
2306 // 10 x0xxxxx 0 Data-processing (modified immediate) on page A6-15
2307 // x1xxxxx 0 Data-processing (plain binary immediate) on page A6-19
2308 // - 1 Branches and miscellaneous control on page A6-20
2309 // 11 000xxx0 - Store single data item on page A6-30
2310 // 001xxx0 - Advanced SIMD element or structure load/store instructions
2311 // on page A7-27
2312 // 00xx001 - Load byte, memory hints on page A6-28
2313 // 00xx011 - Load halfword, memory hints on page A6-26
2314 // 00xx101 - Load word on page A6-25
2315 // 00xx111 - UNDEFINED
2316 // 010xxxx - Data-processing (register) on page A6-33
2317 // 0110xxx - Multiply, multiply accumulate, and absolute difference on
2318 // page A6-38
2319 // 0111xxx - Long multiply, long multiply accumulate, and divide on
2320 // page A6-39
2321 // 1xxxxxx - Coprocessor instructions on page A6-40
2323 static bool DisassembleThumb2(uint16_t op1, uint16_t op2, uint16_t op,
2324 MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps,
2325 unsigned &NumOpsAdded, BO B) {
2327 switch (op1) {
2328 case 1:
2329 if (slice(op2, 6, 5) == 0) {
2330 if (slice(op2, 2, 2) == 0) {
2331 // Load/store multiple.
2332 return DisassembleThumb2LdStMul(MI, Opcode, insn, NumOps, NumOpsAdded,
2336 // Load/store dual, load/store exclusive, table branch, otherwise.
2337 assert(slice(op2, 2, 2) == 1 && "Thumb2 encoding error!");
2338 if ((ARM::t2LDREX <= Opcode && Opcode <= ARM::t2LDREXH) ||
2339 (ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH)) {
2340 // Load/store exclusive.
2341 return DisassembleThumb2LdStEx(MI, Opcode, insn, NumOps, NumOpsAdded,
2344 if (Opcode == ARM::t2LDRDi8 ||
2345 Opcode == ARM::t2LDRD_PRE || Opcode == ARM::t2LDRD_POST ||
2346 Opcode == ARM::t2STRDi8 ||
2347 Opcode == ARM::t2STRD_PRE || Opcode == ARM::t2STRD_POST) {
2348 // Load/store dual.
2349 return DisassembleThumb2LdStDual(MI, Opcode, insn, NumOps, NumOpsAdded,
2352 if (Opcode == ARM::t2TBB || Opcode == ARM::t2TBH) {
2353 // Table branch.
2354 return DisassembleThumb2TB(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2356 } else if (slice(op2, 6, 5) == 1) {
2357 // Data-processing (shifted register).
2358 return DisassembleThumb2DPSoReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2361 // FIXME: A6.3.18 Coprocessor instructions
2362 // But see ThumbDisassembler::getInstruction().
2364 break;
2365 case 2:
2366 if (op == 0) {
2367 if (slice(op2, 5, 5) == 0)
2368 // Data-processing (modified immediate)
2369 return DisassembleThumb2DPModImm(MI, Opcode, insn, NumOps, NumOpsAdded,
2371 if (Thumb2SaturateOpcode(Opcode))
2372 return DisassembleThumb2Sat(MI, Opcode, insn, NumOpsAdded, B);
2374 // Data-processing (plain binary immediate)
2375 return DisassembleThumb2DPBinImm(MI, Opcode, insn, NumOps, NumOpsAdded,
2378 // Branches and miscellaneous control on page A6-20.
2379 return DisassembleThumb2BrMiscCtrl(MI, Opcode, insn, NumOps, NumOpsAdded,
2381 case 3:
2382 switch (slice(op2, 6, 5)) {
2383 case 0:
2384 // Load/store instructions...
2385 if (slice(op2, 0, 0) == 0) {
2386 if (slice(op2, 4, 4) == 0) {
2387 // Store single data item on page A6-30
2388 return DisassembleThumb2LdSt(false, MI,Opcode,insn,NumOps,NumOpsAdded,
2390 } else {
2391 // FIXME: Advanced SIMD element or structure load/store instructions.
2392 // But see ThumbDisassembler::getInstruction().
2395 } else {
2396 // Table A6-9 32-bit Thumb instruction encoding: Load byte|halfword|word
2397 return DisassembleThumb2LdSt(true, MI, Opcode, insn, NumOps,
2398 NumOpsAdded, B);
2400 break;
2401 case 1:
2402 if (slice(op2, 4, 4) == 0) {
2403 // A6.3.12 Data-processing (register)
2404 return DisassembleThumb2DPReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2405 } else if (slice(op2, 3, 3) == 0) {
2406 // A6.3.16 Multiply, multiply accumulate, and absolute difference
2407 return DisassembleThumb2Mul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
2408 } else {
2409 // A6.3.17 Long multiply, long multiply accumulate, and divide
2410 return DisassembleThumb2LongMul(MI, Opcode, insn, NumOps, NumOpsAdded,
2413 break;
2414 default:
2415 // FIXME: A6.3.18 Coprocessor instructions
2416 // But see ThumbDisassembler::getInstruction().
2418 break;
2421 break;
2422 default:
2423 assert(0 && "Thumb2 encoding error!");
2424 break;
2427 return false;
2430 static bool DisassembleThumbFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
2431 unsigned short NumOps, unsigned &NumOpsAdded, BO Builder) {
2433 uint16_t HalfWord = slice(insn, 31, 16);
2435 if (HalfWord == 0) {
2436 // A6.2 16-bit Thumb instruction encoding
2437 // op = bits[15:10]
2438 uint16_t op = slice(insn, 15, 10);
2439 return DisassembleThumb1(op, MI, Opcode, insn, NumOps, NumOpsAdded,
2440 Builder);
2443 unsigned bits15_11 = slice(HalfWord, 15, 11);
2445 // A6.1 Thumb instruction set encoding
2446 if (!(bits15_11 == 0x1D || bits15_11 == 0x1E || bits15_11 == 0x1F)) {
2447 assert("Bits[15:11] first halfword of Thumb2 instruction is out of range");
2448 return false;
2451 // A6.3 32-bit Thumb instruction encoding
2453 uint16_t op1 = slice(HalfWord, 12, 11);
2454 uint16_t op2 = slice(HalfWord, 10, 4);
2455 uint16_t op = slice(insn, 15, 15);
2457 return DisassembleThumb2(op1, op2, op, MI, Opcode, insn, NumOps, NumOpsAdded,
2458 Builder);