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 |