Pass an ISA argument to legalization functions.
This lets them look at the ISA flags.
This commit is contained in:
@@ -360,6 +360,7 @@ def gen_xform_group(xgrp, fmt, type_sets):
|
|||||||
fmt.line('inst: ir::Inst,')
|
fmt.line('inst: ir::Inst,')
|
||||||
fmt.line('func: &mut ir::Function,')
|
fmt.line('func: &mut ir::Function,')
|
||||||
fmt.line('cfg: &mut ::flowgraph::ControlFlowGraph,')
|
fmt.line('cfg: &mut ::flowgraph::ControlFlowGraph,')
|
||||||
|
fmt.line('isa: &::isa::TargetIsa,')
|
||||||
with fmt.indented(') -> bool {', '}'):
|
with fmt.indented(') -> bool {', '}'):
|
||||||
fmt.line('use ir::InstBuilder;')
|
fmt.line('use ir::InstBuilder;')
|
||||||
fmt.line('use cursor::{Cursor, FuncCursor};')
|
fmt.line('use cursor::{Cursor, FuncCursor};')
|
||||||
@@ -387,7 +388,7 @@ def gen_xform_group(xgrp, fmt, type_sets):
|
|||||||
with fmt.indented(
|
with fmt.indented(
|
||||||
'ir::Opcode::{} => {{'
|
'ir::Opcode::{} => {{'
|
||||||
.format(inst.camel_name), '}'):
|
.format(inst.camel_name), '}'):
|
||||||
fmt.format('{}(inst, pos.func, cfg);', funcname)
|
fmt.format('{}(inst, pos.func, cfg, isa);', funcname)
|
||||||
fmt.line('return true;')
|
fmt.line('return true;')
|
||||||
|
|
||||||
# We'll assume there are uncovered opcodes.
|
# 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 we fall through, nothing was expanded. Call the chain if any.
|
||||||
if xgrp.chain:
|
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:
|
else:
|
||||||
fmt.line('false')
|
fmt.line('false')
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,12 @@ include!(concat!(env!("OUT_DIR"), "/encoding-intel.rs"));
|
|||||||
include!(concat!(env!("OUT_DIR"), "/legalize-intel.rs"));
|
include!(concat!(env!("OUT_DIR"), "/legalize-intel.rs"));
|
||||||
|
|
||||||
/// Expand the `srem` instruction using `x86_sdivmodx`.
|
/// 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;
|
use ir::condcodes::IntCC;
|
||||||
|
|
||||||
let (x, y) = match func.dfg[inst] {
|
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`
|
/// Expand the `fmin` and `fmax` instructions using the Intel `x86_fmin` and `x86_fmax`
|
||||||
/// instructions.
|
/// 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;
|
use ir::condcodes::FloatCC;
|
||||||
|
|
||||||
let (x, y, x86_opc, bitwise_opc) = match func.dfg[inst] {
|
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
|
/// 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.
|
/// 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;
|
use ir::condcodes::IntCC;
|
||||||
|
|
||||||
let x;
|
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);
|
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::condcodes::{IntCC, FloatCC};
|
||||||
use ir::immediates::{Ieee32, Ieee64};
|
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);
|
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::condcodes::{IntCC, FloatCC};
|
||||||
use ir::immediates::{Ieee32, Ieee64};
|
use ir::immediates::{Ieee32, Ieee64};
|
||||||
|
|
||||||
|
|||||||
@@ -144,7 +144,8 @@ impl settings::Configurable for Builder {
|
|||||||
/// The `Encodings` iterator returns a legalization function to call.
|
/// The `Encodings` iterator returns a legalization function to call.
|
||||||
pub type Legalize = fn(ir::Inst,
|
pub type Legalize = fn(ir::Inst,
|
||||||
&mut ir::Function,
|
&mut ir::Function,
|
||||||
&mut flowgraph::ControlFlowGraph)
|
&mut flowgraph::ControlFlowGraph,
|
||||||
|
&TargetIsa)
|
||||||
-> bool;
|
-> bool;
|
||||||
|
|
||||||
/// Methods that are specialized to a target ISA. Implies a Display trait that shows the
|
/// Methods that are specialized to a target ISA. Implies a Display trait that shows the
|
||||||
|
|||||||
@@ -6,9 +6,15 @@
|
|||||||
use cursor::{Cursor, FuncCursor};
|
use cursor::{Cursor, FuncCursor};
|
||||||
use flowgraph::ControlFlowGraph;
|
use flowgraph::ControlFlowGraph;
|
||||||
use ir::{self, InstBuilder};
|
use ir::{self, InstBuilder};
|
||||||
|
use isa::TargetIsa;
|
||||||
|
|
||||||
/// Expand a `global_addr` instruction according to the definition of the global variable.
|
/// 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.
|
// Unpack the instruction.
|
||||||
let gv = match func.dfg[inst] {
|
let gv = match func.dfg[inst] {
|
||||||
ir::InstructionData::UnaryGlobalVar { opcode, global_var } => {
|
ir::InstructionData::UnaryGlobalVar { opcode, global_var } => {
|
||||||
|
|||||||
@@ -7,9 +7,15 @@ use cursor::{Cursor, FuncCursor};
|
|||||||
use flowgraph::ControlFlowGraph;
|
use flowgraph::ControlFlowGraph;
|
||||||
use ir::{self, InstBuilder, MemFlags};
|
use ir::{self, InstBuilder, MemFlags};
|
||||||
use ir::condcodes::IntCC;
|
use ir::condcodes::IntCC;
|
||||||
|
use isa::TargetIsa;
|
||||||
|
|
||||||
/// Expand a `heap_addr` instruction according to the definition of the heap.
|
/// 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.
|
// Unpack the instruction.
|
||||||
let (heap, offset, size) = match func.dfg[inst] {
|
let (heap, offset, size) = match func.dfg[inst] {
|
||||||
ir::InstructionData::HeapAddr {
|
ir::InstructionData::HeapAddr {
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ pub fn legalize_function(func: &mut ir::Function, cfg: &mut ControlFlowGraph, is
|
|||||||
Ok(encoding) => pos.func.encodings[inst] = encoding,
|
Ok(encoding) => pos.func.encodings[inst] = encoding,
|
||||||
Err(action) => {
|
Err(action) => {
|
||||||
// We should transform the instruction into legal equivalents.
|
// 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
|
// 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
|
// the expanded sequence. This is both to assign encodings and possible to
|
||||||
// expand further.
|
// expand further.
|
||||||
@@ -114,7 +114,12 @@ include!(concat!(env!("OUT_DIR"), "/legalizer.rs"));
|
|||||||
|
|
||||||
/// Custom expansion for conditional trap instructions.
|
/// Custom expansion for conditional trap instructions.
|
||||||
/// TODO: Add CFG support to the Python patterns so we won't have to do this.
|
/// 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.
|
// Parse the instruction.
|
||||||
let trapz;
|
let trapz;
|
||||||
let (arg, code) = match func.dfg[inst] {
|
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.
|
/// 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;
|
use ir::condcodes::IntCC;
|
||||||
|
|
||||||
let (arg, table) = match func.dfg[inst] {
|
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
|
/// Conditional moves are available in some ISAs for some register classes. The remaining selects
|
||||||
/// are handled by a branch.
|
/// 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] {
|
let (ctrl, tval, fval) = match func.dfg[inst] {
|
||||||
ir::InstructionData::Ternary {
|
ir::InstructionData::Ternary {
|
||||||
opcode: ir::Opcode::Select,
|
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.
|
/// 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));
|
let ty = func.dfg.value_type(func.dfg.first_result(inst));
|
||||||
assert!(!ty.is_vector(), "Only scalar fconst supported: {}", ty);
|
assert!(!ty.is_vector(), "Only scalar fconst supported: {}", ty);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user