Use sign-extension to save instructions

b9832e268cfc26dafad1f1c30f6b7673b8c1c6c2a89db0ef837be08af3fc31d6
Alexis Sellier committed ago 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),