From 05c585d47ccf56a1cff040adbcaf000f463ca8de Mon Sep 17 00:00:00 2001 From: sofia Date: Sun, 29 Jun 2025 19:11:56 +0300 Subject: [PATCH] Add sub and fibonacci calculation --- reid-llvm-lib/examples/libtest.rs | 103 +++++++++++++++++++++--------- reid-llvm-lib/src/lib.rs | 32 +++++++++- reid-llvm-lib/src/types.rs | 2 +- 3 files changed, 103 insertions(+), 34 deletions(-) diff --git a/reid-llvm-lib/examples/libtest.rs b/reid-llvm-lib/examples/libtest.rs index 7cfc9eb..43a3ecd 100644 --- a/reid-llvm-lib/examples/libtest.rs +++ b/reid-llvm-lib/examples/libtest.rs @@ -1,6 +1,6 @@ use reid_lib::{ Context, IntPredicate, - types::{BasicType, IntegerType, IntegerValue}, + types::{BasicType, IntegerType, IntegerValue, Value}, }; pub fn main() { @@ -16,42 +16,83 @@ pub fn main() { let int_32 = context.type_i32(); - let secondary = module.add_function(int_32.function_type(&[]), "secondary"); - let s_entry = secondary.block("entry"); - s_entry.ret(&int_32.from_signed(54)).unwrap(); + let fibonacci = module.add_function(int_32.function_type(vec![&int_32]), "fibonacci"); + let f_main = fibonacci.block("main"); - let function = module.add_function(int_32.function_type(&[]), "main"); - - let entry = function.block("entry"); - - let call = entry.call(&secondary, vec![], "call").unwrap(); - let add = entry.add(&int_32.from_signed(100), &call, "add").unwrap(); - let rhs_cmp = int_32.from_signed(200); - - let cond_res = entry - .integer_compare(&add, &rhs_cmp, &IntPredicate::SLT, "cmp") + let param = fibonacci.get_param::(0).unwrap(); + let cmp = f_main + .integer_compare(¶m, &int_32.from_unsigned(3), &IntPredicate::ULT, "cmp") .unwrap(); - let (lhs, rhs) = entry.conditional_br(&cond_res, "lhs", "rhs").unwrap(); + let (done, recurse) = f_main.conditional_br(&cmp, "done", "recurse").unwrap(); - let left = lhs.add(&call, &int_32.from_signed(20), "add").unwrap(); - let right = rhs.add(&call, &int_32.from_signed(30), "add").unwrap(); + done.ret(&int_32.from_unsigned(1)).unwrap(); - let final_block = function.block("final"); - let phi = final_block - .phi::(&int_32, "phi") - .unwrap() - .add_incoming(&left, &lhs) - .add_incoming(&right, &rhs) - .build(); - - lhs.br(&final_block).unwrap(); - rhs.br(&final_block).unwrap(); - - let val = final_block - .add(&phi, &int_32.from_signed(11), "add") + let minus_one = recurse + .sub(¶m, &int_32.from_unsigned(1), "minus_one") .unwrap(); - final_block.ret(&val).unwrap(); + let minus_two = recurse + .sub(¶m, &int_32.from_unsigned(2), "minus_two") + .unwrap(); + let one = recurse + .call(&fibonacci, vec![Value::Integer(minus_one)], "call_one") + .unwrap(); + let two = recurse + .call(&fibonacci, vec![Value::Integer(minus_two)], "call_two") + .unwrap(); + + let add = recurse.add(&one, &two, "add").unwrap(); + + recurse.ret(&add).unwrap(); + + let main_f = module.add_function(int_32.function_type(Vec::new()), "main"); + + let main_b = main_f.block("main"); + let call = main_b + .call( + &fibonacci, + vec![Value::Integer(int_32.from_unsigned(8))], + "fib_call", + ) + .unwrap(); + main_b.ret(&call).unwrap(); + + // let secondary = module.add_function(int_32.function_type(&[]), "secondary"); + // let s_entry = secondary.block("entry"); + // s_entry.ret(&int_32.from_signed(54)).unwrap(); + + // let function = module.add_function(int_32.function_type(&[]), "main"); + + // let entry = function.block("entry"); + + // let call = entry.call(&secondary, vec![], "call").unwrap(); + // let add = entry.add(&int_32.from_signed(100), &call, "add").unwrap(); + // let rhs_cmp = int_32.from_signed(200); + + // let cond_res = entry + // .integer_compare(&add, &rhs_cmp, &IntPredicate::SLT, "cmp") + // .unwrap(); + + // let (lhs, rhs) = entry.conditional_br(&cond_res, "lhs", "rhs").unwrap(); + + // let left = lhs.add(&call, &int_32.from_signed(20), "add").unwrap(); + // let right = rhs.add(&call, &int_32.from_signed(30), "add").unwrap(); + + // let final_block = function.block("final"); + // let phi = final_block + // .phi::(&int_32, "phi") + // .unwrap() + // .add_incoming(&left, &lhs) + // .add_incoming(&right, &rhs) + // .build(); + + // lhs.br(&final_block).unwrap(); + // rhs.br(&final_block).unwrap(); + + // let val = final_block + // .add(&phi, &int_32.from_signed(11), "add") + // .unwrap(); + // final_block.ret(&val).unwrap(); match module.print_to_string() { Ok(v) => println!("{}", v), diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index ec544ae..92a9688 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -204,6 +204,17 @@ impl<'ctx, ReturnValue: BasicValue<'ctx>> Function<'ctx, ReturnValue> { pub fn block>(&'ctx self, name: T) -> BasicBlock<'ctx, ReturnValue> { BasicBlock::in_function(&self, name.into()) } + + pub fn get_param>(&'ctx self, nth: usize) -> Result { + if let Some(param_type) = self.fn_type.param_types.iter().nth(nth) { + if self.fn_type.return_type(self.module.context).llvm_type() != *param_type { + return Err(String::from("Wrong type")); + } + } else { + return Err(String::from("nth too large")); + } + unsafe { Ok(T::from_llvm(LLVMGetParam(self.fn_ref, nth as u32))) } + } } pub struct BasicBlock<'ctx, ReturnValue: BasicValue<'ctx>> { @@ -238,8 +249,8 @@ impl<'ctx, ReturnValue: BasicValue<'ctx>> BasicBlock<'ctx, ReturnValue> { #[must_use] pub fn integer_compare>( &self, - lhs: &'ctx T, - rhs: &'ctx T, + lhs: &T, + rhs: &T, comparison: &IntPredicate, name: &str, ) -> Result { @@ -304,6 +315,23 @@ impl<'ctx, ReturnValue: BasicValue<'ctx>> BasicBlock<'ctx, ReturnValue> { } } + #[must_use] + pub fn sub>(&self, lhs: &T, rhs: &T, name: &str) -> Result { + if lhs.llvm_type() != rhs.llvm_type() { + return Err(()); // TODO error + } + unsafe { + LLVMPositionBuilderAtEnd(self.builder_ref, self.blockref); + let add_value_ref = LLVMBuildSub( + self.builder_ref, + lhs.llvm_value(), + rhs.llvm_value(), + into_cstring(name).as_ptr(), + ); + Ok(T::from_llvm(add_value_ref)) + } + } + #[must_use] pub fn phi>( &self, diff --git a/reid-llvm-lib/src/types.rs b/reid-llvm-lib/src/types.rs index acb0073..9f585c5 100644 --- a/reid-llvm-lib/src/types.rs +++ b/reid-llvm-lib/src/types.rs @@ -14,7 +14,7 @@ pub trait BasicType<'ctx> { where Self: Sized; - fn function_type(&'ctx self, params: &'ctx [&'ctx dyn BasicType]) -> FunctionType<'ctx, Self> + fn function_type(&'ctx self, params: Vec<&'ctx dyn BasicType>) -> FunctionType<'ctx, Self> where Self: Sized, {