1
1
use libc:: { c_char, c_uint} ;
2
- use ffi:: prelude:: { LLVMBuilderRef , LLVMValueRef } ;
2
+ use ffi:: prelude:: { LLVMBasicBlockRef , LLVMBuilderRef , LLVMValueRef } ;
3
3
use ffi:: { core, LLVMBuilder , LLVMRealPredicate , LLVMIntPredicate } ;
4
4
use cbox:: CSemiBox ;
5
5
use std:: marker:: PhantomData ;
@@ -11,6 +11,7 @@ use value::{Function, Value, Predicate};
11
11
12
12
static NULL_NAME : [ c_char ; 1 ] = [ 0 ] ;
13
13
14
+
14
15
/// This provides a uniform API for creating instructions and inserting them into a basic block.
15
16
pub struct Builder ( PhantomData < [ u8 ] > ) ;
16
17
native_ref ! ( & Builder = LLVMBuilderRef ) ;
@@ -50,6 +51,24 @@ impl Builder {
50
51
pub fn position_at_end ( & self , block : & BasicBlock ) {
51
52
unsafe { core:: LLVMPositionBuilderAtEnd ( self . into ( ) , block. into ( ) ) }
52
53
}
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
+ }
53
72
/// Build an instruction that returns from the function with void.
54
73
pub fn build_ret_void ( & self ) -> & Value {
55
74
unsafe { core:: LLVMBuildRetVoid ( self . into ( ) ) } . into ( )
@@ -73,6 +92,11 @@ impl Builder {
73
92
pub fn build_free ( & self , val : & Value ) -> & Value {
74
93
unsafe { core:: LLVMBuildFree ( self . into ( ) , val. into ( ) ) } . into ( )
75
94
}
95
+
96
+ /// Build an unreachable instruction
97
+ pub fn build_unreachable ( & self ) -> & Value {
98
+ unsafe { core:: LLVMBuildUnreachable ( self . into ( ) ) . into ( ) }
99
+ }
76
100
/// Build an instruction that store the value `val` in the pointer `ptr`.
77
101
pub fn build_store ( & self , val : & Value , ptr : & Value ) -> & Value {
78
102
unsafe { core:: LLVMBuildStore ( self . into ( ) , val. into ( ) , ptr. into ( ) ) } . into ( )
@@ -95,6 +119,16 @@ impl Builder {
95
119
call. into ( )
96
120
}
97
121
}
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
+
98
132
/// Build an instruction that calls the function `func` with the arguments `args`.
99
133
///
100
134
/// This will return the return value of the function.
@@ -121,10 +155,42 @@ impl Builder {
121
155
pub fn build_zext ( & self , value : & Value , dest : & Type ) -> & Value {
122
156
unsafe { core:: LLVMBuildZExtOrBitCast ( self . into ( ) , value. into ( ) , dest. into ( ) , NULL_NAME . as_ptr ( ) ) . into ( ) }
123
157
}
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
+
124
164
/// Build an instruction that truncates the high-order bits of value to fit into a certain type.
125
165
pub fn build_trunc ( & self , value : & Value , dest : & Type ) -> & Value {
126
166
unsafe { core:: LLVMBuildTrunc ( self . into ( ) , value. into ( ) , dest. into ( ) , NULL_NAME . as_ptr ( ) ) . into ( ) }
127
167
}
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
+
128
194
/// Build an instruction that inserts a value into an aggregate data value.
129
195
pub fn build_insert_value ( & self , agg : & Value , elem : & Value , index : usize ) -> & Value {
130
196
unsafe { core:: LLVMBuildInsertValue ( self . into ( ) , agg. into ( ) , elem. into ( ) , index as c_uint , NULL_NAME . as_ptr ( ) ) . into ( ) }
@@ -149,19 +215,26 @@ impl Builder {
149
215
switch. into ( )
150
216
}
151
217
}
218
+
152
219
un_op ! { build_load, LLVMBuildLoad }
153
220
un_op ! { build_neg, LLVMBuildNeg }
221
+ un_op ! { build_fneg, LLVMBuildFNeg }
154
222
un_op ! { build_not, LLVMBuildNot }
155
223
bin_op ! { build_add, LLVMBuildAdd , LLVMBuildFAdd }
156
224
bin_op ! { build_sub, LLVMBuildSub , LLVMBuildFSub }
157
225
bin_op ! { build_mul, LLVMBuildMul , LLVMBuildFMul }
158
226
bin_op ! { build_div, LLVMBuildSDiv , LLVMBuildFDiv }
227
+ bin_op ! { build_udiv, LLVMBuildUDiv }
228
+ bin_op ! { build_urem, LLVMBuildURem }
229
+ bin_op ! { build_srem, LLVMBuildSRem }
159
230
bin_op ! { build_shl, LLVMBuildShl }
160
231
bin_op ! { build_ashr, LLVMBuildAShr }
232
+ bin_op ! { build_lshr, LLVMBuildLShr }
161
233
bin_op ! { build_and, LLVMBuildAnd }
162
234
bin_op ! { build_or, LLVMBuildOr }
235
+ bin_op ! { build_xor, LLVMBuildXor }
163
236
/// 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 {
165
238
let ( at, bt) = ( a. get_type ( ) , b. get_type ( ) ) ;
166
239
assert_eq ! ( at, bt) ;
167
240
if at. is_integer ( ) {
@@ -188,4 +261,22 @@ impl Builder {
188
261
panic ! ( "expected numzextbers, got {:?}" , at)
189
262
}
190
263
}
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
+
191
282
}
0 commit comments