Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/compiler/wasm-compiler.cc

Issue 1729833002: Add wasm internal opcodes for asm.js stdlib functions we're missing. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/snapshot/serializer-common.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 if (!m->Float64RoundTruncate().IsSupported()) return BuildF64Trunc(input); 826 if (!m->Float64RoundTruncate().IsSupported()) return BuildF64Trunc(input);
818 op = m->Float64RoundTruncate().op(); 827 op = m->Float64RoundTruncate().op();
819 break; 828 break;
820 } 829 }
821 case wasm::kExprF64NearestInt: { 830 case wasm::kExprF64NearestInt: {
822 if (!m->Float64RoundTiesEven().IsSupported()) 831 if (!m->Float64RoundTiesEven().IsSupported())
823 return BuildF64NearestInt(input); 832 return BuildF64NearestInt(input);
824 op = m->Float64RoundTiesEven().op(); 833 op = m->Float64RoundTiesEven().op();
825 break; 834 break;
826 } 835 }
836 case wasm::kExprF64Acos: {
837 return BuildF64Acos(input);
838 }
839 case wasm::kExprF64Asin: {
840 return BuildF64Asin(input);
841 }
842 case wasm::kExprF64Atan: {
843 return BuildF64Atan(input);
844 }
845 case wasm::kExprF64Cos: {
846 return BuildF64Cos(input);
847 }
848 case wasm::kExprF64Sin: {
849 return BuildF64Sin(input);
850 }
851 case wasm::kExprF64Tan: {
852 return BuildF64Tan(input);
853 }
854 case wasm::kExprF64Exp: {
855 return BuildF64Exp(input);
856 }
857 case wasm::kExprF64Log: {
858 return BuildF64Log(input);
859 }
827 case wasm::kExprI32ConvertI64: 860 case wasm::kExprI32ConvertI64:
828 op = m->TruncateInt64ToInt32(); 861 op = m->TruncateInt64ToInt32();
829 break; 862 break;
830 #if WASM_64 863 #if WASM_64
831 // Opcodes only supported on 64-bit platforms. 864 // Opcodes only supported on 64-bit platforms.
832 // TODO(titzer): query the machine operator builder here instead of #ifdef. 865 // TODO(titzer): query the machine operator builder here instead of #ifdef.
833 case wasm::kExprI64SConvertI32: 866 case wasm::kExprI64SConvertI32:
834 op = m->ChangeInt32ToInt64(); 867 op = m->ChangeInt32ToInt64();
835 break; 868 break;
836 case wasm::kExprI64UConvertI32: 869 case wasm::kExprI64UConvertI32:
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
1480 // the C function we collect the return value from the stack slot.
1481 1512
1482 Node* stack_slot_param = 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*'s to avoid double
1588 // parameters. For this we reserve slots on the stack, store the parameters
1589 // in those slots, pass pointers to the slot to the C function,
1590 // and after calling the C function we collect the return value from
1591 // the stack slot.
1592
1593 Node* stack_slot_param0 =
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_op0 = jsgraph()->machine()->Store(
1486 StoreRepresentation(type.representation(), kNoWriteBarrier)); 1597 StoreRepresentation(type.representation(), kNoWriteBarrier));
1487 *effect_ = 1598 *effect_ = graph()->NewNode(store_op0, stack_slot_param0,
1488 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0), 1599 jsgraph()->Int32Constant(0), input0, *effect_,
1489 input, *effect_, *control_); 1600 *control_);
1490 1601
1491 Signature<MachineType>::Builder sig_builder(jsgraph()->zone(), 0, 1); 1602 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
1603 Node** args = Buffer(4);
1604 args[0] = function;
1605 args[1] = stack_slot_param0;
1606 int input_count = 1;
1607
1608 if (input1 != nullptr) {
1609 Node* stack_slot_param1 = graph()->NewNode(
1610 jsgraph()->machine()->StackSlot(type.representation()));
1611 const Operator* store_op1 = jsgraph()->machine()->Store(
1612 StoreRepresentation(type.representation(), kNoWriteBarrier));
1613 *effect_ = graph()->NewNode(store_op1, stack_slot_param1,
1614 jsgraph()->Int32Constant(0), input1, *effect_,
1615 *control_);
1616 args = Realloc(args, 5);
1617 args[2] = stack_slot_param1;
1618 ++input_count;
1619 }
1620
1621 Signature<MachineType>::Builder sig_builder(jsgraph()->zone(), 0,
1622 input_count);
1492 sig_builder.AddParam(MachineType::Pointer()); 1623 sig_builder.AddParam(MachineType::Pointer());
1493 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); 1624 if (input1 != nullptr) {
1494 1625 sig_builder.AddParam(MachineType::Pointer());
1495 Node* args[] = {function, stack_slot_param}; 1626 }
1496
1497 BuildCCall(sig_builder.Build(), args); 1627 BuildCCall(sig_builder.Build(), args);
1498 1628
1499 const Operator* load_op = jsgraph()->machine()->Load(type); 1629 const Operator* load_op = jsgraph()->machine()->Load(type);
1500 1630
1501 Node* load = 1631 Node* load =
1502 graph()->NewNode(load_op, stack_slot_param, jsgraph()->Int32Constant(0), 1632 graph()->NewNode(load_op, stack_slot_param0, jsgraph()->Int32Constant(0),
1503 *effect_, *control_); 1633 *effect_, *control_);
1504 *effect_ = load; 1634 *effect_ = load;
1505 return load; 1635 return load;
1506 } 1636 }
1507 1637
1508 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { 1638 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) {
1509 const size_t params = sig->parameter_count(); 1639 const size_t params = sig->parameter_count();
1510 const size_t extra = 2; // effect and control inputs. 1640 const size_t extra = 2; // effect and control inputs.
1511 const size_t count = 1 + params + extra; 1641 const size_t count = 1 + params + extra;
1512 1642
(...skipping 27 matching lines...) Expand all
1540 1670
1541 CallDescriptor* descriptor = 1671 CallDescriptor* descriptor =
1542 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig); 1672 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig);
1543 const Operator* op = jsgraph()->common()->Call(descriptor); 1673 const Operator* op = jsgraph()->common()->Call(descriptor);
1544 Node* call = graph()->NewNode(op, static_cast<int>(count), args); 1674 Node* call = graph()->NewNode(op, static_cast<int>(count), args);
1545 1675
1546 *effect_ = call; 1676 *effect_ = call;
1547 return call; 1677 return call;
1548 } 1678 }
1549 1679
1550
1551 Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args) { 1680 Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args) {
1552 DCHECK_NULL(args[0]); 1681 DCHECK_NULL(args[0]);
1553 1682
1554 // Add code object as constant. 1683 // Add code object as constant.
1555 args[0] = Constant(module_->GetFunctionCode(index)); 1684 args[0] = Constant(module_->GetFunctionCode(index));
1556 wasm::FunctionSig* sig = module_->GetFunctionSignature(index); 1685 wasm::FunctionSig* sig = module_->GetFunctionSignature(index);
1557 1686
1558 return BuildWasmCall(sig, args); 1687 return BuildWasmCall(sig, args);
1559 } 1688 }
1560 1689
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
2263 module_env->module->GetName(function.name_offset)); 2392 module_env->module->GetName(function.name_offset));
2264 } 2393 }
2265 2394
2266 return code; 2395 return code;
2267 } 2396 }
2268 2397
2269 2398
2270 } // namespace compiler 2399 } // namespace compiler
2271 } // namespace internal 2400 } // namespace internal
2272 } // namespace v8 2401 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/snapshot/serializer-common.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698