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 && \
|
# clang++ main.cpp hello.o -o main && \
|
||||||
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
|
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
|
||||||
-o main /usr/lib/crt1.o hello.o -lc && \
|
-o main /usr/lib/crt1.o hello.o -lc && \
|
||||||
./main ; echo $?
|
./main ; echo "Return value: ""$?"
|
||||||
|
|
||||||
|
|
||||||
## Command from: clang -v hello.o -o test
|
## Command from: clang -v hello.o -o test
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::ptr::null_mut;
|
use std::ptr::null_mut;
|
||||||
|
|
||||||
use llvm_sys::analysis::LLVMVerifyModule;
|
use llvm_sys::analysis::LLVMVerifyModule;
|
||||||
@ -14,55 +13,14 @@ use llvm_sys::target_machine::{
|
|||||||
use llvm_sys::{
|
use llvm_sys::{
|
||||||
LLVMBasicBlock, LLVMBuilder, LLVMContext, LLVMModule, LLVMType, LLVMValue, core::*, prelude::*,
|
LLVMBasicBlock, LLVMBuilder, LLVMContext, LLVMModule, LLVMType, LLVMValue, core::*, prelude::*,
|
||||||
};
|
};
|
||||||
|
use primitives::IRType;
|
||||||
use util::{ErrorMessageHolder, from_cstring, into_cstring};
|
use util::{ErrorMessageHolder, from_cstring, into_cstring};
|
||||||
|
|
||||||
|
pub use primitives::{IRValue, OpaqueIRValue};
|
||||||
|
|
||||||
|
mod primitives;
|
||||||
mod util;
|
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 {
|
pub struct IRContext {
|
||||||
context: *mut LLVMContext,
|
context: *mut LLVMContext,
|
||||||
builder: *mut LLVMBuilder,
|
builder: *mut LLVMBuilder,
|
||||||
@ -117,11 +75,7 @@ impl<'a> IRModule<'a> {
|
|||||||
|
|
||||||
let mut target: _ = null_mut();
|
let mut target: _ = null_mut();
|
||||||
let mut err = ErrorMessageHolder::null();
|
let mut err = ErrorMessageHolder::null();
|
||||||
LLVMGetTargetFromTriple(
|
LLVMGetTargetFromTriple(triple, &mut target, err.borrow_mut());
|
||||||
c"x86_64-unknown-linux-gnu".as_ptr(),
|
|
||||||
&mut target,
|
|
||||||
err.borrow_mut(),
|
|
||||||
);
|
|
||||||
println!("{:?}, {:?}", from_cstring(triple), target);
|
println!("{:?}, {:?}", from_cstring(triple), target);
|
||||||
err.into_result().unwrap();
|
err.into_result().unwrap();
|
||||||
|
|
||||||
@ -193,7 +147,7 @@ impl<'a> IRFunction<'a> {
|
|||||||
pub fn new(module: &'a IRModule<'a>, name: &String) -> IRFunction<'a> {
|
pub fn new(module: &'a IRModule<'a>, name: &String) -> IRFunction<'a> {
|
||||||
unsafe {
|
unsafe {
|
||||||
// TODO, fix later!
|
// TODO, fix later!
|
||||||
let return_type = LLVMInt32TypeInContext(module.context.context);
|
let return_type = LLVMInt8TypeInContext(module.context.context);
|
||||||
let mut argts = [];
|
let mut argts = [];
|
||||||
let func_type =
|
let func_type =
|
||||||
LLVMFunctionType(return_type, argts.as_mut_ptr(), argts.len() as u32, 0);
|
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 {
|
unsafe {
|
||||||
let builder = self.context.builder;
|
let builder = self.context.builder;
|
||||||
LLVMPositionBuilderAtEnd(builder, self.blockref);
|
LLVMPositionBuilderAtEnd(builder, self.blockref);
|
||||||
@ -250,13 +204,13 @@ impl<'a> IRBlock<'a> {
|
|||||||
args.len() as u32,
|
args.len() as u32,
|
||||||
into_cstring(&function.name).as_ptr(),
|
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, ()> {
|
pub fn add(&self, lhs: OpaqueIRValue, rhs: OpaqueIRValue) -> Result<OpaqueIRValue, ()> {
|
||||||
let IROpaqueValue(t1, lhs) = lhs;
|
let OpaqueIRValue(t1, lhs) = lhs;
|
||||||
let IROpaqueValue(t2, rhs) = rhs;
|
let OpaqueIRValue(t2, rhs) = rhs;
|
||||||
if t1 != t2 {
|
if t1 != t2 {
|
||||||
Err(())
|
Err(())
|
||||||
} else {
|
} else {
|
||||||
@ -264,14 +218,14 @@ impl<'a> IRBlock<'a> {
|
|||||||
let builder = self.context.builder;
|
let builder = self.context.builder;
|
||||||
LLVMPositionBuilderAtEnd(builder, self.blockref);
|
LLVMPositionBuilderAtEnd(builder, self.blockref);
|
||||||
let value = LLVMBuildAdd(builder, lhs, rhs, c"add".as_ptr());
|
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>, ()> {
|
pub fn less_than(&self, lhs: OpaqueIRValue, rhs: OpaqueIRValue) -> Result<IRValue<bool>, ()> {
|
||||||
let IROpaqueValue(t1, lhs) = lhs;
|
let OpaqueIRValue(t1, lhs) = lhs;
|
||||||
let IROpaqueValue(t2, rhs) = rhs;
|
let OpaqueIRValue(t2, rhs) = rhs;
|
||||||
|
|
||||||
if t1 != t2 {
|
if t1 != t2 {
|
||||||
Err(())
|
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 {
|
unsafe {
|
||||||
let builder = self.context.builder;
|
let builder = self.context.builder;
|
||||||
LLVMPositionBuilderAtEnd(builder, self.blockref);
|
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