mirror of
https://github.com/darlinghq/darling-JavaScriptCore.git
synced 2025-04-15 13:32:38 +00:00
118 lines
4.7 KiB
Ruby
118 lines
4.7 KiB
Ruby
# 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
|