Misc changes
This commit is contained in:
parent
922afaa672
commit
54f25481f4
@ -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
|
||||
|
@ -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<T: IRType>(PhantomData<T>, IROpaqueValue);
|
||||
|
||||
impl<T: IRType> IRValue<T> {
|
||||
unsafe fn from_runtime(t: LLVMTypeRef, value: LLVMValueRef) -> IRValue<T> {
|
||||
IRValue(PhantomData, IROpaqueValue(t, value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IRType + Into<i64>> IRValue<T> {
|
||||
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<T: IRType> From<IRValue<T>> for IROpaqueValue {
|
||||
fn from(value: IRValue<T>) -> 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<IROpaqueValue, ()> {
|
||||
let IROpaqueValue(t1, lhs) = lhs;
|
||||
let IROpaqueValue(t2, rhs) = rhs;
|
||||
pub fn add(&self, lhs: OpaqueIRValue, rhs: OpaqueIRValue) -> Result<OpaqueIRValue, ()> {
|
||||
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<IRValue<bool>, ()> {
|
||||
let IROpaqueValue(t1, lhs) = lhs;
|
||||
let IROpaqueValue(t2, rhs) = rhs;
|
||||
pub fn less_than(&self, lhs: OpaqueIRValue, rhs: OpaqueIRValue) -> Result<IRValue<bool>, ()> {
|
||||
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);
|
||||
|
70
reid-llvm-lib/src/primitives.rs
Normal file
70
reid-llvm-lib/src/primitives.rs
Normal file
@ -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<T: IRType>(PhantomData<T>, pub(crate) OpaqueIRValue);
|
||||
|
||||
impl<T: IRType> IRValue<T> {
|
||||
pub(crate) unsafe fn from_runtime(t: LLVMTypeRef, value: LLVMValueRef) -> IRValue<T> {
|
||||
IRValue(PhantomData, OpaqueIRValue(t, value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IRType + Into<i64>> IRValue<T> {
|
||||
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<T: IRType> From<IRValue<T>> for OpaqueIRValue {
|
||||
fn from(value: IRValue<T>) -> Self {
|
||||
value.1
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user