8000 py/emitnative: Refactor Viper register-indexed load/stores. · micropython/micropython@b6d269e · GitHub
[go: up one dir, main page]

Skip to content

Commit b6d269e

Browse files
committed
py/emitnative: Refactor Viper register-indexed load/stores.
This commit cleans up the Viper code generation blocks for register-indexed load and store operations. An attempt is made to simplify the code in the common code generator code block, by moving architecture-specific code to the appropriate native generation backends whenever possible. This should make that specific bit of code in the Viper generator clearer and easier to maintain in the long term. To achieve this, six generic assembler meta-opcodes have been introduced, named `ASM_{LOAD,STORE}{8,16,32}_REG_REG_REG`. A platform-independent implementation for those operations is provided, so backends that cannot emit a shorter sequence for the requested operation or are fine with the platform-independent implementation can just not provide said meta-opcodes. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
1 parent 04c6b99 commit b6d269e

File tree

6 files changed

+98
-95
lines changed

6 files changed

+98
-95
lines changed

py/asmarm.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,13 @@ void asm_arm_bx_reg(asm_arm_t *as, uint reg_src);
221221
#define ASM_STORE16_REG_REG(as, reg_value, reg_base) asm_arm_strh_reg_reg((as), (reg_value), (reg_base))
222222
#define ASM_STORE32_REG_REG(as, reg_value, reg_base) asm_arm_str_reg_reg((as), (reg_value), (reg_base), 0)
223223

224+
#define ASM_LOAD8_REG_REG_REG(as, reg_dest, reg_base, reg_index) asm_arm_ldrb_reg_reg_reg((as), (reg_dest), (reg_base), (reg_index))
225+
#define ASM_LOAD16_REG_REG_REG(as, reg_dest, reg_base, reg_index) asm_arm_ldrh_reg_reg_reg((as), (reg_dest), (reg_base), (reg_index))
226+
#define ASM_LOAD32_REG_REG_REG(as, reg_dest, reg_base, reg_index) asm_arm_ldr_reg_reg_reg((as), (reg_dest), (reg_base), (reg_index))
227+
#define ASM_STORE8_REG_REG_REG(as, reg_val, reg_base, reg_index) asm_arm_strb_reg_reg_reg((as), (reg_val), (reg_base), (reg_index))
228+
#define ASM_STORE16_REG_REG_REG(as, reg_val, reg_base, reg_index) asm_arm_strh_reg_reg_reg((as), (reg_val), (reg_base), (reg_index))
229+
#define ASM_STORE32_REG_REG_REG(as, reg_val, reg_base, reg_index) asm_arm_str_reg_reg_reg((as), (reg_val), (reg_base), (reg_index))
230+
224231
#endif // GENERIC_ASM_API
225232

226233
#endif // MICROPY_INCLUDED_PY_ASMARM_H

py/asmrv32.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,30 @@ void asm_rv32_emit_store_reg_reg_offset(asm_rv32_t *state, mp_uint_t source, mp_
758758
#define ASM_SUB_REG_REG(state, rd, rs) asm_rv32_opcode_sub(state, rd, rd, rs)
759759
#define ASM_XOR_REG_REG(state, rd, rs) asm_rv32_emit_optimised_xor(state, rd, rs)
760760
#define ASM_CLR_REG(state, rd)
761+
#define ASM_LOAD16_REG_REG_REG(state, rd, rs1, rs2) \
762+
do { \
763+
asm_rv32_opcode_slli(state, rs2, rs2, 1); \
764+
asm_rv32_opcode_cadd(state, rs1, rs2); \
765+
asm_rv32_opcode_lhu(state, rd, rs1, 0); \
766+
} while (0)
767+
#define ASM_LOAD32_REG_REG_REG(state, rd, rs1, rs2) \
768+
do { \
769+
asm_rv32_opcode_slli(state, rs2, rs2, 2); \
770+
asm_rv32_opcode_cadd(state, rs1, rs2); \
771+
asm_rv32_opcode_lw(state, rd, rs1, 0); \
772+
} while (0)
773+
#define ASM_STORE16_REG_REG_REG(state, rd, rs1, rs2) \
774+
do { \
775+
asm_rv32_opcode_slli(state, rs2, rs2, 1); \
776+
asm_rv32_opcode_cadd(state, rs1, rs2); \
777+
asm_rv32_opcode_sh(state, rd, rs1, 0); \
778+
} while (0)
779+
#define ASM_STORE32_REG_REG_REG(state, rd, rs1, rs2) \
780+
do { \
781+
asm_rv32_opcode_slli(state, rs2, rs2, 2); \
782+
asm_rv32_opcode_cadd(state, rs1, rs2); \
783+
asm_rv32_opcode_sw(state, rd, rs1, 0); \
784+
} while (0)
< 57A7 /td>
761785

762786
#endif
763787

py/asmthumb.c

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -491,26 +491,6 @@ void asm_thumb_ldrh_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint r
491491
}
492492
}
493493

