Add a CodeOffset type and CodeSink::offset() method.
We need to keep track of code offsets in order to compute accurate branch displacements.
This commit is contained in:
@@ -5,6 +5,12 @@
|
||||
|
||||
use ir::{Ebb, FuncRef, JumpTable, Function, Inst};
|
||||
|
||||
/// Offset in bytes from the beginning of the function.
|
||||
///
|
||||
/// Cretonne can be used as a cross compiler, so we don't want to use a type like `usize` which
|
||||
/// depends on the *host* platform, not the *target* platform.
|
||||
pub type CodeOffset = u32;
|
||||
|
||||
/// Relocation kinds depend on the current ISA.
|
||||
pub struct Reloc(pub u16);
|
||||
|
||||
@@ -13,6 +19,9 @@ pub struct Reloc(pub u16);
|
||||
/// A `CodeSink` will receive all of the machine code for a function. It also accepts relocations
|
||||
/// which are locations in the code section that need to be fixed up when linking.
|
||||
pub trait CodeSink {
|
||||
/// Get the current position.
|
||||
fn offset(&self) -> CodeOffset;
|
||||
|
||||
/// Add 1 byte to the code section.
|
||||
fn put1(&mut self, u8);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ use std::fmt::Write;
|
||||
use cretonne::binemit;
|
||||
use cretonne::ir;
|
||||
use cretonne::ir::entities::AnyEntity;
|
||||
use cretonne::isa::TargetIsa;
|
||||
use cton_reader::TestCommand;
|
||||
use filetest::subtest::{SubTest, Context, Result};
|
||||
use utils::match_directive;
|
||||
@@ -26,24 +27,46 @@ pub fn subtest(parsed: &TestCommand) -> Result<Box<SubTest>> {
|
||||
// Code sink that generates text.
|
||||
struct TextSink {
|
||||
rnames: &'static [&'static str],
|
||||
offset: binemit::CodeOffset,
|
||||
text: String,
|
||||
}
|
||||
|
||||
impl TextSink {
|
||||
/// Create a new empty TextSink.
|
||||
pub fn new(isa: &TargetIsa) -> TextSink {
|
||||
TextSink {
|
||||
rnames: isa.reloc_names(),
|
||||
offset: 0,
|
||||
text: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl binemit::CodeSink for TextSink {
|
||||
fn offset(&self) -> binemit::CodeOffset {
|
||||
self.offset
|
||||
}
|
||||
|
||||
fn put1(&mut self, x: u8) {
|
||||
write!(self.text, "{:02x} ", x).unwrap();
|
||||
self.offset += 1;
|
||||
}
|
||||
|
||||
fn put2(&mut self, x: u16) {
|
||||
write!(self.text, "{:04x} ", x).unwrap();
|
||||
self.offset += 2;
|
||||
}
|
||||
|
||||
fn put4(&mut self, x: u32) {
|
||||
write!(self.text, "{:08x} ", x).unwrap();
|
||||
self.offset += 4;
|
||||
}
|
||||
|
||||
fn put8(&mut self, x: u64) {
|
||||
write!(self.text, "{:016x} ", x).unwrap();
|
||||
self.offset += 8;
|
||||
}
|
||||
|
||||
fn reloc_ebb(&mut self, reloc: binemit::Reloc, ebb: ir::Ebb) {
|
||||
@@ -77,11 +100,7 @@ impl SubTest for TestBinEmit {
|
||||
// TODO: Run a verifier pass over the code first to detect any bad encodings or missing/bad
|
||||
// value locations. The current error reporting is just crashing...
|
||||
let mut func = func.into_owned();
|
||||
|
||||
let mut sink = TextSink {
|
||||
rnames: isa.reloc_names(),
|
||||
text: String::new(),
|
||||
};
|
||||
let mut sink = TextSink::new(isa);
|
||||
|
||||
for comment in &context.details.comments {
|
||||
if let Some(want) = match_directive(comment.text, "bin:") {
|
||||
|
||||
Reference in New Issue
Block a user