diff --git a/lib/cretonne/meta/gen_legalizer.py b/lib/cretonne/meta/gen_legalizer.py index 54678b4284..51368fea44 100644 --- a/lib/cretonne/meta/gen_legalizer.py +++ b/lib/cretonne/meta/gen_legalizer.py @@ -360,6 +360,7 @@ def gen_xform_group(xgrp, fmt, type_sets): fmt.line('inst: ir::Inst,') fmt.line('func: &mut ir::Function,') fmt.line('cfg: &mut ::flowgraph::ControlFlowGraph,') + fmt.line('isa: &::isa::TargetIsa,') with fmt.indented(') -> bool {', '}'): fmt.line('use ir::InstBuilder;') fmt.line('use cursor::{Cursor, FuncCursor};') @@ -387,7 +388,7 @@ def gen_xform_group(xgrp, fmt, type_sets): with fmt.indented( 'ir::Opcode::{} => {{' .format(inst.camel_name), '}'): - fmt.format('{}(inst, pos.func, cfg);', funcname) + fmt.format('{}(inst, pos.func, cfg, isa);', funcname) fmt.line('return true;') # We'll assume there are uncovered opcodes. @@ -395,7 +396,7 @@ def gen_xform_group(xgrp, fmt, type_sets): # If we fall through, nothing was expanded. Call the chain if any. if xgrp.chain: - fmt.format('{}(inst, pos.func, cfg)', xgrp.chain.rust_name()) + fmt.format('{}(inst, pos.func, cfg, isa)', xgrp.chain.rust_name()) else: fmt.line('false') diff --git a/lib/cretonne/src/isa/intel/enc_tables.rs b/lib/cretonne/src/isa/intel/enc_tables.rs index 8265b731e7..a97607c4c7 100644 --- a/lib/cretonne/src/isa/intel/enc_tables.rs +++ b/lib/cretonne/src/isa/intel/enc_tables.rs @@ -15,7 +15,12 @@ include!(concat!(env!("OUT_DIR"), "/encoding-intel.rs")); include!(concat!(env!("OUT_DIR"), "/legalize-intel.rs")); /// Expand the `srem` instruction using `x86_sdivmodx`. -fn expand_srem(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { +fn expand_srem( + inst: ir::Inst, + func: &mut ir::Function, + cfg: &mut ControlFlowGraph, + _isa: &isa::TargetIsa, +) { use ir::condcodes::IntCC; let (x, y) = match func.dfg[inst] { @@ -70,7 +75,12 @@ fn expand_srem(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGra /// Expand the `fmin` and `fmax` instructions using the Intel `x86_fmin` and `x86_fmax` /// instructions. -fn expand_minmax(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { +fn expand_minmax( + inst: ir::Inst, + func: &mut ir::Function, + cfg: &mut ControlFlowGraph, + _isa: &isa::TargetIsa, +) { use ir::condcodes::FloatCC; let (x, y, x86_opc, bitwise_opc) = match func.dfg[inst] { @@ -159,7 +169,12 @@ fn expand_minmax(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowG /// Intel has no unsigned-to-float conversions. We handle the easy case of zero-extending i32 to /// i64 with a pattern, the rest needs more code. -fn expand_fcvt_from_uint(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { +fn expand_fcvt_from_uint( + inst: ir::Inst, + func: &mut ir::Function, + cfg: &mut ControlFlowGraph, + _isa: &isa::TargetIsa, +) { use ir::condcodes::IntCC; let x; @@ -227,7 +242,12 @@ fn expand_fcvt_from_uint(inst: ir::Inst, func: &mut ir::Function, cfg: &mut Cont cfg.recompute_ebb(pos.func, done); } -fn expand_fcvt_to_sint(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { +fn expand_fcvt_to_sint( + inst: ir::Inst, + func: &mut ir::Function, + cfg: &mut ControlFlowGraph, + _isa: &isa::TargetIsa, +) { use ir::condcodes::{IntCC, FloatCC}; use ir::immediates::{Ieee32, Ieee64}; @@ -303,7 +323,12 @@ fn expand_fcvt_to_sint(inst: ir::Inst, func: &mut ir::Function, cfg: &mut Contro cfg.recompute_ebb(pos.func, done); } -fn expand_fcvt_to_uint(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { +fn expand_fcvt_to_uint( + inst: ir::Inst, + func: &mut ir::Function, + cfg: &mut ControlFlowGraph, + _isa: &isa::TargetIsa, +) { use ir::condcodes::{IntCC, FloatCC}; use ir::immediates::{Ieee32, Ieee64}; diff --git a/lib/cretonne/src/isa/mod.rs b/lib/cretonne/src/isa/mod.rs index b4227d2550..f1ebf39a77 100644 --- a/lib/cretonne/src/isa/mod.rs +++ b/lib/cretonne/src/isa/mod.rs @@ -144,7 +144,8 @@ impl settings::Configurable for Builder { /// The `Encodings` iterator returns a legalization function to call. pub type Legalize = fn(ir::Inst, &mut ir::Function, - &mut flowgraph::ControlFlowGraph) + &mut flowgraph::ControlFlowGraph, + &TargetIsa) -> bool; /// Methods that are specialized to a target ISA. Implies a Display trait that shows the diff --git a/lib/cretonne/src/legalizer/globalvar.rs b/lib/cretonne/src/legalizer/globalvar.rs index 717be0d4f0..b945923f2f 100644 --- a/lib/cretonne/src/legalizer/globalvar.rs +++ b/lib/cretonne/src/legalizer/globalvar.rs @@ -6,9 +6,15 @@ use cursor::{Cursor, FuncCursor}; use flowgraph::ControlFlowGraph; use ir::{self, InstBuilder}; +use isa::TargetIsa; /// Expand a `global_addr` instruction according to the definition of the global variable. -pub fn expand_global_addr(inst: ir::Inst, func: &mut ir::Function, _cfg: &mut ControlFlowGraph) { +pub fn expand_global_addr( + inst: ir::Inst, + func: &mut ir::Function, + _cfg: &mut ControlFlowGraph, + _isa: &TargetIsa, +) { // Unpack the instruction. let gv = match func.dfg[inst] { ir::InstructionData::UnaryGlobalVar { opcode, global_var } => { diff --git a/lib/cretonne/src/legalizer/heap.rs b/lib/cretonne/src/legalizer/heap.rs index 6dd5c11095..af40181d1a 100644 --- a/lib/cretonne/src/legalizer/heap.rs +++ b/lib/cretonne/src/legalizer/heap.rs @@ -7,9 +7,15 @@ use cursor::{Cursor, FuncCursor}; use flowgraph::ControlFlowGraph; use ir::{self, InstBuilder, MemFlags}; use ir::condcodes::IntCC; +use isa::TargetIsa; /// Expand a `heap_addr` instruction according to the definition of the heap. -pub fn expand_heap_addr(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { +pub fn expand_heap_addr( + inst: ir::Inst, + func: &mut ir::Function, + cfg: &mut ControlFlowGraph, + _isa: &TargetIsa, +) { // Unpack the instruction. let (heap, offset, size) = match func.dfg[inst] { ir::InstructionData::HeapAddr { diff --git a/lib/cretonne/src/legalizer/mod.rs b/lib/cretonne/src/legalizer/mod.rs index 8849e215e8..565f3e0971 100644 --- a/lib/cretonne/src/legalizer/mod.rs +++ b/lib/cretonne/src/legalizer/mod.rs @@ -80,7 +80,7 @@ pub fn legalize_function(func: &mut ir::Function, cfg: &mut ControlFlowGraph, is Ok(encoding) => pos.func.encodings[inst] = encoding, Err(action) => { // We should transform the instruction into legal equivalents. - let changed = action(inst, pos.func, cfg); + let changed = action(inst, pos.func, cfg, isa); // If the current instruction was replaced, we need to double back and revisit // the expanded sequence. This is both to assign encodings and possible to // expand further. @@ -114,7 +114,12 @@ include!(concat!(env!("OUT_DIR"), "/legalizer.rs")); /// Custom expansion for conditional trap instructions. /// TODO: Add CFG support to the Python patterns so we won't have to do this. -fn expand_cond_trap(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { +fn expand_cond_trap( + inst: ir::Inst, + func: &mut ir::Function, + cfg: &mut ControlFlowGraph, + _isa: &TargetIsa, +) { // Parse the instruction. let trapz; let (arg, code) = match func.dfg[inst] { @@ -159,7 +164,12 @@ fn expand_cond_trap(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFl } /// Jump tables. -fn expand_br_table(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { +fn expand_br_table( + inst: ir::Inst, + func: &mut ir::Function, + cfg: &mut ControlFlowGraph, + _isa: &TargetIsa, +) { use ir::condcodes::IntCC; let (arg, table) = match func.dfg[inst] { @@ -194,7 +204,12 @@ fn expand_br_table(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlo /// /// Conditional moves are available in some ISAs for some register classes. The remaining selects /// are handled by a branch. -fn expand_select(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowGraph) { +fn expand_select( + inst: ir::Inst, + func: &mut ir::Function, + cfg: &mut ControlFlowGraph, + _isa: &TargetIsa, +) { let (ctrl, tval, fval) = match func.dfg[inst] { ir::InstructionData::Ternary { opcode: ir::Opcode::Select, @@ -226,7 +241,12 @@ fn expand_select(inst: ir::Inst, func: &mut ir::Function, cfg: &mut ControlFlowG /// Expand illegal `f32const` and `f64const` instructions. -fn expand_fconst(inst: ir::Inst, func: &mut ir::Function, _cfg: &mut ControlFlowGraph) { +fn expand_fconst( + inst: ir::Inst, + func: &mut ir::Function, + _cfg: &mut ControlFlowGraph, + _isa: &TargetIsa, +) { let ty = func.dfg.value_type(func.dfg.first_result(inst)); assert!(!ty.is_vector(), "Only scalar fconst supported: {}", ty);