Title: [149349] trunk/Source
Revision
149349
Author
[email protected]
Date
2013-04-29 19:55:18 -0700 (Mon, 29 Apr 2013)

Log Message

[ARM] Expand the use of integer division
https://bugs.webkit.org/show_bug.cgi?id=115138

Patch by Cosmin Truta <[email protected]> on 2013-04-29
Reviewed by Benjamin Poulain.

Source/_javascript_Core:

If availability of hardware integer division isn't known at compile
time, check the CPU flags and decide at runtime whether to fall back
to software. Currently, this OS-specific check is implemented on QNX.

Moreover, use operator % instead of fmod() in the calculation of the
software modulo. Even when it's software-emulated, operator % is faster
than fmod(): on ARM v7 QNX, without hardware division, we noticed
>3% speedup on SunSpider.

* CMakeLists.txt:
* GNUmakefile.list.am:
* _javascript_Core.xcodeproj/project.pbxproj:
* assembler/ARMv7Assembler.h:
(JSC::ARMv7Assembler::sdiv): Did not compile conditionally.
(JSC::ARMv7Assembler::udiv): Ditto.
* assembler/AbstractMacroAssembler.h:
(JSC::isARMv7s): Removed.
* assembler/MacroAssemblerARMv7.cpp: Added.
(JSC::isIntegerDivSupported): Added.
* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::supportsIntegerDiv): Added.
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode): Checked MacroAssembler::supportsIntegerDiv() in ArithDiv case.
* dfg/DFGOperations.cpp:
(JSC::DFG::operationModOnInts): Added.
* dfg/DFGOperations.h:
(JSC::DFG::Z_DFGOperation_ZZ): Added.
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileSoftModulo): Separated the X86-specific and ARM-specific codegen
from the common implementation; used operationModOnInts on ARM.
(JSC::DFG::SpeculativeJIT::compileIntegerArithDivForARM): Renamed from compileIntegerArithDivForARMv7.
(JSC::DFG::SpeculativeJIT::compileArithMod): Allowed run-time detection of integer div on ARM.
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation): Added overloads with Z_DFGOperation_ZZ arguments.
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile): Used compileIntegerArithDivForARM.

Source/WTF:

* wtf/Platform.h: Added ENABLE_ARM_INTEGER_DIV.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (149348 => 149349)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2013-04-30 02:55:18 UTC (rev 149349)
@@ -517,6 +517,7 @@
         assembler/ARMAssembler.cpp
         assembler/ARMv7Assembler.cpp
         assembler/MacroAssemblerARM.cpp
+        assembler/MacroAssemblerARMv7.cpp
     )
 elseif (WTF_CPU_MIPS)
 elseif (WTF_CPU_X86)

Modified: trunk/Source/_javascript_Core/ChangeLog (149348 => 149349)


--- trunk/Source/_javascript_Core/ChangeLog	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-04-30 02:55:18 UTC (rev 149349)
@@ -1,3 +1,47 @@
+2013-04-29  Cosmin Truta  <[email protected]>
+
+        [ARM] Expand the use of integer division
+        https://bugs.webkit.org/show_bug.cgi?id=115138
+
+        Reviewed by Benjamin Poulain.
+
+        If availability of hardware integer division isn't known at compile
+        time, check the CPU flags and decide at runtime whether to fall back
+        to software. Currently, this OS-specific check is implemented on QNX.
+
+        Moreover, use operator % instead of fmod() in the calculation of the
+        software modulo. Even when it's software-emulated, operator % is faster
+        than fmod(): on ARM v7 QNX, without hardware division, we noticed
+        >3% speedup on SunSpider.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::sdiv): Did not compile conditionally.
+        (JSC::ARMv7Assembler::udiv): Ditto.
+        * assembler/AbstractMacroAssembler.h:
+        (JSC::isARMv7s): Removed.
+        * assembler/MacroAssemblerARMv7.cpp: Added.
+        (JSC::isIntegerDivSupported): Added.
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::supportsIntegerDiv): Added.
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode): Checked MacroAssembler::supportsIntegerDiv() in ArithDiv case.
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::operationModOnInts): Added.
+        * dfg/DFGOperations.h:
+        (JSC::DFG::Z_DFGOperation_ZZ): Added.
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileSoftModulo): Separated the X86-specific and ARM-specific codegen
+        from the common implementation; used operationModOnInts on ARM.
+        (JSC::DFG::SpeculativeJIT::compileIntegerArithDivForARM): Renamed from compileIntegerArithDivForARMv7.
+        (JSC::DFG::SpeculativeJIT::compileArithMod): Allowed run-time detection of integer div on ARM.
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation): Added overloads with Z_DFGOperation_ZZ arguments.
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile): Used compileIntegerArithDivForARM.
+
 2013-04-29  Benjamin Poulain  <[email protected]>
 
         Unify the data access of StringImpl members from _javascript_Core

