summaryrefslogtreecommitdiffstatshomepage
path: root/py/emitnative.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/emitnative.c')
-rw-r--r--py/emitnative.c202
1 files changed, 48 insertions, 154 deletions
diff --git a/py/emitnative.c b/py/emitnative.c
index 1aab0a9eb7..f3ab483e8a 100644
--- a/py/emitnative.c
+++ b/py/emitnative.c
@@ -180,12 +180,6 @@ static const uint8_t reg_local_table[MAX_REGS_FOR_LOCAL_VARS] = {REG_LOCAL_1, RE
*emit->error_slot = mp_obj_new_exception_msg_varg(&mp_type_ViperTypeError, __VA_ARGS__); \
} while (0)
-#if N_RV32
-#define FIT_SIGNED(value, bits) \
- ((((value) & ~((1U << ((bits) - 1)) - 1)) == 0) || \
- (((value) & ~((1U << ((bits) - 1)) - 1)) == ~((1U << ((bits) - 1)) - 1)))
-#endif
-
typedef enum {
STACK_VALUE,
STACK_REG,
@@ -1537,87 +1531,50 @@ static void emit_native_load_subscr(emit_t *emit) {
switch (vtype_base) {
case VTYPE_PTR8: {
// pointer to 8-bit memory
- // TODO optimise to use thumb ldrb r1, [r2, r3]
+ #ifdef ASM_LOAD8_REG_REG_OFFSET
+ ASM_LOAD8_REG_REG_OFFSET(emit->as, REG_RET, reg_base, index_value);
+ #else
if (index_value != 0) {
// index is non-zero
- #if N_THUMB
- if (index_value > 0 && index_value < 32) {
- asm_thumb_ldrb_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value);
- break;
- }
- #elif N_RV32
- if (FIT_SIGNED(index_value, 12)) {
- asm_rv32_opcode_lbu(emit->as, REG_RET, reg_base, index_value);
- break;
- }
- #elif N_XTENSA || N_XTENSAWIN
- if (index_value > 0 && index_value < 256) {
- asm_xtensa_op_l8ui(emit->as, REG_RET, reg_base, index_value);
- break;
- }
- #endif
need_reg_single(emit, reg_index, 0);
ASM_MOV_REG_IMM(emit->as, reg_index, index_value);
ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add index to base
reg_base = reg_index;
}
ASM_LOAD8_REG_REG(emit->as, REG_RET, reg_base); // load from (base+index)
+ #endif
break;
}
case VTYPE_PTR16: {
// pointer to 16-bit memory
+ #ifdef ASM_LOAD16_REG_REG_OFFSET
+ ASM_LOAD16_REG_REG_OFFSET(emit->as, REG_RET, reg_base, index_value);
+ #else
if (index_value != 0) {
// index is a non-zero immediate
- #if N_THUMB
- if (index_value > 0 && index_value < 32) {
- asm_thumb_ldrh_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value);
- break;
- }
- #elif N_RV32
- if (FIT_SIGNED(index_value, 11)) {
- 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
need_reg_single(emit, reg_index, 0);
ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 1);
ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 2*index to base
reg_base = reg_index;
}
ASM_LOAD16_REG_REG(emit->as, REG_RET, reg_base); // load from (base+2*index)
+ #endif
break;
}
case VTYPE_PTR32: {
// pointer to 32-bit memory
+ #ifdef ASM_LOAD32_REG_REG_OFFSET
+ ASM_LOAD32_REG_REG_OFFSET(emit->as, REG_RET, reg_base, index_value);
+ #else
if (index_value != 0) {
// index is a non-zero immediate
- #if N_THUMB
- if (index_value > 0 && index_value < 32) {
- asm_thumb_ldr_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value);
- break;
- }
- #elif N_RV32
- if (FIT_SIGNED(index_value, 10)) {
- 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
need_reg_single(emit, reg_index, 0);
ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 2);
ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 4*index to base
reg_base = reg_index;
}
ASM_LOAD32_REG_REG(emit->as, REG_RET, reg_base); // load from (base+4*index)
+ #endif
break;
}
default:
@@ -1638,40 +1595,36 @@ static void emit_native_load_subscr(emit_t *emit) {
switch (vtype_base) {
case VTYPE_PTR8: {
// pointer to 8-bit memory
- // TODO optimise to use thumb ldrb r1, [r2, r3]
+ #ifdef ASM_LOAD8_REG_REG_REG
+ ASM_LOAD8_REG_REG_REG(emit->as, REG_RET, REG_ARG_1, reg_index);
+ #else
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_LOAD8_REG_REG(emit->as, REG_RET, REG_ARG_1); // store value to (base+index)
+ #endif
break;
}
case VTYPE_PTR16: {
// pointer to 16-bit memory
- #if N_XTENSA || N_XTENSAWIN
- asm_xtensa_op_addx2(emit->as, REG_ARG_1, reg_index, REG_ARG_1);
- asm_xtensa_op_l16ui(emit->as, REG_RET, REG_ARG_1, 0);
- break;
- #endif
+ #ifdef ASM_LOAD16_REG_REG_REG
+ ASM_LOAD16_REG_REG_REG(emit->as, REG_RET, REG_ARG_1, reg_index);
+ #else
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_LOAD16_REG_REG(emit->as, REG_RET, REG_ARG_1); // load from (base+2*index)
+ #endif
break;
}
case VTYPE_PTR32: {
// pointer to word-size memory
- #if N_RV32
- asm_rv32_opcode_slli(emit->as, REG_TEMP2, reg_index, 2);
- asm_rv32_opcode_cadd(emit->as, REG_ARG_1, REG_TEMP2);
- asm_rv32_opcode_lw(emit->as, REG_RET, REG_ARG_1, 0);
- break;
- #elif N_XTENSA || N_XTENSAWIN
- asm_xtensa_op_addx4(emit->as, REG_ARG_1, reg_index, REG_ARG_1);
- asm_xtensa_op_l32i_n(emit->as, REG_RET, REG_ARG_1, 0);
- break;
- #endif
+ #ifdef ASM_LOAD32_REG_REG_REG
+ ASM_LOAD32_REG_REG_REG(emit->as, REG_RET, REG_ARG_1, reg_index);
+ #else
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_LOAD32_REG_REG(emit->as, REG_RET, REG_ARG_1); // load from (base+4*index)
+ #endif
break;
}
default:
@@ -1814,92 +1767,47 @@ static void emit_native_store_subscr(emit_t *emit) {
switch (vtype_base) {
case VTYPE_PTR8: {
// pointer to 8-bit memory
- // TODO optimise to use thumb strb r1, [r2, r3]
+ #ifdef ASM_STORE8_REG_REG_OFFSET
+ ASM_STORE8_REG_REG_OFFSET(emit->as, reg_value, reg_base, index_value);
+ #else
if (index_value != 0) {
// index is non-zero
- #if N_THUMB
- if (index_value > 0 && index_value < 32) {
- asm_thumb_strb_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value);
- break;
- }
- #elif N_RV32
- if (FIT_SIGNED(index_value, 12)) {
- asm_rv32_opcode_sb(emit->as, reg_value, reg_base, index_value);
- break;
- }
- #elif N_XTENSA || N_XTENSAWIN
- if (index_value > 0 && index_value < 256) {
- asm_xtensa_op_s8i(emit->as, REG_RET, reg_base, index_value);
- break;
- }
- #endif
ASM_MOV_REG_IMM(emit->as, reg_index, index_value);
- #if N_ARM
- asm_arm_strb_reg_reg_reg(emit->as, reg_value, reg_base, reg_index);
- return;
- #endif
ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add index to base
reg_base = reg_index;
}
ASM_STORE8_REG_REG(emit->as, reg_value, reg_base); // store value to (base+index)
+ #endif
break;
}
case VTYPE_PTR16: {
// pointer to 16-bit memory
+ #ifdef ASM_STORE16_REG_REG_OFFSET
+ ASM_STORE16_REG_REG_OFFSET(emit->as, reg_value, reg_base, index_value);
+ #else
if (index_value != 0) {
// index is a non-zero immediate
- #if N_THUMB
- if (index_value > 0 && index_value < 32) {
- asm_thumb_strh_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value);
- break;
- }
- #elif N_RV32
- if (FIT_SIGNED(index_value, 11)) {
- asm_rv32_opcode_sh(emit->as, reg_value, reg_base, index_value << 1);
- break;
- }
- #elif N_XTENSA || N_XTENSAWIN
- if (index_value > 0 && index_value < 256) {
- asm_xtensa_op_s16i(emit->as, REG_RET, reg_base, index_value);
- break;
- }
- #endif
ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 1);
ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 2*index to base
reg_base = reg_index;
}
ASM_STORE16_REG_REG(emit->as, reg_value, reg_base); // store value to (base+2*index)
+ #endif
break;
}
case VTYPE_PTR32: {
// pointer to 32-bit memory
+ #ifdef ASM_STORE32_REG_REG_OFFSET
+ ASM_STORE32_REG_REG_OFFSET(emit->as, reg_value, reg_base, index_value);
+ #else
if (index_value != 0) {
// index is a non-zero immediate
- #if N_THUMB
- if (index_value > 0 && index_value < 32) {
- asm_thumb_str_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value);
- break;
- }
- #elif N_RV32
- if (FIT_SIGNED(index_value, 10)) {
- 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_RET, reg_base, index_value);
- break;
- }
- #elif N_ARM
- ASM_MOV_REG_IMM(emit->as, reg_index, index_value);
- asm_arm_str_reg_reg_reg(emit->as, reg_value, reg_base, reg_index);
- return;
- #endif
ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 2);
ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 4*index to base
reg_base = reg_index;
}
ASM_STORE32_REG_REG(emit->as, reg_value, reg_base); // store value to (base+4*index)
+ #endif
break;
}
default:
@@ -1930,50 +1838,36 @@ static void emit_native_store_subscr(emit_t *emit) {
switch (vtype_base) {
case VTYPE_PTR8: {
// pointer to 8-bit memory
- // TODO optimise to use thumb strb r1, [r2, r3]
- #if N_ARM
- asm_arm_strb_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
- break;
- #endif
+ #ifdef ASM_STORE8_REG_REG_REG
+ ASM_STORE8_REG_REG_REG(emit->as, reg_value, REG_ARG_1, reg_index);
+ #else
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_STORE8_REG_REG(emit->as, reg_value, REG_ARG_1); // store value to (base+index)
+ #endif
break;
}
case VTYPE_PTR16: {
// pointer to 16-bit memory
- #if N_ARM
- asm_arm_strh_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
- break;
- #elif N_XTENSA || N_XTENSAWIN
- asm_xtensa_op_addx2(emit->as, REG_ARG_1, reg_index, REG_ARG_1);
- asm_xtensa_op_s16i(emit->as, reg_value, REG_ARG_1, 0);
- break;
- #endif
+ #ifdef ASM_STORE16_REG_REG_REG
+ ASM_STORE16_REG_REG_REG(emit->as, reg_value, REG_ARG_1, reg_index);
+ #else
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_STORE16_REG_REG(emit->as, reg_value, REG_ARG_1); // store value to (base+2*index)
+ #endif
break;
}
case VTYPE_PTR32: {
// pointer to 32-bit memory
- #if N_ARM
- asm_arm_str_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index);
- break;
- #elif N_RV32
- asm_rv32_opcode_slli(emit->as, REG_TEMP2, reg_index, 2);
- asm_rv32_opcode_cadd(emit->as, REG_ARG_1, REG_TEMP2);
- asm_rv32_opcode_sw(emit->as, reg_value, REG_ARG_1, 0);
- break;
- #elif N_XTENSA || N_XTENSAWIN
- asm_xtensa_op_addx4(emit->as, REG_ARG_1, reg_index, REG_ARG_1);
- asm_xtensa_op_s32i_n(emit->as, reg_value, REG_ARG_1, 0);
- break;
- #endif
+ #ifdef ASM_STORE32_REG_REG_REG
+ ASM_STORE32_REG_REG_REG(emit->as, reg_value, REG_ARG_1, reg_index);
+ #else
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base
ASM_STORE32_REG_REG(emit->as, reg_value, REG_ARG_1); // store value to (base+4*index)
+ #endif
break;
}
default: