8000 py/asmxtensa: Extend existing specialised load/store operations range. · Carglglz/micropython@84ad2c6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 84ad2c6

Browse files
agattidpgeorge
authored andcommitted
py/asmxtensa: Extend existing specialised load/store operations range.
This commit updates the existing specialised implementations for int-indexed 32-bit load and store operations, and adds a specialised implementation for int-indexed 16-bit load. The 32-bit operations relied on the fact that their applicability was limited to a specific range, falling back on a generic implementation otherwise. Introducing a single entry point for each int-indexed load/store operation size would break that assumption. Now those two operations contain fallback code to generate working code by themselves instead of raising an exception. The 16-bit operation instead simply did not have any range check, but it was not exposed directly to the Viper emitter. When a 16-bit int-indexed load entry point was introduced, the existing implementation would fail when accessing memory outside its 0..255 halfwords range. A specialised implementation is now present, performing fewer operations than the existing Viper emitter equivalent. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
1 parent 1f5ba69 commit 84ad2c6

File tree

3 files changed

+29
-18
lines changed

3 files changed

+29
-18
lines changed

py/asmxtensa.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@
3434

3535
#include "py/asmxtensa.h"
3636

37+
#if N_XTENSAWIN
38+
#define REG_TEMP ASM_XTENSA_REG_TEMPORARY_WIN
39+
#else
40+
#define REG_TEMP ASM_XTENSA_REG_TEMPORARY
41+
#endif
42+
3743
#define WORD_SIZE (4)
3844
#define SIGNED_FIT8(x) ((((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80))
3945
#define SIGNED_FIT12(x) ((((x) & 0xfffff800) == 0) || (((x) & 0xfffff800) == 0xfffff800))
@@ -248,7 +254,9 @@ void asm_xtensa_l32i_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, u
248254
} else if (word_offset < 256) {
249255
asm_xtensa_op_l32i(as, reg_dest, reg_base, word_offset);
250256
} else {
251-
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("asm overflow"));
257+
asm_xtensa_mov_reg_i32_optimised(as, reg_dest, word_offset * 4);
258+
asm_xtensa_op_add_n(as, reg_dest, reg_base, reg_dest);
259+
asm_xtensa_op_l32i_n(as, reg_dest, reg_dest, 0);
252260
}
253261
}
254262

@@ -258,7 +266,19 @@ void asm_xtensa_s32i_optimised(asm_xtensa_t *as, uint reg_src, uint reg_base, ui
258266
} else if (word_offset < 256) {
259267
asm_xtensa_op_s32i(as, reg_src, reg_base, word_offset);
260268
} else {
261-
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("asm overflow"));
269+
asm_xtensa_mov_reg_i32_optimised(as, REG_TEMP, word_offset * 4);
270+
asm_xtensa_op_add_n(as, REG_TEMP, reg_base, REG_TEMP);
271+
asm_xtensa_op_s32i_n(as, reg_src, REG_TEMP, 0);
272+
}
273+
}
274+
275+
void asm_xtensa_l16ui_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint halfword_offset) {
276+
if (halfword_offset < 256) {
277+
asm_xtensa_op_l16ui(as, reg_dest, reg_base, halfword_offset);
278+
} else {
279+
asm_xtensa_mov_reg_i32_optimised(as, reg_dest, halfword_offset * 2);
280+
asm_xtensa_op_add_n(as, reg_dest, reg_base, reg_dest);
281+
asm_xtensa_op_l16ui(as, reg_dest, reg_dest, 0);
262282
}
263283
}
264284

py/asmxtensa.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ void asm_xtensa_mov_reg_local_addr(asm_xtensa_t *as, uint reg_dest, int local_nu
295295
void asm_xtensa_mov_reg_pcrel(asm_xtensa_t *as, uint reg_dest, uint label);
296296
void asm_xtensa_l32i_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint word_offset);
297297
void asm_xtensa_s32i_optimised(asm_xtensa_t *as, uint reg_src, uint reg_base, uint word_offset);
298+
void asm_xtensa_l16ui_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint halfword_offset);
298299
void asm_xtensa_call_ind(asm_xtensa_t *as, uint idx);
299300
void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx);
300301
void asm_xtensa_bit_branch(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t bit, mp_uint_t label, mp_uint_t condition);
@@ -306,6 +307,11 @@ void asm_xtensa_l32r(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t label);
306307
#define ASM_XTENSA_REG_FUN_TABLE ASM_XTENSA_REG_A15
307308
#define ASM_XTENSA_REG_FUN_TABLE_WIN ASM_XTENSA_REG_A7
308309

310+
// Internal temporary register (currently aliased to REG_ARG_5 for xtensa,
311+
// and to REG_TEMP2 for xtensawin).
312+
#define ASM_XTENSA_REG_TEMPORARY ASM_XTENSA_REG_A6
313+
#define ASM_XTENSA_REG_TEMPORARY_WIN ASM_XTENSA_REG_A12
314+
309315
#if GENERIC_ASM_API
310316

311317
// The following macros provide a (mostly) arch-independent API to
@@ -416,7 +422,7 @@ void asm_xtensa_l32r(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t label);
416422
#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) ASM_LOAD32_REG_REG_OFFSET((as), (reg_dest), (reg_base), (word_offset))
417423
#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l8ui((as), (reg_dest), (reg_base), 0)
418424
#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), 0)
419-
#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), (uint16_offset))
425+
#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_xtensa_l16ui_optimised((as), (reg_dest), (reg_base), (uint16_offset))
420426
#define ASM_LOAD16_REG_REG_REG(as, reg_dest, reg_base, reg_index) \
421427
do { \
422428
asm_xtensa_op_addx2((as), (reg_base), (reg_index), (reg_base)); \

py/emitnative.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1572,11 +1572,6 @@ static void emit_ 8000 native_load_subscr(emit_t *emit) {
15721572
asm_rv32_opcode_lhu(emit->as, REG_RET, reg_base, index_value << 1);
15731573
break;
15741574
}
1575-
#elif N_XTENSA || N_XTENSAWIN
1576-
if (index_value >= 0 && index_value < 256) {
1577-
asm_xtensa_op_l16ui(emit->as, REG_RET, reg_base, index_value);
1578-
break;
1579-
}
15801575
#endif
15811576
if (index_value != 0) {
15821577
// index is a non-zero immediate
@@ -1599,11 +1594,6 @@ static void emit_native_load_subscr(emit_t *emit) {
15991594
asm_rv32_opcode_lw(emit->as, REG_RET, reg_base, index_value << 2);
16001595
break;
16011596
}
1602-
#elif N_XTENSA || N_XTENSAWIN
1603-
if (index_value >= 0 && index_value < 256) {
1604-
asm_xtensa_l32i_optimised(emit->as, REG_RET, reg_base, index_value);
1605-
break;
1606-
}
16071597
#endif
16081598
if (index_value != 0) {
16091599
// index is a non-zero immediate
@@ -1870,11 +1860,6 @@ static void emit_native_store_subscr(emit_t *emit) {
18701860
asm_rv32_opcode_sw(emit->as, reg_value, reg_base, index_value << 2);
18711861
break;
18721862
}
1873-
#elif N_XTENSA || N_XTENSAWIN
1874-
if (index_value >= 0 && index_value < 256) {
1875-
asm_xtensa_s32i_optimised(emit->as, reg_value, reg_base, index_value);
1876-
break;
1877-
}
18781863
#endif
18791864
if (index_value != 0) {
18801865
// index is a non-zero immediate

0 commit comments

Comments
 (0)
0