Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(95)

Side by Side Diff: src/compiler/mips64/instruction-selector-mips64.cc

Issue 2391393003: MIPS64: Fix Word32Compare turbofan operator implementation when comparing signed with unsigned oper… (Closed)
Patch Set: Add runtime checks to make sure optimized compare always works Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 // Shared routine for multiple word compare operations.
1862 void VisitFullWord32Compare(InstructionSelector* selector, Node* node,
1863 InstructionCode opcode, FlagsContinuation* cont) {
1864 Mips64OperandGenerator g(selector);
1865 InstructionOperand leftOp = g.TempRegister();
1866 InstructionOperand rightOp = g.TempRegister();
1867
1868 selector->Emit(kMips64Dshl, leftOp, g.UseRegister(node->InputAt(0)),
1869 g.TempImmediate(32));
1870 selector->Emit(kMips64Dshl, rightOp, g.UseRegister(node->InputAt(1)),
1871 g.TempImmediate(32));
1872
1873 VisitCompare(selector, opcode, leftOp, rightOp, cont);
1874 }
1875
1876 void VisitOptimizedWord32Compare(InstructionSelector* selector, Node* node,
1877 InstructionCode opcode,
1878 FlagsContinuation* cont) {
1879 if (FLAG_debug_code) {
1880 Mips64OperandGenerator g(selector);
1881 InstructionOperand leftOp = g.TempRegister();
1882 InstructionOperand rightOp = g.TempRegister();
1883 InstructionOperand optimizedResult = g.TempRegister();
1884 InstructionOperand fullResult = g.TempRegister();
1885 FlagsCondition condition = cont->condition();
1886 InstructionCode testOpcode = opcode |
1887 FlagsConditionField::encode(condition) |
1888 FlagsModeField::encode(kFlags_set);
1889
1890 selector->Emit(testOpcode, optimizedResult, g.UseRegister(node->InputAt(0)),
1891 g.UseRegister(node->InputAt(1)));
1892
1893 selector->Emit(kMips64Dshl, leftOp, g.UseRegister(node->InputAt(0)),
1894 g.TempImmediate(32));
1895 selector->Emit(kMips64Dshl, rightOp, g.UseRegister(node->InputAt(1)),
1896 g.TempImmediate(32));
1897 selector->Emit(testOpcode, fullResult, leftOp, rightOp);
1898
1899 selector->Emit(
1900 kMips64AssertEqual, g.NoOutput(), optimizedResult, fullResult,
1901 g.TempImmediate(BailoutReason::kUnsupportedNonPrimitiveCompare));
1902 }
1903
1904 VisitWordCompare(selector, node, opcode, cont, false);
1905 }
1906
1907 void VisitWord32Compare(InstructionSelector* selector, Node* node,
1908 FlagsContinuation* cont) {
1909 // MIPS64 doesn't support Word32 compare instructions. Instead it relies
1910 // that the values in registers are correctly sign-extended and uses
1911 // Word64 comparison instead. This behavior is correct in most cases,
1912 // but doesn't work when comparing signed with unsigned operands.
1913 // We could simulate full Word32 compare in all cases but this would
1914 // create an unnecessary overhead since unsigned integers are rarely
1915 // used in JavaScript.
1916 // The solution proposed here tries to match a comparison of signed
1917 // with unsigned operand, and perform full Word32Compare only
1918 // in those cases. Unfortunately, the solution is not complete because
1919 // it might skip cases where Word32 full compare is needed, so
1920 // basically it is a hack.
1921 if (IsNodeUnsigned(node->InputAt(0)) != IsNodeUnsigned(node->InputAt(1))) {
1922 VisitFullWord32Compare(selector, node, kMips64Cmp, cont);
1923 } else {
1924 VisitOptimizedWord32Compare(selector, node, kMips64Cmp, cont);
1925 }
1926 }
1927
1843 1928
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, 1929 void VisitWord64Compare(InstructionSelector* selector, Node* node,
1851 FlagsContinuation* cont) { 1930 FlagsContinuation* cont) {
1852 VisitWordCompare(selector, node, kMips64Cmp, cont, false); 1931 VisitWordCompare(selector, node, kMips64Cmp, cont, false);
1853 } 1932 }
1854 1933
1855 1934
1856 1935
1857 void EmitWordCompareZero(InstructionSelector* selector, Node* value, 1936 void EmitWordCompareZero(InstructionSelector* selector, Node* value,
1858 FlagsContinuation* cont) { 1937 FlagsContinuation* cont) {
1859 Mips64OperandGenerator g(selector); 1938 Mips64OperandGenerator g(selector);
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
2331 } else { 2410 } else {
2332 DCHECK(kArchVariant == kMips64r2); 2411 DCHECK(kArchVariant == kMips64r2);
2333 return MachineOperatorBuilder::AlignmentRequirements:: 2412 return MachineOperatorBuilder::AlignmentRequirements::
2334 NoUnalignedAccessSupport(); 2413 NoUnalignedAccessSupport();
2335 } 2414 }
2336 } 2415 }
2337 2416
2338 } // namespace compiler 2417 } // namespace compiler
2339 } // namespace internal 2418 } // namespace internal
2340 } // namespace v8 2419 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/mips64/instruction-codes-mips64.h ('k') | test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698