Add RISC-V encodings for call_indirect.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -182,6 +182,15 @@ fn recipe_iret<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS
|
||||
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) {
|
||||
if let InstructionData::Unary { arg, .. } = func.dfg[inst] {
|
||||
put_i(func.encodings[inst].bits(),
|
||||
|
||||
Reference in New Issue
Block a user