diff --git a/libtest.sh b/libtest.sh index a820069..9150b17 100755 --- a/libtest.sh +++ b/libtest.sh @@ -10,7 +10,7 @@ cargo run --example libtest && \ # clang++ main.cpp hello.o -o main && \ ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 \ -o main /usr/lib/crt1.o hello.o -lc && \ -./main ; echo $? +./main ; echo "Return value: ""$?" ## Command from: clang -v hello.o -o test diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index c2c85e7..0aefe8e 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -1,5 +1,4 @@ use std::ffi::{CStr, CString}; -use std::marker::PhantomData; use std::ptr::null_mut; use llvm_sys::analysis::LLVMVerifyModule; @@ -14,55 +13,14 @@ use llvm_sys::target_machine::{ use llvm_sys::{ LLVMBasicBlock, LLVMBuilder, LLVMContext, LLVMModule, LLVMType, LLVMValue, core::*, prelude::*, }; +use primitives::IRType; use util::{ErrorMessageHolder, from_cstring, into_cstring}; +pub use primitives::{IRValue, OpaqueIRValue}; + +mod primitives; mod util; -pub trait IRType { - const SIGNED: LLVMBool; - unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef; -} - -impl IRType for bool { - const SIGNED: LLVMBool = 0; - unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef { - unsafe { LLVMInt1TypeInContext(context.context) } - } -} - -impl IRType for i32 { - const SIGNED: LLVMBool = 1; - unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef { - unsafe { LLVMInt32TypeInContext(context.context) } - } -} - -pub struct IROpaqueValue(LLVMTypeRef, LLVMValueRef); - -pub struct IRValue(PhantomData, IROpaqueValue); - -impl IRValue { - unsafe fn from_runtime(t: LLVMTypeRef, value: LLVMValueRef) -> IRValue { - IRValue(PhantomData, IROpaqueValue(t, value)) - } -} - -impl> IRValue { - pub fn from_const(context: &IRContext, value: T) -> Self { - unsafe { - let t = T::llvm_type(context); - let value = LLVMConstInt(t, value.into() as u64, T::SIGNED); - IRValue(PhantomData, IROpaqueValue(t, value)) - } - } -} - -impl From> for IROpaqueValue { - fn from(value: IRValue) -> Self { - value.1 - } -} - pub struct IRContext { context: *mut LLVMContext, builder: *mut LLVMBuilder, @@ -117,11 +75,7 @@ impl<'a> IRModule<'a> { let mut target: _ = null_mut(); let mut err = ErrorMessageHolder::null(); - LLVMGetTargetFromTriple( - c"x86_64-unknown-linux-gnu".as_ptr(), - &mut target, - err.borrow_mut(), - ); + LLVMGetTargetFromTriple(triple, &mut target, err.borrow_mut()); println!("{:?}, {:?}", from_cstring(triple), target); err.into_result().unwrap(); @@ -193,7 +147,7 @@ impl<'a> IRFunction<'a> { pub fn new(module: &'a IRModule<'a>, name: &String) -> IRFunction<'a> { unsafe { // TODO, fix later! - let return_type = LLVMInt32TypeInContext(module.context.context); + let return_type = LLVMInt8TypeInContext(module.context.context); let mut argts = []; let func_type = LLVMFunctionType(return_type, argts.as_mut_ptr(), argts.len() as u32, 0); @@ -234,7 +188,7 @@ impl<'a> IRBlock<'a> { } } - pub fn call(&self, function: &IRFunction) -> IROpaqueValue { + pub fn call(&self, function: &IRFunction) -> OpaqueIRValue { unsafe { let builder = self.context.builder; LLVMPositionBuilderAtEnd(builder, self.blockref); @@ -250,13 +204,13 @@ impl<'a> IRBlock<'a> { args.len() as u32, into_cstring(&function.name).as_ptr(), ); - IROpaqueValue(i32::llvm_type(&self.context), value) + OpaqueIRValue(i32::llvm_type(&self.context), value) } } - pub fn add(&self, lhs: IROpaqueValue, rhs: IROpaqueValue) -> Result { - let IROpaqueValue(t1, lhs) = lhs; - let IROpaqueValue(t2, rhs) = rhs; + pub fn add(&self, lhs: OpaqueIRValue, rhs: OpaqueIRValue) -> Result { + let OpaqueIRValue(t1, lhs) = lhs; + let OpaqueIRValue(t2, rhs) = rhs; if t1 != t2 { Err(()) } else { @@ -264,14 +218,14 @@ impl<'a> IRBlock<'a> { let builder = self.context.builder; LLVMPositionBuilderAtEnd(builder, self.blockref); let value = LLVMBuildAdd(builder, lhs, rhs, c"add".as_ptr()); - Ok(IROpaqueValue(t1, value)) + Ok(OpaqueIRValue(t1, value)) } } } - pub fn less_than(&self, lhs: IROpaqueValue, rhs: IROpaqueValue) -> Result, ()> { - let IROpaqueValue(t1, lhs) = lhs; - let IROpaqueValue(t2, rhs) = rhs; + pub fn less_than(&self, lhs: OpaqueIRValue, rhs: OpaqueIRValue) -> Result, ()> { + let OpaqueIRValue(t1, lhs) = lhs; + let OpaqueIRValue(t2, rhs) = rhs; if t1 != t2 { Err(()) @@ -307,7 +261,7 @@ impl<'a> IRBlock<'a> { } } - pub fn ret(self, function: &IRFunction, value: IROpaqueValue) { + pub fn ret(self, function: &IRFunction, value: OpaqueIRValue) { unsafe { let builder = self.context.builder; LLVMPositionBuilderAtEnd(builder, self.blockref); diff --git a/reid-llvm-lib/src/primitives.rs b/reid-llvm-lib/src/primitives.rs new file mode 100644 index 0000000..dfa1c41 --- /dev/null +++ b/reid-llvm-lib/src/primitives.rs @@ -0,0 +1,70 @@ +use std::marker::PhantomData; + +use llvm_sys::{ + core::{ + LLVMConstAdd, LLVMConstInt, LLVMInt1TypeInContext, LLVMInt8Type, LLVMInt8TypeInContext, + LLVMInt16TypeInContext, LLVMInt32TypeInContext, LLVMIntTypeInContext, + }, + prelude::{LLVMBool, LLVMTypeRef, LLVMValueRef}, +}; + +use crate::IRContext; + +pub trait IRType { + const SIGNED: LLVMBool; + unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef; +} + +impl IRType for bool { + const SIGNED: LLVMBool = 0; + unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef { + unsafe { LLVMInt1TypeInContext(context.context) } + } +} + +impl IRType for i32 { + const SIGNED: LLVMBool = 1; + unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef { + unsafe { LLVMInt8TypeInContext(context.context) } + } +} + +impl IRType for u32 { + const SIGNED: LLVMBool = 0; + unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef { + unsafe { LLVMInt32TypeInContext(context.context) } + } +} + +impl IRType for u16 { + const SIGNED: LLVMBool = 0; + unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef { + unsafe { LLVMInt16TypeInContext(context.context) } + } +} + +pub struct OpaqueIRValue(pub(crate) LLVMTypeRef, pub(crate) LLVMValueRef); + +pub struct IRValue(PhantomData, pub(crate) OpaqueIRValue); + +impl IRValue { + pub(crate) unsafe fn from_runtime(t: LLVMTypeRef, value: LLVMValueRef) -> IRValue { + IRValue(PhantomData, OpaqueIRValue(t, value)) + } +} + +impl> IRValue { + pub fn from_const(context: &IRContext, value: T) -> Self { + unsafe { + let t = T::llvm_type(context); + let value = LLVMConstInt(t, value.into() as u64, T::SIGNED); + IRValue(PhantomData, OpaqueIRValue(t, value)) + } + } +} + +impl From> for OpaqueIRValue { + fn from(value: IRValue) -> Self { + value.1 + } +}