diff options
| author | Alessandro Gatti <a.gatti@frob.it> | 2025-10-30 22:47:23 +0100 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2025-11-03 13:53:45 +1100 |
| commit | 3cd95dda649b1b3c855a577cb8f97c874c7047d6 (patch) | |
| tree | 26608ef78860dfffc580333677b7cf4483e04128 /py/asmrv32.c | |
| parent | a1684ad2c142e804cffce8f4f14b7293c1ac44b4 (diff) | |
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>
Diffstat (limited to 'py/asmrv32.c')
| -rw-r--r-- | py/asmrv32.c | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/py/asmrv32.c b/py/asmrv32.c index 9e4fefec0..1d0cea6c0 100644 --- a/py/asmrv32.c +++ b/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 |
