diff --git a/cranelift/codegen/src/isa/zkasm/inst.isle b/cranelift/codegen/src/isa/zkasm/inst.isle index 164b786f8779..fb040a036493 100644 --- a/cranelift/codegen/src/isa/zkasm/inst.isle +++ b/cranelift/codegen/src/isa/zkasm/inst.isle @@ -404,6 +404,12 @@ (src1 Imm32) (src2 Imm32)) + ;; A multiplication with 2 32-bit immediates. + (MulImm32 + (rd WritableReg) + (src1 Imm32) + (src2 Imm32)) + )) @@ -1010,6 +1016,12 @@ (_ Unit (emit (MInst.AddImm32 dst imm1 imm2)))) dst)) +(decl zk_mul (Imm32 Imm32) XReg) +(rule (zk_mul imm1 imm2) + (let ((dst WritableXReg (temp_writable_xreg)) + (_ Unit (emit (MInst.MulImm32 dst imm1 imm2)))) + dst)) + ;; Helper for emitting the `add` instruction. ;; rd ← rs1 + rs2 (decl rv_add (XReg XReg) XReg) diff --git a/cranelift/codegen/src/isa/zkasm/inst/args.rs b/cranelift/codegen/src/isa/zkasm/inst/args.rs index d71cef8a32c4..5ac8fd9e3c7d 100644 --- a/cranelift/codegen/src/isa/zkasm/inst/args.rs +++ b/cranelift/codegen/src/isa/zkasm/inst/args.rs @@ -792,7 +792,7 @@ impl AluOPRRR { Self::Sllw => "sllw", Self::Srlw => "srlw", Self::Sraw => "sraw", - Self::Mul => "mul", + Self::Mul => "MUL", Self::Mulh => "mulh", Self::Mulhsu => "mulhsu", Self::Mulhu => "mulhu", @@ -800,7 +800,7 @@ impl AluOPRRR { Self::DivU => "divu", Self::Rem => "rem", Self::RemU => "remu", - Self::Mulw => "mulw", + Self::Mulw => "MUL", Self::Divw => "divw", Self::Divuw => "divuw", Self::Remw => "remw", diff --git a/cranelift/codegen/src/isa/zkasm/inst/emit.rs b/cranelift/codegen/src/isa/zkasm/inst/emit.rs index b22bde1359ce..1d3b5af54165 100644 --- a/cranelift/codegen/src/isa/zkasm/inst/emit.rs +++ b/cranelift/codegen/src/isa/zkasm/inst/emit.rs @@ -429,6 +429,7 @@ impl Inst { | Inst::LoadConst64 { .. } | Inst::AluRRR { .. } | Inst::AddImm32 { .. } + | Inst::MulImm32 { .. } | Inst::FpuRRR { .. } | Inst::AluRRImm12 { .. } | Inst::Load { .. } @@ -668,6 +669,14 @@ impl MachInstEmit for Inst { sink, ); } + &Inst::MulImm32 { rd, src1, src2 } => { + let rd = allocs.next(rd.to_reg()); + // TODO(akashin): Should we have a function for `bits` field? + put_string( + &format!("{} * {} => {}\n", src1.bits, src2.bits, reg_name(rd)), + sink, + ); + } &Inst::AluRRR { alu_op, rd, @@ -742,6 +751,7 @@ impl MachInstEmit for Inst { sink, ); } + _ => unreachable!("Op {:?} is not implemented", alu_op), }; diff --git a/cranelift/codegen/src/isa/zkasm/inst/mod.rs b/cranelift/codegen/src/isa/zkasm/inst/mod.rs index 4892bd01312a..ef612569dcda 100644 --- a/cranelift/codegen/src/isa/zkasm/inst/mod.rs +++ b/cranelift/codegen/src/isa/zkasm/inst/mod.rs @@ -716,6 +716,10 @@ fn zkasm_get_operands VReg>(inst: &Inst, collector: &mut OperandC collector.reg_def(*rd); } + Inst::MulImm32 { rd, src1, src2 } => { + collector.reg_def(*rd); + } + &Inst::VecAluRRRImm5 { op, vd, @@ -1464,6 +1468,11 @@ impl Inst { format!("{src1} + {src2} => {rd};") } + Inst::MulImm32 { rd, src1, src2 } => { + let rd = format_reg(rd.to_reg(), allocs); + format!("{src1} * {src2} => {rd};") + } + &Inst::FpuRR { frm, alu_op, diff --git a/cranelift/codegen/src/isa/zkasm/lower.isle b/cranelift/codegen/src/isa/zkasm/lower.isle index fcdf74a93cca..ad9bd74abc68 100644 --- a/cranelift/codegen/src/isa/zkasm/lower.isle +++ b/cranelift/codegen/src/isa/zkasm/lower.isle @@ -259,6 +259,11 @@ (rule 5 (lower (has_type (ty_vec_fits_in_register ty) (imul x (splat y)))) (rv_vmul_vx x y (unmasked) ty)) + +(rule 6 (lower (imul (imm32_from_value x) (imm32_from_value y))) + (zk_mul x y)) + + ;;;; Rules for `smulhi` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (rule 0 (lower (has_type (ty_int_ref_scalar_64 ty) (smulhi x y))) (lower_smlhi ty (sext x ty $I64) (sext y ty $I64))) diff --git a/cranelift/data/gen.sh b/cranelift/data/gen.sh index d41eab089e4c..a6af61f42a61 100755 --- a/cranelift/data/gen.sh +++ b/cranelift/data/gen.sh @@ -1,7 +1,7 @@ #!/bin/bash cargo build -for name in add counter add_func add_memory fibonacci locals locals_simple fibonacci_recursive +for name in add counter add_func add_memory fibonacci locals locals_simple fibonacci_recursive mul do echo $name; ../target/debug/clif-util wasm --target sparc-unknown-unknown ../../zkwasm/data/$name.wat > data/$name.zkasm