494-
void asm_thumb_ldrh_reg_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_base, uint reg_index) {
495-
asm_thumb_lsl_rlo_rlo_i5(as, reg_index, reg_index, 1);
496-
asm_thumb_ldrh_rlo_rlo_rlo(as, reg_dest, reg_base, reg_index);
497-
}
498-
499-
void asm_thumb_ldr_reg_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_base, uint reg_index) {
500-
asm_thumb_lsl_rlo_rlo_i5(as, reg_index, reg_index, 2);
501-
asm_thumb_ldr_rlo_rlo_rlo(as, reg_dest, reg_base, reg_index);
502-
}
503-
504-
void asm_thumb_strh_reg_reg_reg(asm_thumb_t *as, uint reg_val, uint reg_base, uint reg_index) {
505-
asm_thumb_lsl_rlo_rlo_i5(as, reg_index, reg_index, 1);
506-
asm_thumb_strh_rlo_rlo_rlo(as, reg_val, reg_base, reg_index);
507-
}
508-
509-
void asm_thumb_str_reg_reg_reg(asm_thumb_t *as, uint reg_val, uint reg_base, uint reg_index) {
510-
asm_thumb_lsl_rlo_rlo_i5(as, reg_index, reg_index, 2);
511-
asm_thumb_str_rlo_rlo_rlo(as, reg_val, reg_base, reg_index);
512-
}
513-
514494
// this could be wrong, because it should have a range of +/- 16MiB...
515495
#define OP_BW_HI(byte_offset) (0xf000 | (((byte_offset) >> 12) & 0x07ff))
516496
#define OP_BW_LO(byte_offset) (0xb800 | (((byte_offset) >> 1) & 0x07ff))

py/asmthumb.h

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -385,11 +385,6 @@ void asm_thumb_mov_reg_pcrel(asm_thumb_t *as, uint rlo_dest, uint label);
385385
void asm_thumb_ldr_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint word_offset); // convenience
386386
void asm_thumb_ldrh_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint uint16_offset); // convenience
387387

388-
void asm_thumb_ldrh_reg_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_base, uint reg_index);
389-
void asm_thumb_ldr_reg_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_base, uint reg_index);
390-
void asm_thumb_strh_reg_reg_reg(asm_thumb_t *as, uint reg_val, uint reg_base, uint reg_index);
391-
void asm_thumb_str_reg_reg_reg(asm_thumb_t *as, uint reg_val, uint reg_base, uint reg_index);
392-
393388
void asm_thumb_b_label(asm_thumb_t *as, uint label); // convenience: picks narrow or wide branch
394389
void asm_thumb_bcc_label(asm_thumb_t *as, int cc, uint label); // convenience: picks narrow or wide branch
395390
void asm_thumb_bl_ind(asm_thumb_t *as, uint fun_id, uint reg_temp); // convenience
@@ -480,6 +475,29 @@ void asm_thumb_b_rel12(asm_thumb_t *as, int rel);
480475
#define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_thumb_strh_rlo_rlo_i5((as), (reg_src), (reg_base), 0)
481476
#define ASM_STORE32_REG_REG(as, reg_src, reg_base) asm_thumb_str_rlo_rlo_i5((as), (reg_src), (reg_base), 0)
482477

