From 9eb0778f9b972975dee66d5b23cb61bfa0ee6122 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 14 Jun 2017 16:14:16 -0700 Subject: [PATCH] Add RISC-V encodings for call_indirect. --- filetests/isa/riscv/binary32.cton | 5 +++++ lib/cretonne/meta/isa/riscv/encodings.py | 4 +++- lib/cretonne/meta/isa/riscv/recipes.py | 6 +++++- lib/cretonne/src/isa/riscv/binemit.rs | 9 +++++++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/filetests/isa/riscv/binary32.cton b/filetests/isa/riscv/binary32.cton index 923b6eb537..209d9922c0 100644 --- a/filetests/isa/riscv/binary32.cton +++ b/filetests/isa/riscv/binary32.cton @@ -4,6 +4,7 @@ isa riscv function %RV32I(i32 link [%x1]) -> i32 link [%x1] { fn0 = function %foo() + sig0 = signature() ebb0(v9999: i32): [-,%x10] v1 = iconst.i32 1 @@ -86,6 +87,10 @@ ebb0(v9999: i32): ; jal %x1, fn0 call fn0() ; bin: Call(fn0) 000000ef + ; jalr %x1, %x10 + call_indirect sig0, v1() ; bin: 000500e7 + call_indirect sig0, v2() ; bin: 000a80e7 + brz v1, ebb3 brnz v1, ebb1 diff --git a/lib/cretonne/meta/isa/riscv/encodings.py b/lib/cretonne/meta/isa/riscv/encodings.py index 5d3c121a14..374cc951af 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, Icopy +from .recipes import R, Rshamt, Ricmp, I, Iicmp, Iret, Icall, Icopy from .recipes import U, UJ, UJcall, SB, SBzero, GPsp, GPfi from .settings import use_m from cdsl.ast import Var @@ -115,6 +115,8 @@ for inst, f3 in [ # is added by legalize_signature(). RV32.enc(base.x_return, Iret, JALR()) RV64.enc(base.x_return, Iret, JALR()) +RV32.enc(base.call_indirect.i32, Icall, JALR()) +RV64.enc(base.call_indirect.i64, Icall, JALR()) # Spill and fill. RV32.enc(base.spill.i32, GPsp, STORE(0b010)) diff --git a/lib/cretonne/meta/isa/riscv/recipes.py b/lib/cretonne/meta/isa/riscv/recipes.py index 8a6be46c5f..60a67fbc00 100644 --- a/lib/cretonne/meta/isa/riscv/recipes.py +++ b/lib/cretonne/meta/isa/riscv/recipes.py @@ -13,7 +13,8 @@ from cdsl.isa import EncRecipe from cdsl.predicates import IsSignedInt from cdsl.registers import Stack from base.formats import Binary, BinaryImm, MultiAry, IntCompare, IntCompareImm -from base.formats import Unary, UnaryImm, BranchIcmp, Branch, Jump, Call +from base.formats import Unary, UnaryImm, BranchIcmp, Branch, Jump +from base.formats import Call, IndirectCall from .registers import GPR # The low 7 bits of a RISC-V instruction is the base opcode. All 32-bit @@ -113,6 +114,9 @@ Iicmp = EncRecipe( # The variable return values are not encoded. Iret = EncRecipe('Iret', MultiAry, size=4, ins=(), outs=()) +# I-type encoding for `jalr` as an indirect call. +Icall = EncRecipe('Icall', IndirectCall, size=4, ins=GPR, outs=()) + # Copy of a GPR is implemented as addi x, 0. Icopy = EncRecipe('Icopy', Unary, 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 0beaf51a8d..0c25f9ec85 100644 --- a/lib/cretonne/src/isa/riscv/binemit.rs +++ b/lib/cretonne/src/isa/riscv/binemit.rs @@ -182,6 +182,15 @@ fn recipe_iret(func: &Function, inst: Inst, sink: &mut CS sink); } +fn recipe_icall(func: &Function, inst: Inst, sink: &mut CS) { + // Indirect instructions are jalr with rd=%x1. + put_i(func.encodings[inst].bits(), + func.locations[func.dfg.inst_args(inst)[0]].unwrap_reg(), + 0, // no offset. + 1, // rd = %x1: link register. + sink); +} + fn recipe_icopy(func: &Function, inst: Inst, sink: &mut CS) { if let InstructionData::Unary { arg, .. } = func.dfg[inst] { put_i(func.encodings[inst].bits(),