Add return_reg encodings for RISC-V.

This commit is contained in:
Jakob Stoklund Olesen
2017-02-21 15:17:33 -08:00
parent a7d24ab1dc
commit 62334b26b4
5 changed files with 33 additions and 8 deletions

View File

@@ -15,5 +15,7 @@ ebb0(v1: i32, v2: i32):
; check: [R#10c] ; check: [R#10c]
; sameln: $v12 = imul ; sameln: $v12 = imul
return return_reg v1
; check: [Iret#19]
; sameln: return_reg
} }

View File

@@ -4,7 +4,7 @@ RISC-V Encodings.
from __future__ import absolute_import from __future__ import absolute_import
from base import instructions as base from base import instructions as base
from .defs import RV32, RV64 from .defs import RV32, RV64
from .recipes import OPIMM, OPIMM32, OP, OP32, R, Rshamt, I from .recipes import OPIMM, OPIMM32, OP, OP32, JALR, R, Rshamt, I, Iret
from .settings import use_m from .settings import use_m
# Basic arithmetic binary instructions are encoded in an R-type instruction. # Basic arithmetic binary instructions are encoded in an R-type instruction.
@@ -52,3 +52,12 @@ for inst, inst_imm, f3, f7 in [
RV32.enc(base.imul.i32, R, OP(0b000, 0b0000001), isap=use_m) RV32.enc(base.imul.i32, R, OP(0b000, 0b0000001), isap=use_m)
RV64.enc(base.imul.i64, R, OP(0b000, 0b0000001), isap=use_m) RV64.enc(base.imul.i64, R, OP(0b000, 0b0000001), isap=use_m)
RV64.enc(base.imul.i32, R, OP32(0b000, 0b0000001), isap=use_m) RV64.enc(base.imul.i32, R, OP32(0b000, 0b0000001), isap=use_m)
# Control flow.
# Returns are a special case of JALR.
# Note: Return stack predictors will only recognize this as a return when the
# return address is provided in `x1`. We may want a special encoding to enforce
# that.
RV32.enc(base.return_reg.i32, Iret, JALR())
RV64.enc(base.return_reg.i64, Iret, JALR())

View File

@@ -11,7 +11,7 @@ instruction formats described in the reference:
from __future__ import absolute_import from __future__ import absolute_import
from cdsl.isa import EncRecipe from cdsl.isa import EncRecipe
from cdsl.predicates import IsSignedInt from cdsl.predicates import IsSignedInt
from base.formats import Binary, BinaryImm from base.formats import Binary, BinaryImm, ReturnReg
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
@@ -40,6 +40,12 @@ def BRANCH(funct3):
return 0b11000 | (funct3 << 5) return 0b11000 | (funct3 << 5)
def JALR(funct3=0):
# type: (int) -> int
assert funct3 <= 0b111
return 0b11001 | (funct3 << 5)
def OPIMM(funct3, funct7=0): def OPIMM(funct3, funct7=0):
# type: (int, int) -> int # type: (int, int) -> int
assert funct3 <= 0b111 assert funct3 <= 0b111
@@ -76,3 +82,8 @@ Rshamt = EncRecipe('Rshamt', BinaryImm, ins=GPR, outs=GPR)
I = EncRecipe( I = EncRecipe(
'I', BinaryImm, ins=GPR, outs=GPR, 'I', BinaryImm, ins=GPR, outs=GPR,
instp=IsSignedInt(BinaryImm.imm, 12)) instp=IsSignedInt(BinaryImm.imm, 12))
# I-type encoding for `jalr` as a return instruction. We won't use the
# immediate offset.
# The variable return values are not encoded.
Iret = EncRecipe('Iret', ReturnReg, ins=GPR, outs=())

View File

@@ -1327,9 +1327,12 @@ impl<'a> Parser<'a> {
} }
} }
InstructionFormat::ReturnReg => { InstructionFormat::ReturnReg => {
let raddr = try!(self.match_value("expected SSA value return addr operand")); let raddr = try!(self.match_value("expected SSA value return address operand"));
try!(self.match_token(Token::Comma, "expected ',' between operands")); let args = if self.optional(Token::Comma) {
let args = try!(self.parse_value_list()); try!(self.parse_value_list())
} else {
VariableArgs::new()
};
InstructionData::ReturnReg { InstructionData::ReturnReg {
opcode: opcode, opcode: opcode,
ty: VOID, ty: VOID,