478+
#define ASM_LOAD8_REG_REG_REG(as, reg_dest, reg_base, reg_index) asm_thumb_ldrb_rlo_rlo_rlo((as), (reg_dest), (reg_base), (reg_index))
479+
#define ASM_LOAD16_REG_REG_REG(as, reg_dest, reg_base, reg_index) \
480+
do { \
481+
asm_thumb_lsl_rlo_rlo_i5((as), (reg_index), (reg_index), 1); \
482+
asm_thumb_ldrh_rlo_rlo_rlo((as), (reg_dest), (reg_base), (reg_index)); \
483+
} while (0)
484+
#define ASM_LOAD32_REG_REG_REG(as, reg_dest, reg_base, reg_index) \
485+
do { \
486+
asm_thumb_lsl_rlo_rlo_i5((as), (reg_index), (reg_index), 2); \
487+
asm_thumb_ldr_rlo_rlo_rlo((as), (reg_dest), (reg_base), (reg_index)); \
488+
} while (0)
489+
#define ASM_STORE8_REG_REG_REG(as, reg_val, reg_base, reg_index) asm_thumb_strb_rlo_rlo_rlo((as), (reg_val), (reg_base), (reg_index))
490+
#define ASM_STORE16_REG_REG_REG(as, reg_val, reg_base, reg_index) \
491+
do { \
492+
asm_thumb_lsl_rlo_rlo_i5((as), (reg_index), (reg_index), 1); \
493+
asm_thumb_strh_rlo_rlo_rlo((as), (reg_val), (reg_base), (reg_index)); \
494+
} while (0)
495+
#define ASM_STORE32_REG_REG_REG(as, reg_val, reg_base, reg_index) \
496+
do { \
497+
asm_thumb_lsl_rlo_rlo_i5((as), (reg_index), (reg_index), 2); \
498+
asm_thumb_str_rlo_rlo_rlo((as), (reg_val), (reg_base), (reg_index)); \
499+
} while (0)
500+
483501
#endif // GENERIC_ASM_API
484502

485503
#endif // MICROPY_INCLUDED_PY_ASMTHUMB_H

py/asmxtensa.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,12 +411,32 @@ void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx);
411411
#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l8ui((as), (reg_dest), (reg_base), 0)
412412
#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), 0)
413413
#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), (uint16_offset))
414+
#define ASM_LOAD16_REG_REG_REG(as, reg_dest, reg_base, reg_index) \
415+
do { \
416+
asm_xtensa_op_addx2((as), (reg_base), (reg_index), (reg_base)); \
417+
asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), 0); \
418+
} while (0)
414419
#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l32i_n((as), (reg_dest), (reg_base), 0)
420+
#define ASM_LOAD32_REG_REG_REG(as, reg_dest, reg_base, reg_index) \
421+
do { \
422+
asm_xtensa_op_addx4((as), (reg_base), (reg_index), (reg_base)); \
423+
asm_xtensa_op_l32i_n((as), (reg_dest), (reg_base), 0); \
424+
} while (0)
415425

416426
#define ASM_STORE_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_xtensa_s32i_optimised((as), (reg_dest), (reg_base), (word_offset))
417427
#define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_xtensa_op_s8i((as), (reg_src), (reg_base), 0)
418428
#define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_xtensa_op_s16i((as), (reg_src), (reg_base), 0)
429+
#define ASM_STORE16_REG_REG_REG(as, reg_val, reg_base, reg_index) \
430+
do { \
431+
asm_xtensa_op_addx2((as), (reg_base), (reg_index), (reg_base)); \
432+
asm_xtensa_op_s16i((as), (reg_val), (reg_base), 0); \
433+
} while (0)
419434
#define ASM_STORE32_REG_REG(as, reg_src, reg_base) asm_xtensa_op_s32i_n((as), (reg_src), (reg_base), 0)
435+
#define ASM_STORE32_REG_REG_REG(as, reg_val, reg_base, reg_index) \
436+
do { \
437+
asm_xtensa_op_addx4((as), (reg_base), (reg_index), (reg_base)); \
438+
asm_xtensa_op_s32i_n((as), (reg_val), (reg_base), 0); \
439+
} while (0)
420440

