Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/compiler/wasm-compiler.h" | 5 #include "src/compiler/wasm-compiler.h" |
| 6 | 6 |
| 7 #include "src/isolate-inl.h" | 7 #include "src/isolate-inl.h" |
| 8 | 8 |
| 9 #include "src/base/platform/elapsed-timer.h" | 9 #include "src/base/platform/elapsed-timer.h" |
| 10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 490 break; | 490 break; |
| 491 case wasm::kExprI64And: | 491 case wasm::kExprI64And: |
| 492 op = m->Word64And(); | 492 op = m->Word64And(); |
| 493 break; | 493 break; |
| 494 // todo(ahaas): I added a list of missing instructions here to make merging | 494 // todo(ahaas): I added a list of missing instructions here to make merging |
| 495 // easier when I do them one by one. | 495 // easier when I do them one by one. |
| 496 // kExprI64Add: | 496 // kExprI64Add: |
| 497 // kExprI64Sub: | 497 // kExprI64Sub: |
| 498 // kExprI64Mul: | 498 // kExprI64Mul: |
| 499 // kExprI64DivS: | 499 // kExprI64DivS: |
| 500 case wasm::kExprI64DivS: | |
| 501 return BuildI64DivS(left, right); | |
| 500 // kExprI64DivU: | 502 // kExprI64DivU: |
| 503 case wasm::kExprI64DivU: | |
| 504 return BuildI64DivU(left, right); | |
| 501 // kExprI64RemS: | 505 // kExprI64RemS: |
| 506 case wasm::kExprI64RemS: | |
| 507 return BuildI64RemS(left, right); | |
| 502 // kExprI64RemU: | 508 // kExprI64RemU: |
| 509 case wasm::kExprI64RemU: | |
| 510 return BuildI64RemU(left, right); | |
| 503 case wasm::kExprI64Ior: | 511 case wasm::kExprI64Ior: |
| 504 op = m->Word64Or(); | 512 op = m->Word64Or(); |
| 505 break; | 513 break; |
| 506 // kExprI64Xor: | 514 // kExprI64Xor: |
| 507 case wasm::kExprI64Xor: | 515 case wasm::kExprI64Xor: |
| 508 op = m->Word64Xor(); | 516 op = m->Word64Xor(); |
| 509 break; | 517 break; |
| 510 // kExprI64Shl: | 518 // kExprI64Shl: |
| 511 case wasm::kExprI64Shl: | 519 case wasm::kExprI64Shl: |
| 512 op = m->Word64Shl(); | 520 op = m->Word64Shl(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 561 // TODO(titzer): query the machine operator builder here instead of #ifdef. | 569 // TODO(titzer): query the machine operator builder here instead of #ifdef. |
| 562 case wasm::kExprI64Add: | 570 case wasm::kExprI64Add: |
| 563 op = m->Int64Add(); | 571 op = m->Int64Add(); |
| 564 break; | 572 break; |
| 565 case wasm::kExprI64Sub: | 573 case wasm::kExprI64Sub: |
| 566 op = m->Int64Sub(); | 574 op = m->Int64Sub(); |
| 567 break; | 575 break; |
| 568 case wasm::kExprI64Mul: | 576 case wasm::kExprI64Mul: |
| 569 op = m->Int64Mul(); | 577 op = m->Int64Mul(); |
| 570 break; | 578 break; |
| 571 case wasm::kExprI64DivS: { | |
| 572 trap_->ZeroCheck64(kTrapDivByZero, right); | |
| 573 Node* before = *control_; | |
| 574 Node* denom_is_m1; | |
| 575 Node* denom_is_not_m1; | |
| 576 Branch(graph()->NewNode(jsgraph()->machine()->Word64Equal(), right, | |
| 577 jsgraph()->Int64Constant(-1)), | |
| 578 &denom_is_m1, &denom_is_not_m1); | |
| 579 *control_ = denom_is_m1; | |
| 580 trap_->TrapIfEq64(kTrapDivUnrepresentable, left, | |
| 581 std::numeric_limits<int64_t>::min()); | |
| 582 if (*control_ != denom_is_m1) { | |
| 583 *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), | |
| 584 denom_is_not_m1, *control_); | |
| 585 } else { | |
| 586 *control_ = before; | |
| 587 } | |
| 588 return graph()->NewNode(m->Int64Div(), left, right, *control_); | |
| 589 } | |
| 590 case wasm::kExprI64DivU: | |
| 591 op = m->Uint64Div(); | |
| 592 return graph()->NewNode(op, left, right, | |
| 593 trap_->ZeroCheck64(kTrapDivByZero, right)); | |
| 594 case wasm::kExprI64RemS: { | |
| 595 trap_->ZeroCheck64(kTrapRemByZero, right); | |
| 596 Diamond d(jsgraph()->graph(), jsgraph()->common(), | |
| 597 graph()->NewNode(jsgraph()->machine()->Word64Equal(), right, | |
| 598 jsgraph()->Int64Constant(-1))); | |
| 599 | |
| 600 Node* rem = graph()->NewNode(m->Int64Mod(), left, right, d.if_false); | |
| 601 | |
| 602 return d.Phi(MachineRepresentation::kWord64, jsgraph()->Int64Constant(0), | |
| 603 rem); | |
| 604 } | |
| 605 case wasm::kExprI64RemU: | |
| 606 op = m->Uint64Mod(); | |
| 607 return graph()->NewNode(op, left, right, | |
| 608 trap_->ZeroCheck64(kTrapRemByZero, right)); | |
| 609 case wasm::kExprI64Ror: | 579 case wasm::kExprI64Ror: |
| 610 op = m->Word64Ror(); | 580 op = m->Word64Ror(); |
| 611 break; | 581 break; |
| 612 case wasm::kExprI64Rol: | 582 case wasm::kExprI64Rol: |
| 613 return BuildI64Rol(left, right); | 583 return BuildI64Rol(left, right); |
| 614 #endif | 584 #endif |
| 615 | 585 |
| 616 case wasm::kExprF32CopySign: | 586 case wasm::kExprF32CopySign: |
| 617 return BuildF32CopySign(left, right); | 587 return BuildF32CopySign(left, right); |
| 618 case wasm::kExprF64CopySign: | 588 case wasm::kExprF64CopySign: |
| (...skipping 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1764 trap_->ZeroCheck32(kTrapFloatUnrepresentable, | 1734 trap_->ZeroCheck32(kTrapFloatUnrepresentable, |
| 1765 BuildCCall(sig_builder.Build(), args)); | 1735 BuildCCall(sig_builder.Build(), args)); |
| 1766 const Operator* load_op = jsgraph()->machine()->Load(result_type); | 1736 const Operator* load_op = jsgraph()->machine()->Load(result_type); |
| 1767 Node* load = | 1737 Node* load = |
| 1768 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), | 1738 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), |
| 1769 *effect_, *control_); | 1739 *effect_, *control_); |
| 1770 *effect_ = load; | 1740 *effect_ = load; |
| 1771 return load; | 1741 return load; |
| 1772 } | 1742 } |
| 1773 | 1743 |
| 1744 Node* WasmGraphBuilder::BuildI64DivS(Node* left, Node* right) { | |
| 1745 if (jsgraph()->machine()->Is32()) { | |
| 1746 return BuildDiv64Call( | |
| 1747 left, right, ExternalReference::wasm_int64_div(jsgraph()->isolate()), | |
| 1748 MachineType::Int64(), kTrapDivByZero); | |
| 1749 } else { | |
| 1750 trap_->ZeroCheck64(kTrapDivByZero, right); | |
|
titzer
2016/03/14 11:03:22
Style nit: leave the else clause unnested.
ahaas
2016/03/14 12:38:12
Done.
| |
| 1751 Node* before = *control_; | |
| 1752 Node* denom_is_m1; | |
| 1753 Node* denom_is_not_m1; | |
| 1754 Branch(graph()->NewNode(jsgraph()->machine()->Word64Equal(), right, | |
| 1755 jsgraph()->Int64Constant(-1)), | |
| 1756 &denom_is_m1, &denom_is_not_m1); | |
| 1757 *control_ = denom_is_m1; | |
| 1758 trap_->TrapIfEq64(kTrapDivUnrepresentable, left, | |
| 1759 std::numeric_limits<int64_t>::min()); | |
| 1760 if (*control_ != denom_is_m1) { | |
| 1761 *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), | |
| 1762 denom_is_not_m1, *control_); | |
| 1763 } else { | |
| 1764 *control_ = before; | |
| 1765 } | |
| 1766 return graph()->NewNode(jsgraph()->machine()->Int64Div(), left, right, | |
| 1767 *control_); | |
| 1768 } | |
| 1769 } | |
| 1770 | |
| 1771 Node* WasmGraphBuilder::BuildI64RemS(Node* left, Node* right) { | |
| 1772 if (jsgraph()->machine()->Is32()) { | |
| 1773 return BuildDiv64Call( | |
| 1774 left, right, ExternalReference::wasm_int64_mod(jsgraph()->isolate()), | |
| 1775 MachineType::Int64(), kTrapRemByZero); | |
| 1776 } else { | |
| 1777 trap_->ZeroCheck64(kTrapRemByZero, right); | |
| 1778 Diamond d(jsgraph()->graph(), jsgraph()->common(), | |
| 1779 graph()->NewNode(jsgraph()->machine()->Word64Equal(), right, | |
| 1780 jsgraph()->Int64Constant(-1))); | |
| 1781 | |
| 1782 Node* rem = graph()->NewNode(jsgraph()->machine()->Int64Mod(), left, right, | |
| 1783 d.if_false); | |
| 1784 | |
| 1785 return d.Phi(MachineRepresentation::kWord64, jsgraph()->Int64Constant(0), | |
| 1786 rem); | |
| 1787 } | |
| 1788 } | |
| 1789 | |
| 1790 Node* WasmGraphBuilder::BuildI64DivU(Node* left, Node* right) { | |
| 1791 if (jsgraph()->machine()->Is32()) { | |
| 1792 return BuildDiv64Call( | |
| 1793 left, right, ExternalReference::wasm_uint64_div(jsgraph()->isolate()), | |
| 1794 MachineType::Int64(), kTrapDivByZero); | |
| 1795 } else { | |
| 1796 return graph()->NewNode(jsgraph()->machine()->Uint64Div(), left, right, | |
| 1797 trap_->ZeroCheck64(kTrapDivByZero, right)); | |
| 1798 } | |
| 1799 } | |
| 1800 Node* WasmGraphBuilder::BuildI64RemU(Node* left, Node* right) { | |
| 1801 if (jsgraph()->machine()->Is32()) { | |
| 1802 return BuildDiv64Call( | |
| 1803 left, right, ExternalReference::wasm_uint64_mod(jsgraph()->isolate()), | |
| 1804 MachineType::Int64(), kTrapRemByZero); | |
| 1805 } else { | |
| 1806 return graph()->NewNode(jsgraph()->machine()->Uint64Mod(), left, right, | |
| 1807 trap_->ZeroCheck64(kTrapRemByZero, right)); | |
| 1808 } | |
| 1809 } | |
| 1810 | |
| 1811 Node* WasmGraphBuilder::BuildDiv64Call(Node* left, Node* right, | |
| 1812 ExternalReference ref, | |
| 1813 MachineType result_type, int trap_zero) { | |
| 1814 Node* stack_slot_dst = graph()->NewNode( | |
| 1815 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64)); | |
| 1816 Node* stack_slot_src = graph()->NewNode( | |
| 1817 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64)); | |
| 1818 | |
| 1819 const Operator* store_op = jsgraph()->machine()->Store( | |
| 1820 StoreRepresentation(MachineRepresentation::kWord64, kNoWriteBarrier)); | |
| 1821 *effect_ = | |
| 1822 graph()->NewNode(store_op, stack_slot_dst, jsgraph()->Int32Constant(0), | |
| 1823 left, *effect_, *control_); | |
| 1824 *effect_ = | |
| 1825 graph()->NewNode(store_op, stack_slot_src, jsgraph()->Int32Constant(0), | |
| 1826 right, *effect_, *control_); | |
| 1827 | |
| 1828 MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2); | |
| 1829 sig_builder.AddReturn(MachineType::Int32()); | |
| 1830 sig_builder.AddParam(MachineType::Pointer()); | |
| 1831 sig_builder.AddParam(MachineType::Pointer()); | |
| 1832 | |
| 1833 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); | |
| 1834 Node* args[] = {function, stack_slot_dst, stack_slot_src}; | |
| 1835 | |
| 1836 Node* call = BuildCCall(sig_builder.Build(), args); | |
| 1837 trap_->ZeroCheck32(static_cast<TrapReason>(trap_zero), call); | |
|
titzer
2016/03/14 11:03:22
Can you leave a TODO here? This can get simpler if
ahaas
2016/03/14 12:38:12
Done.
| |
| 1838 trap_->TrapIfEq32(kTrapDivUnrepresentable, call, -1); | |
| 1839 const Operator* load_op = jsgraph()->machine()->Load(result_type); | |
| 1840 Node* load = | |
| 1841 graph()->NewNode(load_op, stack_slot_dst, jsgraph()->Int32Constant(0), | |
| 1842 *effect_, *control_); | |
| 1843 *effect_ = load; | |
| 1844 return load; | |
| 1845 } | |
| 1846 | |
| 1774 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { | 1847 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { |
| 1775 const size_t params = sig->parameter_count(); | 1848 const size_t params = sig->parameter_count(); |
| 1776 const size_t extra = 2; // effect and control inputs. | 1849 const size_t extra = 2; // effect and control inputs. |
| 1777 const size_t count = 1 + params + extra; | 1850 const size_t count = 1 + params + extra; |
| 1778 | 1851 |
| 1779 // Reallocate the buffer to make space for extra inputs. | 1852 // Reallocate the buffer to make space for extra inputs. |
| 1780 args = Realloc(args, count); | 1853 args = Realloc(args, count); |
| 1781 | 1854 |
| 1782 // Add effect and control inputs. | 1855 // Add effect and control inputs. |
| 1783 args[params + 1] = *effect_; | 1856 args[params + 1] = *effect_; |
| (...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2571 static_cast<int>(function.code_end_offset - function.code_start_offset), | 2644 static_cast<int>(function.code_end_offset - function.code_start_offset), |
| 2572 decode_ms, compile_ms); | 2645 decode_ms, compile_ms); |
| 2573 } | 2646 } |
| 2574 return code; | 2647 return code; |
| 2575 } | 2648 } |
| 2576 | 2649 |
| 2577 | 2650 |
| 2578 } // namespace compiler | 2651 } // namespace compiler |
| 2579 } // namespace internal | 2652 } // namespace internal |
| 2580 } // namespace v8 | 2653 } // namespace v8 |
| OLD | NEW |