Add RISC-V call instruction encodings.

Calls are jal with a fixed %x1 link register.
This commit is contained in:
Jakob Stoklund Olesen
2017-04-06 15:36:03 -07:00
parent b4ac520332
commit 4ee519e620
4 changed files with 26 additions and 8 deletions

View File

@@ -3,6 +3,8 @@ test binemit
isa riscv
function RV32I() {
fn0 = function foo()
ebb0:
[-,%x10] v1 = iconst.i32 1
[-,%x21] v2 = iconst.i32 2
@@ -75,11 +77,14 @@ ebb0:
[-,%x7] v140 = iconst.i32 0x12345000 ; bin: 123453b7
[-,%x16] v141 = iconst.i32 0xffffffff_fedcb000 ; bin: fedcb837
; Control Transfer Instructions
; jal %x1, fn0
call fn0() ; bin: Call(fn0) 000000ef
brz v1, ebb3
fallthrough ebb1
; Control Transfer Instructions
ebb1:
; beq 0x000
br_icmp eq v1, v2, ebb1 ; bin: 01550063

View File

@@ -6,7 +6,8 @@ from base import instructions as base
from base.immediates import intcc
from .defs import RV32, RV64
from .recipes import OPIMM, OPIMM32, OP, OP32, LUI, BRANCH, JALR, JAL
from .recipes import R, Rshamt, Ricmp, I, Iicmp, Iret, U, UJ, SB, SBzero
from .recipes import R, Rshamt, Ricmp, I, Iicmp, Iret
from .recipes import U, UJ, UJcall, SB, SBzero
from .settings import use_m
from cdsl.ast import Var
@@ -84,6 +85,8 @@ RV64.enc(base.imul.i32, R, OP32(0b000, 0b0000001), isap=use_m)
# Unconditional branches.
RV32.enc(base.jump, UJ, JAL())
RV64.enc(base.jump, UJ, JAL())
RV32.enc(base.call, UJcall, JAL())
RV64.enc(base.call, UJcall, JAL())
# Conditional branches.
for cond, f3 in [

View File

@@ -12,7 +12,7 @@ from __future__ import absolute_import
from cdsl.isa import EncRecipe
from cdsl.predicates import IsSignedInt
from base.formats import Binary, BinaryImm, MultiAry, IntCompare, IntCompareImm
from base.formats import UnaryImm, BranchIcmp, Branch, Jump
from base.formats import UnaryImm, BranchIcmp, Branch, Jump, Call
from .registers import GPR
# The low 7 bits of a RISC-V instruction is the base opcode. All 32-bit
@@ -119,6 +119,7 @@ U = EncRecipe(
# UJ-type unconditional branch instructions.
UJ = EncRecipe('UJ', Jump, size=4, ins=(), outs=(), branch_range=(0, 21))
UJcall = EncRecipe('UJcall', Call, size=4, ins=(), outs=())
# SB-type branch instructions.
# TODO: These instructions have a +/- 4 KB branch range. How to encode that

View File

@@ -8,13 +8,12 @@ use predicates::is_signed_int;
include!(concat!(env!("OUT_DIR"), "/binemit-riscv.rs"));
/// RISC-V relocation kinds.
#[allow(dead_code)]
pub enum RelocKind {
/// A conditional (SB-type) branch to an EBB.
Branch,
/// A jal call to a function.
Call,
}
pub static RELOC_NAMES: [&'static str; 1] = ["Branch"];
pub static RELOC_NAMES: [&'static str; 1] = ["Call"];
impl Into<Reloc> for RelocKind {
fn into(self) -> Reloc {
@@ -318,3 +317,13 @@ fn recipe_uj<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS)
panic!("Expected Jump format: {:?}", func.dfg[inst]);
}
}
fn recipe_ujcall<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) {
if let InstructionData::Call { func_ref, .. } = func.dfg[inst] {
sink.reloc_func(RelocKind::Call.into(), func_ref);
// rd=%x1 is the standard link register.
put_uj(func.encodings[inst].bits(), 0, 1, sink);
} else {
panic!("Expected Call format: {:?}", func.dfg[inst]);
}
}