Encode iconst.i32 for RISC-V.

For large constants with the low 12 bits clear, we already have the
"lui" encoding. Add "addi %x0" encodings for signed 12-bit constants.
This commit is contained in:
Jakob Stoklund Olesen
2017-06-22 12:11:54 -07:00
parent e83e2ccf17
commit 9e02b9818f
5 changed files with 27 additions and 2 deletions

View File

@@ -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, Icall, Icopy
from .recipes import R, Rshamt, Ricmp, I, Iz, Iicmp, Iret, Icall, Icopy
from .recipes import U, UJ, UJcall, SB, SBzero, GPsp, GPfi
from .settings import use_m
from cdsl.ast import Var
@@ -40,6 +40,11 @@ RV64.enc(base.isub.i32, R, OP32(0b000, 0b0100000))
# There are no andiw/oriw/xoriw variations.
RV64.enc(base.iadd_imm.i32, I, OPIMM32(0b000))
# Use iadd_imm with %x0 to materialize constants.
RV32.enc(base.iconst.i32, Iz, OPIMM(0b000))
RV64.enc(base.iconst.i32, Iz, OPIMM(0b000))
RV64.enc(base.iconst.i64, Iz, OPIMM(0b000))
# Dynamic shifts have the same masking semantics as the cton base instructions.
for inst, inst_imm, f3, f7 in [
(base.ishl, base.ishl_imm, 0b001, 0b0000000),

View File

@@ -104,6 +104,11 @@ I = EncRecipe(
'I', BinaryImm, size=4, ins=GPR, outs=GPR,
instp=IsSignedInt(BinaryImm.imm, 12))
# I-type instruction with a hardcoded %x0 rs1.
Iz = EncRecipe(
'Iz', UnaryImm, size=4, ins=(), outs=GPR,
instp=IsSignedInt(UnaryImm.imm, 12))
# I-type encoding of an integer comparison.
Iicmp = EncRecipe(
'Iicmp', IntCompareImm, size=4, ins=GPR, outs=GPR,

View File

@@ -160,6 +160,18 @@ fn recipe_i<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) {
}
}
fn recipe_iz<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) {
if let InstructionData::UnaryImm { imm, .. } = func.dfg[inst] {
put_i(func.encodings[inst].bits(),
0,
imm.into(),
func.locations[func.dfg.first_result(inst)].unwrap_reg(),
sink);
} else {
panic!("Expected UnaryImm format: {:?}", func.dfg[inst]);
}
}
fn recipe_iicmp<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) {
if let InstructionData::IntCompareImm { arg, imm, .. } = func.dfg[inst] {
put_i(func.encodings[inst].bits(),