carbon-core 0.1.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/.gitignore +13 -0
- data/.rspec +2 -0
- data/.rubocop.yml +38 -0
- data/.travis.yml +4 -0
- data/.yardopts +1 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +14 -0
- data/carbon.gemspec +30 -0
- data/lib/carbon.rb +54 -0
- data/lib/carbon/concrete.rb +43 -0
- data/lib/carbon/concrete/build.rb +63 -0
- data/lib/carbon/concrete/index.rb +324 -0
- data/lib/carbon/concrete/item.rb +37 -0
- data/lib/carbon/concrete/item/base.rb +153 -0
- data/lib/carbon/concrete/item/data.rb +22 -0
- data/lib/carbon/concrete/item/function.rb +97 -0
- data/lib/carbon/concrete/item/internal.rb +83 -0
- data/lib/carbon/concrete/item/struct.rb +65 -0
- data/lib/carbon/concrete/item/struct/element.rb +42 -0
- data/lib/carbon/concrete/item/trait.rb +72 -0
- data/lib/carbon/concrete/item/trait/expectation.rb +55 -0
- data/lib/carbon/concrete/request.rb +137 -0
- data/lib/carbon/concrete/type.rb +260 -0
- data/lib/carbon/concrete/type/function.rb +91 -0
- data/lib/carbon/concrete/type/generic.rb +118 -0
- data/lib/carbon/concrete/type/name.rb +147 -0
- data/lib/carbon/concrete/type/parse.rb +172 -0
- data/lib/carbon/concrete/type/part.rb +100 -0
- data/lib/carbon/core.rb +61 -0
- data/lib/carbon/core/int.rb +87 -0
- data/lib/carbon/core/integer.rb +109 -0
- data/lib/carbon/core/integer/cast.rb +83 -0
- data/lib/carbon/core/integer/math.rb +198 -0
- data/lib/carbon/core/integer/misc.rb +145 -0
- data/lib/carbon/core/integer/pole.rb +133 -0
- data/lib/carbon/core/integer/ship.rb +71 -0
- data/lib/carbon/core/integer/sign.rb +52 -0
- data/lib/carbon/core/integer/type.rb +42 -0
- data/lib/carbon/core/integer/zero.rb +52 -0
- data/lib/carbon/core/pointer.rb +54 -0
- data/lib/carbon/core/pointer/access.rb +123 -0
- data/lib/carbon/core/pointer/cast.rb +55 -0
- data/lib/carbon/core/pointer/math.rb +187 -0
- data/lib/carbon/core/pointer/memory.rb +85 -0
- data/lib/carbon/core/pointer/type.rb +23 -0
- data/lib/carbon/tacky.rb +21 -0
- data/lib/carbon/tacky/block.rb +96 -0
- data/lib/carbon/tacky/builder.rb +310 -0
- data/lib/carbon/tacky/context.rb +66 -0
- data/lib/carbon/tacky/function.rb +137 -0
- data/lib/carbon/tacky/instruction.rb +170 -0
- data/lib/carbon/tacky/parameter.rb +23 -0
- data/lib/carbon/tacky/reference.rb +23 -0
- data/lib/carbon/tacky/value.rb +40 -0
- data/lib/carbon/version.rb +9 -0
- metadata +186 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Carbon
|
5
|
+
module Core
|
6
|
+
module Pointer
|
7
|
+
# Defines the pointer type.
|
8
|
+
module Type
|
9
|
+
# Defines the pointer type, setting it to implement both
|
10
|
+
# `Carbon::Sized` and `Carbon::Numeric`.
|
11
|
+
#
|
12
|
+
# @return [void]
|
13
|
+
def define_pointer_type
|
14
|
+
Core.define(internal: PTYPE) do |internal|
|
15
|
+
internal[:kind] = :pointer
|
16
|
+
internal[:implements] << Carbon::Type("Carbon::Sized")
|
17
|
+
internal[:implements] << Carbon::Type("Carbon::Numeric")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/carbon/tacky.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "carbon/tacky/block"
|
5
|
+
require "carbon/tacky/builder"
|
6
|
+
require "carbon/tacky/context"
|
7
|
+
require "carbon/tacky/function"
|
8
|
+
require "carbon/tacky/value"
|
9
|
+
require "carbon/tacky/instruction"
|
10
|
+
require "carbon/tacky/parameter"
|
11
|
+
require "carbon/tacky/reference"
|
12
|
+
|
13
|
+
module Carbon
|
14
|
+
# Tacky is a IR implementation. It is a medium-level IR, just above LLVM IR
|
15
|
+
# and just below Carbon. It is here in order to easily serialize the
|
16
|
+
# results of compiling a Carbon file without loosing generic information,
|
17
|
+
# which is essential for building everything else. Tacky is meant to be
|
18
|
+
# easily serialized and deserialized, to allow libraries to be created.
|
19
|
+
module Tacky
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Carbon
|
5
|
+
module Tacky
|
6
|
+
# Defines a "block" in Tacky. This corresponds to LLVM's "basic block" for
|
7
|
+
# functions. This only contains a list of instructions and a name, and
|
8
|
+
# can be referenced by that name.
|
9
|
+
class Block
|
10
|
+
# A list of instructions that are executed by this block. This
|
11
|
+
# shoudln't be directly modified, and instead should be modified via
|
12
|
+
# {#build}.
|
13
|
+
#
|
14
|
+
# @return [<Tacky::Instruction>]
|
15
|
+
attr_reader :instructions
|
16
|
+
|
17
|
+
# The "name" of the block. This is used to make the resulting LLVM IR
|
18
|
+
# more legible.
|
19
|
+
#
|
20
|
+
# @return [::String]
|
21
|
+
attr_reader :name
|
22
|
+
|
23
|
+
# Temporarily used during building to store the mapping of instruction
|
24
|
+
# ids to their LLVM counterparts.
|
25
|
+
#
|
26
|
+
# @return [{::Numeric => ::LLVM::Value}]
|
27
|
+
attr_reader :mapping
|
28
|
+
|
29
|
+
# Initializes the block with the given name and instructions. If
|
30
|
+
# no name is given, it defaults to an empty string (`""`). Instructions
|
31
|
+
# should not be passed by initialization.
|
32
|
+
#
|
33
|
+
# @param function [Tacky::Function] The function this block is a part
|
34
|
+
# of.
|
35
|
+
# @param name [::String] The name of the block.
|
36
|
+
# @param instructions [<Tacky::Instruction>] This should not be used.
|
37
|
+
def initialize(function, name = "", instructions = [])
|
38
|
+
@function = function
|
39
|
+
@name = name
|
40
|
+
@instructions = instructions
|
41
|
+
end
|
42
|
+
|
43
|
+
# Increment the function's counter, returning the next valid instruction
|
44
|
+
# id.
|
45
|
+
#
|
46
|
+
# @return [::Numeric]
|
47
|
+
def next
|
48
|
+
@function.counter.increment
|
49
|
+
end
|
50
|
+
|
51
|
+
# Retrieves the dependencies that the block has. This is determined by
|
52
|
+
# asking any of the instructions if they have any dependencies, returning
|
53
|
+
# an empty set if all of them have none.
|
54
|
+
#
|
55
|
+
# @api private
|
56
|
+
# @see Function#dependencies
|
57
|
+
# @see Instruction#dependencies
|
58
|
+
# @return [Set<Concrete::Type>] The dependencies of the block.
|
59
|
+
def dependencies
|
60
|
+
@instructions.map(&:dependencies).inject(Set.new, :merge)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Builds the block with the given context. This iterates over all of
|
64
|
+
# the instructions, calling them, and storing the results in the function
|
65
|
+
# instruction table ({Tacky::Context#instructions}).
|
66
|
+
#
|
67
|
+
# @api private
|
68
|
+
# @see Instruction#call
|
69
|
+
# @see Context#instructions
|
70
|
+
# @param context [Tacky::Context] The context to build with.
|
71
|
+
# @return [void]
|
72
|
+
def call(context)
|
73
|
+
this = context.blocks.fetch(self)
|
74
|
+
|
75
|
+
@instructions.each do |inst|
|
76
|
+
context.instructions[inst.value] = inst.call(context, this)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Builds the block. If a block is given, it yields a {Tacky::Builder};
|
81
|
+
# otherwise, it returns one.
|
82
|
+
#
|
83
|
+
# @yield [builder] To build the block.
|
84
|
+
# @yieldparam builder [Tacky::Builder] The builder.
|
85
|
+
# @return [Tacky::Builder] If no block was given.
|
86
|
+
# @return [::Object] Otherwise.
|
87
|
+
def build
|
88
|
+
if block_given?
|
89
|
+
yield Tacky::Builder.new(self)
|
90
|
+
else
|
91
|
+
Tacky::Builder.new(self)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,310 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Carbon
|
5
|
+
module Tacky
|
6
|
+
# A "builder." This is used in order to create an instruction set for a
|
7
|
+
# block. The builder defines a set of methods that create and append
|
8
|
+
# an instruction to the parent block. Each instruction gets its own
|
9
|
+
# instruction ID relative to the parent block.
|
10
|
+
#
|
11
|
+
# @see http://llvm.org/releases/3.5.2/docs/LangRef.html The LLVM Language
|
12
|
+
# Reference Manual.
|
13
|
+
# @api semiprivate
|
14
|
+
class Builder
|
15
|
+
# Initialize the builder with the given block.
|
16
|
+
#
|
17
|
+
# @param block [Tacky::Block] The block to build onto.
|
18
|
+
def initialize(block)
|
19
|
+
@block = block
|
20
|
+
end
|
21
|
+
|
22
|
+
methods = ::LLVM::Builder.instance_methods - Object.instance_methods -
|
23
|
+
%i(dispose insert_block position position_at_end
|
24
|
+
position_before to_ptr)
|
25
|
+
|
26
|
+
# @!method add(left, right, name = "")
|
27
|
+
# Creates an `add` instruction.
|
28
|
+
# @return [Tacky::Reference]
|
29
|
+
# @!method aggregate_ret(*values)
|
30
|
+
# Creates a `ret` instruction.
|
31
|
+
# @return [Tacky::Reference]
|
32
|
+
# @!method alloca(type, name = "")
|
33
|
+
# Creates an `alloca` instruction.
|
34
|
+
# @return [Tacky::Reference]
|
35
|
+
# @!method and(left, right, name = "")
|
36
|
+
# Creates an `and` instruction.
|
37
|
+
# @return [Tacky::Reference]
|
38
|
+
# @!method array_alloca(type, size, name = "")
|
39
|
+
# Creates an `array_alloca` instruction.
|
40
|
+
# @return [Tacky::Reference]
|
41
|
+
# @!method ashr(left, right, name = "")
|
42
|
+
# Creates an `ashr` instruction.
|
43
|
+
# @return [Tacky::Reference]
|
44
|
+
# @!method bit_cast(value, type, name = "")
|
45
|
+
# Creates a `bitcast` instruction.
|
46
|
+
# @return [Tacky::Reference]
|
47
|
+
# @!method br(destination)
|
48
|
+
# Creates a `br` instruction.
|
49
|
+
# @return [Tacky::Reference]
|
50
|
+
# @!method call(function, *arguments)
|
51
|
+
# Creates a `call` instruction.
|
52
|
+
# @return [Tacky::Reference]
|
53
|
+
# @!method cond(iftrue, iffalse)
|
54
|
+
# Creates a `br` instruction.
|
55
|
+
# @return [Tacky::Reference]
|
56
|
+
# @!method exact_sdiv(left, right, name = "")
|
57
|
+
# Creates an `sdiv` instruction.
|
58
|
+
# @return [Tacky::Reference]
|
59
|
+
# @!method extract_element(vector, index, name = "")
|
60
|
+
# Creates an `extract_element` instruction.
|
61
|
+
# @return [Tacky::Reference]
|
62
|
+
# @!method extract_value(aggregate, index, name = "")
|
63
|
+
# Creates an `extract_value` instruction.
|
64
|
+
# @return [Tacky::Reference]
|
65
|
+
# @!method fadd(left, right, name = "")
|
66
|
+
# Creates an `fadd` instruction.
|
67
|
+
# @return [Tacky::Reference]
|
68
|
+
# @!method fcmp(pred, left, right, name = "")
|
69
|
+
# Creates an `fcmp` instruction.
|
70
|
+
# @return [Tacky::Reference]
|
71
|
+
# @!method fdiv(left, right, name = "")
|
72
|
+
# Creates an `fdiv` instruction.
|
73
|
+
# @return [Tacky::Reference]
|
74
|
+
# @!method fmul(left, right, name = "")
|
75
|
+
# Creates an `fmul` instruction.
|
76
|
+
# @return [Tacky::Reference]
|
77
|
+
# @!method fp2si(value, type, name = "")
|
78
|
+
# Creates a `fptosi` instruction.
|
79
|
+
# @return [Tacky::Reference]
|
80
|
+
# @!method fp2ui(value, type, name = "")
|
81
|
+
# Creates a `fptoui` instruction.
|
82
|
+
# @return [Tacky::Reference]
|
83
|
+
# @!method fp_cast(value, type, name = "")
|
84
|
+
# Creates a `bitcast` instruction.
|
85
|
+
# @return [Tacky::Reference]
|
86
|
+
# @!method fp_ext(value, type, name = "")
|
87
|
+
# Creates a `fpext` instruction.
|
88
|
+
# @return [Tacky::Reference]
|
89
|
+
# @!method fp_trunc(value, type, name = "")
|
90
|
+
# Creates a `fptrunc` instruction.
|
91
|
+
# @return [Tacky::Reference]
|
92
|
+
# @!method free(pointer)
|
93
|
+
# Creates a `free` instruction.
|
94
|
+
# @return [Tacky::Reference]
|
95
|
+
# @!method frem(left, right, name = "")
|
96
|
+
# Creates a `frem` instruction.
|
97
|
+
# @return [Tacky::Reference]
|
98
|
+
# @!method fsub(left, right, name = "")
|
99
|
+
# Creates a `fsub` instruction.
|
100
|
+
# @return [Tacky::Reference]
|
101
|
+
# @!method gep(value, indices, name = "")
|
102
|
+
# Creates a `gep` instruction.
|
103
|
+
# @return [Tacky::Reference]
|
104
|
+
# @!method global_string(string, name = "")
|
105
|
+
# Creates a `global_string` instruction.
|
106
|
+
# @return [Tacky::Reference]
|
107
|
+
# @!method global_string_pointer(string, name = "")
|
108
|
+
# Creates a `global_string_pointer` instruction.
|
109
|
+
# @return [Tacky::Reference]
|
110
|
+
# @!method ibr(addr, destinations)
|
111
|
+
# Creates a `ibr` instruction.
|
112
|
+
# @return [Tacky::Reference]
|
113
|
+
# @!method icmp(pred, left, right, name = "")
|
114
|
+
# Creates an `icmp` instruction.
|
115
|
+
# @return [Tacky::Reference]
|
116
|
+
# @!method inbounds_gep(value, indices, name = "")
|
117
|
+
# Creates an `gep` instruction.
|
118
|
+
# @return [Tacky::Reference]
|
119
|
+
# @!method insert_element(vector, value, index, name = "")
|
120
|
+
# Creates an `insert_element` instruction.
|
121
|
+
# @return [Tacky::Reference]
|
122
|
+
# @!method insert_value(aggregate, value, index, name = "")
|
123
|
+
# Creates an `insert_value` instruction.
|
124
|
+
# @return [Tacky::Reference]
|
125
|
+
# @!method int2ptr(value, type, name = "")
|
126
|
+
# Creates an `inttoptr` instruction.
|
127
|
+
# @return [Tacky::Reference]
|
128
|
+
# @!method int_cast(value, type, name = "")
|
129
|
+
# Creates an `bitcast` instruction.
|
130
|
+
# @return [Tacky::Reference]
|
131
|
+
# @!method invoke(function, params, normal, exception, name = "")
|
132
|
+
# Creates an `invoke` instruction.
|
133
|
+
# @return [Tacky::Reference]
|
134
|
+
# @!method is_not_null(value, name = "")
|
135
|
+
# Creates an `is_not_null` instruction.
|
136
|
+
# @return [Tacky::Reference]
|
137
|
+
# @!method is_null(value, name = "")
|
138
|
+
# Creates an `is_null` instruction.
|
139
|
+
# @return [Tacky::Reference]
|
140
|
+
# @!method load(pointer, name = "")
|
141
|
+
# Creates a `load` instruction.
|
142
|
+
# @return [Tacky::Reference]
|
143
|
+
# @!method lshr(left, right, name = "")
|
144
|
+
# Creates a `lshr` instruction.
|
145
|
+
# @return [Tacky::Reference]
|
146
|
+
# @!method malloc(type, name = "")
|
147
|
+
# Creates a `malloc` instruction.
|
148
|
+
# @return [Tacky::Reference]
|
149
|
+
# @!method mul(left, right, name = "")
|
150
|
+
# Creates a `mul` instruction.
|
151
|
+
# @return [Tacky::Reference]
|
152
|
+
# @!method neg(value, name = "")
|
153
|
+
# Creates a `sub` instruction.
|
154
|
+
# @return [Tacky::Reference]
|
155
|
+
# @!method not(value, name = "")
|
156
|
+
# Creates a `not` instruction.
|
157
|
+
# @return [Tacky::Reference]
|
158
|
+
# @!method nsw_add(left, right, name = "")
|
159
|
+
# Creates an `add` instruction.
|
160
|
+
# @return [Tacky::Reference]
|
161
|
+
# @!method nsw_mul(left, right, name = "")
|
162
|
+
# Creates a `mul` instruction.
|
163
|
+
# @return [Tacky::Reference]
|
164
|
+
# @!method nsw_neg(left, right, name = "")
|
165
|
+
# Creates a `sub` instruction.
|
166
|
+
# @return [Tacky::Reference]
|
167
|
+
# @!method nsw_sub(left, right, name = "")
|
168
|
+
# Creates a `sub` instruction.
|
169
|
+
# @return [Tacky::Reference]
|
170
|
+
# @!method nuw_add(left, right, name = "")
|
171
|
+
# Creates an `add` instruction.
|
172
|
+
# @return [Tacky::Reference]
|
173
|
+
# @!method nuw_mul(left, right, name = "")
|
174
|
+
# Creates a `mul` instruction.
|
175
|
+
# @return [Tacky::Reference]
|
176
|
+
# @!method nuw_neg(left, right, name = "")
|
177
|
+
# Creates a `sub` instruction.
|
178
|
+
# @return [Tacky::Reference]
|
179
|
+
# @!method nuw_sub(left, right, name = "")
|
180
|
+
# Creates a `sub` instruction.
|
181
|
+
# @return [Tacky::Reference]
|
182
|
+
# @!method or(left, right, name = "")
|
183
|
+
# Creates an `or` instruction.
|
184
|
+
# @return [Tacky::Reference]
|
185
|
+
# @!method phi(type, incoming, name = "")
|
186
|
+
# Creates a `phi` instruction.
|
187
|
+
# @return [Tacky::Reference]
|
188
|
+
# @!method pointer_cast(value, type, name = "")
|
189
|
+
# Creates a `bitcast` instruction.
|
190
|
+
# @return [Tacky::Reference]
|
191
|
+
# @!method ptr2int(value, type, name = "")
|
192
|
+
# Creates a `ptrtoint` instruction.
|
193
|
+
# @return [Tacky::Reference]
|
194
|
+
# @!method ptr_diff(left, right, name = "")
|
195
|
+
# Creates a `ptr_diff` instruction.
|
196
|
+
# @return [Tacky::Reference]
|
197
|
+
# @!method ret(value)
|
198
|
+
# Creates a `ret` instruction.
|
199
|
+
# @return [Tacky::Reference]
|
200
|
+
# @!method ret_void(value)
|
201
|
+
# Creates a `ret` instruction.
|
202
|
+
# @return [Tacky::Reference]
|
203
|
+
# @!method sdiv(left, right, name = "")
|
204
|
+
# Creates an `sdiv` instruction.
|
205
|
+
# @return [Tacky::Reference]
|
206
|
+
# @!method select(check, vtrue, vfalse, name = "")
|
207
|
+
# Creates a `select` instruction.
|
208
|
+
# @return [Tacky::Reference]
|
209
|
+
# @!method sext(value, type, name = "")
|
210
|
+
# Creates a `sext` instruction.
|
211
|
+
# @return [Tacky::Reference]
|
212
|
+
# @!method sext_or_bit_cast(value, type, name = "")
|
213
|
+
# Creates a `sext` or `bitcast` instruction, depending on the value
|
214
|
+
# and type.
|
215
|
+
# @return [Tacky::Reference]
|
216
|
+
# @!method shl(left, right, name = "")
|
217
|
+
# Creates a `shl` instruction.
|
218
|
+
# @return [Tacky::Reference]
|
219
|
+
# @!method shuffle_vector(vec1, vec2, mask, name = "")
|
220
|
+
# Creates a `shuffle_vector` instruction.
|
221
|
+
# @return [Tacky::Reference]
|
222
|
+
# @!method si2fp(value, type, name = "")
|
223
|
+
# Creates a `sitofp` instruction.
|
224
|
+
# @return [Tacky::Reference]
|
225
|
+
# @!method srem(left, right, name = "")
|
226
|
+
# Creates a `srem` instruction.
|
227
|
+
# @return [Tacky::Reference]
|
228
|
+
# @!method store(pointer, value)
|
229
|
+
# Creates a `store` instruction.
|
230
|
+
# @return [Tacky::Reference]
|
231
|
+
# @!method struct_gep(value, index, name = "")
|
232
|
+
# Creates a `gep` instruction.
|
233
|
+
# @return [Tacky::Reference]
|
234
|
+
# @!method sub(left, right, name = "")
|
235
|
+
# Creates a `sub` instruction.
|
236
|
+
# @return [Tacky::Reference]
|
237
|
+
# @!method switch(value, default, cases)
|
238
|
+
# Creates a `switch` instruction.
|
239
|
+
# @return [Tacky::Reference]
|
240
|
+
# @!method trunc(value, type, name = "")
|
241
|
+
# Creates a `trunc` instruction.
|
242
|
+
# @return [Tacky::Reference]
|
243
|
+
# @!method trunc_or_bit_cast(value, type, name = "")
|
244
|
+
# Creates a `trunc` or `bitcast` instruction based on the value and
|
245
|
+
# type.
|
246
|
+
# @return [Tacky::Reference]
|
247
|
+
# @!method udiv(left, right, name = "")
|
248
|
+
# Creates a `udiv` instruction.
|
249
|
+
# @return [Tacky::Reference]
|
250
|
+
# @!method ui2fp(value, type, name = "")
|
251
|
+
# Creates a `uitofp` instruction.
|
252
|
+
# @return [Tacky::Reference]
|
253
|
+
# @!method unreachable
|
254
|
+
# Creates an `unreachable` instruction.
|
255
|
+
# @return [Tacky::Reference]
|
256
|
+
# @!method unwind
|
257
|
+
# Creates an `unwind` instruction.
|
258
|
+
# @return [Tacky::Reference]
|
259
|
+
# @!method urem(left, right, name = "")
|
260
|
+
# Creates a `urem` instruction.
|
261
|
+
# @return [Tacky::Reference]
|
262
|
+
# @!method zext(value, type, name = "")
|
263
|
+
# Creates a `zext` instruction.
|
264
|
+
# @return [Tacky::Reference]
|
265
|
+
# @!method zext_or_bit_cast(value, type, name = "")
|
266
|
+
# Creates a `zext` or `bitcast` instruction based on the value and
|
267
|
+
# type.
|
268
|
+
# @return [Tacky::Reference]
|
269
|
+
methods.each { |m| define_method(m) { |*a| _call(m, *a) } }
|
270
|
+
|
271
|
+
# Returns the size of a type. This may be a constant value or a
|
272
|
+
# generated value.
|
273
|
+
#
|
274
|
+
# @param type [Concrete::Type] The type to find the size of.
|
275
|
+
# @return [Tacky::Reference] A value representing the return value of
|
276
|
+
# the instruction.
|
277
|
+
def sizeof(type)
|
278
|
+
_call(:_sizeof, type)
|
279
|
+
end
|
280
|
+
|
281
|
+
# Returns a null value of a given type. This may be a constant value or a
|
282
|
+
# generated value.
|
283
|
+
#
|
284
|
+
# @param type [Concrete::Type] The type to null.
|
285
|
+
# @return [Tacky::Reference] A value representing the return value of
|
286
|
+
# the instruction.
|
287
|
+
def null(type)
|
288
|
+
_call(:_null, type)
|
289
|
+
end
|
290
|
+
|
291
|
+
# Creates an instruction, and returns a reference to that instruction.
|
292
|
+
# The reference points to the instruction using the "instruction id,"
|
293
|
+
# which is essentially the instruction's place in the block.
|
294
|
+
#
|
295
|
+
# @api private
|
296
|
+
# @param inst [::Symbol, ::String] The instruction name.
|
297
|
+
# @param parameters [<Reference, Parameter, Value, Object>] The
|
298
|
+
# parameters that are being passed to the instruction.
|
299
|
+
# @param name [::String] The return value name of the instruction.
|
300
|
+
# @return [Tacky::Reference] The reference to the new instruction.
|
301
|
+
def _call(inst, *parameters, name: "")
|
302
|
+
id = @block.next
|
303
|
+
instruction = Tacky::Instruction.new(id, inst, parameters)
|
304
|
+
instruction.name = name
|
305
|
+
@block.instructions << instruction
|
306
|
+
Tacky::Reference.new(id)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|