diff options
author | comex | 2015-02-23 00:41:29 -0500 |
---|---|---|
committer | comex | 2015-02-23 00:54:13 -0500 |
commit | b63f1dff9dc736f7fa66f04976436f1f3fe2ac5d (patch) | |
tree | db70eb338a0107fdc70992ea2522fd03f2ecf32e | |
parent | fix some i386 stuff (diff) | |
download | substitute-b63f1dff9dc736f7fa66f04976436f1f3fe2ac5d.tar.gz |
Ban calls within transform regions in threadsafe mode.
-rw-r--r-- | generated/generic-dis-arm.inc.h | 114 | ||||
-rw-r--r-- | generated/generic-dis-arm64.inc.h | 222 | ||||
-rw-r--r-- | generated/generic-dis-thumb.inc.h | 34 | ||||
-rw-r--r-- | generated/generic-dis-thumb2.inc.h | 2599 | ||||
-rw-r--r-- | lib/arm/arch-transform-dis.inc.h | 21 | ||||
-rw-r--r-- | lib/arm/dis-arm.inc.h | 7 | ||||
-rw-r--r-- | lib/arm/dis-thumb.inc.h | 3 | ||||
-rw-r--r-- | lib/arm/dis-thumb2.inc.h | 18 | ||||
-rw-r--r-- | lib/arm64/arch-transform-dis.inc.h | 7 | ||||
-rw-r--r-- | lib/arm64/assemble.h | 4 | ||||
-rw-r--r-- | lib/arm64/dis-main.inc.h | 9 | ||||
-rw-r--r-- | lib/hook-functions.c | 3 | ||||
-rw-r--r-- | lib/jump-dis.c | 4 | ||||
-rw-r--r-- | lib/substitute.h | 8 | ||||
-rw-r--r-- | lib/transform-dis.c | 34 | ||||
-rw-r--r-- | lib/transform-dis.h | 5 | ||||
-rw-r--r-- | lib/x86/arch-transform-dis.inc.h | 9 | ||||
-rw-r--r-- | lib/x86/dis-main.inc.h | 9 | ||||
-rw-r--r-- | test/test-td-simple.c | 5 | ||||
-rw-r--r-- | test/test-transform-dis.c | 12 | ||||
-rw-r--r-- | test/transform-dis-cases-i386.S | 12 |
21 files changed, 2104 insertions, 1035 deletions
diff --git a/generated/generic-dis-arm.inc.h b/generated/generic-dis-arm.inc.h index 88ce9ab..f98a869 100644 --- a/generated/generic-dis-arm.inc.h +++ b/generated/generic-dis-arm.inc.h @@ -1,5 +1,5 @@ /* Generated code; do not edit! - generated by tables/gen.js from imaon2 '2b8112204067abe3d0643e23c2486656841ecafe-dirty' + generated by tables/gen.js from imaon2 'f0e220720bbfb8f8e00e76af56806a28fc8739a2' https://github.com/comex/imaon2 arguments: '--gen-hook-disassembler -n _arm --dis-pattern=P(XXX) out/out-ARM.json' (fair warning: at present the main (Rust) code in that repository is barely @@ -13,6 +13,8 @@ /* GPR_Rn_so_reg_imm_shift_unk_Rd_1_ADDrsi: ADDrsi */ /* GPR_Rn_so_reg_reg_shift_unk_Rd_1_ADDrsr: ADDrsr */ /* adrlabel_label_unk_Rd_1_ADR: ADR */ +/* bl_target_func_2_BL: BL, BL_pred */ +/* GPR_func_3_BLX: BLX, BLX_pred, BXJ */ /* GPR_dst_B_2_BX: BX, BX_pred */ /* br_target_target_pred_p_B_1_Bcc: Bcc */ /* addr_offset_none_addr_unk_Rt_13_LDA: LDA, LDAB, LDAEX, LDAEXB, LDAEXD, LDAEXH, LDAH, LDREX, LDREXB, LDREXD, LDREXH, SWP, SWPB */ @@ -857,9 +859,11 @@ } case 4: goto insn_GPR_Rn_reglist_regs_S_16_STMDA; /* 0x08000000 | 0xf1efffff */ - case 5: - case 7: - return P(unidentified)(ctx); + case 5: { + insn_bl_target_func_2_BL:; + struct bitslice func = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,24}}}; + return P(bl_target_func_2_BL)(ctx, func); /* 0x0b000000 | 0xf0ffffff */ + } case 6: { switch ((op >> 9) & 0x7) { case 0: @@ -880,6 +884,8 @@ } } } + case 7: + return P(unidentified)(ctx); } } case 17: @@ -924,10 +930,11 @@ } } case 2: { - if ((op & 0xe100000) == 0x8100000) { + switch ((op >> 25) & 0x1) { + case 0: goto insn_GPR_Rn_reglist_regs_16_LDMDA; /* 0x08100000 | 0xf1efffff */ - } else { - return P(unidentified)(ctx); + case 1: + goto insn_bl_target_func_2_BL; /* 0x0b000000 | 0xf0ffffff */ } } case 3: { @@ -942,7 +949,7 @@ case 18: { switch ((op >> 26) & 0x3) { case 0: { - switch ((op >> 5) & 0x3) { + switch ((op >> 5) & 0x7) { case 0: { if ((op & 0xffffff0) == 0x12fff10) { struct bitslice dst = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,4}}}; @@ -951,8 +958,20 @@ return P(unidentified)(ctx); } } - case 1: - case 3: { + case 1: { + if ((op & 0xfffffe0) == 0x12fff20) { + struct bitslice func = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,4}}}; + return P(GPR_func_3_BLX)(ctx, func); /* 0x012fff20 | 0xf000001f */ + } else { + return P(unidentified)(ctx); + } + } + case 2: + case 3: + case 4: + return P(unidentified)(ctx); + case 5: + case 7: { if ((op & 0xf3000b0) == 0x12000b0) { insn_GPR_Rt_addrmode3_pre_addr_S_2_STRD_PRE:; struct bitslice addr = {.nruns = 5, .runs = (struct bitslice_run[]) {{0,0,4}, {8,4,4}, {16,9,4}, {22,13,1}, {23,8,1}}}; @@ -962,7 +981,7 @@ return P(unidentified)(ctx); } } - case 2: { + case 6: { if ((op & 0xf2000f0) == 0x12000d0) { insn_addrmode3_pre_addr_unk_Rt_4_LDRD_PRE:; struct bitslice addr = {.nruns = 5, .runs = (struct bitslice_run[]) {{0,0,4}, {8,4,4}, {16,9,4}, {22,13,1}, {23,8,1}}}; @@ -995,10 +1014,11 @@ } } case 2: { - if ((op & 0xe100000) == 0x8000000) { + switch ((op >> 25) & 0x1) { + case 0: goto insn_GPR_Rn_reglist_regs_S_16_STMDA; /* 0x08000000 | 0xf1efffff */ - } else { - return P(unidentified)(ctx); + case 1: + goto insn_bl_target_func_2_BL; /* 0x0b000000 | 0xf0ffffff */ } } case 3: { @@ -1054,10 +1074,11 @@ } } case 2: { - if ((op & 0xe100000) == 0x8100000) { + switch ((op >> 25) & 0x1) { + case 0: goto insn_GPR_Rn_reglist_regs_16_LDMDA; /* 0x08100000 | 0xf1efffff */ - } else { - return P(unidentified)(ctx); + case 1: + goto insn_bl_target_func_2_BL; /* 0x0b000000 | 0xf0ffffff */ } } case 3: { @@ -1120,8 +1141,7 @@ case 4: goto insn_GPR_Rn_reglist_regs_S_16_STMDA; /* 0x08000000 | 0xf1efffff */ case 5: - case 7: - return P(unidentified)(ctx); + goto insn_bl_target_func_2_BL; /* 0x0b000000 | 0xf0ffffff */ case 6: { switch ((op >> 9) & 0x7) { case 0: @@ -1136,6 +1156,8 @@ goto insn_addrmode5_addr_8_LDC2L_OFFSET; /* 0x0d000a00 | 0xf0cff1ff */ } } + case 7: + return P(unidentified)(ctx); } } case 22: { @@ -1172,10 +1194,11 @@ } } case 2: { - if ((op & 0xe100000) == 0x8000000) { + switch ((op >> 25) & 0x1) { + case 0: goto insn_GPR_Rn_reglist_regs_S_16_STMDA; /* 0x08000000 | 0xf1efffff */ - } else { - return P(unidentified)(ctx); + case 1: + goto insn_bl_target_func_2_BL; /* 0x0b000000 | 0xf0ffffff */ } } case 3: { @@ -1271,10 +1294,11 @@ } } case 2: { - if ((op & 0xe100000) == 0x8000000) { + switch ((op >> 25) & 0x1) { + case 0: goto insn_GPR_Rn_reglist_regs_S_16_STMDA; /* 0x08000000 | 0xf1efffff */ - } else { - return P(unidentified)(ctx); + case 1: + goto insn_bl_target_func_2_BL; /* 0x0b000000 | 0xf0ffffff */ } } case 3: { @@ -1365,10 +1389,11 @@ } } case 2: { - if ((op & 0xe100000) == 0x8100000) { + switch ((op >> 25) & 0x1) { + case 0: goto insn_GPR_Rn_reglist_regs_16_LDMDA; /* 0x08100000 | 0xf1efffff */ - } else { - return P(unidentified)(ctx); + case 1: + goto insn_bl_target_func_2_BL; /* 0x0b000000 | 0xf0ffffff */ } } case 3: { @@ -1487,10 +1512,11 @@ case 4: goto insn_GPR_Rn_reglist_regs_S_16_STMDA; /* 0x08000000 | 0xf1efffff */ case 5: - case 7: - return P(unidentified)(ctx); + goto insn_bl_target_func_2_BL; /* 0x0b000000 | 0xf0ffffff */ case 6: goto insn_addrmode5_pre_addr_S_4_STC2L_PRE; /* 0x0d200000 | 0xf0cfffff */ + case 7: + return P(unidentified)(ctx); } } case 27: { @@ -1591,10 +1617,11 @@ case 4: goto insn_GPR_Rn_reglist_regs_16_LDMDA; /* 0x08100000 | 0xf1efffff */ case 5: - case 7: - return P(unidentified)(ctx); + goto insn_bl_target_func_2_BL; /* 0x0b000000 | 0xf0ffffff */ case 6: goto insn_addrmode5_pre_addr_4_LDC2L_PRE; /* 0x0d300000 | 0xf0cfffff */ + case 7: + return P(unidentified)(ctx); } } case 28: { @@ -1674,10 +1701,11 @@ } } case 2: { - if ((op & 0xe100000) == 0x8000000) { + switch ((op >> 25) & 0x1) { + case 0: goto insn_GPR_Rn_reglist_regs_S_16_STMDA; /* 0x08000000 | 0xf1efffff */ - } else { - return P(unidentified)(ctx); + case 1: + goto insn_bl_target_func_2_BL; /* 0x0b000000 | 0xf0ffffff */ } } case 3: { @@ -1783,10 +1811,11 @@ } } case 2: { - if ((op & 0xe100000) == 0x8000000) { + switch ((op >> 25) & 0x1) { + case 0: goto insn_GPR_Rn_reglist_regs_S_16_STMDA; /* 0x08000000 | 0xf1efffff */ - } else { - return P(unidentified)(ctx); + case 1: + goto insn_bl_target_func_2_BL; /* 0x0b000000 | 0xf0ffffff */ } } case 3: { @@ -1875,10 +1904,11 @@ } } case 2: { - if ((op & 0xe100000) == 0x8100000) { + switch ((op >> 25) & 0x1) { + case 0: goto insn_GPR_Rn_reglist_regs_16_LDMDA; /* 0x08100000 | 0xf1efffff */ - } else { - return P(unidentified)(ctx); + case 1: + goto insn_bl_target_func_2_BL; /* 0x0b000000 | 0xf0ffffff */ } } case 3: { @@ -1915,6 +1945,7 @@ static INLINE tdis_ret P(GPR_Rt_addrmode_imm12_pre_addr_S_2_STRB_PRE_IMM)(struct static INLINE tdis_ret P(GPR_Rt_ldst_so_reg_addr_S_2_STRB_PRE_REG)(struct bitslice ctx, struct bitslice addr, struct bitslice Rt) {} static INLINE tdis_ret P(GPR_Rt_ldst_so_reg_shift_S_1_STRrs)(struct bitslice ctx, struct bitslice shift, struct bitslice Rt) {} static INLINE tdis_ret P(GPR_dst_B_2_BX)(struct bitslice ctx, struct bitslice dst) {} +static INLINE tdis_ret P(GPR_func_3_BLX)(struct bitslice ctx, struct bitslice func) {} static INLINE tdis_ret P(GPRnopc_Rt_4_MCRR)(struct bitslice ctx, struct bitslice Rt) {} static INLINE tdis_ret P(GPRnopc_Rt_addrmode_imm12_addr_S_1_STRBi12)(struct bitslice ctx, struct bitslice addr, struct bitslice Rt) {} static INLINE tdis_ret P(GPRnopc_Rt_ldst_so_reg_shift_S_1_STRBrs)(struct bitslice ctx, struct bitslice shift, struct bitslice Rt) {} @@ -1937,6 +1968,7 @@ static INLINE tdis_ret P(addrmode5_pre_addr_S_4_STC2L_PRE)(struct bitslice ctx, static INLINE tdis_ret P(addrmode_imm12_addr_unk_Rt_2_LDRBi12)(struct bitslice ctx, struct bitslice addr, struct bitslice Rt) {} static INLINE tdis_ret P(addrmode_imm12_pre_addr_unk_Rt_2_LDRB_PRE_IMM)(struct bitslice ctx, struct bitslice addr, struct bitslice Rt) {} static INLINE tdis_ret P(adrlabel_label_unk_Rd_1_ADR)(struct bitslice ctx, struct bitslice label, struct bitslice Rd) {} +static INLINE tdis_ret P(bl_target_func_2_BL)(struct bitslice ctx, struct bitslice func) {} static INLINE tdis_ret P(br_target_target_pred_p_B_1_Bcc)(struct bitslice ctx, struct bitslice target, struct bitslice p) {} static INLINE tdis_ret P(ldst_so_reg_addr_unk_Rt_2_LDRB_PRE_REG)(struct bitslice ctx, struct bitslice addr, struct bitslice Rt) {} static INLINE tdis_ret P(ldst_so_reg_shift_unk_Rt_2_LDRBrs)(struct bitslice ctx, struct bitslice shift, struct bitslice Rt) {} diff --git a/generated/generic-dis-arm64.inc.h b/generated/generic-dis-arm64.inc.h index 26ca52c..62f0213 100644 --- a/generated/generic-dis-arm64.inc.h +++ b/generated/generic-dis-arm64.inc.h @@ -1,5 +1,5 @@ /* Generated code; do not edit! - generated by tables/gen.js from imaon2 '2b8112204067abe3d0643e23c2486656841ecafe-dirty' + generated by tables/gen.js from imaon2 'f0e220720bbfb8f8e00e76af56806a28fc8739a2' https://github.com/comex/imaon2 arguments: '--gen-hook-disassembler --dis-pattern=P(XXX) out/out-AArch64.json' (fair warning: at present the main (Rust) code in that repository is barely @@ -12,41 +12,17 @@ /* adrplabel_label_unk_Xd_1_ADRP: ADRP */ /* am_b_target_addr_B_1_B: B */ /* am_bl_target_addr_1_BL: BL */ +/* GPR64_Rn_2_BLR: BLR, RET */ /* ccode_cond_am_brcond_target_B_1_Bcc: Bcc */ /* am_brcond_target_B_4_CBNZW: CBNZW, CBNZX, CBZW, CBZX */ /* am_ldrlit_label_unk_Rt_6_LDRDl: LDRDl, LDRQl, LDRSWl, LDRSl, LDRWl, LDRXl */ -/* GPR64_Rn_1_RET: RET */ /* am_tbrcond_target_B_4_TBNZW: TBNZW, TBNZX, TBZW, TBZX */ - switch ((op >> 26) & 0x1f) { - case 0: - case 1: - case 2: - case 3: - case 8: - case 9: - case 10: - case 11: - case 14: - case 15: - case 16: - case 17: - case 18: - case 19: - case 24: - case 25: - case 26: - case 27: - case 29: - case 30: - case 31: - return P(unidentified)(ctx); - case 4: - case 12: - case 20: - case 28: { - switch ((op >> 31) & 0x1) { + switch ((op >> 29) & 0x7) { + case 0: { + switch ((op >> 26) & 0x3) { case 0: { if ((op & 0x9f000000) == 0x10000000) { + insn_adrlabel_label_unk_Xd_1_ADR:; struct bitslice Xd = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,5}}}; struct bitslice label = {.nruns = 2, .runs = (struct bitslice_run[]) {{5,2,19}, {29,0,2}}}; return P(adrlabel_label_unk_Xd_1_ADR)(ctx, Xd, label); /* 0x10000000 | 0x60ffffff */ @@ -55,42 +31,114 @@ } } case 1: { - if ((op & 0x9f000000) == 0x90000000) { - struct bitslice Xd = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,5}}}; - struct bitslice label = {.nruns = 2, .runs = (struct bitslice_run[]) {{5,2,19}, {29,0,2}}}; - return P(adrplabel_label_unk_Xd_1_ADRP)(ctx, Xd, label); /* 0x90000000 | 0x60ffffff */ + if ((op & 0xfc000000) == 0x14000000) { + struct bitslice addr = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,26}}}; + return P(am_b_target_addr_B_1_B)(ctx, addr); /* 0x14000000 | 0x03ffffff */ + } else { + return P(unidentified)(ctx); + } + } + case 2: + case 3: { + if ((op & 0xbb000000) == 0x18000000) { + insn_am_ldrlit_label_unk_Rt_6_LDRDl:; + struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,5}}}; + struct bitslice label = {.nruns = 1, .runs = (struct bitslice_run[]) {{5,0,19}}}; + return P(am_ldrlit_label_unk_Rt_6_LDRDl)(ctx, Rt, label); /* 0x18000000 | 0x44ffffff */ } else { return P(unidentified)(ctx); } } } } - case 5: { - switch ((op >> 31) & 0x1) { + case 1: { + switch ((op >> 25) & 0x3) { case 0: { - struct bitslice addr = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,26}}}; - return P(am_b_target_addr_B_1_B)(ctx, addr); /* 0x14000000 | 0x03ffffff */ + if ((op & 0x9f000000) == 0x10000000) { + goto insn_adrlabel_label_unk_Xd_1_ADR; /* 0x10000000 | 0x60ffffff */ + } else { + return P(unidentified)(ctx); + } } - case 1: { - struct bitslice addr = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,26}}}; - return P(am_bl_target_addr_1_BL)(ctx, addr); /* 0x94000000 | 0x03ffffff */ + case 1: + return P(unidentified)(ctx); + case 2: { + if ((op & 0x7e000000) == 0x34000000) { + insn_am_brcond_target_B_4_CBNZW:; + struct bitslice target = {.nruns = 1, .runs = (struct bitslice_run[]) {{5,0,19}}}; + return P(am_brcond_target_B_4_CBNZW)(ctx, target); /* 0x34000000 | 0x81ffffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + if ((op & 0x7e000000) == 0x36000000) { + insn_am_tbrcond_target_B_4_TBNZW:; + struct bitslice target = {.nruns = 1, .runs = (struct bitslice_run[]) {{5,0,14}}}; + return P(am_tbrcond_target_B_4_TBNZW)(ctx, target); /* 0x36000000 | 0x81ffffff */ + } else { + return P(unidentified)(ctx); + } } } } - case 6: - case 7: { - switch ((op >> 31) & 0x1) { + case 2: { + switch ((op >> 26) & 0x3) { case 0: { + if ((op & 0x9f000000) == 0x10000000) { + goto insn_adrlabel_label_unk_Xd_1_ADR; /* 0x10000000 | 0x60ffffff */ + } else { + return P(unidentified)(ctx); + } + } + case 1: { + if ((op & 0xff000010) == 0x54000000) { + struct bitslice cond = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,4}}}; + struct bitslice target = {.nruns = 1, .runs = (struct bitslice_run[]) {{5,0,19}}}; + return P(ccode_cond_am_brcond_target_B_1_Bcc)(ctx, cond, target); /* 0x54000000 | 0x00ffffef */ + } else { + return P(unidentified)(ctx); + } + } + case 2: + case 3: { if ((op & 0xbb000000) == 0x18000000) { - insn_am_ldrlit_label_unk_Rt_6_LDRDl:; - struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,5}}}; - struct bitslice label = {.nruns = 1, .runs = (struct bitslice_run[]) {{5,0,19}}}; - return P(am_ldrlit_label_unk_Rt_6_LDRDl)(ctx, Rt, label); /* 0x18000000 | 0x44ffffff */ + goto insn_am_ldrlit_label_unk_Rt_6_LDRDl; /* 0x18000000 | 0x44ffffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } + case 3: { + if ((op & 0x9f000000) == 0x10000000) { + goto insn_adrlabel_label_unk_Xd_1_ADR; /* 0x10000000 | 0x60ffffff */ + } else { + return P(unidentified)(ctx); + } + } + case 4: { + switch ((op >> 26) & 0x3) { + case 0: { + if ((op & 0x9f000000) == 0x90000000) { + insn_adrplabel_label_unk_Xd_1_ADRP:; + struct bitslice Xd = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,5}}}; + struct bitslice label = {.nruns = 2, .runs = (struct bitslice_run[]) {{5,2,19}, {29,0,2}}}; + return P(adrplabel_label_unk_Xd_1_ADRP)(ctx, Xd, label); /* 0x90000000 | 0x60ffffff */ } else { return P(unidentified)(ctx); } } case 1: { + if ((op & 0xfc000000) == 0x94000000) { + struct bitslice addr = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,26}}}; + return P(am_bl_target_addr_1_BL)(ctx, addr); /* 0x94000000 | 0x03ffffff */ + } else { + return P(unidentified)(ctx); + } + } + case 2: + case 3: { if ((op & 0xfb000000) == 0x98000000) { goto insn_am_ldrlit_label_unk_Rt_6_LDRDl; /* 0x98000000 | 0x04ffffff */ } else { @@ -99,50 +147,84 @@ } } } - case 13: { - switch ((op >> 25) & 0x1) { + case 5: { + switch ((op >> 25) & 0x3) { case 0: { - struct bitslice target = {.nruns = 1, .runs = (struct bitslice_run[]) {{5,0,19}}}; - return P(am_brcond_target_B_4_CBNZW)(ctx, target); /* 0x34000000 | 0x81ffffff */ + if ((op & 0x9f000000) == 0x90000000) { + goto insn_adrplabel_label_unk_Xd_1_ADRP; /* 0x90000000 | 0x60ffffff */ + } else { + return P(unidentified)(ctx); + } } - case 1: { - struct bitslice target = {.nruns = 1, .runs = (struct bitslice_run[]) {{5,0,14}}}; - return P(am_tbrcond_target_B_4_TBNZW)(ctx, target); /* 0x36000000 | 0x81ffffff */ + case 1: + return P(unidentified)(ctx); + case 2: { + if ((op & 0x7e000000) == 0x34000000) { + goto insn_am_brcond_target_B_4_CBNZW; /* 0x34000000 | 0x81ffffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + if ((op & 0x7e000000) == 0x36000000) { + goto insn_am_tbrcond_target_B_4_TBNZW; /* 0x36000000 | 0x81ffffff */ + } else { + return P(unidentified)(ctx); + } } } } - case 21: { - switch ((op >> 25) & 0x1) { - case 0: { - if ((op & 0xff000010) == 0x54000000) { - struct bitslice cond = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,4}}}; - struct bitslice target = {.nruns = 1, .runs = (struct bitslice_run[]) {{5,0,19}}}; - return P(ccode_cond_am_brcond_target_B_1_Bcc)(ctx, cond, target); /* 0x54000000 | 0x00ffffef */ + case 6: { + switch ((op >> 22) & 0xf) { + case 0: + case 1: + case 2: + case 3: { + if ((op & 0x9f000000) == 0x90000000) { + goto insn_adrplabel_label_unk_Xd_1_ADRP; /* 0x90000000 | 0x60ffffff */ } else { return P(unidentified)(ctx); } } - case 1: { - if ((op & 0xfffffc1f) == 0xd65f0000) { + case 4: + case 5: + case 6: + case 7: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + return P(unidentified)(ctx); + case 8: { + if ((op & 0xfffffc1f) == 0xd63f0000) { + insn_GPR64_Rn_2_BLR:; struct bitslice Rn = {.nruns = 1, .runs = (struct bitslice_run[]) {{5,0,5}}}; - return P(GPR64_Rn_1_RET)(ctx, Rn); /* 0xd65f0000 | 0x000003e0 */ + return P(GPR64_Rn_2_BLR)(ctx, Rn); /* 0xd63f0000 | 0x000003e0 */ + } else { + return P(unidentified)(ctx); + } + } + case 9: { + if ((op & 0xfffffc1f) == 0xd65f0000) { + goto insn_GPR64_Rn_2_BLR; /* 0xd65f0000 | 0x000003e0 */ } else { return P(unidentified)(ctx); } } } } - case 22: - case 23: { - if ((op & 0xbb000000) == 0x18000000) { - goto insn_am_ldrlit_label_unk_Rt_6_LDRDl; /* 0x18000000 | 0x44ffffff */ + case 7: { + if ((op & 0x9f000000) == 0x90000000) { + goto insn_adrplabel_label_unk_Xd_1_ADRP; /* 0x90000000 | 0x60ffffff */ } else { return P(unidentified)(ctx); } } } /* -static INLINE tdis_ret P(GPR64_Rn_1_RET)(struct bitslice ctx, struct bitslice Rn) {} +static INLINE tdis_ret P(GPR64_Rn_2_BLR)(struct bitslice ctx, struct bitslice Rn) {} static INLINE tdis_ret P(adrlabel_label_unk_Xd_1_ADR)(struct bitslice ctx, struct bitslice Xd, struct bitslice label) {} static INLINE tdis_ret P(adrplabel_label_unk_Xd_1_ADRP)(struct bitslice ctx, struct bitslice Xd, struct bitslice label) {} static INLINE tdis_ret P(am_b_target_addr_B_1_B)(struct bitslice ctx, struct bitslice addr) {} diff --git a/generated/generic-dis-thumb.inc.h b/generated/generic-dis-thumb.inc.h index 42c6c20..50d095f 100644 --- a/generated/generic-dis-thumb.inc.h +++ b/generated/generic-dis-thumb.inc.h @@ -1,5 +1,5 @@ /* Generated code; do not edit! - generated by tables/gen.js from imaon2 '2b8112204067abe3d0643e23c2486656841ecafe-dirty' + generated by tables/gen.js from imaon2 'f0e220720bbfb8f8e00e76af56806a28fc8739a2' https://github.com/comex/imaon2 arguments: '--gen-hook-disassembler -n _thumb --dis-pattern=P(XXX) out/out-ARM.json' (fair warning: at present the main (Rust) code in that repository is barely @@ -14,6 +14,7 @@ /* GPR_Rm_1_tADDspr: tADDspr */ /* t_adrlabel_addr_unk_Rd_1_tADR: tADR */ /* t_brtarget_target_B_1_tB: tB */ +/* GPR_func_1_tBLXr: tBLXr */ /* GPR_Rm_B_1_tBX: tBX */ /* t_bcctarget_target_pred_p_B_1_tBcc: tBcc */ /* t_cbtarget_target_B_2_tCBNZ: tCBNZ, tCBZ */ @@ -87,8 +88,9 @@ } } case 3: { - switch ((op >> 8) & 0x1) { - case 0: { + switch ((op >> 7) & 0x3) { + case 0: + case 1: { switch ((op >> 15) & 0x1) { case 0: { if ((op & 0xffffff00) == 0x4600) { @@ -108,7 +110,7 @@ } } } - case 1: { + case 2: { switch ((op >> 15) & 0x1) { case 0: { if ((op & 0xffffff87) == 0x4700) { @@ -127,6 +129,25 @@ } } } + case 3: { + switch ((op >> 15) & 0x1) { + case 0: { + if ((op & 0xffffff87) == 0x4780) { + struct bitslice func = {.nruns = 1, .runs = (struct bitslice_run[]) {{3,0,4}}}; + return P(GPR_func_1_tBLXr)(ctx, func); /* 0x00004780 | 0x00000078 */ + } else { + return P(unidentified)(ctx); + } + } + case 1: { + if ((op & 0xfffff800) == 0xc000) { + goto insn_tGPR_Rn_reglist_regs_S_1_tSTMIA_UPD; /* 0x0000c000 | 0x000007ff */ + } else { + return P(unidentified)(ctx); + } + } + } + } } } case 4: @@ -228,10 +249,10 @@ } } case 31: { - if ((op & 0xff00) == 0xbf00) { + if ((op & 0xffffff00) == 0xbf00) { struct bitslice mask = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,4}}}; struct bitslice cc = {.nruns = 1, .runs = (struct bitslice_run[]) {{4,0,4}}}; - return P(it_pred_cc_it_mask_mask_1_t2IT)(ctx, mask, cc); /* 0xbf00 | 0x00ff */ + return P(it_pred_cc_it_mask_mask_1_t2IT)(ctx, mask, cc); /* 0x0000bf00 | 0x000000ff */ } else { return P(unidentified)(ctx); } @@ -242,6 +263,7 @@ static INLINE tdis_ret P(GPR_Rm_1_tADDspr)(struct bitslice ctx, struct bitslice static INLINE tdis_ret P(GPR_Rm_B_1_tBX)(struct bitslice ctx, struct bitslice Rm) {} static INLINE tdis_ret P(GPR_Rm_unk_Rd_1_tMOVr)(struct bitslice ctx, struct bitslice Rd, struct bitslice Rm) {} static INLINE tdis_ret P(GPR_Rm_unk_Rdn_1_tADDhirr)(struct bitslice ctx, struct bitslice Rdn, struct bitslice Rm) {} +static INLINE tdis_ret P(GPR_func_1_tBLXr)(struct bitslice ctx, struct bitslice func) {} static INLINE tdis_ret P(it_pred_cc_it_mask_mask_1_t2IT)(struct bitslice ctx, struct bitslice mask, struct bitslice cc) {} static INLINE tdis_ret P(reglist_regs_1_tPOP)(struct bitslice ctx, struct bitslice regs) {} static INLINE tdis_ret P(reglist_regs_S_1_tPUSH)(struct bitslice ctx, struct bitslice regs) {} diff --git a/generated/generic-dis-thumb2.inc.h b/generated/generic-dis-thumb2.inc.h index b685f0d..e4e8ee0 100644 --- a/generated/generic-dis-thumb2.inc.h +++ b/generated/generic-dis-thumb2.inc.h @@ -1,5 +1,5 @@ /* Generated code; do not edit! - generated by tables/gen.js from imaon2 '2b8112204067abe3d0643e23c2486656841ecafe-dirty' + generated by tables/gen.js from imaon2 'f0e220720bbfb8f8e00e76af56806a28fc8739a2' https://github.com/comex/imaon2 arguments: '--gen-hook-disassembler -n _thumb2 --dis-pattern=P(XXX) out/out-ARM.json' (fair warning: at present the main (Rust) code in that repository is barely @@ -16,6 +16,7 @@ /* GPRnopc_Rn_rGPR_Rm_unk_Rd_1_t2ADDrr: t2ADDrr */ /* t2adrlabel_addr_unk_Rd_1_t2ADR: t2ADR */ /* uncondbrtarget_target_B_1_t2B: t2B */ +/* rGPR_func_1_t2BXJ: t2BXJ */ /* brtarget_target_pred_p_B_1_t2Bcc: t2Bcc */ /* addr_offset_none_addr_unk_Rt_11_t2LDA: t2LDA, t2LDAB, t2LDAEX, t2LDAEXB, t2LDAEXD, t2LDAEXH, t2LDAH, t2LDRD_POST, t2LDREXB, t2LDREXD, t2LDREXH */ /* addr_offset_none_addr_4_t2LDC2L_OPTION: t2LDC2L_OPTION, t2LDC2_OPTION, t2LDCL_OPTION, t2LDC_OPTION */ @@ -56,13 +57,16 @@ /* GPR_Rt_t2addrmode_negimm8_addr_S_1_t2STRi8: t2STRi8 */ /* GPR_Rt_t2addrmode_so_reg_addr_S_1_t2STRs: t2STRs */ /* unk_Rm_B_2_t2TBB: t2TBB, t2TBH */ +/* t_bltarget_func_1_tBL: tBL */ +/* t_blxtarget_func_1_tBLXi: tBLXi */ switch ((op >> 20) & 0x1f) { case 0: { switch ((op >> 26) & 0x3) { case 0: case 1: { - switch ((op >> 15) & 0x1) { - case 0: { + switch ((op >> 14) & 0x3) { + case 0: + case 1: { if ((op & 0xfb5f8000) == 0xf20f0000) { insn_t2adrlabel_addr_unk_Rd_1_t2ADR:; struct bitslice addr = {.nruns = 5, .runs = (struct bitslice_run[]) {{0,0,8}, {12,8,3}, {21,12,1}, {23,12,1}, {26,11,1}}}; @@ -78,7 +82,7 @@ } } } - case 1: { + case 2: { switch ((op >> 12) & 0x1) { case 0: { if ((op & 0xf800d000) == 0xf0008000) { @@ -101,6 +105,28 @@ } } } + case 3: { + switch ((op >> 12) & 0x1) { + case 0: { + if ((op & 0xf800d001) == 0xf000c000) { + insn_t_blxtarget_func_1_tBLXi:; + struct bitslice func = {.nruns = 5, .runs = (struct bitslice_run[]) {{1,1,10}, {11,21,1}, {13,22,1}, {16,11,10}, {26,23,1}}}; + return P(t_blxtarget_func_1_tBLXi)(ctx, func); /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } + case 1: { + if ((op & 0xf800d000) == 0xf000d000) { + insn_t_bltarget_func_1_tBL:; + struct bitslice func = {.nruns = 5, .runs = (struct bitslice_run[]) {{0,0,11}, {11,21,1}, {13,22,1}, {16,11,10}, {26,23,1}}}; + return P(t_bltarget_func_1_tBL)(ctx, func); /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } + } + } } } case 2: { @@ -178,29 +204,47 @@ } } case 1: { - switch ((op >> 8) & 0x7) { - case 0: { - switch ((op >> 26) & 0x3) { + switch ((op >> 26) & 0x3) { + case 0: + case 1: { + switch ((op >> 12) & 0x7) { case 0: - case 1: { - switch ((op >> 12) & 0x1) { - case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } + case 2: { + if ((op & 0xf800d000) == 0xf0008000) { + goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); } - case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } + } + case 1: + case 3: { + if ((op & 0xf800d000) == 0xf0009000) { + goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); } + } + case 4: + case 6: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); } } - case 2: { + case 5: + case 7: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } + } + } + case 2: { + switch ((op >> 8) & 0x7) { + case 0: { if ((op & 0xfed00fc0) == 0xf8100000) { insn_t2addrmode_so_reg_addr_unk_Rt_5_t2LDRBs:; struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,2,4}, {4,0,2}, {16,6,4}}}; @@ -217,40 +261,8 @@ } } } + case 1: case 3: { - if ((op & 0xef100010) == 0xee100010) { - insn_unk_Rt_13_VMOVRRD:; - struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; - return P(unk_Rt_13_VMOVRRD)(ctx, Rt); /* 0xee100010 | 0x10efffef */ - } else { - return P(unidentified)(ctx); - } - } - } - } - case 1: - case 3: { - switch ((op >> 26) & 0x3) { - case 0: - case 1: { - switch ((op >> 12) & 0x1) { - case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } - } - case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } - } - } - } - case 2: { switch ((op >> 11) & 0x1) { case 0: { if ((op & 0xfe5f0000) == 0xf81f0000) { @@ -272,36 +284,6 @@ } } } - case 3: { - if ((op & 0xef100010) == 0xee100010) { - goto insn_unk_Rt_13_VMOVRRD; /* 0xee100010 | 0x10efffef */ - } else { - return P(unidentified)(ctx); - } - } - } - } - case 2: { - switch ((op >> 26) & 0x3) { - case 0: - case 1: { - switch ((op >> 12) & 0x1) { - case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } - } - case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } - } - } - } case 2: { if ((op & 0xfe5f0000) == 0xf81f0000) { goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ @@ -309,41 +291,7 @@ return P(unidentified)(ctx); } } - case 3: { - if ((op & 0xff00f7f) == 0xe100a10) { - goto insn_unk_Rt_13_VMOVRRD; /* 0x0e100a10 | 0xf00ff080 */ - } else { - if ((op & 0xef100010) == 0xee100010) { - goto insn_unk_Rt_13_VMOVRRD; /* 0xee100210 | 0x100ff8ef */ - } else { - return P(unidentified)(ctx); - } - } - } - } - } - case 4: { - switch ((op >> 26) & 0x3) { - case 0: - case 1: { - switch ((op >> 12) & 0x1) { - case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } - } - case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } - } - } - } - case 2: { + case 4: { switch ((op >> 11) & 0x1) { case 0: { if ((op & 0xfe5f0000) == 0xf81f0000) { @@ -364,38 +312,8 @@ } } } - case 3: { - if ((op & 0xef100010) == 0xee100010) { - goto insn_unk_Rt_13_VMOVRRD; /* 0xee100010 | 0x10efffef */ - } else { - return P(unidentified)(ctx); - } - } - } - } - case 5: - case 7: { - switch ((op >> 26) & 0x3) { - case 0: - case 1: { - switch ((op >> 12) & 0x1) { - case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } - } - case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } - } - } - } - case 2: { + case 5: + case 7: { switch ((op >> 11) & 0x1) { case 0: { if ((op & 0xfe5f0000) == 0xf81f0000) { @@ -416,37 +334,7 @@ } } } - case 3: { - if ((op & 0xef100010) == 0xee100010) { - goto insn_unk_Rt_13_VMOVRRD; /* 0xee100010 | 0x10efffef */ - } else { - return P(unidentified)(ctx); - } - } - } - } - case 6: { - switch ((op >> 26) & 0x3) { - case 0: - case 1: { - switch ((op >> 12) & 0x1) { - case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } - } - case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } - } - } - } - case 2: { + case 6: { switch ((op >> 11) & 0x1) { case 0: { if ((op & 0xfe5f0000) == 0xf81f0000) { @@ -467,14 +355,20 @@ } } } - case 3: { + } + } + case 3: { + if ((op & 0xff00f7f) == 0xe100a10) { + insn_unk_Rt_13_VMOVRRD:; + struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; + return P(unk_Rt_13_VMOVRRD)(ctx, Rt); /* 0x0e100a10 | 0xf00ff080 */ + } else { if ((op & 0xef100010) == 0xee100010) { - goto insn_unk_Rt_13_VMOVRRD; /* 0xee100010 | 0x10efffef */ + goto insn_unk_Rt_13_VMOVRRD; /* 0xee100010 | 0x100fffef */ } else { return P(unidentified)(ctx); } } - } } } } @@ -514,10 +408,21 @@ } } case 12: + case 14: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } case 13: - case 14: - case 15: - return P(unidentified)(ctx); + case 15: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } } } case 2: { @@ -590,21 +495,39 @@ switch ((op >> 26) & 0x3) { case 0: case 1: { - switch ((op >> 12) & 0x1) { - case 0: { + switch ((op >> 12) & 0x7) { + case 0: + case 2: { if ((op & 0xf800d000) == 0xf0008000) { goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 1: { + case 1: + case 3: { if ((op & 0xf800d000) == 0xf0009000) { goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } + case 4: + case 6: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } + case 5: + case 7: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } } } case 2: { @@ -727,101 +650,158 @@ } } case 4: { - switch ((op >> 26) & 0x7) { + switch ((op >> 25) & 0xf) { case 0: case 1: + case 2: + case 3: + case 13: return P(unidentified)(ctx); - case 2: { - switch ((op >> 25) & 0x1) { - case 0: { - if ((op & 0xfff00000) == 0xe8400000) { - struct bitslice addr = {.nruns = 2, .runs = (struct bitslice_run[]) {{0,0,8}, {16,8,4}}}; - struct bitslice Rd = {.nruns = 1, .runs = (struct bitslice_run[]) {{8,0,4}}}; - struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; - return P(rGPR_Rt_t2addrmode_imm0_1020s4_addr_unk_Rd_S_1_t2STREX)(ctx, addr, Rd, Rt); /* 0xe8400000 | 0x000fffff */ + case 4: { + if ((op & 0xfff00000) == 0xe8400000) { + struct bitslice addr = {.nruns = 2, .runs = (struct bitslice_run[]) {{0,0,8}, {16,8,4}}}; + struct bitslice Rd = {.nruns = 1, .runs = (struct bitslice_run[]) {{8,0,4}}}; + struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; + return P(rGPR_Rt_t2addrmode_imm0_1020s4_addr_unk_Rd_S_1_t2STREX)(ctx, addr, Rd, Rt); /* 0xe8400000 | 0x000fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 5: { + if ((op & 0xffef70f0) == 0xea4f0000) { + insn_GPR_Rm_unk_Rd_1_t2MOVr:; + struct bitslice Rm = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,4}}}; + struct bitslice Rd = {.nruns = 1, .runs = (struct bitslice_run[]) {{8,0,4}}}; + return P(GPR_Rm_unk_Rd_1_t2MOVr)(ctx, Rm, Rd); /* 0xea4f0000 | 0x00108f0f */ + } else { + return P(unidentified)(ctx); + } + } + case 6: + case 14: { + if ((op & 0xff00fd0) == 0xc400b10) { + goto insn_GPR_Rt_8_VMOVDRR; /* 0x0c400b10 | 0xf00ff02f */ + } else { + if ((op & 0xefe00000) == 0xec400000) { + goto insn_GPR_Rt_8_VMOVDRR; /* 0xec400000 | 0x100fffff */ } else { return P(unidentified)(ctx); } } - case 1: { - if ((op & 0xffef70f0) == 0xea4f0000) { - insn_GPR_Rm_unk_Rd_1_t2MOVr:; - struct bitslice Rm = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,4}}}; + } + case 7: + case 15: { + if ((op & 0xef100010) == 0xee000010) { + goto insn_GPR_Rt_8_VMOVDRR; /* 0xee000010 | 0x10efffef */ + } else { + return P(unidentified)(ctx); + } + } + case 8: + case 10: { + switch ((op >> 12) & 0xf) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: { + if ((op & 0xfbef8000) == 0xf04f0000) { + insn_unk_Rd_3_t2MOVTi16:; struct bitslice Rd = {.nruns = 1, .runs = (struct bitslice_run[]) {{8,0,4}}}; - return P(GPR_Rm_unk_Rd_1_t2MOVr)(ctx, Rm, Rd); /* 0xea4f0000 | 0x00108f0f */ + return P(unk_Rd_3_t2MOVTi16)(ctx, Rd); /* 0xf04f0000 | 0x04107fff */ } else { return P(unidentified)(ctx); } } + case 8: + case 10: { + if ((op & 0xf800d000) == 0xf0008000) { + goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } } - } - case 3: - case 7: { - switch ((op >> 25) & 0x1) { - case 0: { - if ((op & 0xff00fd0) == 0xc400b10) { - goto insn_GPR_Rt_8_VMOVDRR; /* 0x0c400b10 | 0xf00ff02f */ + case 9: + case 11: { + if ((op & 0xf800d000) == 0xf0009000) { + goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { - if ((op & 0xefe00000) == 0xec400000) { - goto insn_GPR_Rt_8_VMOVDRR; /* 0xec400000 | 0x100fffff */ - } else { - return P(unidentified)(ctx); - } + return P(unidentified)(ctx); } } - case 1: { - if ((op & 0xef100010) == 0xee000010) { - goto insn_GPR_Rt_8_VMOVDRR; /* 0xee000010 | 0x10efffef */ + case 12: + case 14: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } + case 13: + case 15: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } } } - case 4: - case 5: { - switch ((op >> 15) & 0x1) { - case 0: { - switch ((op >> 25) & 0x1) { - case 0: { - if ((op & 0xfbef8000) == 0xf04f0000) { - insn_unk_Rd_3_t2MOVTi16:; - struct bitslice Rd = {.nruns = 1, .runs = (struct bitslice_run[]) {{8,0,4}}}; - return P(unk_Rd_3_t2MOVTi16)(ctx, Rd); /* 0xf04f0000 | 0x04107fff */ - } else { - return P(unidentified)(ctx); - } - } - case 1: { - if ((op & 0xfb708000) == 0xf2400000) { - goto insn_unk_Rd_3_t2MOVTi16; /* 0xf2400000 | 0x048f7fff */ - } else { - return P(unidentified)(ctx); - } + case 9: + case 11: { + switch ((op >> 12) & 0xf) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: { + if ((op & 0xfb708000) == 0xf2400000) { + goto insn_unk_Rd_3_t2MOVTi16; /* 0xf2400000 | 0x048f7fff */ + } else { + return P(unidentified)(ctx); } + } + case 8: + case 10: { + if ((op & 0xf800d000) == 0xf0008000) { + goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); } } - case 1: { - switch ((op >> 12) & 0x1) { - case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } + case 9: + case 11: { + if ((op & 0xf800d000) == 0xf0009000) { + goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); } - case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } + } + case 12: + case 14: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); } + } + case 13: + case 15: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); } } } } - case 6: { + case 12: { switch ((op >> 8) & 0x7) { case 0: { if ((op & 0xfff00fc0) == 0xf8400000) { @@ -957,10 +937,21 @@ } } case 12: + case 14: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } case 13: - case 14: - case 15: - return P(unidentified)(ctx); + case 15: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } } } case 6: { @@ -1063,46 +1054,65 @@ } case 6: case 14: { - switch ((op >> 26) & 0x3) { - case 0: - case 1: { - switch ((op >> 12) & 0x1) { - case 0: { + switch ((op >> 27) & 0x1) { + case 0: { + switch ((op >> 12) & 0x7) { + case 0: + case 2: { if ((op & 0xf800d000) == 0xf0008000) { goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 1: { + case 1: + case 3: { if ((op & 0xf800d000) == 0xf0009000) { goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } + case 4: + case 6: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } + case 5: + case 7: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } } - } - case 2: { - if ((op & 0xff700000) == 0xe8600000) { - insn_rGPR_Rt_addr_offset_none_addr_S_4_t2STL:; - struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; - struct bitslice addr = {.nruns = 1, .runs = (struct bitslice_run[]) {{16,0,4}}}; - return P(rGPR_Rt_addr_offset_none_addr_S_4_t2STL)(ctx, Rt, addr); /* 0xe8600000 | 0x008fffff */ - } else { - return P(unidentified)(ctx); } } - case 3: { - switch ((op >> 25) & 0x1) { + case 1: { + switch ((op >> 25) & 0x3) { case 0: { + if ((op & 0xff700000) == 0xe8600000) { + insn_rGPR_Rt_addr_offset_none_addr_S_4_t2STL:; + struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; + struct bitslice addr = {.nruns = 1, .runs = (struct bitslice_run[]) {{16,0,4}}}; + return P(rGPR_Rt_addr_offset_none_addr_S_4_t2STL)(ctx, Rt, addr); /* 0xe8600000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 1: + return P(unidentified)(ctx); + case 2: { if ((op & 0xef300000) == 0xec200000) { goto insn_addr_offset_none_addr_postidx_imm8s4_offset_S_4_t2STC2L_POST; /* 0xec200000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } } - case 1: { + case 3: { if ((op & 0xef100010) == 0xee000010) { goto insn_GPR_Rt_8_VMOVDRR; /* 0xee000010 | 0x10efffef */ } else { @@ -1114,46 +1124,65 @@ } } case 7: { - switch ((op >> 26) & 0x3) { - case 0: - case 1: { - switch ((op >> 12) & 0x1) { - case 0: { + switch ((op >> 27) & 0x1) { + case 0: { + switch ((op >> 12) & 0x7) { + case 0: + case 2: { if ((op & 0xf800d000) == 0xf0008000) { goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 1: { + case 1: + case 3: { if ((op & 0xf800d000) == 0xf0009000) { goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } + case 4: + case 6: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } + case 5: + case 7: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } } - } - case 2: { - if ((op & 0xff700000) == 0xe8700000) { - insn_addr_offset_none_addr_unk_Rt_11_t2LDA:; - struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; - struct bitslice addr = {.nruns = 1, .runs = (struct bitslice_run[]) {{16,0,4}}}; - return P(addr_offset_none_addr_unk_Rt_11_t2LDA)(ctx, Rt, addr); /* 0xe8700000 | 0x008fffff */ - } else { - return P(unidentified)(ctx); } } - case 3: { - switch ((op >> 25) & 0x1) { + case 1: { + switch ((op >> 25) & 0x3) { case 0: { + if ((op & 0xff700000) == 0xe8700000) { + insn_addr_offset_none_addr_unk_Rt_11_t2LDA:; + struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; + struct bitslice addr = {.nruns = 1, .runs = (struct bitslice_run[]) {{16,0,4}}}; + return P(addr_offset_none_addr_unk_Rt_11_t2LDA)(ctx, Rt, addr); /* 0xe8700000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 1: + return P(unidentified)(ctx); + case 2: { if ((op & 0xef300000) == 0xec300000) { goto insn_addr_offset_none_addr_postidx_imm8s4_offset_4_t2LDC2L_POST; /* 0xec300000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } } - case 1: { + case 3: { if ((op & 0xef100010) == 0xee100010) { goto insn_unk_Rt_13_VMOVRRD; /* 0xee100010 | 0x10efffef */ } else { @@ -1165,9 +1194,8 @@ } } case 8: { - switch ((op >> 26) & 0x3) { - case 0: - case 1: { + switch ((op >> 27) & 0x1) { + case 0: { switch ((op >> 12) & 0xf) { case 0: case 1: @@ -1200,15 +1228,37 @@ } } case 12: + case 14: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } case 13: - case 14: - case 15: - return P(unidentified)(ctx); + case 15: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } } } - case 2: { - switch ((op >> 28) & 0x1) { - case 0: { + case 1: { + switch ((op >> 25) & 0xf) { + case 0: + case 1: + case 2: + case 3: + case 5: + case 8: + case 9: + case 10: + case 11: + case 13: + return P(unidentified)(ctx); + case 4: { if ((op & 0xffd0a000) == 0xe8800000) { insn_GPR_Rn_reglist_regs_S_4_t2STMDB:; struct bitslice regs = {.nruns = 2, .runs = (struct bitslice_run[]) {{0,0,13}, {14,14,1}}}; @@ -1218,21 +1268,8 @@ return P(unidentified)(ctx); } } - case 1: { - if ((op & 0xffd00000) == 0xf8800000) { - insn_rGPR_Rt_t2addrmode_imm12_addr_S_2_t2STRBi12:; - struct bitslice addr = {.nruns = 2, .runs = (struct bitslice_run[]) {{0,0,12}, {16,13,4}}}; - struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; - return P(rGPR_Rt_t2addrmode_imm12_addr_S_2_t2STRBi12)(ctx, addr, Rt); /* 0xf8800000 | 0x002fffff */ - } else { - return P(unidentified)(ctx); - } - } - } - } - case 3: { - switch ((op >> 25) & 0x1) { - case 0: { + case 6: + case 14: { if ((op & 0xefb00000) == 0xec800000) { insn_addr_offset_none_addr_S_4_t2STC2L_OPTION:; struct bitslice addr = {.nruns = 1, .runs = (struct bitslice_run[]) {{16,0,4}}}; @@ -1241,101 +1278,130 @@ return P(unidentified)(ctx); } } - case 1: { + case 7: + case 15: { if ((op & 0xef100010) == 0xee000010) { goto insn_GPR_Rt_8_VMOVDRR; /* 0xee000010 | 0x10efffef */ } else { return P(unidentified)(ctx); } } + case 12: { + if ((op & 0xffd00000) == 0xf8800000) { + insn_rGPR_Rt_t2addrmode_imm12_addr_S_2_t2STRBi12:; + struct bitslice addr = {.nruns = 2, .runs = (struct bitslice_run[]) {{0,0,12}, {16,13,4}}}; + struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; + return P(rGPR_Rt_t2addrmode_imm12_addr_S_2_t2STRBi12)(ctx, addr, Rt); /* 0xf8800000 | 0x002fffff */ + } else { + return P(unidentified)(ctx); + } + } } } } } case 9: { - switch ((op >> 26) & 0x7) { + switch ((op >> 26) & 0x3) { case 0: - case 1: - return P(unidentified)(ctx); - case 2: { - if ((op & 0xffd00000) == 0xe8900000) { - insn_GPR_Rn_reglist_regs_4_t2LDMDB:; - struct bitslice regs = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,16}}}; - struct bitslice Rn = {.nruns = 1, .runs = (struct bitslice_run[]) {{16,0,4}}}; - return P(GPR_Rn_reglist_regs_4_t2LDMDB)(ctx, regs, Rn); /* 0xe8900000 | 0x002fffff */ - } else { - return P(unidentified)(ctx); + case 1: { + switch ((op >> 12) & 0x7) { + case 0: + case 2: { + if ((op & 0xf800d000) == 0xf0008000) { + goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } } - } - case 3: - case 7: { - switch ((op >> 25) & 0x1) { - case 0: { - if ((op & 0xefb00000) == 0xec900000) { - insn_addr_offset_none_addr_4_t2LDC2L_OPTION:; - struct bitslice addr = {.nruns = 1, .runs = (struct bitslice_run[]) {{16,0,4}}}; - return P(addr_offset_none_addr_4_t2LDC2L_OPTION)(ctx, addr); /* 0xec900000 | 0x104fffff */ + case 1: + case 3: { + if ((op & 0xf800d000) == 0xf0009000) { + goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 1: { - if ((op & 0xef100010) == 0xee100010) { - goto insn_unk_Rt_13_VMOVRRD; /* 0xee100010 | 0x10efffef */ + case 4: + case 6: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } + case 5: + case 7: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } } } - case 4: - case 5: { - switch ((op >> 12) & 0x1) { + case 2: { + switch ((op >> 28) & 0x1) { case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ + if ((op & 0xffd00000) == 0xe8900000) { + insn_GPR_Rn_reglist_regs_4_t2LDMDB:; + struct bitslice regs = {.nruns = 1, .runs = (struct bitslice_run[]) {{0,0,16}}}; + struct bitslice Rn = {.nruns = 1, .runs = (struct bitslice_run[]) {{16,0,4}}}; + return P(GPR_Rn_reglist_regs_4_t2LDMDB)(ctx, regs, Rn); /* 0xe8900000 | 0x002fffff */ } else { return P(unidentified)(ctx); } } case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); + switch ((op >> 16) & 0xf) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: { + if ((op & 0xfed00000) == 0xf8900000) { + insn_t2addrmode_imm12_addr_unk_Rt_5_t2LDRBi12:; + struct bitslice addr = {.nruns = 2, .runs = (struct bitslice_run[]) {{0,0,12}, {16,13,4}}}; + struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; + return P(t2addrmode_imm12_addr_unk_Rt_5_t2LDRBi12)(ctx, addr, Rt); /* 0xf8900000 | 0x012fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 15: { + if ((op & 0xfe5f0000) == 0xf81f0000) { + goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ + } else { + return P(unidentified)(ctx); + } + } } } } } - case 6: { - switch ((op >> 16) & 0xf) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: { - if ((op & 0xfed00000) == 0xf8900000) { - insn_t2addrmode_imm12_addr_unk_Rt_5_t2LDRBi12:; - struct bitslice addr = {.nruns = 2, .runs = (struct bitslice_run[]) {{0,0,12}, {16,13,4}}}; - struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; - return P(t2addrmode_imm12_addr_unk_Rt_5_t2LDRBi12)(ctx, addr, Rt); /* 0xf8900000 | 0x012fffff */ + case 3: { + switch ((op >> 25) & 0x1) { + case 0: { + if ((op & 0xefb00000) == 0xec900000) { + insn_addr_offset_none_addr_4_t2LDC2L_OPTION:; + struct bitslice addr = {.nruns = 1, .runs = (struct bitslice_run[]) {{16,0,4}}}; + return P(addr_offset_none_addr_4_t2LDC2L_OPTION)(ctx, addr); /* 0xec900000 | 0x104fffff */ } else { return P(unidentified)(ctx); } } - case 15: { - if ((op & 0xfe5f0000) == 0xf81f0000) { - goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ + case 1: { + if ((op & 0xef100010) == 0xee100010) { + goto insn_unk_Rt_13_VMOVRRD; /* 0xee100010 | 0x10efffef */ } else { return P(unidentified)(ctx); } @@ -1345,9 +1411,8 @@ } } case 10: { - switch ((op >> 26) & 0x3) { - case 0: - case 1: { + switch ((op >> 27) & 0x1) { + case 0: { switch ((op >> 12) & 0xf) { case 0: case 1: @@ -1380,126 +1445,164 @@ } } case 12: - case 13: - case 14: - case 15: - return P(unidentified)(ctx); - } - } - case 2: { - switch ((op >> 28) & 0x1) { - case 0: { - if ((op & 0xffd0a000) == 0xe8800000) { - goto insn_GPR_Rn_reglist_regs_S_4_t2STMDB; /* 0xe8800000 | 0x002f5fff */ + case 14: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ } else { return P(unidentified)(ctx); } } - case 1: { - if ((op & 0xffd00000) == 0xf8800000) { - goto insn_rGPR_Rt_t2addrmode_imm12_addr_S_2_t2STRBi12; /* 0xf8800000 | 0x002fffff */ + case 13: + case 15: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } } } - case 3: { - switch ((op >> 25) & 0x1) { - case 0: { + case 1: { + switch ((op >> 25) & 0xf) { + case 0: + case 1: + case 2: + case 3: + case 5: + case 8: + case 9: + case 10: + case 11: + case 13: + return P(unidentified)(ctx); + case 4: { + if ((op & 0xffd0a000) == 0xe8800000) { + goto insn_GPR_Rn_reglist_regs_S_4_t2STMDB; /* 0xe8800000 | 0x002f5fff */ + } else { + return P(unidentified)(ctx); + } + } + case 6: + case 14: { if ((op & 0xef300000) == 0xec200000) { goto insn_addr_offset_none_addr_postidx_imm8s4_offset_S_4_t2STC2L_POST; /* 0xec200000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } } - case 1: { + case 7: + case 15: { if ((op & 0xef100010) == 0xee000010) { goto insn_GPR_Rt_8_VMOVDRR; /* 0xee000010 | 0x10efffef */ } else { return P(unidentified)(ctx); } } + case 12: { + if ((op & 0xffd00000) == 0xf8800000) { + goto insn_rGPR_Rt_t2addrmode_imm12_addr_S_2_t2STRBi12; /* 0xf8800000 | 0x002fffff */ + } else { + return P(unidentified)(ctx); + } + } } } } } case 11: { - switch ((op >> 26) & 0x7) { + switch ((op >> 26) & 0x3) { case 0: - case 1: - return P(unidentified)(ctx); - case 2: { - if ((op & 0xffd00000) == 0xe8900000) { - goto insn_GPR_Rn_reglist_regs_4_t2LDMDB; /* 0xe8900000 | 0x002fffff */ - } else { - return P(unidentified)(ctx); + case 1: { + switch ((op >> 12) & 0x7) { + case 0: + case 2: { + if ((op & 0xf800d000) == 0xf0008000) { + goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } } - } - case 3: - case 7: { - switch ((op >> 25) & 0x1) { - case 0: { - if ((op & 0xef300000) == 0xec300000) { - goto insn_addr_offset_none_addr_postidx_imm8s4_offset_4_t2LDC2L_POST; /* 0xec300000 | 0x10cfffff */ + case 1: + case 3: { + if ((op & 0xf800d000) == 0xf0009000) { + goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 1: { - if ((op & 0xef100010) == 0xee100010) { - goto insn_unk_Rt_13_VMOVRRD; /* 0xee100010 | 0x10efffef */ + case 4: + case 6: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } + case 5: + case 7: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } } } - case 4: - case 5: { - switch ((op >> 12) & 0x1) { + case 2: { + switch ((op >> 28) & 0x1) { case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ + if ((op & 0xffd00000) == 0xe8900000) { + goto insn_GPR_Rn_reglist_regs_4_t2LDMDB; /* 0xe8900000 | 0x002fffff */ } else { return P(unidentified)(ctx); } } case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); + switch ((op >> 16) & 0xf) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: { + if ((op & 0xfed00000) == 0xf8900000) { + goto insn_t2addrmode_imm12_addr_unk_Rt_5_t2LDRBi12; /* 0xf8900000 | 0x012fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 15: { + if ((op & 0xfe5f0000) == 0xf81f0000) { + goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ + } else { + return P(unidentified)(ctx); + } + } } } } } - case 6: { - switch ((op >> 16) & 0xf) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: { - if ((op & 0xfed00000) == 0xf8900000) { - goto insn_t2addrmode_imm12_addr_unk_Rt_5_t2LDRBi12; /* 0xf8900000 | 0x012fffff */ + case 3: { + switch ((op >> 25) & 0x1) { + case 0: { + if ((op & 0xef300000) == 0xec300000) { + goto insn_addr_offset_none_addr_postidx_imm8s4_offset_4_t2LDC2L_POST; /* 0xec300000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } } - case 15: { - if ((op & 0xfe5f0000) == 0xf81f0000) { - goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ + case 1: { + if ((op & 0xef100010) == 0xee100010) { + goto insn_unk_Rt_13_VMOVRRD; /* 0xee100010 | 0x10efffef */ } else { return P(unidentified)(ctx); } @@ -1627,10 +1730,21 @@ } } case 12: + case 14: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } case 13: - case 14: - case 15: - return P(unidentified)(ctx); + case 15: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } } } case 6: { @@ -1722,21 +1836,39 @@ } case 4: case 5: { - switch ((op >> 12) & 0x1) { - case 0: { + switch ((op >> 12) & 0x7) { + case 0: + case 2: { if ((op & 0xf800d000) == 0xf0008000) { goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 1: { + case 1: + case 3: { if ((op & 0xf800d000) == 0xf0009000) { goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } + case 4: + case 6: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } + case 5: + case 7: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } } } case 6: { @@ -1779,21 +1911,39 @@ case 1: case 2: case 3: { - switch ((op >> 12) & 0x1) { - case 0: { + switch ((op >> 12) & 0x7) { + case 0: + case 2: { if ((op & 0xf800d000) == 0xf0008000) { goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 1: { + case 1: + case 3: { if ((op & 0xf800d000) == 0xf0009000) { goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } + case 4: + case 6: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } + case 5: + case 7: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } } } case 4: { @@ -1863,9 +2013,8 @@ } } case 16: { - switch ((op >> 26) & 0x3) { - case 0: - case 1: { + switch ((op >> 27) & 0x1) { + case 0: { switch ((op >> 12) & 0xf) { case 0: case 1: @@ -1901,14 +2050,25 @@ } } case 12: + case 14: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } case 13: - case 14: - case 15: - return P(unidentified)(ctx); + case 15: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } } } - case 2: { - switch ((op >> 25) & 0x1) { + case 1: { + switch ((op >> 25) & 0x3) { case 0: { if ((op & 0xffd0a000) == 0xe9000000) { goto insn_GPR_Rn_reglist_regs_S_4_t2STMDB; /* 0xe9000000 | 0x002f5fff */ @@ -1931,34 +2091,32 @@ } } } - } - } - case 3: { - switch ((op >> 29) & 0x7) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: { - if ((op & 0xf200e00) == 0xd000a00) { - insn_addrmode5_addr_8_VLDRD:; - struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; - return P(addrmode5_addr_8_VLDRD)(ctx, addr); /* 0x0d000a00 | 0xf0dff1ff */ - } else { - return P(unidentified)(ctx); + case 2: { + switch ((op >> 29) & 0x7) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: { + if ((op & 0xf200e00) == 0xd000a00) { + insn_addrmode5_addr_8_VLDRD:; + struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; + return P(addrmode5_addr_8_VLDRD)(ctx, addr); /* 0x0d000a00 | 0xf0dff1ff */ + } else { + return P(unidentified)(ctx); + } } - } - case 7: { - if ((op & 0xef300000) == 0xed000000) { + case 7: { insn_addrmode5_addr_S_4_t2STC2L_OFFSET:; struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; return P(addrmode5_addr_S_4_t2STC2L_OFFSET)(ctx, addr); /* 0xed000000 | 0x10cfffff */ - } else { - return P(unidentified)(ctx); + } } } + case 3: + return P(unidentified)(ctx); } } } @@ -2049,10 +2207,21 @@ } } case 12: + case 14: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } case 13: - case 14: - case 15: - return P(unidentified)(ctx); + case 15: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } } } case 6: { @@ -2154,9 +2323,43 @@ } } case 18: { - switch ((op >> 27) & 0x1) { - case 0: { - switch ((op >> 12) & 0x1) { + switch ((op >> 12) & 0xf) { + case 0: + case 1: + case 4: + case 5: { + switch ((op >> 26) & 0x1) { + case 0: { + if ((op & 0xffd0a000) == 0xe9000000) { + goto insn_GPR_Rn_reglist_regs_S_4_t2STMDB; /* 0xe9000000 | 0x002f5fff */ + } else { + return P(unidentified)(ctx); + } + } + case 1: { + if ((op & 0xef300000) == 0xed200000) { + insn_addrmode5_pre_addr_S_4_t2STC2L_PRE:; + struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; + return P(addrmode5_pre_addr_S_4_t2STC2L_PRE)(ctx, addr); /* 0xed200000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } + case 2: + case 3: + case 6: + case 7: { + if ((op & 0xef300000) == 0xed200000) { + goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + case 8: + case 10: { + switch ((op >> 27) & 0x1) { case 0: { if ((op & 0xf800d000) == 0xf0008000) { goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ @@ -2165,28 +2368,65 @@ } } case 1: { + if ((op & 0xef300000) == 0xed200000) { + goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } + case 9: + case 11: { + switch ((op >> 27) & 0x1) { + case 0: { if ((op & 0xf800d000) == 0xf0009000) { goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } + case 1: { + if ((op & 0xef300000) == 0xed200000) { + goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } } } - case 1: { - switch ((op >> 26) & 0x1) { + case 12: + case 14: { + switch ((op >> 27) & 0x1) { case 0: { - if ((op & 0xffd0a000) == 0xe9000000) { - goto insn_GPR_Rn_reglist_regs_S_4_t2STMDB; /* 0xe9000000 | 0x002f5fff */ + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ } else { return P(unidentified)(ctx); } } case 1: { if ((op & 0xef300000) == 0xed200000) { - insn_addrmode5_pre_addr_S_4_t2STC2L_PRE:; - struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; - return P(addrmode5_pre_addr_S_4_t2STC2L_PRE)(ctx, addr); /* 0xed200000 | 0x10cfffff */ + goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } + case 13: + case 15: { + switch ((op >> 27) & 0x1) { + case 0: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } + case 1: { + if ((op & 0xef300000) == 0xed200000) { + goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } @@ -2196,49 +2436,67 @@ } } case 19: { - switch ((op >> 8) & 0x7) { - case 0: { - switch ((op >> 26) & 0x7) { - case 0: - case 1: + switch ((op >> 26) & 0x7) { + case 0: + case 1: + return P(unidentified)(ctx); + case 2: { + if ((op & 0xffd00000) == 0xe9100000) { + goto insn_GPR_Rn_reglist_regs_4_t2LDMDB; /* 0xe9100000 | 0x002fffff */ + } else { return P(unidentified)(ctx); + } + } + case 3: + case 7: { + if ((op & 0xef300000) == 0xed300000) { + insn_addrmode5_pre_addr_4_t2LDC2L_PRE:; + struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; + return P(addrmode5_pre_addr_4_t2LDC2L_PRE)(ctx, addr); /* 0xed300000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + case 4: + case 5: { + switch ((op >> 12) & 0x7) { + case 0: case 2: { - if ((op & 0xffd00000) == 0xe9100000) { - goto insn_GPR_Rn_reglist_regs_4_t2LDMDB; /* 0xe9100000 | 0x002fffff */ + if ((op & 0xf800d000) == 0xf0008000) { + goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 3: - case 7: { - if ((op & 0xef300000) == 0xed300000) { - insn_addrmode5_pre_addr_4_t2LDC2L_PRE:; - struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; - return P(addrmode5_pre_addr_4_t2LDC2L_PRE)(ctx, addr); /* 0xed300000 | 0x10cfffff */ + case 1: + case 3: { + if ((op & 0xf800d000) == 0xf0009000) { + goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } case 4: - case 5: { - switch ((op >> 12) & 0x1) { - case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } - } - case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } + case 6: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); } + } + case 5: + case 7: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); } } - case 6: { + } + } + case 6: { + switch ((op >> 8) & 0x7) { + case 0: { if ((op & 0xfed00fc0) == 0xf8100000) { goto insn_t2addrmode_so_reg_addr_unk_Rt_5_t2LDRBs; /* 0xf8100000 | 0x012ff03f */ } else { @@ -2249,49 +2507,33 @@ } } } - } - } - case 1: - case 3: { - switch ((op >> 26) & 0x7) { - case 0: case 1: - return P(unidentified)(ctx); - case 2: { - if ((op & 0xffd00000) == 0xe9100000) { - goto insn_GPR_Rn_reglist_regs_4_t2LDMDB; /* 0xe9100000 | 0x002fffff */ - } else { - return P(unidentified)(ctx); - } - } - case 3: - case 7: { - if ((op & 0xef300000) == 0xed300000) { - goto insn_addrmode5_pre_addr_4_t2LDC2L_PRE; /* 0xed300000 | 0x10cfffff */ - } else { - return P(unidentified)(ctx); - } - } - case 4: - case 5: { - switch ((op >> 12) & 0x1) { + case 3: { + switch ((op >> 11) & 0x1) { case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ + if ((op & 0xfe5f0000) == 0xf81f0000) { + goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ } else { return P(unidentified)(ctx); } } case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ + if ((op & 0xfed00d00) == 0xf8100900) { + goto insn_addr_offset_none_Rn_t2am_imm8_offset_offset_unk_Rt_5_t2LDRB_POST; /* 0xf8100900 | 0x012ff2ff */ } else { return P(unidentified)(ctx); } } } } - case 6: { + case 2: { + if ((op & 0xfe5f0000) == 0xf81f0000) { + goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ + } else { + return P(unidentified)(ctx); + } + } + case 4: { switch ((op >> 11) & 0x1) { case 0: { if ((op & 0xfe5f0000) == 0xf81f0000) { @@ -2301,115 +2543,123 @@ } } case 1: { - if ((op & 0xfed00d00) == 0xf8100900) { - goto insn_addr_offset_none_Rn_t2am_imm8_offset_offset_unk_Rt_5_t2LDRB_POST; /* 0xf8100900 | 0x012ff2ff */ + if ((op & 0xfed00d00) == 0xf8100c00) { + goto insn_t2addrmode_negimm8_addr_unk_Rt_5_t2LDRBi8; /* 0xf8100c00 | 0x012ff2ff */ } else { return P(unidentified)(ctx); } } } } - } - } - case 2: { - switch ((op >> 26) & 0x3) { - case 0: - case 1: { - switch ((op >> 12) & 0x1) { + case 5: + case 7: { + switch ((op >> 11) & 0x1) { case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ + if ((op & 0xfe5f0000) == 0xf81f0000) { + goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ } else { return P(unidentified)(ctx); } } case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ + if ((op & 0xfed00d00) == 0xf8100d00) { + goto insn_t2addrmode_imm8_pre_addr_unk_Rt_5_t2LDRB_PRE; /* 0xf8100d00 | 0x012ff2ff */ } else { return P(unidentified)(ctx); } } } } - case 2: { - switch ((op >> 28) & 0x1) { + case 6: { + switch ((op >> 11) & 0x1) { case 0: { - if ((op & 0xffd00000) == 0xe9100000) { - goto insn_GPR_Rn_reglist_regs_4_t2LDMDB; /* 0xe9100000 | 0x002fffff */ + if ((op & 0xfe5f0000) == 0xf81f0000) { + goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ } else { return P(unidentified)(ctx); } } case 1: { - if ((op & 0xfe5f0000) == 0xf81f0000) { - goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ + if ((op & 0xfed00f00) == 0xf8100e00) { + goto insn_t2addrmode_posimm8_addr_unk_Rt_5_t2LDRBT; /* 0xf8100e00 | 0x012ff0ff */ } else { return P(unidentified)(ctx); } } } } - case 3: { - if ((op & 0xef300000) == 0xed300000) { - goto insn_addrmode5_pre_addr_4_t2LDC2L_PRE; /* 0xed300000 | 0x10cfffff */ - } else { - return P(unidentified)(ctx); - } - } } } - case 4: { - switch ((op >> 26) & 0x7) { + } + } + case 20: { + switch ((op >> 27) & 0x1) { + case 0: { + switch ((op >> 12) & 0x7) { case 0: - case 1: - return P(unidentified)(ctx); case 2: { - if ((op & 0xffd00000) == 0xe9100000) { - goto insn_GPR_Rn_reglist_regs_4_t2LDMDB; /* 0xe9100000 | 0x002fffff */ + if ((op & 0xf800d000) == 0xf0008000) { + goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 3: - case 7: { - if ((op & 0xef300000) == 0xed300000) { - goto insn_addrmode5_pre_addr_4_t2LDC2L_PRE; /* 0xed300000 | 0x10cfffff */ + case 1: + case 3: { + if ((op & 0xf800d000) == 0xf0009000) { + goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } case 4: - case 5: { - switch ((op >> 12) & 0x1) { - case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } + case 6: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); } - case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } + } + case 5: + case 7: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); } + } + } + } + case 1: { + switch ((op >> 26) & 0x1) { + case 0: { + if ((op & 0xff700000) == 0xe9400000) { + insn_rGPR_Rt_t2addrmode_imm8s4_addr_S_1_t2STRDi8:; + struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; + struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; + return P(rGPR_Rt_t2addrmode_imm8s4_addr_S_1_t2STRDi8)(ctx, addr, Rt); /* 0xe9400000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); } } - case 6: { - switch ((op >> 11) & 0x1) { - case 0: { - if ((op & 0xfe5f0000) == 0xf81f0000) { - goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ + case 1: { + switch ((op >> 29) & 0x7) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: { + if ((op & 0xf200e00) == 0xd000a00) { + goto insn_addrmode5_addr_8_VLDRD; /* 0x0d000a00 | 0xf0dff1ff */ } else { return P(unidentified)(ctx); } } - case 1: { - if ((op & 0xfed00d00) == 0xf8100c00) { - goto insn_t2addrmode_negimm8_addr_unk_Rt_5_t2LDRBi8; /* 0xf8100c00 | 0x012ff2ff */ + case 7: { + if ((op & 0xef300000) == 0xed000000) { + goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } @@ -2418,58 +2668,76 @@ } } } - case 5: - case 7: { - switch ((op >> 26) & 0x7) { + } + } + case 21: + case 29: { + switch ((op >> 27) & 0x1) { + case 0: { + switch ((op >> 12) & 0x7) { case 0: - case 1: - return P(unidentified)(ctx); case 2: { - if ((op & 0xffd00000) == 0xe9100000) { - goto insn_GPR_Rn_reglist_regs_4_t2LDMDB; /* 0xe9100000 | 0x002fffff */ + if ((op & 0xf800d000) == 0xf0008000) { + goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 3: - case 7: { - if ((op & 0xef300000) == 0xed300000) { - goto insn_addrmode5_pre_addr_4_t2LDC2L_PRE; /* 0xed300000 | 0x10cfffff */ + case 1: + case 3: { + if ((op & 0xf800d000) == 0xf0009000) { + goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } case 4: - case 5: { - switch ((op >> 12) & 0x1) { - case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } + case 6: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); } - case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } + } + case 5: + case 7: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); } + } + } + } + case 1: { + switch ((op >> 26) & 0x1) { + case 0: { + if ((op & 0xff700000) == 0xe9500000) { + struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; + struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; + return P(t2addrmode_imm8s4_addr_unk_Rt_1_t2LDRDi8)(ctx, addr, Rt); /* 0xe9500000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); } } - case 6: { - switch ((op >> 11) & 0x1) { - case 0: { - if ((op & 0xfe5f0000) == 0xf81f0000) { - goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ + case 1: { + switch ((op >> 29) & 0x7) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: { + if ((op & 0xf200e00) == 0xd000a00) { + goto insn_addrmode5_addr_8_VLDRD; /* 0x0d000a00 | 0xf0dff1ff */ } else { return P(unidentified)(ctx); } } - case 1: { - if ((op & 0xfed00d00) == 0xf8100d00) { - goto insn_t2addrmode_imm8_pre_addr_unk_Rt_5_t2LDRB_PRE; /* 0xf8100d00 | 0x012ff2ff */ + case 7: { + if ((op & 0xef300000) == 0xed100000) { + goto insn_addrmode5_addr_8_VLDRD; /* 0xed100000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } @@ -2478,80 +2746,161 @@ } } } - case 6: { - switch ((op >> 26) & 0x7) { + } + } + case 22: + case 30: { + switch ((op >> 12) & 0x7) { + case 0: + case 2: { + switch ((op >> 26) & 0x3) { case 0: - case 1: - return P(unidentified)(ctx); + case 1: { + if ((op & 0xf800d000) == 0xf0008000) { + goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } case 2: { - if ((op & 0xffd00000) == 0xe9100000) { - goto insn_GPR_Rn_reglist_regs_4_t2LDMDB; /* 0xe9100000 | 0x002fffff */ + if ((op & 0xff700000) == 0xe9600000) { + insn_rGPR_Rt_t2addrmode_imm8s4_pre_addr_S_1_t2STRD_PRE:; + struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; + struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; + return P(rGPR_Rt_t2addrmode_imm8s4_pre_addr_S_1_t2STRD_PRE)(ctx, addr, Rt); /* 0xe9600000 | 0x008fffff */ } else { return P(unidentified)(ctx); } } - case 3: - case 7: { - if ((op & 0xef300000) == 0xed300000) { - goto insn_addrmode5_pre_addr_4_t2LDC2L_PRE; /* 0xed300000 | 0x10cfffff */ + case 3: { + if ((op & 0xef300000) == 0xed200000) { + goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } } - case 4: - case 5: { - switch ((op >> 12) & 0x1) { - case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } + } + } + case 1: + case 3: { + switch ((op >> 26) & 0x3) { + case 0: + case 1: { + if ((op & 0xf800d000) == 0xf0009000) { + goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); } - case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); - } + } + case 2: { + if ((op & 0xff700000) == 0xe9600000) { + goto insn_rGPR_Rt_t2addrmode_imm8s4_pre_addr_S_1_t2STRD_PRE; /* 0xe9600000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + if ((op & 0xef300000) == 0xed200000) { + goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); } + } + } + } + case 4: + case 6: { + switch ((op >> 26) & 0x3) { + case 0: + case 1: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); } } - case 6: { - switch ((op >> 11) & 0x1) { - case 0: { - if ((op & 0xfe5f0000) == 0xf81f0000) { - goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ - } else { - return P(unidentified)(ctx); - } + case 2: { + if ((op & 0xff700000) == 0xe9600000) { + goto insn_rGPR_Rt_t2addrmode_imm8s4_pre_addr_S_1_t2STRD_PRE; /* 0xe9600000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); } - case 1: { - if ((op & 0xfed00f00) == 0xf8100e00) { - goto insn_t2addrmode_posimm8_addr_unk_Rt_5_t2LDRBT; /* 0xf8100e00 | 0x012ff0ff */ - } else { - return P(unidentified)(ctx); - } + } + case 3: { + if ((op & 0xef300000) == 0xed200000) { + goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } + case 5: + case 7: { + switch ((op >> 26) & 0x3) { + case 0: + case 1: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); } + } + case 2: { + if ((op & 0xff700000) == 0xe9600000) { + goto insn_rGPR_Rt_t2addrmode_imm8s4_pre_addr_S_1_t2STRD_PRE; /* 0xe9600000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + if ((op & 0xef300000) == 0xed200000) { + goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); } } } } } } - case 20: - case 28: { - switch ((op >> 26) & 0x3) { + case 23: + case 31: { + switch ((op >> 12) & 0x7) { case 0: - case 1: { - switch ((op >> 12) & 0x1) { - case 0: { + case 2: { + switch ((op >> 26) & 0x3) { + case 0: + case 1: { if ((op & 0xf800d000) == 0xf0008000) { goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } + case 2: { + if ((op & 0xff700000) == 0xe9700000) { + insn_t2addrmode_imm8s4_pre_addr_unk_Rt_1_t2LDRD_PRE:; + struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; + struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; + return P(t2addrmode_imm8s4_pre_addr_unk_Rt_1_t2LDRD_PRE)(ctx, addr, Rt); /* 0xe9700000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + if ((op & 0xef300000) == 0xed300000) { + goto insn_addrmode5_pre_addr_4_t2LDC2L_PRE; /* 0xed300000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } + case 1: + case 3: { + switch ((op >> 26) & 0x3) { + case 0: case 1: { if ((op & 0xf800d000) == 0xf0009000) { goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ @@ -2559,57 +2908,184 @@ return P(unidentified)(ctx); } } + case 2: { + if ((op & 0xff700000) == 0xe9700000) { + goto insn_t2addrmode_imm8s4_pre_addr_unk_Rt_1_t2LDRD_PRE; /* 0xe9700000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + if ((op & 0xef300000) == 0xed300000) { + goto insn_addrmode5_pre_addr_4_t2LDC2L_PRE; /* 0xed300000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } } } - case 2: { - if ((op & 0xff700000) == 0xe9400000) { - struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; - struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; - return P(rGPR_Rt_t2addrmode_imm8s4_addr_S_1_t2STRDi8)(ctx, addr, Rt); /* 0xe9400000 | 0x008fffff */ - } else { - return P(unidentified)(ctx); + case 4: + case 6: { + switch ((op >> 26) & 0x3) { + case 0: + case 1: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } + case 2: { + if ((op & 0xff700000) == 0xe9700000) { + goto insn_t2addrmode_imm8s4_pre_addr_unk_Rt_1_t2LDRD_PRE; /* 0xe9700000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + if ((op & 0xef300000) == 0xed300000) { + goto insn_addrmode5_pre_addr_4_t2LDC2L_PRE; /* 0xed300000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } } } - case 3: { - switch ((op >> 29) & 0x7) { + case 5: + case 7: { + switch ((op >> 26) & 0x3) { + case 0: + case 1: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } + case 2: { + if ((op & 0xff700000) == 0xe9700000) { + goto insn_t2addrmode_imm8s4_pre_addr_unk_Rt_1_t2LDRD_PRE; /* 0xe9700000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + if ((op & 0xef300000) == 0xed300000) { + goto insn_addrmode5_pre_addr_4_t2LDC2L_PRE; /* 0xed300000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } + } + } + case 24: { + switch ((op >> 12) & 0x7) { + case 0: + case 2: { + switch ((op >> 27) & 0x1f) { case 0: - case 1: case 2: - case 3: case 4: + case 6: + case 8: + case 10: + case 12: + case 14: + case 16: + case 18: + case 20: + case 22: + case 24: + case 26: + case 28: + return P(unidentified)(ctx); + case 1: + case 3: case 5: - case 6: { + case 7: + case 9: + case 11: + case 13: + case 15: + case 17: + case 19: + case 21: + case 23: + case 25: + case 27: { if ((op & 0xf200e00) == 0xd000a00) { goto insn_addrmode5_addr_8_VLDRD; /* 0x0d000a00 | 0xf0dff1ff */ } else { return P(unidentified)(ctx); } } - case 7: { + case 29: + case 31: { if ((op & 0xef300000) == 0xed000000) { goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } } - } - } - } - } - case 21: - case 29: { - switch ((op >> 26) & 0x3) { - case 0: - case 1: { - switch ((op >> 12) & 0x1) { - case 0: { + case 30: { if ((op & 0xf800d000) == 0xf0008000) { goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 1: { + } + } + case 1: + case 3: { + switch ((op >> 27) & 0x1f) { + case 0: + case 2: + case 4: + case 6: + case 8: + case 10: + case 12: + case 14: + case 16: + case 18: + case 20: + case 22: + case 24: + case 26: + case 28: + return P(unidentified)(ctx); + case 1: + case 3: + case 5: + case 7: + case 9: + case 11: + case 13: + case 15: + case 17: + case 19: + case 21: + case 23: + case 25: + case 27: { + if ((op & 0xf200e00) == 0xd000a00) { + goto insn_addrmode5_addr_8_VLDRD; /* 0x0d000a00 | 0xf0dff1ff */ + } else { + return P(unidentified)(ctx); + } + } + case 29: + case 31: { + if ((op & 0xef300000) == 0xed000000) { + goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + case 30: { if ((op & 0xf800d000) == 0xf0009000) { goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { @@ -2618,33 +3094,112 @@ } } } - case 2: { - if ((op & 0xff700000) == 0xe9500000) { - struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; - struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; - return P(t2addrmode_imm8s4_addr_unk_Rt_1_t2LDRDi8)(ctx, addr, Rt); /* 0xe9500000 | 0x008fffff */ - } else { + case 4: + case 6: { + switch ((op >> 27) & 0x1f) { + case 0: + case 2: + case 4: + case 6: + case 8: + case 10: + case 12: + case 14: + case 16: + case 18: + case 20: + case 22: + case 24: + case 26: + case 28: return P(unidentified)(ctx); + case 1: + case 3: + case 5: + case 7: + case 9: + case 11: + case 13: + case 15: + case 17: + case 19: + case 21: + case 23: + case 25: + case 27: { + if ((op & 0xf200e00) == 0xd000a00) { + goto insn_addrmode5_addr_8_VLDRD; /* 0x0d000a00 | 0xf0dff1ff */ + } else { + return P(unidentified)(ctx); + } + } + case 29: + case 31: { + if ((op & 0xef300000) == 0xed000000) { + goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + case 30: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } } } - case 3: { - switch ((op >> 29) & 0x7) { + case 5: + case 7: { + switch ((op >> 27) & 0x1f) { case 0: - case 1: case 2: - case 3: case 4: + case 6: + case 8: + case 10: + case 12: + case 14: + case 16: + case 18: + case 20: + case 22: + case 24: + case 26: + case 28: + return P(unidentified)(ctx); + case 1: + case 3: case 5: - case 6: { + case 7: + case 9: + case 11: + case 13: + case 15: + case 17: + case 19: + case 21: + case 23: + case 25: + case 27: { if ((op & 0xf200e00) == 0xd000a00) { goto insn_addrmode5_addr_8_VLDRD; /* 0x0d000a00 | 0xf0dff1ff */ } else { return P(unidentified)(ctx); } } - case 7: { - if ((op & 0xef300000) == 0xed100000) { - goto insn_addrmode5_addr_8_VLDRD; /* 0xed100000 | 0x10cfffff */ + case 29: + case 31: { + if ((op & 0xef300000) == 0xed000000) { + goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + case 30: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } @@ -2653,34 +3208,114 @@ } } } - case 22: - case 30: { + case 25: { switch ((op >> 27) & 0x1) { case 0: { - switch ((op >> 12) & 0x1) { - case 0: { + switch ((op >> 12) & 0x7) { + case 0: + case 2: { if ((op & 0xf800d000) == 0xf0008000) { goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 1: { + case 1: + case 3: { if ((op & 0xf800d000) == 0xf0009000) { goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } + case 4: + case 6: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ + } else { + return P(unidentified)(ctx); + } + } + case 5: + case 7: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } } } case 1: { switch ((op >> 26) & 0x1) { case 0: { - if ((op & 0xff700000) == 0xe9600000) { - struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; - struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; - return P(rGPR_Rt_t2addrmode_imm8s4_pre_addr_S_1_t2STRD_PRE)(ctx, addr, Rt); /* 0xe9600000 | 0x008fffff */ + switch ((op >> 16) & 0xf) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: { + if ((op & 0xfed00000) == 0xf8900000) { + goto insn_t2addrmode_imm12_addr_unk_Rt_5_t2LDRBi12; /* 0xf8900000 | 0x012fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 15: { + if ((op & 0xfe5f0000) == 0xf81f0000) { + goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } + case 1: { + switch ((op >> 29) & 0x7) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: { + if ((op & 0xf200e00) == 0xd000a00) { + goto insn_addrmode5_addr_8_VLDRD; /* 0x0d000a00 | 0xf0dff1ff */ + } else { + return P(unidentified)(ctx); + } + } + case 7: { + if ((op & 0xef300000) == 0xed100000) { + goto insn_addrmode5_addr_8_VLDRD; /* 0xed100000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } + } + } + } + } + case 26: { + switch ((op >> 12) & 0x7) { + case 0: + case 2: { + switch ((op >> 27) & 0x1) { + case 0: { + if ((op & 0xf800d000) == 0xf0008000) { + goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } @@ -2694,43 +3329,57 @@ } } } + case 1: + case 3: { + switch ((op >> 27) & 0x1) { + case 0: { + if ((op & 0xf800d000) == 0xf0009000) { + goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } + case 1: { + if ((op & 0xef300000) == 0xed200000) { + goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } } - } - case 23: - case 31: { - switch ((op >> 27) & 0x1) { - case 0: { - switch ((op >> 12) & 0x1) { + case 4: + case 6: { + switch ((op >> 27) & 0x1) { case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ } else { return P(unidentified)(ctx); } } case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ + if ((op & 0xef300000) == 0xed200000) { + goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } } } } - case 1: { - switch ((op >> 26) & 0x1) { + case 5: + case 7: { + switch ((op >> 27) & 0x1) { case 0: { - if ((op & 0xff700000) == 0xe9700000) { - struct bitslice addr = {.nruns = 3, .runs = (struct bitslice_run[]) {{0,0,8}, {16,9,4}, {23,8,1}}}; - struct bitslice Rt = {.nruns = 1, .runs = (struct bitslice_run[]) {{12,0,4}}}; - return P(t2addrmode_imm8s4_pre_addr_unk_Rt_1_t2LDRD_PRE)(ctx, addr, Rt); /* 0xe9700000 | 0x008fffff */ + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } case 1: { - if ((op & 0xef300000) == 0xed300000) { - goto insn_addrmode5_pre_addr_4_t2LDC2L_PRE; /* 0xed300000 | 0x10cfffff */ + if ((op & 0xef300000) == 0xed200000) { + goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } @@ -2739,229 +3388,422 @@ } } } - case 24: { + case 27: { switch ((op >> 27) & 0x1) { case 0: { - switch ((op >> 12) & 0x1) { - case 0: { + switch ((op >> 12) & 0x7) { + case 0: + case 2: { if ((op & 0xf800d000) == 0xf0008000) { goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 1: { + case 1: + case 3: { if ((op & 0xf800d000) == 0xf0009000) { goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - } - } - case 1: { - switch ((op >> 29) & 0x7) { - case 0: - case 1: - case 2: - case 3: case 4: - case 5: case 6: { - if ((op & 0xf200e00) == 0xd000a00) { - goto insn_addrmode5_addr_8_VLDRD; /* 0x0d000a00 | 0xf0dff1ff */ + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ } else { return P(unidentified)(ctx); } } + case 5: case 7: { - if ((op & 0xef300000) == 0xed000000) { - goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } } } - } - } - case 25: { - switch ((op >> 26) & 0x3) { - case 0: case 1: { - switch ((op >> 12) & 0x1) { + switch ((op >> 26) & 0x1) { case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ - } else { - return P(unidentified)(ctx); + switch ((op >> 16) & 0xf) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: { + if ((op & 0xfed00000) == 0xf8900000) { + goto insn_t2addrmode_imm12_addr_unk_Rt_5_t2LDRBi12; /* 0xf8900000 | 0x012fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 15: { + if ((op & 0xfe5f0000) == 0xf81f0000) { + goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ + } else { + return P(unidentified)(ctx); + } + } } } case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ + if ((op & 0xef300000) == 0xed300000) { + goto insn_addrmode5_pre_addr_4_t2LDC2L_PRE; /* 0xed300000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } } } } - case 2: { - switch ((op >> 16) & 0xf) { + } + } + case 28: { + switch ((op >> 10) & 0x1f) { + case 0: + case 1: + case 8: + case 9: + case 11: { + switch ((op >> 26) & 0x3) { case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: { - if ((op & 0xfed00000) == 0xf8900000) { - goto insn_t2addrmode_imm12_addr_unk_Rt_5_t2LDRBi12; /* 0xf8900000 | 0x012fffff */ + case 1: { + if ((op & 0xf800d000) == 0xf0008000) { + goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 15: { - if ((op & 0xfe5f0000) == 0xf81f0000) { - goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ + case 2: { + if ((op & 0xff700000) == 0xe9400000) { + goto insn_rGPR_Rt_t2addrmode_imm8s4_addr_S_1_t2STRDi8; /* 0xe9400000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + if ((op & 0xef300000) == 0xed000000) { + goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } } } } - case 3: { - switch ((op >> 29) & 0x7) { + case 2: + case 10: { + switch ((op >> 26) & 0x3) { case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: { - if ((op & 0xf200e00) == 0xd000a00) { - goto insn_addrmode5_addr_8_VLDRD; /* 0x0d000a00 | 0xf0dff1ff */ + case 1: { + if ((op & 0xf800d000) == 0xf0008000) { + goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 7: { - if ((op & 0xef300000) == 0xed100000) { - goto insn_addrmode5_addr_8_VLDRD; /* 0xed100000 | 0x10cfffff */ + case 2: { + if ((op & 0xff700000) == 0xe9400000) { + goto insn_rGPR_Rt_t2addrmode_imm8s4_addr_S_1_t2STRDi8; /* 0xe9400000 | 0x008fffff */ } else { return P(unidentified)(ctx); } } + case 3: { + switch ((op >> 29) & 0x7) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: { + if ((op & 0xf200e00) == 0xd000a00) { + goto insn_addrmode5_addr_8_VLDRD; /* 0x0d000a00 | 0xf0dff1ff */ + } else { + return P(unidentified)(ctx); + } + } + case 7: { + if ((op & 0xef300000) == 0xed000000) { + goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } } } - } - } - case 26: { - switch ((op >> 12) & 0x1) { - case 0: { + case 3: { switch ((op >> 27) & 0x1) { case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ + if ((op & 0xfff0ffff) == 0xf3c08f00) { + struct bitslice func = {.nruns = 1, .runs = (struct bitslice_run[]) {{16,0,4}}}; + return P(rGPR_func_1_t2BXJ)(ctx, func); /* 0xf3c08f00 | 0x000f0000 */ } else { - return P(unidentified)(ctx); + if ((op & 0xf800d000) == 0xf0008000) { + goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf1c08c00 | 0x060f03ff */ + } else { + return P(unidentified)(ctx); + } } } case 1: { - if ((op & 0xef300000) == 0xed200000) { - goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ + switch ((op >> 26) & 0x1) { + case 0: { + if ((op & 0xff700000) == 0xe9400000) { + goto insn_rGPR_Rt_t2addrmode_imm8s4_addr_S_1_t2STRDi8; /* 0xe9400000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 1: { + if ((op & 0xef300000) == 0xed000000) { + goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } + } + } + case 4: + case 5: + case 7: + case 12: + case 13: + case 15: { + switch ((op >> 26) & 0x3) { + case 0: + case 1: { + if ((op & 0xf800d000) == 0xf0009000) { + goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } + case 2: { + if ((op & 0xff700000) == 0xe9400000) { + goto insn_rGPR_Rt_t2addrmode_imm8s4_addr_S_1_t2STRDi8; /* 0xe9400000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + if ((op & 0xef300000) == 0xed000000) { + goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } } } } - case 1: { - switch ((op >> 27) & 0x1) { - case 0: { + case 6: + case 14: { + switch ((op >> 26) & 0x3) { + case 0: + case 1: { if ((op & 0xf800d000) == 0xf0009000) { goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 1: { - if ((op & 0xef300000) == 0xed200000) { - goto insn_addrmode5_pre_addr_S_4_t2STC2L_PRE; /* 0xed200000 | 0x10cfffff */ + case 2: { + if ((op & 0xff700000) == 0xe9400000) { + goto insn_rGPR_Rt_t2addrmode_imm8s4_addr_S_1_t2STRDi8; /* 0xe9400000 | 0x008fffff */ } else { return P(unidentified)(ctx); } } + case 3: { + switch ((op >> 29) & 0x7) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: { + if ((op & 0xf200e00) == 0xd000a00) { + goto insn_addrmode5_addr_8_VLDRD; /* 0x0d000a00 | 0xf0dff1ff */ + } else { + return P(unidentified)(ctx); + } + } + case 7: { + if ((op & 0xef300000) == 0xed000000) { + goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } } } - } - } - case 27: { - switch ((op >> 26) & 0x3) { - case 0: - case 1: { - switch ((op >> 12) & 0x1) { - case 0: { - if ((op & 0xf800d000) == 0xf0008000) { - goto insn_brtarget_target_pred_p_B_1_t2Bcc; /* 0xf0008000 | 0x07ff2fff */ + case 16: + case 17: + case 19: + case 24: + case 25: + case 27: { + switch ((op >> 26) & 0x3) { + case 0: + case 1: { + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ } else { return P(unidentified)(ctx); } } + case 2: { + if ((op & 0xff700000) == 0xe9400000) { + goto insn_rGPR_Rt_t2addrmode_imm8s4_addr_S_1_t2STRDi8; /* 0xe9400000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + if ((op & 0xef300000) == 0xed000000) { + goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } + case 18: + case 26: { + switch ((op >> 26) & 0x3) { + case 0: case 1: { - if ((op & 0xf800d000) == 0xf0009000) { - goto insn_uncondbrtarget_target_B_1_t2B; /* 0xf0009000 | 0x07ff2fff */ + if ((op & 0xf800d001) == 0xf000c000) { + goto insn_t_blxtarget_func_1_tBLXi; /* 0xf000c000 | 0x07ff2ffe */ } else { return P(unidentified)(ctx); } } + case 2: { + if ((op & 0xff700000) == 0xe9400000) { + goto insn_rGPR_Rt_t2addrmode_imm8s4_addr_S_1_t2STRDi8; /* 0xe9400000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + switch ((op >> 29) & 0x7) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: { + if ((op & 0xf200e00) == 0xd000a00) { + goto insn_addrmode5_addr_8_VLDRD; /* 0x0d000a00 | 0xf0dff1ff */ + } else { + return P(unidentified)(ctx); + } + } + case 7: { + if ((op & 0xef300000) == 0xed000000) { + goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } } } - case 2: { - switch ((op >> 16) & 0xf) { + case 20: + case 21: + case 23: + case 28: + case 29: + case 31: { + switch ((op >> 26) & 0x3) { case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: { - if ((op & 0xfed00000) == 0xf8900000) { - goto insn_t2addrmode_imm12_addr_unk_Rt_5_t2LDRBi12; /* 0xf8900000 | 0x012fffff */ + case 1: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ } else { return P(unidentified)(ctx); } } - case 15: { - if ((op & 0xfe5f0000) == 0xf81f0000) { - goto insn_t2ldrlabel_addr_unk_Rt_5_t2LDRBpci; /* 0xf81f0000 | 0x01a0ffff */ + case 2: { + if ((op & 0xff700000) == 0xe9400000) { + goto insn_rGPR_Rt_t2addrmode_imm8s4_addr_S_1_t2STRDi8; /* 0xe9400000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + if ((op & 0xef300000) == 0xed000000) { + goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ } else { return P(unidentified)(ctx); } } } } - case 3: { - if ((op & 0xef300000) == 0xed300000) { - goto insn_addrmode5_pre_addr_4_t2LDC2L_PRE; /* 0xed300000 | 0x10cfffff */ - } else { - return P(unidentified)(ctx); + case 22: + case 30: { + switch ((op >> 26) & 0x3) { + case 0: + case 1: { + if ((op & 0xf800d000) == 0xf000d000) { + goto insn_t_bltarget_func_1_tBL; /* 0xf000d000 | 0x07ff2fff */ + } else { + return P(unidentified)(ctx); + } + } + case 2: { + if ((op & 0xff700000) == 0xe9400000) { + goto insn_rGPR_Rt_t2addrmode_imm8s4_addr_S_1_t2STRDi8; /* 0xe9400000 | 0x008fffff */ + } else { + return P(unidentified)(ctx); + } + } + case 3: { + switch ((op >> 29) & 0x7) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: { + if ((op & 0xf200e00) == 0xd000a00) { + goto insn_addrmode5_addr_8_VLDRD; /* 0x0d000a00 | 0xf0dff1ff */ + } else { + return P(unidentified)(ctx); + } + } + case 7: { + if ((op & 0xef300000) == 0xed000000) { + goto insn_addrmode5_addr_S_4_t2STC2L_OFFSET; /* 0xed000000 | 0x10cfffff */ + } else { + return P(unidentified)(ctx); + } + } + } + } } } } @@ -3001,6 +3843,7 @@ static INLINE tdis_ret P(rGPR_Rt_t2addrmode_imm8s4_addr_S_1_t2STRDi8)(struct bit static INLINE tdis_ret P(rGPR_Rt_t2addrmode_imm8s4_pre_addr_S_1_t2STRD_PRE)(struct bitslice ctx, struct bitslice addr, struct bitslice Rt) {} static INLINE tdis_ret P(rGPR_Rt_t2addrmode_negimm8_addr_S_2_t2STRBi8)(struct bitslice ctx, struct bitslice addr, struct bitslice Rt) {} static INLINE tdis_ret P(rGPR_Rt_t2addrmode_so_reg_addr_S_2_t2STRBs)(struct bitslice ctx, struct bitslice addr, struct bitslice Rt) {} +static INLINE tdis_ret P(rGPR_func_1_t2BXJ)(struct bitslice ctx, struct bitslice func) {} static INLINE tdis_ret P(t2addrmode_imm0_1020s4_addr_unk_Rt_1_t2LDREX)(struct bitslice ctx, struct bitslice addr, struct bitslice Rt) {} static INLINE tdis_ret P(t2addrmode_imm12_addr_unk_Rt_5_t2LDRBi12)(struct bitslice ctx, struct bitslice addr, struct bitslice Rt) {} static INLINE tdis_ret P(t2addrmode_imm8_addr_unk_Rt_S_3_t2STRBT)(struct bitslice ctx, struct bitslice addr, struct bitslice Rt) {} @@ -3012,6 +3855,8 @@ static INLINE tdis_ret P(t2addrmode_posimm8_addr_unk_Rt_5_t2LDRBT)(struct bitsli static INLINE tdis_ret P(t2addrmode_so_reg_addr_unk_Rt_5_t2LDRBs)(struct bitslice ctx, struct bitslice addr, struct bitslice Rt) {} static INLINE tdis_ret P(t2adrlabel_addr_unk_Rd_1_t2ADR)(struct bitslice ctx, struct bitslice addr, struct bitslice Rd) {} static INLINE tdis_ret P(t2ldrlabel_addr_unk_Rt_5_t2LDRBpci)(struct bitslice ctx, struct bitslice addr, struct bitslice Rt) {} +static INLINE tdis_ret P(t_bltarget_func_1_tBL)(struct bitslice ctx, struct bitslice func) {} +static INLINE tdis_ret P(t_blxtarget_func_1_tBLXi)(struct bitslice ctx, struct bitslice func) {} static INLINE tdis_ret P(uncondbrtarget_target_B_1_t2B)(struct bitslice ctx, struct bitslice target) {} static INLINE tdis_ret P(unk_Rd_3_t2MOVTi16)(struct bitslice ctx, struct bitslice Rd) {} static INLINE tdis_ret P(unk_Rm_B_2_t2TBB)(struct bitslice ctx, struct bitslice Rm) {} diff --git a/lib/arm/arch-transform-dis.inc.h b/lib/arm/arch-transform-dis.inc.h index c5963e1..8569300 100644 --- a/lib/arm/arch-transform-dis.inc.h +++ b/lib/arm/arch-transform-dis.inc.h @@ -113,7 +113,7 @@ void transform_dis_data(struct transform_dis_ctx *ctx, unsigned o0, unsigned o1, POPone(actx, scratch); } } - ctx->modify = true; + ctx->base.modify = true; #ifdef TRANSFORM_DIS_VERBOSE printf("transform_dis_data: => %x %x %x %x\n", newval[0], newval[1], newval[2], newval[3]); @@ -149,23 +149,18 @@ void transform_dis_pcrel(struct transform_dis_ctx *ctx, uintptr_t dpc, } static NOINLINE UNUSED -void transform_dis_branch(struct transform_dis_ctx *ctx, - uintptr_t dpc, int cc) { +void transform_dis_branch(struct transform_dis_ctx *ctx, uintptr_t dpc, int cc) { #ifdef TRANSFORM_DIS_VERBOSE printf("transform_dis (0x%llx): branch => 0x%llx\n", (unsigned long long) ctx->base.pc, (unsigned long long) dpc); #endif - if (dpc >= ctx->pc_patch_start && dpc < ctx->pc_patch_end) { - /* don't support this for now */ - /* making the simplifying assumption here that functions will not try - * to branch into the middle of an IT block, which is the case where - * pc_patch_end changes to include additional instructions (as opposed - * to include the end of a partially included instruction, which is - * common) */ - ctx->err = SUBSTITUTE_ERR_FUNC_BAD_INSN_AT_START; - return; - } + /* The check in transform_dis_branch_top is correct under the simplifying + * assumption here that functions will not try to branch into the middle of + * an IT block, which is the case where pc_patch_end changes to include + * additional instructions (as opposed to include the end of a partially + * included instruction, which is common). */ + transform_dis_branch_top(ctx, dpc, cc); struct assemble_ctx actx = tdctx_to_actx(ctx); ctx->write_newop_here = NULL; if ((cc & CC_ARMCC) == CC_ARMCC) { diff --git a/lib/arm/dis-arm.inc.h b/lib/arm/dis-arm.inc.h index 3ae0ab9..ab61877 100644 --- a/lib/arm/dis-arm.inc.h +++ b/lib/arm/dis-arm.inc.h @@ -206,6 +206,13 @@ static INLINE void P(GPR_Rt_addr_offset_none_addr_postidx_reg_Rm_S_1_STRHTr)(tdi static INLINE void P(GPR_dst_B_2_BX)(tdis_ctx ctx, UNUSED struct bitslice dst) { return P(ret)(ctx); } +static INLINE void P(GPR_func_3_BLX)(tdis_ctx ctx, UNUSED struct bitslice func) { + return P(indirect_call)(ctx); +} +static INLINE void P(bl_target_func_2_BL)(tdis_ctx ctx, struct bitslice func) { + return P(branch)(ctx, ctx->base.pc + 8 + sext(bs_get(func, ctx->base.op), 24), + CC_CALL); +} static INLINE void P(dis_arm)(tdis_ctx ctx) { uint32_t op = ctx->base.op = *(uint32_t *) ctx->base.ptr; diff --git a/lib/arm/dis-thumb.inc.h b/lib/arm/dis-thumb.inc.h index 4a2b747..4f758bf 100644 --- a/lib/arm/dis-thumb.inc.h +++ b/lib/arm/dis-thumb.inc.h @@ -81,6 +81,9 @@ static INLINE void P(it_pred_cc_it_mask_mask_1_t2IT)(tdis_ctx ctx, struct bitsli ctx->arch.it_conds[i+2] = (cc_val & ~1) | (mask_val >> (3 - i) & 1); return P(thumb_it)(ctx); } +static INLINE void P(GPR_func_1_tBLXr)(tdis_ctx ctx, UNUSED struct bitslice func) { + return P(indirect_call)(ctx); +} static INLINE void P(thumb_do_it)(tdis_ctx ctx) { uint16_t op = ctx->base.op = *(uint16_t *) ctx->base.ptr; diff --git a/lib/arm/dis-thumb2.inc.h b/lib/arm/dis-thumb2.inc.h index 43ca4ab..5f699c9 100644 --- a/lib/arm/dis-thumb2.inc.h +++ b/lib/arm/dis-thumb2.inc.h @@ -170,6 +170,24 @@ static INLINE void P(unk_Rm_B_2_t2TBB)(tdis_ctx ctx, UNUSED struct bitslice Rm) static INLINE void P(unk_Rt_13_VMOVRRD)(tdis_ctx ctx, UNUSED struct bitslice Rt) { return P(unidentified)(ctx); } +static INLINE void P(t_bltarget_func_1_tBL)(tdis_ctx ctx, struct bitslice func) { + unsigned crap = bs_get(func, ctx->base.op) << 1; + unsigned S = crap >> 24 & 1; + if (S) + crap ^= (3 << 22); + return P(branch)(ctx, ctx->base.pc + 4 + 2 * sext(crap, 25), CC_CALL); + +} +static INLINE void P(t_blxtarget_func_1_tBLXi)(tdis_ctx ctx, struct bitslice func) { + unsigned crap = bs_get(func, ctx->base.op); + unsigned S = crap >> 24 & 1; + if (S) + crap ^= (3 << 22); + return P(branch)(ctx, ctx->base.pc + 4 + 2 * sext(crap, 25), CC_CALL); +} +static INLINE void P(rGPR_func_1_t2BXJ)(tdis_ctx ctx, UNUSED struct bitslice func) { + return P(unidentified)(ctx); +} static INLINE void P(thumb2_do_it)(tdis_ctx ctx) { uint32_t op = ctx->base.op; diff --git a/lib/arm64/arch-transform-dis.inc.h b/lib/arm64/arch-transform-dis.inc.h index ac11e45..123c7ae 100644 --- a/lib/arm64/arch-transform-dis.inc.h +++ b/lib/arm64/arch-transform-dis.inc.h @@ -23,10 +23,7 @@ void transform_dis_branch(struct transform_dis_ctx *ctx, uint_tptr dpc, int cc) (unsigned long long) ctx->base.pc, (unsigned long long) dpc); #endif - if (dpc >= ctx->pc_patch_start && dpc < ctx->pc_patch_end) { - ctx->err = SUBSTITUTE_ERR_FUNC_BAD_INSN_AT_START; - return; - } + transform_dis_branch_top(ctx, dpc, cc); ctx->write_newop_here = NULL; int mov_br_size = size_of_MOVi64(dpc) + 4; @@ -42,7 +39,7 @@ void transform_dis_branch(struct transform_dis_ctx *ctx, uint_tptr dpc, int cc) } int reg = arm64_get_unwritten_temp_reg(&ctx->arch); MOVi64(codep, reg, dpc); - BR(codep, reg); + BR(codep, reg, /*link*/ cc & CC_CALL); } static void transform_dis_pre_dis(UNUSED struct transform_dis_ctx *ctx) {} diff --git a/lib/arm64/assemble.h b/lib/arm64/assemble.h index 1dca7eb..42c0f0c 100644 --- a/lib/arm64/assemble.h +++ b/lib/arm64/assemble.h @@ -56,8 +56,8 @@ static inline void ADRP_ADD(void **codep, int reg, uint64_t pc, uint64_t dpc) { } } -static inline void BR(void **codep, int reg) { - op32(codep, 0xd61f0000 | reg << 5); +static inline void BR(void **codep, int reg, bool link) { + op32(codep, 0xd61f0000 | reg << 5 | link << 21); } static inline void Bccrel(void **codep, int cc, int offset) { diff --git a/lib/arm64/dis-main.inc.h b/lib/arm64/dis-main.inc.h index 0107715..a009189 100644 --- a/lib/arm64/dis-main.inc.h +++ b/lib/arm64/dis-main.inc.h @@ -55,8 +55,13 @@ static INLINE void P(am_ldrlit_label_unk_Rt_6_LDRDl)(tdis_ctx ctx, struct bitsli return P(pcrel)(ctx, ctx->base.pc + sext(bs_get(label, ctx->base.op), 19) * 4, (struct arch_pcrel_info) {bs_get(Rt, ctx->base.op), mode}); } -static INLINE void P(GPR64_Rn_1_RET)(tdis_ctx ctx, UNUSED struct bitslice Rn) { - return P(ret)(ctx); + +static INLINE void P(GPR64_Rn_2_BLR)(tdis_ctx ctx, UNUSED struct bitslice Rn) { + int op = ctx->base.op >> 21 & 3; + if (op == 1) + return P(indirect_call)(ctx); + else + return P(ret)(ctx); } static INLINE void P(dis)(tdis_ctx ctx) { diff --git a/lib/hook-functions.c b/lib/hook-functions.c index faadd82..6d53a0d 100644 --- a/lib/hook-functions.c +++ b/lib/hook-functions.c @@ -207,7 +207,8 @@ int substitute_hook_functions(const struct substitute_function_hook *hooks, * ending make_jump_patch call) */ if ((ret = transform_dis_main(code, &trampoline_ptr, pc_patch_start, &pc_patch_end, (uintptr_t) trampoline_ptr, - &arch, hi->offset_by_pcdiff))) + &arch, hi->offset_by_pcdiff, + thread_safe ? TRANSFORM_DIS_BAN_CALLS : 0))) goto end; uintptr_t dpc = pc_patch_end; diff --git a/lib/jump-dis.c b/lib/jump-dis.c index 528cfc2..e1a7d48 100644 --- a/lib/jump-dis.c +++ b/lib/jump-dis.c @@ -91,6 +91,10 @@ void jump_dis_pcrel(struct jump_dis_ctx *ctx, uint_tptr dpc, } static INLINE UNUSED +void jump_dis_indirect_call(UNUSED struct jump_dis_ctx *ctx) { +} + +static INLINE UNUSED void jump_dis_ret(struct jump_dis_ctx *ctx) { ctx->continue_after_this_insn = false; } diff --git a/lib/substitute.h b/lib/substitute.h index 2045c3d..d8b9fd0 100644 --- a/lib/substitute.h +++ b/lib/substitute.h @@ -29,6 +29,14 @@ enum { * updated to handle that case properly */ SUBSTITUTE_ERR_FUNC_BAD_INSN_AT_START, + /* substitute_hook_functions: can't patch a function because one of the + * instructions within the patch region (other than the last instruction) + * is a call - meaning that a return address within the region (i.e. about + * to point to clobbered code) could be on some thread's stack, where we + * can't easily find and patch it. This check is skipped if + * SUBSTITUTE_NO_THREAD_SAFETY is set. */ + SUBSTITUTE_ERR_FUNC_CALLS_AT_START, + /* substitute_hook_functions: can't patch a function because the (somewhat * cursory) jump analysis found a jump later in the function to within the * patch region at the beginning */ diff --git a/lib/transform-dis.c b/lib/transform-dis.c index 75abc82..4d69da1 100644 --- a/lib/transform-dis.c +++ b/lib/transform-dis.c @@ -12,7 +12,6 @@ struct transform_dis_ctx { /* outputs */ - bool modify; int err; struct dis_ctx_base base; @@ -24,6 +23,8 @@ struct transform_dis_ctx { /* for IT - eww */ bool force_keep_transforming; + bool ban_calls; /* i.e. trying to be thread safe */ + void **rewritten_ptr_ptr; void *write_newop_here; @@ -34,7 +35,14 @@ struct transform_dis_ctx { /* largely similar to jump_dis */ -static INLINE UNUSED +static NOINLINE UNUSED +void transform_dis_indirect_call(struct transform_dis_ctx *ctx) { + /* see error description */ + if (ctx->ban_calls && ctx->base.pc + ctx->base.op_size < ctx->pc_patch_end) + ctx->err = SUBSTITUTE_ERR_FUNC_CALLS_AT_START; +} + +static NOINLINE UNUSED void transform_dis_ret(struct transform_dis_ctx *ctx) { /* ret is okay if it's at the end of the required patch (past the original * patch size is good too) */ @@ -42,7 +50,7 @@ void transform_dis_ret(struct transform_dis_ctx *ctx) { ctx->err = SUBSTITUTE_ERR_FUNC_TOO_SHORT; } -static INLINE UNUSED +static UNUSED void transform_dis_unidentified(UNUSED struct transform_dis_ctx *ctx) { #ifdef TRANSFORM_DIS_VERBOSE printf("transform_dis (0x%llx): unidentified\n", @@ -51,7 +59,7 @@ void transform_dis_unidentified(UNUSED struct transform_dis_ctx *ctx) { /* this isn't exhaustive, so unidentified is fine */ } -static INLINE UNUSED +static NOINLINE UNUSED void transform_dis_bad(struct transform_dis_ctx *ctx) { ctx->err = SUBSTITUTE_ERR_FUNC_BAD_INSN_AT_START; } @@ -61,6 +69,20 @@ void transform_dis_thumb_it(UNUSED struct transform_dis_ctx *ctx) { /* ignore, since it was turned into B */ } +static void transform_dis_branch_top(struct transform_dis_ctx *ctx, + uintptr_t dpc, int cc) { + if (dpc >= ctx->pc_patch_start && dpc < ctx->pc_patch_end) { + /* don't support this for now */ + ctx->err = SUBSTITUTE_ERR_FUNC_BAD_INSN_AT_START; + return; + } + if (cc & CC_CALL) { + transform_dis_indirect_call(ctx); + } else { + transform_dis_ret(ctx); + } +} + static void transform_dis_dis(struct transform_dis_ctx *ctx); static void transform_dis_pre_dis(struct transform_dis_ctx *ctx); static void transform_dis_post_dis(struct transform_dis_ctx *ctx); @@ -71,13 +93,15 @@ int transform_dis_main(const void *restrict code_ptr, uint_tptr *pc_patch_end_p, uint_tptr pc_trampoline, struct arch_dis_ctx *arch_ctx_p, - int *offset_by_pcdiff) { + int *offset_by_pcdiff, + int options) { struct transform_dis_ctx ctx; memset(&ctx, 0, sizeof(ctx)); ctx.pc_patch_start = pc_patch_start; ctx.pc_patch_end = *pc_patch_end_p; ctx.base.pc = pc_patch_start; ctx.arch = *arch_ctx_p; + ctx.ban_calls = options & TRANSFORM_DIS_BAN_CALLS; /* data is written to rewritten both by this function directly and, in case * additional scaffolding is needed, by arch-specific transform_dis_* */ ctx.rewritten_ptr_ptr = rewritten_ptr_ptr; diff --git a/lib/transform-dis.h b/lib/transform-dis.h index 4e853b0..e8969a8 100644 --- a/lib/transform-dis.h +++ b/lib/transform-dis.h @@ -3,10 +3,13 @@ #include <stdbool.h> #include stringify(TARGET_DIR/arch-dis.h) +#define TRANSFORM_DIS_BAN_CALLS 1 + int transform_dis_main(const void *restrict code_ptr, void **restrict rewritten_ptr_ptr, uint_tptr pc_patch_start, uint_tptr *pc_patch_end_p, uint_tptr pc_trampoline, struct arch_dis_ctx *arch_ctx_p, - int *offset_by_pcdiff); + int *offset_by_pcdiff, + int options); diff --git a/lib/x86/arch-transform-dis.inc.h b/lib/x86/arch-transform-dis.inc.h index 56e41eb..a4be424 100644 --- a/lib/x86/arch-transform-dis.inc.h +++ b/lib/x86/arch-transform-dis.inc.h @@ -81,10 +81,7 @@ static void transform_dis_branch(struct transform_dis_ctx *ctx, uint_tptr dpc, *ctx->rewritten_ptr_ptr = code; return; } - if (dpc >= ctx->pc_patch_start && dpc < ctx->pc_patch_end) { - ctx->err = SUBSTITUTE_ERR_FUNC_BAD_INSN_AT_START; - return; - } + transform_dis_branch_top(ctx, dpc, cc); void *code = *ctx->rewritten_ptr_ptr; struct arch_dis_ctx arch; @@ -109,10 +106,8 @@ static void transform_dis_branch(struct transform_dis_ctx *ctx, uint_tptr dpc, transform_dis_ret(ctx); } else { ctx->write_newop_here = NULL; - make_jmp_or_call(&code, ctx->pc_trampoline, dpc, cc & CC_CALL); - if (!(cc & CC_CALL)) - transform_dis_ret(ctx); + make_jmp_or_call(&code, ctx->pc_trampoline, dpc, cc & CC_CALL); } *ctx->rewritten_ptr_ptr = code; } diff --git a/lib/x86/dis-main.inc.h b/lib/x86/dis-main.inc.h index 9959409..b6064e9 100644 --- a/lib/x86/dis-main.inc.h +++ b/lib/x86/dis-main.inc.h @@ -44,6 +44,7 @@ VEX last byte 1:0: {none, 66, f3, f2} #define I_JIMM_ONLY 0x80 /* imm is jump offset */ #define I_JIMM (0x80|I_JMP) #define I_BAD 0x80 +#define I_CALL 0x100 /* not really in the table */ #ifdef TARGET_x86_64 #define if64(_64, _32) _64 #else @@ -119,7 +120,7 @@ static void P(dis)(tdis_ctx ctx) { int mod, rm = 0; restart:; uint8_t byte1 = *ptr++; - uint8_t bits = onebyte_bits[byte1]; + int bits = onebyte_bits[byte1]; /* printf("b1=%x bytes=%x\n", byte1, bits); */ if ((bits & I_TYPE_MASK) == I_SPEC) { if (byte1 == 0x0f) { @@ -134,6 +135,8 @@ restart:; int subop = modrm >> 3 & 7; if (subop == 4 || subop == 5) /* JMP */ bits = I_JMP | I_MODA; + else if (subop == 2 || subop == 3) /* CALL */ + bits = I_CALL | I_MODA; else bits = I_MODA; } else { @@ -283,6 +286,8 @@ got_bits: UNUSED #ifdef TARGET_x86_64 } else if ((bits & I_MODA) == I_MODA && mod == 0 && rm == 5) { int32_t disp = *(int32_t *) (orig + modrm_off + 1); + if (bits & I_CALL) + P(indirect_call)(ctx); /* unlike ARM, we can always switch to non-pcrel without making the * instruction from scratch, so we don't have 'reg' and 'lm' */ struct arch_pcrel_info info = { @@ -319,6 +324,8 @@ got_bits: UNUSED #endif } else if ((bits & I_TYPE_MASK) == I_JMP) { P(ret)(ctx); + } else if (bits & I_CALL) { + P(indirect_call)(ctx); } else { P(unidentified)(ctx); } diff --git a/test/test-td-simple.c b/test/test-td-simple.c index be84ef3..d776d0e 100644 --- a/test/test-td-simple.c +++ b/test/test-td-simple.c @@ -49,6 +49,11 @@ static void P_ret(UNUSED struct tc *ctx) { } NOINLINE UNUSED +static void P_indirect_call(UNUSED struct tc *ctx) { + printf("indirect call\n"); +} + +NOINLINE UNUSED static void P_branch(UNUSED struct tc *ctx, uint64_t dpc, int cc) { printf("branch(%s,%s) => %08llx\n", (cc & CC_CONDITIONAL) ? "cond" : "uncond", diff --git a/test/test-transform-dis.c b/test/test-transform-dis.c index 2d7de9e..98c98e3 100644 --- a/test/test-transform-dis.c +++ b/test/test-transform-dis.c @@ -37,7 +37,8 @@ static void do_manual(uint8_t *in, size_t in_size, int patch_size, &pc_patch_end, pc_trampoline, &arch, - offsets); + offsets, + TRANSFORM_DIS_BAN_CALLS); printf("=> %d\n", ret); printf("#endif\n"); int print_out_idx = 0; @@ -97,8 +98,10 @@ static void do_auto(uint8_t *in, size_t in_size, struct arch_dis_ctx arch) { if (!memcmp(expect, "_ERR", 4)) { expect_err = true; in += 4; - assert(!memcmp(in, "GIVEN", 5)); - in += 5; + if (in != end) { + assert(!memcmp(in, "GIVEN", 5)); + in += 5; + } } else { in = memmem(in, end - in, "GIVEN", 5); if (in) { @@ -123,7 +126,8 @@ static void do_auto(uint8_t *in, size_t in_size, struct arch_dis_ctx arch) { &pc_patch_end, pc_trampoline, &arch, - offsets); + offsets, + TRANSFORM_DIS_BAN_CALLS); if (ret) { if (expect_err) { printf("OK\n"); diff --git a/test/transform-dis-cases-i386.S b/test/transform-dis-cases-i386.S index 3e468d4..c02a044 100644 --- a/test/transform-dis-cases-i386.S +++ b/test/transform-dis-cases-i386.S @@ -17,3 +17,15 @@ EXPECT 2: .byte 0x0f, 0x85; .long 2; jmp 1f; 0: jmp .+0x10000+0x1000-8; 1: GIVEN loopne .+0x80 EXPECT loopne 0f; jmp 1f; 0: jmp .+0x10000+0x80-4; 1: + +GIVEN call .+0x1000; nop +EXPECT_ERR + +GIVEN call *%edi +EXPECT call *%edi + +GIVEN call *%edi; nop +EXPECT_ERR + +GIVEN call *(%edi); nop +EXPECT_ERR |