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/platform.h" | 9 #include "src/base/platform/platform.h" |
10 | 10 |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 break; | 541 break; |
542 case wasm::kExprI64GtU: | 542 case wasm::kExprI64GtU: |
543 op = m->Uint64LessThan(); | 543 op = m->Uint64LessThan(); |
544 std::swap(left, right); | 544 std::swap(left, right); |
545 break; | 545 break; |
546 case wasm::kExprI64GeU: | 546 case wasm::kExprI64GeU: |
547 op = m->Uint64LessThanOrEqual(); | 547 op = m->Uint64LessThanOrEqual(); |
548 std::swap(left, right); | 548 std::swap(left, right); |
549 break; | 549 break; |
550 | 550 |
551 // kExprI32ConvertI64: | |
552 // kExprI64SConvertI32: | |
553 // kExprI64UConvertI32: | |
554 | |
555 // kExprF64ReinterpretI64: | |
556 // kExprI64ReinterpretF64: | |
557 | |
558 // kExprI64Clz: | |
559 // kExprI64Ctz: | |
560 // kExprI64Popcnt: | |
561 | |
562 // kExprF32SConvertI64: | |
563 // kExprF32UConvertI64: | |
564 // kExprF64SConvertI64: | |
565 // kExprF64UConvertI64: | |
566 // kExprI64SConvertF32: | |
567 // kExprI64SConvertF64: | |
568 // kExprI64UConvertF32: | |
569 // kExprI64UConvertF64: | |
570 #if WASM_64 | 551 #if WASM_64 |
571 // Opcodes only supported on 64-bit platforms. | 552 // Opcodes only supported on 64-bit platforms. |
572 // TODO(titzer): query the machine operator builder here instead of #ifdef. | 553 // TODO(titzer): query the machine operator builder here instead of #ifdef. |
573 case wasm::kExprI64Add: | 554 case wasm::kExprI64Add: |
574 op = m->Int64Add(); | 555 op = m->Int64Add(); |
575 break; | 556 break; |
576 case wasm::kExprI64Sub: | 557 case wasm::kExprI64Sub: |
577 op = m->Int64Sub(); | 558 op = m->Int64Sub(); |
578 break; | 559 break; |
579 case wasm::kExprI64Mul: | 560 case wasm::kExprI64Mul: |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
863 } | 844 } |
864 case wasm::kExprF64Exp: { | 845 case wasm::kExprF64Exp: { |
865 return BuildF64Exp(input); | 846 return BuildF64Exp(input); |
866 } | 847 } |
867 case wasm::kExprF64Log: { | 848 case wasm::kExprF64Log: { |
868 return BuildF64Log(input); | 849 return BuildF64Log(input); |
869 } | 850 } |
870 case wasm::kExprI32ConvertI64: | 851 case wasm::kExprI32ConvertI64: |
871 op = m->TruncateInt64ToInt32(); | 852 op = m->TruncateInt64ToInt32(); |
872 break; | 853 break; |
| 854 |
| 855 // kExprI32ConvertI64: |
| 856 // kExprI64SConvertI32: |
| 857 // kExprI64UConvertI32: |
| 858 // kExprF64ReinterpretI64: |
| 859 // kExprI64ReinterpretF64: |
| 860 // kExprI64Clz: |
| 861 // kExprI64Ctz: |
| 862 // kExprI64Popcnt: |
| 863 // kExprF32SConvertI64: |
| 864 case wasm::kExprF32SConvertI64: |
| 865 if (kPointerSize == 4) { |
| 866 return BuildF32SConvertI64(input); |
| 867 } |
| 868 op = m->RoundInt64ToFloat32(); |
| 869 break; |
| 870 // kExprF32UConvertI64: |
| 871 case wasm::kExprF32UConvertI64: |
| 872 if (kPointerSize == 4) { |
| 873 return BuildF32UConvertI64(input); |
| 874 } |
| 875 op = m->RoundUint64ToFloat32(); |
| 876 break; |
| 877 // kExprF64SConvertI64: |
| 878 case wasm::kExprF64SConvertI64: |
| 879 if (kPointerSize == 4) { |
| 880 return BuildF64SConvertI64(input); |
| 881 } |
| 882 op = m->RoundInt64ToFloat64(); |
| 883 break; |
| 884 // kExprF64UConvertI64: |
| 885 case wasm::kExprF64UConvertI64: |
| 886 if (kPointerSize == 4) { |
| 887 return BuildF64UConvertI64(input); |
| 888 } |
| 889 op = m->RoundUint64ToFloat64(); |
| 890 break; |
| 891 // kExprI64SConvertF32: |
| 892 // kExprI64SConvertF64: |
| 893 // kExprI64UConvertF32: |
| 894 // kExprI64UConvertF64: |
873 #if WASM_64 | 895 #if WASM_64 |
874 // Opcodes only supported on 64-bit platforms. | 896 // Opcodes only supported on 64-bit platforms. |
875 // TODO(titzer): query the machine operator builder here instead of #ifdef. | 897 // TODO(titzer): query the machine operator builder here instead of #ifdef. |
876 case wasm::kExprI64SConvertI32: | 898 case wasm::kExprI64SConvertI32: |
877 op = m->ChangeInt32ToInt64(); | 899 op = m->ChangeInt32ToInt64(); |
878 break; | 900 break; |
879 case wasm::kExprI64UConvertI32: | 901 case wasm::kExprI64UConvertI32: |
880 op = m->ChangeUint32ToUint64(); | 902 op = m->ChangeUint32ToUint64(); |
881 break; | 903 break; |
882 case wasm::kExprF32SConvertI64: | |
883 op = m->RoundInt64ToFloat32(); | |
884 break; | |
885 case wasm::kExprF32UConvertI64: | |
886 op = m->RoundUint64ToFloat32(); | |
887 break; | |
888 case wasm::kExprF64SConvertI64: | |
889 op = m->RoundInt64ToFloat64(); | |
890 break; | |
891 case wasm::kExprF64UConvertI64: | |
892 op = m->RoundUint64ToFloat64(); | |
893 break; | |
894 case wasm::kExprI64SConvertF32: { | 904 case wasm::kExprI64SConvertF32: { |
895 Node* trunc = graph()->NewNode(m->TryTruncateFloat32ToInt64(), input); | 905 Node* trunc = graph()->NewNode(m->TryTruncateFloat32ToInt64(), input); |
896 Node* result = | 906 Node* result = |
897 graph()->NewNode(jsgraph()->common()->Projection(0), trunc); | 907 graph()->NewNode(jsgraph()->common()->Projection(0), trunc); |
898 Node* overflow = | 908 Node* overflow = |
899 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); | 909 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); |
900 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); | 910 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); |
901 return result; | 911 return result; |
902 } | 912 } |
903 case wasm::kExprI64SConvertF64: { | 913 case wasm::kExprI64SConvertF64: { |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1453 jsgraph()->Int64Constant(0x00000000ffffffff)), | 1463 jsgraph()->Int64Constant(0x00000000ffffffff)), |
1454 Binop(wasm::kExprI64And, result, | 1464 Binop(wasm::kExprI64And, result, |
1455 jsgraph()->Int64Constant(0x00000000ffffffff))); | 1465 jsgraph()->Int64Constant(0x00000000ffffffff))); |
1456 | 1466 |
1457 return result; | 1467 return result; |
1458 } | 1468 } |
1459 | 1469 |
1460 Node* WasmGraphBuilder::BuildF32Trunc(Node* input) { | 1470 Node* WasmGraphBuilder::BuildF32Trunc(Node* input) { |
1461 MachineType type = MachineType::Float32(); | 1471 MachineType type = MachineType::Float32(); |
1462 ExternalReference ref = | 1472 ExternalReference ref = |
1463 ExternalReference::f32_trunc_wrapper_function(jsgraph()->isolate()); | 1473 ExternalReference::wasm_f32_trunc(jsgraph()->isolate()); |
| 1474 |
1464 return BuildCFuncInstruction(ref, type, input); | 1475 return BuildCFuncInstruction(ref, type, input); |
1465 } | 1476 } |
1466 | 1477 |
1467 Node* WasmGraphBuilder::BuildF32Floor(Node* input) { | 1478 Node* WasmGraphBuilder::BuildF32Floor(Node* input) { |
1468 MachineType type = MachineType::Float32(); | 1479 MachineType type = MachineType::Float32(); |
1469 ExternalReference ref = | 1480 ExternalReference ref = |
1470 ExternalReference::f32_floor_wrapper_function(jsgraph()->isolate()); | 1481 ExternalReference::wasm_f32_floor(jsgraph()->isolate()); |
1471 return BuildCFuncInstruction(ref, type, input); | 1482 return BuildCFuncInstruction(ref, type, input); |
1472 } | 1483 } |
1473 | 1484 |
1474 Node* WasmGraphBuilder::BuildF32Ceil(Node* input) { | 1485 Node* WasmGraphBuilder::BuildF32Ceil(Node* input) { |
1475 MachineType type = MachineType::Float32(); | 1486 MachineType type = MachineType::Float32(); |
1476 ExternalReference ref = | 1487 ExternalReference ref = |
1477 ExternalReference::f32_ceil_wrapper_function(jsgraph()->isolate()); | 1488 ExternalReference::wasm_f32_ceil(jsgraph()->isolate()); |
1478 return BuildCFuncInstruction(ref, type, input); | 1489 return BuildCFuncInstruction(ref, type, input); |
1479 } | 1490 } |
1480 | 1491 |
1481 Node* WasmGraphBuilder::BuildF32NearestInt(Node* input) { | 1492 Node* WasmGraphBuilder::BuildF32NearestInt(Node* input) { |
1482 MachineType type = MachineType::Float32(); | 1493 MachineType type = MachineType::Float32(); |
1483 ExternalReference ref = | 1494 ExternalReference ref = |
1484 ExternalReference::f32_nearest_int_wrapper_function(jsgraph()->isolate()); | 1495 ExternalReference::wasm_f32_nearest_int(jsgraph()->isolate()); |
1485 return BuildCFuncInstruction(ref, type, input); | 1496 return BuildCFuncInstruction(ref, type, input); |
1486 } | 1497 } |
1487 | 1498 |
1488 Node* WasmGraphBuilder::BuildF64Trunc(Node* input) { | 1499 Node* WasmGraphBuilder::BuildF64Trunc(Node* input) { |
1489 MachineType type = MachineType::Float64(); | 1500 MachineType type = MachineType::Float64(); |
1490 ExternalReference ref = | 1501 ExternalReference ref = |
1491 ExternalReference::f64_trunc_wrapper_function(jsgraph()->isolate()); | 1502 ExternalReference::wasm_f64_trunc(jsgraph()->isolate()); |
1492 return BuildCFuncInstruction(ref, type, input); | 1503 return BuildCFuncInstruction(ref, type, input); |
1493 } | 1504 } |
1494 | 1505 |
1495 Node* WasmGraphBuilder::BuildF64Floor(Node* input) { | 1506 Node* WasmGraphBuilder::BuildF64Floor(Node* input) { |
1496 MachineType type = MachineType::Float64(); | 1507 MachineType type = MachineType::Float64(); |
1497 ExternalReference ref = | 1508 ExternalReference ref = |
1498 ExternalReference::f64_floor_wrapper_function(jsgraph()->isolate()); | 1509 ExternalReference::wasm_f64_floor(jsgraph()->isolate()); |
1499 return BuildCFuncInstruction(ref, type, input); | 1510 return BuildCFuncInstruction(ref, type, input); |
1500 } | 1511 } |
1501 | 1512 |
1502 Node* WasmGraphBuilder::BuildF64Ceil(Node* input) { | 1513 Node* WasmGraphBuilder::BuildF64Ceil(Node* input) { |
1503 MachineType type = MachineType::Float64(); | 1514 MachineType type = MachineType::Float64(); |
1504 ExternalReference ref = | 1515 ExternalReference ref = |
1505 ExternalReference::f64_ceil_wrapper_function(jsgraph()->isolate()); | 1516 ExternalReference::wasm_f64_ceil(jsgraph()->isolate()); |
1506 return BuildCFuncInstruction(ref, type, input); | 1517 return BuildCFuncInstruction(ref, type, input); |
1507 } | 1518 } |
1508 | 1519 |
1509 Node* WasmGraphBuilder::BuildF64NearestInt(Node* input) { | 1520 Node* WasmGraphBuilder::BuildF64NearestInt(Node* input) { |
1510 MachineType type = MachineType::Float64(); | 1521 MachineType type = MachineType::Float64(); |
1511 ExternalReference ref = | 1522 ExternalReference ref = |
1512 ExternalReference::f64_nearest_int_wrapper_function(jsgraph()->isolate()); | 1523 ExternalReference::wasm_f64_nearest_int(jsgraph()->isolate()); |
1513 return BuildCFuncInstruction(ref, type, input); | 1524 return BuildCFuncInstruction(ref, type, input); |
1514 } | 1525 } |
1515 | 1526 |
1516 Node* WasmGraphBuilder::BuildF64Acos(Node* input) { | 1527 Node* WasmGraphBuilder::BuildF64Acos(Node* input) { |
1517 MachineType type = MachineType::Float64(); | 1528 MachineType type = MachineType::Float64(); |
1518 ExternalReference ref = | 1529 ExternalReference ref = |
1519 ExternalReference::f64_acos_wrapper_function(jsgraph()->isolate()); | 1530 ExternalReference::f64_acos_wrapper_function(jsgraph()->isolate()); |
1520 return BuildCFuncInstruction(ref, type, input); | 1531 return BuildCFuncInstruction(ref, type, input); |
1521 } | 1532 } |
1522 | 1533 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1638 | 1649 |
1639 const Operator* load_op = jsgraph()->machine()->Load(type); | 1650 const Operator* load_op = jsgraph()->machine()->Load(type); |
1640 | 1651 |
1641 Node* load = | 1652 Node* load = |
1642 graph()->NewNode(load_op, stack_slot_param0, jsgraph()->Int32Constant(0), | 1653 graph()->NewNode(load_op, stack_slot_param0, jsgraph()->Int32Constant(0), |
1643 *effect_, *control_); | 1654 *effect_, *control_); |
1644 *effect_ = load; | 1655 *effect_ = load; |
1645 return load; | 1656 return load; |
1646 } | 1657 } |
1647 | 1658 |
| 1659 Node* WasmGraphBuilder::BuildF32SConvertI64(Node* input) { |
| 1660 return BuildConversionInstruction( |
| 1661 input, ExternalReference::wasm_int64_to_float32(jsgraph()->isolate()), |
| 1662 MachineRepresentation::kWord64, MachineType::Float32()); |
| 1663 } |
| 1664 Node* WasmGraphBuilder::BuildF32UConvertI64(Node* input) { |
| 1665 return BuildConversionInstruction( |
| 1666 input, ExternalReference::wasm_uint64_to_float32(jsgraph()->isolate()), |
| 1667 MachineRepresentation::kWord64, MachineType::Float32()); |
| 1668 } |
| 1669 Node* WasmGraphBuilder::BuildF64SConvertI64(Node* input) { |
| 1670 return BuildConversionInstruction( |
| 1671 input, ExternalReference::wasm_int64_to_float64(jsgraph()->isolate()), |
| 1672 MachineRepresentation::kWord64, MachineType::Float64()); |
| 1673 } |
| 1674 Node* WasmGraphBuilder::BuildF64UConvertI64(Node* input) { |
| 1675 return BuildConversionInstruction( |
| 1676 input, ExternalReference::wasm_uint64_to_float64(jsgraph()->isolate()), |
| 1677 MachineRepresentation::kWord64, MachineType::Float64()); |
| 1678 } |
| 1679 Node* WasmGraphBuilder::BuildConversionInstruction( |
| 1680 Node* input, ExternalReference ref, |
| 1681 MachineRepresentation parameter_representation, |
| 1682 const MachineType result_type) { |
| 1683 Node* stack_slot_param = graph()->NewNode( |
| 1684 jsgraph()->machine()->StackSlot(parameter_representation)); |
| 1685 Node* stack_slot_result = graph()->NewNode( |
| 1686 jsgraph()->machine()->StackSlot(result_type.representation())); |
| 1687 const Operator* store_op = jsgraph()->machine()->Store( |
| 1688 StoreRepresentation(parameter_representation, kNoWriteBarrier)); |
| 1689 *effect_ = |
| 1690 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0), |
| 1691 input, *effect_, *control_); |
| 1692 MachineSignature::Builder sig_builder(jsgraph()->zone(), 0, 2); |
| 1693 sig_builder.AddParam(MachineType::Pointer()); |
| 1694 sig_builder.AddParam(MachineType::Pointer()); |
| 1695 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); |
| 1696 Node* args[] = {function, stack_slot_param, stack_slot_result}; |
| 1697 BuildCCall(sig_builder.Build(), args); |
| 1698 const Operator* load_op = jsgraph()->machine()->Load(result_type); |
| 1699 Node* load = |
| 1700 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), |
| 1701 *effect_, *control_); |
| 1702 *effect_ = load; |
| 1703 return load; |
| 1704 } |
| 1705 |
1648 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { | 1706 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { |
1649 const size_t params = sig->parameter_count(); | 1707 const size_t params = sig->parameter_count(); |
1650 const size_t extra = 2; // effect and control inputs. | 1708 const size_t extra = 2; // effect and control inputs. |
1651 const size_t count = 1 + params + extra; | 1709 const size_t count = 1 + params + extra; |
1652 | 1710 |
1653 // Reallocate the buffer to make space for extra inputs. | 1711 // Reallocate the buffer to make space for extra inputs. |
1654 args = Realloc(args, count); | 1712 args = Realloc(args, count); |
1655 | 1713 |
1656 // Add effect and control inputs. | 1714 // Add effect and control inputs. |
1657 args[params + 1] = *effect_; | 1715 args[params + 1] = *effect_; |
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2425 module_env->module->GetName(function.name_offset)); | 2483 module_env->module->GetName(function.name_offset)); |
2426 } | 2484 } |
2427 | 2485 |
2428 return code; | 2486 return code; |
2429 } | 2487 } |
2430 | 2488 |
2431 | 2489 |
2432 } // namespace compiler | 2490 } // namespace compiler |
2433 } // namespace internal | 2491 } // namespace internal |
2434 } // namespace v8 | 2492 } // namespace v8 |
OLD | NEW |