Optimize subtraction by small immediate

eace45a744258390b6b287b413a4c8733a1e8cedc54cc8f624de1ecea2ef789f
Use ADDI/ADDIW with negated value instead of LI+SUB.
Alexis Sellier committed ago 1 parent 6cd41da3
lib/std/arch/rv64/isel.rad +12 -0
702 702
            } else {
703 703
                selectBinOp(s, rd, rs1, b, BinOp::Add, super::SCRATCH2);
704 704
            }
705 705
        }
706 706
        case il::BinOp::Sub => {
707 +
            // Optimize subtraction by small immediate: use ADDI with negated value.
708 +
            if let case il::Val::Imm(imm) = b {
709 +
                let neg = -imm;
710 +
                if neg >= super::MIN_IMM as i64 and neg <= super::MAX_IMM as i64 {
711 +
                    emit::emit(s.e,
712 +
                        encode::addiw(rd, rs1, neg as i32)
713 +
                            if typ == il::Type::W32 else
714 +
                        encode::addi(rd, rs1, neg as i32));
715 +
                    return;
716 +
                }
717 +
            }
707 718
            let rs2 = resolveVal(s, super::SCRATCH2, b);
719 +
708 720
            emit::emit(s.e,
709 721
                encode::subw(rd, rs1, rs2)
710 722
                    if typ == il::Type::W32 else
711 723
                encode::sub(rd, rs1, rs2));
712 724
        }