Add load and store instructions.
Define a MemFlags class, currently holding a notrap and aligned flag.
This commit is contained in:
@@ -5,7 +5,8 @@
|
||||
|
||||
use ir::types;
|
||||
use ir::{InstructionData, DataFlowGraph, Cursor};
|
||||
use ir::{Opcode, Type, Inst, Value, Ebb, JumpTable, SigRef, FuncRef, StackSlot, ValueList};
|
||||
use ir::{Opcode, Type, Inst, Value, Ebb, JumpTable, SigRef, FuncRef, StackSlot, ValueList,
|
||||
MemFlags};
|
||||
use ir::immediates::{Imm64, Uimm8, Ieee32, Ieee64, Offset32, Uoffset32};
|
||||
use ir::condcodes::{IntCC, FloatCC};
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ use std::fmt::{self, Display, Formatter};
|
||||
use std::str::FromStr;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use ir::{Value, Type, Ebb, JumpTable, SigRef, FuncRef, StackSlot};
|
||||
use ir::{Value, Type, Ebb, JumpTable, SigRef, FuncRef, StackSlot, MemFlags};
|
||||
use ir::immediates::{Imm64, Uimm8, Ieee32, Ieee64, Offset32, Uoffset32};
|
||||
use ir::condcodes::*;
|
||||
use ir::types;
|
||||
@@ -252,6 +252,20 @@ pub enum InstructionData {
|
||||
args: [Value; 2],
|
||||
offset: Uoffset32,
|
||||
},
|
||||
Load {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
flags: MemFlags,
|
||||
arg: Value,
|
||||
offset: Offset32,
|
||||
},
|
||||
Store {
|
||||
opcode: Opcode,
|
||||
ty: Type,
|
||||
flags: MemFlags,
|
||||
args: [Value; 2],
|
||||
offset: Offset32,
|
||||
},
|
||||
}
|
||||
|
||||
/// A variable list of `Value` operands used for function call arguments and passing arguments to
|
||||
|
||||
92
lib/cretonne/src/ir/memflags.rs
Normal file
92
lib/cretonne/src/ir/memflags.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
//! Memory operation flags.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
enum FlagBit {
|
||||
Notrap,
|
||||
Aligned,
|
||||
}
|
||||
|
||||
const NAMES: [&'static str; 2] = ["notrap", "aligned"];
|
||||
|
||||
/// Flags for memory operations like load/store.
|
||||
///
|
||||
/// Each of these flags introduce a limited form of undefined behavior. The flags each enable
|
||||
/// certain optimizations that need to make additional assumptions. Generally, the semantics of a
|
||||
/// program does not change when a flag is removed, but adding a flag will.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct MemFlags {
|
||||
bits: u8,
|
||||
}
|
||||
|
||||
impl MemFlags {
|
||||
/// Create a new empty set of flags.
|
||||
pub fn new() -> MemFlags {
|
||||
MemFlags { bits: 0 }
|
||||
}
|
||||
|
||||
/// Read a flag bit.
|
||||
fn read(self, bit: FlagBit) -> bool {
|
||||
self.bits & (1 << bit as usize) != 0
|
||||
}
|
||||
|
||||
/// Set a flag bit.
|
||||
fn set(&mut self, bit: FlagBit) {
|
||||
self.bits |= 1 << bit as usize
|
||||
}
|
||||
|
||||
/// Set a flag bit by name.
|
||||
///
|
||||
/// Returns true if the flag was found and set, false for an unknown flag name.
|
||||
pub fn set_by_name(&mut self, name: &str) -> bool {
|
||||
match NAMES.iter().position(|&s| s == name) {
|
||||
Some(bit) => {
|
||||
self.bits |= 1 << bit;
|
||||
true
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Test if the `notrap` flag is set.
|
||||
///
|
||||
/// Normally, trapping is part of the semantics of a load/store operation. If the platform
|
||||
/// would cause a trap when accessing the effective address, the Cretonne memory operation is
|
||||
/// also required to trap.
|
||||
///
|
||||
/// The `notrap` flag gives a Cretonne operation permission to not trap. This makes it possible
|
||||
/// to delete an unused load or a dead store instruction.
|
||||
pub fn notrap(self) -> bool {
|
||||
self.read(FlagBit::Notrap)
|
||||
}
|
||||
|
||||
/// Set the `notrap` flag.
|
||||
pub fn set_notrap(&mut self) {
|
||||
self.set(FlagBit::Notrap)
|
||||
}
|
||||
|
||||
/// Test if the `aligned` flag is set.
|
||||
///
|
||||
/// By default, Cretonne memory instructions work with any unaligned effective address. If the
|
||||
/// `aligned` flag is set, the instruction is permitted to trap or return a wrong result if the
|
||||
/// effective address is misaligned.
|
||||
pub fn aligned(self) -> bool {
|
||||
self.read(FlagBit::Aligned)
|
||||
}
|
||||
|
||||
/// Set the `aligned` flag.
|
||||
pub fn set_aligned(&mut self) {
|
||||
self.set(FlagBit::Aligned)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for MemFlags {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for (i, n) in NAMES.iter().enumerate() {
|
||||
if self.bits & (1 << i) != 0 {
|
||||
write!(f, " {}", n)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -10,11 +10,12 @@ pub mod jumptable;
|
||||
pub mod dfg;
|
||||
pub mod layout;
|
||||
pub mod function;
|
||||
mod funcname;
|
||||
mod extfunc;
|
||||
mod builder;
|
||||
mod valueloc;
|
||||
mod extfunc;
|
||||
mod funcname;
|
||||
mod memflags;
|
||||
mod progpoint;
|
||||
mod valueloc;
|
||||
|
||||
pub use ir::funcname::FunctionName;
|
||||
pub use ir::extfunc::{Signature, ArgumentType, ArgumentExtension, ExtFuncData};
|
||||
@@ -29,3 +30,4 @@ pub use ir::layout::{Layout, Cursor};
|
||||
pub use ir::function::Function;
|
||||
pub use ir::builder::InstBuilder;
|
||||
pub use ir::progpoint::{ProgramPoint, ProgramOrder, ExpandedProgramPoint};
|
||||
pub use ir::memflags::MemFlags;
|
||||
|
||||
@@ -271,7 +271,9 @@ impl<'a> Verifier<'a> {
|
||||
&IntCompareImm { .. } |
|
||||
&FloatCompare { .. } |
|
||||
&HeapLoad { .. } |
|
||||
&HeapStore { .. } => {}
|
||||
&HeapStore { .. } |
|
||||
&Load { .. } |
|
||||
&Store { .. } => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -322,6 +322,13 @@ pub fn write_operands(w: &mut Write, dfg: &DataFlowGraph, inst: Inst) -> Result
|
||||
} => write!(w, " {}, {}{}", arg, stack_slot, offset),
|
||||
HeapLoad { arg, offset, .. } => write!(w, " {}{}", arg, offset),
|
||||
HeapStore { args, offset, .. } => write!(w, " {}, {}{}", args[0], args[1], offset),
|
||||
Load { flags, arg, offset, .. } => write!(w, "{} {}{}", flags, arg, offset),
|
||||
Store {
|
||||
flags,
|
||||
args,
|
||||
offset,
|
||||
..
|
||||
} => write!(w, "{} {}, {}{}", flags, args[0], args[1], offset),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user