diff options
author | Chris Webb <chris@arachsys.com> | 2025-07-27 22:16:24 +0100 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2025-08-01 14:15:39 +1000 |
commit | f39434e9fb17405754277dd62dfea788a42d5afb (patch) | |
tree | 1eeb59aa1cc0bea5680a1e5b6198a6c31dbbc989 | |
parent | 69ead7d98ef30df3b6bd4485633490e80fca1718 (diff) |
py/asmthumb: Don't corrupt base register in large offset store.
asm_thumb_store_reg_reg_offset() modifies the base register when storing
with a large offset which triggers the generic path. If a variable lives
in that register, this corrupts it. Fix this by saving the base register
on the stack before modifying it.
Signed-off-by: Chris Webb <chris@arachsys.com>
-rw-r--r-- | py/asmthumb.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/py/asmthumb.c b/py/asmthumb.c index 18c3db9e4..93860d2fd 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -492,8 +492,10 @@ void asm_thumb_store_reg_reg_offset(asm_thumb_t *as, uint reg_src, uint reg_base asm_thumb_op32(as, (OP_LDR_STR_W_HI(operation_size, reg_base) | OP_STR_W), OP_LDR_STR_W_LO(reg_src, (offset << operation_size))); } else { // Must use the generic sequence + asm_thumb_op16(as, OP_PUSH_RLIST(1 << reg_base)); asm_thumb_add_reg_reg_offset(as, reg_base, reg_base, offset - 31, operation_size); asm_thumb_op16(as, ((OP_LDR_STR_TABLE[operation_size] | OP_STR) << 11) | (31 << 6) | (reg_base << 3) | reg_src); + asm_thumb_op16(as, OP_POP_RLIST(1 << reg_base)); } } |