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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 opcode = reverse_opcode; | 181 opcode = reverse_opcode; |
182 input_count++; | 182 input_count++; |
183 } else { | 183 } else { |
184 inputs[input_count++] = g.UseRegister(m.left().node()); | 184 inputs[input_count++] = g.UseRegister(m.left().node()); |
185 inputs[input_count++] = g.UseOperand(m.right().node(), opcode); | 185 inputs[input_count++] = g.UseOperand(m.right().node(), opcode); |
186 } | 186 } |
187 | 187 |
188 if (cont->IsBranch()) { | 188 if (cont->IsBranch()) { |
189 inputs[input_count++] = g.Label(cont->true_block()); | 189 inputs[input_count++] = g.Label(cont->true_block()); |
190 inputs[input_count++] = g.Label(cont->false_block()); | 190 inputs[input_count++] = g.Label(cont->false_block()); |
| 191 } else if (cont->IsTrap()) { |
| 192 inputs[input_count++] = g.TempImmediate(cont->trap_id()); |
191 } | 193 } |
192 | 194 |
193 if (cont->IsDeoptimize()) { | 195 if (cont->IsDeoptimize()) { |
194 // If we can deoptimize as a result of the binop, we need to make sure that | 196 // If we can deoptimize as a result of the binop, we need to make sure that |
195 // the deopt inputs are not overwritten by the binop result. One way | 197 // the deopt inputs are not overwritten by the binop result. One way |
196 // to achieve that is to declare the output register as same-as-first. | 198 // to achieve that is to declare the output register as same-as-first. |
197 outputs[output_count++] = g.DefineSameAsFirst(node); | 199 outputs[output_count++] = g.DefineSameAsFirst(node); |
198 } else { | 200 } else { |
199 outputs[output_count++] = g.DefineAsRegister(node); | 201 outputs[output_count++] = g.DefineAsRegister(node); |
200 } | 202 } |
(...skipping 1160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 InstructionOperand left, InstructionOperand right, | 1363 InstructionOperand left, InstructionOperand right, |
1362 FlagsContinuation* cont) { | 1364 FlagsContinuation* cont) { |
1363 MipsOperandGenerator g(selector); | 1365 MipsOperandGenerator g(selector); |
1364 opcode = cont->Encode(opcode); | 1366 opcode = cont->Encode(opcode); |
1365 if (cont->IsBranch()) { | 1367 if (cont->IsBranch()) { |
1366 selector->Emit(opcode, g.NoOutput(), left, right, | 1368 selector->Emit(opcode, g.NoOutput(), left, right, |
1367 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1369 g.Label(cont->true_block()), g.Label(cont->false_block())); |
1368 } else if (cont->IsDeoptimize()) { | 1370 } else if (cont->IsDeoptimize()) { |
1369 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->reason(), | 1371 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->reason(), |
1370 cont->frame_state()); | 1372 cont->frame_state()); |
| 1373 } else if (cont->IsSet()) { |
| 1374 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); |
1371 } else { | 1375 } else { |
1372 DCHECK(cont->IsSet()); | 1376 DCHECK(cont->IsTrap()); |
1373 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); | 1377 selector->Emit(opcode, g.NoOutput(), left, right, |
| 1378 g.TempImmediate(cont->trap_id())); |
1374 } | 1379 } |
1375 } | 1380 } |
1376 | 1381 |
1377 | 1382 |
1378 // Shared routine for multiple float32 compare operations. | 1383 // Shared routine for multiple float32 compare operations. |
1379 void VisitFloat32Compare(InstructionSelector* selector, Node* node, | 1384 void VisitFloat32Compare(InstructionSelector* selector, Node* node, |
1380 FlagsContinuation* cont) { | 1385 FlagsContinuation* cont) { |
1381 MipsOperandGenerator g(selector); | 1386 MipsOperandGenerator g(selector); |
1382 Float32BinopMatcher m(node); | 1387 Float32BinopMatcher m(node); |
1383 InstructionOperand lhs, rhs; | 1388 InstructionOperand lhs, rhs; |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1571 MipsOperandGenerator g(selector); | 1576 MipsOperandGenerator g(selector); |
1572 InstructionCode const opcode = cont->Encode(kMipsCmp); | 1577 InstructionCode const opcode = cont->Encode(kMipsCmp); |
1573 InstructionOperand const value_operand = g.UseRegister(value); | 1578 InstructionOperand const value_operand = g.UseRegister(value); |
1574 if (cont->IsBranch()) { | 1579 if (cont->IsBranch()) { |
1575 selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0), | 1580 selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0), |
1576 g.Label(cont->true_block()), g.Label(cont->false_block())); | 1581 g.Label(cont->true_block()), g.Label(cont->false_block())); |
1577 } else if (cont->IsDeoptimize()) { | 1582 } else if (cont->IsDeoptimize()) { |
1578 selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand, | 1583 selector->EmitDeoptimize(opcode, g.NoOutput(), value_operand, |
1579 g.TempImmediate(0), cont->reason(), | 1584 g.TempImmediate(0), cont->reason(), |
1580 cont->frame_state()); | 1585 cont->frame_state()); |
1581 } else { | 1586 } else if (cont->IsSet()) { |
1582 DCHECK(cont->IsSet()); | |
1583 selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, | 1587 selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand, |
1584 g.TempImmediate(0)); | 1588 g.TempImmediate(0)); |
| 1589 } else { |
| 1590 DCHECK(cont->IsTrap()); |
| 1591 selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0), |
| 1592 g.TempImmediate(cont->trap_id())); |
1585 } | 1593 } |
1586 } | 1594 } |
1587 | 1595 |
1588 } // namespace | 1596 } // namespace |
1589 | 1597 |
1590 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, | 1598 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
1591 BasicBlock* fbranch) { | 1599 BasicBlock* fbranch) { |
1592 FlagsContinuation cont(kNotEqual, tbranch, fbranch); | 1600 FlagsContinuation cont(kNotEqual, tbranch, fbranch); |
1593 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); | 1601 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont); |
1594 } | 1602 } |
1595 | 1603 |
1596 void InstructionSelector::VisitDeoptimizeIf(Node* node) { | 1604 void InstructionSelector::VisitDeoptimizeIf(Node* node) { |
1597 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( | 1605 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( |
1598 kNotEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); | 1606 kNotEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); |
1599 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 1607 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
1600 } | 1608 } |
1601 | 1609 |
1602 void InstructionSelector::VisitDeoptimizeUnless(Node* node) { | 1610 void InstructionSelector::VisitDeoptimizeUnless(Node* node) { |
1603 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( | 1611 FlagsContinuation cont = FlagsContinuation::ForDeoptimize( |
1604 kEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); | 1612 kEqual, DeoptimizeReasonOf(node->op()), node->InputAt(1)); |
1605 VisitWordCompareZero(this, node, node->InputAt(0), &cont); | 1613 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
1606 } | 1614 } |
1607 | 1615 |
1608 void InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { | 1616 void InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) { |
1609 UNREACHABLE(); | 1617 FlagsContinuation cont = |
| 1618 FlagsContinuation::ForTrap(kNotEqual, func_id, node->InputAt(1)); |
| 1619 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
1610 } | 1620 } |
1611 | 1621 |
1612 void InstructionSelector::VisitTrapUnless(Node* node, | 1622 void InstructionSelector::VisitTrapUnless(Node* node, |
1613 Runtime::FunctionId func_id) { | 1623 Runtime::FunctionId func_id) { |
1614 UNREACHABLE(); | 1624 FlagsContinuation cont = |
| 1625 FlagsContinuation::ForTrap(kEqual, func_id, node->InputAt(1)); |
| 1626 VisitWordCompareZero(this, node, node->InputAt(0), &cont); |
1615 } | 1627 } |
1616 | 1628 |
1617 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { | 1629 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { |
1618 MipsOperandGenerator g(this); | 1630 MipsOperandGenerator g(this); |
1619 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); | 1631 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); |
1620 | 1632 |
1621 // Emit either ArchTableSwitch or ArchLookupSwitch. | 1633 // Emit either ArchTableSwitch or ArchLookupSwitch. |
1622 size_t table_space_cost = 9 + sw.value_range; | 1634 size_t table_space_cost = 9 + sw.value_range; |
1623 size_t table_time_cost = 3; | 1635 size_t table_time_cost = 3; |
1624 size_t lookup_space_cost = 2 + 2 * sw.case_count; | 1636 size_t lookup_space_cost = 2 + 2 * sw.case_count; |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1888 DCHECK(IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r1) || | 1900 DCHECK(IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r1) || |
1889 IsMipsArchVariant(kMips32r2)); | 1901 IsMipsArchVariant(kMips32r2)); |
1890 return MachineOperatorBuilder::AlignmentRequirements:: | 1902 return MachineOperatorBuilder::AlignmentRequirements:: |
1891 NoUnalignedAccessSupport(); | 1903 NoUnalignedAccessSupport(); |
1892 } | 1904 } |
1893 } | 1905 } |
1894 | 1906 |
1895 } // namespace compiler | 1907 } // namespace compiler |
1896 } // namespace internal | 1908 } // namespace internal |
1897 } // namespace v8 | 1909 } // namespace v8 |
OLD | NEW |