diff options
| author | Galen Williamson <galen@vector35.com> | 2025-02-04 17:02:30 -0500 |
|---|---|---|
| committer | Galen Williamson <galen@vector35.com> | 2025-06-09 12:40:14 -0400 |
| commit | 9373cab26ee2e7b2febab7674360d54d6fb8adc6 (patch) | |
| tree | 648349697b52b82b5c734368a0a333ac69a03b23 /arch | |
| parent | c8de8363f3dd55ab09bfde7fcb01a11f7d0a0e94 (diff) | |
WIP improve thumb2 MSR lifting
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/armv7/armv7_disasm/armv7.h | 8 | ||||
| -rw-r--r-- | arch/armv7/thumb2_disasm/arch_thumb2.cpp | 16 | ||||
| -rw-r--r-- | arch/armv7/thumb2_disasm/il_thumb2.cpp | 42 |
3 files changed, 54 insertions, 12 deletions
diff --git a/arch/armv7/armv7_disasm/armv7.h b/arch/armv7/armv7_disasm/armv7.h index eae0f3de..d91d75ca 100644 --- a/arch/armv7/armv7_disasm/armv7.h +++ b/arch/armv7/armv7_disasm/armv7.h @@ -697,16 +697,20 @@ enum Register REGS_FPEXC, // 8 REGS_FPINST, // 9 REGS_FPINST2, //10 - REGS_MSP, - REGS_PSP, // these are M-profile only (special) // but are here in ARM common (general) // TODO: implement "microarchitecture support" + REGS_MSP, + REGS_PSP, REGS_PRIMASK, REGS_BASEPRI, REGS_FAULTMASK, REGS_CONTROL, + REGS_BASEPRI_MAX, + REGS_IPSR, + REGS_EPSR, + REGS_IEPSR, REG_INVALID, }; diff --git a/arch/armv7/thumb2_disasm/arch_thumb2.cpp b/arch/armv7/thumb2_disasm/arch_thumb2.cpp index a6b8ee0a..a4a3c1cc 100644 --- a/arch/armv7/thumb2_disasm/arch_thumb2.cpp +++ b/arch/armv7/thumb2_disasm/arch_thumb2.cpp @@ -1219,9 +1219,23 @@ public: else { uint32_t tmp = (decomp.fields[FIELD_write_nzcvq] << 1) | decomp.fields[FIELD_write_g]; uint8_t sysm = decomp.fields[FIELD_SYSm]; + bool xPSR = ((sysm >> 2) & 1) == 1; switch (sysm >> 3) { case 0: /* xPSR access */ - switch(tmp) { + if (xPSR) + switch (sysm) { + case 5: // '101' == IPSR + result.emplace_back(RegisterToken, "ipsr"); + break; + case 6: // '110' == EPSR + result.emplace_back(RegisterToken, "epsr"); + break; + case 7: // '111' == IEPSR + result.emplace_back(RegisterToken, "iepsr"); + break; + } + else + switch(tmp) { case 0: // unpredictable break; case 1: // '01' == write_g diff --git a/arch/armv7/thumb2_disasm/il_thumb2.cpp b/arch/armv7/thumb2_disasm/il_thumb2.cpp index 56443ff1..05a9f16f 100644 --- a/arch/armv7/thumb2_disasm/il_thumb2.cpp +++ b/arch/armv7/thumb2_disasm/il_thumb2.cpp @@ -1142,16 +1142,40 @@ bool GetLowLevelILForThumbInstruction(Architecture* arch, LowLevelILFunction& il int intrinsic_id = ARMV7_INTRIN_MSR; /* certain MSR scenarios earn a specialized intrinsic */ - if (dest_reg == REGS_BASEPRI) - intrinsic_id = ARM_M_INTRIN_SET_BASEPRI; + // if (dest_reg == REGS_BASEPRI) + // intrinsic_id = ARM_M_INTRIN_SET_BASEPRI; + switch (dest_reg) { + case REGS_MSP: + case REGS_PSP: + case REGS_BASEPRI: + case REGS_BASEPRI_MAX: + case REGS_PRIMASK: + case REGS_FAULTMASK: + case REGS_CONTROL: + case REGS_IPSR: + case REGS_EPSR: + case REGS_IEPSR: + il.AddInstruction( + il.Intrinsic( + {}, /* outputs */ + intrinsic_id, + { + il.Register(4, dest_reg), + ReadILOperand(il, instr, 1) + } /* inputs */ + ) + ); + break; + default: + il.AddInstruction( + il.Intrinsic( + {RegisterOrFlag::Register(dest_reg)}, /* outputs */ + intrinsic_id, + {ReadILOperand(il, instr, 1)} /* inputs */ + ) + ); + } - il.AddInstruction( - il.Intrinsic( - {RegisterOrFlag::Register(dest_reg)}, /* outputs */ - intrinsic_id, - {ReadILOperand(il, instr, 1)} /* inputs */ - ) - ); break; } case armv7::ARMV7_MUL: |
