Skip to content

Commit afba3e0

Browse files
committed
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 <[email protected]>
1 parent d2e33fe commit afba3e0

File tree

1 file changed

+5
-3
lines changed

1 file changed

+5
-3
lines changed

py/emitnative.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ static void emit_native_mov_reg_qstr(emit_t *emit, int arg_reg, qstr qst) {
357357
#endif
358358
}
359359

360+
// This function may clobber REG_TEMP0 (and `reg_dest` can be REG_TEMP0).
360361
static void emit_native_mov_reg_qstr_obj(emit_t *emit, int reg_dest, qstr qst) {
361362
#if MICROPY_PERSISTENT_CODE_SAVE
362363
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) {
11171118
return e;
11181119
}
11191120

1121+
// This function will clobber REG_TEMP0 (and `reg` can be REG_TEMP0).
11201122
static void emit_load_reg_with_object(emit_t *emit, int reg, mp_obj_t obj) {
11211123
emit->scope->scope_flags |= MP_SCOPE_FLAG_HASCONSTS;
11221124
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) {
13911393

13921394
static void emit_native_load_const_obj(emit_t *emit, mp_obj_t obj) {
13931395
emit_native_pre(emit);
1394-
need_reg_single(emit, REG_RET, 0);
1395-
emit_load_reg_with_object(emit, REG_RET, obj);
1396-
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
1396+
need_reg_single(emit, REG_TEMP0, 0);
1397+
emit_load_reg_with_object(emit, REG_TEMP0, obj);
1398+
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_TEMP0);
13971399
}
13981400

13991401
static void emit_native_load_null(emit_t *emit) {

0 commit comments

Comments
 (0)