[WIP] Add a Trap sink to code generation (#279)
* First draft of TrapSink implementation. * Add trap sink calls to 'trapif' and 'trapff' recipes. * Add SourceLoc to trap sink calls, and add trap sink calls to all loads and stores. * Add IntegerDivisionByZero trap to div recipe. * Only emit load/store traps if 'notrap' flag is not set on the instruction. * Update filetest machinery to add new trap sink functionality. * Update filetests to include traps in output. * Add a few more trap outputs to filetests. * Add trap output to CLI tool.
This commit is contained in:
committed by
Dan Gohman
parent
d566faa8fb
commit
951ff11f85
@@ -14,7 +14,7 @@
|
||||
//! relocations to a `RelocSink` trait object. Relocations are less frequent than the
|
||||
//! `CodeSink::put*` methods, so the performance impact of the virtual callbacks is less severe.
|
||||
|
||||
use ir::{ExternalName, JumpTable};
|
||||
use ir::{ExternalName, JumpTable, TrapCode, SourceLoc};
|
||||
use super::{CodeSink, CodeOffset, Reloc, Addend};
|
||||
use std::ptr::write_unaligned;
|
||||
|
||||
@@ -33,15 +33,21 @@ pub struct MemoryCodeSink<'a> {
|
||||
data: *mut u8,
|
||||
offset: isize,
|
||||
relocs: &'a mut RelocSink,
|
||||
traps: &'a mut TrapSink,
|
||||
}
|
||||
|
||||
impl<'a> MemoryCodeSink<'a> {
|
||||
/// Create a new memory code sink that writes a function to the memory pointed to by `data`.
|
||||
pub fn new(data: *mut u8, relocs: &mut RelocSink) -> MemoryCodeSink {
|
||||
pub fn new<'sink>(
|
||||
data: *mut u8,
|
||||
relocs: &'sink mut RelocSink,
|
||||
traps: &'sink mut TrapSink,
|
||||
) -> MemoryCodeSink<'sink> {
|
||||
MemoryCodeSink {
|
||||
data,
|
||||
offset: 0,
|
||||
relocs,
|
||||
traps,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,6 +64,12 @@ pub trait RelocSink {
|
||||
fn reloc_jt(&mut self, CodeOffset, Reloc, JumpTable);
|
||||
}
|
||||
|
||||
/// A trait for receiving trap codes and offsets.
|
||||
pub trait TrapSink {
|
||||
/// Add trap information for a specific offset.
|
||||
fn trap(&mut self, CodeOffset, SourceLoc, TrapCode);
|
||||
}
|
||||
|
||||
impl<'a> CodeSink for MemoryCodeSink<'a> {
|
||||
fn offset(&self) -> CodeOffset {
|
||||
self.offset as CodeOffset
|
||||
@@ -105,4 +117,9 @@ impl<'a> CodeSink for MemoryCodeSink<'a> {
|
||||
let ofs = self.offset();
|
||||
self.relocs.reloc_jt(ofs, rel, jt);
|
||||
}
|
||||
|
||||
fn trap(&mut self, code: TrapCode, srcloc: SourceLoc) {
|
||||
let ofs = self.offset();
|
||||
self.traps.trap(ofs, srcloc, code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ mod memorysink;
|
||||
|
||||
pub use regalloc::RegDiversions;
|
||||
pub use self::relaxation::relax_branches;
|
||||
pub use self::memorysink::{MemoryCodeSink, RelocSink};
|
||||
pub use self::memorysink::{MemoryCodeSink, RelocSink, TrapSink};
|
||||
|
||||
use ir::{ExternalName, JumpTable, Function, Inst};
|
||||
use ir::{ExternalName, JumpTable, Function, Inst, TrapCode, SourceLoc};
|
||||
use std::fmt;
|
||||
|
||||
/// Offset in bytes from the beginning of the function.
|
||||
@@ -86,6 +86,9 @@ pub trait CodeSink {
|
||||
|
||||
/// Add a relocation referencing a jump table.
|
||||
fn reloc_jt(&mut self, Reloc, JumpTable);
|
||||
|
||||
/// Add trap information for the current offset.
|
||||
fn trap(&mut self, TrapCode, SourceLoc);
|
||||
}
|
||||
|
||||
/// Report a bad encoding error.
|
||||
|
||||
Reference in New Issue
Block a user