Add custom legalization for floating point constants.

Use the simplest expansion which materializes the bits of the floating
point constant as an integer and then bit-casts to the floating point
type. In the future, we may want to use constant pools instead. Either
way, we need custom legalization.

Also add a legalize_monomorphic() function to the Python targetISA class
which permits the configuration of a default legalization action for
monomorphic instructions, just like legalize_type() does for polymorphic
instructions.
This commit is contained in:
Jakob Stoklund Olesen
2017-09-18 13:27:25 -07:00
parent d2273c73ea
commit 88348368a8
7 changed files with 67 additions and 0 deletions

View File

@@ -599,6 +599,11 @@ impl Ieee32 {
pub fn with_float(x: f32) -> Ieee32 {
Ieee32(unsafe { mem::transmute(x) })
}
/// Get the bitwise representation.
pub fn bits(self) -> u32 {
self.0
}
}
impl Display for Ieee32 {
@@ -630,6 +635,11 @@ impl Ieee64 {
pub fn with_float(x: f64) -> Ieee64 {
Ieee64(unsafe { mem::transmute(x) })
}
/// Get the bitwise representation.
pub fn bits(self) -> u64 {
self.0
}
}
impl Display for Ieee64 {

View File

@@ -146,3 +146,25 @@ fn expand_cond_trap(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFl
cfg.recompute_ebb(pos.func, old_ebb);
cfg.recompute_ebb(pos.func, new_ebb);
}
/// Expand illegal `f32const` and `f64const` instructions.
fn expand_fconst(inst: ir::Inst, func: &mut ir::Function, _cfg: &mut ControlFlowGraph) {
let ty = func.dfg.value_type(func.dfg.first_result(inst));
assert!(ty.is_scalar(), "Only scalar fconst supported: {}", ty);
// In the future, we may want to generate constant pool entries for these constants, but for
// now use an `iconst` and a bit cast.
let mut pos = FuncCursor::new(func).at_inst(inst);
let ival = match pos.func.dfg[inst] {
ir::InstructionData::UnaryIeee32 {
opcode: ir::Opcode::F32const,
imm,
} => pos.ins().iconst(ir::types::I32, imm.bits() as i64),
ir::InstructionData::UnaryIeee64 {
opcode: ir::Opcode::F64const,
imm,
} => pos.ins().iconst(ir::types::I64, imm.bits() as i64),
_ => panic!("Expected fconst: {}", pos.func.dfg.display_inst(inst, None)),
};
pos.func.dfg.replace(inst).bitcast(ty, ival);
}