blob: c6cc5ac16e123dc5e60692da4fa8445b281af9ba [file] [log] [blame]
# Copyright (C) 2011-2018 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
require "config"
require "arm"
require "arm64"
require "ast"
require "x86"
require "mips"
require "cloop"
begin
require "arm64e"
rescue LoadError
end
BACKENDS =
[
"X86",
"X86_WIN",
"X86_64",
"X86_64_WIN",
"ARMv7",
"ARM64",
"ARM64E",
"MIPS",
"C_LOOP"
]
# Keep the set of working backends separate from the set of backends that might be
# supported. This is great because the BACKENDS list is almost like a reserved
# words list, in that it causes settings resolution to treat those words specially.
# Hence this lets us set aside the name of a backend we might want to support in
# the future while not actually supporting the backend yet.
WORKING_BACKENDS =
[
"X86",
"X86_WIN",
"X86_64",
"X86_64_WIN",
"ARMv7",
"ARM64",
"ARM64E",
"MIPS",
"C_LOOP"
]
BACKEND_PATTERN = Regexp.new('\\A(' + BACKENDS.join(')|(') + ')\\Z')
$allBackends = {}
$validBackends = {}
BACKENDS.each {
| backend |
$validBackends[backend] = true
$allBackends[backend] = true
}
def canonicalizeBackendNames(backendNames)
newBackendNames = []
backendNames.each {
| backendName |
backendName = backendName.upcase
if backendName =~ /ARM.*/
backendName.sub!(/ARMV7(S?)(.*)/) { | _ | 'ARMv7' + $1.downcase + $2 }
backendName = "ARM64" if backendName == "ARM64_32"
end
backendName = "X86" if backendName == "I386"
newBackendNames << backendName
newBackendNames << "ARMv7" if backendName == "ARMv7s"
}
newBackendNames.uniq
end
def includeOnlyBackends(list)
newValidBackends = {}
list.each {
| backend |
if $validBackends[backend]
newValidBackends[backend] = true
end
}
$validBackends = newValidBackends
end
def isBackend?(backend)
$allBackends[backend]
end
def isValidBackend?(backend)
$validBackends[backend]
end
def validBackends
$validBackends.keys
end
class LoweringError < StandardError
attr_reader :originString
def initialize(e, originString)
super "#{e} (due to #{originString})"
@originString = originString
set_backtrace e.backtrace
end
end
class Node
def lower(name)
begin
$activeBackend = name
send("prepareToLower", name)
send("lower#{name}")
rescue => e
raise LoweringError.new(e, codeOriginString)
end
end
end
# Overrides for lower() for those nodes that are backend-agnostic
class Label
def lower(name)
$asm.debugAnnotation codeOrigin.debugDirective if $enableDebugAnnotations
$asm.putsLabel(self.name[1..-1], @global)
end
end
class LocalLabel
def lower(name)
$asm.putsLocalLabel "_offlineasm_#{self.name[1..-1]}"
end
end
class LabelReference
def asmLabel
if extern?
Assembler.externLabelReference(name[1..-1])
else
Assembler.labelReference(name[1..-1])
end
end
def cLabel
Assembler.cLabelReference(name[1..-1])
end
end
class LocalLabelReference
def asmLabel
Assembler.localLabelReference("_offlineasm_"+name[1..-1])
end
def cLabel
Assembler.cLocalLabelReference("_offlineasm_"+name[1..-1])
end
end
class Skip
def lower(name)
end
end
class Sequence
def lower(name)
$activeBackend = name
if respond_to? "getModifiedList#{name}"
newList = send("getModifiedList#{name}")
newList.each {
| node |
node.lower(name)
}
elsif respond_to? "lower#{name}"
send("lower#{name}")
else
@list.each {
| node |
node.lower(name)
}
end
end
end