| 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 |