Browse Source

py/asmrv32: Use REG_TEMP2 whenever possible.

The RV32 emitter used an additional temporary register, as certain code
sequences required extra storage.  This commit removes its usage in all
but one case, using REG_TEMP2 instead.

Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
pull/15575/head
Alessandro Gatti 3 months ago
committed by Damien George
parent
commit
7d8b2d89cc
  1. 46
      py/asmrv32.c

46
py/asmrv32.c

@ -312,8 +312,8 @@ void asm_rv32_emit_call_ind(asm_rv32_t *state, mp_uint_t index) {
if (FIT_UNSIGNED(offset, 11)) { if (FIT_UNSIGNED(offset, 11)) {
// lw temporary, offset(fun_table) // lw temporary, offset(fun_table)
// c.jalr temporary // c.jalr temporary
asm_rv32_opcode_lw(state, INTERNAL_TEMPORARY, REG_FUN_TABLE, offset); asm_rv32_opcode_lw(state, REG_TEMP2, REG_FUN_TABLE, offset);
asm_rv32_opcode_cjalr(state, INTERNAL_TEMPORARY); asm_rv32_opcode_cjalr(state, REG_TEMP2);
return; return;
} }
@ -321,16 +321,14 @@ void asm_rv32_emit_call_ind(asm_rv32_t *state, mp_uint_t index) {
mp_uint_t lower = 0; mp_uint_t lower = 0;
split_immediate(offset, &upper, &lower); split_immediate(offset, &upper, &lower);
// TODO: Can this clobber REG_TEMP[0:2]?
// lui temporary, HI(index) ; Or c.lui if possible // lui temporary, HI(index) ; Or c.lui if possible
// c.add temporary, fun_table // c.add temporary, fun_table
// lw temporary, LO(index)(temporary) // lw temporary, LO(index)(temporary)
// c.jalr temporary // c.jalr temporary
load_upper_immediate(state, INTERNAL_TEMPORARY, upper); load_upper_immediate(state, REG_TEMP2, upper);
asm_rv32_opcode_cadd(state, INTERNAL_TEMPORARY, REG_FUN_TABLE); asm_rv32_opcode_cadd(state, REG_TEMP2, REG_FUN_TABLE);
asm_rv32_opcode_lw(state, INTERNAL_TEMPORARY, INTERNAL_TEMPORARY, lower); asm_rv32_opcode_lw(state, REG_TEMP2, REG_TEMP2, lower);
asm_rv32_opcode_cjalr(state, INTERNAL_TEMPORARY); asm_rv32_opcode_cjalr(state, REG_TEMP2);
} }
void asm_rv32_emit_jump_if_reg_eq(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t label) { void asm_rv32_emit_jump_if_reg_eq(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t label) {
@ -350,15 +348,13 @@ void asm_rv32_emit_jump_if_reg_eq(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs
mp_uint_t lower = 0; mp_uint_t lower = 0;
split_immediate(displacement, &upper, &lower); split_immediate(displacement, &upper, &lower);
// TODO: Can this clobber REG_TEMP[0:2]?
// bne rs1, rs2, 12 ; PC + 0 // bne rs1, rs2, 12 ; PC + 0
// auipc temporary, HI(displacement) ; PC + 4 // auipc temporary, HI(displacement) ; PC + 4
// jalr zero, temporary, LO(displacement) ; PC + 8 // jalr zero, temporary, LO(displacement) ; PC + 8
// ... ; PC + 12 // ... ; PC + 12
asm_rv32_opcode_bne(state, rs1, rs2, 12); asm_rv32_opcode_bne(state, rs1, rs2, 12);
asm_rv32_opcode_auipc(state, INTERNAL_TEMPORARY, upper); asm_rv32_opcode_auipc(state, REG_TEMP2, upper);
asm_rv32_opcode_jalr(state, ASM_RV32_REG_ZERO, INTERNAL_TEMPORARY, lower); asm_rv32_opcode_jalr(state, ASM_RV32_REG_ZERO, REG_TEMP2, lower);
} }
void asm_rv32_emit_jump_if_reg_nonzero(asm_rv32_t *state, mp_uint_t rs, mp_uint_t label) { void asm_rv32_emit_jump_if_reg_nonzero(asm_rv32_t *state, mp_uint_t rs, mp_uint_t label) {
@ -377,8 +373,6 @@ void asm_rv32_emit_jump_if_reg_nonzero(asm_rv32_t *state, mp_uint_t rs, mp_uint_
return; return;
} }
// TODO: Can this clobber REG_TEMP[0:2]?
// if rs1 in C window and displacement is negative: // if rs1 in C window and displacement is negative:
// c.beqz rs', 10 ; PC + 0 // c.beqz rs', 10 ; PC + 0
// auipc temporary, HI(displacement) ; PC + 2 // auipc temporary, HI(displacement) ; PC + 2
@ -403,8 +397,8 @@ void asm_rv32_emit_jump_if_reg_nonzero(asm_rv32_t *state, mp_uint_t rs, mp_uint_
mp_uint_t upper = 0; mp_uint_t upper = 0;
mp_uint_t lower = 0; mp_uint_t lower = 0;
split_immediate(displacement, &upper, &lower); split_immediate(displacement, &upper, &lower);
asm_rv32_opcode_auipc(state, INTERNAL_TEMPORARY, upper); asm_rv32_opcode_auipc(state, REG_TEMP2, upper);
asm_rv32_opcode_jalr(state, ASM_RV32_REG_ZERO, INTERNAL_TEMPORARY, lower); asm_rv32_opcode_jalr(state, ASM_RV32_REG_ZERO, REG_TEMP2, lower);
} }
void asm_rv32_emit_mov_local_reg(asm_rv32_t *state, mp_uint_t local, mp_uint_t rs) { void asm_rv32_emit_mov_local_reg(asm_rv32_t *state, mp_uint_t local, mp_uint_t rs) {
@ -426,14 +420,12 @@ void asm_rv32_emit_mov_local_reg(asm_rv32_t *state, mp_uint_t local, mp_uint_t r
mp_uint_t lower = 0; mp_uint_t lower = 0;
split_immediate(offset, &upper, &lower); split_immediate(offset, &upper, &lower);
// TODO: Can this clobber REG_TEMP[0:2]?
// lui temporary, HI(offset) ; Or c.lui if possible // lui temporary, HI(offset) ; Or c.lui if possible
// c.add temporary, sp // c.add temporary, sp
// sw rs, LO(offset)(temporary) // sw rs, LO(offset)(temporary)
load_upper_immediate(state, INTERNAL_TEMPORARY, upper); load_upper_immediate(state, REG_TEMP2, upper);
asm_rv32_opcode_cadd(state, INTERNAL_TEMPORARY, ASM_RV32_REG_SP); asm_rv32_opcode_cadd(state, REG_TEMP2, ASM_RV32_REG_SP);
asm_rv32_opcode_sw(state, rs, INTERNAL_TEMPORARY, lower); asm_rv32_opcode_sw(state, rs, REG_TEMP2, lower);
} }
void asm_rv32_emit_mov_reg_local(asm_rv32_t *state, mp_uint_t rd, mp_uint_t local) { void asm_rv32_emit_mov_reg_local(asm_rv32_t *state, mp_uint_t rd, mp_uint_t local) {
@ -525,12 +517,10 @@ void asm_rv32_emit_jump(asm_rv32_t *state, mp_uint_t label) {
mp_uint_t lower = 0; mp_uint_t lower = 0;
split_immediate(displacement, &upper, &lower); split_immediate(displacement, &upper, &lower);
// TODO: Can this clobber REG_TEMP[0:2]?
// auipc temporary, HI(displacement) // auipc temporary, HI(displacement)
// jalr zero, temporary, LO(displacement) // jalr zero, temporary, LO(displacement)
asm_rv32_opcode_auipc(state, INTERNAL_TEMPORARY, upper); asm_rv32_opcode_auipc(state, REG_TEMP2, upper);
asm_rv32_opcode_jalr(state, ASM_RV32_REG_ZERO, INTERNAL_TEMPORARY, lower); asm_rv32_opcode_jalr(state, ASM_RV32_REG_ZERO, REG_TEMP2, lower);
} }
void asm_rv32_emit_store_reg_reg_offset(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) { void asm_rv32_emit_store_reg_reg_offset(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) {
@ -549,9 +539,9 @@ void asm_rv32_emit_store_reg_reg_offset(asm_rv32_t *state, mp_uint_t rd, mp_uint
// lui temporary, HI(offset) ; Or c.lui if possible // lui temporary, HI(offset) ; Or c.lui if possible
// c.add temporary, rs // c.add temporary, rs
// sw rd, LO(offset)(temporary) // sw rd, LO(offset)(temporary)
load_upper_immediate(state, INTERNAL_TEMPORARY, upper); load_upper_immediate(state, REG_TEMP2, upper);
asm_rv32_opcode_cadd(state, INTERNAL_TEMPORARY, rs); asm_rv32_opcode_cadd(state, REG_TEMP2, rs);
asm_rv32_opcode_sw(state, rd, INTERNAL_TEMPORARY, lower); asm_rv32_opcode_sw(state, rd, REG_TEMP2, lower);
} }
void asm_rv32_emit_mov_reg_pcrel(asm_rv32_t *state, mp_uint_t rd, mp_uint_t label) { void asm_rv32_emit_mov_reg_pcrel(asm_rv32_t *state, mp_uint_t rd, mp_uint_t label) {

Loading…
Cancel
Save