[Qt][ARM] REGRESSION(r130826): It made 33 JSC test and 466 layout tests crash
https://bugs.webkit.org/show_bug.cgi?id=98857

Patch by Gabor Ballabas <gaborb@inf.u-szeged.hu> on 2012-11-26
Reviewed by Zoltan Herczeg.

Implement a new version of patchableBranch32 to fix crashing JSC
tests.

* assembler/MacroAssembler.h:
(MacroAssembler):
* assembler/MacroAssemblerARM.h:
(JSC::MacroAssemblerARM::patchableBranch32):
(MacroAssemblerARM):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@135717 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index ba2979b..d5a9207 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,19 @@
+2012-11-26  Gabor Ballabas  <gaborb@inf.u-szeged.hu>
+
+        [Qt][ARM] REGRESSION(r130826): It made 33 JSC test and 466 layout tests crash
+        https://bugs.webkit.org/show_bug.cgi?id=98857
+
+        Reviewed by Zoltan Herczeg.
+
+        Implement a new version of patchableBranch32 to fix crashing JSC
+        tests.
+
+        * assembler/MacroAssembler.h:
+        (MacroAssembler):
+        * assembler/MacroAssemblerARM.h:
+        (JSC::MacroAssemblerARM::patchableBranch32):
+        (MacroAssemblerARM):
+
 2012-11-21  Filip Pizlo  <fpizlo@apple.com>
 
         Any function that can log things should be able to easily log them to a memory buffer as well
diff --git a/Source/JavaScriptCore/assembler/MacroAssembler.h b/Source/JavaScriptCore/assembler/MacroAssembler.h
index 642b5ca..dcfdd48 100644
--- a/Source/JavaScriptCore/assembler/MacroAssembler.h
+++ b/Source/JavaScriptCore/assembler/MacroAssembler.h
@@ -266,12 +266,14 @@
     {
         return PatchableJump(branchTest32(cond, reg, mask));
     }
-    
+#endif // !CPU(ARM_THUMB2)
+
+#if !CPU(ARM)
     PatchableJump patchableBranch32(RelationalCondition cond, RegisterID reg, TrustedImm32 imm)
     {
         return PatchableJump(branch32(cond, reg, imm));
     }
-#endif
+#endif // !(CPU(ARM)
 
     void jump(Label target)
     {
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
index 9c77e93..e6b5ad3 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -570,11 +570,7 @@
 
     Jump branch32(RelationalCondition cond, RegisterID left, TrustedImm32 right, int useConstantPool = 0)
     {
-        ARMWord tmp = (static_cast<unsigned>(right.m_value) == 0x80000000) ? ARMAssembler::InvalidImmediate : m_assembler.getOp2(-right.m_value);
-        if (tmp != ARMAssembler::InvalidImmediate)
-            m_assembler.cmn(left, tmp);
-        else
-            m_assembler.cmp(left, m_assembler.getImm(right.m_value, ARMRegisters::S0));
+        internalCompare32(left, right);
         return Jump(m_assembler.jmp(ARMCondition(cond), useConstantPool));
     }
 
@@ -807,6 +803,14 @@
         return Jump(m_assembler.jmp(ARMCondition(cond)));
     }
 
+    PatchableJump patchableBranch32(RelationalCondition cond, RegisterID reg, TrustedImm32 imm)
+    {
+        internalCompare32(reg, imm);
+        Jump jump(m_assembler.loadBranchTarget(ARMRegisters::S1, ARMCondition(cond), true));
+        m_assembler.bx(ARMRegisters::S1, ARMCondition(cond));
+        return PatchableJump(jump);
+    }
+
     void breakpoint()
     {
         m_assembler.bkpt(0);
@@ -1320,6 +1324,15 @@
     friend class LinkBuffer;
     friend class RepatchBuffer;
 
+    void internalCompare32(RegisterID left, TrustedImm32 right)
+    {
+        ARMWord tmp = (static_cast<unsigned>(right.m_value) == 0x80000000) ? ARMAssembler::InvalidImmediate : m_assembler.getOp2(-right.m_value);
+        if (tmp != ARMAssembler::InvalidImmediate)
+            m_assembler.cmn(left, tmp);
+        else
+            m_assembler.cmp(left, m_assembler.getImm(right.m_value, ARMRegisters::S0));
+    }
+
     static void linkCall(void* code, Call call, FunctionPtr function)
     {
         ARMAssembler::linkCall(code, call.m_label, function.value());