diff options
| author | Damien George <damien@micropython.org> | 2024-07-31 12:33:33 +1000 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2024-08-07 12:25:21 +1000 |
| commit | afba3e054041bbad961fad61df7c4797ab35d9e3 (patch) | |
| tree | c05db5277813d8fd13eb04901c7f8f9c5a76c301 /py | |
| parent | d2e33fe3096eec60d7017b0f17c4ddb6910a4d0b (diff) | |
py/emitnative: Fix case of clobbered REG_TEMP0 when loading const obj.
The `emit_load_reg_with_object()` helper function will clobber `REG_TEMP0`.
This is currently OK on architectures where `REG_RET` and `REG_TEMP0` are
the same (all architectures except RV32), because all callers of
`emit_load_reg_with_object()` use either `REG_RET` or `REG_TEMP0` as the
destination register. But on RV32 these registers are different and so
when `REG_RET` is the destination, `REG_TEMP0` is clobbered, leading to
incorrectly generated machine code.
This commit fixes the issue simply by using `REG_TEMP0` as the destination
register for all uses of `emit_load_reg_with_object()`, and adds a comment
to make sure the caller of this function is careful.
Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'py')
| -rw-r--r-- | py/emitnative.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/py/emitnative.c b/py/emitnative.c index 88ebf0bfc..66c345b23 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -357,6 +357,7 @@ static void emit_native_mov_reg_qstr(emit_t *emit, int arg_reg, qstr qst) { #endif } +// This function may clobber REG_TEMP0 (and `reg_dest` can be REG_TEMP0). static void emit_native_mov_reg_qstr_obj(emit_t *emit, int reg_dest, qstr qst) { #if MICROPY_PERSISTENT_CODE_SAVE emit_load_reg_with_object(emit, reg_dest, MP_OBJ_NEW_QSTR(qst)); @@ -1117,6 +1118,7 @@ static exc_stack_entry_t *emit_native_pop_exc_stack(emit_t *emit) { return e; } +// This function will clobber REG_TEMP0 (and `reg` can be REG_TEMP0). static void emit_load_reg_with_object(emit_t *emit, int reg, mp_obj_t obj) { emit->scope->scope_flags |= MP_SCOPE_FLAG_HASCONSTS; size_t table_off = mp_emit_common_use_const_obj(emit->emit_common, obj); @@ -1391,9 +1393,9 @@ static void emit_native_load_const_str(emit_t *emit, qstr qst) { static void emit_native_load_const_obj(emit_t *emit, mp_obj_t obj) { emit_native_pre(emit); - need_reg_single(emit, REG_RET, 0); - emit_load_reg_with_object(emit, REG_RET, obj); - emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); + need_reg_single(emit, REG_TEMP0, 0); + emit_load_reg_with_object(emit, REG_TEMP0, obj); + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_TEMP0); } static void emit_native_load_null(emit_t *emit) { |
