summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorAlessandro Gatti <a.gatti@frob.it>2025-10-30 22:47:23 +0100
committerDamien George <damien@micropython.org>2025-11-03 13:53:45 +1100
commit3cd95dda649b1b3c855a577cb8f97c874c7047d6 (patch)
tree26608ef78860dfffc580333677b7cf4483e04128 /py
parenta1684ad2c142e804cffce8f4f14b7293c1ac44b4 (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')
-rw-r--r--py/asmrv32.c22
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