Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (193787 => 193788)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2015-12-08 23:05:57 UTC (rev 193788)
@@ -465,12 +465,14 @@
jit/JITDivGenerator.cpp
jit/JITExceptions.cpp
jit/JITInlineCacheGenerator.cpp
+ jit/JITLeftShiftGenerator.cpp
jit/JITMulGenerator.cpp
jit/JITOpcodes.cpp
jit/JITOpcodes32_64.cpp
jit/JITOperations.cpp
jit/JITPropertyAccess.cpp
jit/JITPropertyAccess32_64.cpp
+ jit/JITRightShiftGenerator.cpp
jit/JITStubRoutine.cpp
jit/JITSubGenerator.cpp
jit/JITThunks.cpp
Modified: trunk/Source/_javascript_Core/ChangeLog (193787 => 193788)
--- trunk/Source/_javascript_Core/ChangeLog 2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-12-08 23:05:57 UTC (rev 193788)
@@ -1,3 +1,70 @@
+2015-12-08 Mark Lam <mark....@apple.com>
+
+ Snippefy shift operators for the baseline JIT.
+ https://bugs.webkit.org/show_bug.cgi?id=151875
+
+ Reviewed by Geoffrey Garen.
+
+ * CMakeLists.txt:
+ * _javascript_Core.vcxproj/_javascript_Core.vcxproj:
+ * _javascript_Core.vcxproj/_javascript_Core.vcxproj.filters:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * jit/JIT.h:
+
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emitBitBinaryOpFastPath):
+ - Don't need GPRInfo:: qualifiers. Removed them to reduce verbosity.
+ - Also removed the emitStoreInt32() case for storing the result on 32-bit ports.
+ This is because:
+ 1. The client should not make assumptions about whether the snippet fast path
+ only include cases where the result tag already contain the IntTag.
+ 2. The "(op1 == result || op2 == result)" condition for skipping the IntTag
+ storage, is only valid for the bitand, bitor, and bitxor implementations.
+ It is invalid for the lshift implementation that uses this code now.
+ Instead, we'll always unconditionally store what the result tag that the
+ snippet computed for us.
+
+ (JSC::JIT::emit_op_lshift):
+ (JSC::JIT::emitSlow_op_lshift):
+ (JSC::JIT::emitRightShiftFastPath):
+ (JSC::JIT::emit_op_rshift):
+ (JSC::JIT::emitSlow_op_rshift):
+ (JSC::JIT::emit_op_urshift):
+ (JSC::JIT::emitSlow_op_urshift):
+
+ * jit/JITArithmetic32_64.cpp:
+ (JSC::JIT::emit_op_lshift): Deleted.
+ (JSC::JIT::emitSlow_op_lshift): Deleted.
+ (JSC::JIT::emitRightShift): Deleted.
+ (JSC::JIT::emitRightShiftSlowCase): Deleted.
+ (JSC::JIT::emit_op_rshift): Deleted.
+ (JSC::JIT::emitSlow_op_rshift): Deleted.
+ (JSC::JIT::emit_op_urshift): Deleted.
+ (JSC::JIT::emitSlow_op_urshift): Deleted.
+
+ * jit/JITLeftShiftGenerator.cpp: Added.
+ (JSC::JITLeftShiftGenerator::generateFastPath):
+ * jit/JITLeftShiftGenerator.h: Added.
+ (JSC::JITLeftShiftGenerator::JITLeftShiftGenerator):
+ * jit/JITRightShiftGenerator.cpp: Added.
+ (JSC::JITRightShiftGenerator::generateFastPath):
+ * jit/JITRightShiftGenerator.h: Added.
+ (JSC::JITRightShiftGenerator::JITRightShiftGenerator):
+
+ * tests/stress/op_lshift.js:
+ * tests/stress/op_rshift.js:
+ * tests/stress/op_urshift.js:
+ - Fixed some values and added others that are meaningful for testing shifts.
+
+ * tests/stress/resources/binary-op-test.js:
+ (stringifyIfNeeded):
+ (generateBinaryTests):
+ - Fixed the test generator to give unique names to all the generated test
+ functions. Without this, multiple tests may end up using the same global
+ test function. As a result, with enough test values to test, the function may
+ get prematurely JITted, and the computed expected result which is supposed to
+ be computed by the LLINT, may end up being computed by a JIT instead.
+
2015-12-08 Joseph Pecoraro <pecor...@apple.com>
Create a Sandbox SPI header
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj (193787 => 193788)
--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj 2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj 2015-12-08 23:05:57 UTC (rev 193788)
@@ -654,6 +654,7 @@
<ClCompile Include="..\jit\JITDivGenerator.cpp" />
<ClCompile Include="..\jit\JITExceptions.cpp" />
<ClCompile Include="..\jit\JITInlineCacheGenerator.cpp" />
+ <ClCompile Include="..\jit\JITLeftShiftGenerator.cpp" />
<ClCompile Include="..\jit\JITMulGenerator.cpp" />
<ClCompile Include="..\jit\JITOpcodes.cpp" />
<ClCompile Include="..\jit\JITOpcodes32_64.cpp" />
@@ -661,6 +662,7 @@
<ClCompile Include="..\jit\JITOperationsMSVC64.cpp" />
<ClCompile Include="..\jit\JITPropertyAccess.cpp" />
<ClCompile Include="..\jit\JITPropertyAccess32_64.cpp" />
+ <ClCompile Include="..\jit\JITRightShiftGenerator.cpp" />
<ClCompile Include="..\jit\JITStubRoutine.cpp" />
<ClCompile Include="..\jit\JITSubGenerator.cpp" />
<ClCompile Include="..\jit\JITThunks.cpp" />
@@ -1486,8 +1488,10 @@
<ClInclude Include="..\jit\JITExceptions.h" />
<ClInclude Include="..\jit\JITInlineCacheGenerator.h" />
<ClInclude Include="..\jit\JITInlines.h" />
+ <ClInclude Include="..\jit\JITLeftShiftGenerator.h" />
<ClInclude Include="..\jit\JITMulGenerator.h" />
<ClInclude Include="..\jit\JITOperations.h" />
+ <ClInclude Include="..\jit\JITRightShiftGenerator.h" />
<ClInclude Include="..\jit\JITStubRoutine.h" />
<ClInclude Include="..\jit\JITSubGenerator.h" />
<ClInclude Include="..\jit\JITThunks.h" />
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters (193787 => 193788)
--- trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters 2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcxproj/_javascript_Core.vcxproj.filters 2015-12-08 23:05:57 UTC (rev 193788)
@@ -456,6 +456,9 @@
<ClCompile Include="..\jit\JITExceptions.cpp">
<Filter>jit</Filter>
</ClCompile>
+ <ClCompile Include="..\jit\JITLeftShiftGenerator.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
<ClCompile Include="..\jit\JITMulGenerator.cpp">
<Filter>jit</Filter>
</ClCompile>
@@ -471,6 +474,9 @@
<ClCompile Include="..\jit\JITPropertyAccess32_64.cpp">
<Filter>jit</Filter>
</ClCompile>
+ <ClCompile Include="..\jit\JITRightShiftGenerator.cpp">
+ <Filter>jit</Filter>
+ </ClCompile>
<ClCompile Include="..\jit\JITStubRoutine.cpp">
<Filter>jit</Filter>
</ClCompile>
@@ -2567,9 +2573,15 @@
<ClInclude Include="..\jit\JITInlines.h">
<Filter>jit</Filter>
</ClInclude>
+ <ClInclude Include="..\jit\JITLeftShiftGenerator.h">
+ <Filter>jit</Filter>
+ </ClInclude>
<ClInclude Include="..\jit\JITMulGenerator.h">
<Filter>jit</Filter>
</ClInclude>
+ <ClInclude Include="..\jit\JITRightShiftGenerator.h">
+ <Filter>jit</Filter>
+ </ClInclude>
<ClInclude Include="..\jit\JITStubRoutine.h">
<Filter>jit</Filter>
</ClInclude>
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (193787 => 193788)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2015-12-08 23:05:57 UTC (rev 193788)
@@ -2022,6 +2022,10 @@
FE3A06B21C10CB8900390FDD /* JITBitAndGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06AE1C10CB6F00390FDD /* JITBitAndGenerator.h */; settings = {ASSET_TAGS = (); }; };
FE3A06B31C10CB8E00390FDD /* JITBitXorGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06AF1C10CB6F00390FDD /* JITBitXorGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
FE3A06B41C10CB9300390FDD /* JITBitXorGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B01C10CB6F00390FDD /* JITBitXorGenerator.h */; settings = {ASSET_TAGS = (); }; };
+ FE3A06BD1C11040D00390FDD /* JITLeftShiftGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06B61C1103D900390FDD /* JITLeftShiftGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
+ FE3A06BE1C11041200390FDD /* JITLeftShiftGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B71C1103D900390FDD /* JITLeftShiftGenerator.h */; settings = {ASSET_TAGS = (); }; };
+ FE3A06BF1C11041600390FDD /* JITRightShiftGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE3A06B81C1103D900390FDD /* JITRightShiftGenerator.cpp */; settings = {ASSET_TAGS = (); }; };
+ FE3A06C01C11041A00390FDD /* JITRightShiftGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */; settings = {ASSET_TAGS = (); }; };
FE4238901BE18C3C00514737 /* JITSubGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */; };
FE4BFF2B1AD476E700088F87 /* FunctionOverrides.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */; };
FE4BFF2C1AD476E700088F87 /* FunctionOverrides.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */; };
@@ -4203,6 +4207,10 @@
FE3A06AE1C10CB6F00390FDD /* JITBitAndGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITBitAndGenerator.h; sourceTree = "<group>"; };
FE3A06AF1C10CB6F00390FDD /* JITBitXorGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITBitXorGenerator.cpp; sourceTree = "<group>"; };
FE3A06B01C10CB6F00390FDD /* JITBitXorGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITBitXorGenerator.h; sourceTree = "<group>"; };
+ FE3A06B61C1103D900390FDD /* JITLeftShiftGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITLeftShiftGenerator.cpp; sourceTree = "<group>"; };
+ FE3A06B71C1103D900390FDD /* JITLeftShiftGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITLeftShiftGenerator.h; sourceTree = "<group>"; };
+ FE3A06B81C1103D900390FDD /* JITRightShiftGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITRightShiftGenerator.cpp; sourceTree = "<group>"; };
+ FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITRightShiftGenerator.h; sourceTree = "<group>"; };
FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITSubGenerator.cpp; sourceTree = "<group>"; };
FE4BFF291AD476E700088F87 /* FunctionOverrides.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FunctionOverrides.cpp; sourceTree = "<group>"; };
FE4BFF2A1AD476E700088F87 /* FunctionOverrides.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FunctionOverrides.h; sourceTree = "<group>"; };
@@ -4902,6 +4910,8 @@
0FB14E1C18124ACE009B6B4D /* JITInlineCacheGenerator.cpp */,
0FB14E1D18124ACE009B6B4D /* JITInlineCacheGenerator.h */,
86CC85A00EE79A4700288682 /* JITInlines.h */,
+ FE3A06B61C1103D900390FDD /* JITLeftShiftGenerator.cpp */,
+ FE3A06B71C1103D900390FDD /* JITLeftShiftGenerator.h */,
FE1879FF1BFBC73C0038BBCA /* JITMulGenerator.cpp */,
FE187A001BFBC73C0038BBCA /* JITMulGenerator.h */,
BCDD51E90FB8DF74004A8BDC /* JITOpcodes.cpp */,
@@ -4910,6 +4920,8 @@
0F24E54617EE274900ABB217 /* JITOperations.h */,
86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */,
A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */,
+ FE3A06B81C1103D900390FDD /* JITRightShiftGenerator.cpp */,
+ FE3A06B91C1103D900390FDD /* JITRightShiftGenerator.h */,
0F766D2615A8CC1B008F363E /* JITStubRoutine.cpp */,
0F766D1C15A5028D008F363E /* JITStubRoutine.h */,
FE42388F1BE18C1200514737 /* JITSubGenerator.cpp */,
@@ -6801,6 +6813,7 @@
A5EA70E919F5B1010098F5EC /* AlternateDispatchableAgent.h in Headers */,
2A48D1911772365B00C65A5F /* APICallbackFunction.h in Headers */,
BC18C3E50E16F5CD00B34460 /* APICast.h in Headers */,
+ FE3A06BE1C11041200390FDD /* JITLeftShiftGenerator.h in Headers */,
BCF605140E203EF800B9A64D /* ArgList.h in Headers */,
0FE050141AA9091100D33B33 /* ArgumentsMode.h in Headers */,
0F6B1CB91861244C00845D97 /* ArityCheckMode.h in Headers */,
@@ -7310,6 +7323,7 @@
C4703CD5192844CC0013FBEA /* generator_templates.py in Headers */,
0FE050191AA9091100D33B33 /* GenericArguments.h in Headers */,
0FE0501A1AA9091100D33B33 /* GenericArgumentsInlines.h in Headers */,
+ FE3A06C01C11041A00390FDD /* JITRightShiftGenerator.h in Headers */,
0FE0501B1AA9091100D33B33 /* GenericOffset.h in Headers */,
0F2B66E017B6B5AB00A7AE3F /* GenericTypedArrayView.h in Headers */,
0F2B66E117B6B5AB00A7AE3F /* GenericTypedArrayViewInlines.h in Headers */,
@@ -8831,6 +8845,7 @@
A1B9E23D1B4E0D6700BC7FED /* IntlCollatorPrototype.cpp in Sources */,
A1587D6D1B4DC14100D69849 /* IntlDateTimeFormat.cpp in Sources */,
A1587D6F1B4DC14100D69849 /* IntlDateTimeFormatConstructor.cpp in Sources */,
+ FE3A06BF1C11041600390FDD /* JITRightShiftGenerator.cpp in Sources */,
262D85B61C0D650F006ACB61 /* AirFixPartialRegisterStalls.cpp in Sources */,
70B7919B1C024A46002481E2 /* JSGeneratorFunction.cpp in Sources */,
A1587D711B4DC14100D69849 /* IntlDateTimeFormatPrototype.cpp in Sources */,
@@ -8985,6 +9000,7 @@
0F4680CC14BBB17A00BFE272 /* LowLevelInterpreter.cpp in Sources */,
A5AB49DC1BEC8082007020FB /* PerGlobalObjectWrapperWorld.cpp in Sources */,
14B723B212D7DA46003BD5ED /* MachineStackMarker.cpp in Sources */,
+ FE3A06BD1C11040D00390FDD /* JITLeftShiftGenerator.cpp in Sources */,
0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */,
86C568E011A213EE0007F7F0 /* MacroAssemblerARM.cpp in Sources */,
FEB137571BB11EF900CD5100 /* MacroAssemblerARM64.cpp in Sources */,
Modified: trunk/Source/_javascript_Core/jit/JIT.h (193787 => 193788)
--- trunk/Source/_javascript_Core/jit/JIT.h 2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2015-12-08 23:05:57 UTC (rev 193788)
@@ -830,6 +830,12 @@
template<typename SnippetGenerator>
void emitBitBinaryOpFastPath(Instruction* currentInstruction);
+ enum RightShiftType {
+ SignedShift,
+ UnsignedShift
+ };
+ void emitRightShiftFastPath(Instruction* currentInstruction, RightShiftType);
+
Jump checkStructure(RegisterID reg, Structure* structure);
void updateTopCallFrame();
Modified: trunk/Source/_javascript_Core/jit/JITArithmetic.cpp (193787 => 193788)
--- trunk/Source/_javascript_Core/jit/JITArithmetic.cpp 2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/jit/JITArithmetic.cpp 2015-12-08 23:05:57 UTC (rev 193788)
@@ -35,8 +35,10 @@
#include "JITBitXorGenerator.h"
#include "JITDivGenerator.h"
#include "JITInlines.h"
+#include "JITLeftShiftGenerator.h"
#include "JITMulGenerator.h"
#include "JITOperations.h"
+#include "JITRightShiftGenerator.h"
#include "JITSubGenerator.h"
#include "JSArray.h"
#include "JSFunction.h"
@@ -228,141 +230,6 @@
slowPathCall.call();
}
-void JIT::emit_op_lshift(Instruction* currentInstruction)
-{
- int result = currentInstruction[1].u.operand;
- int op1 = currentInstruction[2].u.operand;
- int op2 = currentInstruction[3].u.operand;
-
- emitGetVirtualRegisters(op1, regT0, op2, regT2);
- // FIXME: would we be better using a 'emitJumpSlowCaseIfNotInt' that tests both values at once? - we *probably* ought to be consistent.
- emitJumpSlowCaseIfNotInt(regT0);
- emitJumpSlowCaseIfNotInt(regT2);
- lshift32(regT2, regT0);
- emitTagInt(regT0, regT0);
- emitPutVirtualRegister(result);
-}
-
-void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- linkSlowCase(iter);
- linkSlowCase(iter);
- JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_lshift);
- slowPathCall.call();
-}
-
-void JIT::emit_op_rshift(Instruction* currentInstruction)
-{
- int result = currentInstruction[1].u.operand;
- int op1 = currentInstruction[2].u.operand;
- int op2 = currentInstruction[3].u.operand;
-
- if (isOperandConstantInt(op2)) {
- // isOperandConstantInt(op2) => 1 SlowCase
- emitGetVirtualRegister(op1, regT0);
- emitJumpSlowCaseIfNotInt(regT0);
- // Mask with 0x1f as per ecma-262 11.7.2 step 7.
- rshift32(Imm32(getOperandConstantInt(op2) & 0x1f), regT0);
- } else {
- emitGetVirtualRegisters(op1, regT0, op2, regT2);
- if (supportsFloatingPointTruncate()) {
- Jump lhsIsInt = emitJumpIfInt(regT0);
- // supportsFloatingPoint() && USE(JSVALUE64) => 3 SlowCases
- addSlowCase(emitJumpIfNotNumber(regT0));
- add64(tagTypeNumberRegister, regT0);
- move64ToDouble(regT0, fpRegT0);
- addSlowCase(branchTruncateDoubleToInt32(fpRegT0, regT0));
- lhsIsInt.link(this);
- emitJumpSlowCaseIfNotInt(regT2);
- } else {
- // !supportsFloatingPoint() => 2 SlowCases
- emitJumpSlowCaseIfNotInt(regT0);
- emitJumpSlowCaseIfNotInt(regT2);
- }
- rshift32(regT2, regT0);
- }
- emitTagInt(regT0, regT0);
- emitPutVirtualRegister(result);
-}
-
-void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- int op2 = currentInstruction[3].u.operand;
-
- if (isOperandConstantInt(op2))
- linkSlowCase(iter);
-
- else {
- if (supportsFloatingPointTruncate()) {
- linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
- } else {
- linkSlowCase(iter);
- linkSlowCase(iter);
- }
- }
-
- JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_rshift);
- slowPathCall.call();
-}
-
-void JIT::emit_op_urshift(Instruction* currentInstruction)
-{
- int result = currentInstruction[1].u.operand;
- int op1 = currentInstruction[2].u.operand;
- int op2 = currentInstruction[3].u.operand;
-
- if (isOperandConstantInt(op2)) {
- // isOperandConstantInt(op2) => 1 SlowCase
- emitGetVirtualRegister(op1, regT0);
- emitJumpSlowCaseIfNotInt(regT0);
- // Mask with 0x1f as per ecma-262 11.7.2 step 7.
- urshift32(Imm32(getOperandConstantInt(op2) & 0x1f), regT0);
- } else {
- emitGetVirtualRegisters(op1, regT0, op2, regT2);
- if (supportsFloatingPointTruncate()) {
- Jump lhsIsInt = emitJumpIfInt(regT0);
- // supportsFloatingPoint() && USE(JSVALUE64) => 3 SlowCases
- addSlowCase(emitJumpIfNotNumber(regT0));
- add64(tagTypeNumberRegister, regT0);
- move64ToDouble(regT0, fpRegT0);
- addSlowCase(branchTruncateDoubleToInt32(fpRegT0, regT0));
- lhsIsInt.link(this);
- emitJumpSlowCaseIfNotInt(regT2);
- } else {
- // !supportsFloatingPoint() => 2 SlowCases
- emitJumpSlowCaseIfNotInt(regT0);
- emitJumpSlowCaseIfNotInt(regT2);
- }
- urshift32(regT2, regT0);
- }
- emitTagInt(regT0, regT0);
- emitPutVirtualRegister(result);
-}
-
-void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- int op2 = currentInstruction[3].u.operand;
-
- if (isOperandConstantInt(op2))
- linkSlowCase(iter);
-
- else {
- if (supportsFloatingPointTruncate()) {
- linkSlowCase(iter);
- linkSlowCase(iter);
- linkSlowCase(iter);
- } else {
- linkSlowCase(iter);
- linkSlowCase(iter);
- }
- }
-
- JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_urshift);
- slowPathCall.call();
-}
-
void JIT::emit_op_unsigned(Instruction* currentInstruction)
{
int result = currentInstruction[1].u.operand;
@@ -639,13 +506,13 @@
int op2 = currentInstruction[3].u.operand;
#if USE(JSVALUE64)
- JSValueRegs leftRegs = JSValueRegs(GPRInfo::regT0);
- JSValueRegs rightRegs = JSValueRegs(GPRInfo::regT1);
+ JSValueRegs leftRegs = JSValueRegs(regT0);
+ JSValueRegs rightRegs = JSValueRegs(regT1);
JSValueRegs resultRegs = leftRegs;
GPRReg scratchGPR = GPRInfo::regT2;
#else
- JSValueRegs leftRegs = JSValueRegs(GPRInfo::regT1, GPRInfo::regT0);
- JSValueRegs rightRegs = JSValueRegs(GPRInfo::regT3, GPRInfo::regT2);
+ JSValueRegs leftRegs = JSValueRegs(regT1, regT0);
+ JSValueRegs rightRegs = JSValueRegs(regT3, regT2);
JSValueRegs resultRegs = leftRegs;
GPRReg scratchGPR = InvalidGPRReg;
#endif
@@ -671,11 +538,7 @@
if (gen.didEmitFastPath()) {
gen.endJumpList().link(this);
-#if USE(JSVALUE32_64)
- emitStoreInt32(result, resultRegs.payloadGPR(), op1 == result || op2 == result);
-#else
emitPutVirtualRegister(result, resultRegs);
-#endif
addSlowCase(gen.slowPathJumpList());
} else {
@@ -725,6 +588,101 @@
slowPathCall.call();
}
+void JIT::emit_op_lshift(Instruction* currentInstruction)
+{
+ emitBitBinaryOpFastPath<JITLeftShiftGenerator>(currentInstruction);
+}
+
+void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkAllSlowCasesForBytecodeOffset(m_slowCases, iter, m_bytecodeOffset);
+
+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_lshift);
+ slowPathCall.call();
+}
+
+void JIT::emitRightShiftFastPath(Instruction* currentInstruction, RightShiftType rightShiftType)
+{
+ int result = currentInstruction[1].u.operand;
+ int op1 = currentInstruction[2].u.operand;
+ int op2 = currentInstruction[3].u.operand;
+
+#if USE(JSVALUE64)
+ JSValueRegs leftRegs = JSValueRegs(regT0);
+ JSValueRegs rightRegs = JSValueRegs(regT1);
+ JSValueRegs resultRegs = leftRegs;
+ GPRReg scratchGPR = regT2;
+ FPRReg scratchFPR = InvalidFPRReg;
+#else
+ JSValueRegs leftRegs = JSValueRegs(regT1, regT0);
+ JSValueRegs rightRegs = JSValueRegs(regT3, regT2);
+ JSValueRegs resultRegs = leftRegs;
+ GPRReg scratchGPR = regT4;
+ FPRReg scratchFPR = fpRegT2;
+#endif
+
+ SnippetOperand leftOperand;
+ SnippetOperand rightOperand;
+
+ if (isOperandConstantInt(op1))
+ leftOperand.setConstInt32(getOperandConstantInt(op1));
+ if (isOperandConstantInt(op2))
+ rightOperand.setConstInt32(getOperandConstantInt(op2));
+
+ RELEASE_ASSERT(!leftOperand.isConst() || !rightOperand.isConst());
+
+ if (!leftOperand.isConst())
+ emitGetVirtualRegister(op1, leftRegs);
+ if (!rightOperand.isConst())
+ emitGetVirtualRegister(op2, rightRegs);
+
+ JITRightShiftGenerator::ShiftType snippetShiftType =
+ (rightShiftType == SignedShift) ? JITRightShiftGenerator::SignedShift : JITRightShiftGenerator::UnsignedShift;
+
+ JITRightShiftGenerator gen(leftOperand, rightOperand, resultRegs, leftRegs, rightRegs,
+ fpRegT0, scratchGPR, scratchFPR, snippetShiftType);
+
+ gen.generateFastPath(*this);
+
+ if (gen.didEmitFastPath()) {
+ gen.endJumpList().link(this);
+ emitPutVirtualRegister(result, resultRegs);
+
+ addSlowCase(gen.slowPathJumpList());
+ } else {
+ ASSERT(gen.endJumpList().empty());
+ ASSERT(gen.slowPathJumpList().empty());
+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_add);
+ slowPathCall.call();
+ }
+}
+
+void JIT::emit_op_rshift(Instruction* currentInstruction)
+{
+ emitRightShiftFastPath(currentInstruction, RightShiftType::SignedShift);
+}
+
+void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkAllSlowCasesForBytecodeOffset(m_slowCases, iter, m_bytecodeOffset);
+
+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_rshift);
+ slowPathCall.call();
+}
+
+void JIT::emit_op_urshift(Instruction* currentInstruction)
+{
+ emitRightShiftFastPath(currentInstruction, RightShiftType::UnsignedShift);
+}
+
+void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+ linkAllSlowCasesForBytecodeOffset(m_slowCases, iter, m_bytecodeOffset);
+
+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_urshift);
+ slowPathCall.call();
+}
+
void JIT::emit_op_add(Instruction* currentInstruction)
{
int result = currentInstruction[1].u.operand;
Modified: trunk/Source/_javascript_Core/jit/JITArithmetic32_64.cpp (193787 => 193788)
--- trunk/Source/_javascript_Core/jit/JITArithmetic32_64.cpp 2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/jit/JITArithmetic32_64.cpp 2015-12-08 23:05:57 UTC (rev 193788)
@@ -154,155 +154,6 @@
emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, returnValueGPR), target);
}
-// LeftShift (<<)
-
-void JIT::emit_op_lshift(Instruction* currentInstruction)
-{
- int dst = currentInstruction[1].u.operand;
- int op1 = currentInstruction[2].u.operand;
- int op2 = currentInstruction[3].u.operand;
-
- if (isOperandConstantInt(op2)) {
- emitLoad(op1, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
- lshift32(Imm32(getConstantOperand(op2).asInt32()), regT0);
- emitStoreInt32(dst, regT0, dst == op1);
- return;
- }
-
- emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- if (!isOperandConstantInt(op1))
- addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
- addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
- lshift32(regT2, regT0);
- emitStoreInt32(dst, regT0, dst == op1 || dst == op2);
-}
-
-void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- int op1 = currentInstruction[2].u.operand;
- int op2 = currentInstruction[3].u.operand;
-
- if (!isOperandConstantInt(op1) && !isOperandConstantInt(op2))
- linkSlowCase(iter); // int32 check
- linkSlowCase(iter); // int32 check
-
- JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_lshift);
- slowPathCall.call();
-}
-
-// RightShift (>>) and UnsignedRightShift (>>>) helper
-
-void JIT::emitRightShift(Instruction* currentInstruction, bool isUnsigned)
-{
- int dst = currentInstruction[1].u.operand;
- int op1 = currentInstruction[2].u.operand;
- int op2 = currentInstruction[3].u.operand;
-
- // Slow case of rshift makes assumptions about what registers hold the
- // shift arguments, so any changes must be updated there as well.
- if (isOperandConstantInt(op2)) {
- emitLoad(op1, regT1, regT0);
- addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
- int shift = getConstantOperand(op2).asInt32() & 0x1f;
- if (shift) {
- if (isUnsigned)
- urshift32(Imm32(shift), regT0);
- else
- rshift32(Imm32(shift), regT0);
- }
- emitStoreInt32(dst, regT0, dst == op1);
- } else {
- emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
- if (!isOperandConstantInt(op1))
- addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
- addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
- if (isUnsigned)
- urshift32(regT2, regT0);
- else
- rshift32(regT2, regT0);
- emitStoreInt32(dst, regT0, dst == op1);
- }
-}
-
-void JIT::emitRightShiftSlowCase(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter, bool isUnsigned)
-{
- int dst = currentInstruction[1].u.operand;
- int op1 = currentInstruction[2].u.operand;
- int op2 = currentInstruction[3].u.operand;
- if (isOperandConstantInt(op2)) {
- int shift = getConstantOperand(op2).asInt32() & 0x1f;
- // op1 = regT1:regT0
- linkSlowCase(iter); // int32 check
- if (supportsFloatingPointTruncate()) {
- JumpList failures;
- failures.append(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::LowestTag)));
- emitLoadDouble(op1, fpRegT0);
- failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0));
- if (shift) {
- if (isUnsigned)
- urshift32(Imm32(shift), regT0);
- else
- rshift32(Imm32(shift), regT0);
- }
- move(TrustedImm32(JSValue::Int32Tag), regT1);
- emitStoreInt32(dst, regT0, false);
- emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
- failures.link(this);
- }
- } else {
- // op1 = regT1:regT0
- // op2 = regT3:regT2
- if (!isOperandConstantInt(op1)) {
- linkSlowCase(iter); // int32 check -- op1 is not an int
- if (supportsFloatingPointTruncate()) {
- JumpList failures;
- failures.append(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag))); // op1 is not a double
- emitLoadDouble(op1, fpRegT0);
- failures.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); // op2 is not an int
- failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0));
- if (isUnsigned)
- urshift32(regT2, regT0);
- else
- rshift32(regT2, regT0);
- move(TrustedImm32(JSValue::Int32Tag), regT1);
- emitStoreInt32(dst, regT0, false);
- emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
- failures.link(this);
- }
- }
-
- linkSlowCase(iter); // int32 check - op2 is not an int
- }
-
- JITSlowPathCall slowPathCall(this, currentInstruction, isUnsigned ? slow_path_urshift : slow_path_rshift);
- slowPathCall.call();
-}
-
-// RightShift (>>)
-
-void JIT::emit_op_rshift(Instruction* currentInstruction)
-{
- emitRightShift(currentInstruction, false);
-}
-
-void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- emitRightShiftSlowCase(currentInstruction, iter, false);
-}
-
-// UnsignedRightShift (>>>)
-
-void JIT::emit_op_urshift(Instruction* currentInstruction)
-{
- emitRightShift(currentInstruction, true);
-}
-
-void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
- emitRightShiftSlowCase(currentInstruction, iter, true);
-}
-
void JIT::emit_op_unsigned(Instruction* currentInstruction)
{
int result = currentInstruction[1].u.operand;
Added: trunk/Source/_javascript_Core/jit/JITLeftShiftGenerator.cpp (0 => 193788)
--- trunk/Source/_javascript_Core/jit/JITLeftShiftGenerator.cpp (rev 0)
+++ trunk/Source/_javascript_Core/jit/JITLeftShiftGenerator.cpp 2015-12-08 23:05:57 UTC (rev 193788)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2015 Apple Inc. 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 APPLE INC. ``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 APPLE INC. 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"
+#include "JITLeftShiftGenerator.h"
+
+#if ENABLE(JIT)
+
+namespace JSC {
+
+void JITLeftShiftGenerator::generateFastPath(CCallHelpers& jit)
+{
+ ASSERT(!m_leftOperand.isConstInt32() || !m_rightOperand.isConstInt32());
+
+ m_didEmitFastPath = true;
+
+ if (m_rightOperand.isConstInt32()) {
+ // Try to do (intVar << intConstant).
+ m_slowPathJumpList.append(jit.branchIfNotInt32(m_left));
+
+ jit.moveValueRegs(m_left, m_result);
+ jit.lshift32(CCallHelpers::Imm32(m_rightOperand.asConstInt32()), m_result.payloadGPR());
+
+ } else {
+ // Try to do (intConstant << intVar) or (intVar << intVar).
+ m_slowPathJumpList.append(jit.branchIfNotInt32(m_right));
+
+ if (m_leftOperand.isConstInt32()) {
+#if USE(JSVALUE32_64)
+ jit.move(m_right.tagGPR(), m_result.tagGPR());
+#endif
+ jit.move(CCallHelpers::Imm32(m_leftOperand.asConstInt32()), m_result.payloadGPR());
+ } else {
+ m_slowPathJumpList.append(jit.branchIfNotInt32(m_left));
+ jit.moveValueRegs(m_left, m_result);
+ }
+
+ jit.lshift32(m_right.payloadGPR(), m_result.payloadGPR());
+ }
+
+#if USE(JSVALUE64)
+ jit.or64(GPRInfo::tagTypeNumberRegister, m_result.payloadGPR());
+#endif
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
Added: trunk/Source/_javascript_Core/jit/JITLeftShiftGenerator.h (0 => 193788)
--- trunk/Source/_javascript_Core/jit/JITLeftShiftGenerator.h (rev 0)
+++ trunk/Source/_javascript_Core/jit/JITLeftShiftGenerator.h 2015-12-08 23:05:57 UTC (rev 193788)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 Apple Inc. 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 APPLE INC. ``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 APPLE INC. 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.
+ */
+
+#ifndef JITLeftShiftGenerator_h
+#define JITLeftShiftGenerator_h
+
+#if ENABLE(JIT)
+
+#include "JITBitBinaryOpGenerator.h"
+
+namespace JSC {
+
+class JITLeftShiftGenerator : public JITBitBinaryOpGenerator {
+public:
+ JITLeftShiftGenerator(const SnippetOperand& leftOperand, const SnippetOperand& rightOperand,
+ JSValueRegs result, JSValueRegs left, JSValueRegs right, GPRReg unused = InvalidGPRReg)
+ : JITBitBinaryOpGenerator(leftOperand, rightOperand, result, left, right, unused)
+ { }
+
+ void generateFastPath(CCallHelpers&);
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // JITLeftShiftGenerator_h
Added: trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.cpp (0 => 193788)
--- trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.cpp (rev 0)
+++ trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.cpp 2015-12-08 23:05:57 UTC (rev 193788)
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2015 Apple Inc. 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 APPLE INC. ``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 APPLE INC. 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"
+#include "JITRightShiftGenerator.h"
+
+#if ENABLE(JIT)
+
+namespace JSC {
+
+void JITRightShiftGenerator::generateFastPath(CCallHelpers& jit)
+{
+ ASSERT(m_scratchGPR != InvalidGPRReg);
+ ASSERT(m_scratchGPR != m_left.payloadGPR());
+ ASSERT(m_scratchGPR != m_right.payloadGPR());
+#if USE(JSVALUE32_64)
+ ASSERT(m_scratchGPR != m_left.tagGPR());
+ ASSERT(m_scratchGPR != m_right.tagGPR());
+ ASSERT(m_scratchFPR != InvalidFPRReg);
+#endif
+
+ ASSERT(!m_leftOperand.isConstInt32() || !m_rightOperand.isConstInt32());
+
+ m_didEmitFastPath = true;
+
+ if (m_rightOperand.isConstInt32()) {
+ // Try to do (intVar >> intConstant).
+ CCallHelpers::Jump notInt = jit.branchIfNotInt32(m_left);
+
+ jit.moveValueRegs(m_left, m_result);
+ int32_t shiftAmount = m_rightOperand.asConstInt32() & 0x1f;
+ if (shiftAmount) {
+ if (m_shiftType == SignedShift)
+ jit.rshift32(CCallHelpers::Imm32(shiftAmount), m_result.payloadGPR());
+ else
+ jit.urshift32(CCallHelpers::Imm32(shiftAmount), m_result.payloadGPR());
+#if USE(JSVALUE64)
+ jit.or64(GPRInfo::tagTypeNumberRegister, m_result.payloadGPR());
+#endif
+ }
+
+ if (jit.supportsFloatingPointTruncate()) {
+ m_endJumpList.append(jit.jump()); // Terminate the above case before emitting more code.
+
+ // Try to do (doubleVar >> intConstant).
+ notInt.link(&jit);
+
+ m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
+
+ jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
+ m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
+
+ if (shiftAmount) {
+ if (m_shiftType == SignedShift)
+ jit.rshift32(CCallHelpers::Imm32(shiftAmount), m_scratchGPR);
+ else
+ jit.urshift32(CCallHelpers::Imm32(shiftAmount), m_scratchGPR);
+ }
+ jit.boxInt32(m_scratchGPR, m_result);
+
+ } else
+ m_slowPathJumpList.append(notInt);
+
+ } else {
+ // Try to do (intConstant >> intVar) or (intVar >> intVar).
+ m_slowPathJumpList.append(jit.branchIfNotInt32(m_right));
+
+ CCallHelpers::Jump notInt;
+ if (m_leftOperand.isConstInt32()) {
+#if USE(JSVALUE32_64)
+ jit.move(m_right.tagGPR(), m_result.tagGPR());
+#endif
+ jit.move(CCallHelpers::Imm32(m_leftOperand.asConstInt32()), m_result.payloadGPR());
+ } else {
+ notInt = jit.branchIfNotInt32(m_left);
+ jit.moveValueRegs(m_left, m_result);
+ }
+
+ if (m_shiftType == SignedShift)
+ jit.rshift32(m_right.payloadGPR(), m_result.payloadGPR());
+ else
+ jit.urshift32(m_right.payloadGPR(), m_result.payloadGPR());
+#if USE(JSVALUE64)
+ jit.or64(GPRInfo::tagTypeNumberRegister, m_result.payloadGPR());
+#endif
+ if (m_leftOperand.isConstInt32())
+ return;
+
+ if (jit.supportsFloatingPointTruncate()) {
+ m_endJumpList.append(jit.jump()); // Terminate the above case before emitting more code.
+
+ // Try to do (doubleVar >> intVar).
+ notInt.link(&jit);
+
+ m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
+ jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
+ m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
+
+ if (m_shiftType == SignedShift)
+ jit.rshift32(m_right.payloadGPR(), m_scratchGPR);
+ else
+ jit.urshift32(m_right.payloadGPR(), m_scratchGPR);
+ jit.boxInt32(m_scratchGPR, m_result);
+
+ } else
+ m_slowPathJumpList.append(notInt);
+ }
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
Added: trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.h (0 => 193788)
--- trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.h (rev 0)
+++ trunk/Source/_javascript_Core/jit/JITRightShiftGenerator.h 2015-12-08 23:05:57 UTC (rev 193788)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2015 Apple Inc. 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 APPLE INC. ``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 APPLE INC. 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.
+ */
+
+#ifndef JITRightShiftGenerator_h
+#define JITRightShiftGenerator_h
+
+#if ENABLE(JIT)
+
+#include "JITBitBinaryOpGenerator.h"
+
+namespace JSC {
+
+class JITRightShiftGenerator : public JITBitBinaryOpGenerator {
+public:
+ enum ShiftType {
+ SignedShift,
+ UnsignedShift
+ };
+
+ JITRightShiftGenerator(const SnippetOperand& leftOperand, const SnippetOperand& rightOperand,
+ JSValueRegs result, JSValueRegs left, JSValueRegs right,
+ FPRReg leftFPR, GPRReg scratchGPR, FPRReg scratchFPR, ShiftType type = SignedShift)
+ : JITBitBinaryOpGenerator(leftOperand, rightOperand, result, left, right, scratchGPR)
+ , m_shiftType(type)
+ , m_leftFPR(leftFPR)
+ , m_scratchFPR(scratchFPR)
+ { }
+
+ void generateFastPath(CCallHelpers&);
+
+private:
+ ShiftType m_shiftType;
+ FPRReg m_leftFPR;
+ FPRReg m_scratchFPR;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // JITRightShiftGenerator_h
Modified: trunk/Source/_javascript_Core/tests/stress/op_lshift.js (193787 => 193788)
--- trunk/Source/_javascript_Core/tests/stress/op_lshift.js 2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/tests/stress/op_lshift.js 2015-12-08 23:05:57 UTC (rev 193788)
@@ -30,6 +30,8 @@
'negInfinity',
'100.2', // Some random small double value.
'-100.2',
+ '2147483647.5', // Value that will get truncated down to 0x7fffffff.
+ '-2147483647.5',
'54294967296.2923', // Some random large double value.
'-54294967296.2923',
@@ -49,8 +51,8 @@
'-0x7fff',
'0x10000',
'-0x10000',
- '0x7ffffff',
- '-0x7ffffff',
+ '0x7fffffff',
+ '-0x7fffffff',
'0x100000000',
'-0x100000000',
Modified: trunk/Source/_javascript_Core/tests/stress/op_rshift.js (193787 => 193788)
--- trunk/Source/_javascript_Core/tests/stress/op_rshift.js 2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/tests/stress/op_rshift.js 2015-12-08 23:05:57 UTC (rev 193788)
@@ -31,6 +31,8 @@
'negInfinity',
'100.2', // Some random small double value.
'-100.2',
+ '2147483647.5', // Value that will get truncated down to 0x7fffffff.
+ '-2147483647.5',
'54294967296.2923', // Some random large double value.
'-54294967296.2923',
@@ -50,8 +52,8 @@
'-0x7fff',
'0x10000',
'-0x10000',
- '0x7ffffff',
- '-0x7ffffff',
+ '0x7fffffff',
+ '-0x7fffffff',
'0x100000000',
'-0x100000000',
Modified: trunk/Source/_javascript_Core/tests/stress/op_urshift.js (193787 => 193788)
--- trunk/Source/_javascript_Core/tests/stress/op_urshift.js 2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/tests/stress/op_urshift.js 2015-12-08 23:05:57 UTC (rev 193788)
@@ -31,6 +31,8 @@
'negInfinity',
'100.2', // Some random small double value.
'-100.2',
+ '2147483647.5', // Value that will get truncated down to 0x7fffffff.
+ '-2147483647.5',
'54294967296.2923', // Some random large double value.
'-54294967296.2923',
@@ -50,8 +52,8 @@
'-0x7fff',
'0x10000',
'-0x10000',
- '0x7ffffff',
- '-0x7ffffff',
+ '0x7fffffff',
+ '-0x7fffffff',
'0x100000000',
'-0x100000000',
Modified: trunk/Source/_javascript_Core/tests/stress/resources/binary-op-test.js (193787 => 193788)
--- trunk/Source/_javascript_Core/tests/stress/resources/binary-op-test.js 2015-12-08 23:05:52 UTC (rev 193787)
+++ trunk/Source/_javascript_Core/tests/stress/resources/binary-op-test.js 2015-12-08 23:05:57 UTC (rev 193788)
@@ -34,8 +34,9 @@
}
// operandTypes are "VarVar", "VarConst", and "ConstVar".
+var funcIndex = 0;
function generateBinaryTests(tests, opName, op, operandTypes, leftValues, rightValues) {
- var funcName = opName + operandTypes;
+ var funcNamePrefix = opName + operandTypes;
for (var i = 0; i < leftValues.length; i++) {
for (var j = 0; j < rightValues.length; j++) {
var test = { };
@@ -44,6 +45,7 @@
test.x = eval(xStr);
test.y = eval(yStr);
+ var funcName = funcNamePrefix + funcIndex++;
if (operandTypes == "VarVar") {
test.signature = funcName + "(x, y) { return x " + op + " y }";
test.name = test.signature + " with x:" + xStr + ", y:" + yStr;