diff --git a/filetests/isa/riscv/binary32.cton b/filetests/isa/riscv/binary32.cton index fd3d910a18..aa0a7b7389 100644 --- a/filetests/isa/riscv/binary32.cton +++ b/filetests/isa/riscv/binary32.cton @@ -44,7 +44,6 @@ ebb0: ; addi [-,%x7] v100 = iadd_imm v1, 1000 ; bin: 3e850393 [-,%x16] v101 = iadd_imm v2, -905 ; bin: c77a8813 - ; TBD: slti ; andi [-,%x7] v110 = band_imm v1, 1000 ; bin: 3e857393 [-,%x16] v111 = band_imm v2, -905 ; bin: c77af813 @@ -65,5 +64,12 @@ ebb0: [-,%x7] v124 = sshr_imm v1, 31 ; bin: 41f55393 [-,%x16] v125 = sshr_imm v2, 8 ; bin: 408ad813 + ; slti + [-,%x7] v130 = icmp_imm slt, v1, 1000 ; bin: 3e852393 + [-,%x16] v131 = icmp_imm slt, v2, -905 ; bin: c77aa813 + ; sltiu + [-,%x7] v132 = icmp_imm ult, v1, 1000 ; bin: 3e853393 + [-,%x16] v133 = icmp_imm ult, v2, -905 ; bin: c77ab813 + return } diff --git a/lib/cretonne/meta/isa/riscv/encodings.py b/lib/cretonne/meta/isa/riscv/encodings.py index b97c92386a..1966a576c2 100644 --- a/lib/cretonne/meta/isa/riscv/encodings.py +++ b/lib/cretonne/meta/isa/riscv/encodings.py @@ -5,7 +5,8 @@ from __future__ import absolute_import from base import instructions as base from base.immediates import intcc from .defs import RV32, RV64 -from .recipes import OPIMM, OPIMM32, OP, OP32, JALR, R, Rshamt, Ricmp, I, Iret +from .recipes import OPIMM, OPIMM32, OP, OP32 +from .recipes import JALR, R, Rshamt, Ricmp, I, Iicmp, Iret from .settings import use_m from cdsl.ast import Var @@ -60,6 +61,11 @@ RV64.enc(base.icmp.i64(intcc.slt, x, y), Ricmp, OP(0b010, 0b0000000)) RV32.enc(base.icmp.i32(intcc.ult, x, y), Ricmp, OP(0b011, 0b0000000)) RV64.enc(base.icmp.i64(intcc.ult, x, y), Ricmp, OP(0b011, 0b0000000)) +RV32.enc(base.icmp_imm.i32(intcc.slt, x, y), Iicmp, OPIMM(0b010)) +RV64.enc(base.icmp_imm.i64(intcc.slt, x, y), Iicmp, OPIMM(0b010)) +RV32.enc(base.icmp_imm.i32(intcc.ult, x, y), Iicmp, OPIMM(0b011)) +RV64.enc(base.icmp_imm.i64(intcc.ult, x, y), Iicmp, OPIMM(0b011)) + # "M" Standard Extension for Integer Multiplication and Division. # Gated by the `use_m` flag. RV32.enc(base.imul.i32, R, OP(0b000, 0b0000001), isap=use_m) diff --git a/lib/cretonne/meta/isa/riscv/recipes.py b/lib/cretonne/meta/isa/riscv/recipes.py index 2fd326e5cc..fb31b5d60a 100644 --- a/lib/cretonne/meta/isa/riscv/recipes.py +++ b/lib/cretonne/meta/isa/riscv/recipes.py @@ -11,7 +11,7 @@ instruction formats described in the reference: from __future__ import absolute_import from cdsl.isa import EncRecipe from cdsl.predicates import IsSignedInt -from base.formats import Binary, BinaryImm, MultiAry, IntCompare +from base.formats import Binary, BinaryImm, MultiAry, IntCompare, IntCompareImm from .registers import GPR # The low 7 bits of a RISC-V instruction is the base opcode. All 32-bit @@ -86,6 +86,11 @@ I = EncRecipe( 'I', BinaryImm, ins=GPR, outs=GPR, instp=IsSignedInt(BinaryImm.imm, 12)) +# I-type encoding of an integer comparison. +Iicmp = EncRecipe( + 'Iicmp', IntCompareImm, ins=GPR, outs=GPR, + instp=IsSignedInt(IntCompareImm.imm, 12)) + # I-type encoding for `jalr` as a return instruction. We won't use the # immediate offset. # The variable return values are not encoded. diff --git a/lib/cretonne/src/isa/riscv/binemit.rs b/lib/cretonne/src/isa/riscv/binemit.rs index a3941af526..5479a60898 100644 --- a/lib/cretonne/src/isa/riscv/binemit.rs +++ b/lib/cretonne/src/isa/riscv/binemit.rs @@ -145,6 +145,18 @@ fn recipe_i(func: &Function, inst: Inst, sink: &mut CS) { } } +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(), + func.locations[arg].unwrap_reg(), + imm.into(), + func.locations[func.dfg.first_result(inst)].unwrap_reg(), + sink); + } else { + panic!("Expected IntCompareImm format: {:?}", func.dfg[inst]); + } +} + fn recipe_iret(_func: &Function, _inst: Inst, _sink: &mut CS) { unimplemented!() }