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('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')
|
||||
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 } => {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user