diff options
-rw-r--r-- | py/asmxtensa.c | 24 | ||||
-rw-r--r-- | py/asmxtensa.h | 8 | ||||
-rw-r--r-- | py/emitnative.c | 15 |
3 files changed, 29 insertions, 18 deletions
diff --git a/py/asmxtensa.c b/py/asmxtensa.c index ab2e7aeae..2b36a56ea 100644 --- a/py/asmxtensa.c +++ b/py/asmxtensa.c @@ -34,6 +34,12 @@ #include "py/asmxtensa.h" +#if N_XTENSAWIN +#define REG_TEMP ASM_XTENSA_REG_TEMPORARY_WIN +#else +#define REG_TEMP ASM_XTENSA_REG_TEMPORARY +#endif + #define WORD_SIZE (4) #define SIGNED_FIT8(x) ((((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80)) #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 } else if (word_offset < 256) { asm_xtensa_op_l32i(as, reg_dest, reg_base, word_offset); } else { - mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("asm overflow")); + asm_xtensa_mov_reg_i32_optimised(as, reg_dest, word_offset * 4); + asm_xtensa_op_add_n(as, reg_dest, reg_base, reg_dest); + asm_xtensa_op_l32i_n(as, reg_dest, reg_dest, 0); } } @@ -258,7 +266,19 @@ void asm_xtensa_s32i_optimised(asm_xtensa_t *as, uint reg_src, uint reg_base, ui } else if (word_offset < 256) { asm_xtensa_op_s32i(as, reg_src, reg_base, word_offset); } else { - mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("asm overflow")); + asm_xtensa_mov_reg_i32_optimised(as, REG_TEMP, word_offset * 4); + asm_xtensa_op_add_n(as, REG_TEMP, reg_base, REG_TEMP); + asm_xtensa_op_s32i_n(as, reg_src, REG_TEMP, 0); + } +} + +void asm_xtensa_l16ui_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint halfword_offset) { + if (halfword_offset < 256) { + asm_xtensa_op_l16ui(as, reg_dest, reg_base, halfword_offset); + } else { + asm_xtensa_mov_reg_i32_optimised(as, reg_dest, halfword_offset * 2); + asm_xtensa_op_add_n(as, reg_dest, reg_base, reg_dest); + asm_xtensa_op_l16ui(as, reg_dest, reg_dest, 0); } } diff --git a/py/asmxtensa.h b/py/asmxtensa.h index 598111f90..d90aef3c5 100644 --- a/py/asmxtensa.h +++ b/py/asmxtensa.h @@ -295,6 +295,7 @@ void asm_xtensa_mov_reg_local_addr(asm_xtensa_t *as, uint reg_dest, int local_nu void asm_xtensa_mov_reg_pcrel(asm_xtensa_t *as, uint reg_dest, uint label); void asm_xtensa_l32i_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint word_offset); void asm_xtensa_s32i_optimised(asm_xtensa_t *as, uint reg_src, uint reg_base, uint word_offset); +void asm_xtensa_l16ui_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint halfword_offset); void asm_xtensa_call_ind(asm_xtensa_t *as, uint idx); void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx); 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); #define ASM_XTENSA_REG_FUN_TABLE ASM_XTENSA_REG_A15 #define ASM_XTENSA_REG_FUN_TABLE_WIN ASM_XTENSA_REG_A7 +// Internal temporary register (currently aliased to REG_ARG_5 for xtensa, +// and to REG_TEMP2 for xtensawin). +#define ASM_XTENSA_REG_TEMPORARY ASM_XTENSA_REG_A6 +#define ASM_XTENSA_REG_TEMPORARY_WIN ASM_XTENSA_REG_A12 + #if GENERIC_ASM_API // 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); #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)) #define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l8ui((as), (reg_dest), (reg_base), 0) #define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), 0) -#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), (uint16_offset)) +#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_xtensa_l16ui_optimised((as), (reg_dest), (reg_base), (uint16_offset)) #define ASM_LOAD16_REG_REG_REG(as, reg_dest, reg_base, reg_index) \ do { \ asm_xtensa_op_addx2((as), (reg_base), (reg_index), (reg_base)); \ diff --git a/py/emitnative.c b/py/emitnative.c index c1965fc91..dba9c7169 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -1572,11 +1572,6 @@ static void emit_native_load_subscr(emit_t *emit) { asm_rv32_opcode_lhu(emit->as, REG_RET, reg_base, index_value << 1); break; } - #elif N_XTENSA || N_XTENSAWIN - if (index_value >= 0 && index_value < 256) { - asm_xtensa_op_l16ui(emit->as, REG_RET, reg_base, index_value); - break; - } #endif if (index_value != 0) { // index is a non-zero immediate @@ -1599,11 +1594,6 @@ static void emit_native_load_subscr(emit_t *emit) { asm_rv32_opcode_lw(emit->as, REG_RET, reg_base, index_value << 2); break; } - #elif N_XTENSA || N_XTENSAWIN - if (index_value >= 0 && index_value < 256) { - asm_xtensa_l32i_optimised(emit->as, REG_RET, reg_base, index_value); - break; - } #endif if (index_value != 0) { // index is a non-zero immediate @@ -1870,11 +1860,6 @@ static void emit_native_store_subscr(emit_t *emit) { asm_rv32_opcode_sw(emit->as, reg_value, reg_base, index_value << 2); break; } - #elif N_XTENSA || N_XTENSAWIN - if (index_value >= 0 && index_value < 256) { - asm_xtensa_s32i_optimised(emit->as, reg_value, reg_base, index_value); - break; - } #endif if (index_value != 0) { // index is a non-zero immediate |