Add RISC-V encodings for call_indirect.
This commit is contained in:
@@ -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