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)