Add a Context::emit_to_memory function.

This function will emit the binary machine code into contiguous raw
memory while sending relocations to a RelocSink.

Add a MemoryCodeSink for generating machine code directly into memory
efficiently. Allow the TargetIsa to provide emit_function
implementations that are specialized to the MemoryCodeSink type to avoid
needless small virtual callbacks to put1() et etc.
This commit is contained in:
Jakob Stoklund Olesen
2017-07-17 18:13:05 -07:00
parent 9dc92eb8b3
commit 2f7057b96f
9 changed files with 168 additions and 13 deletions

View File

@@ -6,7 +6,7 @@ mod binemit;
mod enc_tables;
mod registers;
use binemit::CodeSink;
use binemit::{CodeSink, MemoryCodeSink, emit_function};
use super::super::settings as shared_settings;
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, Encodings};
use isa::Builder as IsaBuilder;
@@ -95,6 +95,10 @@ impl TargetIsa for Isa {
binemit::emit_inst(func, inst, sink)
}
fn emit_function(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
emit_function(func, binemit::emit_inst, sink)
}
fn reloc_names(&self) -> &'static [&'static str] {
&binemit::RELOC_NAMES
}

View File

@@ -6,7 +6,7 @@ mod binemit;
mod enc_tables;
mod registers;
use binemit::CodeSink;
use binemit::{CodeSink, MemoryCodeSink, emit_function};
use super::super::settings as shared_settings;
use isa::enc_tables::{lookup_enclist, Encodings};
use isa::Builder as IsaBuilder;
@@ -88,6 +88,10 @@ impl TargetIsa for Isa {
binemit::emit_inst(func, inst, sink)
}
fn emit_function(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
emit_function(func, binemit::emit_inst, sink)
}
fn reloc_names(&self) -> &'static [&'static str] {
&binemit::RELOC_NAMES
}

View File

@@ -6,7 +6,7 @@ mod binemit;
mod enc_tables;
mod registers;
use binemit::CodeSink;
use binemit::{CodeSink, MemoryCodeSink, emit_function};
use super::super::settings as shared_settings;
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, Encodings};
use isa::Builder as IsaBuilder;
@@ -95,6 +95,10 @@ impl TargetIsa for Isa {
binemit::emit_inst(func, inst, sink)
}
fn emit_function(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
emit_function(func, binemit::emit_inst, sink)
}
fn reloc_names(&self) -> &'static [&'static str] {
&binemit::RELOC_NAMES
}

View File

@@ -44,7 +44,7 @@ pub use isa::constraints::{RecipeConstraints, OperandConstraint, ConstraintKind,
pub use isa::encoding::{Encoding, EncInfo};
pub use isa::registers::{RegInfo, RegUnit, RegClass, RegClassIndex, regs_overlap};
use binemit::CodeSink;
use binemit;
use settings;
use ir;
use regalloc;
@@ -215,7 +215,12 @@ pub trait TargetIsa {
///
/// Note that this will call `put*` methods on the trait object via its vtable which is not the
/// fastest way of emitting code.
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut CodeSink);
fn emit_inst(&self, func: &ir::Function, inst: ir::Inst, sink: &mut binemit::CodeSink);
/// Emit a whole function into memory.
///
/// This is more performant than calling `emit_inst` for each instruction.
fn emit_function(&self, func: &ir::Function, sink: &mut binemit::MemoryCodeSink);
/// Get a static array of names associated with relocations in this ISA.
///

View File

@@ -7,7 +7,7 @@ mod enc_tables;
mod registers;
use super::super::settings as shared_settings;
use binemit::CodeSink;
use binemit::{CodeSink, MemoryCodeSink, emit_function};
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, Encodings};
use isa::Builder as IsaBuilder;
use isa::{TargetIsa, RegInfo, RegClass, EncInfo, Legalize};
@@ -95,6 +95,10 @@ impl TargetIsa for Isa {
binemit::emit_inst(func, inst, sink)
}
fn emit_function(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
emit_function(func, binemit::emit_inst, sink)
}
fn reloc_names(&self) -> &'static [&'static str] {
&binemit::RELOC_NAMES
}