mirror of
https://github.com/micropython/micropython.git
synced 2025-12-16 01:40:14 +01:00
py/asmrv32: Refactor register-indexed load/store emitters.
This commit shortens register-indexed load/store emitter functions, by reusing integer-indexed equivalent operations as part of the sequence generation process. Before these changes, register-indexed load/store emitters would follow two steps to generate the sequence: generate opcodes to fix up the register offset to make it point to the exact position in memory where the operation should take place, and then perform the load/store operation itself using 0 as an offset from the recalculated address register. Since there is already a generic optimised emitter for integer-indexed load/stores, that bit of code can be reused rather than having an ad-hoc implementation that is tailored to operate on an offset of 0. Removing the custom emitter code in favour of calling the general integer-indexed emitter saves around 150 bytes without any changes in the emitter behaviour (generating the same opcode sequence and making use of future improvement in that emitter too). Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit is contained in:
committed by
Damien George
parent
385e4f3d0c
commit
a1684ad2c1
16
py/asmrv32.c
16
py/asmrv32.c
@@ -577,24 +577,12 @@ static void asm_rv32_fix_up_scaled_reg_reg_reg(asm_rv32_t *state, mp_uint_t rs1,
|
||||
|
||||
void asm_rv32_emit_load_reg_reg_reg(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t operation_size) {
|
||||
asm_rv32_fix_up_scaled_reg_reg_reg(state, rs1, rs2, operation_size);
|
||||
if (operation_size == 2 && RV32_IS_IN_C_REGISTER_WINDOW(rd) && RV32_IS_IN_C_REGISTER_WINDOW(rs1)) {
|
||||
// c.lw rd', offset(rs')
|
||||
asm_rv32_opcode_clw(state, RV32_MAP_IN_C_REGISTER_WINDOW(rd), RV32_MAP_IN_C_REGISTER_WINDOW(rs1), 0);
|
||||
} else {
|
||||
// lbu|lhu|lw rd, offset(rs)
|
||||
asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x03, RV32_LOAD_OPCODE_TABLE[operation_size], rd, rs1, 0));
|
||||
}
|
||||
asm_rv32_emit_load_reg_reg_offset(state, rd, rs1, 0, operation_size);
|
||||
}
|
||||
|
||||
void asm_rv32_emit_store_reg_reg_reg(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t operation_size) {
|
||||
asm_rv32_fix_up_scaled_reg_reg_reg(state, rs1, rs2, operation_size);
|
||||
if (operation_size == 2 && RV32_IS_IN_C_REGISTER_WINDOW(rd) && RV32_IS_IN_C_REGISTER_WINDOW(rs1)) {
|
||||
// c.sw rd', offset(rs')
|
||||
asm_rv32_opcode_csw(state, RV32_MAP_IN_C_REGISTER_WINDOW(rd), RV32_MAP_IN_C_REGISTER_WINDOW(rs1), 0);
|
||||
} else {
|
||||
// sb|sh|sw rd, offset(rs)
|
||||
asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_S(0x23, operation_size, rs1, rd, 0));
|
||||
}
|
||||
asm_rv32_emit_store_reg_reg_offset(state, rd, rs1, 0, operation_size);
|
||||
}
|
||||
|
||||
void asm_rv32_meta_comparison_eq(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd) {
|
||||
|
||||
Reference in New Issue
Block a user