4 #include "AsmUnparser_compat.h"
33 throw Exception(
"instruction pointer not word aligned", start_va);
34 if (start_va >= 0xffffffff)
35 throw Exception(
"instruction pointer out of range", start_va);
39 unsigned char temp[4];
45 uint32_t c = temp[0] | (temp[1]<<8) | (temp[2]<<16) | (temp[3]<<24);
56 successors->insert(suc2.begin(), suc2.end());
78 ArmInstructionKind kind, ArmInstructionCondition cond, uint32_t insn)
81 ROSE_ASSERT (instruction);
88 for (
int i = 0; i < 4; ++i) {
89 bytes[i] = (insn >> (8 * i)) & 0xFF;
105 ROSE_ASSERT(rdesc!=NULL);
124 std::string
name = useSPSR ?
"spsr" :
"cpsr";
126 ROSE_ASSERT(rdesc!=NULL);
143 uint8_t rsField = (
insn >> 8) & 15;
144 uint8_t rotateCount = rsField * 2;
145 uint32_t immRaw =
insn & 0xFF;
146 if (rotateCount == 0) {
156 bool i = (
insn >> 25) & 1;
157 uint8_t rsField = (
insn >> 8) & 15;
158 uint8_t rmField =
insn & 15;
159 uint8_t shiftCount = (
insn >> 7) & 31;
160 uint8_t shiftCountOr32 = shiftCount == 0 ? 32 : shiftCount;
163 }
else if ((
insn & 0xFF0) == 0) {
165 }
else if ((
insn & 0x070) == 0) {
167 }
else if ((
insn & 0x0F0) == 0x010) {
169 }
else if ((
insn & 0x070) == 0x020) {
171 }
else if ((
insn & 0x0F0) == 0x030) {
173 }
else if ((
insn & 0x070) == 0x040) {
175 }
else if ((
insn & 0x0F0) == 0x050) {
177 }
else if ((
insn & 0xFF0) == 0x060) {
179 }
else if ((
insn & 0x070) == 0x060) {
181 }
else if ((
insn & 0x0F0) == 0x070) {
188 #define MAKE_INSN0(Mne, CondPos) (makeInstructionWithoutOperands(ip, #Mne, (CondPos), arm_##Mne, cond, insn))
189 #define MAKE_INSN1(Mne, CondPos, Op1) (SageBuilderAsm::appendOperand(MAKE_INSN0(Mne, CondPos), (Op1)))
190 #define MAKE_INSN2(Mne, CondPos, Op1, Op2) (SageBuilderAsm::appendOperand(MAKE_INSN1(Mne, CondPos, Op1), (Op2)))
191 #define MAKE_INSN3(Mne, CondPos, Op1, Op2, Op3) (SageBuilderAsm::appendOperand(MAKE_INSN2(Mne, CondPos, Op1, Op2), (Op3)))
192 #define MAKE_INSN4(Mne, CondPos, Op1, Op2, Op3, Op4) (SageBuilderAsm::appendOperand(MAKE_INSN3(Mne, CondPos, Op1, Op2, Op3), (Op4)))
198 switch ((s ? 16 : 0) | opcode) {
199 case 0x00:
return MAKE_INSN3(and, 3, rd, rn, rhsOperand);
200 case 0x01:
return MAKE_INSN3(eor, 3, rd, rn, rhsOperand);
201 case 0x02:
return MAKE_INSN3(sub, 3, rd, rn, rhsOperand);
202 case 0x03:
return MAKE_INSN3(rsb, 3, rd, rn, rhsOperand);
204 case 0x05:
return MAKE_INSN3(adc, 3, rd, rn, rhsOperand);
205 case 0x06:
return MAKE_INSN3(sbc, 3, rd, rn, rhsOperand);
206 case 0x07:
return MAKE_INSN3(rsc, 3, rd, rn, rhsOperand);
207 case 0x08: ROSE_ASSERT (!
"Not a data processing insn");
208 case 0x09: ROSE_ASSERT (!
"Not a data processing insn");
209 case 0x0A: ROSE_ASSERT (!
"Not a data processing insn");
210 case 0x0B: ROSE_ASSERT (!
"Not a data processing insn");
211 case 0x0C:
return MAKE_INSN3(orr, 3, rd, rn, rhsOperand);
212 case 0x0D:
return MAKE_INSN2(mov, 3, rd, rhsOperand);
213 case 0x0E:
return MAKE_INSN3(bic, 3, rd, rn, rhsOperand);
214 case 0x0F:
return MAKE_INSN2(mvn, 3, rd, rhsOperand);
215 case 0x10:
return MAKE_INSN3(ands, 3, rd, rn, rhsOperand);
216 case 0x11:
return MAKE_INSN3(eors, 3, rd, rn, rhsOperand);
217 case 0x12:
return MAKE_INSN3(subs, 3, rd, rn, rhsOperand);
218 case 0x13:
return MAKE_INSN3(rsbs, 3, rd, rn, rhsOperand);
219 case 0x14:
return MAKE_INSN3(adds, 3, rd, rn, rhsOperand);
220 case 0x15:
return MAKE_INSN3(adcs, 3, rd, rn, rhsOperand);
221 case 0x16:
return MAKE_INSN3(sbcs, 3, rd, rn, rhsOperand);
222 case 0x17:
return MAKE_INSN3(rscs, 3, rd, rn, rhsOperand);
223 case 0x18:
return MAKE_INSN2(tst, 3, rn, rhsOperand);
224 case 0x19:
return MAKE_INSN2(teq, 3, rn, rhsOperand);
225 case 0x1A:
return MAKE_INSN2(cmp, 3, rn, rhsOperand);
226 case 0x1B:
return MAKE_INSN2(cmn, 3, rn, rhsOperand);
227 case 0x1C:
return MAKE_INSN3(orrs, 3, rd, rn, rhsOperand);
228 case 0x1D:
return MAKE_INSN2(movs, 3, rd, rhsOperand);
229 case 0x1E:
return MAKE_INSN3(bics, 3, rd, rn, rhsOperand);
230 case 0x1F:
return MAKE_INSN2(mvns, 3, rd, rhsOperand);
231 default: ROSE_ASSERT (
false);
240 int32_t val = ((
insn >> 4) & 0xF0) | (
insn & 0xF);
249 int32_t val =
insn & 0xFFFFFF;
252 uint32_t targetAddr =
ip + 8 + val;
259 bool bit25 = (
insn >> 25) & 1;
260 bool p = (
insn >> 24) & 1;
261 bool u = (
insn >> 23) & 1;
262 bool w = (
insn >> 21) & 1;
264 switch ((p ? 4 : 0) | (u ? 2 : 0) | (w ? 1 : 0)) {
285 throw ExceptionArm(
"media instruction not supported",
this);
295 switch ((
insn >> 20) & 15) {
296 case 0x0:
return MAKE_INSN3(mul, 3, rn, rm, rs);
297 case 0x1:
return MAKE_INSN3(muls, 3, rn, rm, rs);
298 case 0x2:
return MAKE_INSN4(mla, 3, rn, rm, rs, rd);
299 case 0x3:
return MAKE_INSN4(mlas, 3, rn, rm, rs, rd);
300 case 0x4:
return MAKE_INSN4(umaal, 3, rd, rn, rm, rs);
301 case 0x5:
throw ExceptionArm(
"bad bits in decodeMultiplyInstruction (0x5)",
this, 20);
302 case 0x6:
throw ExceptionArm(
"bad bits in decodeMultiplyInstruction (0x6)",
this, 20);
303 case 0x7:
throw ExceptionArm(
"bad bits in decodeMultiplyInstruction (0x7)",
this, 20);
304 case 0x8:
return MAKE_INSN4(umull, 5, rd, rn, rm, rs);
305 case 0x9:
return MAKE_INSN4(umulls, 5, rd, rn, rm, rs);
306 case 0xA:
return MAKE_INSN4(umlal, 5, rd, rn, rm, rs);
307 case 0xB:
return MAKE_INSN4(umlals, 5, rd, rn, rm, rs);
308 case 0xC:
return MAKE_INSN4(smull, 5, rd, rn, rm, rs);
309 case 0xD:
return MAKE_INSN4(smulls, 5, rd, rn, rm, rs);
310 case 0xE:
return MAKE_INSN4(smlal, 5, rd, rn, rm, rs);
311 case 0xF:
return MAKE_INSN4(smlals, 5, rd, rn, rm, rs);
312 default: ROSE_ASSERT (
false);
321 bool bit5 = (
insn >> 5) & 1;
322 bool bit6 = (
insn >> 6) & 1;
323 bool bit20 = (
insn >> 20) & 1;
324 bool bit21 = (
insn >> 21) & 1;
325 bool bit22 = (
insn >> 22) & 1;
326 bool bit23 = (
insn >> 23) & 1;
327 bool bit24 = (
insn >> 24) & 1;
332 switch ((bit24 ? 4 : 0) | (bit23 ? 2 : 0) | (bit21 ? 1 : 0)) {
334 case 1:
throw ExceptionArm(
"bad bits in decodeExtraLoadStores (1)",
this, 21);
336 case 3:
throw ExceptionArm(
"bad bits in decodeExtraLoadStores (3)",
this, 21);
341 default: ROSE_ASSERT (
false);
344 uint8_t lsh = (bit20 ? 4 : 0) | (bit6 ? 2 : 0) | (bit5 ? 1 : 0);
348 throw ExceptionArm(
"bad bits in decodeExtraLoadStores (0)",
this, 5);
349 case 1:
return MAKE_INSN2(strh, 3, rd, memref);
350 case 2:
return MAKE_INSN2(ldrd, 3, rd, memref);
351 case 3:
return MAKE_INSN2(strd, 3, rd, memref);
354 throw ExceptionArm(
"bad bits in decodeExtraLoadStores (4)",
this, 5);
355 case 5:
return MAKE_INSN2(ldruh, 3, rd, memref);
356 case 6:
return MAKE_INSN2(ldrsb, 3, rd, memref);
357 case 7:
return MAKE_INSN2(ldrsh, 3, rd, memref);
358 default: ROSE_ASSERT (
false);
367 bool bit7 = (
insn >> 7) & 1;
368 bool bit21 = (
insn >> 21) & 1;
369 bool bit22 = (
insn >> 22) & 1;
371 switch ((
insn >> 4) & 7) {
375 bool useSPSR = bit22;
376 uint8_t mask = (
insn >> 16) & 15;
380 bool useSPSR = bit22;
397 case 4:
throw ExceptionArm(
"bad bits in decodeMiscInstruction (4)",
this, 4);
402 uint8_t op = (
insn >> 21) & 3;
404 case 0:
return MAKE_INSN3(qadd, 4, rd, rm, rn);
405 case 1:
return MAKE_INSN3(qsub, 4, rd, rm, rn);
406 case 2:
return MAKE_INSN3(qdadd, 5, rd, rm, rn);
407 case 3:
return MAKE_INSN3(qdsub, 5, rd, rm, rn);
408 default: ROSE_ASSERT (
false);
411 case 6:
throw ExceptionArm(
"bad bits in decodeMiscInstruction (6)",
this, 4);
413 uint16_t imm1 = (
insn >> 8) & 0xFFF;
414 uint16_t imm2 =
insn & 0xF;
415 uint16_t imm = (imm1 << 4) | imm2;
418 default: ROSE_ASSERT (
false);
425 uint8_t op = (
insn >> 21) & 3;
426 bool y = (
insn >> 6) & 1;
427 bool x = (
insn >> 5) & 1;
428 switch ((op << 2) | (x ? 2 : 0) | (y ? 1 : 0)) {
429 case 0x0:
return MAKE_INSN4(smlabb, 6, rd, rm, rs, rn);
430 case 0x1:
return MAKE_INSN4(smlabt, 6, rd, rm, rs, rn);
431 case 0x2:
return MAKE_INSN4(smlatb, 6, rd, rm, rs, rn);
432 case 0x3:
return MAKE_INSN4(smlatt, 6, rd, rm, rs, rn);
433 case 0x4:
return MAKE_INSN4(smlawb, 6, rd, rm, rs, rn);
434 case 0x5:
return MAKE_INSN4(smlawt, 6, rd, rm, rs, rn);
435 case 0x6:
return MAKE_INSN4(smluwb, 6, rd, rm, rs, rn);
436 case 0x7:
return MAKE_INSN4(smluwt, 6, rd, rm, rs, rn);
437 case 0x8:
return MAKE_INSN4(smlalbb, 7, rn, rd, rm, rs);
438 case 0x9:
return MAKE_INSN4(smlalbt, 7, rn, rd, rm, rs);
439 case 0xA:
return MAKE_INSN4(smlaltb, 7, rn, rd, rm, rs);
440 case 0xB:
return MAKE_INSN4(smlaltt, 7, rn, rd, rm, rs);
441 case 0xC:
return MAKE_INSN3(smulbb, 6, rd, rm, rs);
442 case 0xD:
return MAKE_INSN3(smulbt, 6, rd, rm, rs);
443 case 0xE:
return MAKE_INSN3(smultb, 6, rd, rm, rs);
444 case 0xF:
return MAKE_INSN3(smultt, 6, rd, rm, rs);
445 default: ROSE_ASSERT (
false);
456 uint8_t condField = (
insn >> 28) & 0xF;
457 bool bit4 = (
insn >> 4) & 1;
458 bool bit7 = (
insn >> 7) & 1;
459 bool bit9 = (
insn >> 9) & 1;
460 bool bit16 = (
insn >> 16) & 1;
461 bool bit20 = (
insn >> 20) & 1;
462 bool bit21 = (
insn >> 21) & 1;
463 bool bit22 = (
insn >> 22) & 1;
464 bool bit23 = (
insn >> 23) & 1;
465 bool bit24 = (
insn >> 24) & 1;
466 bool bit25 = (
insn >> 25) & 1;
467 bool bit4_and_bit7 = bit4 && bit7;
469 cond = (ArmInstructionCondition)(condField + 1);
470 uint8_t dataProcOpcode = (
insn >> 21) & 15;
471 bool dpIsSpecial = (
insn & 0x01900000) == 0x01000000;
472 switch ((
insn >> 26) & 3) {
474 if ((
insn & 0x0F0000F0U) == 0x00000090U) {
476 }
else if (bit4_and_bit7 && !bit25) {
478 }
else if (dpIsSpecial && bit25) {
481 bool useSPSR = bit22;
482 uint8_t mask = (
insn >> 16) & 15;
488 }
else if (dpIsSpecial && !bit25) {
498 if (!bit4 || !bit25) {
504 bool isTranslated = !bit24 && bit21;
505 switch ((isTranslated ? 4 : 0) | (isLoad ? 2 : 0) | (isByte ? 1 : 0)) {
506 case 0:
return MAKE_INSN2(str, 3, rd, memref);
507 case 1:
return MAKE_INSN2(strb, 3, rd, memref);
508 case 2:
return MAKE_INSN2(ldr, 3, rd, memref);
509 case 3:
return MAKE_INSN2(ldrb, 3, rd, memref);
510 case 4:
return MAKE_INSN2(strt, 3, rd, memref);
511 case 5:
return MAKE_INSN2(strbt, 3, rd, memref);
512 case 6:
return MAKE_INSN2(ldrt, 3, rd, memref);
513 case 7:
return MAKE_INSN2(ldrbt, 3, rd, memref);
514 default: ROSE_ASSERT (
false);
516 }
else if ((
insn & 0x0FF000F0U) == 0x07F000F0U) {
526 for (
int i = 0; i < 16; ++i) {
527 if ((
insn >> i) & 1) {
544 switch (((
insn >> 21) & 62) | bit20) {
545 case 0x0:
return MAKE_INSN2(stmda, 3, rn, regs);
546 case 0x1:
return MAKE_INSN2(ldmda, 3, rn, regs);
549 case 0x4:
return MAKE_INSN2(stmia, 3, rn, regs);
550 case 0x5:
return MAKE_INSN2(ldmia, 3, rn, regs);
553 case 0x8:
return MAKE_INSN2(stmdb, 3, rn, regs);
554 case 0x9:
return MAKE_INSN2(ldmdb, 3, rn, regs);
557 case 0xC:
return MAKE_INSN2(stmib, 3, rn, regs);
558 case 0xD:
return MAKE_INSN2(ldmib, 3, rn, regs);
561 default: ROSE_ASSERT (
false);
565 if ((
insn >> 24) & 1) {
573 if ((
insn & 0x0F000000U) == 0x0F000000U) {
577 throw ExceptionArm(
"coprocessor not supported",
this, 26);
580 default: ROSE_ASSERT (!
"Can't happen");
584 uint16_t opcode1 = (
insn >> 20) & 0xFF;
594 ROSE_ASSERT (!
"CPS not supported");
599 throw ExceptionArm(
"too many unconditional instructions",
this, 32);
604 ROSE_ASSERT (!
"Fell off end of disassemble");