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 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 opcode = reverse_opcode; | 277 opcode = reverse_opcode; |
278 input_count++; | 278 input_count++; |
279 } else { | 279 } else { |
280 inputs[input_count++] = g.UseRegister(m.left().node()); | 280 inputs[input_count++] = g.UseRegister(m.left().node()); |
281 inputs[input_count++] = g.UseOperand(m.right().node(), opcode); | 281 inputs[input_count++] = g.UseOperand(m.right().node(), opcode); |
282 } | 282 } |
283 | 283 |
284 if (cont->IsBranch()) { | 284 if (cont->IsBranch()) { |
285 inputs[input_count++] = g.Label(cont->true_block()); | 285 inputs[input_count++] = g.Label(cont->true_block()); |
286 inputs[input_count++] = g.Label(cont->false_block()); | 286 inputs[input_count++] = g.Label(cont->false_block()); |
| 287 } else if (cont->IsTrap()) { |
| 288 inputs[input_count++] = g.TempImmediate(cont->trap_id()); |
287 } | 289 } |
288 | 290 |
289 if (cont->IsDeoptimize()) { | 291 if (cont->IsDeoptimize()) { |
290 // If we can deoptimize as a result of the binop, we need to make sure that | 292 // If we can deoptimize as a result of the binop, we need to make sure that |
291 // the deopt inputs are not overwritten by the binop result. One way | 293 // the deopt inputs are not overwritten by the binop result. One way |
292 // to achieve that is to declare the output register as same-as-first. | 294 // to achieve that is to declare the output register as same-as-first. |
293 outputs[output_count++] = g.DefineSameAsFirst(node); | 295 outputs[output_count++] = g.DefineSameAsFirst(node); |
294 } else { | 296 } else { |
295 outputs[output_count++] = g.DefineAsRegister(node); | 297 outputs[output_count++] = g.DefineAsRegister(node); |
296 } | 298 } |
(...skipping 1620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1917 InstructionOperand left, InstructionOperand right, | 1919 InstructionOperand left, InstructionOperand right, |
1918 FlagsContinuation* cont) { | 1920 FlagsContinuation* cont) { |
1919 Mips64OperandGenerator g(selector); | 1921 Mips64OperandGenerator g(selector); |
1920 opcode = cont->Encode(opcode); | 1922 opcode = cont->Encode(opcode); |
1921 if (cont->IsBranch()) { | 1923 if (cont->IsBranch()) { |
1922 selector->Emit(opcode, g.NoOutput(), left, right, | 1924 selector->Emit(opcode, g.NoOutput(), left, right, |
1923 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1925 g.Label(cont->true_block()), g.Label(cont->false_block())); |
1924 } else if (cont->IsDeoptimize()) { | 1926 } else if (cont->IsDeoptimize()) { |
1925 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->reason(), | 1927 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->reason(), |
1926 cont->frame_state()); | 1928 cont->frame_state()); |
| 1929 } else if (cont->IsSet()) { |
| 1930 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); |
1927 } else { | 1931 } else { |
1928 DCHECK(cont->IsSet()); | 1932 DCHECK(cont->IsTrap()); |
1929 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); | 1933 selector->Emit(opcode, g.NoOutput(), left, right, |
| 1934 g.TempImmediate(cont->trap_id())); |
1930 } | 1935 } |
1931 } | 1936 } |
1932 | 1937 |
1933 | 1938 |
1934 // Shared routine for multiple float32 compare operations. | 1939 // Shared routine for multiple float32 compare operations. |
1935 void VisitFloat32Compare(InstructionSelector* selector, Node* node, | 1940 void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
1936 FlagsContinuation* cont) { | 1941 FlagsContinuation* cont) { |
1937 Mips64OperandGenerator g(selector); | 1942 Mips64OperandGenerator g(selector); |
1938 Float32BinopMatcher m(node); | 1943 Float32BinopMatcher m(node); |
1939 InstructionOperand lhs, rhs; | 1944 InstructionOperand lhs, rhs; |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2131 Mips64OperandGenerator g(selector); | 2136 Mips64OperandGenerator g(selector); |
2132 InstructionCode opcode = cont->Encode(kMips64Cmp); | 2137 InstructionCode opcode = cont->Encode(kMips64Cmp); |
2133 InstructionOperand const value_operand = g.UseRegister(value); | 2138 InstructionOperand const value_operand = g.UseRegister(value); |
2134 if (cont->IsBranch()) { | 2139 if (cont->IsBranch()) { |
2135 selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0), | 2140 selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0), |
2136 g.Label(cont->true_block()), g.Label(cont->false_block())); | 2141 g.Label(cont->true_block()), g.Label(cont->false_block())); |
2137 } else if (cont->IsDeoptimize()) { | 2142 } else if (cont->IsDeoptimize()) { |
2138 selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand, | 2143 selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand, |
2139 g.TempImmediate(0), cont->reason(), | 2144 g.TempImmediate(0), cont->reason(), |
2140 cont->frame_state()); | 2145 cont->frame_state()); |
| 2146 } else if (cont->IsTrap()) { |
| 2147 selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0), |
| 2148 g.TempImmediate(cont->trap_id())); |
2141 } else { | 2149 } else { |
2142 selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, | 2150 selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, |
2143 g.TempImmediate(0)); | 2151 g.TempImmediate(0)); |
2144 } | 2152 } |
2145 } | 2153 } |
2146 | 2154 |
2147 | 2155 |
2148 // Shared routine for word comparisons against zero. | 2156 // Shared routine for word comparisons against zero. |
2149 void VisitWordCompareZero(InstructionSelector* selector, Node* user, | 2157 void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
2150 Node* value, FlagsContinuation* cont) { | 2158 Node* value, FlagsContinuation* cont) { |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2277 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 2285 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
2278 } | 2286 } |
2279 | 2287 |
2280 void InstructionSelector::VisitDeoptimizeUnless(Node* node) { | 2288 void InstructionSelector::VisitDeoptimizeUnless(Node* node) { |
2281 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( | 2289 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( |
2282 kEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); | 2290 kEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); |
2283 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 2291 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
2284 } | 2292 } |
2285 | 2293 |
2286 void InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { | 2294 void InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { |
2287 UNREACHABLE(); | 2295 FlagsContinuation cont = |
| 2296 FlagsContinuation::ForTrap(kNotEqual, func_id, node->InputAt(1)); |
| 2297 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
2288 } | 2298 } |
2289 | 2299 |
2290 void InstructionSelector::VisitTrapUnless(Node* node, | 2300 void InstructionSelector::VisitTrapUnless(Node* node, |
2291 Runtime::FunctionId func_id) { | 2301 Runtime::FunctionId func_id) { |
2292 UNREACHABLE(); | 2302 FlagsContinuation cont = |
| 2303 FlagsContinuation::ForTrap(kEqual, func_id, node->InputAt(1)); |
| 2304 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
2293 } | 2305 } |
2294 | 2306 |
2295 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { | 2307 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { |
2296 Mips64OperandGenerator g(this); | 2308 Mips64OperandGenerator g(this); |
2297 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); | 2309 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); |
2298 | 2310 |
2299 // Emit either ArchTableSwitch or ArchLookupSwitch. | 2311 // Emit either ArchTableSwitch or ArchLookupSwitch. |
2300 size_t table_space_cost = 10 + 2 * sw.value_range; | 2312 size_t table_space_cost = 10 + 2 * sw.value_range; |
2301 size_t table_time_cost = 3; | 2313 size_t table_time_cost = 3; |
2302 size_t lookup_space_cost = 2 + 2 * sw.case_count; | 2314 size_t lookup_space_cost = 2 + 2 * sw.case_count; |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2611 } else { | 2623 } else { |
2612 DCHECK(kArchVariant == kMips64r2); | 2624 DCHECK(kArchVariant == kMips64r2); |
2613 return MachineOperatorBuilder::AlignmentRequirements:: | 2625 return MachineOperatorBuilder::AlignmentRequirements:: |
2614 NoUnalignedAccessSupport(); | 2626 NoUnalignedAccessSupport(); |
2615 } | 2627 } |
2616 } | 2628 } |
2617 | 2629 |
2618 } // namespace compiler | 2630 } // namespace compiler |
2619 } // namespace internal | 2631 } // namespace internal |
2620 } // namespace v8 | 2632 } // namespace v8 |
OLD | NEW |