mirror of
https://github.com/micropython/micropython.git
synced 2025-12-16 09:50:15 +01:00
py/asmrv32: Generate better comparison sequences.
This commit changes the sequences generated for not-equal and less-than-or-equal comparisons, in favour of better replacements. The new not-equal comparison generates a sequence of equal size but without the burden of a jump to set the output value, this also had the effect of reducing the size of the code generator as only two opcodes need to be generated instead of three. The less-than-or-equal sequence, on the other hand, is actually two bytes shorter and does not contain any jumps. If Zcb opcodes can be used for performing the final XOR operation then two more bytes could be saved on each comparison. The same remarks about having a shorter generator due to two opcodes being generated instead of three still applies here. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit is contained in:
committed by
Damien George
parent
a1684ad2c1
commit
3cd95dda64
22
py/asmrv32.c
22
py/asmrv32.c
@@ -586,13 +586,10 @@ void asm_rv32_emit_store_reg_reg_reg(asm_rv32_t *state, mp_uint_t rd, mp_uint_t
|
||||
}
|
||||
|
||||
void asm_rv32_meta_comparison_eq(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd) {
|
||||
// c.li rd, 1 ;
|
||||
// beq rs1, rs2, 6 ; PC + 0
|
||||
// c.li rd, 0 ; PC + 4
|
||||
// ... ; PC + 6
|
||||
asm_rv32_opcode_cli(state, rd, 1);
|
||||
asm_rv32_opcode_beq(state, rs1, rs2, 6);
|
||||
asm_rv32_opcode_cli(state, rd, 0);
|
||||
// sub rd, rs1, rs2
|
||||
// sltiu rd, rd, 1
|
||||
asm_rv32_opcode_sub(state, rd, rs1, rs2);
|
||||
asm_rv32_opcode_sltiu(state, rd, rd, 1);
|
||||
}
|
||||
|
||||
void asm_rv32_meta_comparison_ne(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd) {
|
||||
@@ -608,13 +605,10 @@ void asm_rv32_meta_comparison_lt(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2
|
||||
}
|
||||
|
||||
void asm_rv32_meta_comparison_le(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd, bool unsigned_comparison) {
|
||||
// c.li rd, 1 ;
|
||||
// beq rs1, rs2, 8 ; PC + 0
|
||||
// slt(u) rd, rs1, rs2 ; PC + 4
|
||||
// ... ; PC + 8
|
||||
asm_rv32_opcode_cli(state, rd, 1);
|
||||
asm_rv32_opcode_beq(state, rs1, rs2, 8);
|
||||
asm_rv32_meta_comparison_lt(state, rs1, rs2, rd, unsigned_comparison);
|
||||
// slt[u] rd, rs2, rs1
|
||||
// xori rd, rd, 1
|
||||
asm_rv32_meta_comparison_lt(state, rs2, rs1, rd, unsigned_comparison);
|
||||
asm_rv32_opcode_xori(state, rd, rd, 1);
|
||||
}
|
||||
|
||||
#endif // MICROPY_EMIT_RV32
|
||||
|
||||
Reference in New Issue
Block a user