# Copyright (C) 2018-2019 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. ``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
# 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.

class ARM64E
    # FIXME: This is fragile and needs to match the enum value in PtrTag.h.
    CFunctionPtrTag = 2
end

class Sequence
    def getModifiedListARM64E
        result = riscLowerMisplacedAddresses(@list)
        getModifiedListARM64(result)
    end
end

class Instruction
    def self.lowerMisplacedAddressesARM64E(node, newList)
        wasHandled = false
        if node.is_a? Instruction
            postInstructions = []
            annotation = node.annotation
            codeOrigin = node.codeOrigin
            case node.opcode
            when "jmp", "call"
                if node.operands.size > 1
                    if node.operands[1].is_a? RegisterID
                        tag = riscLowerOperandToRegister(node, newList, postInstructions, 1, "p", false)
                    else
                        tag = Tmp.new(codeOrigin, :gpr)
                        newList << Instruction.new(codeOrigin, "move", [node.operands[1], tag], annotation)
                    end
                    operands = [
                        riscLowerOperandToRegister(node, newList, postInstructions, 0, "p", false),
                        tag
                    ]
                    newList << node.cloneWithNewOperands(operands)
                    wasHandled = true
                end
            when "untagArrayPtr"
                newOperands = node.operands.map {
                    | operand |
                    if operand.address?
                        tmp = Tmp.new(codeOrigin, :gpr)
                        newList << Instruction.new(codeOrigin, "loadp", [operand, tmp], annotation)
                        tmp
                    else
                        operand
                    end
                }
                newList << node.cloneWithNewOperands(newOperands)
                wasHandled = true
            end
            newList += postInstructions if wasHandled
        end
        return wasHandled, newList
    end

    def lowerARM64E
        case opcode
        when "call"
            if operands.size == 1 or operands[0].label?
                lowerARM64
            elsif operands[1] == ARM64E::CFunctionPtrTag
                emitARM64Unflipped("blraaz", [operands[0]], :ptr)
            else
                emitARM64Unflipped("blrab", operands, :ptr)
            end
        when "jmp"
            if operands[0].label?
                lowerARM64
            else
                emitARM64Unflipped("brab", operands, :ptr)
            end
        when "tagReturnAddress"
            raise if operands.size < 1 or not operands[0].is_a? RegisterID
            if operands[0].is_a? RegisterID and operands[0].name == "sp"
                $asm.puts "pacibsp"
            else
                emitARM64Unflipped("pacib lr,", operands, :ptr)
            end
        when "untagReturnAddress"
            raise if operands.size < 1 or not operands[0].is_a? RegisterID
            if operands[0].is_a? RegisterID and operands[0].name == "sp"
                $asm.puts "autibsp"
            else
                emitARM64Unflipped("autib lr,", operands, :ptr)
            end
        when "removeCodePtrTag"
            raise unless operands[0].is_a? RegisterID
            emitARM64Unflipped("xpaci ", operands, :ptr)
        when "untagArrayPtr"
            raise if operands.size != 2 or not operands.each { |operand| operand.is_a? RegisterID or operand.is_a? Tmp }
            emitARM64("autdb ", operands, :ptr)
        when "ret"
            $asm.puts "retab"
        else
            lowerARM64
        end
    end
end
