plessl-llvmruby 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +21 -0
- data/README +76 -0
- data/Rakefile +31 -0
- data/ext/extconf.rb +14 -0
- data/ext/llvm_basicblock.cpp +299 -0
- data/ext/llvm_function.cpp +48 -0
- data/ext/llvm_instruction.cpp +259 -0
- data/ext/llvm_module.cpp +189 -0
- data/ext/llvm_use.cpp +9 -0
- data/ext/llvm_user.cpp +71 -0
- data/ext/llvm_value.cpp +254 -0
- data/ext/llvmruby.c +328 -0
- data/ext/llvmruby.h +73 -0
- data/lib/llvm.rb +146 -0
- data/lib/ruby_vm.rb +352 -0
- data/lib/version.rb +11 -0
- data/test/byteswap.bc +0 -0
- data/test/test_basic.rb +340 -0
- data/test/test_basic_block.rb +80 -0
- data/test/test_instructions.rb +112 -0
- data/test/test_read_bitcode.rb +38 -0
- data/test/test_ruby_vm.rb +172 -0
- data/test/test_user.rb +72 -0
- data/test/test_value.rb +63 -0
- metadata +87 -0
data/lib/version.rb
ADDED
data/test/byteswap.bc
ADDED
Binary file
|
data/test/test_basic.rb
ADDED
@@ -0,0 +1,340 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
$:.unshift File.dirname(__FILE__) + "/../ext"
|
3
|
+
require 'llvm'
|
4
|
+
|
5
|
+
include LLVM
|
6
|
+
|
7
|
+
class BasicTests < Test::Unit::TestCase
|
8
|
+
def function_tester(expected)
|
9
|
+
m = LLVM::Module.new("test_module")
|
10
|
+
type = Type::function(MACHINE_WORD, [])
|
11
|
+
f = m.get_or_insert_function("test", type)
|
12
|
+
yield(f)
|
13
|
+
ExecutionEngine.get(m);
|
14
|
+
assert_equal(expected, ExecutionEngine.run_autoconvert(f))
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_module
|
18
|
+
function_tester(5) do |f|
|
19
|
+
b = f.create_block.builder
|
20
|
+
v = b.add(2.llvm, 3.llvm)
|
21
|
+
b.return(v)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def bin_op(op, v1, v2, expected)
|
26
|
+
function_tester(expected) do |f|
|
27
|
+
b = f.create_block.builder
|
28
|
+
ret = b.bin_op(op, v1.llvm, v2.llvm)
|
29
|
+
b.return(ret)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_bin_ops
|
34
|
+
bin_op(Instruction::Add, 2, 3, 5)
|
35
|
+
bin_op(Instruction::Sub, 5, 3, 2)
|
36
|
+
bin_op(Instruction::Mul, 2, 3, 6)
|
37
|
+
bin_op(Instruction::UDiv, 42, 6, 7)
|
38
|
+
bin_op(Instruction::SDiv, 42, 6, 7)
|
39
|
+
#bin_op(Instruction::FDiv, 23.0, 5, 0.23)
|
40
|
+
bin_op(Instruction::URem, 23, 5, 3)
|
41
|
+
bin_op(Instruction::SRem, 23, 5, 3)
|
42
|
+
#bin_op(Instruction::FRem, 23.0, 5, 0.23)
|
43
|
+
|
44
|
+
bin_op(Instruction::Shl, 2, 1, 4)
|
45
|
+
bin_op(Instruction::LShr, 8, 1, 4)
|
46
|
+
#bin_op(Instruction::AShr, 8, 1, 4)
|
47
|
+
bin_op(Instruction::And, 8, 15, 8)
|
48
|
+
bin_op(Instruction::Or, 8, 15, 15)
|
49
|
+
bin_op(Instruction::Xor, 8, 15, 7)
|
50
|
+
end
|
51
|
+
|
52
|
+
def builder_bin_op(op, v1, v2, expected)
|
53
|
+
function_tester(expected) do |f|
|
54
|
+
b = f.create_block.builder
|
55
|
+
ret = b.send(op, v1.llvm, v2.llvm)
|
56
|
+
b.return(ret)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_builder_bin_ops
|
61
|
+
builder_bin_op(:add, 23, 42, 65)
|
62
|
+
builder_bin_op(:sub, 69, 13, 56)
|
63
|
+
builder_bin_op(:mul, 23, 5, 115)
|
64
|
+
builder_bin_op(:udiv, 23, 5, 4)
|
65
|
+
builder_bin_op(:sdiv, 99, 33, 3)
|
66
|
+
#builder_bin_op(:fdiv, 23, 42, 65)
|
67
|
+
builder_bin_op(:urem, 23, 42, 23)
|
68
|
+
builder_bin_op(:srem, 77, 5, 2)
|
69
|
+
#builder_bin_op(:frem, 23, 42, 65)
|
70
|
+
builder_bin_op(:shl, 15, 1, 30)
|
71
|
+
builder_bin_op(:lshr, 32, 2, 8)
|
72
|
+
#builder_bin_op(:ashr, 23, 42, 65)
|
73
|
+
builder_bin_op(:and, 32, 37, 32)
|
74
|
+
builder_bin_op(:or, 15, 8, 15)
|
75
|
+
builder_bin_op(:xor, 33, 15, 46)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_insert_point
|
79
|
+
function_tester(2) do |f|
|
80
|
+
b1 = f.create_block
|
81
|
+
b2 = f.create_block
|
82
|
+
builder = b1.builder
|
83
|
+
builder.br(b2)
|
84
|
+
builder.set_insert_point(b2)
|
85
|
+
builder.return(2.llvm)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_builder_utils
|
90
|
+
function_tester(5) do |f|
|
91
|
+
b = f.create_block.builder
|
92
|
+
b.write do
|
93
|
+
ret = add(2.llvm, 3.llvm)
|
94
|
+
self.return(ret)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_cmps
|
100
|
+
m = LLVM::Module.new("test_cmps")
|
101
|
+
type = Type.function(MACHINE_WORD, [])
|
102
|
+
f = m.get_or_insert_function("sgt", type)
|
103
|
+
|
104
|
+
entry_block = f.create_block
|
105
|
+
exit_block_true = f.create_block
|
106
|
+
exit_block_false = f.create_block
|
107
|
+
|
108
|
+
b = entry_block.builder
|
109
|
+
cmp = b.icmp_sgt(-1.llvm, 1.llvm)
|
110
|
+
b.cond_br(cmp, exit_block_true, exit_block_false)
|
111
|
+
|
112
|
+
b = exit_block_true.builder
|
113
|
+
b.return(1.llvm)
|
114
|
+
|
115
|
+
b = exit_block_false.builder
|
116
|
+
b.return(0.llvm)
|
117
|
+
|
118
|
+
ExecutionEngine.get(m)
|
119
|
+
result = ExecutionEngine.run_autoconvert(f)
|
120
|
+
assert_equal(0, result)
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_fcmps
|
124
|
+
m = LLVM::Module.new('test_fcmps')
|
125
|
+
type = Type.function(MACHINE_WORD, [])
|
126
|
+
f = m.get_or_insert_function('ult', type)
|
127
|
+
|
128
|
+
entry_block = f.create_block
|
129
|
+
exit_block_true = f.create_block
|
130
|
+
exit_block_false = f.create_block
|
131
|
+
|
132
|
+
b = entry_block.builder
|
133
|
+
cmp = b.fcmp_ult(1.0.llvm, 2.0.llvm)
|
134
|
+
b.cond_br(cmp, exit_block_true, exit_block_false)
|
135
|
+
|
136
|
+
b = exit_block_true.builder
|
137
|
+
b.return(0.llvm)
|
138
|
+
|
139
|
+
b = exit_block_false.builder
|
140
|
+
b.return(1.llvm)
|
141
|
+
|
142
|
+
ExecutionEngine.get(m)
|
143
|
+
result = ExecutionEngine.run_autoconvert(f)
|
144
|
+
assert_equal(0, result)
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_function_calls
|
148
|
+
m = LLVM::Module.new('test_module')
|
149
|
+
type = Type::function(MACHINE_WORD, [])
|
150
|
+
f_caller = m.get_or_insert_function("caller", type)
|
151
|
+
type = Type::function(MACHINE_WORD, [MACHINE_WORD, MACHINE_WORD])
|
152
|
+
f_callee = m.get_or_insert_function("callee", type)
|
153
|
+
|
154
|
+
b = f_callee.create_block.builder
|
155
|
+
x, y = f_callee.arguments
|
156
|
+
sum = b.add(x, y)
|
157
|
+
b.return(sum)
|
158
|
+
|
159
|
+
b = f_caller.create_block.builder
|
160
|
+
ret = b.call(f_callee, 2.llvm, 3.llvm)
|
161
|
+
b.return(ret)
|
162
|
+
|
163
|
+
ExecutionEngine.get(m)
|
164
|
+
result = ExecutionEngine.run_autoconvert(f_caller)
|
165
|
+
assert_equal(5, result)
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_phi_node
|
169
|
+
m = LLVM::Module.new('test_module')
|
170
|
+
type = Type::function(MACHINE_WORD, [])
|
171
|
+
f = m.get_or_insert_function('phi_node', type)
|
172
|
+
|
173
|
+
entry_block = f.create_block
|
174
|
+
loop_block = f.create_block
|
175
|
+
exit_block = f.create_block
|
176
|
+
|
177
|
+
b = entry_block.builder
|
178
|
+
b.br(loop_block)
|
179
|
+
|
180
|
+
b = loop_block.builder
|
181
|
+
phi = b.phi(MACHINE_WORD)
|
182
|
+
phi.add_incoming(0.llvm, entry_block)
|
183
|
+
count = b.add(phi, 1.llvm)
|
184
|
+
phi.add_incoming(count, loop_block)
|
185
|
+
cmp = b.icmp_ult(count, 10.llvm)
|
186
|
+
b.cond_br(cmp, loop_block, exit_block)
|
187
|
+
|
188
|
+
b = exit_block.builder
|
189
|
+
b.return(phi)
|
190
|
+
|
191
|
+
ExecutionEngine.get(m)
|
192
|
+
result = ExecutionEngine.run_autoconvert(f)
|
193
|
+
assert_equal(9, result)
|
194
|
+
end
|
195
|
+
|
196
|
+
def test_bitcode_writer
|
197
|
+
m = LLVM::Module.new('static_module')
|
198
|
+
# create main function
|
199
|
+
type = Type.function(Type::Int32Ty, [
|
200
|
+
Type::Int32Ty,
|
201
|
+
Type.pointer(Type.pointer(Type::Int8Ty))
|
202
|
+
])
|
203
|
+
f = m.get_or_insert_function('main', type)
|
204
|
+
b = f.create_block.builder
|
205
|
+
b.return(666.llvm(Type::Int32Ty))
|
206
|
+
|
207
|
+
m.write_bitcode("test/static.o")
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_type_errors
|
211
|
+
m = LLVM::Module.new('type_errors')
|
212
|
+
ftype = Type.function(Type::Int32Ty, [])
|
213
|
+
assert_raise(TypeError) { f = LLVM::Module.new(5) }
|
214
|
+
assert_raise(TypeError) { m.get_or_insert_function(5, ftype) }
|
215
|
+
assert_raise(TypeError) { m.get_or_insert_function('bad_arg', 5) }
|
216
|
+
assert_raise(TypeError) { ExecutionEngine.get(5) }
|
217
|
+
assert_raise(TypeError) { m.external_function(5, ftype) }
|
218
|
+
assert_raise(TypeError) { m.external_function('fname', 5) }
|
219
|
+
assert_raise(TypeError) { m.write_bitcode(5) }
|
220
|
+
assert_raise(ArgumentError) { ExecutionEngine.run_function }
|
221
|
+
assert_raise(TypeError) { ExecutionEngine.run_function(5) }
|
222
|
+
assert_raise(TypeError) { ExecutionEngine.run_function(5, 5) }
|
223
|
+
|
224
|
+
f = m.get_or_insert_function('test', ftype)
|
225
|
+
block1 = f.create_block
|
226
|
+
block2 = f.create_block
|
227
|
+
b = block1.builder
|
228
|
+
assert_raise(TypeError) { b.set_insert_point(5) }
|
229
|
+
assert_raise(TypeError) { b.phi(5) }
|
230
|
+
phi = b.phi(Type::Int32Ty)
|
231
|
+
assert_raise(TypeError) { phi.add_incoming(5, 5) }
|
232
|
+
assert_raise(TypeError) { phi.add_incoming(5.llvm(Type::Int32Ty), 5) }
|
233
|
+
assert_raise(TypeError) { b.bin_op([], 2.llvm, 3.llvm) }
|
234
|
+
assert_raise(TypeError) { b.bin_op(Instruction::Add, 5, 3.llvm) }
|
235
|
+
assert_raise(TypeError) { b.bin_op(Instruction::Add, 3.llvm, 5) }
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_inspectors
|
239
|
+
m = LLVM::Module.new('example')
|
240
|
+
ftype = Type.function(Type::Int32Ty, [])
|
241
|
+
f = m.get_or_insert_function('inspect', ftype)
|
242
|
+
b = f.create_block.builder
|
243
|
+
b.return(5.llvm(Type::Int32Ty))
|
244
|
+
|
245
|
+
assert_match(/define i32 @inspect\(\)/, m.inspect)
|
246
|
+
assert_match(/define i32 @inspect\(\)/, f.inspect)
|
247
|
+
end
|
248
|
+
|
249
|
+
def test_global_strings
|
250
|
+
m = LLVM::Module.new('globalstrings')
|
251
|
+
ftype = Type.function(Type::Int32Ty, [])
|
252
|
+
f = m.get_or_insert_function('use_global_strings', ftype)
|
253
|
+
b = f.create_block.builder
|
254
|
+
v = b.create_global_string_ptr("SHAKA KHAN")
|
255
|
+
end
|
256
|
+
|
257
|
+
def test_var_arg_ftypes
|
258
|
+
ftype = Type.function(Type::Int32Ty, [], true)
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_struct_constants
|
262
|
+
int_t = Type::Int32Ty
|
263
|
+
struct_type = Type.struct([int_t, int_t, int_t])
|
264
|
+
struct_const = Value.get_struct_constant(struct_type, 2.llvm(int_t), 3.llvm(int_t), 5.llvm(int_t))
|
265
|
+
assert_kind_of(Value, struct_const)
|
266
|
+
|
267
|
+
m = LLVM::Module.new('globals')
|
268
|
+
gv = m.global_variable(struct_type, struct_const)
|
269
|
+
assert_kind_of(Value, gv)
|
270
|
+
end
|
271
|
+
|
272
|
+
def test_malloc_free
|
273
|
+
function_tester(23) do |f|
|
274
|
+
b = f.create_block.builder
|
275
|
+
new_space = b.malloc(MACHINE_WORD, 1)
|
276
|
+
assert_kind_of(AllocationInst, new_space)
|
277
|
+
assert(!new_space.array_allocation?)
|
278
|
+
assert_kind_of(Value, new_space.array_size)
|
279
|
+
assert_kind_of(Type, new_space.allocated_type)
|
280
|
+
assert_equal(0, new_space.alignment)
|
281
|
+
|
282
|
+
store_inst = b.store(23.llvm(MACHINE_WORD), new_space)
|
283
|
+
assert(store_inst.may_write_to_memory?)
|
284
|
+
v = b.load(new_space)
|
285
|
+
free_inst = b.free(new_space)
|
286
|
+
assert_kind_of(FreeInst, free_inst)
|
287
|
+
b.return(v)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def test_cast
|
292
|
+
function_tester(5) do |f|
|
293
|
+
b = f.create_block.builder
|
294
|
+
b.return(b.cast(Instruction::FPToSI, 5.0.llvm, MACHINE_WORD))
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
def test_switch
|
299
|
+
function_tester(23) do |f|
|
300
|
+
b = f.create_block.builder
|
301
|
+
default = f.create_block
|
302
|
+
on5 = f.create_block
|
303
|
+
switch = b.switch(5.llvm, default)
|
304
|
+
switch.add_case(5.llvm, on5)
|
305
|
+
assert_instance_of(SwitchInst, switch)
|
306
|
+
assert_equal(2, switch.get_num_cases);
|
307
|
+
|
308
|
+
b = default.builder
|
309
|
+
b.return(7.llvm(MACHINE_WORD))
|
310
|
+
|
311
|
+
b = on5.builder
|
312
|
+
b.return(23.llvm)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
def test_vector
|
317
|
+
function_tester(666) do |f|
|
318
|
+
b = f.create_block.builder
|
319
|
+
vt = Type.vector(MACHINE_WORD, 3)
|
320
|
+
vp = b.alloca(vt, 0)
|
321
|
+
v = b.load(vp)
|
322
|
+
v2 = b.insert_element(v, 666.llvm(MACHINE_WORD), 0.llvm(Type::Int32Ty))
|
323
|
+
r = b.extract_element(v2, 0.llvm(Type::Int32Ty))
|
324
|
+
b.return(r)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
def test_pass_manager_run
|
329
|
+
m = LLVM::Module.new('test')
|
330
|
+
assert PassManager.new.run(m)
|
331
|
+
end
|
332
|
+
|
333
|
+
def test_type_to_s
|
334
|
+
assert_equal "i32", 2.llvm.type.to_s
|
335
|
+
end
|
336
|
+
|
337
|
+
def test_type_type_id
|
338
|
+
assert_equal IntegerTyID, 2.llvm.type.type_id
|
339
|
+
end
|
340
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'llvm'
|
3
|
+
|
4
|
+
include LLVM
|
5
|
+
|
6
|
+
class BasicBlockTests < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
|
10
|
+
@assembly_gcd=<<-EOF
|
11
|
+
; ModuleID = 'gcd.o'
|
12
|
+
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
13
|
+
target triple = "i386-apple-darwin9"
|
14
|
+
|
15
|
+
define i32 @gcd(i32 %a, i32 %b) nounwind {
|
16
|
+
entry:
|
17
|
+
%tmp2 = icmp eq i32 %a, 0 ; <i1> [#uses=1]
|
18
|
+
br i1 %tmp2, label %bb26, label %bb19
|
19
|
+
|
20
|
+
bb5: ; preds = %bb19, %bb11
|
21
|
+
%indvar48 = phi i32 [ %indvar.next49, %bb11 ], [ 0, %bb19 ] ; <i32> [#uses=2]
|
22
|
+
%tmp50 = sub i32 0, %b_addr.0 ; <i32> [#uses=1]
|
23
|
+
%tmp51 = mul i32 %indvar48, %tmp50 ; <i32> [#uses=1]
|
24
|
+
%a_addr.0.reg2mem.0 = add i32 %tmp51, %a_addr.0 ; <i32> [#uses=3]
|
25
|
+
%tmp8 = icmp sgt i32 %a_addr.0.reg2mem.0, %b_addr.0 ; <i1> [#uses=1]
|
26
|
+
br i1 %tmp8, label %bb11, label %bb15.split
|
27
|
+
|
28
|
+
bb11: ; preds = %bb5
|
29
|
+
%indvar.next49 = add i32 %indvar48, 1 ; <i32> [#uses=1]
|
30
|
+
br label %bb5
|
31
|
+
|
32
|
+
bb15.split: ; preds = %bb5
|
33
|
+
%tmp18 = sub i32 %b_addr.0, %a_addr.0.reg2mem.0 ; <i32> [#uses=1]
|
34
|
+
br label %bb19
|
35
|
+
|
36
|
+
bb19: ; preds = %bb15.split, %entry
|
37
|
+
%b_addr.0 = phi i32 [ %tmp18, %bb15.split ], [ %b, %entry ] ; <i32> [#uses=4]
|
38
|
+
%a_addr.0 = phi i32 [ %a_addr.0.reg2mem.0, %bb15.split ], [ %a, %entry ] ; <i32> [#uses=2]
|
39
|
+
%tmp21 = icmp eq i32 %b_addr.0, 0 ; <i1> [#uses=1]
|
40
|
+
br i1 %tmp21, label %bb26, label %bb5
|
41
|
+
|
42
|
+
bb26: ; preds = %bb19, %entry
|
43
|
+
%tmp.0 = phi i32 [ %b, %entry ], [ %a_addr.0, %bb19 ] ; <i32> [#uses=1]
|
44
|
+
ret i32 %tmp.0
|
45
|
+
}
|
46
|
+
EOF
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def test_count_intructions_in_basic_block
|
52
|
+
m = LLVM::Module.read_assembly(@assembly_gcd)
|
53
|
+
gcd = m.get_function("gcd")
|
54
|
+
assert(gcd)
|
55
|
+
|
56
|
+
bbs = gcd.get_basic_block_list
|
57
|
+
expected = { 'entry' => 2, 'bb5' => 6, 'bb11' => 2, 'bb15.split' => 2, 'bb19' => 4, 'bb26' => 2 }
|
58
|
+
res = Hash.new
|
59
|
+
bbs.each { |b|
|
60
|
+
res[b.name] = b.size
|
61
|
+
}
|
62
|
+
assert_equal(expected,res)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_manipulate_values
|
66
|
+
m = LLVM::Module.read_assembly(@assembly_gcd)
|
67
|
+
gcd = m.get_function("gcd")
|
68
|
+
|
69
|
+
bbs = gcd.get_basic_block_list
|
70
|
+
bb = bbs.first
|
71
|
+
assert_equal('entry', bb.name)
|
72
|
+
bb.name = 'first_block'
|
73
|
+
assert_equal('first_block', bb.name)
|
74
|
+
assert_equal(3, bb.num_uses)
|
75
|
+
bb2 = bbs.find {|x| x.name == 'bb19'}
|
76
|
+
assert(bb.used_in_basic_block?(bb2))
|
77
|
+
bb3 = bbs.find {|x| x.name = 'bb26'}
|
78
|
+
assert(!bb.used_in_basic_block?(bb3))
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'llvm'
|
3
|
+
|
4
|
+
include LLVM
|
5
|
+
|
6
|
+
class InstructionTests < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
|
10
|
+
@assembly_byteswap=<<-EOF
|
11
|
+
; ModuleID = 'byteswap.bc'
|
12
|
+
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
|
13
|
+
target triple = "i386-apple-darwin9"
|
14
|
+
|
15
|
+
define i32 @bswap(i32 %x) nounwind {
|
16
|
+
entry:
|
17
|
+
%tmp3 = shl i32 %x, 24 ; <i32> [#uses=1]
|
18
|
+
%tmp5 = shl i32 %x, 8 ; <i32> [#uses=1]
|
19
|
+
%tmp6 = and i32 %tmp5, 16711680 ; <i32> [#uses=1]
|
20
|
+
%tmp9 = lshr i32 %x, 8 ; <i32> [#uses=1]
|
21
|
+
%tmp1018 = and i32 %tmp9, 65280 ; <i32> [#uses=1]
|
22
|
+
%tmp7 = or i32 %tmp1018, %tmp3 ; <i32> [#uses=1]
|
23
|
+
%tmp11 = or i32 %tmp7, %tmp6 ; <i32> [#uses=1]
|
24
|
+
ret i32 %tmp11
|
25
|
+
}
|
26
|
+
EOF
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_count_intructions_in_basic_block
|
31
|
+
m = LLVM::Module.read_assembly(@assembly_byteswap)
|
32
|
+
bswap = m.get_function("bswap")
|
33
|
+
assert(bswap)
|
34
|
+
|
35
|
+
bbs = bswap.get_basic_block_list
|
36
|
+
assert_equal(1,bbs.size)
|
37
|
+
b = bbs[0]
|
38
|
+
assert_equal(8,b.size)
|
39
|
+
|
40
|
+
expected_opcodes_in_bswap = ["shl", "shl", "and", "lshr", "and", "or", "or", "ret"]
|
41
|
+
ins = b.get_instruction_list
|
42
|
+
actual_opcodes_in_bswap = ins.map { |i| i.get_opcode_name}
|
43
|
+
assert_equal(expected_opcodes_in_bswap, actual_opcodes_in_bswap)
|
44
|
+
|
45
|
+
assert_kind_of(BinaryOperator, ins.first)
|
46
|
+
assert_kind_of(ReturnInst, ins.last)
|
47
|
+
|
48
|
+
f1, f2 = ins[0], ins[1]
|
49
|
+
assert(!f1.may_read_from_memory?)
|
50
|
+
assert(!f1.may_write_to_memory?)
|
51
|
+
assert(!f1.identical_to?(f2))
|
52
|
+
assert(f1.identical_to?(f1))
|
53
|
+
assert(f1.same_operation_as?(f2))
|
54
|
+
assert(f1.same_operation_as?(f1))
|
55
|
+
assert(!f1.used_outside_of_block?(b))
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_instruction_classes
|
59
|
+
#m = LLVM::Module.read_assembly(@assembly_byteswap)
|
60
|
+
#bswap = m.get_function('bswap')
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_branch_instructions
|
64
|
+
m = LLVM::Module.new('branch_instructions')
|
65
|
+
ExecutionEngine.get(m)
|
66
|
+
type = Type::function(MACHINE_WORD, [])
|
67
|
+
|
68
|
+
f = m.get_or_insert_function("test_br", type)
|
69
|
+
b1 = f.create_block
|
70
|
+
b2 = f.create_block
|
71
|
+
b3 = f.create_block
|
72
|
+
b4 = f.create_block
|
73
|
+
b5 = f.create_block
|
74
|
+
|
75
|
+
b = b1.builder
|
76
|
+
br_inst = b.br(b2)
|
77
|
+
|
78
|
+
b = b2.builder
|
79
|
+
cmp1 = b.icmp_sgt(-1.llvm, 1.llvm)
|
80
|
+
cmp2 = b.icmp_slt(-1.llvm, 1.llvm)
|
81
|
+
cond_br_inst = b.cond_br(cmp1, b3, b4)
|
82
|
+
|
83
|
+
b = b3.builder
|
84
|
+
b.return(23.llvm)
|
85
|
+
|
86
|
+
b = b4.builder
|
87
|
+
b.return(5.llvm)
|
88
|
+
|
89
|
+
b = b5.builder
|
90
|
+
ret_inst = b.return(1999.llvm)
|
91
|
+
|
92
|
+
assert_kind_of(BranchInst, br_inst)
|
93
|
+
assert(br_inst.unconditional?)
|
94
|
+
assert(!br_inst.conditional?)
|
95
|
+
assert_equal(1, br_inst.num_successors)
|
96
|
+
assert_kind_of(BasicBlock, br_inst.get_successor(0))
|
97
|
+
|
98
|
+
assert_kind_of(BranchInst, cond_br_inst)
|
99
|
+
assert(cond_br_inst.conditional?)
|
100
|
+
assert(!cond_br_inst.unconditional?)
|
101
|
+
assert_kind_of(Value, cond_br_inst.condition)
|
102
|
+
assert_equal(2, cond_br_inst.num_successors)
|
103
|
+
assert_kind_of(BasicBlock, cond_br_inst.get_successor(1))
|
104
|
+
|
105
|
+
assert_kind_of(ReturnInst, ret_inst)
|
106
|
+
assert_equal(0, ret_inst.num_successors)
|
107
|
+
|
108
|
+
cond_br_inst.condition = cmp2
|
109
|
+
cond_br_inst.set_successor(0, b5)
|
110
|
+
assert_equal(1999, ExecutionEngine.run_autoconvert(f))
|
111
|
+
end
|
112
|
+
end
|