ruby-llvm-next 10.0.0
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.
- checksums.yaml +7 -0
- data/LICENSE +30 -0
- data/README.md +67 -0
- data/ext/ruby-llvm-support/Rakefile +110 -0
- data/ext/ruby-llvm-support/support.cpp +32 -0
- data/lib/llvm.rb +29 -0
- data/lib/llvm/analysis.rb +49 -0
- data/lib/llvm/analysis_ffi.rb +77 -0
- data/lib/llvm/config.rb +10 -0
- data/lib/llvm/core.rb +97 -0
- data/lib/llvm/core/bitcode.rb +84 -0
- data/lib/llvm/core/bitcode_ffi.rb +132 -0
- data/lib/llvm/core/builder.rb +944 -0
- data/lib/llvm/core/context.rb +24 -0
- data/lib/llvm/core/module.rb +240 -0
- data/lib/llvm/core/pass_manager.rb +80 -0
- data/lib/llvm/core/type.rb +210 -0
- data/lib/llvm/core/value.rb +1005 -0
- data/lib/llvm/core_ffi.rb +6021 -0
- data/lib/llvm/execution_engine.rb +323 -0
- data/lib/llvm/execution_engine_ffi.rb +421 -0
- data/lib/llvm/linker.rb +16 -0
- data/lib/llvm/linker_ffi.rb +44 -0
- data/lib/llvm/support.rb +38 -0
- data/lib/llvm/target.rb +318 -0
- data/lib/llvm/target_ffi.rb +628 -0
- data/lib/llvm/transforms/builder.rb +107 -0
- data/lib/llvm/transforms/builder_ffi.rb +117 -0
- data/lib/llvm/transforms/ipo.rb +78 -0
- data/lib/llvm/transforms/ipo_ffi.rb +127 -0
- data/lib/llvm/transforms/scalar.rb +152 -0
- data/lib/llvm/transforms/scalar_ffi.rb +344 -0
- data/lib/llvm/transforms/vectorize.rb +22 -0
- data/lib/llvm/transforms/vectorize_ffi.rb +38 -0
- data/lib/llvm/version.rb +5 -0
- data/test/array_test.rb +38 -0
- data/test/basic_block_test.rb +87 -0
- data/test/binary_operations_test.rb +58 -0
- data/test/bitcode_test.rb +24 -0
- data/test/branch_test.rb +57 -0
- data/test/call_test.rb +82 -0
- data/test/comparisons_test.rb +66 -0
- data/test/conversions_test.rb +92 -0
- data/test/double_test.rb +34 -0
- data/test/equality_test.rb +89 -0
- data/test/function_test.rb +100 -0
- data/test/generic_value_test.rb +22 -0
- data/test/instruction_test.rb +30 -0
- data/test/ipo_test.rb +53 -0
- data/test/linker_test.rb +37 -0
- data/test/mcjit_test.rb +94 -0
- data/test/memory_access_test.rb +38 -0
- data/test/module_test.rb +93 -0
- data/test/parameter_collection_test.rb +28 -0
- data/test/pass_manager_builder_test.rb +53 -0
- data/test/phi_test.rb +33 -0
- data/test/select_test.rb +22 -0
- data/test/struct_test.rb +98 -0
- data/test/target_test.rb +113 -0
- data/test/test_helper.rb +62 -0
- data/test/type_test.rb +15 -0
- data/test/vector_test.rb +64 -0
- metadata +240 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class MemoryAccessTestCase < Minitest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_jit
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_memory_access
|
10
|
+
assert_equal 1 + 2, simple_memory_access_function(1, 2).to_i
|
11
|
+
assert_equal 3 + 4, array_memory_access_function(3, 4).to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def simple_memory_access_function(value1, value2)
|
15
|
+
run_function([LLVM::Int, LLVM::Int], [value1, value2], LLVM::Int) do |builder, function, *arguments|
|
16
|
+
entry = function.basic_blocks.append
|
17
|
+
builder.position_at_end(entry)
|
18
|
+
pointer1 = builder.alloca(LLVM::Int)
|
19
|
+
pointer2 = builder.alloca(LLVM::Int)
|
20
|
+
builder.store(arguments.first, pointer1)
|
21
|
+
builder.store(arguments.last, pointer2)
|
22
|
+
builder.ret(builder.add(builder.load(pointer1), builder.load(pointer2)))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def array_memory_access_function(value1, value2)
|
27
|
+
run_function([LLVM::Int, LLVM::Int], [value1, value2], LLVM::Int) do |builder, function, *arguments|
|
28
|
+
entry = function.basic_blocks.append
|
29
|
+
builder.position_at_end(entry)
|
30
|
+
pointer = builder.array_alloca(LLVM::Int, LLVM::Int(2))
|
31
|
+
builder.store(arguments.first, builder.gep(pointer, [LLVM::Int(0)]))
|
32
|
+
builder.store(arguments.last, builder.gep(pointer, [LLVM::Int(1)]))
|
33
|
+
builder.ret(builder.add(builder.load(builder.gep(pointer, [LLVM::Int(0)])),
|
34
|
+
builder.load(builder.gep(pointer, [LLVM::Int(1)]))))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/test/module_test.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "tempfile"
|
3
|
+
|
4
|
+
class ModuleTestCase < Minitest::Test
|
5
|
+
|
6
|
+
def setup
|
7
|
+
LLVM.init_jit
|
8
|
+
end
|
9
|
+
|
10
|
+
def simple_function
|
11
|
+
run_function([], [], LLVM::Int) do |builder, function, *arguments|
|
12
|
+
entry = function.basic_blocks.append
|
13
|
+
builder.position_at_end(entry)
|
14
|
+
builder.ret(LLVM::Int(1))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_simple_module
|
19
|
+
assert_equal 1, simple_function().to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_global_variable
|
23
|
+
yielded = false
|
24
|
+
|
25
|
+
define_module('test_globals_add') do |mod|
|
26
|
+
mod.globals.add(LLVM::Int32, 'i') do |var|
|
27
|
+
yielded = true
|
28
|
+
|
29
|
+
assert var.kind_of?(LLVM::GlobalVariable)
|
30
|
+
|
31
|
+
# unnamed_addr
|
32
|
+
assert !var.unnamed_addr?
|
33
|
+
var.unnamed_addr = true
|
34
|
+
assert var.unnamed_addr?
|
35
|
+
|
36
|
+
assert (var.dll_storage_class == :default)
|
37
|
+
var.dll_storage_class = :dll_import
|
38
|
+
assert (var.dll_storage_class == :dll_import)
|
39
|
+
|
40
|
+
# global_constant
|
41
|
+
assert !var.global_constant?
|
42
|
+
var.global_constant = true
|
43
|
+
assert var.global_constant?
|
44
|
+
|
45
|
+
assert_output("", "Warning: Passing Integer value to LLVM::GlobalValue#global_constant=(Boolean) is deprecated.\n") do
|
46
|
+
var.global_constant = 0
|
47
|
+
end
|
48
|
+
assert !var.global_constant?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
assert yielded, 'LLVM::Module::GlobalCollection#add takes block'
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_to_s
|
56
|
+
mod = LLVM::Module.new('test_print')
|
57
|
+
assert_equal mod.to_s,
|
58
|
+
"; ModuleID = 'test_print'\nsource_filename = \"test_print\"\n"
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_dump
|
62
|
+
mod = LLVM::Module.new('test_print')
|
63
|
+
expected_pattern = /^; ModuleID = 'test_print'$/
|
64
|
+
|
65
|
+
Tempfile.open('test_dump.1') do |tmpfile|
|
66
|
+
# debug stream (stderr)
|
67
|
+
stderr_old = $stderr.dup
|
68
|
+
$stderr.reopen(tmpfile.path, 'a')
|
69
|
+
begin
|
70
|
+
mod.dump
|
71
|
+
$stderr.flush
|
72
|
+
assert_match expected_pattern, File.read(tmpfile.path)
|
73
|
+
ensure
|
74
|
+
$stderr.reopen(stderr_old)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_module_properties
|
80
|
+
mod = LLVM::Module.new('mod')
|
81
|
+
|
82
|
+
assert_equal '', mod.triple
|
83
|
+
|
84
|
+
mod.triple = 'x86-linux-gnu'
|
85
|
+
assert_equal 'x86-linux-gnu', mod.triple
|
86
|
+
|
87
|
+
assert_equal '', mod.data_layout
|
88
|
+
|
89
|
+
mod.data_layout = 'e-p:32:32'
|
90
|
+
assert_equal 'e-p:32:32', mod.data_layout
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class ParameterCollectionTestCase < Minitest::Test
|
4
|
+
def setup
|
5
|
+
@mod = LLVM::Module.new('test')
|
6
|
+
@fun = @mod.functions.add('fun', [LLVM::Int, LLVM::Int], LLVM::Int)
|
7
|
+
@fun.params[0].name = 'foo'
|
8
|
+
@fun.params[1].name = 'bar'
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_positive_index_in_range
|
12
|
+
assert_equal 'foo', @fun.params[0].name
|
13
|
+
assert_equal 'bar', @fun.params[1].name
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_negative_index_in_range
|
17
|
+
assert_equal 'foo', @fun.params[-2].name
|
18
|
+
assert_equal 'bar', @fun.params[-1].name
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_positive_index_out_of_range
|
22
|
+
assert_nil @fun.params[2]
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_negative_index_out_of_range
|
26
|
+
assert_nil @fun.params[-3]
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'llvm/config'
|
3
|
+
require 'llvm/transforms/builder'
|
4
|
+
|
5
|
+
class PassManagerBuilderTest < Minitest::Test
|
6
|
+
def setup
|
7
|
+
LLVM.init_jit
|
8
|
+
@builder = LLVM::PassManagerBuilder.new
|
9
|
+
|
10
|
+
@pass_manager = LLVM::PassManager.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown
|
14
|
+
@builder.dispose
|
15
|
+
@pass_manager.dispose
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_init
|
19
|
+
assert_equal 0, @builder.size_level
|
20
|
+
assert_equal 0, @builder.opt_level
|
21
|
+
assert_equal false, @builder.unit_at_a_time
|
22
|
+
assert_equal false, @builder.unroll_loops
|
23
|
+
assert_equal false, @builder.simplify_lib_calls
|
24
|
+
assert_equal 0, @builder.inliner_threshold
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_opt_level
|
28
|
+
@builder.opt_level = 3
|
29
|
+
assert_equal 3, @builder.opt_level
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_build
|
33
|
+
@builder.build(@pass_manager)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_build_with_lto
|
37
|
+
assert_output('', '') do
|
38
|
+
@builder.build_with_lto(@pass_manager)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_build_with_lto_deprecated_internalize_param
|
43
|
+
assert_output("", "Warning: Passing Integer value to LLVM::PassManagerBuilder#build_with_lto is deprecated.\n") do
|
44
|
+
@builder.build_with_lto(@pass_manager, 0)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_build_with_lto_deprecated_run_inliner_param
|
49
|
+
assert_output("", "Warning: Passing Integer value to LLVM::PassManagerBuilder#build_with_lto is deprecated.\n") do
|
50
|
+
@builder.build_with_lto(@pass_manager, false, 0)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/test/phi_test.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class PhiTest < Minitest::Test
|
4
|
+
def setup
|
5
|
+
LLVM.init_jit
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_phi
|
9
|
+
assert_equal 1, run_phi_function(0).to_i
|
10
|
+
assert_equal 0, run_phi_function(1).to_i
|
11
|
+
end
|
12
|
+
|
13
|
+
def run_phi_function(argument)
|
14
|
+
run_function([LLVM::Int], argument, LLVM::Int) do |builder, function, *arguments|
|
15
|
+
entry = function.basic_blocks.append
|
16
|
+
block1 = function.basic_blocks.append
|
17
|
+
block2 = function.basic_blocks.append
|
18
|
+
exit = function.basic_blocks.append
|
19
|
+
builder.position_at_end(entry)
|
20
|
+
builder.cond(builder.icmp(:eq, arguments.first, LLVM::Int(0)), block1, block2)
|
21
|
+
builder.position_at_end(block1)
|
22
|
+
result1 = builder.add(arguments.first, LLVM::Int(1))
|
23
|
+
builder.br(exit)
|
24
|
+
builder.position_at_end(block2)
|
25
|
+
result2 = builder.sub(arguments.first, LLVM::Int(1))
|
26
|
+
builder.br(exit)
|
27
|
+
builder.position_at_end(exit)
|
28
|
+
builder.ret(builder.phi(LLVM::Int,
|
29
|
+
block1 => result1,
|
30
|
+
block2 => result2))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/test/select_test.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class SelectTestCase < Minitest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_jit
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_select
|
10
|
+
assert_equal 0, select_function(1).to_i
|
11
|
+
assert_equal 1, select_function(0).to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def select_function(value)
|
15
|
+
run_function([LLVM::Int1], [value], LLVM::Int) do |builder, function, *arguments|
|
16
|
+
entry = function.basic_blocks.append
|
17
|
+
builder.position_at_end(entry)
|
18
|
+
builder.ret(builder.select(arguments.first, LLVM::Int(0), LLVM::Int(1)))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/test/struct_test.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class StructTestCase < Minitest::Test
|
4
|
+
|
5
|
+
LLVM_UNPACKED = false
|
6
|
+
LLVM_PACKED = true
|
7
|
+
|
8
|
+
def setup
|
9
|
+
LLVM.init_jit
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_simple_struct
|
13
|
+
struct = LLVM::Struct(LLVM::Int, LLVM::Float)
|
14
|
+
assert_instance_of LLVM::StructType, struct
|
15
|
+
assert_equal 2, struct.element_types.size
|
16
|
+
assert_equal LLVM::Int.type, struct.element_types[0]
|
17
|
+
assert_equal LLVM::Float.type, struct.element_types[1]
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_named_struct
|
21
|
+
struct = LLVM::Struct(LLVM::Int, LLVM::Float, "struct100")
|
22
|
+
assert_instance_of LLVM::StructType, struct
|
23
|
+
assert_equal "struct100", struct.name
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_deferred_element_type_setting
|
27
|
+
struct = LLVM::Struct("struct200")
|
28
|
+
struct.element_types = [LLVM::Int, LLVM::Float]
|
29
|
+
assert_equal 2, struct.element_types.size
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_unpacked_constant_struct_from_size
|
33
|
+
struct = LLVM::ConstantStruct.const(2, LLVM_UNPACKED) { |i| LLVM::Int(i) }
|
34
|
+
assert_instance_of LLVM::ConstantStruct, struct
|
35
|
+
assert_equal 2, struct.operands.size
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_unpacked_constant_struct_from_struct
|
39
|
+
struct = LLVM::ConstantStruct.const([LLVM::Int(0), LLVM::Int(1)], LLVM_UNPACKED)
|
40
|
+
assert_instance_of LLVM::ConstantStruct, struct
|
41
|
+
assert_equal 2, struct.operands.size
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_packed_constant_struct_from_size
|
45
|
+
struct = LLVM::ConstantStruct.const(2, LLVM_PACKED) { |i| LLVM::Int(i) }
|
46
|
+
assert_instance_of LLVM::ConstantStruct, struct
|
47
|
+
assert_equal 2, struct.operands.size
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_packed_constant_struct_from_struct
|
51
|
+
struct = LLVM::ConstantStruct.const([LLVM::Int(0), LLVM::Int(1)], LLVM_PACKED)
|
52
|
+
assert_instance_of LLVM::ConstantStruct, struct
|
53
|
+
assert_equal 2, struct.operands.size
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_constant_named_struct
|
57
|
+
struct_ty = LLVM::Struct(LLVM::Int, "struct300")
|
58
|
+
struct = LLVM::ConstantStruct.named_const(struct_ty, [ LLVM::Int(1) ])
|
59
|
+
assert_instance_of LLVM::ConstantStruct, struct
|
60
|
+
assert_equal 1, struct.operands.size
|
61
|
+
assert_equal struct_ty, struct.type
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_struct_values
|
65
|
+
assert_equal 2 + 3, run_struct_values(2, 3).to_i
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_struct_access
|
69
|
+
assert_in_delta 2 + 3.3, run_struct_access(LLVM::Float, 2, 3.3).to_f, 0.001
|
70
|
+
end
|
71
|
+
|
72
|
+
def run_struct_values(value1, value2)
|
73
|
+
run_function([LLVM::Int, LLVM::Int], [value1, value2], LLVM::Int) do |builder, function, *arguments|
|
74
|
+
entry = function.basic_blocks.append
|
75
|
+
builder.position_at_end(entry)
|
76
|
+
pointer = builder.alloca(LLVM::Struct(LLVM::Int, LLVM::Int))
|
77
|
+
struct = builder.load(pointer)
|
78
|
+
struct = builder.insert_value(struct, arguments.first, 0)
|
79
|
+
struct = builder.insert_value(struct, arguments.last, 1)
|
80
|
+
builder.ret(builder.add(builder.extract_value(struct, 0),
|
81
|
+
builder.extract_value(struct, 1)))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def run_struct_access(return_type, value1, value2)
|
86
|
+
run_function([LLVM::Int, LLVM::Float], [value1, value2], return_type) do |builder, function, *arguments|
|
87
|
+
entry = function.basic_blocks.append
|
88
|
+
builder.position_at_end(entry)
|
89
|
+
pointer = builder.alloca(LLVM::Struct(LLVM::Float, LLVM::Struct(LLVM::Int, LLVM::Float), LLVM::Int))
|
90
|
+
builder.store(arguments.first, builder.gep(pointer, [LLVM::Int(0), LLVM::Int32.from_i(1), LLVM::Int32.from_i(0)]))
|
91
|
+
builder.store(arguments.last, builder.gep(pointer, [LLVM::Int(0), LLVM::Int32.from_i(1), LLVM::Int32.from_i(1)]))
|
92
|
+
address1 = builder.gep(pointer, [LLVM::Int(0), LLVM::Int32.from_i(1), LLVM::Int32.from_i(0)])
|
93
|
+
address2 = builder.gep(pointer, [LLVM::Int(0), LLVM::Int32.from_i(1), LLVM::Int32.from_i(1)])
|
94
|
+
builder.ret(builder.fadd(builder.ui2fp(builder.load(address1), LLVM::Float), builder.load(address2)))
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
data/test/target_test.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# encoding: ascii-8bit
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
require 'tempfile'
|
5
|
+
require 'llvm/version'
|
6
|
+
require 'llvm/config'
|
7
|
+
|
8
|
+
class TargetTestCase < Minitest::Test
|
9
|
+
|
10
|
+
def setup
|
11
|
+
LLVM::Target.init('X86', true)
|
12
|
+
|
13
|
+
@x86 = LLVM::Target.by_name('x86')
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_init_native
|
17
|
+
LLVM::Target.init_native
|
18
|
+
LLVM::Target.init_native(true)
|
19
|
+
end
|
20
|
+
|
21
|
+
if LLVM::CONFIG::TARGETS_BUILT.include?('ARM')
|
22
|
+
def test_init_arm
|
23
|
+
LLVM::Target.init('ARM')
|
24
|
+
LLVM::Target.init('ARM', true)
|
25
|
+
|
26
|
+
arm_target = LLVM::Target.by_name('arm')
|
27
|
+
assert_equal 'arm', arm_target.name
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_init_all
|
32
|
+
LLVM::Target.init_all
|
33
|
+
LLVM::Target.init_all(true)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_each
|
37
|
+
targets = LLVM::Target.each
|
38
|
+
|
39
|
+
assert_instance_of Enumerator, targets
|
40
|
+
assert targets.count > 0
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_target
|
44
|
+
assert_equal 'x86', @x86.name
|
45
|
+
assert_equal "32-bit X86: Pentium-Pro and above", @x86.description
|
46
|
+
assert_equal true, @x86.jit?
|
47
|
+
assert_equal true, @x86.target_machine?
|
48
|
+
assert_equal true, @x86.asm_backend?
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_target_machine
|
52
|
+
@x86 = LLVM::Target.by_name('x86')
|
53
|
+
mach = @x86.create_machine('x86-linux-gnu', 'i686')
|
54
|
+
|
55
|
+
assert_equal @x86, mach.target
|
56
|
+
assert_equal 'x86-linux-gnu', mach.triple
|
57
|
+
assert_equal 'i686', mach.cpu
|
58
|
+
assert_equal '', mach.features
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_emit
|
62
|
+
mach = @x86.create_machine('x86-linux-gnu')
|
63
|
+
|
64
|
+
mod = define_module('test') do |mod|
|
65
|
+
define_function(mod, 'main', [], LLVM::Int) do |builder, fun|
|
66
|
+
entry = fun.basic_blocks.append
|
67
|
+
builder.position_at_end(entry)
|
68
|
+
builder.ret(LLVM::Int(0))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
Tempfile.open('emit') do |tmp|
|
73
|
+
mach.emit(mod, tmp.path)
|
74
|
+
assert_match(/xorl\t%eax, %eax/, tmp.read)
|
75
|
+
end
|
76
|
+
|
77
|
+
Tempfile.open('emit') do |tmp|
|
78
|
+
mach.emit(mod, tmp.path, :object)
|
79
|
+
assert_match(/\x66\x31\xc0/, File.read(tmp.path, mode: 'rb'))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_data_layout
|
84
|
+
layout_be = LLVM::TargetDataLayout.new('E')
|
85
|
+
assert_equal :big_endian, layout_be.byte_order
|
86
|
+
|
87
|
+
desc = "e-p:32:32:32-S0-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f16:16:16-f32:32:32-f64:64:64-f128:128:128-v64:64:64-v128:128:128-a0:0:64"
|
88
|
+
layout = LLVM::TargetDataLayout.new(desc)
|
89
|
+
|
90
|
+
assert_equal desc, layout.to_s
|
91
|
+
assert_equal :little_endian, layout.byte_order
|
92
|
+
assert_equal 4, layout.pointer_size
|
93
|
+
assert_equal 4, layout.pointer_size(0)
|
94
|
+
assert_equal LLVM::Int32.type, layout.int_ptr_type
|
95
|
+
assert_equal LLVM::Int32.type, layout.int_ptr_type(0)
|
96
|
+
|
97
|
+
assert_equal 19, layout.bit_size_of(LLVM::Int19.type)
|
98
|
+
assert_equal 3, layout.storage_size_of(LLVM::Int19.type)
|
99
|
+
assert_equal 4, layout.abi_size_of(LLVM::Int19.type)
|
100
|
+
assert_equal 4, layout.abi_alignment_of(LLVM::Int19.type)
|
101
|
+
assert_equal 4, layout.call_frame_alignment_of(LLVM::Int19.type)
|
102
|
+
assert_equal 4, layout.preferred_alignment_of(LLVM::Int19.type)
|
103
|
+
|
104
|
+
struct = LLVM.Struct(LLVM::Int8, LLVM::Int32)
|
105
|
+
|
106
|
+
assert_equal 0, layout.offset_of_element(struct, 0)
|
107
|
+
assert_equal 4, layout.offset_of_element(struct, 1)
|
108
|
+
|
109
|
+
assert_equal 0, layout.element_at_offset(struct, 0)
|
110
|
+
assert_equal 0, layout.element_at_offset(struct, 3)
|
111
|
+
assert_equal 1, layout.element_at_offset(struct, 4)
|
112
|
+
end
|
113
|
+
end
|