421441
#endif // GENERIC_ASM_API
422442

py/emitnative.c

Lines changed: 24 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,59 +1638,36 @@ static void emit_native_load_subscr(emit_t *emit) {
16381638
switch (vtype_base) {
16391639
case VTYPE_PTR8: {
16401640
// pointer to 8-bit memory
1641-
#if N_ARM
1642-
asm_arm_ldrb_reg_reg_reg(emit->as, REG_RET, REG_ARG_1, reg_index);
1643-
break;
1644-
#elif N_THUMB
1645-
asm_thumb_ldrb_rlo_rlo_rlo(emit->as, REG_RET, REG_ARG_1, reg_index);
1646-
break;
1647-
#endif
1648-
// TODO optimise to use thumb ldrb r1, [r2, r3]
1641+
#ifdef ASM_LOAD8_REG_REG_REG
1642+
ASM_LOAD8_REG_REG_REG(emit->as, REG_RET, REG_ARG_1, reg_index);
1643+
#else
16491644
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
16501645
ASM_LOAD8_REG_REG(emit->as, REG_RET, REG_ARG_1); // store value to (base+index)
1646+
#endif
16511647
break;
16521648
}
16531649
case VTYPE_PTR16: {
16541650
// pointer to 16-bit memory
1655-
#if N_ARM
1656-
asm_arm_ldrh_reg_reg_reg(emit->as, REG_RET, REG_ARG_1, reg_index);
1657-
break;
1658-
#elif N_THUMB
1659-
asm_thumb_ldrh_reg_reg_reg(emit->as, REG_RET, REG_ARG_1, reg_index);
1660-
break;
1661-
#elif N_XTENSA || N_XTENSAWIN
1662-
asm_xtensa_op_addx2(emit->as, REG_ARG_1, reg_index, REG_ARG_1);
1663-
asm_xtensa_op_l16ui(emit->as, REG_RET, REG_ARG_1, 0);
1664-
break;
1665-
#endif
1651+
#ifdef ASM_LOAD16_REG_REG_REG
1652+
ASM_LOAD16_REG_REG_REG(emit->as, REG_RET, REG_ARG_1, reg_index);
1653+
#else
16661654
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
16671655
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
16681656
ASM_LOAD16_REG_REG(emit->as, REG_RET, REG_ARG_1); // load from (base+2*index)
1657+
#endif
16691658
break;
16701659
}
16711660
case VTYPE_PTR32: {
16721661
// pointer to word-size memory
1673-
#if N_ARM
1674-
asm_arm_ldr_reg_reg_reg(emit->as, REG_RET, REG_ARG_1, reg_index);
1675-
break;
1676-
#elif N_THUMB
1677-
asm_thumb_ldr_reg_reg_reg(emit->as, REG_RET, REG_ARG_1, reg_index);
1678-
break;
1679-
#elif N_RV32
1680-
asm_rv32_opcode_slli(emit->as, REG_TEMP2, reg_index, 2);
1681-
asm_rv32_opcode_cadd(emit->as, REG_ARG_1, REG_TEMP2);
1682-
asm_rv32_opcode_lw(emit->as, REG_RET, REG_ARG_1, 0);
1683-
break;
1684-
#elif N_XTENSA || N_XTENSAWIN
1685-
asm_xtensa_op_addx4(emit->as, REG_ARG_1, reg_index, REG_ARG_1);
1686-
asm_xtensa_op_l32i_n(emit->as, REG_RET, REG_ARG_1, 0);
1687-
break;
1688-
#endif
1662+
#ifdef ASM_LOAD32_REG_REG_REG
1663+
ASM_LOAD32_REG_REG_REG(emit->as, REG_RET, REG_ARG_1, reg_index);
1664+
#else
16891665
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
16901666
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
16911667
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
16921668
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
16931669
ASM_LOAD32_REG_REG(emit->as, REG_RET, REG_ARG_1); // load from (base+4*index)
1670+
#endif
16941671
break;
16951672
}
16961673
default:
@@ -1949,59 +1926,36 @@ static void emit_native_store_subscr(emit_t *emit) {
19491926
switch (vtype_base) {
19501927
case VTYPE_PTR8: {
19511928
// pointer to 8-bit memory
1952-
// TODO optimise to use thumb strb r1, [r2, r3]
1953-
#if N_ARM
1954-
asm_arm_strb_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
1955-
break;
1956-
#elif N_THUMB
1957-
asm_thumb_strb_rlo_rlo_rlo(emit->as, reg_value, REG_ARG_1, reg_index);
1958-
break;
1959-
#endif
1929+
#ifdef ASM_STORE8_REG_REG_REG
1930+
ASM_STORE8_REG_REG_REG(emit->as, reg_value, REG_ARG_1, reg_index);
1931+
#else
19601932
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
19611933
ASM_STORE8_REG_REG(emit->as, reg_value, REG_ARG_1); // store value to (base+index)
1934+
#endif
19621935
break;
19631936
}
19641937
case VTYPE_PTR16: {
19651938
// pointer to 16-bit memory
1966-
#if N_ARM
1967-
asm_arm_strh_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
1968-
break;
1969-
#elif N_THUMB
1970-
asm_thumb_strh_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
1971-
break;
1972-
#elif N_XTENSA || N_XTENSAWIN
1973-
asm_xtensa_op_addx2(emit->as, REG_ARG_1, reg_index, REG_ARG_1);
1974-
asm_xtensa_op_s16i(emit->as, reg_value, REG_ARG_1, 0);
1975-
break;
1976-
#endif
1939+
#ifdef ASM_STORE16_REG_REG_REG
1940+
ASM_STORE16_REG_REG_REG(emit->as, reg_value, REG_ARG_1, reg_index);
1941+
#else
19771942
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
19781943
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
19791944
ASM_STORE16_REG_REG(emit->as, reg_value, REG_ARG_1); // store value to (base+2*index)
1945+
#endif
19801946
break;
19811947
}
19821948
case VTYPE_PTR32: {
19831949
// pointer to 32-bit memory
1984-
#if N_ARM
1985-
asm_arm_str_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
1986-
break;
1987-
#elif N_THUMB
1988-
asm_thumb_str_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
1989-
break;
1990-
#elif N_RV32
1991-
asm_rv32_opcode_slli(emit->as, REG_TEMP2, reg_index, 2);
1992-
asm_rv32_opcode_cadd(emit->as, REG_ARG_1, REG_TEMP2);
1993-
asm_rv32_opcode_sw(emit->as, reg_value, REG_ARG_1, 0);
1994-
break;
1995-
#elif N_XTENSA || N_XTENSAWIN
1996-
asm_xtensa_op_addx4(emit->as, REG_ARG_1, reg_index, REG_ARG_1);
1997-
asm_xtensa_op_s32i_n(emit->as, reg_value, REG_ARG_1, 0);
1998-
break;
1999-
#endif
1950+
#ifdef ASM_STORE32_REG_REG_REG
1951+
ASM_STORE32_REG_REG_REG(emit->as, reg_value, REG_ARG_1, reg_index);
1952+
#else
20001953
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
20011954
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
20021955
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
20031956
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
20041957
ASM_STORE32_REG_REG(emit->as, reg_value, REG_ARG_1); // s 4D62 tore value to (base+4*index)
1958+
#endif
20051959
break;
20061960
}
20071961
default:

0 commit comments

Comments
 (0)
0