Use sign-extension to save instructions
b9832e268cfc26dafad1f1c30f6b7673b8c1c6c2a89db0ef837be08af3fc31d6
1 parent
68bd0f27
lib/std/arch/rv64/isel.rad
+17 -8
| 805 | 805 | selectShift(s, rd, rs1, b, ShiftOp::Sra, typ, super::SCRATCH2), |
|
| 806 | 806 | case il::BinOp::Ushr => |
|
| 807 | 807 | selectShift(s, rd, rs1, b, ShiftOp::Srl, typ, super::SCRATCH2), |
|
| 808 | 808 | case il::BinOp::Eq => { |
|
| 809 | 809 | let rs2 = resolveVal(s, super::SCRATCH2, b); |
|
| 810 | - | // Canonicalize both operands to the declared width |
|
| 811 | - | // so high-bit junk doesn't affect the result. |
|
| 812 | - | emitZext(s.e, rs1, rs1, typ); |
|
| 813 | - | emitZext(s.e, rs2, rs2, typ); |
|
| 810 | + | // Canonicalize both operands to the declared width. |
|
| 811 | + | // For W32 EQ, sign-extension suffices instead of |
|
| 812 | + | // zero-extension since both sides get same canonical form. |
|
| 813 | + | if typ == il::Type::W32 { |
|
| 814 | + | emitSext(s.e, rs1, rs1, typ); |
|
| 815 | + | emitSext(s.e, rs2, rs2, typ); |
|
| 816 | + | } else { |
|
| 817 | + | emitZext(s.e, rs1, rs1, typ); |
|
| 818 | + | emitZext(s.e, rs2, rs2, typ); |
|
| 819 | + | } |
|
| 814 | 820 | emit::emit(s.e, encode::xor(rd, rs1, rs2)); |
|
| 815 | 821 | emit::emit(s.e, encode::sltiu(rd, rd, 1)); |
|
| 816 | 822 | } |
|
| 817 | 823 | case il::BinOp::Ne => { |
|
| 818 | 824 | let rs2 = resolveVal(s, super::SCRATCH2, b); |
|
| 819 | - | // Canonicalize both operands to the declared width |
|
| 820 | - | // so high-bit junk doesn't affect the result. |
|
| 821 | - | emitZext(s.e, rs1, rs1, typ); |
|
| 822 | - | emitZext(s.e, rs2, rs2, typ); |
|
| 825 | + | if typ == il::Type::W32 { |
|
| 826 | + | emitSext(s.e, rs1, rs1, typ); |
|
| 827 | + | emitSext(s.e, rs2, rs2, typ); |
|
| 828 | + | } else { |
|
| 829 | + | emitZext(s.e, rs1, rs1, typ); |
|
| 830 | + | emitZext(s.e, rs2, rs2, typ); |
|
| 831 | + | } |
|
| 823 | 832 | emit::emit(s.e, encode::xor(rd, rs1, rs2)); |
|
| 824 | 833 | emit::emit(s.e, encode::sltu(rd, super::ZERO, rd)); |
|
| 825 | 834 | } |
|
| 826 | 835 | case il::BinOp::Slt => |
|
| 827 | 836 | selectCmp(s, rd, rs1, b, CmpOp::Slt, super::SCRATCH2), |