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 2019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2030 } else { | 2030 } else { |
2031 selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, | 2031 selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, |
2032 g.TempImmediate(0)); | 2032 g.TempImmediate(0)); |
2033 } | 2033 } |
2034 } | 2034 } |
2035 | 2035 |
2036 | 2036 |
2037 // Shared routine for word comparisons against zero. | 2037 // Shared routine for word comparisons against zero. |
2038 void VisitWordCompareZero(InstructionSelector* selector, Node* user, | 2038 void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
2039 Node* value, FlagsContinuation* cont) { | 2039 Node* value, FlagsContinuation* cont) { |
| 2040 // Try to combine with comparisons against 0 by simply inverting the branch. |
2040 while (selector->CanCover(user, value)) { | 2041 while (selector->CanCover(user, value)) { |
| 2042 if (value->opcode() == IrOpcode::kWord32Equal) { |
| 2043 Int32BinopMatcher m(value); |
| 2044 if (!m.right().Is(0)) break; |
| 2045 user = value; |
| 2046 value = m.left().node(); |
| 2047 } else if (value->opcode() == IrOpcode::kWord64Equal) { |
| 2048 Int64BinopMatcher m(value); |
| 2049 if (!m.right().Is(0)) break; |
| 2050 user = value; |
| 2051 value = m.left().node(); |
| 2052 } else { |
| 2053 break; |
| 2054 } |
| 2055 |
| 2056 cont->Negate(); |
| 2057 } |
| 2058 |
| 2059 if (selector->CanCover(user, value)) { |
2041 switch (value->opcode()) { | 2060 switch (value->opcode()) { |
2042 case IrOpcode::kWord32Equal: { | 2061 case IrOpcode::kWord32Equal: |
2043 // Combine with comparisons against 0 by simply inverting the | |
2044 // continuation. | |
2045 Int32BinopMatcher m(value); | |
2046 if (m.right().Is(0)) { | |
2047 user = value; | |
2048 value = m.left().node(); | |
2049 cont->Negate(); | |
2050 continue; | |
2051 } | |
2052 cont->OverwriteAndNegateIfEqual(kEqual); | 2062 cont->OverwriteAndNegateIfEqual(kEqual); |
2053 return VisitWord32Compare(selector, value, cont); | 2063 return VisitWord32Compare(selector, value, cont); |
2054 } | |
2055 case IrOpcode::kInt32LessThan: | 2064 case IrOpcode::kInt32LessThan: |
2056 cont->OverwriteAndNegateIfEqual(kSignedLessThan); | 2065 cont->OverwriteAndNegateIfEqual(kSignedLessThan); |
2057 return VisitWord32Compare(selector, value, cont); | 2066 return VisitWord32Compare(selector, value, cont); |
2058 case IrOpcode::kInt32LessThanOrEqual: | 2067 case IrOpcode::kInt32LessThanOrEqual: |
2059 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); | 2068 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); |
2060 return VisitWord32Compare(selector, value, cont); | 2069 return VisitWord32Compare(selector, value, cont); |
2061 case IrOpcode::kUint32LessThan: | 2070 case IrOpcode::kUint32LessThan: |
2062 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); | 2071 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); |
2063 return VisitWord32Compare(selector, value, cont); | 2072 return VisitWord32Compare(selector, value, cont); |
2064 case IrOpcode::kUint32LessThanOrEqual: | 2073 case IrOpcode::kUint32LessThanOrEqual: |
2065 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); | 2074 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); |
2066 return VisitWord32Compare(selector, value, cont); | 2075 return VisitWord32Compare(selector, value, cont); |
2067 case IrOpcode::kWord64Equal: { | 2076 case IrOpcode::kWord64Equal: |
2068 // Combine with comparisons against 0 by simply inverting the | |
2069 // continuation. | |
2070 Int64BinopMatcher m(value); | |
2071 if (m.right().Is(0)) { | |
2072 user = value; | |
2073 value = m.left().node(); | |
2074 cont->Negate(); | |
2075 continue; | |
2076 } | |
2077 cont->OverwriteAndNegateIfEqual(kEqual); | 2077 cont->OverwriteAndNegateIfEqual(kEqual); |
2078 return VisitWord64Compare(selector, value, cont); | 2078 return VisitWord64Compare(selector, value, cont); |
2079 } | |
2080 case IrOpcode::kInt64LessThan: | 2079 case IrOpcode::kInt64LessThan: |
2081 cont->OverwriteAndNegateIfEqual(kSignedLessThan); | 2080 cont->OverwriteAndNegateIfEqual(kSignedLessThan); |
2082 return VisitWord64Compare(selector, value, cont); | 2081 return VisitWord64Compare(selector, value, cont); |
2083 case IrOpcode::kInt64LessThanOrEqual: | 2082 case IrOpcode::kInt64LessThanOrEqual: |
2084 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); | 2083 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); |
2085 return VisitWord64Compare(selector, value, cont); | 2084 return VisitWord64Compare(selector, value, cont); |
2086 case IrOpcode::kUint64LessThan: | 2085 case IrOpcode::kUint64LessThan: |
2087 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); | 2086 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan); |
2088 return VisitWord64Compare(selector, value, cont); | 2087 return VisitWord64Compare(selector, value, cont); |
2089 case IrOpcode::kUint64LessThanOrEqual: | 2088 case IrOpcode::kUint64LessThanOrEqual: |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2140 } | 2139 } |
2141 } | 2140 } |
2142 } | 2141 } |
2143 break; | 2142 break; |
2144 case IrOpcode::kWord32And: | 2143 case IrOpcode::kWord32And: |
2145 case IrOpcode::kWord64And: | 2144 case IrOpcode::kWord64And: |
2146 return VisitWordCompare(selector, value, kMips64Tst, cont, true); | 2145 return VisitWordCompare(selector, value, kMips64Tst, cont, true); |
2147 default: | 2146 default: |
2148 break; | 2147 break; |
2149 } | 2148 } |
2150 break; | |
2151 } | 2149 } |
2152 | 2150 |
2153 // Continuation could not be combined with a compare, emit compare against 0. | 2151 // Continuation could not be combined with a compare, emit compare against 0. |
2154 EmitWordCompareZero(selector, value, cont); | 2152 EmitWordCompareZero(selector, value, cont); |
2155 } | 2153 } |
2156 | 2154 |
2157 } // namespace | 2155 } // namespace |
2158 | 2156 |
2159 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, | 2157 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
2160 BasicBlock* fbranch) { | 2158 BasicBlock* fbranch) { |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2492 } else { | 2490 } else { |
2493 DCHECK(kArchVariant == kMips64r2); | 2491 DCHECK(kArchVariant == kMips64r2); |
2494 return MachineOperatorBuilder::AlignmentRequirements:: | 2492 return MachineOperatorBuilder::AlignmentRequirements:: |
2495 NoUnalignedAccessSupport(); | 2493 NoUnalignedAccessSupport(); |
2496 } | 2494 } |
2497 } | 2495 } |
2498 | 2496 |
2499 } // namespace compiler | 2497 } // namespace compiler |
2500 } // namespace internal | 2498 } // namespace internal |
2501 } // namespace v8 | 2499 } // namespace v8 |
OLD | NEW |