diff options
| author | Jean-Michel Deva <185384874+jeanmicheldeva@users.noreply.github.com> | 2024-11-04 21:03:27 +0100 |
|---|---|---|
| committer | Mason Reed <mason@vector35.com> | 2024-11-25 15:44:50 -0500 |
| commit | fce3b5ba8e08f22b0d1604ac350348d5077e8e90 (patch) | |
| tree | ac4ebebdd4490473b891ae9a1e8cec381c03d736 | |
| parent | a91a145fb6adac3adc0fa1d35128af1865789f81 (diff) | |
RISC-V: Implements MULH, MULHU, MULHSU lifting
| -rw-r--r-- | arch/riscv/src/lib.rs | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/arch/riscv/src/lib.rs b/arch/riscv/src/lib.rs index b56d15c4..8970cd3f 100644 --- a/arch/riscv/src/lib.rs +++ b/arch/riscv/src/lib.rs @@ -1184,11 +1184,28 @@ impl<D: 'static + RiscVDisassembler + Send + Sync> architecture::Architecture fo Op::SraW(r) => simple_r!(r, |rs1, rs2| il.sx(max_width, il.asr(4, rs1, rs2))), Op::Mul(r) => simple_r!(r, |rs1, rs2| il.mul(max_width, rs1, rs2)), - /* - Op::MulH(r) => - Op::MulHU(r) => - Op::MulHSU(r) => - */ + Op::MulH(r) => simple_r!(r, |rs1, rs2| { + let extended_width = max_width * 2; + let extended_rs1 = il.sx(extended_width, rs1); + let extended_rs2 = il.sx(extended_width, rs2); + let mul_expr = il.mul(extended_width, extended_rs1, extended_rs2); + il.asr(max_width, mul_expr, il.const_int(1, 8 * (max_width as u64))) + }), + Op::MulHU(r) => simple_r!(r, |rs1, rs2| { + let extended_width = max_width * 2; + let extended_rs1 = il.zx(extended_width, rs1); + let extended_rs2 = il.zx(extended_width, rs2); + let mul_expr = il.mul(extended_width, extended_rs1, extended_rs2); + il.lsr(max_width, mul_expr, il.const_int(1, 8 * (max_width as u64))) + }), + Op::MulHSU(r) => simple_r!(r, |rs1, rs2| { + let extended_width = max_width * 2; + let extended_rs1 = il.sx(extended_width, rs1); + let extended_rs2 = il.zx(extended_width, rs2); + let mul_expr = il.mul(extended_width, extended_rs1, extended_rs2); + il.asr(max_width, mul_expr, il.const_int(1, 8 * (max_width as u64))) + }), + Op::Div(r) => simple_r!(r, |rs1, rs2| il.divs(max_width, rs1, rs2)), Op::DivU(r) => simple_r!(r, |rs1, rs2| il.divu(max_width, rs1, rs2)), Op::Rem(r) => simple_r!(r, |rs1, rs2| il.mods(max_width, rs1, rs2)), |
