| 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 |