mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-25 16:50:50 +01:00
[python] Upgrade to micropython 1.11
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
#define WORD_SIZE (4)
|
||||
#define SIGNED_FIT8(x) ((((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80))
|
||||
#define SIGNED_FIT12(x) ((((x) & 0xfffff800) == 0) || (((x) & 0xfffff800) == 0xfffff800))
|
||||
#define NUM_REGS_SAVED (5)
|
||||
|
||||
void asm_xtensa_end_pass(asm_xtensa_t *as) {
|
||||
as->num_const = as->cur_const;
|
||||
@@ -67,26 +68,37 @@ void asm_xtensa_entry(asm_xtensa_t *as, int num_locals) {
|
||||
mp_asm_base_get_cur_to_write_bytes(&as->base, 1); // padding/alignment byte
|
||||
as->const_table = (uint32_t*)mp_asm_base_get_cur_to_write_bytes(&as->base, as->num_const * 4);
|
||||
|
||||
// adjust the stack-pointer to store a0, a12, a13, a14 and locals, 16-byte aligned
|
||||
as->stack_adjust = (((4 + num_locals) * WORD_SIZE) + 15) & ~15;
|
||||
asm_xtensa_op_addi(as, ASM_XTENSA_REG_A1, ASM_XTENSA_REG_A1, -as->stack_adjust);
|
||||
// adjust the stack-pointer to store a0, a12, a13, a14, a15 and locals, 16-byte aligned
|
||||
as->stack_adjust = (((NUM_REGS_SAVED + num_locals) * WORD_SIZE) + 15) & ~15;
|
||||
if (SIGNED_FIT8(-as->stack_adjust)) {
|
||||
asm_xtensa_op_addi(as, ASM_XTENSA_REG_A1, ASM_XTENSA_REG_A1, -as->stack_adjust);
|
||||
} else {
|
||||
asm_xtensa_op_movi(as, ASM_XTENSA_REG_A9, as->stack_adjust);
|
||||
asm_xtensa_op_sub(as, ASM_XTENSA_REG_A1, ASM_XTENSA_REG_A1, ASM_XTENSA_REG_A9);
|
||||
}
|
||||
|
||||
// save return value (a0) and callee-save registers (a12, a13, a14)
|
||||
// save return value (a0) and callee-save registers (a12, a13, a14, a15)
|
||||
asm_xtensa_op_s32i_n(as, ASM_XTENSA_REG_A0, ASM_XTENSA_REG_A1, 0);
|
||||
asm_xtensa_op_s32i_n(as, ASM_XTENSA_REG_A12, ASM_XTENSA_REG_A1, 1);
|
||||
asm_xtensa_op_s32i_n(as, ASM_XTENSA_REG_A13, ASM_XTENSA_REG_A1, 2);
|
||||
asm_xtensa_op_s32i_n(as, ASM_XTENSA_REG_A14, ASM_XTENSA_REG_A1, 3);
|
||||
for (int i = 1; i < NUM_REGS_SAVED; ++i) {
|
||||
asm_xtensa_op_s32i_n(as, ASM_XTENSA_REG_A11 + i, ASM_XTENSA_REG_A1, i);
|
||||
}
|
||||
}
|
||||
|
||||
void asm_xtensa_exit(asm_xtensa_t *as) {
|
||||
// restore registers
|
||||
asm_xtensa_op_l32i_n(as, ASM_XTENSA_REG_A14, ASM_XTENSA_REG_A1, 3);
|
||||
asm_xtensa_op_l32i_n(as, ASM_XTENSA_REG_A13, ASM_XTENSA_REG_A1, 2);
|
||||
asm_xtensa_op_l32i_n(as, ASM_XTENSA_REG_A12, ASM_XTENSA_REG_A1, 1);
|
||||
for (int i = NUM_REGS_SAVED - 1; i >= 1; --i) {
|
||||
asm_xtensa_op_l32i_n(as, ASM_XTENSA_REG_A11 + i, ASM_XTENSA_REG_A1, i);
|
||||
}
|
||||
asm_xtensa_op_l32i_n(as, ASM_XTENSA_REG_A0, ASM_XTENSA_REG_A1, 0);
|
||||
|
||||
// restore stack-pointer and return
|
||||
asm_xtensa_op_addi(as, ASM_XTENSA_REG_A1, ASM_XTENSA_REG_A1, as->stack_adjust);
|
||||
if (SIGNED_FIT8(as->stack_adjust)) {
|
||||
asm_xtensa_op_addi(as, ASM_XTENSA_REG_A1, ASM_XTENSA_REG_A1, as->stack_adjust);
|
||||
} else {
|
||||
asm_xtensa_op_movi(as, ASM_XTENSA_REG_A9, as->stack_adjust);
|
||||
asm_xtensa_op_add_n(as, ASM_XTENSA_REG_A1, ASM_XTENSA_REG_A1, ASM_XTENSA_REG_A9);
|
||||
}
|
||||
|
||||
asm_xtensa_op_ret_n(as);
|
||||
}
|
||||
|
||||
@@ -144,31 +156,74 @@ void asm_xtensa_setcc_reg_reg_reg(asm_xtensa_t *as, uint cond, uint reg_dest, ui
|
||||
asm_xtensa_op_movi_n(as, reg_dest, 0);
|
||||
}
|
||||
|
||||
void asm_xtensa_mov_reg_i32(asm_xtensa_t *as, uint reg_dest, uint32_t i32) {
|
||||
size_t asm_xtensa_mov_reg_i32(asm_xtensa_t *as, uint reg_dest, uint32_t i32) {
|
||||
// load the constant
|
||||
uint32_t const_table_offset = (uint8_t*)as->const_table - as->base.code_base;
|
||||
size_t loc = const_table_offset + as->cur_const * WORD_SIZE;
|
||||
asm_xtensa_op_l32r(as, reg_dest, as->base.code_offset, loc);
|
||||
// store the constant in the table
|
||||
if (as->const_table != NULL) {
|
||||
as->const_table[as->cur_const] = i32;
|
||||
}
|
||||
++as->cur_const;
|
||||
return loc;
|
||||
}
|
||||
|
||||
void asm_xtensa_mov_reg_i32_optimised(asm_xtensa_t *as, uint reg_dest, uint32_t i32) {
|
||||
if (SIGNED_FIT12(i32)) {
|
||||
asm_xtensa_op_movi(as, reg_dest, i32);
|
||||
} else {
|
||||
// load the constant
|
||||
asm_xtensa_op_l32r(as, reg_dest, as->base.code_offset, 4 + as->cur_const * WORD_SIZE);
|
||||
// store the constant in the table
|
||||
if (as->const_table != NULL) {
|
||||
as->const_table[as->cur_const] = i32;
|
||||
}
|
||||
++as->cur_const;
|
||||
asm_xtensa_mov_reg_i32(as, reg_dest, i32);
|
||||
}
|
||||
}
|
||||
|
||||
void asm_xtensa_mov_local_reg(asm_xtensa_t *as, int local_num, uint reg_src) {
|
||||
asm_xtensa_op_s32i(as, reg_src, ASM_XTENSA_REG_A1, 4 + local_num);
|
||||
asm_xtensa_op_s32i(as, reg_src, ASM_XTENSA_REG_A1, NUM_REGS_SAVED + local_num);
|
||||
}
|
||||
|
||||
void asm_xtensa_mov_reg_local(asm_xtensa_t *as, uint reg_dest, int local_num) {
|
||||
asm_xtensa_op_l32i(as, reg_dest, ASM_XTENSA_REG_A1, 4 + local_num);
|
||||
asm_xtensa_op_l32i(as, reg_dest, ASM_XTENSA_REG_A1, NUM_REGS_SAVED + local_num);
|
||||
}
|
||||
|
||||
void asm_xtensa_mov_reg_local_addr(asm_xtensa_t *as, uint reg_dest, int local_num) {
|
||||
asm_xtensa_op_mov_n(as, reg_dest, ASM_XTENSA_REG_A1);
|
||||
asm_xtensa_op_addi(as, reg_dest, reg_dest, (4 + local_num) * WORD_SIZE);
|
||||
uint off = (NUM_REGS_SAVED + local_num) * WORD_SIZE;
|
||||
if (SIGNED_FIT8(off)) {
|
||||
asm_xtensa_op_addi(as, reg_dest, ASM_XTENSA_REG_A1, off);
|
||||
} else {
|
||||
asm_xtensa_op_movi(as, reg_dest, off);
|
||||
asm_xtensa_op_add_n(as, reg_dest, reg_dest, ASM_XTENSA_REG_A1);
|
||||
}
|
||||
}
|
||||
|
||||
void asm_xtensa_mov_reg_pcrel(asm_xtensa_t *as, uint reg_dest, uint label) {
|
||||
// Get relative offset from PC
|
||||
uint32_t dest = get_label_dest(as, label);
|
||||
int32_t rel = dest - as->base.code_offset;
|
||||
rel -= 3 + 3; // account for 3 bytes of movi instruction, 3 bytes call0 adjustment
|
||||
asm_xtensa_op_movi(as, reg_dest, rel); // imm has 12-bit range
|
||||
|
||||
// Use call0 to get PC+3 into a0
|
||||
// call0 destination must be aligned on 4 bytes:
|
||||
// - code_offset&3=0: off=0, pad=1
|
||||
// - code_offset&3=1: off=0, pad=0
|
||||
// - code_offset&3=2: off=1, pad=3
|
||||
// - code_offset&3=3: off=1, pad=2
|
||||
uint32_t off = as->base.code_offset >> 1 & 1;
|
||||
uint32_t pad = (5 - as->base.code_offset) & 3;
|
||||
asm_xtensa_op_call0(as, off);
|
||||
mp_asm_base_get_cur_to_write_bytes(&as->base, pad);
|
||||
|
||||
// Add PC to relative offset
|
||||
asm_xtensa_op_add_n(as, reg_dest, reg_dest, ASM_XTENSA_REG_A0);
|
||||
}
|
||||
|
||||
void asm_xtensa_call_ind(asm_xtensa_t *as, uint idx) {
|
||||
if (idx < 16) {
|
||||
asm_xtensa_op_l32i_n(as, ASM_XTENSA_REG_A0, ASM_XTENSA_REG_FUN_TABLE, idx);
|
||||
} else {
|
||||
asm_xtensa_op_l32i(as, ASM_XTENSA_REG_A0, ASM_XTENSA_REG_FUN_TABLE, idx);
|
||||
}
|
||||
asm_xtensa_op_callx0(as, ASM_XTENSA_REG_A0);
|
||||
}
|
||||
|
||||
#endif // MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA
|
||||
|
||||
Reference in New Issue
Block a user