Add return_reg encodings for RISC-V.
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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=())
|
||||||
|
|||||||
@@ -241,9 +241,9 @@ fn write_instruction(w: &mut Write,
|
|||||||
}
|
}
|
||||||
ReturnReg { ref data, .. } => {
|
ReturnReg { ref data, .. } => {
|
||||||
if data.varargs.is_empty() {
|
if data.varargs.is_empty() {
|
||||||
writeln!(w, "{}", data.arg)
|
writeln!(w, " {}", data.arg)
|
||||||
} else {
|
} else {
|
||||||
writeln!(w, "{}, {}", data.arg, data.varargs)
|
writeln!(w, " {}, {}", data.arg, data.varargs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user