Modified: trunk/Source/_javascript_Core/GNUmakefile.list.am (149348 => 149349)


--- trunk/Source/_javascript_Core/GNUmakefile.list.am	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/_javascript_Core/GNUmakefile.list.am	2013-04-30 02:55:18 UTC (rev 149349)
@@ -73,6 +73,7 @@
 	Source/_javascript_Core/assembler/MacroAssembler.h \
 	Source/_javascript_Core/assembler/MacroAssemblerARM.cpp \
 	Source/_javascript_Core/assembler/MacroAssemblerARM.h \
+	Source/_javascript_Core/assembler/MacroAssemblerARMv7.cpp \
 	Source/_javascript_Core/assembler/MacroAssemblerARMv7.h \
 	Source/_javascript_Core/assembler/MacroAssemblerCodeRef.h \
 	Source/_javascript_Core/assembler/MacroAssemblerMIPS.h \

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (149348 => 149349)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2013-04-30 02:55:18 UTC (rev 149349)
@@ -574,6 +574,7 @@
 		86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */; };
 		86C568E111A213EE0007F7F0 /* MacroAssemblerMIPS.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DE11A213EE0007F7F0 /* MacroAssemblerMIPS.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		86C568E211A213EE0007F7F0 /* MIPSAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C568DF11A213EE0007F7F0 /* MIPSAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		86C568E4FB92867A16FD1002 /* MacroAssemblerARMv7.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86C568E3FB92867A16FD1002 /* MacroAssemblerARMv7.cpp */; };
 		86CA032E1038E8440028A609 /* Executable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CA032D1038E8440028A609 /* Executable.cpp */; };
 		86CAFEE31035DDE60028A609 /* Executable.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CAFEE21035DDE60028A609 /* Executable.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		86CC85A10EE79A4700288682 /* JITInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CC85A00EE79A4700288682 /* JITInlines.h */; };
@@ -1477,6 +1478,7 @@
 		86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssemblerARM.cpp; sourceTree = "<group>"; };
 		86C568DE11A213EE0007F7F0 /* MacroAssemblerMIPS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerMIPS.h; sourceTree = "<group>"; };
 		86C568DF11A213EE0007F7F0 /* MIPSAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIPSAssembler.h; sourceTree = "<group>"; };
+		86C568E3FB92867A16FD1002 /* MacroAssemblerARMv7.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssemblerARMv7.cpp; sourceTree = "<group>"; };
 		86CA032D1038E8440028A609 /* Executable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Executable.cpp; sourceTree = "<group>"; };
 		86CAFEE21035DDE60028A609 /* Executable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Executable.h; sourceTree = "<group>"; };
 		86CC85A00EE79A4700288682 /* JITInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITInlines.h; sourceTree = "<group>"; };
@@ -2845,6 +2847,7 @@
 				86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */,
 				86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */,
 				86D3B2C210156BDE002865E7 /* MacroAssemblerARM.h */,
+				86C568E3FB92867A16FD1002 /* MacroAssemblerARMv7.cpp */,
 				86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */,
 				863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */,
 				86C568DE11A213EE0007F7F0 /* MacroAssemblerMIPS.h */,
