X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/2d39b0e377c0896910ee49ae70082ba665faf986..refs/heads/master:/offlineasm/arm64.rb diff --git a/offlineasm/arm64.rb b/offlineasm/arm64.rb index 76d3dcc..3a0d786 100644 --- a/offlineasm/arm64.rb +++ b/offlineasm/arm64.rb @@ -1,4 +1,5 @@ # Copyright (C) 2011, 2012, 2014 Apple Inc. All rights reserved. +# Copyright (C) 2014 University of Szeged. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -197,6 +198,64 @@ end # Actual lowering code follows. # +def arm64LowerMalformedLoadStoreAddresses(list) + newList = [] + + def isAddressMalformed(operand) + operand.is_a? Address and not (-255..4095).include? operand.offset.value + end + + list.each { + | node | + if node.is_a? Instruction + if node.opcode =~ /^store/ and isAddressMalformed(node.operands[1]) + address = node.operands[1] + tmp = Tmp.new(codeOrigin, :gpr) + newList << Instruction.new(node.codeOrigin, "move", [address.offset, tmp]) + newList << Instruction.new(node.codeOrigin, node.opcode, [node.operands[0], BaseIndex.new(node.codeOrigin, address.base, tmp, 1, Immediate.new(codeOrigin, 0))], node.annotation) + elsif node.opcode =~ /^load/ and isAddressMalformed(node.operands[0]) + address = node.operands[0] + tmp = Tmp.new(codeOrigin, :gpr) + newList << Instruction.new(node.codeOrigin, "move", [address.offset, tmp]) + newList << Instruction.new(node.codeOrigin, node.opcode, [BaseIndex.new(node.codeOrigin, address.base, tmp, 1, Immediate.new(codeOrigin, 0)), node.operands[1]], node.annotation) + else + newList << node + end + else + newList << node + end + } + newList +end + +# Workaround for Cortex-A53 erratum (835769) +def arm64CortexA53Fix835769(list) + newList = [] + lastOpcodeUnsafe = false + + list.each { + | node | + if node.is_a? Instruction + case node.opcode + when /^store/, /^load/ + # List all macro instructions that can be lowered to a load, store or prefetch ARM64 assembly instruction + lastOpcodeUnsafe = true + when "muli", "mulp", "mulq", "smulli" + # List all macro instructions that can be lowered to a 64-bit multiply-accumulate ARM64 assembly instruction + # (defined as one of MADD, MSUB, SMADDL, SMSUBL, UMADDL or UMSUBL). + if lastOpcodeUnsafe + newList << Instruction.new(node.codeOrigin, "nopCortexA53Fix835769", []) + end + lastOpcodeUnsafe = false + else + lastOpcodeUnsafe = false + end + end + newList << node + } + newList +end + class Sequence def getModifiedListARM64 result = @list @@ -204,6 +263,7 @@ class Sequence result = riscLowerSimpleBranchOps(result) result = riscLowerHardBranchOps64(result) result = riscLowerShiftOps(result) + result = arm64LowerMalformedLoadStoreAddresses(result) result = riscLowerMalformedAddresses(result) { | node, address | case node.opcode @@ -252,6 +312,7 @@ class Sequence result = riscLowerTest(result) result = assignRegistersToTemporaries(result, :gpr, ARM64_EXTRA_GPRS) result = assignRegistersToTemporaries(result, :fpr, ARM64_EXTRA_FPRS) + result = arm64CortexA53Fix835769(result) return result end end @@ -369,7 +430,7 @@ def emitARM64MoveImmediate(value, target) [48, 32, 16, 0].each { | shift | currentValue = (value >> shift) & 0xffff - next if currentValue == (isNegative ? 0xffff : 0) and shift != 0 + next if currentValue == (isNegative ? 0xffff : 0) and (shift != 0 or !first) if first if isNegative $asm.puts "movn #{target.arm64Operand(:ptr)}, \##{(~currentValue) & 0xffff}, lsl \##{shift}" @@ -586,22 +647,6 @@ class Instruction | ops | $asm.puts "stp #{ops[0].arm64Operand(:ptr)}, #{ops[1].arm64Operand(:ptr)}, [sp, #-16]!" } - when "popLRAndFP" - $asm.puts "ldp x29, x30, [sp], #16" - when "pushLRAndFP" - $asm.puts "stp x29, x30, [sp, #-16]!" - when "popCalleeSaves" - $asm.puts "ldp x28, x27, [sp], #16" - $asm.puts "ldp x26, x25, [sp], #16" - $asm.puts "ldp x24, x23, [sp], #16" - $asm.puts "ldp x22, x21, [sp], #16" - $asm.puts "ldp x20, x19, [sp], #16" - when "pushCalleeSaves" - $asm.puts "stp x20, x19, [sp, #-16]!" - $asm.puts "stp x22, x21, [sp, #-16]!" - $asm.puts "stp x24, x23, [sp, #-16]!" - $asm.puts "stp x26, x25, [sp, #-16]!" - $asm.puts "stp x28, x27, [sp, #-16]!" when "move" if operands[0].immediate? emitARM64MoveImmediate(operands[0].value, operands[1]) @@ -821,7 +866,11 @@ class Instruction when "memfence" $asm.puts "dmb sy" when "pcrtoaddr" - $asm.puts "adr #{operands[1].arm64Operand(:ptr)}, #{operands[0].value}" + $asm.puts "adr #{operands[1].arm64Operand(:ptr)}, #{operands[0].value}" + when "nopCortexA53Fix835769" + $asm.putStr("#if CPU(ARM64_CORTEXA53)") + $asm.puts "nop" + $asm.putStr("#endif") else lowerDefault end