OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/base/bits.h" | 6 #include "src/base/bits.h" |
7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 | 10 |
(...skipping 1822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1833 default: | 1833 default: |
1834 VisitCompare(selector, opcode, g.UseRegister(right), | 1834 VisitCompare(selector, opcode, g.UseRegister(right), |
1835 g.UseRegister(left), cont); | 1835 g.UseRegister(left), cont); |
1836 } | 1836 } |
1837 } else { | 1837 } else { |
1838 VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), | 1838 VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right), |
1839 cont); | 1839 cont); |
1840 } | 1840 } |
1841 } | 1841 } |
1842 | 1842 |
1843 bool IsNodeUnsigned(Node* n) { | |
1844 NodeMatcher m(n); | |
1845 | |
1846 if (m.IsLoad()) { | |
1847 LoadRepresentation load_rep = LoadRepresentationOf(n->op()); | |
1848 return load_rep.IsUnsigned(); | |
1849 } else if (m.IsUnalignedLoad()) { | |
1850 UnalignedLoadRepresentation load_rep = | |
1851 UnalignedLoadRepresentationOf(n->op()); | |
1852 return load_rep.IsUnsigned(); | |
1853 } else { | |
1854 return m.IsUint32Div() || m.IsUint32LessThan() || | |
1855 m.IsUint32LessThanOrEqual() || m.IsUint32Mod() || | |
1856 m.IsUint32MulHigh() || m.IsChangeFloat64ToUint32() || | |
1857 m.IsTruncateFloat64ToUint32() || m.IsTruncateFloat32ToUint32(); | |
1858 } | |
1859 } | |
1860 | |
1861 bool ToSimulateWord32Compare(Node* node) { | |
ahaas
2016/10/11 09:24:58
I think you could even just inline this function a
| |
1862 Node* left = node->InputAt(0); | |
1863 Node* right = node->InputAt(1); | |
1864 | |
1865 bool leftUnsigned = IsNodeUnsigned(left); | |
1866 bool rightUnsigned = IsNodeUnsigned(right); | |
1867 | |
1868 return (leftUnsigned && !rightUnsigned) || (!leftUnsigned && rightUnsigned); | |
miran.karic
2016/10/06 10:24:21
You can just have
return IsNodeUnsigned(left) != I
| |
1869 } | |
1870 | |
1871 // Shared routine for multiple word compare operations. | |
1872 void VisitSimulateWord32Compare(InstructionSelector* selector, Node* node, | |
1873 InstructionCode opcode, FlagsContinuation* cont, | |
1874 bool commutative) { | |
1875 Mips64OperandGenerator g(selector); | |
1876 Node* left = node->InputAt(0); | |
1877 Node* right = node->InputAt(1); | |
1878 InstructionOperand leftOp = g.TempRegister(); | |
1879 InstructionOperand rightOp = g.TempRegister(); | |
1880 | |
1881 selector->Emit(kMips64Dshl, leftOp, g.UseRegister(left), g.TempImmediate(32)); | |
1882 selector->Emit(kMips64Dshl, rightOp, g.UseRegister(right), | |
1883 g.TempImmediate(32)); | |
1884 | |
1885 VisitCompare(selector, opcode, leftOp, rightOp, cont); | |
1886 } | |
1887 | |
1888 void VisitWord32Compare(InstructionSelector* selector, Node* node, | |
1889 FlagsContinuation* cont) { | |
1890 // MIPS64 doesn't support Word32 compare instructions. Instead it relies | |
1891 // that the values in registers are correctly sign-extended and uses | |
1892 // Word64 comparison instead. This behavior is correct in most cases, | |
1893 // but doesn't work when comparing signed with unsigned operands. | |
1894 // We could simulate Word32 compare in all cases but this would create | |
1895 // an unnecessary overhead since unsigned integers are rarely used | |
1896 // in JavaScript. | |
1897 // The solution proposed here tries to match a comparison of signed | |
1898 // with unsigned operand, and perform Word32Compare simulation only | |
1899 // in those cases. Unfortunately, the solution is not complete because | |
1900 // it might skip cases where Word32 compare simulation is needed, so | |
1901 // basically it is a hack. | |
1902 if (ToSimulateWord32Compare(node)) { | |
1903 VisitSimulateWord32Compare(selector, node, kMips64Cmp, cont, false); | |
1904 } else { | |
1905 VisitWordCompare(selector, node, kMips64Cmp, cont, false); | |
1906 } | |
1907 } | |
1908 | |
1843 | 1909 |
1844 void VisitWord32Compare(InstructionSelector* selector, Node* node, | |
1845 FlagsContinuation* cont) { | |
1846 VisitWordCompare(selector, node, kMips64Cmp, cont, false); | |
1847 } | |
1848 | |
1849 | |
1850 void VisitWord64Compare(InstructionSelector* selector, Node* node, | 1910 void VisitWord64Compare(InstructionSelector* selector, Node* node, |
1851 FlagsContinuation* cont) { | 1911 FlagsContinuation* cont) { |
1852 VisitWordCompare(selector, node, kMips64Cmp, cont, false); | 1912 VisitWordCompare(selector, node, kMips64Cmp, cont, false); |
1853 } | 1913 } |
1854 | 1914 |
1855 | 1915 |
1856 | 1916 |
1857 void EmitWordCompareZero(InstructionSelector* selector, Node* value, | 1917 void EmitWordCompareZero(InstructionSelector* selector, Node* value, |
1858 FlagsContinuation* cont) { | 1918 FlagsContinuation* cont) { |
1859 Mips64OperandGenerator g(selector); | 1919 Mips64OperandGenerator g(selector); |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2331 } else { | 2391 } else { |
2332 DCHECK(kArchVariant == kMips64r2); | 2392 DCHECK(kArchVariant == kMips64r2); |
2333 return MachineOperatorBuilder::AlignmentRequirements:: | 2393 return MachineOperatorBuilder::AlignmentRequirements:: |
2334 NoUnalignedAccessSupport(); | 2394 NoUnalignedAccessSupport(); |
2335 } | 2395 } |
2336 } | 2396 } |
2337 | 2397 |
2338 } // namespace compiler | 2398 } // namespace compiler |
2339 } // namespace internal | 2399 } // namespace internal |
2340 } // namespace v8 | 2400 } // namespace v8 |
OLD | NEW |