Optimize subtraction by small immediate
eace45a744258390b6b287b413a4c8733a1e8cedc54cc8f624de1ecea2ef789f
Use ADDI/ADDIW with negated value instead of LI+SUB.
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 | } |