1
# Copyright (C) 2011 Apple Inc. All rights reserved.
3
# Redistribution and use in source and binary forms, with or without
4
# modification, are permitted provided that the following conditions
6
# 1. Redistributions of source code must retain the above copyright
7
# notice, this list of conditions and the following disclaimer.
8
# 2. Redistributions in binary form must reproduce the above copyright
9
# notice, this list of conditions and the following disclaimer in the
10
# documentation and/or other materials provided with the distribution.
12
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22
# THE POSSIBILITY OF SUCH DAMAGE.
28
# node.resolveSettings(settings)
30
# Construct a new AST that does not have any IfThenElse nodes by
31
# substituting concrete boolean values for each Setting.
35
def resolveSettings(settings)
38
child.resolveSettings(settings)
44
def resolveSettings(settings)
50
def resolveSettings(settings)
56
def resolveSettings(settings)
57
settings[@name].asNode
62
def resolveSettings(settings)
63
(@left.resolveSettings(settings).value and @right.resolveSettings(settings).value).asNode
68
def resolveSettings(settings)
69
(@left.resolveSettings(settings).value or @right.resolveSettings(settings).value).asNode
74
def resolveSettings(settings)
75
(not @child.resolveSettings(settings).value).asNode
80
def resolveSettings(settings)
81
if @predicate.resolveSettings(settings).value
82
@thenCase.resolveSettings(settings)
84
@elseCase.resolveSettings(settings)
90
def resolveSettings(settings)
94
item = item.resolveSettings(settings)
95
if item.is_a? Sequence
101
Sequence.new(codeOrigin, newList)
106
# node.demacroify(macros)
107
# node.substitute(mapping)
109
# demacroify() constructs a new AST that does not have any Macro
110
# nodes, while substitute() replaces Variable nodes with the given
111
# nodes in the mapping.
115
def demacroify(macros)
118
child.demacroify(macros)
122
def substitute(mapping)
125
child.substitute(mapping)
129
def substituteLabels(mapping)
132
child.substituteLabels(mapping)
138
def substitute(mapping)
142
unless @variables.include? key
143
myMapping[key] = value
148
child.substitute(myMapping)
154
def substitute(mapping)
164
def substituteLabels(mapping)
174
def substitute(constants)
176
myConstants = constants.dup
179
if item.is_a? ConstDecl
180
myConstants[item.variable] = item.value.substitute(myConstants)
182
newList << item.substitute(myConstants)
185
Sequence.new(codeOrigin, newList)
188
def renameLabels(comment)
193
if item.is_a? LocalLabel
194
mapping[item] = LocalLabel.unique(if comment then comment + "_" else "" end + item.cleanName)
198
substituteLabels(mapping)
201
def demacroify(macros)
202
myMacros = macros.dup
206
myMacros[item.name] = item
214
elsif item.is_a? MacroCall
216
myMyMacros = myMacros.dup
217
raise "Could not find macro #{item.name} at #{item.codeOriginString}" unless myMacros[item.name]
218
raise "Argument count mismatch for call to #{item.name} at #{item.codeOriginString}" unless item.operands.size == myMacros[item.name].variables.size
219
item.operands.size.times {
221
if item.operands[idx].is_a? Variable and myMacros[item.operands[idx].name]
222
myMyMacros[myMacros[item.name].variables[idx].name] = myMacros[item.operands[idx].name]
223
mapping[myMacros[item.name].variables[idx].name] = nil
224
elsif item.operands[idx].is_a? Macro
225
myMyMacros[myMacros[item.name].variables[idx].name] = item.operands[idx]
226
mapping[myMacros[item.name].variables[idx].name] = nil
228
myMyMacros[myMacros[item.name].variables[idx]] = nil
229
mapping[myMacros[item.name].variables[idx]] = item.operands[idx]
233
newList << Instruction.new(item.codeOrigin, "localAnnotation", [], item.annotation)
235
newList += myMacros[item.name].body.substitute(mapping).demacroify(myMyMacros).renameLabels(item.name).list
237
newList << item.demacroify(myMacros)
240
Sequence.new(codeOrigin, newList).substitute({})
245
# node.resolveOffsets(offsets, sizes)
247
# Construct a new AST that has offset values instead of symbolic
252
def resolveOffsets(offsets, sizes)
255
child.resolveOffsets(offsets, sizes)
261
def resolveOffsets(offsets, sizes)
263
Immediate.new(codeOrigin, offsets[self])
271
def resolveOffsets(offsets, sizes)
273
Immediate.new(codeOrigin, sizes[self])
275
puts "Could not find #{self.inspect} in #{sizes.keys.inspect}"
276
puts "sizes = #{sizes.inspect}"
285
# Resolve constant references and compute arithmetic expressions.
301
return self unless @left.is_a? Immediate
302
return self unless @right.is_a? Immediate
303
Immediate.new(codeOrigin, @left.value + @right.value)
311
return self unless @left.is_a? Immediate
312
return self unless @right.is_a? Immediate
313
Immediate.new(codeOrigin, @left.value - @right.value)
321
return self unless @left.is_a? Immediate
322
return self unless @right.is_a? Immediate
323
Immediate.new(codeOrigin, @left.value * @right.value)
330
return self unless @child.is_a? Immediate
331
Immediate.new(codeOrigin, -@child.value)
339
return self unless @left.is_a? Immediate
340
return self unless @right.is_a? Immediate
341
Immediate.new(codeOrigin, @left.value | @right.value)
349
return self unless @left.is_a? Immediate
350
return self unless @right.is_a? Immediate
351
Immediate.new(codeOrigin, @left.value & @right.value)
359
return self unless @left.is_a? Immediate
360
return self unless @right.is_a? Immediate
361
Immediate.new(codeOrigin, @left.value ^ @right.value)
365
class BitnotImmediate
368
return self unless @child.is_a? Immediate
369
Immediate.new(codeOrigin, ~@child.value)
374
# node.resolveAfterSettings(offsets, sizes)
376
# Compile assembly against a set of offsets.
380
def resolve(offsets, sizes)
381
demacroify({}).resolveOffsets(offsets, sizes).fold
388
# Checks that the node is ready for backend compilation.
393
raise "Unresolved #{dump} at #{codeOriginString}"
437
class AbsoluteAddress
469
class LocalLabelReference