aboutsummaryrefslogtreecommitdiff
path: root/patio-to-cranelift
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-04-04 10:10:25 +0100
committerMichael Williamson <mike@zwobble.org>2026-04-04 10:10:25 +0100
commit12603907da475e329b0900f125a8cc2612ed78e6 (patch)
tree89647c0e137caa119df96b72b892b6feddb38ad3 /patio-to-cranelift
parent3d4f48ccc6bcfe27bc7d433e1e5a90c52445586e (diff)
Add rust-native PatioInstruction
Diffstat (limited to 'patio-to-cranelift')
-rw-r--r--patio-to-cranelift/src/lib.rs188
-rw-r--r--patio-to-cranelift/src/patio/flatbuffers.rs160
-rw-r--r--patio-to-cranelift/src/patio/instructions.rs96
-rw-r--r--patio-to-cranelift/src/patio/mod.rs1
4 files changed, 333 insertions, 112 deletions
diff --git a/patio-to-cranelift/src/lib.rs b/patio-to-cranelift/src/lib.rs
index 1b1da2d4..ad54d59e 100644
--- a/patio-to-cranelift/src/lib.rs
+++ b/patio-to-cranelift/src/lib.rs
@@ -7,16 +7,17 @@ use crate::{
errors::CompileError,
patio::{
compilation_unit::{PatioLocal, PatioLocalType, PatioVisibility},
+ instructions::{
+ PatioBlock, PatioBoolToInt, PatioCall, PatioIf, PatioInstruction, PatioIntAdd,
+ PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool, PatioLocalStore,
+ PatioResume, PatioReturn, PatioReturnVoid, PatioVarLoad, PatioVarStore,
+ },
operands::{PatioLocalRef, PatioOperand},
types::{PatioDataLayout, PatioType},
values::PatioIntValue,
},
patio_generated::patio::{
- PatioBlock, PatioBoolToInt, PatioCall, PatioCompilationUnitElement,
- PatioCompilationUnitElementValue, PatioFunctionDefinition, PatioIf, PatioInstruction,
- PatioInstructionValue, PatioIntAdd, PatioIntEquals, PatioIntNotEqual, PatioIntSub,
- PatioIntToBool, PatioLocalStore, PatioResume, PatioReturn, PatioReturnVoid, PatioVarLoad,
- PatioVarStore,
+ PatioCompilationUnitElement, PatioCompilationUnitElementValue, PatioFunctionDefinition,
},
};
@@ -180,149 +181,122 @@ fn define_function_definition(
}
for instruction in function_definition.body() {
- compile_instruction(instruction, function_context)
+ compile_instruction(&instruction.into(), function_context)
}
},
);
}
-fn compile_instruction(
- instruction: PatioInstruction<'_>,
- context: &mut CompilerFunctionContext<'_>,
-) {
- match instruction.value_type() {
- PatioInstructionValue::PatioBlock => {
- let block = instruction.value_as_patio_block().unwrap();
+fn compile_instruction(instruction: &PatioInstruction, context: &mut CompilerFunctionContext<'_>) {
+ match instruction {
+ PatioInstruction::Block(block) => {
compile_block(block, context);
}
- PatioInstructionValue::PatioBoolToInt => {
- let bool_to_int = instruction.value_as_patio_bool_to_int().unwrap();
+ PatioInstruction::BoolToInt(bool_to_int) => {
compile_bool_to_int(bool_to_int, context);
}
- PatioInstructionValue::PatioCall => {
- let call = instruction.value_as_patio_call().unwrap();
+ PatioInstruction::Call(call) => {
compile_call(call, context);
}
- PatioInstructionValue::PatioIf => {
- let if_ = instruction.value_as_patio_if().unwrap();
+ PatioInstruction::If(if_) => {
compile_if(if_, context);
}
- PatioInstructionValue::PatioIntAdd => {
- let int_add = instruction.value_as_patio_int_add().unwrap();
+ PatioInstruction::IntAdd(int_add) => {
compile_int_add(int_add, context);
}
- PatioInstructionValue::PatioIntEquals => {
- let int_equals = instruction.value_as_patio_int_equals().unwrap();
+ PatioInstruction::IntEquals(int_equals) => {
compile_int_equals(int_equals, context);
}
- PatioInstructionValue::PatioIntNotEqual => {
- let int_not_equal = instruction.value_as_patio_int_not_equal().unwrap();
+ PatioInstruction::IntNotEqual(int_not_equal) => {
compile_int_not_equal(int_not_equal, context);
}
- PatioInstructionValue::PatioIntSub => {
- let int_sub = instruction.value_as_patio_int_sub().unwrap();
+ PatioInstruction::IntSub(int_sub) => {
compile_int_sub(int_sub, context);
}
- PatioInstructionValue::PatioIntToBool => {
- let int_to_bool = instruction.value_as_patio_int_to_bool().unwrap();
+ PatioInstruction::IntToBool(int_to_bool) => {
compile_int_to_bool(int_to_bool, context);
}
- PatioInstructionValue::PatioLocalStore => {
- let local_store = instruction.value_as_patio_local_store().unwrap();
+ PatioInstruction::LocalStore(local_store) => {
compile_local_store(local_store, context);
}
- PatioInstructionValue::PatioResume => {
- let resume = instruction.value_as_patio_resume().unwrap();
+ PatioInstruction::Resume(resume) => {
compile_resume(resume, context);
}
- PatioInstructionValue::PatioReturn => {
- let return_ = instruction.value_as_patio_return().unwrap();
+ PatioInstruction::Return(return_) => {
compile_return(return_, context);
}
- PatioInstructionValue::PatioReturnVoid => {
- let return_void = instruction.value_as_patio_return_void().unwrap();
+ PatioInstruction::ReturnVoid(return_void) => {
compile_return_void(return_void, context);
}
- PatioInstructionValue::PatioVarLoad => {
- let var_load = instruction.value_as_patio_var_load().unwrap();
+ PatioInstruction::VarLoad(var_load) => {
compile_var_load(var_load, context);
}
- PatioInstructionValue::PatioVarStore => {
- let var_store = instruction.value_as_patio_var_store().unwrap();
+ PatioInstruction::VarStore(var_store) => {
compile_var_store(var_store, context);
}
-
- instruction_type => {
- todo!(
- "Unhandled instruction type: {:?} {}",
- instruction_type.variant_name(),
- instruction_type.0
- )
- }
}
}
fn compile_block(
- block: PatioBlock<'_>,
+ block: &PatioBlock,
context: &mut CompilerFunctionContext<'_>,
) -> Vec<cranelift_codegen::ir::Value> {
- for instruction in block.body() {
+ for instruction in &block.body {
compile_instruction(instruction, context);
}
block
- .results()
+ .results
.iter()
- .map(|result| compile_operand(&result.into(), context))
+ .map(|result| compile_operand(&result, context))
.collect()
}
-fn compile_bool_to_int(bool_to_int: PatioBoolToInt<'_>, context: &mut CompilerFunctionContext<'_>) {
- let cranelift_value = compile_operand(&bool_to_int.value().into(), context);
+fn compile_bool_to_int(bool_to_int: &PatioBoolToInt, context: &mut CompilerFunctionContext<'_>) {
+ let cranelift_value = compile_operand(&bool_to_int.value, context);
let cranelift_result = context
.function_builder
.ins()
.uextend(cranelift_int_type(&context.target_triple), cranelift_value);
- def_destination(&bool_to_int.destination().into(), cranelift_result, context)
+ def_destination(&bool_to_int.destination, cranelift_result, context)
}
-fn compile_call(call: PatioCall<'_>, context: &mut CompilerFunctionContext<'_>) {
- let args: Vec<_> = call.args().iter().map(PatioOperand::from).collect();
- let cranelift_args = compile_operands(args.iter(), context);
+fn compile_call(call: &PatioCall, context: &mut CompilerFunctionContext<'_>) {
+ let cranelift_args = compile_operands(call.args.iter(), context);
- let func_ref = context.func_id(call.function_name());
+ let func_ref = context.func_id(&call.function_name);
context
.function_builder
.ins()
.call(func_ref, &cranelift_args);
}
-fn compile_if(if_: PatioIf<'_>, context: &mut CompilerFunctionContext<'_>) {
- let cranelift_condition = compile_operand(&if_.condition().into(), context);
+fn compile_if(if_: &PatioIf, context: &mut CompilerFunctionContext<'_>) {
+ let cranelift_condition = compile_operand(&if_.condition, context);
let cranelift_then_block = context.function_builder.create_block();
let cranelift_else_block = context.function_builder.create_block();
let cranelift_end_block = context.function_builder.create_block();
let cranelift_end_params: Vec<_> = if_
- .destinations()
+ .destinations
.iter()
.map(|destination| {
- let cranelift_type = context.var_type(destination.name());
+ let cranelift_type = context.var_type(&destination.name);
context
.function_builder
.append_block_param(cranelift_end_block, cranelift_type)
@@ -343,7 +317,7 @@ fn compile_if(if_: PatioIf<'_>, context: &mut CompilerFunctionContext<'_>) {
context
.function_builder
.switch_to_block(cranelift_then_block);
- let cranelift_then_results = compile_block(if_.true_body(), context);
+ let cranelift_then_results = compile_block(&if_.true_body, context);
context.function_builder.ins().jump(
cranelift_end_block,
cranelift_block_args(cranelift_then_results).iter(),
@@ -353,7 +327,7 @@ fn compile_if(if_: PatioIf<'_>, context: &mut CompilerFunctionContext<'_>) {
context
.function_builder
.switch_to_block(cranelift_else_block);
- let cranelift_else_results = compile_block(if_.false_body(), context);
+ let cranelift_else_results = compile_block(&if_.false_body, context);
context.function_builder.ins().jump(
cranelift_end_block,
cranelift_block_args(cranelift_else_results).iter(),
@@ -364,116 +338,106 @@ fn compile_if(if_: PatioIf<'_>, context: &mut CompilerFunctionContext<'_>) {
.function_builder
.switch_to_block(cranelift_end_block);
- for (destination, cranelift_end_param) in if_.destinations().iter().zip(cranelift_end_params) {
- def_destination(&destination.into(), cranelift_end_param, context);
+ for (destination, cranelift_end_param) in if_.destinations.iter().zip(cranelift_end_params) {
+ def_destination(destination, cranelift_end_param, context);
}
}
-fn compile_int_add(int_add: PatioIntAdd<'_>, context: &mut CompilerFunctionContext<'_>) {
- let cranelift_left = compile_operand(&int_add.left().into(), context);
- let cranelift_right = compile_operand(&int_add.right().into(), context);
+fn compile_int_add(int_add: &PatioIntAdd, context: &mut CompilerFunctionContext<'_>) {
+ let cranelift_left = compile_operand(&int_add.left, context);
+ let cranelift_right = compile_operand(&int_add.right, context);
let cranelift_result = context
.function_builder
.ins()
.iadd(cranelift_left, cranelift_right);
- def_destination(&int_add.destination().into(), cranelift_result, context);
+ def_destination(&int_add.destination, cranelift_result, context);
}
-fn compile_int_equals(int_equals: PatioIntEquals<'_>, context: &mut CompilerFunctionContext<'_>) {
- let cranelift_left = compile_operand(&int_equals.left().into(), context);
- let cranelift_right = compile_operand(&int_equals.right().into(), context);
+fn compile_int_equals(int_equals: &PatioIntEquals, context: &mut CompilerFunctionContext<'_>) {
+ let cranelift_left = compile_operand(&int_equals.left, context);
+ let cranelift_right = compile_operand(&int_equals.right, context);
let cranelift_result = context.function_builder.ins().icmp(
cranelift_codegen::ir::condcodes::IntCC::Equal,
cranelift_left,
cranelift_right,
);
- def_destination(&int_equals.destination().into(), cranelift_result, context);
+ def_destination(&int_equals.destination, cranelift_result, context);
}
fn compile_int_not_equal(
- int_not_equal: PatioIntNotEqual<'_>,
+ int_not_equal: &PatioIntNotEqual,
context: &mut CompilerFunctionContext<'_>,
) {
- let cranelift_left = compile_operand(&int_not_equal.left().into(), context);
- let cranelift_right = compile_operand(&int_not_equal.right().into(), context);
+ let cranelift_left = compile_operand(&int_not_equal.left, context);
+ let cranelift_right = compile_operand(&int_not_equal.right, context);
let cranelift_result = context.function_builder.ins().icmp(
cranelift_codegen::ir::condcodes::IntCC::NotEqual,
cranelift_left,
cranelift_right,
);
- def_destination(
- &int_not_equal.destination().into(),
- cranelift_result,
- context,
- );
+ def_destination(&int_not_equal.destination, cranelift_result, context);
}
-fn compile_int_sub(int_sub: PatioIntSub<'_>, context: &mut CompilerFunctionContext<'_>) {
- let cranelift_left = compile_operand(&int_sub.left().into(), context);
- let cranelift_right = compile_operand(&int_sub.right().into(), context);
+fn compile_int_sub(int_sub: &PatioIntSub, context: &mut CompilerFunctionContext<'_>) {
+ let cranelift_left = compile_operand(&int_sub.left, context);
+ let cranelift_right = compile_operand(&int_sub.right, context);
let cranelift_result = context
.function_builder
.ins()
.isub(cranelift_left, cranelift_right);
- def_destination(&int_sub.destination().into(), cranelift_result, context);
+ def_destination(&int_sub.destination, cranelift_result, context);
}
-fn compile_int_to_bool(int_to_bool: PatioIntToBool<'_>, context: &mut CompilerFunctionContext<'_>) {
- let cranelift_value = compile_operand(&int_to_bool.value().into(), context);
+fn compile_int_to_bool(int_to_bool: &PatioIntToBool, context: &mut CompilerFunctionContext<'_>) {
+ let cranelift_value = compile_operand(&int_to_bool.value, context);
let cranelift_result = context
.function_builder
.ins()
.ireduce(CRANELIFT_BOOL_TYPE, cranelift_value);
- def_destination(&int_to_bool.destination().into(), cranelift_result, context);
+ def_destination(&int_to_bool.destination, cranelift_result, context);
}
-fn compile_local_store(
- local_store: PatioLocalStore<'_>,
- context: &mut CompilerFunctionContext<'_>,
-) {
- let cranelift_value = compile_operand(&local_store.value().into(), context);
- def_destination(&local_store.destination().into(), cranelift_value, context);
+fn compile_local_store(local_store: &PatioLocalStore, context: &mut CompilerFunctionContext<'_>) {
+ let cranelift_value = compile_operand(&local_store.value, context);
+ def_destination(&local_store.destination, cranelift_value, context);
}
-fn compile_resume(resume: PatioResume<'_>, context: &mut CompilerFunctionContext<'_>) {
- let cranelift_value = compile_operand(&resume.value().into(), context);
+fn compile_resume(resume: &PatioResume, context: &mut CompilerFunctionContext<'_>) {
+ let cranelift_value = compile_operand(&resume.value, context);
context.function_builder.ins().return_(&[cranelift_value]);
}
-fn compile_return(return_: PatioReturn<'_>, context: &mut CompilerFunctionContext<'_>) {
- let cranelift_value = compile_operand(&return_.value().into(), context);
+fn compile_return(return_: &PatioReturn, context: &mut CompilerFunctionContext<'_>) {
+ let cranelift_value = compile_operand(&return_.value, context);
context.function_builder.ins().return_(&[cranelift_value]);
}
-fn compile_return_void(
- _return_void: PatioReturnVoid<'_>,
- context: &mut CompilerFunctionContext<'_>,
-) {
+fn compile_return_void(_return_void: &PatioReturnVoid, context: &mut CompilerFunctionContext<'_>) {
context.function_builder.ins().return_(&[]);
}
-fn compile_var_load(var_load: PatioVarLoad<'_>, context: &mut CompilerFunctionContext<'_>) {
- let stack_slot = context.stack_slot(var_load.var().name());
- let type_ = context.stack_slot_type(var_load.var().name());
+fn compile_var_load(var_load: &PatioVarLoad, context: &mut CompilerFunctionContext<'_>) {
+ let stack_slot = context.stack_slot(&var_load.var.name);
+ let type_ = context.stack_slot_type(&var_load.var.name);
let value = context.function_builder.ins().stack_load(
type_,
stack_slot,
cranelift_codegen::ir::immediates::Offset32::new(0),
);
- def_destination(&var_load.destination().into(), value, context);
+ def_destination(&var_load.destination, value, context);
}
-fn compile_var_store(var_store: PatioVarStore<'_>, context: &mut CompilerFunctionContext<'_>) {
- let stack_slot = context.stack_slot(var_store.var().name());
- let value = compile_operand(&var_store.value().into(), context);
+fn compile_var_store(var_store: &PatioVarStore, context: &mut CompilerFunctionContext<'_>) {
+ let stack_slot = context.stack_slot(&var_store.var.name);
+ let value = compile_operand(&var_store.value, context);
context.function_builder.ins().stack_store(
value,
stack_slot,
diff --git a/patio-to-cranelift/src/patio/flatbuffers.rs b/patio-to-cranelift/src/patio/flatbuffers.rs
index 3ebf652f..9f147695 100644
--- a/patio-to-cranelift/src/patio/flatbuffers.rs
+++ b/patio-to-cranelift/src/patio/flatbuffers.rs
@@ -1,6 +1,11 @@
use crate::{
patio::{
compilation_unit::{PatioLocal, PatioLocalType, PatioVisibility},
+ instructions::{
+ PatioBlock, PatioBoolToInt, PatioCall, PatioIf, PatioInstruction, PatioIntAdd,
+ PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool, PatioLocalStore,
+ PatioResume, PatioReturn, PatioReturnVoid, PatioVarLoad, PatioVarStore,
+ },
operands::{PatioLocalRef, PatioOperand},
types::{PatioDataLayout, PatioType},
values::PatioIntValue,
@@ -52,6 +57,161 @@ impl From<patio_generated::patio::PatioVisibility> for PatioVisibility {
}
}
+// == Instructions ==
+
+impl From<patio_generated::patio::PatioInstruction<'_>> for PatioInstruction {
+ fn from(value: patio_generated::patio::PatioInstruction<'_>) -> Self {
+ match value.value_type() {
+ patio_generated::patio::PatioInstructionValue::PatioBlock => {
+ let block = value.value_as_patio_block().unwrap();
+
+ Self::Block(block.into())
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioBoolToInt => {
+ let bool_to_int = value.value_as_patio_bool_to_int().unwrap();
+
+ Self::BoolToInt(PatioBoolToInt {
+ destination: bool_to_int.destination().into(),
+ value: bool_to_int.value().into(),
+ })
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioCall => {
+ let call = value.value_as_patio_call().unwrap();
+
+ Self::Call(PatioCall {
+ destination: call.destination().map(Into::into),
+ function_name: call.function_name().into(),
+ args: call.args().iter().map(Into::into).collect(),
+ })
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioIf => {
+ let if_ = value.value_as_patio_if().unwrap();
+
+ Self::If(PatioIf {
+ destinations: if_.destinations().iter().map(Into::into).collect(),
+ condition: if_.condition().into(),
+ true_body: if_.true_body().into(),
+ false_body: if_.false_body().into(),
+ })
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioIntAdd => {
+ let int_add = value.value_as_patio_int_add().unwrap();
+
+ Self::IntAdd(PatioIntAdd {
+ destination: int_add.destination().into(),
+ left: int_add.left().into(),
+ right: int_add.right().into(),
+ })
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioIntEquals => {
+ let int_add = value.value_as_patio_int_equals().unwrap();
+
+ Self::IntEquals(PatioIntEquals {
+ destination: int_add.destination().into(),
+ left: int_add.left().into(),
+ right: int_add.right().into(),
+ })
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioIntNotEqual => {
+ let int_not_equal = value.value_as_patio_int_not_equal().unwrap();
+
+ Self::IntNotEqual(PatioIntNotEqual {
+ destination: int_not_equal.destination().into(),
+ left: int_not_equal.left().into(),
+ right: int_not_equal.right().into(),
+ })
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioIntSub => {
+ let int_sub = value.value_as_patio_int_sub().unwrap();
+
+ Self::IntSub(PatioIntSub {
+ destination: int_sub.destination().into(),
+ left: int_sub.left().into(),
+ right: int_sub.right().into(),
+ })
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioIntToBool => {
+ let int_to_bool = value.value_as_patio_int_to_bool().unwrap();
+
+ Self::IntToBool(PatioIntToBool {
+ destination: int_to_bool.destination().into(),
+ value: int_to_bool.value().into(),
+ })
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioLocalStore => {
+ let local_store = value.value_as_patio_local_store().unwrap();
+
+ Self::LocalStore(PatioLocalStore {
+ destination: local_store.destination().into(),
+ value: local_store.value().into(),
+ })
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioResume => {
+ let resume = value.value_as_patio_resume().unwrap();
+
+ Self::Resume(PatioResume {
+ value: resume.value().into(),
+ })
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioReturn => {
+ let return_ = value.value_as_patio_return().unwrap();
+
+ Self::Return(PatioReturn {
+ value: return_.value().into(),
+ })
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioReturnVoid => {
+ Self::ReturnVoid(PatioReturnVoid)
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioVarLoad => {
+ let var_load = value.value_as_patio_var_load().unwrap();
+
+ Self::VarLoad(PatioVarLoad {
+ destination: var_load.destination().into(),
+ var: var_load.var().into(),
+ })
+ }
+
+ patio_generated::patio::PatioInstructionValue::PatioVarStore => {
+ let var_store = value.value_as_patio_var_store().unwrap();
+
+ Self::VarStore(PatioVarStore {
+ var: var_store.var().into(),
+ value: var_store.value().into(),
+ })
+ }
+
+ instruction_type => todo!(
+ "Unhandled instruction type: {:?} {}",
+ instruction_type.variant_name(),
+ instruction_type.0
+ ),
+ }
+ }
+}
+
+impl From<patio_generated::patio::PatioBlock<'_>> for PatioBlock {
+ fn from(value: patio_generated::patio::PatioBlock<'_>) -> Self {
+ Self {
+ body: value.body().iter().map(Into::into).collect(),
+ results: value.results().iter().map(Into::into).collect(),
+ }
+ }
+}
+
// == Operands ==
impl From<patio_generated::patio::PatioOperand<'_>> for PatioOperand {
diff --git a/patio-to-cranelift/src/patio/instructions.rs b/patio-to-cranelift/src/patio/instructions.rs
new file mode 100644
index 00000000..23268a22
--- /dev/null
+++ b/patio-to-cranelift/src/patio/instructions.rs
@@ -0,0 +1,96 @@
+use crate::patio::operands::{PatioLocalRef, PatioOperand};
+
+pub(crate) enum PatioInstruction {
+ Block(PatioBlock),
+ BoolToInt(PatioBoolToInt),
+ Call(PatioCall),
+ If(PatioIf),
+ IntAdd(PatioIntAdd),
+ IntEquals(PatioIntEquals),
+ IntNotEqual(PatioIntNotEqual),
+ IntSub(PatioIntSub),
+ IntToBool(PatioIntToBool),
+ LocalStore(PatioLocalStore),
+ Resume(PatioResume),
+ Return(PatioReturn),
+ ReturnVoid(PatioReturnVoid),
+ VarLoad(PatioVarLoad),
+ VarStore(PatioVarStore),
+}
+
+pub(crate) struct PatioBlock {
+ pub(crate) body: Vec<PatioInstruction>,
+ pub(crate) results: Vec<PatioOperand>,
+}
+
+pub(crate) struct PatioBoolToInt {
+ pub(crate) destination: PatioLocalRef,
+ pub(crate) value: PatioOperand,
+}
+
+pub(crate) struct PatioCall {
+ pub(crate) destination: Option<PatioLocalRef>,
+ pub(crate) function_name: String,
+ pub(crate) args: Vec<PatioOperand>,
+}
+
+pub(crate) struct PatioIf {
+ pub(crate) destinations: Vec<PatioLocalRef>,
+ pub(crate) condition: PatioOperand,
+ pub(crate) true_body: PatioBlock,
+ pub(crate) false_body: PatioBlock,
+}
+
+pub(crate) struct PatioIntAdd {
+ pub(crate) destination: PatioLocalRef,
+ pub(crate) left: PatioOperand,
+ pub(crate) right: PatioOperand,
+}
+
+pub(crate) struct PatioIntEquals {
+ pub(crate) destination: PatioLocalRef,
+ pub(crate) left: PatioOperand,
+ pub(crate) right: PatioOperand,
+}
+
+pub(crate) struct PatioIntNotEqual {
+ pub(crate) destination: PatioLocalRef,
+ pub(crate) left: PatioOperand,
+ pub(crate) right: PatioOperand,
+}
+
+pub(crate) struct PatioIntSub {
+ pub(crate) destination: PatioLocalRef,
+ pub(crate) left: PatioOperand,
+ pub(crate) right: PatioOperand,
+}
+
+pub(crate) struct PatioIntToBool {
+ pub(crate) destination: PatioLocalRef,
+ pub(crate) value: PatioOperand,
+}
+
+pub(crate) struct PatioLocalStore {
+ pub(crate) destination: PatioLocalRef,
+ pub(crate) value: PatioOperand,
+}
+
+pub(crate) struct PatioResume {
+ pub(crate) value: PatioOperand,
+}
+
+pub(crate) struct PatioReturn {
+ pub(crate) value: PatioOperand,
+}
+
+pub(crate) struct PatioReturnVoid;
+
+pub(crate) struct PatioVarLoad {
+ pub(crate) destination: PatioLocalRef,
+ pub(crate) var: PatioLocalRef,
+}
+
+pub(crate) struct PatioVarStore {
+ pub(crate) var: PatioLocalRef,
+ pub(crate) value: PatioOperand,
+}
diff --git a/patio-to-cranelift/src/patio/mod.rs b/patio-to-cranelift/src/patio/mod.rs
index c8a569e6..4316b519 100644
--- a/patio-to-cranelift/src/patio/mod.rs
+++ b/patio-to-cranelift/src/patio/mod.rs
@@ -1,5 +1,6 @@
pub(crate) mod compilation_unit;
pub(crate) mod flatbuffers;
+pub(crate) mod instructions;
pub(crate) mod operands;
pub(crate) mod types;
pub(crate) mod values;