summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorGalen Williamson <galen@vector35.com>2025-02-04 17:02:30 -0500
committerGalen Williamson <galen@vector35.com>2025-06-09 12:40:14 -0400
commit9373cab26ee2e7b2febab7674360d54d6fb8adc6 (patch)
tree648349697b52b82b5c734368a0a333ac69a03b23 /arch
parentc8de8363f3dd55ab09bfde7fcb01a11f7d0a0e94 (diff)
WIP improve thumb2 MSR lifting
Diffstat (limited to 'arch')
-rw-r--r--arch/armv7/armv7_disasm/armv7.h8
-rw-r--r--arch/armv7/thumb2_disasm/arch_thumb2.cpp16
-rw-r--r--arch/armv7/thumb2_disasm/il_thumb2.cpp42
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: