Strength-reduce multiplication by known constants
a81e17175b498e57b8ed31f044c7508a47e93a13695c0c19c368fe0605f40a1b
1 parent
ebab4823
lib/std/arch/rv64/isel.rad
+26 -5
| 677 | 677 | encode::subw(rd, rs1, rs2) |
|
| 678 | 678 | if typ == il::Type::W32 else |
|
| 679 | 679 | encode::sub(rd, rs1, rs2)); |
|
| 680 | 680 | } |
|
| 681 | 681 | case il::BinOp::Mul => { |
|
| 682 | - | let rs2 = resolveVal(s, super::SCRATCH2, b); |
|
| 683 | - | emit::emit(s.e, |
|
| 684 | - | encode::mulw(rd, rs1, rs2) |
|
| 685 | - | if typ == il::Type::W32 else |
|
| 686 | - | encode::mul(rd, rs1, rs2)); |
|
| 682 | + | // Strength-reduce multiplication by known constants. |
|
| 683 | + | if let case il::Val::Imm(imm) = b { |
|
| 684 | + | if imm == 0 { |
|
| 685 | + | emit::emit(s.e, encode::mv(rd, super::ZERO)); |
|
| 686 | + | } else if imm == 1 { |
|
| 687 | + | emitMv(s, rd, rs1); |
|
| 688 | + | } else if imm == 2 { |
|
| 689 | + | emit::emit(s.e, encode::slli(rd, rs1, 1)); |
|
| 690 | + | } else if imm == 4 { |
|
| 691 | + | emit::emit(s.e, encode::slli(rd, rs1, 2)); |
|
| 692 | + | } else if imm == 8 { |
|
| 693 | + | emit::emit(s.e, encode::slli(rd, rs1, 3)); |
|
| 694 | + | } else { |
|
| 695 | + | let rs2 = resolveVal(s, super::SCRATCH2, b); |
|
| 696 | + | emit::emit(s.e, |
|
| 697 | + | encode::mulw(rd, rs1, rs2) |
|
| 698 | + | if typ == il::Type::W32 else |
|
| 699 | + | encode::mul(rd, rs1, rs2)); |
|
| 700 | + | } |
|
| 701 | + | } else { |
|
| 702 | + | let rs2 = resolveVal(s, super::SCRATCH2, b); |
|
| 703 | + | emit::emit(s.e, |
|
| 704 | + | encode::mulw(rd, rs1, rs2) |
|
| 705 | + | if typ == il::Type::W32 else |
|
| 706 | + | encode::mul(rd, rs1, rs2)); |
|
| 707 | + | } |
|
| 687 | 708 | } |
|
| 688 | 709 | case il::BinOp::Sdiv => { |
|
| 689 | 710 | let rs2 = resolveVal(s, super::SCRATCH2, b); |
|
| 690 | 711 | emitTrapIfZero(s, rs2); |
|
| 691 | 712 | emit::emit(s.e, |