Skip to content

Commit 3cd95dd

Browse files
agattidpgeorge
authored andcommitted
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 <[email protected]>
1 parent a1684ad commit 3cd95dd

File tree

1 file changed

+8
-14
lines changed

1 file changed

+8
-14
lines changed

py/asmrv32.c

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -586,13 +586,10 @@ void asm_rv32_emit_store_reg_reg_reg(asm_rv32_t *state, mp_uint_t rd, mp_uint_t
586586
}
587587

588588
void asm_rv32_meta_comparison_eq(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd) {
589-
// c.li rd, 1 ;
590-
// beq rs1, rs2, 6 ; PC + 0
591-
// c.li rd, 0 ; PC + 4
592-
// ... ; PC + 6
593-
asm_rv32_opcode_cli(state, rd, 1);
594-
asm_rv32_opcode_beq(state, rs1, rs2, 6);
595-
asm_rv32_opcode_cli(state, rd, 0);
589+
// sub rd, rs1, rs2
590+
// sltiu rd, rd, 1
591+
asm_rv32_opcode_sub(state, rd, rs1, rs2);
592+
asm_rv32_opcode_sltiu(state, rd, rd, 1);
596593
}
597594

598595
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
608605
}
609606

610607
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) {
611-
// c.li rd, 1 ;
612-
// beq rs1, rs2, 8 ; PC + 0
613-
// slt(u) rd, rs1, rs2 ; PC + 4
614-
// ... ; PC + 8
615-
asm_rv32_opcode_cli(state, rd, 1);
616-
asm_rv32_opcode_beq(state, rs1, rs2, 8);
617-
asm_rv32_meta_comparison_lt(state, rs1, rs2, rd, unsigned_comparison);
608+
// slt[u] rd, rs2, rs1
609+
// xori rd, rd, 1
610+
asm_rv32_meta_comparison_lt(state, rs2, rs1, rd, unsigned_comparison);
611+
asm_rv32_opcode_xori(state, rd, rd, 1);
618612
}
619613

620614
#endif // MICROPY_EMIT_RV32

0 commit comments

Comments
 (0)