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:
@@ -77,6 +77,9 @@ ebb0(v9999: i32):
|
|||||||
; lui
|
; lui
|
||||||
[-,%x7] v140 = iconst.i32 0x12345000 ; bin: 123453b7
|
[-,%x7] v140 = iconst.i32 0x12345000 ; bin: 123453b7
|
||||||
[-,%x16] v141 = iconst.i32 0xffffffff_fedcb000 ; bin: fedcb837
|
[-,%x16] v141 = iconst.i32 0xffffffff_fedcb000 ; bin: fedcb837
|
||||||
|
; addi
|
||||||
|
[-,%x7] v142 = iconst.i32 1000 ; bin: 3e800393
|
||||||
|
[-,%x16] v143 = iconst.i32 -905 ; bin: c7700813
|
||||||
|
|
||||||
; Copies alias to iadd_imm.
|
; Copies alias to iadd_imm.
|
||||||
[-,%x7] v150 = copy v1 ; bin: 00050393
|
[-,%x7] v150 = copy v1 ; bin: 00050393
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ function %RV32I(i32 link [%x1]) -> i32 link [%x1] {
|
|||||||
|
|
||||||
ebb0(v9999: i32):
|
ebb0(v9999: i32):
|
||||||
; iconst.i32 needs legalizing, so it should throw a
|
; iconst.i32 needs legalizing, so it should throw a
|
||||||
[R#0,-] v1 = iconst.i32 1 ; error: Instruction failed to re-encode
|
[R#0,-] v1 = iconst.i32 0xf0f0f0f0f0 ; error: Instruction failed to re-encode
|
||||||
return v9999
|
return v9999
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from base.immediates import intcc
|
|||||||
from .defs import RV32, RV64
|
from .defs import RV32, RV64
|
||||||
from .recipes import OPIMM, OPIMM32, OP, OP32, LUI, BRANCH, JALR, JAL
|
from .recipes import OPIMM, OPIMM32, OP, OP32, LUI, BRANCH, JALR, JAL
|
||||||
from .recipes import LOAD, STORE
|
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 .recipes import U, UJ, UJcall, SB, SBzero, GPsp, GPfi
|
||||||
from .settings import use_m
|
from .settings import use_m
|
||||||
from cdsl.ast import Var
|
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.
|
# There are no andiw/oriw/xoriw variations.
|
||||||
RV64.enc(base.iadd_imm.i32, I, OPIMM32(0b000))
|
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.
|
# Dynamic shifts have the same masking semantics as the cton base instructions.
|
||||||
for inst, inst_imm, f3, f7 in [
|
for inst, inst_imm, f3, f7 in [
|
||||||
(base.ishl, base.ishl_imm, 0b001, 0b0000000),
|
(base.ishl, base.ishl_imm, 0b001, 0b0000000),
|
||||||
|
|||||||
@@ -104,6 +104,11 @@ I = EncRecipe(
|
|||||||
'I', BinaryImm, size=4, ins=GPR, outs=GPR,
|
'I', BinaryImm, size=4, ins=GPR, outs=GPR,
|
||||||
instp=IsSignedInt(BinaryImm.imm, 12))
|
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.
|
# I-type encoding of an integer comparison.
|
||||||
Iicmp = EncRecipe(
|
Iicmp = EncRecipe(
|
||||||
'Iicmp', IntCompareImm, size=4, ins=GPR, outs=GPR,
|
'Iicmp', IntCompareImm, size=4, ins=GPR, outs=GPR,
|
||||||
|
|||||||
@@ -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) {
|
fn recipe_iicmp<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) {
|
||||||
if let InstructionData::IntCompareImm { arg, imm, .. } = func.dfg[inst] {
|
if let InstructionData::IntCompareImm { arg, imm, .. } = func.dfg[inst] {
|
||||||
put_i(func.encodings[inst].bits(),
|
put_i(func.encodings[inst].bits(),
|
||||||
|
|||||||
Reference in New Issue
Block a user