aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--patio-to-cranelift/src/codegen/mod.rs96
-rw-r--r--patio-to-cranelift/src/patio/flatbuffers.rs21
-rw-r--r--patio-to-cranelift/src/patio/instructions.rs7
-rw-r--r--patio-to-cranelift/src/patio/operands.rs2
4 files changed, 113 insertions, 13 deletions
diff --git a/patio-to-cranelift/src/codegen/mod.rs b/patio-to-cranelift/src/codegen/mod.rs
index 75e13ba2..1a383a7c 100644
--- a/patio-to-cranelift/src/codegen/mod.rs
+++ b/patio-to-cranelift/src/codegen/mod.rs
@@ -3,7 +3,10 @@ use std::path::Path;
use cranelift::prelude::InstBuilder;
use crate::{
- codegen::context::{CompilerContext, CompilerFunctionContext, Mutability},
+ codegen::{
+ context::{CompilerContext, CompilerFunctionContext, Mutability},
+ types::patio_type_to_cranelift_type,
+ },
errors::CompileError,
patio::{
compilation_unit::{
@@ -12,10 +15,10 @@ use crate::{
PatioLocal, PatioLocalType, PatioVisibility,
},
instructions::{
- PatioBlock, PatioBoolToInt, PatioCall, PatioIf, PatioInstruction, PatioIntAdd,
- PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool, PatioLocalStore,
- PatioMemoryLoad, PatioMemoryStore, PatioResume, PatioReturn, PatioReturnVoid,
- PatioVarLoad, PatioVarStore,
+ PatioBlock, PatioBoolToInt, PatioCall, PatioCallPointer, PatioIf, PatioInstruction,
+ PatioIntAdd, PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool,
+ PatioLocalStore, PatioMemoryLoad, PatioMemoryStore, PatioResume, PatioReturn,
+ PatioReturnVoid, PatioVarLoad, PatioVarStore,
},
operands::{PatioLocalRef, PatioOperand},
types::PatioType,
@@ -235,6 +238,10 @@ fn compile_instruction(instruction: &PatioInstruction, context: &mut CompilerFun
compile_call(call, context);
}
+ PatioInstruction::CallPointer(call_pointer) => {
+ compile_call_pointer(call_pointer, context);
+ }
+
PatioInstruction::If(if_) => {
compile_if(if_, context);
}
@@ -334,6 +341,41 @@ fn compile_call(call: &PatioCall, context: &mut CompilerFunctionContext<'_>) {
}
}
+fn compile_call_pointer(
+ call_pointer: &PatioCallPointer,
+ context: &mut CompilerFunctionContext<'_>,
+) {
+ let mut cranelift_signature = new_cranelift_signature();
+ for arg in &call_pointer.args {
+ cranelift_signature
+ .params
+ .push(cranelift_codegen::ir::AbiParam::new(
+ patio_operand_to_cranelift_type(arg, context),
+ ));
+ }
+ cranelift_signature
+ .returns
+ .push(cranelift_codegen::ir::AbiParam::new(
+ context.var_type(&call_pointer.destination.name),
+ ));
+
+ let cranelift_signature_ref = context
+ .function_builder
+ .import_signature(cranelift_signature);
+
+ let cranelift_function_pointer = compile_operand(&call_pointer.function_pointer, context);
+ let cranelift_args = compile_operands(call_pointer.args.iter(), context);
+
+ let cranelift_call = context.function_builder.ins().call_indirect(
+ cranelift_signature_ref,
+ cranelift_function_pointer,
+ &cranelift_args,
+ );
+
+ let cranelift_value = context.function_builder.inst_results(cranelift_call)[0];
+ def_destination(&call_pointer.destination, cranelift_value, 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();
@@ -565,6 +607,16 @@ fn compile_operand(
PatioOperand::DataPtrConst(value) => compile_data_ptr_value(&value, context),
+ PatioOperand::FunctionPtrConst(name) => {
+ let func_ref = context.func_id(name);
+ let function_ptr_type = context.pointer_type();
+
+ context
+ .function_builder
+ .ins()
+ .func_addr(function_ptr_type, func_ref)
+ }
+
PatioOperand::IntConst(value) => {
let cranelift_int_type = types::cranelift_int_type(&context.target_triple);
compile_int_value(&value, cranelift_int_type, context)
@@ -637,13 +689,16 @@ fn def_destination(
.def_var(cranelift_destination, value);
}
+fn new_cranelift_signature() -> cranelift::prelude::Signature {
+ cranelift_codegen::ir::Signature::new(cranelift_codegen::isa::CallConv::SystemV)
+}
+
fn cranelift_signature<'a>(
locals: impl Iterator<Item = &'a PatioLocal>,
return_type: PatioType,
target_triple: &target_lexicon::Triple,
) -> cranelift::prelude::Signature {
- let mut signature =
- cranelift::prelude::Signature::new(cranelift_codegen::isa::CallConv::SystemV);
+ let mut signature = new_cranelift_signature();
for local in locals {
if local.local_type == PatioLocalType::Param {
@@ -669,3 +724,30 @@ fn patio_visibility_to_cranelift_linkage(visibility: PatioVisibility) -> craneli
PatioVisibility::Public => cranelift_module::Linkage::Export,
}
}
+
+fn patio_operand_to_cranelift_type(
+ operand: &PatioOperand,
+ context: &mut CompilerFunctionContext<'_>,
+) -> cranelift_codegen::ir::Type {
+ match operand {
+ PatioOperand::BoolConst(_) => {
+ patio_type_to_cranelift_type(PatioType::Bool, &context.target_triple)
+ }
+ PatioOperand::ByteConst(_) => {
+ patio_type_to_cranelift_type(PatioType::Byte, &context.target_triple)
+ }
+ PatioOperand::DataPtrConst(_) => {
+ patio_type_to_cranelift_type(PatioType::DataPtr, &context.target_triple)
+ }
+ PatioOperand::FunctionPtrConst(_) => {
+ patio_type_to_cranelift_type(PatioType::FunctionPtr, &context.target_triple)
+ }
+ PatioOperand::IntConst(_) => {
+ patio_type_to_cranelift_type(PatioType::Int, &context.target_triple)
+ }
+ PatioOperand::Int32Const(_) => {
+ patio_type_to_cranelift_type(PatioType::Int32, &context.target_triple)
+ }
+ PatioOperand::LocalRef(local_ref) => context.var_type(&local_ref.name),
+ }
+}
diff --git a/patio-to-cranelift/src/patio/flatbuffers.rs b/patio-to-cranelift/src/patio/flatbuffers.rs
index 7548d35d..c219d823 100644
--- a/patio-to-cranelift/src/patio/flatbuffers.rs
+++ b/patio-to-cranelift/src/patio/flatbuffers.rs
@@ -6,10 +6,10 @@ use crate::{
PatioLocal, PatioLocalType, PatioVisibility,
},
instructions::{
- PatioBlock, PatioBoolToInt, PatioCall, PatioIf, PatioInstruction, PatioIntAdd,
- PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool, PatioLocalStore,
- PatioMemoryLoad, PatioMemoryStore, PatioResume, PatioReturn, PatioReturnVoid,
- PatioVarLoad, PatioVarStore,
+ PatioBlock, PatioBoolToInt, PatioCall, PatioCallPointer, PatioIf, PatioInstruction,
+ PatioIntAdd, PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool,
+ PatioLocalStore, PatioMemoryLoad, PatioMemoryStore, PatioResume, PatioReturn,
+ PatioReturnVoid, PatioVarLoad, PatioVarStore,
},
operands::{PatioLocalRef, PatioOperand},
types::{PatioDataLayout, PatioType},
@@ -164,6 +164,16 @@ impl From<patio_generated::patio::PatioInstruction<'_>> for PatioInstruction {
})
}
+ patio_generated::patio::PatioInstructionValue::PatioCallPointer => {
+ let call_pointer = value.value_as_patio_call_pointer().unwrap();
+
+ Self::CallPointer(PatioCallPointer {
+ destination: call_pointer.destination().into(),
+ function_pointer: call_pointer.function_pointer().into(),
+ args: call_pointer.args().iter().map(Into::into).collect(),
+ })
+ }
+
patio_generated::patio::PatioInstructionValue::PatioIf => {
let if_ = value.value_as_patio_if().unwrap();
@@ -332,7 +342,8 @@ impl From<patio_generated::patio::PatioOperand<'_>> for PatioOperand {
}
patio_generated::patio::PatioOperandValue::PatioFunctionPtrConst => {
- Self::FunctionPtrConst
+ let function_ptr_const = value.value_as_patio_function_ptr_const().unwrap();
+ Self::FunctionPtrConst(function_ptr_const.name().to_string())
}
patio_generated::patio::PatioOperandValue::PatioIntConst => {
diff --git a/patio-to-cranelift/src/patio/instructions.rs b/patio-to-cranelift/src/patio/instructions.rs
index 39c39964..1cba2953 100644
--- a/patio-to-cranelift/src/patio/instructions.rs
+++ b/patio-to-cranelift/src/patio/instructions.rs
@@ -7,6 +7,7 @@ pub(crate) enum PatioInstruction {
Block(PatioBlock),
BoolToInt(PatioBoolToInt),
Call(PatioCall),
+ CallPointer(PatioCallPointer),
If(PatioIf),
IntAdd(PatioIntAdd),
IntEquals(PatioIntEquals),
@@ -39,6 +40,12 @@ pub(crate) struct PatioCall {
pub(crate) args: Vec<PatioOperand>,
}
+pub(crate) struct PatioCallPointer {
+ pub(crate) destination: PatioLocalRef,
+ pub(crate) function_pointer: PatioOperand,
+ pub(crate) args: Vec<PatioOperand>,
+}
+
pub(crate) struct PatioIf {
pub(crate) destinations: Vec<PatioLocalRef>,
pub(crate) condition: PatioOperand,
diff --git a/patio-to-cranelift/src/patio/operands.rs b/patio-to-cranelift/src/patio/operands.rs
index 05f9eec3..ca8eb3bc 100644
--- a/patio-to-cranelift/src/patio/operands.rs
+++ b/patio-to-cranelift/src/patio/operands.rs
@@ -5,7 +5,7 @@ pub(crate) enum PatioOperand {
BoolConst(bool),
ByteConst(u8),
DataPtrConst(PatioDataPtrValue),
- FunctionPtrConst,
+ FunctionPtrConst(String),
IntConst(PatioIntValue),
Int32Const(PatioIntValue),
LocalRef(PatioLocalRef),