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:
Alessandro Gatti
2025-10-30 22:47:23 +01:00
committed by Damien George
parent a1684ad2c1
commit 3cd95dda64

View File

@@ -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) { 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 ; // sub rd, rs1, rs2
// beq rs1, rs2, 6 ; PC + 0 // sltiu rd, rd, 1
// c.li rd, 0 ; PC + 4 asm_rv32_opcode_sub(state, rd, rs1, rs2);
// ... ; PC + 6 asm_rv32_opcode_sltiu(state, rd, rd, 1);
asm_rv32_opcode_cli(state, rd, 1);
asm_rv32_opcode_beq(state, rs1, rs2, 6);
asm_rv32_opcode_cli(state, rd, 0);
} }
void asm_rv32_meta_comparison_ne(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd) { 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) { 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 ; // slt[u] rd, rs2, rs1
// beq rs1, rs2, 8 ; PC + 0 // xori rd, rd, 1
// slt(u) rd, rs1, rs2 ; PC + 4 asm_rv32_meta_comparison_lt(state, rs2, rs1, rd, unsigned_comparison);
// ... ; PC + 8 asm_rv32_opcode_xori(state, rd, rd, 1);
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);
} }
#endif // MICROPY_EMIT_RV32 #endif // MICROPY_EMIT_RV32