| # 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 = riscAsRegister(newList, postInstructions, node.operands[1], "p", false) |
| else |
| tag = Tmp.new(codeOrigin, :gpr) |
| newList << Instruction.new(codeOrigin, "move", [node.operands[1], tag], annotation) |
| end |
| operands = [riscAsRegister(newList, postInstructions, node.operands[0], "p", false), tag] |
| newList << Instruction.new(codeOrigin, node.opcode, operands, annotation) |
| 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 << Instruction.new(codeOrigin, node.opcode, newOperands, annotation) |
| 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 |