Add RISC-V encodings for lui.
This instruction can materialize constants with the low 12 bits clear.
This commit is contained in:
@@ -71,5 +71,9 @@ ebb0:
|
|||||||
[-,%x7] v132 = icmp_imm ult, v1, 1000 ; bin: 3e853393
|
[-,%x7] v132 = icmp_imm ult, v1, 1000 ; bin: 3e853393
|
||||||
[-,%x16] v133 = icmp_imm ult, v2, -905 ; bin: c77ab813
|
[-,%x16] v133 = icmp_imm ult, v2, -905 ; bin: c77ab813
|
||||||
|
|
||||||
|
; lui
|
||||||
|
[-,%x7] v140 = iconst.i32 0x12345000 ; bin: 123453b7
|
||||||
|
[-,%x16] v141 = iconst.i32 0xffffffff_fedcb000 ; bin: fedcb837
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ from __future__ import absolute_import
|
|||||||
from base import instructions as base
|
from base import instructions as base
|
||||||
from base.immediates import intcc
|
from base.immediates import intcc
|
||||||
from .defs import RV32, RV64
|
from .defs import RV32, RV64
|
||||||
from .recipes import OPIMM, OPIMM32, OP, OP32
|
from .recipes import OPIMM, OPIMM32, OP, OP32, LUI
|
||||||
from .recipes import JALR, R, Rshamt, Ricmp, I, Iicmp, Iret
|
from .recipes import JALR, R, Rshamt, Ricmp, I, Iicmp, Iret, U
|
||||||
from .settings import use_m
|
from .settings import use_m
|
||||||
from cdsl.ast import Var
|
from cdsl.ast import Var
|
||||||
|
|
||||||
@@ -66,6 +66,11 @@ RV64.enc(base.icmp_imm.i64(intcc.slt, x, y), Iicmp, OPIMM(0b010))
|
|||||||
RV32.enc(base.icmp_imm.i32(intcc.ult, x, y), Iicmp, OPIMM(0b011))
|
RV32.enc(base.icmp_imm.i32(intcc.ult, x, y), Iicmp, OPIMM(0b011))
|
||||||
RV64.enc(base.icmp_imm.i64(intcc.ult, x, y), Iicmp, OPIMM(0b011))
|
RV64.enc(base.icmp_imm.i64(intcc.ult, x, y), Iicmp, OPIMM(0b011))
|
||||||
|
|
||||||
|
# Integer constants with the low 12 bits clear are materialized by lui.
|
||||||
|
RV32.enc(base.iconst.i32, U, LUI())
|
||||||
|
RV64.enc(base.iconst.i32, U, LUI())
|
||||||
|
RV64.enc(base.iconst.i64, U, LUI())
|
||||||
|
|
||||||
# "M" Standard Extension for Integer Multiplication and Division.
|
# "M" Standard Extension for Integer Multiplication and Division.
|
||||||
# Gated by the `use_m` flag.
|
# Gated by the `use_m` flag.
|
||||||
RV32.enc(base.imul.i32, R, OP(0b000, 0b0000001), isap=use_m)
|
RV32.enc(base.imul.i32, R, OP(0b000, 0b0000001), isap=use_m)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ 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, MultiAry, IntCompare, IntCompareImm
|
from base.formats import Binary, BinaryImm, MultiAry, IntCompare, IntCompareImm
|
||||||
|
from base.formats import UnaryImm
|
||||||
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
|
||||||
@@ -72,6 +73,16 @@ def OP32(funct3, funct7):
|
|||||||
return 0b01110 | (funct3 << 5) | (funct7 << 8)
|
return 0b01110 | (funct3 << 5) | (funct7 << 8)
|
||||||
|
|
||||||
|
|
||||||
|
def AIUPC():
|
||||||
|
# type: () -> int
|
||||||
|
return 0b00101
|
||||||
|
|
||||||
|
|
||||||
|
def LUI():
|
||||||
|
# type: () -> int
|
||||||
|
return 0b01101
|
||||||
|
|
||||||
|
|
||||||
# R-type 32-bit instructions: These are mostly binary arithmetic instructions.
|
# R-type 32-bit instructions: These are mostly binary arithmetic instructions.
|
||||||
# The encbits are `opcode[6:2] | (funct3 << 5) | (funct7 << 8)
|
# The encbits are `opcode[6:2] | (funct3 << 5) | (funct7 << 8)
|
||||||
R = EncRecipe('R', Binary, ins=(GPR, GPR), outs=GPR)
|
R = EncRecipe('R', Binary, ins=(GPR, GPR), outs=GPR)
|
||||||
@@ -95,3 +106,8 @@ Iicmp = EncRecipe(
|
|||||||
# immediate offset.
|
# immediate offset.
|
||||||
# The variable return values are not encoded.
|
# The variable return values are not encoded.
|
||||||
Iret = EncRecipe('Iret', MultiAry, ins=GPR, outs=())
|
Iret = EncRecipe('Iret', MultiAry, ins=GPR, outs=())
|
||||||
|
|
||||||
|
# U-type instructions have a 20-bit immediate that targets bits 12-31.
|
||||||
|
U = EncRecipe(
|
||||||
|
'U', UnaryImm, ins=(), outs=GPR,
|
||||||
|
instp=IsSignedInt(UnaryImm.imm, 32, 12))
|
||||||
|
|||||||
@@ -160,3 +160,35 @@ fn recipe_iicmp<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut C
|
|||||||
fn recipe_iret<CS: CodeSink + ?Sized>(_func: &Function, _inst: Inst, _sink: &mut CS) {
|
fn recipe_iret<CS: CodeSink + ?Sized>(_func: &Function, _inst: Inst, _sink: &mut CS) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// U-type instructions.
|
||||||
|
///
|
||||||
|
/// 31 11 6
|
||||||
|
/// imm rd opcode
|
||||||
|
/// 12 7 0
|
||||||
|
///
|
||||||
|
/// Encoding bits: `opcode[6:2] | (funct3 << 5)`
|
||||||
|
fn put_u<CS: CodeSink + ?Sized>(bits: u16, imm: i64, rd: RegUnit, sink: &mut CS) {
|
||||||
|
let bits = bits as u32;
|
||||||
|
let opcode5 = bits & 0x1f;
|
||||||
|
let rd = rd as u32 & 0x1f;
|
||||||
|
|
||||||
|
// 0-6: opcode
|
||||||
|
let mut i = 0x3;
|
||||||
|
i |= opcode5 << 2;
|
||||||
|
i |= rd << 7;
|
||||||
|
i |= imm as u32 & 0xfffff000;
|
||||||
|
|
||||||
|
sink.put4(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recipe_u<CS: CodeSink + ?Sized>(func: &Function, inst: Inst, sink: &mut CS) {
|
||||||
|
if let InstructionData::UnaryImm { imm, .. } = func.dfg[inst] {
|
||||||
|
put_u(func.encodings[inst].bits(),
|
||||||
|
imm.into(),
|
||||||
|
func.locations[func.dfg.first_result(inst)].unwrap_reg(),
|
||||||
|
sink);
|
||||||
|
} else {
|
||||||
|
panic!("Expected UnaryImm format: {:?}", func.dfg[inst]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user