diff --git a/filetests/isa/riscv/binary32.cton b/filetests/isa/riscv/binary32.cton index 209d9922c0..6575609267 100644 --- a/filetests/isa/riscv/binary32.cton +++ b/filetests/isa/riscv/binary32.cton @@ -77,6 +77,9 @@ ebb0(v9999: i32): ; lui [-,%x7] v140 = iconst.i32 0x12345000 ; bin: 123453b7 [-,%x16] v141 = iconst.i32 0xffffffff_fedcb000 ; bin: fedcb837 + ; addi + [-,%x7] v142 = iconst.i32 1000 ; bin: 3e800393 + [-,%x16] v143 = iconst.i32 -905 ; bin: c7700813 ; Copies alias to iadd_imm. [-,%x7] v150 = copy v1 ; bin: 00050393 diff --git a/filetests/isa/riscv/verify-encoding.cton b/filetests/isa/riscv/verify-encoding.cton index 52b8d6d79c..b88fdc6402 100644 --- a/filetests/isa/riscv/verify-encoding.cton +++ b/filetests/isa/riscv/verify-encoding.cton @@ -6,7 +6,7 @@ function %RV32I(i32 link [%x1]) -> i32 link [%x1] { ebb0(v9999: i32): ; iconst.i32 needs legalizing, so it should throw a - [R#0,-] v1 = iconst.i32 1 ; error: Instruction failed to re-encode + [R#0,-] v1 = iconst.i32 0xf0f0f0f0f0 ; error: Instruction failed to re-encode return v9999 } diff --git a/lib/cretonne/meta/isa/riscv/encodings.py b/lib/cretonne/meta/isa/riscv/encodings.py index 374cc951af..d8afbab2cf 100644 --- a/lib/cretonne/meta/isa/riscv/encodings.py +++ b/lib/cretonne/meta/isa/riscv/encodings.py @@ -7,7 +7,7 @@ from base.immediates import intcc from .defs import RV32, RV64 from .recipes import OPIMM, OPIMM32, OP, OP32, LUI, BRANCH, JALR, JAL from .recipes import LOAD, STORE -from .recipes import R, Rshamt, Ricmp, I, Iicmp, Iret, Icall, Icopy +from .recipes import R, Rshamt, Ricmp, I, Iz, Iicmp, Iret, Icall, Icopy from .recipes import U, UJ, UJcall, SB, SBzero, GPsp, GPfi from .settings import use_m from cdsl.ast import Var @@ -40,6 +40,11 @@ RV64.enc(base.isub.i32, R, OP32(0b000, 0b0100000)) # There are no andiw/oriw/xoriw variations. RV64.enc(base.iadd_imm.i32, I, OPIMM32(0b000)) +# Use iadd_imm with %x0 to materialize constants. +RV32.enc(base.iconst.i32, Iz, OPIMM(0b000)) +RV64.enc(base.iconst.i32, Iz, OPIMM(0b000)) +RV64.enc(base.iconst.i64, Iz, OPIMM(0b000)) + # Dynamic shifts have the same masking semantics as the cton base instructions. for inst, inst_imm, f3, f7 in [ (base.ishl, base.ishl_imm, 0b001, 0b0000000), diff --git a/lib/cretonne/meta/isa/riscv/recipes.py b/lib/cretonne/meta/isa/riscv/recipes.py index 60a67fbc00..2ea7f35597 100644 --- a/lib/cretonne/meta/isa/riscv/recipes.py +++ b/lib/cretonne/meta/isa/riscv/recipes.py @@ -104,6 +104,11 @@ I = EncRecipe( 'I', BinaryImm, size=4, ins=GPR, outs=GPR, instp=IsSignedInt(BinaryImm.imm, 12)) +# I-type instruction with a hardcoded %x0 rs1. +Iz = EncRecipe( + 'Iz', UnaryImm, size=4, ins=(), outs=GPR, + instp=IsSignedInt(UnaryImm.imm, 12)) + # I-type encoding of an integer comparison. Iicmp = EncRecipe( 'Iicmp', IntCompareImm, size=4, ins=GPR, outs=GPR, diff --git a/lib/cretonne/src/isa/riscv/binemit.rs b/lib/cretonne/src/isa/riscv/binemit.rs index 0c25f9ec85..21638980b2 100644 --- a/lib/cretonne/src/isa/riscv/binemit.rs +++ b/lib/cretonne/src/isa/riscv/binemit.rs @@ -160,6 +160,18 @@ fn recipe_i(func: &Function, inst: Inst, sink: &mut CS) { } } +fn recipe_iz(func: &Function, inst: Inst, sink: &mut CS) { + if let InstructionData::UnaryImm { imm, .. } = func.dfg[inst] { + put_i(func.encodings[inst].bits(), + 0, + imm.into(), + func.locations[func.dfg.first_result(inst)].unwrap_reg(), + sink); + } else { + panic!("Expected UnaryImm format: {:?}", func.dfg[inst]); + } +} + fn recipe_iicmp(func: &Function, inst: Inst, sink: &mut CS) { if let InstructionData::IntCompareImm { arg, imm, .. } = func.dfg[inst] { put_i(func.encodings[inst].bits(),