Add sub and fibonacci calculation
This commit is contained in:
parent
7b93ab5d2e
commit
05c585d47c
@ -1,6 +1,6 @@
|
|||||||
use reid_lib::{
|
use reid_lib::{
|
||||||
Context, IntPredicate,
|
Context, IntPredicate,
|
||||||
types::{BasicType, IntegerType, IntegerValue},
|
types::{BasicType, IntegerType, IntegerValue, Value},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
@ -16,42 +16,83 @@ pub fn main() {
|
|||||||
|
|
||||||
let int_32 = context.type_i32();
|
let int_32 = context.type_i32();
|
||||||
|
|
||||||
let secondary = module.add_function(int_32.function_type(&[]), "secondary");
|
let fibonacci = module.add_function(int_32.function_type(vec![&int_32]), "fibonacci");
|
||||||
let s_entry = secondary.block("entry");
|
let f_main = fibonacci.block("main");
|
||||||
s_entry.ret(&int_32.from_signed(54)).unwrap();
|
|
||||||
|
|
||||||
let function = module.add_function(int_32.function_type(&[]), "main");
|
let param = fibonacci.get_param::<IntegerValue>(0).unwrap();
|
||||||
|
let cmp = f_main
|
||||||
let entry = function.block("entry");
|
.integer_compare(¶m, &int_32.from_unsigned(3), &IntPredicate::ULT, "cmp")
|
||||||
|
|
||||||
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();
|
.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();
|
done.ret(&int_32.from_unsigned(1)).unwrap();
|
||||||
let right = rhs.add(&call, &int_32.from_signed(30), "add").unwrap();
|
|
||||||
|
|
||||||
let final_block = function.block("final");
|
let minus_one = recurse
|
||||||
let phi = final_block
|
.sub(¶m, &int_32.from_unsigned(1), "minus_one")
|
||||||
.phi::<IntegerValue>(&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();
|
.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::<IntegerValue>(&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() {
|
match module.print_to_string() {
|
||||||
Ok(v) => println!("{}", v),
|
Ok(v) => println!("{}", v),
|
||||||
|
@ -204,6 +204,17 @@ impl<'ctx, ReturnValue: BasicValue<'ctx>> Function<'ctx, ReturnValue> {
|
|||||||
pub fn block<T: Into<String>>(&'ctx self, name: T) -> BasicBlock<'ctx, ReturnValue> {
|
pub fn block<T: Into<String>>(&'ctx self, name: T) -> BasicBlock<'ctx, ReturnValue> {
|
||||||
BasicBlock::in_function(&self, name.into())
|
BasicBlock::in_function(&self, name.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_param<T: BasicValue<'ctx>>(&'ctx self, nth: usize) -> Result<T, String> {
|
||||||
|
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>> {
|
pub struct BasicBlock<'ctx, ReturnValue: BasicValue<'ctx>> {
|
||||||
@ -238,8 +249,8 @@ impl<'ctx, ReturnValue: BasicValue<'ctx>> BasicBlock<'ctx, ReturnValue> {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn integer_compare<T: BasicValue<'ctx>>(
|
pub fn integer_compare<T: BasicValue<'ctx>>(
|
||||||
&self,
|
&self,
|
||||||
lhs: &'ctx T,
|
lhs: &T,
|
||||||
rhs: &'ctx T,
|
rhs: &T,
|
||||||
comparison: &IntPredicate,
|
comparison: &IntPredicate,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> Result<T, ()> {
|
) -> Result<T, ()> {
|
||||||
@ -304,6 +315,23 @@ impl<'ctx, ReturnValue: BasicValue<'ctx>> BasicBlock<'ctx, ReturnValue> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn sub<T: BasicValue<'ctx>>(&self, lhs: &T, rhs: &T, name: &str) -> Result<T, ()> {
|
||||||
|
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]
|
#[must_use]
|
||||||
pub fn phi<PhiValue: BasicValue<'ctx>>(
|
pub fn phi<PhiValue: BasicValue<'ctx>>(
|
||||||
&self,
|
&self,
|
||||||
|
@ -14,7 +14,7 @@ pub trait BasicType<'ctx> {
|
|||||||
where
|
where
|
||||||
Self: Sized;
|
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
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user