mirror of
https://github.com/micropython/micropython.git
synced 2026-01-05 03:30:14 +01:00
py/emitnative: Emit shorter exception handler entry code on RV32.
This commit improves the RV32 code sequence that is emitted if a function needs to set up an exception handler as its prologue. The old code would clear a temporary register and then copy that value to places that needed to be initialised with zero values. On RV32 there's a dedicated register that's hardwired to be equal to zero, which allows us to bypass the extra register clear and use the zero register to initialise values. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit is contained in:
committed by
Damien George
parent
bfc0d7b0b9
commit
40585eaa8f
@@ -288,6 +288,11 @@ struct _emit_t {
|
||||
ASM_T *as;
|
||||
};
|
||||
|
||||
#ifndef REG_ZERO
|
||||
#define REG_ZERO REG_TEMP0
|
||||
#define ASM_CLR_REG(state, rd) ASM_XOR_REG_REG(state, rd, rd)
|
||||
#endif
|
||||
|
||||
static void emit_load_reg_with_object(emit_t *emit, int reg, mp_obj_t obj);
|
||||
static void emit_native_global_exc_entry(emit_t *emit);
|
||||
static void emit_native_global_exc_exit(emit_t *emit);
|
||||
@@ -1200,12 +1205,12 @@ static void emit_native_global_exc_entry(emit_t *emit) {
|
||||
ASM_JUMP_IF_REG_ZERO(emit->as, REG_RET, start_label, true);
|
||||
} else {
|
||||
// Clear the unwind state
|
||||
ASM_XOR_REG_REG(emit->as, REG_TEMP0, REG_TEMP0);
|
||||
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_UNWIND(emit), REG_TEMP0);
|
||||
ASM_CLR_REG(emit->as, REG_ZERO);
|
||||
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_UNWIND(emit), REG_ZERO);
|
||||
|
||||
// clear nlr.ret_val, because it's passed to mp_native_raise regardless
|
||||
// of whether there was an exception or not
|
||||
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_TEMP0);
|
||||
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_ZERO);
|
||||
|
||||
// Put PC of start code block into REG_LOCAL_1
|
||||
ASM_MOV_REG_PCREL(emit->as, REG_LOCAL_1, start_label);
|
||||
@@ -1221,8 +1226,8 @@ static void emit_native_global_exc_entry(emit_t *emit) {
|
||||
ASM_JUMP_IF_REG_NONZERO(emit->as, REG_RET, global_except_label, true);
|
||||
|
||||
// Clear PC of current code block, and jump there to resume execution
|
||||
ASM_XOR_REG_REG(emit->as, REG_TEMP0, REG_TEMP0);
|
||||
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_PC(emit), REG_TEMP0);
|
||||
ASM_CLR_REG(emit->as, REG_ZERO);
|
||||
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_PC(emit), REG_ZERO);
|
||||
ASM_JUMP_REG(emit->as, REG_LOCAL_1);
|
||||
|
||||
// Global exception handler: check for valid exception handler
|
||||
|
||||
Reference in New Issue
Block a user