Skip to content

Commit 35ebeb0

Browse files
committed
Make changes relevent to the silverfish project
1 parent e123202 commit 35ebeb0

File tree

7 files changed

+126
-18
lines changed

7 files changed

+126
-18
lines changed

Cargo.lock

Lines changed: 16 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/builder.rs

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use libc::{c_char, c_uint};
2-
use ffi::prelude::{LLVMBuilderRef, LLVMValueRef};
2+
use ffi::prelude::{LLVMBasicBlockRef, LLVMBuilderRef, LLVMValueRef};
33
use ffi::{core, LLVMBuilder, LLVMRealPredicate, LLVMIntPredicate};
44
use cbox::CSemiBox;
55
use std::marker::PhantomData;
@@ -11,6 +11,7 @@ use value::{Function, Value, Predicate};
1111

1212
static NULL_NAME:[c_char; 1] = [0];
1313

14+
1415
/// This provides a uniform API for creating instructions and inserting them into a basic block.
1516
pub struct Builder(PhantomData<[u8]>);
1617
native_ref!(&Builder = LLVMBuilderRef);
@@ -50,6 +51,24 @@ impl Builder {
5051
pub fn position_at_end(&self, block: &BasicBlock) {
5152
unsafe { core::LLVMPositionBuilderAtEnd(self.into(), block.into()) }
5253
}
54+
/// Build a PHI instruction with no useful values
55+
pub fn build_phi(&self, incoming: Vec<(&BasicBlock, &Value)>) -> &Value{
56+
let count = incoming.len() as u32;
57+
assert!(count > 0);
58+
let ty = incoming[0].1.get_type();
59+
60+
let mut incoming_values: Vec<LLVMValueRef> = Vec::with_capacity(incoming.len());
61+
let mut incoming_blocks: Vec<LLVMBasicBlockRef> = Vec::with_capacity(incoming.len());
62+
for (bb, v) in incoming {
63+
incoming_values.push(v.into());
64+
incoming_blocks.push(bb.into());
65+
}
66+
unsafe {
67+
let phi = core::LLVMBuildPhi(self.into(), ty.into(), NULL_NAME.as_ptr());
68+
core::LLVMAddIncoming(phi, incoming_values.as_mut_ptr(), incoming_blocks.as_mut_ptr(), count);
69+
phi
70+
}.into()
71+
}
5372
/// Build an instruction that returns from the function with void.
5473
pub fn build_ret_void(&self) -> &Value {
5574
unsafe { core::LLVMBuildRetVoid(self.into()) }.into()
@@ -73,6 +92,11 @@ impl Builder {
7392
pub fn build_free(&self, val: &Value) -> &Value {
7493
unsafe { core::LLVMBuildFree(self.into(), val.into()) }.into()
7594
}
95+
96+
/// Build an unreachable instruction
97+
pub fn build_unreachable(&self) -> &Value {
98+
unsafe { core::LLVMBuildUnreachable(self.into()).into() }
99+
}
76100
/// Build an instruction that store the value `val` in the pointer `ptr`.
77101
pub fn build_store(&self, val: &Value, ptr: &Value) -> &Value {
78102
unsafe { core::LLVMBuildStore(self.into(), val.into(), ptr.into()) }.into()
@@ -95,6 +119,16 @@ impl Builder {
95119
call.into()
96120
}
97121
}
122+
123+
pub fn build_value_call(&self, func: &Value, args: &[&Value]) -> &Value {
124+
unsafe {
125+
let call = core::LLVMBuildCall(self.into(), func.into(), args.as_ptr() as *mut LLVMValueRef, args.len() as c_uint, NULL_NAME.as_ptr());
126+
core::LLVMSetTailCall(call, 0);
127+
call.into()
128+
}
129+
}
130+
131+
98132
/// Build an instruction that calls the function `func` with the arguments `args`.
99133
///
100134
/// This will return the return value of the function.
@@ -121,10 +155,42 @@ impl Builder {
121155
pub fn build_zext(&self, value: &Value, dest: &Type) -> &Value {
122156
unsafe { core::LLVMBuildZExtOrBitCast(self.into(), value.into(), dest.into(), NULL_NAME.as_ptr()).into() }
123157
}
158+
159+
/// Build an instruction that sign extends its operand to the type `dest`.
160+
pub fn build_sext(&self, value: &Value, dest: &Type) -> &Value {
161+
unsafe { core::LLVMBuildSExtOrBitCast(self.into(), value.into(), dest.into(), NULL_NAME.as_ptr()).into() }
162+
}
163+
124164
/// Build an instruction that truncates the high-order bits of value to fit into a certain type.
125165
pub fn build_trunc(&self, value: &Value, dest: &Type) -> &Value {
126166
unsafe { core::LLVMBuildTrunc(self.into(), value.into(), dest.into(), NULL_NAME.as_ptr()).into() }
127167
}
168+
/// Build an instruction that converts a floating point value to an signed int type
169+
pub fn build_fptosi(&self, value: &Value, dest: &Type) -> &Value {
170+
unsafe { core::LLVMBuildFPToSI(self.into(), value.into(), dest.into(), NULL_NAME.as_ptr()).into() }
171+
}
172+
/// Build an instruction that converts a floating point value to an unsigned int type
173+
pub fn build_fptoui(&self, value: &Value, dest: &Type) -> &Value {
174+
unsafe { core::LLVMBuildFPToUI(self.into(), value.into(), dest.into(), NULL_NAME.as_ptr()).into() }
175+
}
176+
/// Build an instruction that converts a signed int to an floating point type
177+
pub fn build_sitofp(&self, value: &Value, dest: &Type) -> &Value {
178+
unsafe { core::LLVMBuildSIToFP(self.into(), value.into(), dest.into(), NULL_NAME.as_ptr()).into() }
179+
}
180+
/// Build an instruction that converts a unsigned int to an floating point type
181+
pub fn build_uitofp(&self, value: &Value, dest: &Type) -> &Value {
182+
unsafe { core::LLVMBuildUIToFP(self.into(), value.into(), dest.into(), NULL_NAME.as_ptr()).into() }
183+
}
184+
185+
pub fn build_fpext(&self, value: &Value, dest: &Type) -> &Value {
186+
unsafe { core::LLVMBuildFPExt(self.into(), value.into(), dest.into(), NULL_NAME.as_ptr()).into() }
187+
}
188+
189+
pub fn build_fptrunc(&self, value: &Value, dest: &Type) -> &Value {
190+
unsafe { core::LLVMBuildFPTrunc(self.into(), value.into(), dest.into(), NULL_NAME.as_ptr()).into() }
191+
}
192+
193+
128194
/// Build an instruction that inserts a value into an aggregate data value.
129195
pub fn build_insert_value(&self, agg: &Value, elem: &Value, index: usize) -> &Value {
130196
unsafe { core::LLVMBuildInsertValue(self.into(), agg.into(), elem.into(), index as c_uint, NULL_NAME.as_ptr()).into() }
@@ -149,19 +215,26 @@ impl Builder {
149215
switch.into()
150216
}
151217
}
218+
152219
un_op!{build_load, LLVMBuildLoad}
153220
un_op!{build_neg, LLVMBuildNeg}
221+
un_op!{build_fneg, LLVMBuildFNeg}
154222
un_op!{build_not, LLVMBuildNot}
155223
bin_op!{build_add, LLVMBuildAdd, LLVMBuildFAdd}
156224
bin_op!{build_sub, LLVMBuildSub, LLVMBuildFSub}
157225
bin_op!{build_mul, LLVMBuildMul, LLVMBuildFMul}
158226
bin_op!{build_div, LLVMBuildSDiv, LLVMBuildFDiv}
227+
bin_op!{build_udiv, LLVMBuildUDiv}
228+
bin_op!{build_urem, LLVMBuildURem}
229+
bin_op!{build_srem, LLVMBuildSRem}
159230
bin_op!{build_shl, LLVMBuildShl}
160231
bin_op!{build_ashr, LLVMBuildAShr}
232+
bin_op!{build_lshr, LLVMBuildLShr}
161233
bin_op!{build_and, LLVMBuildAnd}
162234
bin_op!{build_or, LLVMBuildOr}
235+
bin_op!{build_xor, LLVMBuildXor}
163236
/// Build an instruction to compare the values `a` and `b` with the predicate / comparative operator `pred`.
164-
pub fn build_cmp(&self, a: &Value, b: &Value, pred: Predicate) -> &Value {
237+
pub fn build_signed_cmp(&self, a: &Value, b: &Value, pred: Predicate) -> &Value {
165238
let (at, bt) = (a.get_type(), b.get_type());
166239
assert_eq!(at, bt);
167240
if at.is_integer() {
@@ -188,4 +261,22 @@ impl Builder {
188261
panic!("expected numzextbers, got {:?}", at)
189262
}
190263
}
264+
265+
pub fn build_unsigned_cmp(&self, a: &Value, b: &Value, pred: Predicate) -> &Value {
266+
let (at, bt) = (a.get_type(), b.get_type());
267+
assert_eq!(at, bt);
268+
assert!(at.is_integer());
269+
270+
271+
let pred = match pred {
272+
Predicate::Equal => LLVMIntPredicate::LLVMIntEQ,
273+
Predicate::NotEqual => LLVMIntPredicate::LLVMIntNE,
274+
Predicate::GreaterThan => LLVMIntPredicate::LLVMIntUGT,
275+
Predicate::GreaterThanOrEqual => LLVMIntPredicate::LLVMIntUGE,
276+
Predicate::LessThan => LLVMIntPredicate::LLVMIntULT,
277+
Predicate::LessThanOrEqual => LLVMIntPredicate::LLVMIntULE
278+
};
279+
unsafe { core::LLVMBuildICmp(self.into(), pred, a.into(), b.into(), NULL_NAME.as_ptr()) }.into()
280+
}
281+
191282
}

src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
//!
44
//! The original LLVM reference is available [here](http://llvm.org/doxygen/)
55
//! but take note that this isn't as thorough as this documentation.
6+
#![cfg_attr(feature = "cargo-clippy", allow(clippy))]
67

7-
extern crate llvm_sys as ffi;
8+
pub extern crate llvm_sys as ffi;
89
extern crate libc;
910
extern crate cbox;
1011

@@ -31,7 +32,7 @@ pub use context::{Context, GetContext};
3132
pub use engine::{JitEngine, JitOptions, Interpreter, ExecutionEngine, GenericValue, GenericValueCast};
3233
pub use module::{AddressSpace, Module, Functions};
3334
pub use object::{ObjectFile, Symbol, Symbols};
34-
pub use target::{TargetData, Target};
35+
pub use target::{TargetData, Target, get_default_target_triple};
3536
pub use types::*;
3637
pub use value::{Alias, Arg, Attribute, Value, Function, GlobalValue, GlobalVariable, Linkage, Predicate};
3738
pub use util::Sub;

src/macros.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
#[macro_escape]
2-
macro_rules! build {
3-
($ctx:expr) => ()
4-
}
5-
61
macro_rules! native_ref(
72
(&$name:ident = $alias:ty) => (
83
impl Eq for $name {}

src/module.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ impl Module {
4242
let c_name = CString::new(name).unwrap();
4343
unsafe { CSemiBox::new(core::LLVMModuleCreateWithNameInContext(c_name.as_ptr(), context.into())) }
4444
}
45+
/// Dump the module to stderr (for debugging purposes)
46+
pub fn dump(&self) {
47+
unsafe {
48+
core::LLVMDumpModule(self.into());
49+
}
50+
}
4551
/// Add a global to the module with the given type and name.
4652
pub fn add_global<'a>(&'a self, name: &str, ty: &'a Type) -> &'a GlobalVariable {
4753
util::with_cstr(name, |ptr| unsafe {

src/target.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,10 @@ impl Target {
9393
unsafe { target_machine::LLVMTargetHasTargetMachine(self.into()) != 0 }
9494
}
9595
}
96+
97+
pub fn get_default_target_triple() -> &'static str{
98+
unsafe {
99+
let s = target_machine::LLVMGetDefaultTargetTriple();
100+
util::to_str(s)
101+
}
102+
}

src/value.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ impl Value {
7979
unsafe { core::LLVMTypeOf(self.into()) }.into()
8080
}
8181
}
82+
8283
/// Comparative operations on values.
8384
#[derive(Copy, Clone, Eq, PartialEq)]
8485
pub enum Predicate {

0 commit comments

Comments
 (0)