Merge pull request #3639 from bjorn3/machinst_cleanups
Various cleanups around machinst
This commit is contained in:
@@ -55,12 +55,7 @@ impl<'a> MemoryCodeSink<'a> {
|
|||||||
Self {
|
Self {
|
||||||
data,
|
data,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
info: CodeInfo {
|
info: CodeInfo { total_size: 0 },
|
||||||
code_size: 0,
|
|
||||||
jumptables_size: 0,
|
|
||||||
rodata_size: 0,
|
|
||||||
total_size: 0,
|
|
||||||
},
|
|
||||||
relocs,
|
relocs,
|
||||||
traps,
|
traps,
|
||||||
}
|
}
|
||||||
@@ -140,16 +135,7 @@ impl<'a> CodeSink for MemoryCodeSink<'a> {
|
|||||||
self.traps.trap(ofs, srcloc, code);
|
self.traps.trap(ofs, srcloc, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn begin_jumptables(&mut self) {
|
|
||||||
self.info.code_size = self.offset();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn begin_rodata(&mut self) {
|
|
||||||
self.info.jumptables_size = self.offset() - self.info.code_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn end_codegen(&mut self) {
|
fn end_codegen(&mut self) {
|
||||||
self.info.rodata_size = self.offset() - (self.info.jumptables_size + self.info.code_size);
|
|
||||||
self.info.total_size = self.offset();
|
self.info.total_size = self.offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,31 +96,10 @@ impl fmt::Display for Reloc {
|
|||||||
/// precedes the boundary between the sections.
|
/// precedes the boundary between the sections.
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct CodeInfo {
|
pub struct CodeInfo {
|
||||||
/// Number of bytes of machine code (the code starts at offset 0).
|
|
||||||
pub code_size: CodeOffset,
|
|
||||||
|
|
||||||
/// Number of bytes of jumptables.
|
|
||||||
pub jumptables_size: CodeOffset,
|
|
||||||
|
|
||||||
/// Number of bytes of rodata.
|
|
||||||
pub rodata_size: CodeOffset,
|
|
||||||
|
|
||||||
/// Number of bytes in total.
|
/// Number of bytes in total.
|
||||||
pub total_size: CodeOffset,
|
pub total_size: CodeOffset,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CodeInfo {
|
|
||||||
/// Offset of any relocatable jump tables, or equal to rodata if there are no jump tables.
|
|
||||||
pub fn jumptables(&self) -> CodeOffset {
|
|
||||||
self.code_size
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Offset of any copyable read-only data, or equal to total_size if there are no rodata.
|
|
||||||
pub fn rodata(&self) -> CodeOffset {
|
|
||||||
self.code_size + self.jumptables_size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Abstract interface for adding bytes to the code segment.
|
/// Abstract interface for adding bytes to the code segment.
|
||||||
///
|
///
|
||||||
/// A `CodeSink` will receive all of the machine code for a function. It also accepts relocations
|
/// A `CodeSink` will receive all of the machine code for a function. It also accepts relocations
|
||||||
@@ -147,12 +126,6 @@ pub trait CodeSink {
|
|||||||
/// Add trap information for the current offset.
|
/// Add trap information for the current offset.
|
||||||
fn trap(&mut self, _: TrapCode, _: SourceLoc);
|
fn trap(&mut self, _: TrapCode, _: SourceLoc);
|
||||||
|
|
||||||
/// Machine code output is complete, jump table data may follow.
|
|
||||||
fn begin_jumptables(&mut self);
|
|
||||||
|
|
||||||
/// Jump table output is complete, raw read-only data may follow.
|
|
||||||
fn begin_rodata(&mut self);
|
|
||||||
|
|
||||||
/// Read-only data output is complete, we're done.
|
/// Read-only data output is complete, we're done.
|
||||||
fn end_codegen(&mut self);
|
fn end_codegen(&mut self);
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ impl Context {
|
|||||||
relocs: &mut dyn RelocSink,
|
relocs: &mut dyn RelocSink,
|
||||||
traps: &mut dyn TrapSink,
|
traps: &mut dyn TrapSink,
|
||||||
stack_maps: &mut dyn StackMapSink,
|
stack_maps: &mut dyn StackMapSink,
|
||||||
) -> CodegenResult<CodeInfo> {
|
) -> CodegenResult<()> {
|
||||||
let info = self.compile(isa)?;
|
let info = self.compile(isa)?;
|
||||||
let old_len = mem.len();
|
let old_len = mem.len();
|
||||||
mem.resize(old_len + info.total_size as usize, 0);
|
mem.resize(old_len + info.total_size as usize, 0);
|
||||||
@@ -122,7 +122,7 @@ impl Context {
|
|||||||
self.emit_to_memory(mem.as_mut_ptr().add(old_len), relocs, traps, stack_maps)
|
self.emit_to_memory(mem.as_mut_ptr().add(old_len), relocs, traps, stack_maps)
|
||||||
};
|
};
|
||||||
debug_assert!(new_info == info);
|
debug_assert!(new_info == info);
|
||||||
Ok(info)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compile the function.
|
/// Compile the function.
|
||||||
@@ -167,8 +167,7 @@ impl Context {
|
|||||||
|
|
||||||
self.remove_constant_phis(isa)?;
|
self.remove_constant_phis(isa)?;
|
||||||
|
|
||||||
// FIXME: make this non optional
|
let backend = isa.get_mach_backend();
|
||||||
let backend = isa.get_mach_backend().expect("only mach backends nowadays");
|
|
||||||
let result = backend.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);
|
||||||
@@ -243,12 +242,10 @@ impl Context {
|
|||||||
&self,
|
&self,
|
||||||
isa: &dyn TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
) -> CodegenResult<Option<crate::isa::unwind::UnwindInfo>> {
|
) -> CodegenResult<Option<crate::isa::unwind::UnwindInfo>> {
|
||||||
if let Some(backend) = isa.get_mach_backend() {
|
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();
|
||||||
return backend.emit_unwind_info(result, unwind_info_kind);
|
backend.emit_unwind_info(result, unwind_info_kind)
|
||||||
}
|
|
||||||
isa.create_unwind_info(&self.func)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run the verifier on the function.
|
/// Run the verifier on the function.
|
||||||
|
|||||||
@@ -669,12 +669,6 @@ impl EmitInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachInstEmitInfo for EmitInfo {
|
|
||||||
fn flags(&self) -> &settings::Flags {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MachInstEmit for Inst {
|
impl MachInstEmit for Inst {
|
||||||
type State = EmitState;
|
type State = EmitState;
|
||||||
type Info = EmitInfo;
|
type Info = EmitInfo;
|
||||||
@@ -2699,7 +2693,7 @@ impl MachInstEmit for Inst {
|
|||||||
inst.emit(sink, emit_info, state);
|
inst.emit(sink, emit_info, state);
|
||||||
let srcloc = state.cur_srcloc();
|
let srcloc = state.cur_srcloc();
|
||||||
sink.add_reloc(srcloc, Reloc::Abs8, name, offset);
|
sink.add_reloc(srcloc, Reloc::Abs8, name, offset);
|
||||||
if emit_info.flags().emit_all_ones_funcaddrs() {
|
if emit_info.0.emit_all_ones_funcaddrs() {
|
||||||
sink.put8(u64::max_value());
|
sink.put8(u64::max_value());
|
||||||
} else {
|
} else {
|
||||||
sink.put8(0);
|
sink.put8(0);
|
||||||
|
|||||||
@@ -98,8 +98,8 @@ impl MachBackend for AArch64Backend {
|
|||||||
"aarch64"
|
"aarch64"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn triple(&self) -> Triple {
|
fn triple(&self) -> &Triple {
|
||||||
self.triple.clone()
|
&self.triple
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flags(&self) -> &shared_settings::Flags {
|
fn flags(&self) -> &shared_settings::Flags {
|
||||||
|
|||||||
@@ -276,12 +276,6 @@ impl EmitInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachInstEmitInfo for EmitInfo {
|
|
||||||
fn flags(&self) -> &settings::Flags {
|
|
||||||
&self.flags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MachInstEmit for Inst {
|
impl MachInstEmit for Inst {
|
||||||
type Info = EmitInfo;
|
type Info = EmitInfo;
|
||||||
type State = EmitState;
|
type State = EmitState;
|
||||||
|
|||||||
@@ -88,8 +88,8 @@ impl MachBackend for Arm32Backend {
|
|||||||
"arm32"
|
"arm32"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn triple(&self) -> Triple {
|
fn triple(&self) -> &Triple {
|
||||||
self.triple.clone()
|
&self.triple
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flags(&self) -> &settings::Flags {
|
fn flags(&self) -> &settings::Flags {
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ use crate::ir;
|
|||||||
#[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::{MachBackend, UnwindInfoKind};
|
||||||
use crate::result::CodegenResult;
|
|
||||||
use crate::settings;
|
use crate::settings;
|
||||||
use crate::settings::SetResult;
|
use crate::settings::SetResult;
|
||||||
use alloc::{boxed::Box, vec::Vec};
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
@@ -237,18 +236,6 @@ 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 create_unwind_info(
|
|
||||||
&self,
|
|
||||||
_func: &ir::Function,
|
|
||||||
) -> CodegenResult<Option<unwind::UnwindInfo>> {
|
|
||||||
// By default, an ISA has no unwind information
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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.
|
||||||
@@ -258,10 +245,8 @@ pub trait TargetIsa: fmt::Display + Send + Sync {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the new-style MachBackend, if this is an adapter around one.
|
/// Get the new-style MachBackend.
|
||||||
fn get_mach_backend(&self) -> Option<&dyn MachBackend> {
|
fn get_mach_backend(&self) -> &dyn MachBackend;
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Methods implemented for free for target ISA!
|
/// Methods implemented for free for target ISA!
|
||||||
|
|||||||
@@ -916,12 +916,6 @@ impl EmitInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachInstEmitInfo for EmitInfo {
|
|
||||||
fn flags(&self) -> &settings::Flags {
|
|
||||||
&self.flags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MachInstEmit for Inst {
|
impl MachInstEmit for Inst {
|
||||||
type State = EmitState;
|
type State = EmitState;
|
||||||
type Info = EmitInfo;
|
type Info = EmitInfo;
|
||||||
@@ -1703,7 +1697,7 @@ impl MachInstEmit for Inst {
|
|||||||
let reg = writable_spilltmp_reg().to_reg();
|
let reg = writable_spilltmp_reg().to_reg();
|
||||||
put(sink, &enc_ri_b(opcode, reg, 12));
|
put(sink, &enc_ri_b(opcode, reg, 12));
|
||||||
sink.add_reloc(srcloc, Reloc::Abs8, name, offset);
|
sink.add_reloc(srcloc, Reloc::Abs8, name, offset);
|
||||||
if emit_info.flags().emit_all_ones_funcaddrs() {
|
if emit_info.flags.emit_all_ones_funcaddrs() {
|
||||||
sink.put8(u64::max_value());
|
sink.put8(u64::max_value());
|
||||||
} else {
|
} else {
|
||||||
sink.put8(0);
|
sink.put8(0);
|
||||||
|
|||||||
@@ -101,8 +101,8 @@ impl MachBackend for S390xBackend {
|
|||||||
"s390x"
|
"s390x"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn triple(&self) -> Triple {
|
fn triple(&self) -> &Triple {
|
||||||
self.triple.clone()
|
&self.triple
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flags(&self) -> &shared_settings::Flags {
|
fn flags(&self) -> &shared_settings::Flags {
|
||||||
|
|||||||
@@ -68,10 +68,6 @@ impl CodeSink for TestCodeSink {
|
|||||||
|
|
||||||
fn trap(&mut self, _code: TrapCode, _srcloc: SourceLoc) {}
|
fn trap(&mut self, _code: TrapCode, _srcloc: SourceLoc) {}
|
||||||
|
|
||||||
fn begin_jumptables(&mut self) {}
|
|
||||||
|
|
||||||
fn begin_rodata(&mut self) {}
|
|
||||||
|
|
||||||
fn end_codegen(&mut self) {}
|
fn end_codegen(&mut self) {}
|
||||||
|
|
||||||
fn add_call_site(&mut self, _opcode: Opcode, _srcloc: SourceLoc) {}
|
fn add_call_site(&mut self, _opcode: Opcode, _srcloc: SourceLoc) {}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use crate::{
|
|||||||
args::{Amode, OperandSize},
|
args::{Amode, OperandSize},
|
||||||
regs, EmitInfo, EmitState, Inst, LabelUse,
|
regs, EmitInfo, EmitState, Inst, LabelUse,
|
||||||
},
|
},
|
||||||
machinst::{MachBuffer, MachInstEmitInfo},
|
machinst::MachBuffer,
|
||||||
};
|
};
|
||||||
use regalloc::{Reg, RegClass};
|
use regalloc::{Reg, RegClass};
|
||||||
|
|
||||||
@@ -299,7 +299,7 @@ pub(crate) fn emit_std_enc_mem(
|
|||||||
Amode::ImmReg { simm32, base, .. } => {
|
Amode::ImmReg { simm32, base, .. } => {
|
||||||
// If this is an access based off of RSP, it may trap with a stack overflow if it's the
|
// If this is an access based off of RSP, it may trap with a stack overflow if it's the
|
||||||
// first touch of a new stack page.
|
// first touch of a new stack page.
|
||||||
if *base == regs::rsp() && !can_trap && info.flags().enable_probestack() {
|
if *base == regs::rsp() && !can_trap && info.flags.enable_probestack() {
|
||||||
sink.add_trap(srcloc, TrapCode::StackOverflow);
|
sink.add_trap(srcloc, TrapCode::StackOverflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,7 +365,7 @@ pub(crate) fn emit_std_enc_mem(
|
|||||||
} => {
|
} => {
|
||||||
// If this is an access based off of RSP, it may trap with a stack overflow if it's the
|
// If this is an access based off of RSP, it may trap with a stack overflow if it's the
|
||||||
// first touch of a new stack page.
|
// first touch of a new stack page.
|
||||||
if *reg_base == regs::rsp() && !can_trap && info.flags().enable_probestack() {
|
if *reg_base == regs::rsp() && !can_trap && info.flags.enable_probestack() {
|
||||||
sink.add_trap(srcloc, TrapCode::StackOverflow);
|
sink.add_trap(srcloc, TrapCode::StackOverflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1088,7 +1088,7 @@ pub(crate) fn emit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Inst::Push64 { src } => {
|
Inst::Push64 { src } => {
|
||||||
if info.flags().enable_probestack() {
|
if info.flags.enable_probestack() {
|
||||||
sink.add_trap(state.cur_srcloc(), TrapCode::StackOverflow);
|
sink.add_trap(state.cur_srcloc(), TrapCode::StackOverflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1139,7 +1139,7 @@ pub(crate) fn emit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Inst::CallKnown { dest, opcode, .. } => {
|
Inst::CallKnown { dest, opcode, .. } => {
|
||||||
if info.flags().enable_probestack() {
|
if info.flags.enable_probestack() {
|
||||||
sink.add_trap(state.cur_srcloc(), TrapCode::StackOverflow);
|
sink.add_trap(state.cur_srcloc(), TrapCode::StackOverflow);
|
||||||
}
|
}
|
||||||
if let Some(s) = state.take_stack_map() {
|
if let Some(s) = state.take_stack_map() {
|
||||||
@@ -1157,7 +1157,7 @@ pub(crate) fn emit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Inst::CallUnknown { dest, opcode, .. } => {
|
Inst::CallUnknown { dest, opcode, .. } => {
|
||||||
if info.flags().enable_probestack() {
|
if info.flags.enable_probestack() {
|
||||||
sink.add_trap(state.cur_srcloc(), TrapCode::StackOverflow);
|
sink.add_trap(state.cur_srcloc(), TrapCode::StackOverflow);
|
||||||
}
|
}
|
||||||
let start_offset = sink.cur_offset();
|
let start_offset = sink.cur_offset();
|
||||||
@@ -2412,7 +2412,7 @@ pub(crate) fn emit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Inst::LoadExtName { dst, name, offset } => {
|
Inst::LoadExtName { dst, name, offset } => {
|
||||||
if info.flags().is_pic() {
|
if info.flags.is_pic() {
|
||||||
// Generates: movq symbol@GOTPCREL(%rip), %dst
|
// Generates: movq symbol@GOTPCREL(%rip), %dst
|
||||||
let enc_dst = int_reg_enc(dst.to_reg());
|
let enc_dst = int_reg_enc(dst.to_reg());
|
||||||
sink.put1(0x48 | ((enc_dst >> 3) & 1) << 2);
|
sink.put1(0x48 | ((enc_dst >> 3) & 1) << 2);
|
||||||
@@ -2442,7 +2442,7 @@ pub(crate) fn emit(
|
|||||||
sink.put1(0x48 | ((enc_dst >> 3) & 1));
|
sink.put1(0x48 | ((enc_dst >> 3) & 1));
|
||||||
sink.put1(0xB8 | (enc_dst & 7));
|
sink.put1(0xB8 | (enc_dst & 7));
|
||||||
emit_reloc(sink, state, Reloc::Abs8, name, *offset);
|
emit_reloc(sink, state, Reloc::Abs8, name, *offset);
|
||||||
if info.flags().emit_all_ones_funcaddrs() {
|
if info.flags.emit_all_ones_funcaddrs() {
|
||||||
sink.put8(u64::max_value());
|
sink.put8(u64::max_value());
|
||||||
} else {
|
} else {
|
||||||
sink.put8(0);
|
sink.put8(0);
|
||||||
|
|||||||
@@ -3298,7 +3298,7 @@ pub struct EmitState {
|
|||||||
|
|
||||||
/// Constant state used during emissions of a sequence of instructions.
|
/// Constant state used during emissions of a sequence of instructions.
|
||||||
pub struct EmitInfo {
|
pub struct EmitInfo {
|
||||||
flags: settings::Flags,
|
pub(super) flags: settings::Flags,
|
||||||
isa_flags: x64_settings::Flags,
|
isa_flags: x64_settings::Flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3308,12 +3308,6 @@ impl EmitInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachInstEmitInfo for EmitInfo {
|
|
||||||
fn flags(&self) -> &Flags {
|
|
||||||
&self.flags
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MachInstEmit for Inst {
|
impl MachInstEmit for Inst {
|
||||||
type State = EmitState;
|
type State = EmitState;
|
||||||
type Info = EmitInfo;
|
type Info = EmitInfo;
|
||||||
|
|||||||
@@ -98,8 +98,8 @@ impl MachBackend for X64Backend {
|
|||||||
"x64"
|
"x64"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn triple(&self) -> Triple {
|
fn triple(&self) -> &Triple {
|
||||||
self.triple.clone()
|
&self.triple
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reg_universe(&self) -> &RealRegUniverse {
|
fn reg_universe(&self) -> &RealRegUniverse {
|
||||||
|
|||||||
@@ -14,16 +14,13 @@ use target_lexicon::Triple;
|
|||||||
/// A wrapper around a `MachBackend` that provides a `TargetIsa` impl.
|
/// A wrapper around a `MachBackend` that provides a `TargetIsa` impl.
|
||||||
pub struct TargetIsaAdapter {
|
pub struct TargetIsaAdapter {
|
||||||
backend: Box<dyn MachBackend + Send + Sync + 'static>,
|
backend: Box<dyn MachBackend + Send + Sync + 'static>,
|
||||||
triple: Triple,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TargetIsaAdapter {
|
impl TargetIsaAdapter {
|
||||||
/// Create a new `TargetIsa` wrapper around a `MachBackend`.
|
/// Create a new `TargetIsa` wrapper around a `MachBackend`.
|
||||||
pub fn new<B: MachBackend + Send + Sync + 'static>(backend: B) -> TargetIsaAdapter {
|
pub fn new<B: MachBackend + Send + Sync + 'static>(backend: B) -> TargetIsaAdapter {
|
||||||
let triple = backend.triple();
|
|
||||||
TargetIsaAdapter {
|
TargetIsaAdapter {
|
||||||
backend: Box::new(backend),
|
backend: Box::new(backend),
|
||||||
triple,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,7 +41,7 @@ impl TargetIsa for TargetIsaAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn triple(&self) -> &Triple {
|
fn triple(&self) -> &Triple {
|
||||||
&self.triple
|
self.backend.triple()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flags(&self) -> &Flags {
|
fn flags(&self) -> &Flags {
|
||||||
@@ -55,8 +52,8 @@ impl TargetIsa for TargetIsaAdapter {
|
|||||||
self.backend.isa_flags()
|
self.backend.isa_flags()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_mach_backend(&self) -> Option<&dyn MachBackend> {
|
fn get_mach_backend(&self) -> &dyn MachBackend {
|
||||||
Some(&*self.backend)
|
&*self.backend
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC {
|
fn unsigned_add_overflow_condition(&self) -> ir::condcodes::IntCC {
|
||||||
|
|||||||
@@ -1460,8 +1460,6 @@ impl MachBufferFinalized {
|
|||||||
sink.put1(*byte);
|
sink.put1(*byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
sink.begin_jumptables();
|
|
||||||
sink.begin_rodata();
|
|
||||||
sink.end_codegen();
|
sink.end_codegen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2091,8 +2089,6 @@ mod test {
|
|||||||
fn trap(&mut self, t: TrapCode, _: SourceLoc) {
|
fn trap(&mut self, t: TrapCode, _: SourceLoc) {
|
||||||
self.traps.push((self.offset, t));
|
self.traps.push((self.offset, t));
|
||||||
}
|
}
|
||||||
fn begin_jumptables(&mut self) {}
|
|
||||||
fn begin_rodata(&mut self) {}
|
|
||||||
fn end_codegen(&mut self) {}
|
fn end_codegen(&mut self) {}
|
||||||
fn add_call_site(&mut self, op: Opcode, _: SourceLoc) {
|
fn add_call_site(&mut self, op: Opcode, _: SourceLoc) {
|
||||||
self.callsites.push((self.offset, op));
|
self.callsites.push((self.offset, op));
|
||||||
|
|||||||
@@ -310,20 +310,13 @@ pub trait MachInstEmit: MachInst {
|
|||||||
/// Persistent state carried across `emit` invocations.
|
/// Persistent state carried across `emit` invocations.
|
||||||
type State: MachInstEmitState<Self>;
|
type State: MachInstEmitState<Self>;
|
||||||
/// Constant information used in `emit` invocations.
|
/// Constant information used in `emit` invocations.
|
||||||
type Info: MachInstEmitInfo;
|
type Info;
|
||||||
/// Emit the instruction.
|
/// Emit the instruction.
|
||||||
fn emit(&self, code: &mut MachBuffer<Self>, info: &Self::Info, state: &mut Self::State);
|
fn emit(&self, code: &mut MachBuffer<Self>, info: &Self::Info, state: &mut Self::State);
|
||||||
/// Pretty-print the instruction.
|
/// Pretty-print the instruction.
|
||||||
fn pretty_print(&self, mb_rru: Option<&RealRegUniverse>, state: &mut Self::State) -> String;
|
fn pretty_print(&self, mb_rru: Option<&RealRegUniverse>, state: &mut Self::State) -> String;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constant information used to emit an instruction.
|
|
||||||
pub trait MachInstEmitInfo {
|
|
||||||
/// Return the target-independent settings used for the compilation of this
|
|
||||||
/// particular function.
|
|
||||||
fn flags(&self) -> &Flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A trait describing the emission state carried between MachInsts when
|
/// A trait describing the emission state carried between MachInsts when
|
||||||
/// emitting a function body.
|
/// emitting a function body.
|
||||||
pub trait MachInstEmitState<I: MachInst>: Default + Clone + Debug {
|
pub trait MachInstEmitState<I: MachInst>: Default + Clone + Debug {
|
||||||
@@ -367,12 +360,8 @@ pub struct MachCompileResult {
|
|||||||
impl MachCompileResult {
|
impl MachCompileResult {
|
||||||
/// Get a `CodeInfo` describing section sizes from this compilation result.
|
/// Get a `CodeInfo` describing section sizes from this compilation result.
|
||||||
pub fn code_info(&self) -> CodeInfo {
|
pub fn code_info(&self) -> CodeInfo {
|
||||||
let code_size = self.buffer.total_size();
|
|
||||||
CodeInfo {
|
CodeInfo {
|
||||||
code_size,
|
total_size: self.buffer.total_size(),
|
||||||
jumptables_size: 0,
|
|
||||||
rodata_size: 0,
|
|
||||||
total_size: code_size,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -394,7 +383,7 @@ pub trait MachBackend {
|
|||||||
fn isa_flags(&self) -> Vec<settings::Value>;
|
fn isa_flags(&self) -> Vec<settings::Value>;
|
||||||
|
|
||||||
/// Return triple for this backend.
|
/// Return triple for this backend.
|
||||||
fn triple(&self) -> Triple;
|
fn triple(&self) -> &Triple;
|
||||||
|
|
||||||
/// Return name for this backend.
|
/// Return name for this backend.
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
|
|||||||
@@ -93,7 +93,5 @@ impl binemit::CodeSink for SizeSink {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
fn trap(&mut self, _code: ir::TrapCode, _srcloc: ir::SourceLoc) {}
|
fn trap(&mut self, _code: ir::TrapCode, _srcloc: ir::SourceLoc) {}
|
||||||
fn begin_jumptables(&mut self) {}
|
|
||||||
fn begin_rodata(&mut self) {}
|
|
||||||
fn end_codegen(&mut self) {}
|
fn end_codegen(&mut self) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -652,11 +652,6 @@ impl Module for JITModule {
|
|||||||
stack_map_sink: &mut dyn StackMapSink,
|
stack_map_sink: &mut dyn StackMapSink,
|
||||||
) -> ModuleResult<ModuleCompiledFunction> {
|
) -> ModuleResult<ModuleCompiledFunction> {
|
||||||
info!("defining function {}: {}", id, ctx.func.display());
|
info!("defining function {}: {}", id, ctx.func.display());
|
||||||
let CodeInfo {
|
|
||||||
total_size: code_size,
|
|
||||||
..
|
|
||||||
} = ctx.compile(self.isa())?;
|
|
||||||
|
|
||||||
let decl = self.declarations.get_function_decl(id);
|
let decl = self.declarations.get_function_decl(id);
|
||||||
if !decl.linkage.is_definable() {
|
if !decl.linkage.is_definable() {
|
||||||
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
|
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
|
||||||
@@ -666,6 +661,11 @@ impl Module for JITModule {
|
|||||||
return Err(ModuleError::DuplicateDefinition(decl.name.to_owned()));
|
return Err(ModuleError::DuplicateDefinition(decl.name.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let CodeInfo {
|
||||||
|
total_size: code_size,
|
||||||
|
..
|
||||||
|
} = ctx.compile(self.isa())?;
|
||||||
|
|
||||||
let size = code_size as usize;
|
let size = code_size as usize;
|
||||||
let ptr = self
|
let ptr = self
|
||||||
.memory
|
.memory
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use cranelift_codegen::entity::SecondaryMap;
|
|||||||
use cranelift_codegen::isa::TargetIsa;
|
use cranelift_codegen::isa::TargetIsa;
|
||||||
use cranelift_codegen::{self, ir};
|
use cranelift_codegen::{self, ir};
|
||||||
use cranelift_codegen::{
|
use cranelift_codegen::{
|
||||||
binemit::{Addend, CodeInfo, CodeOffset, Reloc, RelocSink, StackMapSink, TrapSink},
|
binemit::{Addend, CodeOffset, Reloc, RelocSink, StackMapSink, TrapSink},
|
||||||
CodegenError,
|
CodegenError,
|
||||||
};
|
};
|
||||||
use cranelift_module::{
|
use cranelift_module::{
|
||||||
@@ -311,21 +311,16 @@ impl Module for ObjectModule {
|
|||||||
stack_map_sink: &mut dyn StackMapSink,
|
stack_map_sink: &mut dyn StackMapSink,
|
||||||
) -> ModuleResult<ModuleCompiledFunction> {
|
) -> ModuleResult<ModuleCompiledFunction> {
|
||||||
info!("defining function {}: {}", func_id, ctx.func.display());
|
info!("defining function {}: {}", func_id, ctx.func.display());
|
||||||
let CodeInfo {
|
let mut code: Vec<u8> = Vec::new();
|
||||||
total_size: code_size,
|
|
||||||
..
|
|
||||||
} = ctx.compile(self.isa())?;
|
|
||||||
let mut code: Vec<u8> = vec![0; code_size as usize];
|
|
||||||
let mut reloc_sink = ObjectRelocSink::default();
|
let mut reloc_sink = ObjectRelocSink::default();
|
||||||
|
|
||||||
unsafe {
|
ctx.compile_and_emit(
|
||||||
ctx.emit_to_memory(
|
self.isa(),
|
||||||
code.as_mut_ptr(),
|
&mut code,
|
||||||
&mut reloc_sink,
|
&mut reloc_sink,
|
||||||
trap_sink,
|
trap_sink,
|
||||||
stack_map_sink,
|
stack_map_sink,
|
||||||
)
|
)?;
|
||||||
};
|
|
||||||
|
|
||||||
self.define_function_bytes(func_id, &code, &reloc_sink.relocs)
|
self.define_function_bytes(func_id, &code, &reloc_sink.relocs)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,9 +78,10 @@ fn handle_module(options: &Options, path: &Path, name: &str, fisa: FlagsOrIsa) -
|
|||||||
let mut mem = vec![];
|
let mut mem = vec![];
|
||||||
|
|
||||||
// Compile and encode the result to machine code.
|
// Compile and encode the result to machine code.
|
||||||
let code_info = context
|
context
|
||||||
.compile_and_emit(isa, &mut mem, &mut relocs, &mut traps, &mut stack_maps)
|
.compile_and_emit(isa, &mut mem, &mut relocs, &mut traps, &mut stack_maps)
|
||||||
.map_err(|err| anyhow::anyhow!("{}", pretty_error(&context.func, err)))?;
|
.map_err(|err| anyhow::anyhow!("{}", pretty_error(&context.func, err)))?;
|
||||||
|
let code_info = context.mach_compile_result.as_ref().unwrap().code_info();
|
||||||
|
|
||||||
if options.print {
|
if options.print {
|
||||||
println!("{}", context.func.display());
|
println!("{}", context.func.display());
|
||||||
@@ -90,8 +91,7 @@ fn handle_module(options: &Options, path: &Path, name: &str, fisa: FlagsOrIsa) -
|
|||||||
print_all(
|
print_all(
|
||||||
isa,
|
isa,
|
||||||
&mem,
|
&mem,
|
||||||
code_info.code_size,
|
code_info.total_size,
|
||||||
code_info.jumptables_size + code_info.rodata_size,
|
|
||||||
&relocs,
|
&relocs,
|
||||||
&traps,
|
&traps,
|
||||||
&stack_maps,
|
&stack_maps,
|
||||||
|
|||||||
@@ -193,14 +193,12 @@ pub fn print_all(
|
|||||||
isa: &dyn TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
mem: &[u8],
|
mem: &[u8],
|
||||||
code_size: u32,
|
code_size: u32,
|
||||||
rodata_size: u32,
|
|
||||||
relocs: &PrintRelocs,
|
relocs: &PrintRelocs,
|
||||||
traps: &PrintTraps,
|
traps: &PrintTraps,
|
||||||
stack_maps: &PrintStackMaps,
|
stack_maps: &PrintStackMaps,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
print_bytes(&mem);
|
print_bytes(&mem);
|
||||||
print_disassembly(isa, &mem[0..code_size as usize])?;
|
print_disassembly(isa, &mem[0..code_size as usize])?;
|
||||||
print_readonly_data(&mem[code_size as usize..(code_size + rodata_size) as usize]);
|
|
||||||
println!("\n{}\n{}\n{}", &relocs.text, &traps.text, &stack_maps.text);
|
println!("\n{}\n{}\n{}", &relocs.text, &traps.text, &stack_maps.text);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -218,25 +216,3 @@ pub fn print_bytes(mem: &[u8]) {
|
|||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_readonly_data(mem: &[u8]) {
|
|
||||||
if mem.is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("\nFollowed by {} bytes of read-only data:", mem.len());
|
|
||||||
|
|
||||||
for (i, byte) in mem.iter().enumerate() {
|
|
||||||
if i % 16 == 0 {
|
|
||||||
if i != 0 {
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
print!("{:4}: ", i);
|
|
||||||
}
|
|
||||||
if i % 4 == 0 {
|
|
||||||
print!(" ");
|
|
||||||
}
|
|
||||||
print!("{:02x} ", byte);
|
|
||||||
}
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ fn handle_module(options: &Options, path: &Path, name: &str, fisa: FlagsOrIsa) -
|
|||||||
for (def_index, func) in dummy_environ.info.function_bodies.iter() {
|
for (def_index, func) in dummy_environ.info.function_bodies.iter() {
|
||||||
context.func = func.clone();
|
context.func = func.clone();
|
||||||
|
|
||||||
let mut saved_sizes = None;
|
let mut saved_size = None;
|
||||||
let func_index = num_func_imports + def_index.index();
|
let func_index = num_func_imports + def_index.index();
|
||||||
let mut mem = vec![];
|
let mut mem = vec![];
|
||||||
let mut relocs = PrintRelocs::new(options.print);
|
let mut relocs = PrintRelocs::new(options.print);
|
||||||
@@ -266,9 +266,10 @@ fn handle_module(options: &Options, path: &Path, name: &str, fisa: FlagsOrIsa) -
|
|||||||
anyhow::bail!("{}", pretty_verifier_error(&context.func, None, errors));
|
anyhow::bail!("{}", pretty_verifier_error(&context.func, None, errors));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let code_info = context
|
context
|
||||||
.compile_and_emit(isa, &mut mem, &mut relocs, &mut traps, &mut stack_maps)
|
.compile_and_emit(isa, &mut mem, &mut relocs, &mut traps, &mut stack_maps)
|
||||||
.map_err(|err| anyhow::anyhow!("{}", pretty_error(&context.func, err)))?;
|
.map_err(|err| anyhow::anyhow!("{}", pretty_error(&context.func, err)))?;
|
||||||
|
let code_info = context.mach_compile_result.as_ref().unwrap().code_info();
|
||||||
|
|
||||||
if options.print_size {
|
if options.print_size {
|
||||||
println!(
|
println!(
|
||||||
@@ -284,10 +285,7 @@ fn handle_module(options: &Options, path: &Path, name: &str, fisa: FlagsOrIsa) -
|
|||||||
}
|
}
|
||||||
|
|
||||||
if options.disasm {
|
if options.disasm {
|
||||||
saved_sizes = Some((
|
saved_size = Some(code_info.total_size);
|
||||||
code_info.code_size,
|
|
||||||
code_info.jumptables_size + code_info.rodata_size,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,16 +322,8 @@ fn handle_module(options: &Options, path: &Path, name: &str, fisa: FlagsOrIsa) -
|
|||||||
vprintln!(options.verbose, "");
|
vprintln!(options.verbose, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((code_size, rodata_size)) = saved_sizes {
|
if let Some(total_size) = saved_size {
|
||||||
print_all(
|
print_all(isa, &mem, total_size, &relocs, &traps, &stack_maps)?;
|
||||||
isa,
|
|
||||||
&mem,
|
|
||||||
code_size,
|
|
||||||
rodata_size,
|
|
||||||
&relocs,
|
|
||||||
&traps,
|
|
||||||
&stack_maps,
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context.clear();
|
context.clear();
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
use crate::debug::{DwarfSection, DwarfSectionRelocTarget};
|
use crate::debug::{DwarfSection, DwarfSectionRelocTarget};
|
||||||
use crate::{CompiledFunction, Relocation, RelocationTarget};
|
use crate::{CompiledFunction, Relocation, RelocationTarget};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cranelift_codegen::binemit::{Addend, Reloc};
|
use cranelift_codegen::binemit::Reloc;
|
||||||
use cranelift_codegen::ir::LibCall;
|
use cranelift_codegen::ir::LibCall;
|
||||||
use cranelift_codegen::isa::{
|
use cranelift_codegen::isa::{
|
||||||
unwind::{systemv, UnwindInfo},
|
unwind::{systemv, UnwindInfo},
|
||||||
@@ -204,12 +204,9 @@ impl<'a> ObjectBuilder<'a> {
|
|||||||
systemv_unwind_info_id: None,
|
systemv_unwind_info_id: None,
|
||||||
systemv_unwind_info: Vec::new(),
|
systemv_unwind_info: Vec::new(),
|
||||||
relocations: Vec::new(),
|
relocations: Vec::new(),
|
||||||
text: match isa.get_mach_backend() {
|
text: isa
|
||||||
Some(backend) => backend.text_section_builder(
|
.get_mach_backend()
|
||||||
(module.functions.len() - module.num_imported_funcs) as u32,
|
.text_section_builder((module.functions.len() - module.num_imported_funcs) as u32),
|
||||||
),
|
|
||||||
None => Box::new(DummyBuilder::default()),
|
|
||||||
},
|
|
||||||
added_unwind_info: false,
|
added_unwind_info: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -627,37 +624,3 @@ impl<'a> ObjectBuilder<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct DummyBuilder {
|
|
||||||
data: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TextSectionBuilder for DummyBuilder {
|
|
||||||
fn append(&mut self, _named: bool, func: &[u8], align: u32) -> u64 {
|
|
||||||
while self.data.len() % align as usize != 0 {
|
|
||||||
self.data.push(0);
|
|
||||||
}
|
|
||||||
let pos = self.data.len() as u64;
|
|
||||||
self.data.extend_from_slice(func);
|
|
||||||
pos
|
|
||||||
}
|
|
||||||
|
|
||||||
fn resolve_reloc(
|
|
||||||
&mut self,
|
|
||||||
_offset: u64,
|
|
||||||
_reloc: Reloc,
|
|
||||||
_addend: Addend,
|
|
||||||
_target: u32,
|
|
||||||
) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn force_veneers(&mut self) {
|
|
||||||
// not implemented
|
|
||||||
}
|
|
||||||
|
|
||||||
fn finish(&mut self) -> Vec<u8> {
|
|
||||||
mem::take(&mut self.data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user