| 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 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 886 op = m->RoundInt64ToFloat64(); | 886 op = m->RoundInt64ToFloat64(); |
| 887 break; | 887 break; |
| 888 // kExprF64UConvertI64: | 888 // kExprF64UConvertI64: |
| 889 case wasm::kExprF64UConvertI64: | 889 case wasm::kExprF64UConvertI64: |
| 890 if (m->Is32()) { | 890 if (m->Is32()) { |
| 891 return BuildF64UConvertI64(input); | 891 return BuildF64UConvertI64(input); |
| 892 } | 892 } |
| 893 op = m->RoundUint64ToFloat64(); | 893 op = m->RoundUint64ToFloat64(); |
| 894 break; | 894 break; |
| 895 // kExprI64SConvertF32: | 895 // kExprI64SConvertF32: |
| 896 // kExprI64SConvertF64: | 896 case wasm::kExprI64SConvertF32: { |
| 897 // kExprI64UConvertF32: | 897 return BuildI64SConvertF32(input); |
| 898 // kExprI64UConvertF64: | 898 } |
| 899 // kExprI64SConvertF64: |
| 900 case wasm::kExprI64SConvertF64: { |
| 901 return BuildI64SConvertF64(input); |
| 902 } |
| 903 // kExprI64UConvertF32: |
| 904 case wasm::kExprI64UConvertF32: { |
| 905 return BuildI64UConvertF32(input); |
| 906 } |
| 907 // kExprI64UConvertF64: |
| 908 case wasm::kExprI64UConvertF64: { |
| 909 return BuildI64UConvertF64(input); |
| 910 } |
| 899 #if WASM_64 | 911 #if WASM_64 |
| 900 // Opcodes only supported on 64-bit platforms. | 912 // Opcodes only supported on 64-bit platforms. |
| 901 // TODO(titzer): query the machine operator builder here instead of #ifdef. | 913 // TODO(titzer): query the machine operator builder here instead of #ifdef. |
| 902 case wasm::kExprI64SConvertF32: { | |
| 903 Node* trunc = graph()->NewNode(m->TryTruncateFloat32ToInt64(), input); | |
| 904 Node* result = | |
| 905 graph()->NewNode(jsgraph()->common()->Projection(0), trunc); | |
| 906 Node* overflow = | |
| 907 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); | |
| 908 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); | |
| 909 return result; | |
| 910 } | |
| 911 case wasm::kExprI64SConvertF64: { | |
| 912 Node* trunc = graph()->NewNode(m->TryTruncateFloat64ToInt64(), input); | |
| 913 Node* result = | |
| 914 graph()->NewNode(jsgraph()->common()->Projection(0), trunc); | |
| 915 Node* overflow = | |
| 916 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); | |
| 917 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); | |
| 918 return result; | |
| 919 } | |
| 920 case wasm::kExprI64UConvertF32: { | |
| 921 Node* trunc = graph()->NewNode(m->TryTruncateFloat32ToUint64(), input); | |
| 922 Node* result = | |
| 923 graph()->NewNode(jsgraph()->common()->Projection(0), trunc); | |
| 924 Node* overflow = | |
| 925 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); | |
| 926 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); | |
| 927 return result; | |
| 928 } | |
| 929 case wasm::kExprI64UConvertF64: { | |
| 930 Node* trunc = graph()->NewNode(m->TryTruncateFloat64ToUint64(), input); | |
| 931 Node* result = | |
| 932 graph()->NewNode(jsgraph()->common()->Projection(0), trunc); | |
| 933 Node* overflow = | |
| 934 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); | |
| 935 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); | |
| 936 return result; | |
| 937 } | |
| 938 case wasm::kExprF64ReinterpretI64: | 914 case wasm::kExprF64ReinterpretI64: |
| 939 op = m->BitcastInt64ToFloat64(); | 915 op = m->BitcastInt64ToFloat64(); |
| 940 break; | 916 break; |
| 941 case wasm::kExprI64ReinterpretF64: | 917 case wasm::kExprI64ReinterpretF64: |
| 942 op = m->BitcastFloat64ToInt64(); | 918 op = m->BitcastFloat64ToInt64(); |
| 943 break; | 919 break; |
| 944 case wasm::kExprI64Clz: | 920 case wasm::kExprI64Clz: |
| 945 op = m->Word64Clz(); | 921 op = m->Word64Clz(); |
| 946 break; | 922 break; |
| 947 case wasm::kExprI64Ctz: { | 923 case wasm::kExprI64Ctz: { |
| (...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1648 const Operator* load_op = jsgraph()->machine()->Load(type); | 1624 const Operator* load_op = jsgraph()->machine()->Load(type); |
| 1649 | 1625 |
| 1650 Node* load = | 1626 Node* load = |
| 1651 graph()->NewNode(load_op, stack_slot_param0, jsgraph()->Int32Constant(0), | 1627 graph()->NewNode(load_op, stack_slot_param0, jsgraph()->Int32Constant(0), |
| 1652 *effect_, *control_); | 1628 *effect_, *control_); |
| 1653 *effect_ = load; | 1629 *effect_ = load; |
| 1654 return load; | 1630 return load; |
| 1655 } | 1631 } |
| 1656 | 1632 |
| 1657 Node* WasmGraphBuilder::BuildF32SConvertI64(Node* input) { | 1633 Node* WasmGraphBuilder::BuildF32SConvertI64(Node* input) { |
| 1658 return BuildConversionInstruction( | 1634 return BuildIntToFloatConversionInstruction( |
| 1659 input, ExternalReference::wasm_int64_to_float32(jsgraph()->isolate()), | 1635 input, ExternalReference::wasm_int64_to_float32(jsgraph()->isolate()), |
| 1660 MachineRepresentation::kWord64, MachineType::Float32()); | 1636 MachineRepresentation::kWord64, MachineType::Float32()); |
| 1661 } | 1637 } |
| 1662 Node* WasmGraphBuilder::BuildF32UConvertI64(Node* input) { | 1638 Node* WasmGraphBuilder::BuildF32UConvertI64(Node* input) { |
| 1663 return BuildConversionInstruction( | 1639 return BuildIntToFloatConversionInstruction( |
| 1664 input, ExternalReference::wasm_uint64_to_float32(jsgraph()->isolate()), | 1640 input, ExternalReference::wasm_uint64_to_float32(jsgraph()->isolate()), |
| 1665 MachineRepresentation::kWord64, MachineType::Float32()); | 1641 MachineRepresentation::kWord64, MachineType::Float32()); |
| 1666 } | 1642 } |
| 1667 Node* WasmGraphBuilder::BuildF64SConvertI64(Node* input) { | 1643 Node* WasmGraphBuilder::BuildF64SConvertI64(Node* input) { |
| 1668 return BuildConversionInstruction( | 1644 return BuildIntToFloatConversionInstruction( |
| 1669 input, ExternalReference::wasm_int64_to_float64(jsgraph()->isolate()), | 1645 input, ExternalReference::wasm_int64_to_float64(jsgraph()->isolate()), |
| 1670 MachineRepresentation::kWord64, MachineType::Float64()); | 1646 MachineRepresentation::kWord64, MachineType::Float64()); |
| 1671 } | 1647 } |
| 1672 Node* WasmGraphBuilder::BuildF64UConvertI64(Node* input) { | 1648 Node* WasmGraphBuilder::BuildF64UConvertI64(Node* input) { |
| 1673 return BuildConversionInstruction( | 1649 return BuildIntToFloatConversionInstruction( |
| 1674 input, ExternalReference::wasm_uint64_to_float64(jsgraph()->isolate()), | 1650 input, ExternalReference::wasm_uint64_to_float64(jsgraph()->isolate()), |
| 1675 MachineRepresentation::kWord64, MachineType::Float64()); | 1651 MachineRepresentation::kWord64, MachineType::Float64()); |
| 1676 } | 1652 } |
| 1677 Node* WasmGraphBuilder::BuildConversionInstruction( | 1653 |
| 1654 Node* WasmGraphBuilder::BuildIntToFloatConversionInstruction( |
| 1678 Node* input, ExternalReference ref, | 1655 Node* input, ExternalReference ref, |
| 1679 MachineRepresentation parameter_representation, | 1656 MachineRepresentation parameter_representation, |
| 1680 const MachineType result_type) { | 1657 const MachineType result_type) { |
| 1681 Node* stack_slot_param = graph()->NewNode( | 1658 Node* stack_slot_param = graph()->NewNode( |
| 1682 jsgraph()->machine()->StackSlot(parameter_representation)); | 1659 jsgraph()->machine()->StackSlot(parameter_representation)); |
| 1683 Node* stack_slot_result = graph()->NewNode( | 1660 Node* stack_slot_result = graph()->NewNode( |
| 1684 jsgraph()->machine()->StackSlot(result_type.representation())); | 1661 jsgraph()->machine()->StackSlot(result_type.representation())); |
| 1685 const Operator* store_op = jsgraph()->machine()->Store( | 1662 const Operator* store_op = jsgraph()->machine()->Store( |
| 1686 StoreRepresentation(parameter_representation, kNoWriteBarrier)); | 1663 StoreRepresentation(parameter_representation, kNoWriteBarrier)); |
| 1687 *effect_ = | 1664 *effect_ = |
| 1688 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0), | 1665 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0), |
| 1689 input, *effect_, *control_); | 1666 input, *effect_, *control_); |
| 1690 MachineSignature::Builder sig_builder(jsgraph()->zone(), 0, 2); | 1667 MachineSignature::Builder sig_builder(jsgraph()->zone(), 0, 2); |
| 1691 sig_builder.AddParam(MachineType::Pointer()); | 1668 sig_builder.AddParam(MachineType::Pointer()); |
| 1692 sig_builder.AddParam(MachineType::Pointer()); | 1669 sig_builder.AddParam(MachineType::Pointer()); |
| 1693 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); | 1670 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); |
| 1694 Node* args[] = {function, stack_slot_param, stack_slot_result}; | 1671 Node* args[] = {function, stack_slot_param, stack_slot_result}; |
| 1695 BuildCCall(sig_builder.Build(), args); | 1672 BuildCCall(sig_builder.Build(), args); |
| 1696 const Operator* load_op = jsgraph()->machine()->Load(result_type); | 1673 const Operator* load_op = jsgraph()->machine()->Load(result_type); |
| 1697 Node* load = | 1674 Node* load = |
| 1698 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), | 1675 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), |
| 1699 *effect_, *control_); | 1676 *effect_, *control_); |
| 1700 *effect_ = load; | 1677 *effect_ = load; |
| 1701 return load; | 1678 return load; |
| 1702 } | 1679 } |
| 1703 | 1680 |
| 1681 Node* WasmGraphBuilder::BuildI64SConvertF32(Node* input) { |
| 1682 if (jsgraph()->machine()->Is32()) { |
| 1683 return BuildFloatToIntConversionInstruction( |
| 1684 input, ExternalReference::wasm_float32_to_int64(jsgraph()->isolate()), |
| 1685 MachineRepresentation::kFloat32, MachineType::Int64()); |
| 1686 } else { |
| 1687 Node* trunc = graph()->NewNode( |
| 1688 jsgraph()->machine()->TryTruncateFloat32ToInt64(), input); |
| 1689 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); |
| 1690 Node* overflow = |
| 1691 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); |
| 1692 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); |
| 1693 return result; |
| 1694 } |
| 1695 } |
| 1696 |
| 1697 Node* WasmGraphBuilder::BuildI64UConvertF32(Node* input) { |
| 1698 if (jsgraph()->machine()->Is32()) { |
| 1699 return BuildFloatToIntConversionInstruction( |
| 1700 input, ExternalReference::wasm_float32_to_uint64(jsgraph()->isolate()), |
| 1701 MachineRepresentation::kFloat32, MachineType::Int64()); |
| 1702 } else { |
| 1703 Node* trunc = graph()->NewNode( |
| 1704 jsgraph()->machine()->TryTruncateFloat32ToUint64(), input); |
| 1705 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); |
| 1706 Node* overflow = |
| 1707 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); |
| 1708 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); |
| 1709 return result; |
| 1710 } |
| 1711 } |
| 1712 |
| 1713 Node* WasmGraphBuilder::BuildI64SConvertF64(Node* input) { |
| 1714 if (jsgraph()->machine()->Is32()) { |
| 1715 return BuildFloatToIntConversionInstruction( |
| 1716 input, ExternalReference::wasm_float64_to_int64(jsgraph()->isolate()), |
| 1717 MachineRepresentation::kFloat64, MachineType::Int64()); |
| 1718 } else { |
| 1719 Node* trunc = graph()->NewNode( |
| 1720 jsgraph()->machine()->TryTruncateFloat64ToInt64(), input); |
| 1721 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); |
| 1722 Node* overflow = |
| 1723 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); |
| 1724 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); |
| 1725 return result; |
| 1726 } |
| 1727 } |
| 1728 |
| 1729 Node* WasmGraphBuilder::BuildI64UConvertF64(Node* input) { |
| 1730 if (jsgraph()->machine()->Is32()) { |
| 1731 return BuildFloatToIntConversionInstruction( |
| 1732 input, ExternalReference::wasm_float64_to_uint64(jsgraph()->isolate()), |
| 1733 MachineRepresentation::kFloat64, MachineType::Int64()); |
| 1734 } else { |
| 1735 Node* trunc = graph()->NewNode( |
| 1736 jsgraph()->machine()->TryTruncateFloat64ToUint64(), input); |
| 1737 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); |
| 1738 Node* overflow = |
| 1739 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); |
| 1740 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); |
| 1741 return result; |
| 1742 } |
| 1743 } |
| 1744 |
| 1745 Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction( |
| 1746 Node* input, ExternalReference ref, |
| 1747 MachineRepresentation parameter_representation, |
| 1748 const MachineType result_type) { |
| 1749 Node* stack_slot_param = graph()->NewNode( |
| 1750 jsgraph()->machine()->StackSlot(parameter_representation)); |
| 1751 Node* stack_slot_result = graph()->NewNode( |
| 1752 jsgraph()->machine()->StackSlot(result_type.representation())); |
| 1753 const Operator* store_op = jsgraph()->machine()->Store( |
| 1754 StoreRepresentation(parameter_representation, kNoWriteBarrier)); |
| 1755 *effect_ = |
| 1756 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0), |
| 1757 input, *effect_, *control_); |
| 1758 MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2); |
| 1759 sig_builder.AddReturn(MachineType::Int32()); |
| 1760 sig_builder.AddParam(MachineType::Pointer()); |
| 1761 sig_builder.AddParam(MachineType::Pointer()); |
| 1762 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); |
| 1763 Node* args[] = {function, stack_slot_param, stack_slot_result}; |
| 1764 trap_->ZeroCheck32(kTrapFloatUnrepresentable, |
| 1765 BuildCCall(sig_builder.Build(), args)); |
| 1766 const Operator* load_op = jsgraph()->machine()->Load(result_type); |
| 1767 Node* load = |
| 1768 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), |
| 1769 *effect_, *control_); |
| 1770 *effect_ = load; |
| 1771 return load; |
| 1772 } |
| 1773 |
| 1704 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { | 1774 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { |
| 1705 const size_t params = sig->parameter_count(); | 1775 const size_t params = sig->parameter_count(); |
| 1706 const size_t extra = 2; // effect and control inputs. | 1776 const size_t extra = 2; // effect and control inputs. |
| 1707 const size_t count = 1 + params + extra; | 1777 const size_t count = 1 + params + extra; |
| 1708 | 1778 |
| 1709 // Reallocate the buffer to make space for extra inputs. | 1779 // Reallocate the buffer to make space for extra inputs. |
| 1710 args = Realloc(args, count); | 1780 args = Realloc(args, count); |
| 1711 | 1781 |
| 1712 // Add effect and control inputs. | 1782 // Add effect and control inputs. |
| 1713 args[params + 1] = *effect_; | 1783 args[params + 1] = *effect_; |
| (...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2501 static_cast<int>(function.code_end_offset - function.code_start_offset), | 2571 static_cast<int>(function.code_end_offset - function.code_start_offset), |
| 2502 decode_ms, compile_ms); | 2572 decode_ms, compile_ms); |
| 2503 } | 2573 } |
| 2504 return code; | 2574 return code; |
| 2505 } | 2575 } |
| 2506 | 2576 |
| 2507 | 2577 |
| 2508 } // namespace compiler | 2578 } // namespace compiler |
| 2509 } // namespace internal | 2579 } // namespace internal |
| 2510 } // namespace v8 | 2580 } // namespace v8 |
| OLD | NEW |