summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBalazs Kilvady <kilvadyb@homejinni.com>2014-02-10 10:54:20 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-10 16:27:56 +0100
commita1b801fc98ccda988df41e08dc70fdbd50ecb513 (patch)
tree50b48630a826445fcafaec3ba446287e27af8abb
parent01614b1d9ab60057bb98a6f740dbfa16f2636060 (diff)
[mips] Wrong register usage in LLInt.old/5.2
Fix register usage and add PIC header to all LLInt operations. This patch is taken from https://bugs.webkit.org/show_bug.cgi?id=125168. It fixes the crash of fast/js/exception-propagate-from-dfg-to-llint test on mips architecture. Change-Id: I98ad3b5766451cab48a76f7e028b210f9ebe99ed Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
-rw-r--r--Source/JavaScriptCore/offlineasm/instructions.rb4
-rw-r--r--Source/JavaScriptCore/offlineasm/mips.rb163
2 files changed, 115 insertions, 52 deletions
diff --git a/Source/JavaScriptCore/offlineasm/instructions.rb b/Source/JavaScriptCore/offlineasm/instructions.rb
index eb394afab..cae8ec8b3 100644
--- a/Source/JavaScriptCore/offlineasm/instructions.rb
+++ b/Source/JavaScriptCore/offlineasm/instructions.rb
@@ -267,12 +267,12 @@ ARM_INSTRUCTIONS =
MIPS_INSTRUCTIONS =
[
+ "la",
"movz",
"movn",
"slt",
"sltu",
- "pichdr",
- "pichdrra"
+ "pichdr"
]
SH4_INSTRUCTIONS =
diff --git a/Source/JavaScriptCore/offlineasm/mips.rb b/Source/JavaScriptCore/offlineasm/mips.rb
index 3ec7022ee..c0adfd029 100644
--- a/Source/JavaScriptCore/offlineasm/mips.rb
+++ b/Source/JavaScriptCore/offlineasm/mips.rb
@@ -62,7 +62,6 @@ MIPS_TEMP_GPRS = [SpecialRegister.new("$t5"), SpecialRegister.new("$t6"), Specia
MIPS_ZERO_REG = SpecialRegister.new("$zero")
MIPS_GP_REG = SpecialRegister.new("$gp")
MIPS_GPSAVE_REG = SpecialRegister.new("$s4")
-MIPS_JUMP_REG = SpecialRegister.new("$ra")
MIPS_CALL_REG = SpecialRegister.new("$t9")
MIPS_TEMP_FPRS = [SpecialRegister.new("$f16")]
MIPS_SCRATCH_FPR = SpecialRegister.new("$f18")
@@ -158,6 +157,70 @@ class AbsoluteAddress
end
#
+# Negate condition of branches to labels.
+#
+
+class Instruction
+ def mipsNegateCondition(list)
+ /^(b(add|sub|or|mul|t)?)([ipb])/.match(opcode)
+ case $~.post_match
+ when "eq"
+ op = "neq"
+ when "neq"
+ op = "eq"
+ when "z"
+ op = "nz"
+ when "nz"
+ op = "z"
+ when "gt"
+ op = "lteq"
+ when "gteq"
+ op = "lt"
+ when "lt"
+ op = "gteq"
+ when "lteq"
+ op = "gt"
+ when "a"
+ op = "beq"
+ when "b"
+ op = "aeq"
+ when "aeq"
+ op = "b"
+ when "beq"
+ op = "a"
+ else
+ raise "Can't negate #{opcode} branch."
+ end
+ noBranch = LocalLabel.unique("nobranch")
+ noBranchRef = LocalLabelReference.new(codeOrigin, noBranch)
+ toRef = operands[-1]
+ list << Instruction.new(codeOrigin, "#{$1}#{$3}#{op}", operands[0..-2].push(noBranchRef), annotation)
+ list << Instruction.new(codeOrigin, "la", [toRef, MIPS_CALL_REG])
+ list << Instruction.new(codeOrigin, "jmp", [MIPS_CALL_REG])
+ list << noBranch
+ end
+end
+
+def mipsLowerFarBranchOps(list)
+ newList = []
+ list.each {
+ | node |
+ if node.is_a? Instruction
+ annotation = node.annotation
+ case node.opcode
+ when /^b(add|sub|or|mul|t)?([ipb])/
+ if node.operands[-1].is_a? LabelReference
+ node.mipsNegateCondition(newList)
+ next
+ end
+ end
+ end
+ newList << node
+ }
+ newList
+end
+
+#
# Lower 'and' masked branches
#
@@ -392,6 +455,30 @@ end
# Specialization of lowering of misplaced addresses.
#
+class LocalLabelReference
+ def register?
+ false
+ end
+end
+
+def mipsAsRegister(preList, postList, operand, needRestore)
+ tmp = MIPS_CALL_REG
+ if operand.address?
+ preList << Instruction.new(operand.codeOrigin, "loadp", [operand, MIPS_CALL_REG])
+ elsif operand.is_a? LabelReference
+ preList << Instruction.new(operand.codeOrigin, "la", [operand, MIPS_CALL_REG])
+ elsif operand.register? and operand != MIPS_CALL_REG
+ preList << Instruction.new(operand.codeOrigin, "move", [operand, MIPS_CALL_REG])
+ else
+ needRestore = false
+ tmp = operand
+ end
+ if needRestore
+ postList << Instruction.new(operand.codeOrigin, "move", [MIPS_GPSAVE_REG, MIPS_GP_REG])
+ end
+ tmp
+end
+
def mipsLowerMisplacedAddresses(list)
newList = []
list.each {
@@ -401,33 +488,13 @@ def mipsLowerMisplacedAddresses(list)
annotation = node.annotation
case node.opcode
when "jmp"
- if node.operands[0].address?
- newList << Instruction.new(node.operands[0].codeOrigin, "loadi", [node.operands[0], MIPS_JUMP_REG])
- newList << Instruction.new(node.codeOrigin, node.opcode, [MIPS_JUMP_REG])
- else
- newList << Instruction.new(node.codeOrigin,
- node.opcode,
- [riscAsRegister(newList, postInstructions, node.operands[0], "p", false)])
- end
+ newList << Instruction.new(node.codeOrigin,
+ node.opcode,
+ [mipsAsRegister(newList, [], node.operands[0], false)])
when "call"
- restoreGP = false;
- tmp = MIPS_CALL_REG
- if node.operands[0].address?
- newList << Instruction.new(node.operands[0].codeOrigin, "loadp", [node.operands[0], MIPS_CALL_REG])
- restoreGP = true;
- elsif node.operands[0].is_a? LabelReference
- tmp = node.operands[0]
- restoreGP = true;
- elsif node.operands[0].register?
- newList << Instruction.new(node.operands[0].codeOrigin, "move", [node.operands[0], MIPS_CALL_REG])
- restoreGP = true;
- else
- tmp = node.operands[0]
- end
- newList << Instruction.new(node.codeOrigin, node.opcode, [tmp])
- if restoreGP
- newList << Instruction.new(node.codeOrigin, "move", [MIPS_GPSAVE_REG, MIPS_GP_REG])
- end
+ newList << Instruction.new(node.codeOrigin,
+ node.opcode,
+ [mipsAsRegister(newList, postInstructions, node.operands[0], true)])
when "slt", "sltu"
newList << Instruction.new(node.codeOrigin,
node.opcode,
@@ -512,7 +579,7 @@ class Address
end
#
-# Add PIC compatible header code to prologue/entry rutins.
+# Add PIC compatible header code to all the LLInt rutins.
#
def mipsAddPICCode(list)
@@ -521,13 +588,7 @@ def mipsAddPICCode(list)
| node |
myList << node
if node.is_a? Label
- if /_prologue$/.match(node.name) || /^_llint_function_/.match(node.name)
- # Functions called from trampoline/JIT codes.
- myList << Instruction.new(node.codeOrigin, "pichdr", [])
- elsif /_llint_op_catch/.match(node.name)
- # Exception cactcher entry point function.
- myList << Instruction.new(node.codeOrigin, "pichdrra", [])
- end
+ myList << Instruction.new(node.codeOrigin, "pichdr", [])
end
}
myList
@@ -553,6 +614,7 @@ class Sequence
}
result = mipsAddPICCode(result)
+ result = mipsLowerFarBranchOps(result)
result = mipsLowerSimpleBranchOps(result)
result = riscLowerSimpleBranchOps(result)
result = riscLowerHardBranchOps(result)
@@ -660,6 +722,16 @@ def emitMIPSDoubleBranch(branchOpcode, neg, operands)
end
end
+def emitMIPSJumpOrCall(opcode, operand)
+ if operand.label?
+ raise "Direct call/jump to a not local label." unless operand.is_a? LocalLabelReference
+ $asm.puts "#{opcode} #{operand.asmLabel}"
+ else
+ raise "Invalid call/jump register." unless operand == MIPS_CALL_REG
+ $asm.puts "#{opcode}r #{MIPS_CALL_REG.mipsOperand}"
+ end
+end
+
class Instruction
def lowerMIPS
$asm.comment codeOriginString
@@ -730,6 +802,8 @@ class Instruction
$asm.puts "ldc1 #{mipsFlippedOperands(operands)}"
when "stored"
$asm.puts "sdc1 #{mipsOperands(operands)}"
+ when "la"
+ $asm.puts "la #{operands[1].mipsOperand}, #{operands[0].asmLabel}"
when "addd"
emitMIPS("add.d", operands)
when "divd"
@@ -811,17 +885,9 @@ class Instruction
when "bilteq", "bplteq", "bblteq"
$asm.puts "ble #{mipsOperands(operands[0..1])}, #{operands[2].asmLabel}"
when "jmp"
- if operands[0].label?
- $asm.puts "j #{operands[0].asmLabel}"
- else
- $asm.puts "jr #{operands[0].mipsOperand}"
- end
+ emitMIPSJumpOrCall("j", operands[0])
when "call"
- if operands[0].label?
- $asm.puts "jal #{operands[0].asmLabel}"
- else
- $asm.puts "jalr #{operands[0].mipsOperand}"
- end
+ emitMIPSJumpOrCall("jal", operands[0])
when "break"
$asm.puts "break"
when "ret"
@@ -880,11 +946,8 @@ class Instruction
when "sltu", "sltub"
$asm.puts "sltu #{operands[0].mipsOperand}, #{operands[1].mipsOperand}, #{operands[2].mipsOperand}"
when "pichdr"
- $asm.putStr("OFFLINE_ASM_CPLOAD($25)")
- $asm.puts "move $s4, $gp"
- when "pichdrra"
- $asm.putStr("OFFLINE_ASM_CPLOAD($31)")
- $asm.puts "move $s4, $gp"
+ $asm.putStr("OFFLINE_ASM_CPLOAD(#{MIPS_CALL_REG.mipsOperand})")
+ $asm.puts "move #{MIPS_GPSAVE_REG.mipsOperand}, #{MIPS_GP_REG.mipsOperand}"
else
raise "Unhandled opcode #{opcode} at #{codeOriginString}"
end