Modified: trunk/Source/_javascript_Core/ChangeLog (159287 => 159288)
--- trunk/Source/_javascript_Core/ChangeLog 2013-11-14 16:49:29 UTC (rev 159287)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-11-14 16:52:48 UTC (rev 159288)
@@ -1,5 +1,20 @@
2013-11-14 Julien Brianceau <[email protected]>
+ REGRESSION (r159276): Fix lots of crashes for sh4 architecture.
+ https://bugs.webkit.org/show_bug.cgi?id=124347
+
+ Reviewed by Michael Saboff.
+
+ Since r159276, we have (t4 == a0 == r4) and (t5 == a1 == r5) in LLINT for sh4.
+ This leads to argument register trampling in cCallX macros, especially with cCall2
+ macro when arg1 == t4.
+
+ * llint/LowLevelInterpreter32_64.asm: Use a new "setargs" pseudo-op to setup arguments for sh4.
+ * offlineasm/instructions.rb:
+ * offlineasm/sh4.rb: Lower "setargs" pseudo-op to setup argument registers and prevent register trampling issues.
+
+2013-11-14 Julien Brianceau <[email protected]>
+
Fix build for sh4 architectures (broken since r159276).
https://bugs.webkit.org/show_bug.cgi?id=124344
Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm (159287 => 159288)
--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm 2013-11-14 16:49:29 UTC (rev 159287)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter32_64.asm 2013-11-14 16:52:48 UTC (rev 159288)
@@ -105,10 +105,13 @@
poke arg1, 0
poke arg2, 1
call function
- elsif MIPS or SH4
+ elsif MIPS
move arg1, a0
move arg2, a1
call function
+ elsif SH4
+ setargs arg1, arg2
+ call function
elsif C_LOOP
cloopCallSlowPath function, arg1, arg2
else
@@ -130,12 +133,15 @@
poke arg3, 2
poke arg4, 3
call function
- elsif MIPS or SH4
+ elsif MIPS
move arg1, a0
move arg2, a1
move arg3, a2
move arg4, a3
call function
+ elsif SH4
+ setargs arg1, arg2, arg3, arg4
+ call function
elsif C_LOOP
error
else
Modified: trunk/Source/_javascript_Core/offlineasm/instructions.rb (159287 => 159288)
--- trunk/Source/_javascript_Core/offlineasm/instructions.rb 2013-11-14 16:49:29 UTC (rev 159287)
+++ trunk/Source/_javascript_Core/offlineasm/instructions.rb 2013-11-14 16:52:48 UTC (rev 159288)
@@ -288,7 +288,8 @@
"loaddReversedAndIncrementAddress",
"storedReversedAndDecrementAddress",
"ldspr",
- "stspr"
+ "stspr",
+ "setargs"
]
CXX_INSTRUCTIONS =
Modified: trunk/Source/_javascript_Core/offlineasm/sh4.rb (159287 => 159288)
--- trunk/Source/_javascript_Core/offlineasm/sh4.rb 2013-11-14 16:49:29 UTC (rev 159287)
+++ trunk/Source/_javascript_Core/offlineasm/sh4.rb 2013-11-14 16:52:48 UTC (rev 159288)
@@ -563,6 +563,78 @@
end
+#
+# Lowering of argument setup for SH4.
+# This phase avoids argument register trampling. For example, if a0 == t4:
+#
+# setargs t1, t4
+#
+# becomes:
+#
+# move t4, a1
+# move t1, a0
+#
+
+def sh4LowerArgumentSetup(list)
+ a0 = RegisterID.forName(codeOrigin, "a0")
+ a1 = RegisterID.forName(codeOrigin, "a1")
+ a2 = RegisterID.forName(codeOrigin, "a2")
+ a3 = RegisterID.forName(codeOrigin, "a3")
+ newList = []
+ list.each {
+ | node |
+ if node.is_a? Instruction
+ case node.opcode
+ when "setargs"
+ if node.operands.size == 2
+ if node.operands[1].sh4Operand != a0.sh4Operand
+ newList << Instruction.new(codeOrigin, "move", [node.operands[0], a0])
+ newList << Instruction.new(codeOrigin, "move", [node.operands[1], a1])
+ elsif node.operands[0].sh4Operand != a1.sh4Operand
+ newList << Instruction.new(codeOrigin, "move", [node.operands[1], a1])
+ newList << Instruction.new(codeOrigin, "move", [node.operands[0], a0])
+ else
+ # As (operands[0] == a1) and (operands[1] == a0), we just need to swap a0 and a1.
+ newList << Instruction.new(codeOrigin, "xori", [a0, a1])
+ newList << Instruction.new(codeOrigin, "xori", [a1, a0])
+ newList << Instruction.new(codeOrigin, "xori", [a0, a1])
+ end
+ elsif node.operands.size == 4
+ # FIXME: We just raise an error if something is likely to go wrong for now.
+ # It would be better to implement a recovering algorithm.
+ if (node.operands[0].sh4Operand == a1.sh4Operand) or
+ (node.operands[0].sh4Operand == a2.sh4Operand) or
+ (node.operands[0].sh4Operand == a3.sh4Operand) or
+ (node.operands[1].sh4Operand == a0.sh4Operand) or
+ (node.operands[1].sh4Operand == a2.sh4Operand) or
+ (node.operands[1].sh4Operand == a3.sh4Operand) or
+ (node.operands[2].sh4Operand == a0.sh4Operand) or
+ (node.operands[2].sh4Operand == a1.sh4Operand) or
+ (node.operands[2].sh4Operand == a3.sh4Operand) or
+ (node.operands[3].sh4Operand == a0.sh4Operand) or
+ (node.operands[3].sh4Operand == a1.sh4Operand) or
+ (node.operands[3].sh4Operand == a2.sh4Operand)
+ raise "Potential argument register trampling detected."
+ end
+
+ newList << Instruction.new(codeOrigin, "move", [node.operands[0], a0])
+ newList << Instruction.new(codeOrigin, "move", [node.operands[1], a1])
+ newList << Instruction.new(codeOrigin, "move", [node.operands[2], a2])
+ newList << Instruction.new(codeOrigin, "move", [node.operands[3], a3])
+ else
+ raise "Invalid operands number (#{node.operands.size}) for setargs"
+ end
+ else
+ newList << node
+ end
+ else
+ newList << node
+ end
+ }
+ newList
+end
+
+
class Sequence
def getModifiedListSH4
result = @list
@@ -613,6 +685,7 @@
result = assignRegistersToTemporaries(result, :gpr, SH4_TMP_FPRS)
result = sh4LowerConstPool(result)
+ result = sh4LowerArgumentSetup(result)
return result
end
@@ -883,7 +956,7 @@
else
$asm.puts "mov.l #{operands[0].labelref.asmLabel}, #{operands[1].sh4Operand}"
end
- else
+ elsif operands[0].sh4Operand != operands[1].sh4Operand
$asm.puts "mov #{sh4Operands(operands)}"
end
when "leap"