@@ -3977,6 +3980,7 @@
 				14B723B212D7DA46003BD5ED /* MachineStackMarker.cpp in Sources */,
 				0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */,
 				86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */,
+				86C568E4FB92867A16FD1002 /* MacroAssemblerARMv7.cpp in Sources */,
 				86AE64A8135E5E1C00963012 /* MacroAssemblerSH4.cpp in Sources */,
 				C2B916C514DA040C00CBAC86 /* MarkedAllocator.cpp in Sources */,
 				142D6F0813539A2800B02E86 /* MarkedBlock.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/assembler/ARMv7Assembler.h (149348 => 149349)


--- trunk/Source/_javascript_Core/assembler/ARMv7Assembler.h	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/_javascript_Core/assembler/ARMv7Assembler.h	2013-04-30 02:55:18 UTC (rev 149349)
@@ -661,10 +661,8 @@
         OP_ROR_reg_T2   = 0xFA60,
         OP_CLZ          = 0xFAB0,
         OP_SMULL_T1     = 0xFB80,
-#if CPU(APPLE_ARMV7S)
         OP_SDIV_T1      = 0xFB90,
         OP_UDIV_T1      = 0xFBB0,
-#endif
     } OpcodeID1;
 
     typedef enum {
@@ -1407,7 +1405,6 @@
         m_formatter.twoWordOp12Reg4FourFours(OP_ROR_reg_T2, rn, FourFours(0xf, rd, 0, rm));
     }
 
-#if CPU(APPLE_ARMV7S)
     ALWAYS_INLINE void sdiv(RegisterID rd, RegisterID rn, RegisterID rm)
     {
         ASSERT(!BadReg(rd));
@@ -1415,7 +1412,6 @@
         ASSERT(!BadReg(rm));
         m_formatter.twoWordOp12Reg4FourFours(OP_SDIV_T1, rn, FourFours(0xf, rd, 0xf, rm));
     }
-#endif
 
     ALWAYS_INLINE void smull(RegisterID rdLo, RegisterID rdHi, RegisterID rn, RegisterID rm)
     {
@@ -1753,7 +1749,6 @@
         m_formatter.twoWordOp12Reg40Imm3Reg4Imm20Imm5(OP_UBFX_T1, rd, rn, (lsb & 0x1c) << 10, (lsb & 0x3) << 6, (width - 1) & 0x1f);
     }
 
-#if CPU(APPLE_ARMV7S)
     ALWAYS_INLINE void udiv(RegisterID rd, RegisterID rn, RegisterID rm)
     {
         ASSERT(!BadReg(rd));
@@ -1761,7 +1756,6 @@
         ASSERT(!BadReg(rm));
         m_formatter.twoWordOp12Reg4FourFours(OP_UDIV_T1, rn, FourFours(0xf, rd, 0xf, rm));
     }
-#endif
 
     void vadd(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm)
     {

Modified: trunk/Source/_javascript_Core/assembler/AbstractMacroAssembler.h (149348 => 149349)


--- trunk/Source/_javascript_Core/assembler/AbstractMacroAssembler.h	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/_javascript_Core/assembler/AbstractMacroAssembler.h	2013-04-30 02:55:18 UTC (rev 149349)
@@ -46,15 +46,6 @@
 
 namespace JSC {
 
-inline bool isARMv7s()
-{
-#if CPU(APPLE_ARMV7S)
-    return true;
-#else
-    return false;
-#endif
-}
-
 inline bool isX86()
 {
 #if CPU(X86_64) || CPU(X86)

Added: trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.cpp (0 => 149349)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.cpp	2013-04-30 02:55:18 UTC (rev 149349)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012, 2013 Research In Motion Limited. 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 UNIVERSITY OF SZEGED ``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 UNIVERSITY OF SZEGED 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2)
+
+#include "MacroAssemblerARMv7.h"
+
+#if OS(QNX)
+#include <sys/syspage.h>
+#endif
+
+namespace JSC {
+
+#if OS(QNX)
+
+static bool isIntegerDivSupported()
+{
+#ifdef ARM_CPU_FLAG_IDIV
+    return !!(SYSPAGE_ENTRY(cpuinfo)->flags & ARM_CPU_FLAG_IDIV);
+#else
+    return false;
+#endif
+}
+
+const bool MacroAssemblerARMv7::s_isIntegerDivSupported = isIntegerDivSupported();
+
+#endif // OS(QNX)
+
+}
+
+#endif // ENABLE(ASSEMBLER) && CPU(ARM_THUMB2)

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h (149348 => 149349)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h	2013-04-30 02:55:18 UTC (rev 149349)
@@ -793,8 +793,19 @@
     }
 #endif
 
-    // Floating-point operations:
+    // Integer operations.
+    static bool supportsIntegerDiv()
+    {
+#if CPU(APPLE_ARMV7S)
+        return true;
+#elif OS(QNX)
+        return s_isIntegerDivSupported;
+#else
+        return false;
+#endif
+    }
 
+    // Floating-point operations.
     static bool supportsFloatingPoint() { return true; }
     static bool supportsFloatingPointTruncate() { return true; }
     static bool supportsFloatingPointSqrt() { return true; }
@@ -1907,6 +1918,10 @@
     }
 
     bool m_makeJumpPatchable;
+
+#if OS(QNX)
+    static const bool s_isIntegerDivSupported;
+#endif
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (149348 => 149349)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2013-04-30 02:55:18 UTC (rev 149349)
@@ -214,7 +214,14 @@
         case ArithDiv: {
             if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
                 && node->canSpeculateInteger()) {
-                if (isX86() || isARMv7s()) {
+#if CPU(X86) || CPU(X86_64)
+                const bool cpuSupportsIntegerDiv = true;
+#elif CPU(ARM_THUMB2)
+                const bool cpuSupportsIntegerDiv = MacroAssembler::supportsIntegerDiv();
+#else
+                const bool cpuSupportsIntegerDiv = false;
+#endif
+                if (cpuSupportsIntegerDiv) {
                     setUseKindAndUnboxIfProfitable<Int32Use>(node->child1());
                     setUseKindAndUnboxIfProfitable<Int32Use>(node->child2());
                     break;

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (149348 => 149349)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2013-04-30 02:55:18 UTC (rev 149349)
@@ -45,6 +45,7 @@
 #include "ObjectConstructor.h"
 #include "Operations.h"
 #include "StringConstructor.h"
+#include <stdlib.h>
 #include <wtf/InlineASM.h>
 
 #if ENABLE(JIT)
@@ -1600,6 +1601,11 @@
     return JSRopeString::create(vm, a, b, c);
 }
 
+int32_t DFG_OPERATION operationModOnInts(int32_t a, int32_t b)
+{
+    return a % b;
+}
+
 double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b)
 {
     return fmod(a, b);

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (149348 => 149349)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.h	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h	2013-04-30 02:55:18 UTC (rev 149349)
@@ -97,6 +97,7 @@
 typedef double DFG_OPERATION (*D_DFGOperation_ZZ)(int32_t, int32_t);
 typedef double DFG_OPERATION (*D_DFGOperation_EJ)(ExecState*, EncodedJSValue);
 typedef int32_t DFG_OPERATION (*Z_DFGOperation_D)(double);
+typedef int32_t DFG_OPERATION (*Z_DFGOperation_ZZ)(int32_t, int32_t);
 typedef size_t DFG_OPERATION (*S_DFGOperation_ECC)(ExecState*, JSCell*, JSCell*);
 typedef size_t DFG_OPERATION (*S_DFGOperation_EJ)(ExecState*, EncodedJSValue);
 typedef size_t DFG_OPERATION (*S_DFGOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue);
@@ -208,6 +209,7 @@
 EncodedJSValue DFG_OPERATION operationGetArgumentByVal(ExecState*, int32_t, int32_t) WTF_INTERNAL;
 JSCell* DFG_OPERATION operationNewFunction(ExecState*, JSCell*) WTF_INTERNAL;
 JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState*, JSCell*) WTF_INTERNAL;
+int32_t DFG_OPERATION operationModOnInts(int32_t, int32_t) WTF_INTERNAL;
 double DFG_OPERATION operationFModOnInts(int32_t, int32_t) WTF_INTERNAL;
 size_t DFG_OPERATION operationIsObject(ExecState*, EncodedJSValue) WTF_INTERNAL;
 size_t DFG_OPERATION operationIsFunction(EncodedJSValue) WTF_INTERNAL;

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (149348 => 149349)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2013-04-30 02:55:18 UTC (rev 149349)
@@ -2877,12 +2877,12 @@
 #endif
 }
 
+#if CPU(X86) || CPU(X86_64)
 void SpeculativeJIT::compileSoftModulo(Node* node)
 {
     // In the fast path, the dividend value could be the final result
     // (in case of |dividend| < |divisor|), so we speculate it as strict int32.
     SpeculateStrictInt32Operand op1(this, node->child1());
-#if CPU(X86) || CPU(X86_64)
     if (isInt32Constant(node->child2().node())) {
         int32_t divisor = valueOfInt32Constant(node->child2().node());
         if (divisor) {
@@ -2922,36 +2922,9 @@
             return;
         }
     }
-#elif CPU(APPLE_ARMV7S) || CPU(ARM_THUMB2)
-    if (isInt32Constant(node->child2().node())) {
-        int32_t divisor = valueOfInt32Constant(node->child2().node());
-        if (divisor > 0 && hasOneBitSet(divisor)) { // If power of 2 then just mask
-            GPRReg dividendGPR = op1.gpr();
-            GPRTemporary result(this);
-            GPRReg resultGPR = result.gpr();
 
-            m_jit.assembler().cmp(dividendGPR, ARMThumbImmediate::makeEncodedImm(0));
-            m_jit.assembler().it(ARMv7Assembler::ConditionLT, false);
-            m_jit.assembler().neg(resultGPR, dividendGPR);
-            m_jit.assembler().mov(resultGPR, dividendGPR);
-            m_jit.and32(TrustedImm32(divisor - 1), resultGPR);
-            m_jit.assembler().it(ARMv7Assembler::ConditionLT);
-            m_jit.assembler().neg(resultGPR, resultGPR);
+    SpeculateIntegerOperand op2(this, node->child2());
 
-            if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
-                // Check that we're not about to create negative zero.
-                JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0));
-                speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, resultGPR));
-                numeratorPositive.link(&m_jit);
-            }
-            integerResult(resultGPR, node);
-            return;
-        }
-    }
-#endif
-
-    SpeculateIntegerOperand op2(this, node->child2());
-#if CPU(X86) || CPU(X86_64)
     GPRTemporary eax(this, X86Registers::eax);
     GPRTemporary edx(this, X86Registers::edx);
     GPRReg op1GPR = op1.gpr();
@@ -3016,43 +2989,87 @@
     
     if (op1SaveGPR != op1GPR)
         unlock(op1SaveGPR);
-            
+
     integerResult(edx.gpr(), node);
+}
+#elif CPU(ARM_THUMB2)
+void SpeculativeJIT::compileSoftModulo(Node* node)
+{
+    // In the fast path, the dividend value could be the final result
+    // (in case of |dividend| < |divisor|), so we speculate it as strict int32.
+    SpeculateStrictInt32Operand op1(this, node->child1());
+    if (isInt32Constant(node->child2().node())) {
+        int32_t divisor = valueOfInt32Constant(node->child2().node());
+        if (divisor > 0 && hasOneBitSet(divisor)) { // If power of 2 then just mask
+            GPRReg dividendGPR = op1.gpr();
+            GPRTemporary result(this);
+            GPRReg resultGPR = result.gpr();
 
-#elif CPU(APPLE_ARMV7S)
-    GPRTemporary temp(this);
-    GPRTemporary quotientThenRemainder(this);
-    GPRTemporary multiplyAnswer(this);
+            m_jit.assembler().cmp(dividendGPR, ARMThumbImmediate::makeEncodedImm(0));
+            m_jit.assembler().it(ARMv7Assembler::ConditionLT, false);
+            m_jit.assembler().neg(resultGPR, dividendGPR);
+            m_jit.assembler().mov(resultGPR, dividendGPR);
+            m_jit.and32(TrustedImm32(divisor - 1), resultGPR);
+            m_jit.assembler().it(ARMv7Assembler::ConditionLT);
+            m_jit.assembler().neg(resultGPR, resultGPR);
+
+            if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
+                // Check that we're not about to create negative zero.
+                JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0));
+                speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, resultGPR));
+                numeratorPositive.link(&m_jit);
+            }
+            integerResult(resultGPR, node);
+            return;
+        }
+    }
+
+    SpeculateIntegerOperand op2(this, node->child2());
+
     GPRReg dividendGPR = op1.gpr();
     GPRReg divisorGPR = op2.gpr();
-    GPRReg quotientThenRemainderGPR = quotientThenRemainder.gpr();
-    GPRReg multiplyAnswerGPR = multiplyAnswer.gpr();
 
-    m_jit.assembler().sdiv(quotientThenRemainderGPR, dividendGPR, divisorGPR);
-    speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, quotientThenRemainderGPR, divisorGPR, multiplyAnswerGPR));
-    m_jit.assembler().sub(quotientThenRemainderGPR, dividendGPR, multiplyAnswerGPR);
+    GPRResult result(this);
+    GPRReg resultGPR = result.gpr();
 
+    if (MacroAssembler::supportsIntegerDiv()) {
+        GPRTemporary multiplyAnswer(this);
+        GPRReg multiplyAnswerGPR = multiplyAnswer.gpr();
+        m_jit.assembler().sdiv(resultGPR, dividendGPR, divisorGPR);
+        speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchMul32(JITCompiler::Overflow, resultGPR, divisorGPR, multiplyAnswerGPR));
+        m_jit.assembler().sub(resultGPR, dividendGPR, multiplyAnswerGPR);
+    } else {
+        flushRegisters();
+        callOperation(operationModOnInts, resultGPR, dividendGPR, divisorGPR);
+    }
+
     // If the user cares about negative zero, then speculate that we're not about
     // to produce negative zero.
     if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) {
         // Check that we're not about to create negative zero.
         JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0));
-        speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, quotientThenRemainderGPR));
+        speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, resultGPR));
         numeratorPositive.link(&m_jit);
     }
 
-    integerResult(quotientThenRemainderGPR, node);
-#else // not architecture that can do integer division
+    integerResult(resultGPR, node);
+}
+#else // CPU type without integer division
+void SpeculativeJIT::compileSoftModulo(Node* node)
+{
+    SpeculateStrictInt32Operand op1(this, node->child1());
+    SpeculateIntegerOperand op2(this, node->child2());
+
     // Do this the *safest* way possible: call out to a C function that will do the modulo,
     // and then attempt to convert back.
-    GPRReg op1GPR = op1.gpr();
-    GPRReg op2GPR = op2.gpr();
-    
+    GPRReg dividendGPR = op1.gpr();
+    GPRReg divisorGPR = op2.gpr();
+
     FPRResult result(this);
-    
+
     flushRegisters();
-    callOperation(operationFModOnInts, result.fpr(), op1GPR, op2GPR);
-    
+    callOperation(operationFModOnInts, result.fpr(), dividendGPR, divisorGPR);
+
     FPRTemporary scratch(this);
     GPRTemporary intResult(this);
     JITCompiler::JumpList failureCases;
@@ -3064,10 +3081,10 @@
         speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, intResult.gpr()));
         numeratorPositive.link(&m_jit);
     }
-    
+
     integerResult(intResult.gpr(), node);
-#endif // CPU(X86) || CPU(X86_64)
 }
+#endif
 
 void SpeculativeJIT::compileAdd(Node* node)
 {
@@ -3476,8 +3493,8 @@
             
     integerResult(eax.gpr(), node);
 }
-#elif CPU(APPLE_ARMV7S)
-void SpeculativeJIT::compileIntegerArithDivForARMv7s(Node* node)
+#elif ENABLE(ARM_INTEGER_DIV)
+void SpeculativeJIT::compileIntegerArithDivForARM(Node* node)
 {
     SpeculateIntegerOperand op1(this, node->child1());
     SpeculateIntegerOperand op2(this, node->child2());

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (149348 => 149349)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2013-04-30 02:55:18 UTC (rev 149349)
@@ -1110,6 +1110,13 @@
         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
         return call;
     }
+    JITCompiler::Call callOperation(Z_DFGOperation_ZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArguments(arg1, arg2);
+        JITCompiler::Call call = m_jit.appendCall(operation);
+        m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
+        return call;
+    }
     JITCompiler::Call callOperation(J_DFGOperation_EGriJsgI operation, GPRReg result, GPRReg arg1, GPRReg arg2, Identifier* identifier)
     {
         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
@@ -1315,6 +1322,13 @@
         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
         return call;
     }
+    JITCompiler::Call callOperation(Z_DFGOperation_ZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    {
+        m_jit.setupArguments(arg1, arg2);
+        JITCompiler::Call call = m_jit.appendCall(operation);
+        m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
+        return call;
+    }
     JITCompiler::Call callOperation(J_DFGOperation_E operation, GPRReg resultTag, GPRReg resultPayload)
     {
         m_jit.setupArgumentsExecState();
@@ -1971,8 +1985,8 @@
     void compileArithIMul(Node*);
 #if CPU(X86) || CPU(X86_64)
     void compileIntegerArithDivForX86(Node*);
-#elif CPU(APPLE_ARMV7S)
-    void compileIntegerArithDivForARMv7s(Node*);
+#elif ENABLE(ARM_INTEGER_DIV)
+    void compileIntegerArithDivForARM(Node*);
 #endif
     void compileArithMod(Node*);
     void compileSoftModulo(Node*);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (149348 => 149349)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2013-04-30 02:55:18 UTC (rev 149349)
@@ -2253,8 +2253,9 @@
         case Int32Use: {
 #if CPU(X86)
             compileIntegerArithDivForX86(node);
-#elif CPU(APPLE_ARMV7S)
-            compileIntegerArithDivForARMv7s(node);
+#elif ENABLE(ARM_INTEGER_DIV)
+            ASSERT(MacroAssembler::supportsIntegerDiv());
+            compileIntegerArithDivForARM(node);
 #else // CPU type without integer divide
             RELEASE_ASSERT_NOT_REACHED(); // should have been coverted into a double divide.
 #endif

Modified: trunk/Source/WTF/ChangeLog (149348 => 149349)


--- trunk/Source/WTF/ChangeLog	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/WTF/ChangeLog	2013-04-30 02:55:18 UTC (rev 149349)
@@ -1,3 +1,12 @@
+2013-04-29  Cosmin Truta  <[email protected]>
+
+        [ARM] Expand the use of integer division
+        https://bugs.webkit.org/show_bug.cgi?id=115138
+
+        Reviewed by Benjamin Poulain.
+
+        * wtf/Platform.h: Added ENABLE_ARM_INTEGER_DIV.
+
 2013-04-29  Anders Carlsson  <[email protected]>
 
         It should be an error to use adoptPtr with RefCounted subclasses

Modified: trunk/Source/WTF/wtf/Platform.h (149348 => 149349)


--- trunk/Source/WTF/wtf/Platform.h	2013-04-30 02:04:50 UTC (rev 149348)
+++ trunk/Source/WTF/wtf/Platform.h	2013-04-30 02:55:18 UTC (rev 149349)
@@ -926,6 +926,10 @@
 #define ENABLE_COMPARE_AND_SWAP 1
 #endif
 
+#if CPU(APPLE_ARMV7S) || (CPU(ARM_THUMB2) && OS(QNX))
+#define ENABLE_ARM_INTEGER_DIV 1
+#endif
+
 #define ENABLE_OBJECT_MARK_LOGGING 0
 
 #if !defined(ENABLE_PARALLEL_GC) && !ENABLE(OBJECT_MARK_LOGGING) && (PLATFORM(MAC) || PLATFORM(IOS) || PLATFORM(BLACKBERRY) || PLATFORM(GTK)) && ENABLE(COMPARE_AND_SWAP)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to