use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SynthIR {
pub functions: Vec<IRFunction>,
pub globals: Vec<IRGlobal>,
pub memories: Vec<IRMemory>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IRFunction {
pub name: String,
pub params: Vec<IRValue>,
pub results: Vec<IRValue>,
pub blocks: Vec<IRBlock>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IRBlock {
pub label: String,
pub instructions: Vec<IRInstruction>,
pub terminator: IRTerminator,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum IRInstruction {
BinOp {
op: BinOp,
dest: IRValue,
left: IRValue,
right: IRValue,
},
UnOp {
op: UnOp,
dest: IRValue,
operand: IRValue,
},
Load {
dest: IRValue,
address: IRValue,
offset: i32,
},
Store {
address: IRValue,
value: IRValue,
offset: i32,
},
Call {
function: String,
args: Vec<IRValue>,
dest: Option<IRValue>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum IRTerminator {
Return(Option<IRValue>),
Branch(String),
BranchIf {
condition: IRValue,
true_block: String,
false_block: String,
},
Unreachable,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum BinOp {
IAdd,
ISub,
IMul,
IDivS,
IDivU,
IRemS,
IRemU,
IAnd,
IOr,
IXor,
IShl,
IShrS,
IShrU,
IRotl,
IRotr,
IEq,
INe,
ILtS,
ILtU,
ILeS,
ILeU,
IGtS,
IGtU,
IGeS,
IGeU,
FAdd,
FSub,
FMul,
FDiv,
FMin,
FMax,
FEq,
FNe,
FLt,
FLe,
FGt,
FGe,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum UnOp {
IClz,
ICtz,
IPopcnt,
IEqz,
FAbs,
FNeg,
FSqrt,
FCeil,
FFloor,
FTrunc,
FNearest,
I32WrapI64,
I64ExtendI32S,
I64ExtendI32U,
F32DemoteF64,
F64PromoteF32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum IRValue {
Local(u32),
ConstI32(i32),
ConstI64(i64),
ConstF32(f32),
ConstF64(f64),
Global(u32),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IRGlobal {
pub index: u32,
pub init: IRValue,
pub mutable: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IRMemory {
pub index: u32,
pub initial: u32,
pub maximum: Option<u32>,
}
impl SynthIR {
pub fn new() -> Self {
Self {
functions: Vec::new(),
globals: Vec::new(),
memories: Vec::new(),
}
}
}
impl Default for SynthIR {
fn default() -> Self {
Self::new()
}
}