diff options
author | Alessandro Gatti <a.gatti@frob.it> | 2024-06-14 19:43:47 +0200 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2024-06-21 15:06:52 +1000 |
commit | 3dd1130f6d85e9d378609fb244332d52a6caa059 (patch) | |
tree | cda1a1978caa281c7871dd208073a90ffabd9f7a /py | |
parent | 99f5659cf5fa84d3b9dc8bbd286315fcf56ad899 (diff) | |
download | micropython-3dd1130f6d85e9d378609fb244332d52a6caa059.tar.gz micropython-3dd1130f6d85e9d378609fb244332d52a6caa059.zip |
py/emitnative: Emit better load/store sequences for RISC-V RV32IMC.
Selected load/store code sequences have been optimised for RV32IMC when the
chance to use fewer and smaller opcodes was possible.
Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
Diffstat (limited to 'py')
-rw-r--r-- | py/emitnative.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/py/emitnative.c b/py/emitnative.c index 7557e4ba48..3294fd9ea3 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -178,6 +178,12 @@ static const uint8_t reg_local_table[MAX_REGS_FOR_LOCAL_VARS] = {REG_LOCAL_1, RE *emit->error_slot = mp_obj_new_exception_msg_varg(&mp_type_ViperTypeError, __VA_ARGS__); \ } while (0) +#if N_RV32 +#define FIT_SIGNED(value, bits) \ + ((((value) & ~((1U << ((bits) - 1)) - 1)) == 0) || \ + (((value) & ~((1U << ((bits) - 1)) - 1)) == ~((1U << ((bits) - 1)) - 1))) +#endif + typedef enum { STACK_VALUE, STACK_REG, @@ -1519,6 +1525,11 @@ static void emit_native_load_subscr(emit_t *emit) { asm_thumb_ldrb_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value); break; } + #elif N_RV32 + if (FIT_SIGNED(index_value, 12)) { + asm_rv32_opcode_lbu(emit->as, REG_RET, reg_base, index_value); + break; + } #endif need_reg_single(emit, reg_index, 0); ASM_MOV_REG_IMM(emit->as, reg_index, index_value); @@ -1537,6 +1548,11 @@ static void emit_native_load_subscr(emit_t *emit) { asm_thumb_ldrh_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value); break; } + #elif N_RV32 + if (FIT_SIGNED(index_value, 11)) { + asm_rv32_opcode_lhu(emit->as, REG_RET, reg_base, index_value << 1); + break; + } #endif need_reg_single(emit, reg_index, 0); ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 1); @@ -1555,6 +1571,11 @@ static void emit_native_load_subscr(emit_t *emit) { asm_thumb_ldr_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value); break; } + #elif N_RV32 + if (FIT_SIGNED(index_value, 10)) { + asm_rv32_opcode_lw(emit->as, REG_RET, reg_base, index_value << 2); + break; + } #endif need_reg_single(emit, reg_index, 0); ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 2); @@ -1596,6 +1617,12 @@ static void emit_native_load_subscr(emit_t *emit) { } case VTYPE_PTR32: { // pointer to word-size memory + #if N_RV32 + asm_rv32_opcode_slli(emit->as, REG_TEMP2, reg_index, 2); + asm_rv32_opcode_cadd(emit->as, REG_ARG_1, REG_TEMP2); + asm_rv32_opcode_lw(emit->as, REG_RET, REG_ARG_1, 0); + break; + #endif ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base @@ -1751,6 +1778,11 @@ static void emit_native_store_subscr(emit_t *emit) { asm_thumb_strb_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value); break; } + #elif N_RV32 + if (FIT_SIGNED(index_value, 12)) { + asm_rv32_opcode_sb(emit->as, reg_value, reg_base, index_value); + break; + } #endif ASM_MOV_REG_IMM(emit->as, reg_index, index_value); #if N_ARM @@ -1772,6 +1804,11 @@ static void emit_native_store_subscr(emit_t *emit) { asm_thumb_strh_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value); break; } + #elif N_RV32 + if (FIT_SIGNED(index_value, 11)) { + asm_rv32_opcode_sh(emit->as, reg_value, reg_base, index_value << 1); + break; + } #endif ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 1); ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 2*index to base @@ -1789,8 +1826,12 @@ static void emit_native_store_subscr(emit_t *emit) { asm_thumb_str_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value); break; } - #endif - #if N_ARM + #elif N_RV32 + if (FIT_SIGNED(index_value, 10)) { + asm_rv32_opcode_sw(emit->as, reg_value, reg_base, index_value << 2); + break; + } + #elif N_ARM ASM_MOV_REG_IMM(emit->as, reg_index, index_value); asm_arm_str_reg_reg_reg(emit->as, reg_value, reg_base, reg_index); return; @@ -1855,6 +1896,11 @@ static void emit_native_store_subscr(emit_t *emit) { #if N_ARM asm_arm_str_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index); break; + #elif N_RV32 + asm_rv32_opcode_slli(emit->as, REG_TEMP2, reg_index, 2); + asm_rv32_opcode_cadd(emit->as, REG_ARG_1, REG_TEMP2); + asm_rv32_opcode_sw(emit->as, reg_value, REG_ARG_1, 0); + break; #endif ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base |