# Copyright (C) 2011-2020 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 "riscv64"
require "cloop"

begin
    require "arm64e"
rescue LoadError
end

BACKENDS =
    [
     "X86",
     "X86_WIN",
     "X86_64",
     "X86_64_WIN",
     "ARMv7",
     "ARM64",
     "ARM64E",
     "MIPS",
     "RISCV64",
     "C_LOOP",
     "C_LOOP_WIN"
    ]

# 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",
     "RISCV64",
     "C_LOOP",
     "C_LOOP_WIN"
    ]

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([KS]?)(.*)/) { | _ | 'ARMv7' + $1.downcase + $2 }
            backendName = "ARM64" if backendName == "ARM64_32"
        end
        backendName = "X86" if backendName == "I386"
        newBackendNames << backendName
        newBackendNames << "ARMv7" if backendName.start_with?("ARMv7")
    }
    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

