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 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 std::swap(left, right); | 690 std::swap(left, right); |
691 break; | 691 break; |
692 case wasm::kExprF32Min: | 692 case wasm::kExprF32Min: |
693 return BuildF32Min(left, right); | 693 return BuildF32Min(left, right); |
694 case wasm::kExprF64Min: | 694 case wasm::kExprF64Min: |
695 return BuildF64Min(left, right); | 695 return BuildF64Min(left, right); |
696 case wasm::kExprF32Max: | 696 case wasm::kExprF32Max: |
697 return BuildF32Max(left, right); | 697 return BuildF32Max(left, right); |
698 case wasm::kExprF64Max: | 698 case wasm::kExprF64Max: |
699 return BuildF64Max(left, right); | 699 return BuildF64Max(left, right); |
| 700 case wasm::kExprF64Pow: { |
| 701 return BuildF64Pow(left, right); |
| 702 } |
| 703 case wasm::kExprF64Atan2: { |
| 704 return BuildF64Atan2(left, right); |
| 705 } |
| 706 case wasm::kExprF64Mod: { |
| 707 return BuildF64Mod(left, right); |
| 708 } |
700 default: | 709 default: |
701 op = UnsupportedOpcode(opcode); | 710 op = UnsupportedOpcode(opcode); |
702 } | 711 } |
703 return graph()->NewNode(op, left, right); | 712 return graph()->NewNode(op, left, right); |
704 } | 713 } |
705 | 714 |
706 | 715 |
707 Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) { | 716 Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) { |
708 const Operator* op; | 717 const Operator* op; |
709 MachineOperatorBuilder* m = jsgraph()->machine(); | 718 MachineOperatorBuilder* m = jsgraph()->machine(); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
906 } | 915 } |
907 } | 916 } |
908 case wasm::kExprI64Popcnt: { | 917 case wasm::kExprI64Popcnt: { |
909 if (m->Word64Popcnt().IsSupported()) { | 918 if (m->Word64Popcnt().IsSupported()) { |
910 op = m->Word64Popcnt().op(); | 919 op = m->Word64Popcnt().op(); |
911 break; | 920 break; |
912 } else { | 921 } else { |
913 return BuildI64Popcnt(input); | 922 return BuildI64Popcnt(input); |
914 } | 923 } |
915 } | 924 } |
| 925 case wasm::kExprF64Acos: { |
| 926 return BuildF64Acos(input); |
| 927 } |
| 928 case wasm::kExprF64Asin: { |
| 929 return BuildF64Asin(input); |
| 930 } |
| 931 case wasm::kExprF64Atan: { |
| 932 return BuildF64Atan(input); |
| 933 } |
| 934 case wasm::kExprF64Cos: { |
| 935 return BuildF64Cos(input); |
| 936 } |
| 937 case wasm::kExprF64Sin: { |
| 938 return BuildF64Sin(input); |
| 939 } |
| 940 case wasm::kExprF64Tan: { |
| 941 return BuildF64Tan(input); |
| 942 } |
| 943 case wasm::kExprF64Exp: { |
| 944 return BuildF64Exp(input); |
| 945 } |
| 946 case wasm::kExprF64Log: { |
| 947 return BuildF64Log(input); |
| 948 } |
916 #endif | 949 #endif |
917 default: | 950 default: |
918 op = UnsupportedOpcode(opcode); | 951 op = UnsupportedOpcode(opcode); |
919 } | 952 } |
920 return graph()->NewNode(op, input); | 953 return graph()->NewNode(op, input); |
921 } | 954 } |
922 | 955 |
923 | 956 |
924 Node* WasmGraphBuilder::Float32Constant(float value) { | 957 Node* WasmGraphBuilder::Float32Constant(float value) { |
925 return jsgraph()->Float32Constant(value); | 958 return jsgraph()->Float32Constant(value); |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1411 Binop(wasm::kExprI64And, result, | 1444 Binop(wasm::kExprI64And, result, |
1412 jsgraph()->Int64Constant(0x00000000ffffffff))); | 1445 jsgraph()->Int64Constant(0x00000000ffffffff))); |
1413 | 1446 |
1414 return result; | 1447 return result; |
1415 } | 1448 } |
1416 | 1449 |
1417 Node* WasmGraphBuilder::BuildF32Trunc(Node* input) { | 1450 Node* WasmGraphBuilder::BuildF32Trunc(Node* input) { |
1418 MachineType type = MachineType::Float32(); | 1451 MachineType type = MachineType::Float32(); |
1419 ExternalReference ref = | 1452 ExternalReference ref = |
1420 ExternalReference::f32_trunc_wrapper_function(jsgraph()->isolate()); | 1453 ExternalReference::f32_trunc_wrapper_function(jsgraph()->isolate()); |
1421 return BuildRoundingInstruction(input, ref, type); | 1454 return BuildCFuncInstruction(ref, type, input); |
1422 } | 1455 } |
1423 | 1456 |
1424 Node* WasmGraphBuilder::BuildF32Floor(Node* input) { | 1457 Node* WasmGraphBuilder::BuildF32Floor(Node* input) { |
1425 MachineType type = MachineType::Float32(); | 1458 MachineType type = MachineType::Float32(); |
1426 ExternalReference ref = | 1459 ExternalReference ref = |
1427 ExternalReference::f32_floor_wrapper_function(jsgraph()->isolate()); | 1460 ExternalReference::f32_floor_wrapper_function(jsgraph()->isolate()); |
1428 return BuildRoundingInstruction(input, ref, type); | 1461 return BuildCFuncInstruction(ref, type, input); |
1429 } | 1462 } |
1430 | 1463 |
1431 Node* WasmGraphBuilder::BuildF32Ceil(Node* input) { | 1464 Node* WasmGraphBuilder::BuildF32Ceil(Node* input) { |
1432 MachineType type = MachineType::Float32(); | 1465 MachineType type = MachineType::Float32(); |
1433 ExternalReference ref = | 1466 ExternalReference ref = |
1434 ExternalReference::f32_ceil_wrapper_function(jsgraph()->isolate()); | 1467 ExternalReference::f32_ceil_wrapper_function(jsgraph()->isolate()); |
1435 return BuildRoundingInstruction(input, ref, type); | 1468 return BuildCFuncInstruction(ref, type, input); |
1436 } | 1469 } |
1437 | 1470 |
1438 Node* WasmGraphBuilder::BuildF32NearestInt(Node* input) { | 1471 Node* WasmGraphBuilder::BuildF32NearestInt(Node* input) { |
1439 MachineType type = MachineType::Float32(); | 1472 MachineType type = MachineType::Float32(); |
1440 ExternalReference ref = | 1473 ExternalReference ref = |
1441 ExternalReference::f32_nearest_int_wrapper_function(jsgraph()->isolate()); | 1474 ExternalReference::f32_nearest_int_wrapper_function(jsgraph()->isolate()); |
1442 return BuildRoundingInstruction(input, ref, type); | 1475 return BuildCFuncInstruction(ref, type, input); |
1443 } | 1476 } |
1444 | 1477 |
1445 Node* WasmGraphBuilder::BuildF64Trunc(Node* input) { | 1478 Node* WasmGraphBuilder::BuildF64Trunc(Node* input) { |
1446 MachineType type = MachineType::Float64(); | 1479 MachineType type = MachineType::Float64(); |
1447 ExternalReference ref = | 1480 ExternalReference ref = |
1448 ExternalReference::f64_trunc_wrapper_function(jsgraph()->isolate()); | 1481 ExternalReference::f64_trunc_wrapper_function(jsgraph()->isolate()); |
1449 return BuildRoundingInstruction(input, ref, type); | 1482 return BuildCFuncInstruction(ref, type, input); |
1450 } | 1483 } |
1451 | 1484 |
1452 Node* WasmGraphBuilder::BuildF64Floor(Node* input) { | 1485 Node* WasmGraphBuilder::BuildF64Floor(Node* input) { |
1453 MachineType type = MachineType::Float64(); | 1486 MachineType type = MachineType::Float64(); |
1454 ExternalReference ref = | 1487 ExternalReference ref = |
1455 ExternalReference::f64_floor_wrapper_function(jsgraph()->isolate()); | 1488 ExternalReference::f64_floor_wrapper_function(jsgraph()->isolate()); |
1456 return BuildRoundingInstruction(input, ref, type); | 1489 return BuildCFuncInstruction(ref, type, input); |
1457 } | 1490 } |
1458 | 1491 |
1459 Node* WasmGraphBuilder::BuildF64Ceil(Node* input) { | 1492 Node* WasmGraphBuilder::BuildF64Ceil(Node* input) { |
1460 MachineType type = MachineType::Float64(); | 1493 MachineType type = MachineType::Float64(); |
1461 ExternalReference ref = | 1494 ExternalReference ref = |
1462 ExternalReference::f64_ceil_wrapper_function(jsgraph()->isolate()); | 1495 ExternalReference::f64_ceil_wrapper_function(jsgraph()->isolate()); |
1463 return BuildRoundingInstruction(input, ref, type); | 1496 return BuildCFuncInstruction(ref, type, input); |
1464 } | 1497 } |
1465 | 1498 |
1466 Node* WasmGraphBuilder::BuildF64NearestInt(Node* input) { | 1499 Node* WasmGraphBuilder::BuildF64NearestInt(Node* input) { |
1467 MachineType type = MachineType::Float64(); | 1500 MachineType type = MachineType::Float64(); |
1468 ExternalReference ref = | 1501 ExternalReference ref = |
1469 ExternalReference::f64_nearest_int_wrapper_function(jsgraph()->isolate()); | 1502 ExternalReference::f64_nearest_int_wrapper_function(jsgraph()->isolate()); |
1470 return BuildRoundingInstruction(input, ref, type); | 1503 return BuildCFuncInstruction(ref, type, input); |
1471 } | 1504 } |
1472 | 1505 |
1473 Node* WasmGraphBuilder::BuildRoundingInstruction(Node* input, | 1506 Node* WasmGraphBuilder::BuildF64Acos(Node* input) { |
1474 ExternalReference ref, | 1507 MachineType type = MachineType::Float64(); |
1475 MachineType type) { | 1508 ExternalReference ref = |
1476 // We do truncation by calling a C function which calculates the truncation | 1509 ExternalReference::f64_acos_wrapper_function(jsgraph()->isolate()); |
1477 // for us. The input is passed to the C function as a double* to avoid double | 1510 return BuildCFuncInstruction(ref, type, input); |
1478 // parameters. For this we reserve a slot on the stack, store the parameter in | 1511 } |
1479 // that slot, pass a pointer to the slot to the C function, and after calling | 1512 |
1480 // the C function we collect the return value from the stack slot. | 1513 Node* WasmGraphBuilder::BuildF64Asin(Node* input) { |
| 1514 MachineType type = MachineType::Float64(); |
| 1515 ExternalReference ref = |
| 1516 ExternalReference::f64_asin_wrapper_function(jsgraph()->isolate()); |
| 1517 return BuildCFuncInstruction(ref, type, input); |
| 1518 } |
| 1519 |
| 1520 Node* WasmGraphBuilder::BuildF64Atan(Node* input) { |
| 1521 MachineType type = MachineType::Float64(); |
| 1522 ExternalReference ref = |
| 1523 ExternalReference::f64_atan_wrapper_function(jsgraph()->isolate()); |
| 1524 return BuildCFuncInstruction(ref, type, input); |
| 1525 } |
| 1526 |
| 1527 Node* WasmGraphBuilder::BuildF64Cos(Node* input) { |
| 1528 MachineType type = MachineType::Float64(); |
| 1529 ExternalReference ref = |
| 1530 ExternalReference::f64_cos_wrapper_function(jsgraph()->isolate()); |
| 1531 return BuildCFuncInstruction(ref, type, input); |
| 1532 } |
| 1533 |
| 1534 Node* WasmGraphBuilder::BuildF64Sin(Node* input) { |
| 1535 MachineType type = MachineType::Float64(); |
| 1536 ExternalReference ref = |
| 1537 ExternalReference::f64_sin_wrapper_function(jsgraph()->isolate()); |
| 1538 return BuildCFuncInstruction(ref, type, input); |
| 1539 } |
| 1540 |
| 1541 Node* WasmGraphBuilder::BuildF64Tan(Node* input) { |
| 1542 MachineType type = MachineType::Float64(); |
| 1543 ExternalReference ref = |
| 1544 ExternalReference::f64_tan_wrapper_function(jsgraph()->isolate()); |
| 1545 return BuildCFuncInstruction(ref, type, input); |
| 1546 } |
| 1547 |
| 1548 Node* WasmGraphBuilder::BuildF64Exp(Node* input) { |
| 1549 MachineType type = MachineType::Float64(); |
| 1550 ExternalReference ref = |
| 1551 ExternalReference::f64_exp_wrapper_function(jsgraph()->isolate()); |
| 1552 return BuildCFuncInstruction(ref, type, input); |
| 1553 } |
| 1554 |
| 1555 Node* WasmGraphBuilder::BuildF64Log(Node* input) { |
| 1556 MachineType type = MachineType::Float64(); |
| 1557 ExternalReference ref = |
| 1558 ExternalReference::f64_log_wrapper_function(jsgraph()->isolate()); |
| 1559 return BuildCFuncInstruction(ref, type, input); |
| 1560 } |
| 1561 |
| 1562 Node* WasmGraphBuilder::BuildF64Atan2(Node* left, Node* right) { |
| 1563 MachineType type = MachineType::Float64(); |
| 1564 ExternalReference ref = |
| 1565 ExternalReference::f64_atan2_wrapper_function(jsgraph()->isolate()); |
| 1566 return BuildCFuncInstruction(ref, type, left, right); |
| 1567 } |
| 1568 |
| 1569 Node* WasmGraphBuilder::BuildF64Pow(Node* left, Node* right) { |
| 1570 MachineType type = MachineType::Float64(); |
| 1571 ExternalReference ref = |
| 1572 ExternalReference::f64_pow_wrapper_function(jsgraph()->isolate()); |
| 1573 return BuildCFuncInstruction(ref, type, left, right); |
| 1574 } |
| 1575 |
| 1576 Node* WasmGraphBuilder::BuildF64Mod(Node* left, Node* right) { |
| 1577 MachineType type = MachineType::Float64(); |
| 1578 ExternalReference ref = |
| 1579 ExternalReference::f64_mod_wrapper_function(jsgraph()->isolate()); |
| 1580 return BuildCFuncInstruction(ref, type, left, right); |
| 1581 } |
| 1582 |
| 1583 Node* WasmGraphBuilder::BuildCFuncInstruction(ExternalReference ref, |
| 1584 MachineType type, Node* input0, |
| 1585 Node* input1) { |
| 1586 // We do truncation by calling a C function which calculates the result. |
| 1587 // The input is passed to the C function as a double* to avoid double |
| 1588 // parameters. For this we reserve slots on the stack, store the parameters |
| 1589 // in those slots, pass a pointer to the slot to the C function, |
| 1590 // and after calling the C function we collect the return value from |
| 1591 // the stack slot. |
1481 | 1592 |
1482 Node* stack_slot_param = | 1593 Node* stack_slot_param = |
1483 graph()->NewNode(jsgraph()->machine()->StackSlot(type.representation())); | 1594 graph()->NewNode(jsgraph()->machine()->StackSlot(type.representation())); |
1484 | 1595 |
1485 const Operator* store_op = jsgraph()->machine()->Store( | 1596 const Operator* store_op = jsgraph()->machine()->Store( |
1486 StoreRepresentation(type.representation(), kNoWriteBarrier)); | 1597 StoreRepresentation(type.representation(), kNoWriteBarrier)); |
1487 *effect_ = | 1598 *effect_ = |
1488 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0), | 1599 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0), |
1489 input, *effect_, *control_); | 1600 input0, *effect_, *control_); |
| 1601 if (input1 != nullptr) { |
| 1602 *effect_ = graph()->NewNode(store_op, stack_slot_param, |
| 1603 jsgraph()->Int32Constant(8), input1, *effect_, |
| 1604 *control_); |
| 1605 } |
1490 | 1606 |
1491 Signature<MachineType>::Builder sig_builder(jsgraph()->zone(), 0, 1); | 1607 Signature<MachineType>::Builder sig_builder(jsgraph()->zone(), 0, 1); |
1492 sig_builder.AddParam(MachineType::Pointer()); | 1608 sig_builder.AddParam(MachineType::Pointer()); |
1493 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); | 1609 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); |
1494 | 1610 |
1495 Node* args[] = {function, stack_slot_param}; | 1611 Node* args[] = {function, stack_slot_param}; |
1496 | 1612 |
1497 BuildCCall(sig_builder.Build(), args); | 1613 BuildCCall(sig_builder.Build(), args); |
1498 | 1614 |
1499 const Operator* load_op = jsgraph()->machine()->Load(type); | 1615 const Operator* load_op = jsgraph()->machine()->Load(type); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1540 | 1656 |
1541 CallDescriptor* descriptor = | 1657 CallDescriptor* descriptor = |
1542 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig); | 1658 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig); |
1543 const Operator* op = jsgraph()->common()->Call(descriptor); | 1659 const Operator* op = jsgraph()->common()->Call(descriptor); |
1544 Node* call = graph()->NewNode(op, static_cast<int>(count), args); | 1660 Node* call = graph()->NewNode(op, static_cast<int>(count), args); |
1545 | 1661 |
1546 *effect_ = call; | 1662 *effect_ = call; |
1547 return call; | 1663 return call; |
1548 } | 1664 } |
1549 | 1665 |
1550 | |
1551 Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args) { | 1666 Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args) { |
1552 DCHECK_NULL(args[0]); | 1667 DCHECK_NULL(args[0]); |
1553 | 1668 |
1554 // Add code object as constant. | 1669 // Add code object as constant. |
1555 args[0] = Constant(module_->GetFunctionCode(index)); | 1670 args[0] = Constant(module_->GetFunctionCode(index)); |
1556 wasm::FunctionSig* sig = module_->GetFunctionSignature(index); | 1671 wasm::FunctionSig* sig = module_->GetFunctionSignature(index); |
1557 | 1672 |
1558 return BuildWasmCall(sig, args); | 1673 return BuildWasmCall(sig, args); |
1559 } | 1674 } |
1560 | 1675 |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2263 module_env->module->GetName(function.name_offset)); | 2378 module_env->module->GetName(function.name_offset)); |
2264 } | 2379 } |
2265 | 2380 |
2266 return code; | 2381 return code; |
2267 } | 2382 } |
2268 | 2383 |
2269 | 2384 |
2270 } // namespace compiler | 2385 } // namespace compiler |
2271 } // namespace internal | 2386 } // namespace internal |
2272 } // namespace v8 | 2387 } // namespace v8 |
OLD | NEW |