Skip to content

Commit 3dd1130

Browse files
agattidpgeorge
authored andcommitted
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 <[email protected]>
1 parent 99f5659 commit 3dd1130

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

py/emitnative.c

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,12 @@ static const uint8_t reg_local_table[MAX_REGS_FOR_LOCAL_VARS] = {REG_LOCAL_1, RE
178178
*emit->error_slot = mp_obj_new_exception_msg_varg(&mp_type_ViperTypeError, __VA_ARGS__); \
179179
} while (0)
180180

181+
#if N_RV32
182+
#define FIT_SIGNED(value, bits) \
183+
((((value) & ~((1U << ((bits) - 1)) - 1)) == 0) || \
184+
(((value) & ~((1U << ((bits) - 1)) - 1)) == ~((1U << ((bits) - 1)) - 1)))
185+
#endif
186+
181187
typedef enum {
182188
STACK_VALUE,
183189
STACK_REG,
@@ -1519,6 +1525,11 @@ static void emit_native_load_subscr(emit_t *emit) {
15191525
asm_thumb_ldrb_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value);
15201526
break;
15211527
}
1528+
#elif N_RV32
1529+
if (FIT_SIGNED(index_value, 12)) {
1530+
asm_rv32_opcode_lbu(emit->as, REG_RET, reg_base, index_value);
1531+
break;
1532+
}
15221533
#endif
15231534
need_reg_single(emit, reg_index, 0);
15241535
ASM_MOV_REG_IMM(emit->as, reg_index, index_value);
@@ -1537,6 +1548,11 @@ static void emit_native_load_subscr(emit_t *emit) {
15371548
asm_thumb_ldrh_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value);
15381549
break;
15391550
}
1551+
#elif N_RV32
1552+
if (FIT_SIGNED(index_value, 11)) {
1553+
asm_rv32_opcode_lhu(emit->as, REG_RET, reg_base, index_value << 1);
1554+
break;
1555+
}
15401556
#endif
15411557
need_reg_single(emit, reg_index, 0);
15421558
ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 1);
@@ -1555,6 +1571,11 @@ static void emit_native_load_subscr(emit_t *emit) {
15551571
asm_thumb_ldr_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value);
15561572
break;
15571573
}
1574+
#elif N_RV32
1575+
if (FIT_SIGNED(index_value, 10)) {
1576+
asm_rv32_opcode_lw(emit->as, REG_RET, reg_base, index_value << 2);
1577+
break;
1578+
}
15581579
#endif
15591580
need_reg_single(emit, reg_index, 0);
15601581
ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 2);
@@ -1596,6 +1617,12 @@ static void emit_native_load_subscr(emit_t *emit) {
15961617
}
15971618
case VTYPE_PTR32: {
15981619
// pointer to word-size memory
1620+
#if N_RV32
1621+
asm_rv32_opcode_slli(emit->as, REG_TEMP2, reg_index, 2);
1622+
asm_rv32_opcode_cadd(emit->as, REG_ARG_1, REG_TEMP2);
1623+
asm_rv32_opcode_lw(emit->as, REG_RET, REG_ARG_1, 0);
1624+
break;
1625+
#endif
15991626
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
16001627
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
16011628
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) {
17511778
asm_thumb_strb_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value);
17521779
break;
17531780
}
1781+
#elif N_RV32
1782+
if (FIT_SIGNED(index_value, 12)) {
1783+
asm_rv32_opcode_sb(emit->as, reg_value, reg_base, index_value);
1784+
break;
1785+
}
17541786
#endif
17551787
ASM_MOV_REG_IMM(emit->as, reg_index, index_value);
17561788
#if N_ARM
@@ -1772,6 +1804,11 @@ static void emit_native_store_subscr(emit_t *emit) {
17721804
asm_thumb_strh_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value);
17731805
break;
17741806
}
1807+
#elif N_RV32
1808+
if (FIT_SIGNED(index_value, 11)) {
1809+
asm_rv32_opcode_sh(emit->as, reg_value, reg_base, index_value << 1);
1810+
break;
1811+
}
17751812
#endif
17761813
ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 1);
17771814
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) {
17891826
asm_thumb_str_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value);
17901827
break;
17911828
}
1792-
#endif
1793-
#if N_ARM
1829+
#elif N_RV32
1830+
if (FIT_SIGNED(index_value, 10)) {
1831+
asm_rv32_opcode_sw(emit->as, reg_value, reg_base, index_value << 2);
1832+
break;
1833+
}
1834+
#elif N_ARM
17941835
ASM_MOV_REG_IMM(emit->as, reg_index, index_value);
17951836
asm_arm_str_reg_reg_reg(emit->as, reg_value, reg_base, reg_index);
17961837
return;
@@ -1855,6 +1896,11 @@ static void emit_native_store_subscr(emit_t *emit) {
18551896
#if N_ARM
18561897
asm_arm_str_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
18571898
break;
1899+
#elif N_RV32
1900+
asm_rv32_opcode_slli(emit->as, REG_TEMP2, reg_index, 2);
1901+
asm_rv32_opcode_cadd(emit->as, REG_ARG_1, REG_TEMP2);
1902+
asm_rv32_opcode_sw(emit->as, reg_value, REG_ARG_1, 0);
1903+
break;
18581904
#endif
18591905
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
18601906
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base

0 commit comments

Comments
 (0)