mirror of
https://github.com/micropython/micropython.git
synced 2025-07-21 21:11:12 +02:00
py/asmxtensa: Extend BCC range to 18 bits.
This commit lets the native emitter backend extends the range of the BCC family of opcodes (BALL, BANY, BBC, BBS, BEQ, BGE, BGEU, BLT, BLTU, BNALL, BNE, BNONE) from 8 bits to 18 bits. The test suite contains some test files that, when compiled into native code, would require BCC jumps outside the (signed) 8 bits range. In this case either the MicroPython interpreter or mpy-cross would raise an exception, not running the test when using the "--via-mpy --emit native" command line options with the test runner. This comes with a 3 bytes penalty on each forward jump, bringing the footprint of those jumps to 6 bytes each, as a longer opcode sequence has to be emitted to let jumps access a larger range. However, this is slightly offset by the fact that backward jumps can be emitted with a single opcode if the range is small enough (8-bits offset). Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit is contained in:
committed by
Damien George
parent
80b823bca1
commit
43f6013294
@@ -192,12 +192,27 @@ void asm_xtensa_bccz_reg_label(asm_xtensa_t *as, uint cond, uint reg, uint label
|
|||||||
}
|
}
|
||||||
|
|
||||||
void asm_xtensa_bcc_reg_reg_label(asm_xtensa_t *as, uint cond, uint reg1, uint reg2, uint label) {
|
void asm_xtensa_bcc_reg_reg_label(asm_xtensa_t *as, uint cond, uint reg1, uint reg2, uint label) {
|
||||||
uint32_t dest = get_label_dest(as, label);
|
ptrdiff_t rel = 0;
|
||||||
int32_t rel = dest - as->base.code_offset - 4;
|
bool can_emit_short_jump = calculate_branch_displacement(as, label, &rel);
|
||||||
if (as->base.pass == MP_ASM_PASS_EMIT && !SIGNED_FIT8(rel)) {
|
|
||||||
|
if (can_emit_short_jump && SIGNED_FIT8(rel)) {
|
||||||
|
// Backwards BCC opcodes with an offset that fits in 8 bits can
|
||||||
|
// be emitted without any change.
|
||||||
|
asm_xtensa_op_bcc(as, cond, reg1, reg2, rel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range is effectively extended to 18 bits, as a more complex jump code
|
||||||
|
// sequence is emitted.
|
||||||
|
if (as->base.pass == MP_ASM_PASS_EMIT && !SIGNED_FIT18(rel - 6)) {
|
||||||
mp_raise_msg_varg(&mp_type_RuntimeError, ET_OUT_OF_RANGE, MP_QSTR_bcc);
|
mp_raise_msg_varg(&mp_type_RuntimeError, ET_OUT_OF_RANGE, MP_QSTR_bcc);
|
||||||
}
|
}
|
||||||
asm_xtensa_op_bcc(as, cond, reg1, reg2, rel);
|
|
||||||
|
// ~BCC skip ; +0 <- Condition is flipped here (EQ -> NE, etc.)
|
||||||
|
// J addr ; +3
|
||||||
|
// skip: ; +6
|
||||||
|
asm_xtensa_op_bcc(as, cond ^ 8, reg1, reg2, 6 - 4);
|
||||||
|
asm_xtensa_op_j(as, rel - 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// convenience function; reg_dest must be different from reg_src[12]
|
// convenience function; reg_dest must be different from reg_src[12]
|
||||||
|
Reference in New Issue
Block a user