#![allow(dead_code)] #![allow(unused_variables)] use ast::ptr::P; use ast::types::*; pub type WPID = usize; pub type MuID = usize; pub type MuTag = &'static str; pub type Address = usize; // TODO: replace this with Address(usize) #[derive(Clone)] pub struct SSAVar { pub id: MuID, pub tag: MuTag, pub ty: P } #[derive(Clone)] pub enum Value { SSAVar(SSAVar), Constant(MuConstant) } #[derive(Copy, Clone)] pub enum MemoryOrder { NotAtomic, Relaxed, Consume, Acquire, Release, AcqRel, SeqCst } #[derive(Copy, Clone)] pub enum CallConvention { Mu, Foreign(ForeignFFI) } #[derive(Copy, Clone)] pub enum ForeignFFI { C } pub struct CallData { pub func: P, pub args: Vec>, pub convention: CallConvention } pub struct Block { label: MuTag, content: Option } impl Block { pub fn new(label: MuTag) -> Block { Block{label: label, content: None} } pub fn set_content(&mut self, v: BlockContent) { self.content = Some(v); } } pub struct BlockContent { pub args: Vec>, pub body: Vec, pub exit: Terminal, pub keepalives: Option>> } pub struct ResumptionData { pub normal_dest: Destination, pub exn_dest: Destination } pub enum DestArg { Normal(P), Freshbound(usize) } pub struct Destination { pub target: MuTag, pub args: Vec } #[derive(Clone)] pub enum Constant { Int(usize, usize), IRef(P, Address), FloatV(f32), DoubleV(f64), VectorV(Vec), FuncRefV(Address), UFuncRefV(Address) } pub enum Expression { BinOp(BinOp, P, P), CmpOp(CmpOp, P, P), // yields the constant value Constant(P), // yields a tuple of results from the call ExprCall{ data: CallData, is_abort: bool, // T to abort, F to rethrow }, // yields the memory value Load{ is_iref: bool, mem_loc: P, order: MemoryOrder }, // yields nothing Store{ is_iref: bool, mem_loc: P, order: MemoryOrder }, // yields pair (oldvalue, boolean (T = success, F = failure)) CmpXchg{ is_iref: bool, // T for iref, F for ptr is_strong: bool, success_order: MemoryOrder, fail_order: MemoryOrder, mem_loc: P, expected_value: P, desired_value: P }, // yields old memory value AtomicRMW{ is_iref: bool, // T for iref, F for ptr order: MemoryOrder, op: AtomicRMWOp, mem_loc: P, value: P // operand for op }, // yields a reference of the type New(P), // yields an iref of the type AllocA(P), // yields ref NewHybrid{ // hybrid type, var part length ty: P, var_len: P }, // yields iref AllocAHybrid{ ty: P, var_len: P }, // yields stack ref NewStack{ func: P }, // yields thread reference NewThread{ stack: P, args: Vec> }, // yields thread reference (thread resumes with exceptional value) NewThreadExn{ stack: P, exn: P }, // yields frame cursor NewFrameCursor(P), // stack GetIRef(P), GetFieldIRef{ base: P, // iref or ptr index: P }, GetElementIRef{ base: P, index: P }, ShiftIRef{ base: P, offset: P }, GetVarPartIRef(P), // PushFrame{ // stack: P, // func: P // }, // PopFrame{ // stack: P // } } pub enum Instruction { Assign{ left: Vec>, right: Expression }, Fence(MemoryOrder), } pub enum Terminal { Return(Vec>), ThreadExit, Throw(Vec>), TailCall(CallData), Branch1(Destination), Branch2{ cond: P, true_dest: Destination, false_dest: Destination }, Watchpoint{ // Watchpoint NONE ResumptionData // serves as an unconditional trap. Trap to client, and resume with ResumptionData // Watchpoint (WPID dest) ResumptionData // when disabled, jump to dest // when enabled, trap to client and resume id: Option, disable_dest: Option, resume: ResumptionData }, WPBranch{ wp: WPID, disable_dest: Destination, enable_dest: Destination }, Call{ data: CallData, resume: ResumptionData }, SwapStack{ stack: P, is_exception: bool, args: Vec>, resume: ResumptionData }, Switch{ cond: P, default: Destination, branches: Vec<(P, Destination)> }, ExnInstruction{ inner: Expression, resume: ResumptionData } } #[derive(Clone)] pub struct MuConstant{ pub ty: P, pub val: Constant } pub struct MuFunction { pub fn_name: MuTag, pub sig: P, pub entry: MuTag, pub blocks: Vec<(MuTag, Block)> } #[derive(Copy, Clone)] pub enum BinOp { // Int(n) BinOp Int(n) -> Int(n) Add, Sub, Mul, Sdiv, Srem, Udiv, And, Or, Xor, // Int(n) BinOp Int(m) -> Int(n) Shl, Lshr, AsHR, // FP BinOp FP -> FP Fadd, FSub, FMul, FDiv, FRem } #[derive(Copy, Clone)] pub enum CmpOp { // for Int comparison EQ, NE, SGE, SGT, SLE, SLT, UGE, UGT, ULE, ULT, // for FP comparison FFALSE, FTRUE, FOEQ, FOGT, FOGE, FOLT, FOLE, FONE, FORD, FUEQ, FUGT, FUGE, FULT, FULE, FUNE, FUNO } #[derive(Copy, Clone)] pub enum AtomicRMWOp { XCHG, ADD, SUB, AND, NAND, OR, XOR, MAX, MIN, UMAX, UMIN }