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",
"ARM",
"ARMv7",
"ARMv7_TRADITIONAL",
"ARM64",
"ARM64E",
"MIPS",
"C_LOOP"
]
WORKING_BACKENDS =
[
"X86",
"X86_WIN",
"X86_64",
"X86_64_WIN",
"ARM",
"ARMv7",
"ARMv7_TRADITIONAL",
"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 }
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
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