Add RISC-V encodings for call_indirect.

This commit is contained in:
Jakob Stoklund Olesen
2017-06-14 16:14:16 -07:00
parent 66af915eed
commit 9eb0778f9b
4 changed files with 22 additions and 2 deletions

View File

@@ -4,6 +4,7 @@ isa riscv
function %RV32I(i32 link [%x1]) -> i32 link [%x1] { function %RV32I(i32 link [%x1]) -> i32 link [%x1] {
fn0 = function %foo() fn0 = function %foo()
sig0 = signature()
ebb0(v9999: i32): ebb0(v9999: i32):
[-,%x10] v1 = iconst.i32 1 [-,%x10] v1 = iconst.i32 1
@@ -86,6 +87,10 @@ ebb0(v9999: i32):
; jal %x1, fn0 ; jal %x1, fn0
call fn0() ; bin: Call(fn0) 000000ef call fn0() ; bin: Call(fn0) 000000ef
; jalr %x1, %x10
call_indirect sig0, v1() ; bin: 000500e7
call_indirect sig0, v2() ; bin: 000a80e7
brz v1, ebb3 brz v1, ebb3
brnz v1, ebb1 brnz v1, ebb1

View File

@@ -7,7 +7,7 @@ from base.immediates import intcc
from .defs import RV32, RV64 from .defs import RV32, RV64
from .recipes import OPIMM, OPIMM32, OP, OP32, LUI, BRANCH, JALR, JAL from .recipes import OPIMM, OPIMM32, OP, OP32, LUI, BRANCH, JALR, JAL
from .recipes import LOAD, STORE 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 .recipes import U, UJ, UJcall, SB, SBzero, GPsp, GPfi
from .settings import use_m from .settings import use_m
from cdsl.ast import Var from cdsl.ast import Var
@@ -115,6 +115,8 @@ for inst, f3 in [
# is added by legalize_signature(). # is added by legalize_signature().
RV32.enc(base.x_return, Iret, JALR()) RV32.enc(base.x_return, Iret, JALR())
RV64.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. # Spill and fill.
RV32.enc(base.spill.i32, GPsp, STORE(0b010)) RV32.enc(base.spill.i32, GPsp, STORE(0b010))

View File

@@ -13,7 +13,8 @@ from cdsl.isa import EncRecipe
from cdsl.predicates import IsSignedInt from cdsl.predicates import IsSignedInt
from cdsl.registers import Stack from cdsl.registers import Stack
from base.formats import Binary, BinaryImm, MultiAry, IntCompare, IntCompareImm 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 from .registers import GPR
# The low 7 bits of a RISC-V instruction is the base opcode. All 32-bit # 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. # The variable return values are not encoded.
Iret = EncRecipe('Iret', MultiAry, size=4, ins=(), outs=()) 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. # Copy of a GPR is implemented as addi x, 0.
Icopy = EncRecipe('Icopy', Unary, size=4, ins=GPR, outs=GPR) Icopy = EncRecipe('Icopy', Unary, size=4, ins=GPR, outs=GPR)

View File

@@ -182,6 +182,15 @@ fn recipe_iret<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS
sink); sink);
} }
fn recipe_icall<CS: CodeSink + ?Sized>(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<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) { fn recipe_icopy<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) {
if let InstructionData::Unary { arg, .. } = func.dfg[inst] { if let InstructionData::Unary { arg, .. } = func.dfg[inst] {
put_i(func.encodings[inst].bits(), put_i(func.encodings[inst].bits(),