mirror of
https://github.com/micropython/micropython.git
synced 2026-01-07 20:50:14 +01:00
py/asmxtensa: Implement the full set of Viper load/store operations.
This commit expands the implementation of Viper load/store operations that are optimised for the Xtensa platform. Now both load and store emitters should generate the shortest possible sequence in all cases. Redundant specialised operation emitters have been aliased to the general case implementation - this was the case of integer-indexed load/store operations with a fixed offset of zero. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit is contained in:
committed by
Damien George
parent
cd1b921bf2
commit
12f36cc13c
@@ -299,25 +299,47 @@ void asm_xtensa_l32i_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, u
|
||||
}
|
||||
}
|
||||
|
||||
void asm_xtensa_s32i_optimised(asm_xtensa_t *as, uint reg_src, uint reg_base, uint word_offset) {
|
||||
if (word_offset < 16) {
|
||||
asm_xtensa_op_s32i_n(as, reg_src, reg_base, word_offset);
|
||||
} else if (word_offset < 256) {
|
||||
asm_xtensa_op_s32i(as, reg_src, reg_base, word_offset);
|
||||
void asm_xtensa_load_reg_reg_offset(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint offset, uint operation_size) {
|
||||
assert(operation_size <= 2 && "Operation size value out of range.");
|
||||
|
||||
if (operation_size == 2 && MP_FIT_UNSIGNED(4, offset)) {
|
||||
asm_xtensa_op_l32i_n(as, reg_dest, reg_base, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
if (MP_FIT_UNSIGNED(8, offset)) {
|
||||
asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(2, operation_size, reg_base, reg_dest, offset));
|
||||
return;
|
||||
}
|
||||
|
||||
asm_xtensa_mov_reg_i32_optimised(as, reg_dest, offset << operation_size);
|
||||
asm_xtensa_op_add_n(as, reg_dest, reg_base, reg_dest);
|
||||
if (operation_size == 2) {
|
||||
asm_xtensa_op_l32i_n(as, reg_dest, reg_dest, 0);
|
||||
} else {
|
||||
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);
|
||||
asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(2, operation_size, reg_dest, reg_dest, 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);
|
||||
void asm_xtensa_store_reg_reg_offset(asm_xtensa_t *as, uint reg_src, uint reg_base, uint offset, uint operation_size) {
|
||||
assert(operation_size <= 2 && "Operation size value out of range.");
|
||||
|
||||
if (operation_size == 2 && MP_FIT_UNSIGNED(4, offset)) {
|
||||
asm_xtensa_op_s32i_n(as, reg_src, reg_base, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
if (MP_FIT_UNSIGNED(8, offset)) {
|
||||
asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(2, 0x04 | operation_size, reg_base, reg_src, offset));
|
||||
return;
|
||||
}
|
||||
|
||||
asm_xtensa_mov_reg_i32_optimised(as, REG_TEMP, offset << operation_size);
|
||||
asm_xtensa_op_add_n(as, REG_TEMP, reg_base, REG_TEMP);
|
||||
if (operation_size == 2) {
|
||||
asm_xtensa_op_s32i_n(as, reg_src, REG_TEMP, 0);
|
||||
} 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);
|
||||
asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(2, 0x04 | operation_size, REG_TEMP, reg_src, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user