Merge pull request #3655 from bjorn3/machinst_cleanups2
Remove MachBackend
This commit is contained in:
@@ -167,8 +167,7 @@ impl Context {
|
|||||||
|
|
||||||
self.remove_constant_phis(isa)?;
|
self.remove_constant_phis(isa)?;
|
||||||
|
|
||||||
let backend = isa.get_mach_backend();
|
let result = isa.compile_function(&self.func, self.want_disasm)?;
|
||||||
let result = backend.compile_function(&self.func, self.want_disasm)?;
|
|
||||||
let info = result.code_info();
|
let info = result.code_info();
|
||||||
self.mach_compile_result = Some(result);
|
self.mach_compile_result = Some(result);
|
||||||
Ok(info)
|
Ok(info)
|
||||||
@@ -242,10 +241,9 @@ impl Context {
|
|||||||
&self,
|
&self,
|
||||||
isa: &dyn TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) -> CodegenResult<Option<crate::isa::unwind::UnwindInfo>> {
|
) -> CodegenResult<Option<crate::isa::unwind::UnwindInfo>> {
|
||||||
let backend = isa.get_mach_backend();
|
|
||||||
let unwind_info_kind = isa.unwind_info_kind();
|
let unwind_info_kind = isa.unwind_info_kind();
|
||||||
let result = self.mach_compile_result.as_ref().unwrap();
|
let result = self.mach_compile_result.as_ref().unwrap();
|
||||||
backend.emit_unwind_info(result, unwind_info_kind)
|
isa.emit_unwind_info(result, unwind_info_kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the verifier on the function.
|
/// Run the verifier on the function.
|
||||||
|
|||||||
@@ -2017,10 +2017,6 @@ impl MachInst for Inst {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reg_universe(flags: &settings::Flags) -> RealRegUniverse {
|
|
||||||
create_reg_universe(flags)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn worst_case_size() -> CodeOffset {
|
fn worst_case_size() -> CodeOffset {
|
||||||
// The maximum size, in bytes, of any `Inst`'s emitted code. We have at least one case of
|
// The maximum size, in bytes, of any `Inst`'s emitted code. We have at least one case of
|
||||||
// an 8-instruction sequence (saturating int-to-float conversions) with three embedded
|
// an 8-instruction sequence (saturating int-to-float conversions) with three embedded
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
use crate::ir::condcodes::IntCC;
|
use crate::ir::condcodes::IntCC;
|
||||||
use crate::ir::Function;
|
use crate::ir::Function;
|
||||||
use crate::isa::aarch64::settings as aarch64_settings;
|
use crate::isa::aarch64::settings as aarch64_settings;
|
||||||
use crate::isa::Builder as IsaBuilder;
|
use crate::isa::{Builder as IsaBuilder, TargetIsa};
|
||||||
use crate::machinst::{
|
use crate::machinst::{
|
||||||
compile, MachBackend, MachCompileResult, MachTextSectionBuilder, TargetIsaAdapter,
|
compile, MachCompileResult, MachTextSectionBuilder, TextSectionBuilder, VCode,
|
||||||
TextSectionBuilder, VCode,
|
|
||||||
};
|
};
|
||||||
use crate::result::CodegenResult;
|
use crate::result::CodegenResult;
|
||||||
use crate::settings as shared_settings;
|
use crate::settings as shared_settings;
|
||||||
use alloc::{boxed::Box, vec::Vec};
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
|
use core::fmt;
|
||||||
use regalloc::{PrettyPrint, RealRegUniverse};
|
use regalloc::{PrettyPrint, RealRegUniverse};
|
||||||
use target_lexicon::{Aarch64Architecture, Architecture, Triple};
|
use target_lexicon::{Aarch64Architecture, Architecture, Triple};
|
||||||
|
|
||||||
@@ -58,11 +58,11 @@ impl AArch64Backend {
|
|||||||
) -> CodegenResult<VCode<inst::Inst>> {
|
) -> CodegenResult<VCode<inst::Inst>> {
|
||||||
let emit_info = EmitInfo::new(flags.clone());
|
let emit_info = EmitInfo::new(flags.clone());
|
||||||
let abi = Box::new(abi::AArch64ABICallee::new(func, flags)?);
|
let abi = Box::new(abi::AArch64ABICallee::new(func, flags)?);
|
||||||
compile::compile::<AArch64Backend>(func, self, abi, emit_info)
|
compile::compile::<AArch64Backend>(func, self, abi, &self.reg_universe, emit_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachBackend for AArch64Backend {
|
impl TargetIsa for AArch64Backend {
|
||||||
fn compile_function(
|
fn compile_function(
|
||||||
&self,
|
&self,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
@@ -110,10 +110,6 @@ impl MachBackend for AArch64Backend {
|
|||||||
self.isa_flags.iter().collect()
|
self.isa_flags.iter().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reg_universe(&self) -> &RealRegUniverse {
|
|
||||||
&self.reg_universe
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unsigned_add_overflow_condition(&self) -> IntCC {
|
fn unsigned_add_overflow_condition(&self) -> IntCC {
|
||||||
// Unsigned `>=`; this corresponds to the carry flag set on aarch64, which happens on
|
// Unsigned `>=`; this corresponds to the carry flag set on aarch64, which happens on
|
||||||
// overflow of an add.
|
// overflow of an add.
|
||||||
@@ -157,6 +153,16 @@ impl MachBackend for AArch64Backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for AArch64Backend {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_struct("MachBackend")
|
||||||
|
.field("name", &self.name())
|
||||||
|
.field("triple", &self.triple())
|
||||||
|
.field("flags", &format!("{}", self.flags()))
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new `isa::Builder`.
|
/// Create a new `isa::Builder`.
|
||||||
pub fn isa_builder(triple: Triple) -> IsaBuilder {
|
pub fn isa_builder(triple: Triple) -> IsaBuilder {
|
||||||
assert!(triple.architecture == Architecture::Aarch64(Aarch64Architecture::Aarch64));
|
assert!(triple.architecture == Architecture::Aarch64(Aarch64Architecture::Aarch64));
|
||||||
@@ -166,7 +172,7 @@ pub fn isa_builder(triple: Triple) -> IsaBuilder {
|
|||||||
constructor: |triple, shared_flags, builder| {
|
constructor: |triple, shared_flags, builder| {
|
||||||
let isa_flags = aarch64_settings::Flags::new(&shared_flags, builder);
|
let isa_flags = aarch64_settings::Flags::new(&shared_flags, builder);
|
||||||
let backend = AArch64Backend::new_with_flags(triple, shared_flags, isa_flags);
|
let backend = AArch64Backend::new_with_flags(triple, shared_flags, isa_flags);
|
||||||
Box::new(TargetIsaAdapter::new(backend))
|
Box::new(backend)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -859,10 +859,6 @@ impl MachInst for Inst {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reg_universe(_flags: &settings::Flags) -> RealRegUniverse {
|
|
||||||
create_reg_universe()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn worst_case_size() -> CodeOffset {
|
fn worst_case_size() -> CodeOffset {
|
||||||
// It inst with four 32-bit instructions
|
// It inst with four 32-bit instructions
|
||||||
2 + 4 * 4
|
2 + 4 * 4
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
use crate::ir::condcodes::IntCC;
|
use crate::ir::condcodes::IntCC;
|
||||||
use crate::ir::Function;
|
use crate::ir::Function;
|
||||||
use crate::isa::Builder as IsaBuilder;
|
use crate::isa::{Builder as IsaBuilder, TargetIsa};
|
||||||
use crate::machinst::{
|
use crate::machinst::{
|
||||||
compile, MachBackend, MachCompileResult, MachTextSectionBuilder, TargetIsaAdapter,
|
compile, MachCompileResult, MachTextSectionBuilder, TextSectionBuilder, VCode,
|
||||||
TextSectionBuilder, VCode,
|
|
||||||
};
|
};
|
||||||
use crate::result::CodegenResult;
|
use crate::result::CodegenResult;
|
||||||
use crate::settings;
|
use crate::settings;
|
||||||
|
|
||||||
use alloc::{boxed::Box, vec::Vec};
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
|
use core::fmt;
|
||||||
use regalloc::{PrettyPrint, RealRegUniverse};
|
use regalloc::{PrettyPrint, RealRegUniverse};
|
||||||
use target_lexicon::{Architecture, ArmArchitecture, Triple};
|
use target_lexicon::{Architecture, ArmArchitecture, Triple};
|
||||||
|
|
||||||
@@ -49,11 +49,11 @@ impl Arm32Backend {
|
|||||||
// block layout and finalizes branches. The result is ready for binary emission.
|
// block layout and finalizes branches. The result is ready for binary emission.
|
||||||
let emit_info = EmitInfo::new(flags.clone());
|
let emit_info = EmitInfo::new(flags.clone());
|
||||||
let abi = Box::new(abi::Arm32ABICallee::new(func, flags)?);
|
let abi = Box::new(abi::Arm32ABICallee::new(func, flags)?);
|
||||||
compile::compile::<Arm32Backend>(func, self, abi, emit_info)
|
compile::compile::<Arm32Backend>(func, self, abi, &self.reg_universe, emit_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachBackend for Arm32Backend {
|
impl TargetIsa for Arm32Backend {
|
||||||
fn compile_function(
|
fn compile_function(
|
||||||
&self,
|
&self,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
@@ -100,8 +100,13 @@ impl MachBackend for Arm32Backend {
|
|||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reg_universe(&self) -> &RealRegUniverse {
|
#[cfg(feature = "unwind")]
|
||||||
&self.reg_universe
|
fn emit_unwind_info(
|
||||||
|
&self,
|
||||||
|
_result: &MachCompileResult,
|
||||||
|
_kind: crate::machinst::UnwindInfoKind,
|
||||||
|
) -> CodegenResult<Option<crate::isa::unwind::UnwindInfo>> {
|
||||||
|
Ok(None) // FIXME implement this
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unsigned_add_overflow_condition(&self) -> IntCC {
|
fn unsigned_add_overflow_condition(&self) -> IntCC {
|
||||||
@@ -114,6 +119,16 @@ impl MachBackend for Arm32Backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Arm32Backend {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_struct("MachBackend")
|
||||||
|
.field("name", &self.name())
|
||||||
|
.field("triple", &self.triple())
|
||||||
|
.field("flags", &format!("{}", self.flags()))
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new `isa::Builder`.
|
/// Create a new `isa::Builder`.
|
||||||
pub fn isa_builder(triple: Triple) -> IsaBuilder {
|
pub fn isa_builder(triple: Triple) -> IsaBuilder {
|
||||||
assert!(match triple.architecture {
|
assert!(match triple.architecture {
|
||||||
@@ -127,7 +142,7 @@ pub fn isa_builder(triple: Triple) -> IsaBuilder {
|
|||||||
setup: settings::builder(),
|
setup: settings::builder(),
|
||||||
constructor: |triple, shared_flags, _| {
|
constructor: |triple, shared_flags, _| {
|
||||||
let backend = Arm32Backend::new_with_flags(triple, shared_flags);
|
let backend = Arm32Backend::new_with_flags(triple, shared_flags);
|
||||||
Box::new(TargetIsaAdapter::new(backend))
|
Box::new(backend)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,12 +46,13 @@
|
|||||||
pub use crate::isa::call_conv::CallConv;
|
pub use crate::isa::call_conv::CallConv;
|
||||||
|
|
||||||
use crate::flowgraph;
|
use crate::flowgraph;
|
||||||
use crate::ir;
|
use crate::ir::{self, Function};
|
||||||
#[cfg(feature = "unwind")]
|
#[cfg(feature = "unwind")]
|
||||||
use crate::isa::unwind::systemv::RegisterMappingError;
|
use crate::isa::unwind::systemv::RegisterMappingError;
|
||||||
use crate::machinst::{MachBackend, UnwindInfoKind};
|
use crate::machinst::{MachCompileResult, TextSectionBuilder, UnwindInfoKind};
|
||||||
use crate::settings;
|
use crate::settings;
|
||||||
use crate::settings::SetResult;
|
use crate::settings::SetResult;
|
||||||
|
use crate::CodegenResult;
|
||||||
use alloc::{boxed::Box, vec::Vec};
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::fmt::{Debug, Formatter};
|
use core::fmt::{Debug, Formatter};
|
||||||
@@ -227,6 +228,13 @@ pub trait TargetIsa: fmt::Display + Send + Sync {
|
|||||||
/// Get the ISA-dependent flag values that were used to make this trait object.
|
/// Get the ISA-dependent flag values that were used to make this trait object.
|
||||||
fn isa_flags(&self) -> Vec<settings::Value>;
|
fn isa_flags(&self) -> Vec<settings::Value>;
|
||||||
|
|
||||||
|
/// Compile the given function.
|
||||||
|
fn compile_function(
|
||||||
|
&self,
|
||||||
|
func: &Function,
|
||||||
|
want_disasm: bool,
|
||||||
|
) -> CodegenResult<MachCompileResult>;
|
||||||
|
|
||||||
#[cfg(feature = "unwind")]
|
#[cfg(feature = "unwind")]
|
||||||
/// Map a regalloc::Reg to its corresponding DWARF register.
|
/// Map a regalloc::Reg to its corresponding DWARF register.
|
||||||
fn map_regalloc_reg_to_dwarf(&self, _: ::regalloc::Reg) -> Result<u16, RegisterMappingError> {
|
fn map_regalloc_reg_to_dwarf(&self, _: ::regalloc::Reg) -> Result<u16, RegisterMappingError> {
|
||||||
@@ -236,6 +244,16 @@ pub trait TargetIsa: fmt::Display + Send + Sync {
|
|||||||
/// IntCC condition for Unsigned Addition Overflow (Carry).
|
/// IntCC condition for Unsigned Addition Overflow (Carry).
|
||||||
fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC;
|
fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC;
|
||||||
|
|
||||||
|
/// Creates unwind information for the function.
|
||||||
|
///
|
||||||
|
/// Returns `None` if there is no unwind information for the function.
|
||||||
|
#[cfg(feature = "unwind")]
|
||||||
|
fn emit_unwind_info(
|
||||||
|
&self,
|
||||||
|
result: &MachCompileResult,
|
||||||
|
kind: UnwindInfoKind,
|
||||||
|
) -> CodegenResult<Option<crate::isa::unwind::UnwindInfo>>;
|
||||||
|
|
||||||
/// Creates a new System V Common Information Entry for the ISA.
|
/// Creates a new System V Common Information Entry for the ISA.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the ISA does not support System V unwind information.
|
/// Returns `None` if the ISA does not support System V unwind information.
|
||||||
@@ -245,8 +263,16 @@ pub trait TargetIsa: fmt::Display + Send + Sync {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the new-style MachBackend.
|
/// Returns an object that can be used to build the text section of an
|
||||||
fn get_mach_backend(&self) -> &dyn MachBackend;
|
/// executable.
|
||||||
|
///
|
||||||
|
/// This object will internally attempt to handle as many relocations as
|
||||||
|
/// possible using relative calls/jumps/etc between functions.
|
||||||
|
///
|
||||||
|
/// The `num_labeled_funcs` argument here is the number of functions which
|
||||||
|
/// will be "labeled" or might have calls between them, typically the number
|
||||||
|
/// of defined functions in the object file.
|
||||||
|
fn text_section_builder(&self, num_labeled_funcs: u32) -> Box<dyn TextSectionBuilder>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Methods implemented for free for target ISA!
|
/// Methods implemented for free for target ISA!
|
||||||
|
|||||||
@@ -2507,10 +2507,6 @@ impl MachInst for Inst {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reg_universe(flags: &settings::Flags) -> RealRegUniverse {
|
|
||||||
create_reg_universe(flags)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn worst_case_size() -> CodeOffset {
|
fn worst_case_size() -> CodeOffset {
|
||||||
// The maximum size, in bytes, of any `Inst`'s emitted code. We have at least one case of
|
// The maximum size, in bytes, of any `Inst`'s emitted code. We have at least one case of
|
||||||
// an 8-instruction sequence (saturating int-to-float conversions) with three embedded
|
// an 8-instruction sequence (saturating int-to-float conversions) with three embedded
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ use crate::ir::Function;
|
|||||||
use crate::isa::s390x::settings as s390x_settings;
|
use crate::isa::s390x::settings as s390x_settings;
|
||||||
#[cfg(feature = "unwind")]
|
#[cfg(feature = "unwind")]
|
||||||
use crate::isa::unwind::systemv::RegisterMappingError;
|
use crate::isa::unwind::systemv::RegisterMappingError;
|
||||||
use crate::isa::Builder as IsaBuilder;
|
use crate::isa::{Builder as IsaBuilder, TargetIsa};
|
||||||
use crate::machinst::{
|
use crate::machinst::{
|
||||||
compile, MachBackend, MachCompileResult, MachTextSectionBuilder, TargetIsaAdapter,
|
compile, MachCompileResult, MachTextSectionBuilder, TextSectionBuilder, VCode,
|
||||||
TextSectionBuilder, VCode,
|
|
||||||
};
|
};
|
||||||
use crate::result::CodegenResult;
|
use crate::result::CodegenResult;
|
||||||
use crate::settings as shared_settings;
|
use crate::settings as shared_settings;
|
||||||
|
|
||||||
use alloc::{boxed::Box, vec::Vec};
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
use regalloc::{PrettyPrint, RealRegUniverse, Reg};
|
use regalloc::{PrettyPrint, RealRegUniverse, Reg};
|
||||||
use target_lexicon::{Architecture, Triple};
|
use target_lexicon::{Architecture, Triple};
|
||||||
@@ -61,11 +61,11 @@ impl S390xBackend {
|
|||||||
) -> CodegenResult<VCode<inst::Inst>> {
|
) -> CodegenResult<VCode<inst::Inst>> {
|
||||||
let emit_info = EmitInfo::new(flags.clone(), self.isa_flags.clone());
|
let emit_info = EmitInfo::new(flags.clone(), self.isa_flags.clone());
|
||||||
let abi = Box::new(abi::S390xABICallee::new(func, flags)?);
|
let abi = Box::new(abi::S390xABICallee::new(func, flags)?);
|
||||||
compile::compile::<S390xBackend>(func, self, abi, emit_info)
|
compile::compile::<S390xBackend>(func, self, abi, &self.reg_universe, emit_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachBackend for S390xBackend {
|
impl TargetIsa for S390xBackend {
|
||||||
fn compile_function(
|
fn compile_function(
|
||||||
&self,
|
&self,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
@@ -113,10 +113,6 @@ impl MachBackend for S390xBackend {
|
|||||||
self.isa_flags.iter().collect()
|
self.isa_flags.iter().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reg_universe(&self) -> &RealRegUniverse {
|
|
||||||
&self.reg_universe
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unsigned_add_overflow_condition(&self) -> IntCC {
|
fn unsigned_add_overflow_condition(&self) -> IntCC {
|
||||||
// The ADD LOGICAL family of instructions set the condition code
|
// The ADD LOGICAL family of instructions set the condition code
|
||||||
// differently from normal comparisons, in a way that cannot be
|
// differently from normal comparisons, in a way that cannot be
|
||||||
@@ -155,7 +151,7 @@ impl MachBackend for S390xBackend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unwind")]
|
#[cfg(feature = "unwind")]
|
||||||
fn map_reg_to_dwarf(&self, reg: Reg) -> Result<u16, RegisterMappingError> {
|
fn map_regalloc_reg_to_dwarf(&self, reg: Reg) -> Result<u16, RegisterMappingError> {
|
||||||
inst::unwind::systemv::map_reg(reg).map(|reg| reg.0)
|
inst::unwind::systemv::map_reg(reg).map(|reg| reg.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,6 +160,16 @@ impl MachBackend for S390xBackend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for S390xBackend {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_struct("MachBackend")
|
||||||
|
.field("name", &self.name())
|
||||||
|
.field("triple", &self.triple())
|
||||||
|
.field("flags", &format!("{}", self.flags()))
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new `isa::Builder`.
|
/// Create a new `isa::Builder`.
|
||||||
pub fn isa_builder(triple: Triple) -> IsaBuilder {
|
pub fn isa_builder(triple: Triple) -> IsaBuilder {
|
||||||
assert!(triple.architecture == Architecture::S390x);
|
assert!(triple.architecture == Architecture::S390x);
|
||||||
@@ -173,7 +179,7 @@ pub fn isa_builder(triple: Triple) -> IsaBuilder {
|
|||||||
constructor: |triple, shared_flags, builder| {
|
constructor: |triple, shared_flags, builder| {
|
||||||
let isa_flags = s390x_settings::Flags::new(&shared_flags, builder);
|
let isa_flags = s390x_settings::Flags::new(&shared_flags, builder);
|
||||||
let backend = S390xBackend::new_with_flags(triple, shared_flags, isa_flags);
|
let backend = S390xBackend::new_with_flags(triple, shared_flags, isa_flags);
|
||||||
Box::new(TargetIsaAdapter::new(backend))
|
Box::new(backend)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::isa::x64::abi::X64ABIMachineSpec;
|
|||||||
use crate::isa::x64::settings as x64_settings;
|
use crate::isa::x64::settings as x64_settings;
|
||||||
use crate::isa::CallConv;
|
use crate::isa::CallConv;
|
||||||
use crate::machinst::*;
|
use crate::machinst::*;
|
||||||
use crate::{settings, settings::Flags, CodegenError, CodegenResult};
|
use crate::{settings, CodegenError, CodegenResult};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use regalloc::{
|
use regalloc::{
|
||||||
@@ -26,7 +26,7 @@ pub mod regs;
|
|||||||
pub mod unwind;
|
pub mod unwind;
|
||||||
|
|
||||||
use args::*;
|
use args::*;
|
||||||
use regs::{create_reg_universe_systemv, show_ireg_sized};
|
use regs::show_ireg_sized;
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Instructions (top level): definition
|
// Instructions (top level): definition
|
||||||
@@ -3226,10 +3226,6 @@ impl MachInst for Inst {
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reg_universe(flags: &Flags) -> RealRegUniverse {
|
|
||||||
create_reg_universe_systemv(flags)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn worst_case_size() -> CodeOffset {
|
fn worst_case_size() -> CodeOffset {
|
||||||
15
|
15
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ use crate::isa::unwind::systemv;
|
|||||||
use crate::isa::x64::{inst::regs::create_reg_universe_systemv, settings as x64_settings};
|
use crate::isa::x64::{inst::regs::create_reg_universe_systemv, settings as x64_settings};
|
||||||
use crate::isa::Builder as IsaBuilder;
|
use crate::isa::Builder as IsaBuilder;
|
||||||
use crate::machinst::{
|
use crate::machinst::{
|
||||||
compile, MachBackend, MachCompileResult, MachTextSectionBuilder, TargetIsaAdapter,
|
compile, MachCompileResult, MachTextSectionBuilder, TextSectionBuilder, VCode,
|
||||||
TextSectionBuilder, VCode,
|
|
||||||
};
|
};
|
||||||
use crate::result::CodegenResult;
|
use crate::result::CodegenResult;
|
||||||
use crate::settings::{self as shared_settings, Flags};
|
use crate::settings::{self as shared_settings, Flags};
|
||||||
use alloc::{boxed::Box, vec::Vec};
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
use regalloc::{PrettyPrint, RealRegUniverse, Reg};
|
use regalloc::{PrettyPrint, RealRegUniverse, Reg};
|
||||||
use target_lexicon::Triple;
|
use target_lexicon::Triple;
|
||||||
@@ -50,11 +50,11 @@ impl X64Backend {
|
|||||||
// block layout and finalizes branches. The result is ready for binary emission.
|
// block layout and finalizes branches. The result is ready for binary emission.
|
||||||
let emit_info = EmitInfo::new(flags.clone(), self.x64_flags.clone());
|
let emit_info = EmitInfo::new(flags.clone(), self.x64_flags.clone());
|
||||||
let abi = Box::new(abi::X64ABICallee::new(&func, flags)?);
|
let abi = Box::new(abi::X64ABICallee::new(&func, flags)?);
|
||||||
compile::compile::<Self>(&func, self, abi, emit_info)
|
compile::compile::<Self>(&func, self, abi, &self.reg_universe, emit_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachBackend for X64Backend {
|
impl TargetIsa for X64Backend {
|
||||||
fn compile_function(
|
fn compile_function(
|
||||||
&self,
|
&self,
|
||||||
func: &Function,
|
func: &Function,
|
||||||
@@ -102,10 +102,6 @@ impl MachBackend for X64Backend {
|
|||||||
&self.triple
|
&self.triple
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reg_universe(&self) -> &RealRegUniverse {
|
|
||||||
&self.reg_universe
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unsigned_add_overflow_condition(&self) -> IntCC {
|
fn unsigned_add_overflow_condition(&self) -> IntCC {
|
||||||
// Unsigned `<`; this corresponds to the carry flag set on x86, which
|
// Unsigned `<`; this corresponds to the carry flag set on x86, which
|
||||||
// indicates an add has overflowed.
|
// indicates an add has overflowed.
|
||||||
@@ -146,7 +142,7 @@ impl MachBackend for X64Backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "unwind")]
|
#[cfg(feature = "unwind")]
|
||||||
fn map_reg_to_dwarf(&self, reg: Reg) -> Result<u16, systemv::RegisterMappingError> {
|
fn map_regalloc_reg_to_dwarf(&self, reg: Reg) -> Result<u16, systemv::RegisterMappingError> {
|
||||||
inst::unwind::systemv::map_reg(reg).map(|reg| reg.0)
|
inst::unwind::systemv::map_reg(reg).map(|reg| reg.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +151,16 @@ impl MachBackend for X64Backend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for X64Backend {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
f.debug_struct("MachBackend")
|
||||||
|
.field("name", &self.name())
|
||||||
|
.field("triple", &self.triple())
|
||||||
|
.field("flags", &format!("{}", self.flags()))
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new `isa::Builder`.
|
/// Create a new `isa::Builder`.
|
||||||
pub(crate) fn isa_builder(triple: Triple) -> IsaBuilder {
|
pub(crate) fn isa_builder(triple: Triple) -> IsaBuilder {
|
||||||
IsaBuilder {
|
IsaBuilder {
|
||||||
@@ -171,5 +177,5 @@ fn isa_constructor(
|
|||||||
) -> Box<dyn TargetIsa> {
|
) -> Box<dyn TargetIsa> {
|
||||||
let isa_flags = x64_settings::Flags::new(&shared_flags, builder);
|
let isa_flags = x64_settings::Flags::new(&shared_flags, builder);
|
||||||
let backend = X64Backend::new_with_flags(triple, shared_flags, isa_flags);
|
let backend = X64Backend::new_with_flags(triple, shared_flags, isa_flags);
|
||||||
Box::new(TargetIsaAdapter::new(backend))
|
Box::new(backend)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
//! Adapter for a `MachBackend` to implement the `TargetIsa` trait.
|
|
||||||
|
|
||||||
use crate::ir;
|
|
||||||
use crate::isa::TargetIsa;
|
|
||||||
use crate::machinst::*;
|
|
||||||
use crate::settings::{self, Flags};
|
|
||||||
|
|
||||||
#[cfg(feature = "unwind")]
|
|
||||||
use crate::isa::unwind::systemv::RegisterMappingError;
|
|
||||||
|
|
||||||
use std::fmt;
|
|
||||||
use target_lexicon::Triple;
|
|
||||||
|
|
||||||
/// A wrapper around a `MachBackend` that provides a `TargetIsa` impl.
|
|
||||||
pub struct TargetIsaAdapter {
|
|
||||||
backend: Box<dyn MachBackend + Send + Sync + 'static>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TargetIsaAdapter {
|
|
||||||
/// Create a new `TargetIsa` wrapper around a `MachBackend`.
|
|
||||||
pub fn new<B: MachBackend + Send + Sync + 'static>(backend: B) -> TargetIsaAdapter {
|
|
||||||
TargetIsaAdapter {
|
|
||||||
backend: Box::new(backend),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for TargetIsaAdapter {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
f.debug_struct("MachBackend")
|
|
||||||
.field("name", &self.backend.name())
|
|
||||||
.field("triple", &self.backend.triple())
|
|
||||||
.field("flags", &format!("{}", self.backend.flags()))
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TargetIsa for TargetIsaAdapter {
|
|
||||||
fn name(&self) -> &'static str {
|
|
||||||
self.backend.name()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn triple(&self) -> &Triple {
|
|
||||||
self.backend.triple()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn flags(&self) -> &Flags {
|
|
||||||
self.backend.flags()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn isa_flags(&self) -> Vec<settings::Value> {
|
|
||||||
self.backend.isa_flags()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_mach_backend(&self) -> &dyn MachBackend {
|
|
||||||
&*self.backend
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC {
|
|
||||||
self.backend.unsigned_add_overflow_condition()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "unwind")]
|
|
||||||
fn create_systemv_cie(&self) -> Option<gimli::write::CommonInformationEntry> {
|
|
||||||
self.backend.create_systemv_cie()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "unwind")]
|
|
||||||
fn map_regalloc_reg_to_dwarf(&self, r: Reg) -> Result<u16, RegisterMappingError> {
|
|
||||||
self.backend.map_reg_to_dwarf(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
//! Compilation backend pipeline: optimized IR to VCode / binemit.
|
//! Compilation backend pipeline: optimized IR to VCode / binemit.
|
||||||
|
|
||||||
use crate::ir::Function;
|
use crate::ir::Function;
|
||||||
|
use crate::isa::TargetIsa;
|
||||||
use crate::log::DeferredDisplay;
|
use crate::log::DeferredDisplay;
|
||||||
use crate::machinst::*;
|
use crate::machinst::*;
|
||||||
use crate::settings;
|
use crate::settings;
|
||||||
@@ -10,10 +11,11 @@ use regalloc::{allocate_registers_with_opts, Algorithm, Options, PrettyPrint};
|
|||||||
|
|
||||||
/// Compile the given function down to VCode with allocated registers, ready
|
/// Compile the given function down to VCode with allocated registers, ready
|
||||||
/// for binary emission.
|
/// for binary emission.
|
||||||
pub fn compile<B: LowerBackend + MachBackend>(
|
pub fn compile<B: LowerBackend + TargetIsa>(
|
||||||
f: &Function,
|
f: &Function,
|
||||||
b: &B,
|
b: &B,
|
||||||
abi: Box<dyn ABICallee<I = B::MInst>>,
|
abi: Box<dyn ABICallee<I = B::MInst>>,
|
||||||
|
reg_universe: &RealRegUniverse,
|
||||||
emit_info: <B::MInst as MachInstEmit>::Info,
|
emit_info: <B::MInst as MachInstEmit>::Info,
|
||||||
) -> CodegenResult<VCode<B::MInst>>
|
) -> CodegenResult<VCode<B::MInst>>
|
||||||
where
|
where
|
||||||
@@ -33,7 +35,7 @@ where
|
|||||||
// rendering.
|
// rendering.
|
||||||
log::trace!(
|
log::trace!(
|
||||||
"vcode from lowering: \n{}",
|
"vcode from lowering: \n{}",
|
||||||
DeferredDisplay::new(|| vcode.show_rru(Some(b.reg_universe())))
|
DeferredDisplay::new(|| vcode.show_rru(Some(reg_universe)))
|
||||||
);
|
);
|
||||||
|
|
||||||
// Perform register allocation.
|
// Perform register allocation.
|
||||||
@@ -55,7 +57,7 @@ where
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
if let Some(path) = std::env::var("SERIALIZE_REGALLOC").ok() {
|
if let Some(path) = std::env::var("SERIALIZE_REGALLOC").ok() {
|
||||||
let snapshot = regalloc::IRSnapshot::from_function(&vcode, b.reg_universe());
|
let snapshot = regalloc::IRSnapshot::from_function(&vcode, reg_universe);
|
||||||
let serialized = bincode::serialize(&snapshot).expect("couldn't serialize snapshot");
|
let serialized = bincode::serialize(&snapshot).expect("couldn't serialize snapshot");
|
||||||
|
|
||||||
let file_path = Path::new(&path).join(Path::new(&format!("ir{}.bin", f.name)));
|
let file_path = Path::new(&path).join(Path::new(&format!("ir{}.bin", f.name)));
|
||||||
@@ -78,7 +80,7 @@ where
|
|||||||
let _tt = timing::regalloc();
|
let _tt = timing::regalloc();
|
||||||
allocate_registers_with_opts(
|
allocate_registers_with_opts(
|
||||||
&mut vcode,
|
&mut vcode,
|
||||||
b.reg_universe(),
|
reg_universe,
|
||||||
sri,
|
sri,
|
||||||
Options {
|
Options {
|
||||||
run_checker,
|
run_checker,
|
||||||
@@ -88,7 +90,7 @@ where
|
|||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
log::error!(
|
log::error!(
|
||||||
"Register allocation error for vcode\n{}\nError: {:?}",
|
"Register allocation error for vcode\n{}\nError: {:?}",
|
||||||
vcode.show_rru(Some(b.reg_universe())),
|
vcode.show_rru(Some(reg_universe)),
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
err
|
err
|
||||||
@@ -105,7 +107,7 @@ where
|
|||||||
|
|
||||||
log::trace!(
|
log::trace!(
|
||||||
"vcode after regalloc: final version:\n{}",
|
"vcode after regalloc: final version:\n{}",
|
||||||
DeferredDisplay::new(|| vcode.show_rru(Some(b.reg_universe())))
|
DeferredDisplay::new(|| vcode.show_rru(Some(reg_universe)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(vcode)
|
Ok(vcode)
|
||||||
|
|||||||
@@ -61,10 +61,9 @@
|
|||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use crate::binemit::{Addend, CodeInfo, CodeOffset, Reloc, StackMap};
|
use crate::binemit::{Addend, CodeInfo, CodeOffset, Reloc, StackMap};
|
||||||
use crate::ir::condcodes::IntCC;
|
use crate::ir::{SourceLoc, StackSlot, Type, ValueLabel};
|
||||||
use crate::ir::{Function, SourceLoc, StackSlot, Type, ValueLabel};
|
|
||||||
use crate::result::CodegenResult;
|
use crate::result::CodegenResult;
|
||||||
use crate::settings::{self, Flags};
|
use crate::settings::Flags;
|
||||||
use crate::value_label::ValueLabelsRanges;
|
use crate::value_label::ValueLabelsRanges;
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
@@ -76,10 +75,6 @@ use regalloc::{
|
|||||||
};
|
};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
use target_lexicon::Triple;
|
|
||||||
|
|
||||||
#[cfg(feature = "unwind")]
|
|
||||||
use crate::isa::unwind::systemv::RegisterMappingError;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod isle;
|
pub mod isle;
|
||||||
@@ -98,8 +93,6 @@ pub mod abi_impl;
|
|||||||
pub use abi_impl::*;
|
pub use abi_impl::*;
|
||||||
pub mod buffer;
|
pub mod buffer;
|
||||||
pub use buffer::*;
|
pub use buffer::*;
|
||||||
pub mod adapter;
|
|
||||||
pub use adapter::*;
|
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
pub use helpers::*;
|
pub use helpers::*;
|
||||||
pub mod inst_common;
|
pub mod inst_common;
|
||||||
@@ -181,9 +174,6 @@ pub trait MachInst: Clone + Debug {
|
|||||||
/// the instruction must have a nonzero size if preferred_size is nonzero.
|
/// the instruction must have a nonzero size if preferred_size is nonzero.
|
||||||
fn gen_nop(preferred_size: usize) -> Self;
|
fn gen_nop(preferred_size: usize) -> Self;
|
||||||
|
|
||||||
/// Get the register universe for this backend.
|
|
||||||
fn reg_universe(flags: &Flags) -> RealRegUniverse;
|
|
||||||
|
|
||||||
/// Align a basic block offset (from start of function). By default, no
|
/// Align a basic block offset (from start of function). By default, no
|
||||||
/// alignment occurs.
|
/// alignment occurs.
|
||||||
fn align_basic_block(offset: CodeOffset) -> CodeOffset {
|
fn align_basic_block(offset: CodeOffset) -> CodeOffset {
|
||||||
@@ -366,70 +356,6 @@ impl MachCompileResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Top-level machine backend trait, which wraps all monomorphized code and
|
|
||||||
/// allows a virtual call from the machine-independent `Function::compile()`.
|
|
||||||
pub trait MachBackend {
|
|
||||||
/// Compile the given function.
|
|
||||||
fn compile_function(
|
|
||||||
&self,
|
|
||||||
func: &Function,
|
|
||||||
want_disasm: bool,
|
|
||||||
) -> CodegenResult<MachCompileResult>;
|
|
||||||
|
|
||||||
/// Return flags for this backend.
|
|
||||||
fn flags(&self) -> &Flags;
|
|
||||||
|
|
||||||
/// Get the ISA-dependent flag values that were used to make this trait object.
|
|
||||||
fn isa_flags(&self) -> Vec<settings::Value>;
|
|
||||||
|
|
||||||
/// Return triple for this backend.
|
|
||||||
fn triple(&self) -> &Triple;
|
|
||||||
|
|
||||||
/// Return name for this backend.
|
|
||||||
fn name(&self) -> &'static str;
|
|
||||||
|
|
||||||
/// Return the register universe for this backend.
|
|
||||||
fn reg_universe(&self) -> &RealRegUniverse;
|
|
||||||
|
|
||||||
/// Machine-specific condcode info needed by TargetIsa.
|
|
||||||
/// Condition that will be true when an IaddIfcout overflows.
|
|
||||||
fn unsigned_add_overflow_condition(&self) -> IntCC;
|
|
||||||
|
|
||||||
/// Produces unwind info based on backend results.
|
|
||||||
#[cfg(feature = "unwind")]
|
|
||||||
fn emit_unwind_info(
|
|
||||||
&self,
|
|
||||||
_result: &MachCompileResult,
|
|
||||||
_kind: UnwindInfoKind,
|
|
||||||
) -> CodegenResult<Option<crate::isa::unwind::UnwindInfo>> {
|
|
||||||
// By default, an backend cannot produce unwind info.
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new System V Common Information Entry for the ISA.
|
|
||||||
#[cfg(feature = "unwind")]
|
|
||||||
fn create_systemv_cie(&self) -> Option<gimli::write::CommonInformationEntry> {
|
|
||||||
// By default, an ISA cannot create a System V CIE
|
|
||||||
None
|
|
||||||
}
|
|
||||||
/// Maps a regalloc::Reg to a DWARF register number.
|
|
||||||
#[cfg(feature = "unwind")]
|
|
||||||
fn map_reg_to_dwarf(&self, _: Reg) -> Result<u16, RegisterMappingError> {
|
|
||||||
Err(RegisterMappingError::UnsupportedArchitecture)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an object that can be used to build the text section of an
|
|
||||||
/// executable.
|
|
||||||
///
|
|
||||||
/// This object will internally attempt to handle as many relocations as
|
|
||||||
/// possible using relative calls/jumps/etc between functions.
|
|
||||||
///
|
|
||||||
/// The `num_labeled_funcs` argument here is the number of functions which
|
|
||||||
/// will be "labeled" or might have calls between them, typically the number
|
|
||||||
/// of defined functions in the object file.
|
|
||||||
fn text_section_builder(&self, num_labeled_funcs: u32) -> Box<dyn TextSectionBuilder>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An object that can be used to create the text section of an executable.
|
/// An object that can be used to create the text section of an executable.
|
||||||
///
|
///
|
||||||
/// This primarily handles resolving relative relocations at
|
/// This primarily handles resolving relative relocations at
|
||||||
|
|||||||
@@ -205,7 +205,6 @@ impl<'a> ObjectBuilder<'a> {
|
|||||||
systemv_unwind_info: Vec::new(),
|
systemv_unwind_info: Vec::new(),
|
||||||
relocations: Vec::new(),
|
relocations: Vec::new(),
|
||||||
text: isa
|
text: isa
|
||||||
.get_mach_backend()
|
|
||||||
.text_section_builder((module.functions.len() - module.num_imported_funcs) as u32),
|
.text_section_builder((module.functions.len() - module.num_imported_funcs) as u32),
|
||||||
added_unwind_info: false,
|
added_unwind_info: false,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user