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 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
536 break; | 536 break; |
537 case wasm::kExprI64GtU: | 537 case wasm::kExprI64GtU: |
538 op = m->Uint64LessThan(); | 538 op = m->Uint64LessThan(); |
539 std::swap(left, right); | 539 std::swap(left, right); |
540 break; | 540 break; |
541 case wasm::kExprI64GeU: | 541 case wasm::kExprI64GeU: |
542 op = m->Uint64LessThanOrEqual(); | 542 op = m->Uint64LessThanOrEqual(); |
543 std::swap(left, right); | 543 std::swap(left, right); |
544 break; | 544 break; |
545 | 545 |
546 // kExprI32ConvertI64: | |
547 // kExprI64SConvertI32: | |
548 // kExprI64UConvertI32: | |
549 | |
550 // kExprF64ReinterpretI64: | |
551 // kExprI64ReinterpretF64: | |
552 | |
553 // kExprI64Clz: | |
554 // kExprI64Ctz: | |
555 // kExprI64Popcnt: | |
556 | |
557 // kExprF32SConvertI64: | |
558 // kExprF32UConvertI64: | |
559 // kExprF64SConvertI64: | |
560 // kExprF64UConvertI64: | |
561 // kExprI64SConvertF32: | |
562 // kExprI64SConvertF64: | |
563 // kExprI64UConvertF32: | |
564 // kExprI64UConvertF64: | |
565 #if WASM_64 | 546 #if WASM_64 |
566 // Opcodes only supported on 64-bit platforms. | 547 // Opcodes only supported on 64-bit platforms. |
567 // TODO(titzer): query the machine operator builder here instead of #ifdef. | 548 // TODO(titzer): query the machine operator builder here instead of #ifdef. |
568 case wasm::kExprI64Add: | 549 case wasm::kExprI64Add: |
569 op = m->Int64Add(); | 550 op = m->Int64Add(); |
570 break; | 551 break; |
571 case wasm::kExprI64Sub: | 552 case wasm::kExprI64Sub: |
572 op = m->Int64Sub(); | 553 op = m->Int64Sub(); |
573 break; | 554 break; |
574 case wasm::kExprI64Mul: | 555 case wasm::kExprI64Mul: |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
820 } | 801 } |
821 case wasm::kExprF64NearestInt: { | 802 case wasm::kExprF64NearestInt: { |
822 if (!m->Float64RoundTiesEven().IsSupported()) | 803 if (!m->Float64RoundTiesEven().IsSupported()) |
823 return BuildF64NearestInt(input); | 804 return BuildF64NearestInt(input); |
824 op = m->Float64RoundTiesEven().op(); | 805 op = m->Float64RoundTiesEven().op(); |
825 break; | 806 break; |
826 } | 807 } |
827 case wasm::kExprI32ConvertI64: | 808 case wasm::kExprI32ConvertI64: |
828 op = m->TruncateInt64ToInt32(); | 809 op = m->TruncateInt64ToInt32(); |
829 break; | 810 break; |
811 // kExprI32ConvertI64: | |
812 // kExprI64SConvertI32: | |
813 // kExprI64UConvertI32: | |
814 | |
815 // kExprF64ReinterpretI64: | |
816 // kExprI64ReinterpretF64: | |
817 | |
818 // kExprI64Clz: | |
819 // kExprI64Ctz: | |
820 // kExprI64Popcnt: | |
821 | |
822 // kExprF32SConvertI64: | |
823 case wasm::kExprF32SConvertI64: | |
824 if (kPointerSize == 4) { | |
825 return BuildF32SConvertI64(input); | |
826 } | |
827 op = m->RoundInt64ToFloat32(); | |
828 break; | |
829 // kExprF32UConvertI64: | |
830 case wasm::kExprF32UConvertI64: | |
831 if (kPointerSize == 4) { | |
832 return BuildF32UConvertI64(input); | |
833 } | |
834 op = m->RoundUint64ToFloat32(); | |
835 break; | |
836 // kExprF64SConvertI64: | |
837 case wasm::kExprF64SConvertI64: | |
838 if (kPointerSize == 4) { | |
839 return BuildF64SConvertI64(input); | |
840 } | |
841 op = m->RoundInt64ToFloat64(); | |
842 break; | |
843 // kExprF64UConvertI64: | |
844 case wasm::kExprF64UConvertI64: | |
845 if (kPointerSize == 4) { | |
846 return BuildF64UConvertI64(input); | |
847 } | |
848 op = m->RoundUint64ToFloat64(); | |
849 break; | |
850 // kExprI64SConvertF32: | |
851 // kExprI64SConvertF64: | |
852 // kExprI64UConvertF32: | |
853 // kExprI64UConvertF64: | |
854 | |
830 #if WASM_64 | 855 #if WASM_64 |
831 // Opcodes only supported on 64-bit platforms. | 856 // Opcodes only supported on 64-bit platforms. |
832 // TODO(titzer): query the machine operator builder here instead of #ifdef. | 857 // TODO(titzer): query the machine operator builder here instead of #ifdef. |
833 case wasm::kExprI64SConvertI32: | 858 case wasm::kExprI64SConvertI32: |
834 op = m->ChangeInt32ToInt64(); | 859 op = m->ChangeInt32ToInt64(); |
835 break; | 860 break; |
836 case wasm::kExprI64UConvertI32: | 861 case wasm::kExprI64UConvertI32: |
837 op = m->ChangeUint32ToUint64(); | 862 op = m->ChangeUint32ToUint64(); |
838 break; | 863 break; |
839 case wasm::kExprF32SConvertI64: | |
840 op = m->RoundInt64ToFloat32(); | |
841 break; | |
842 case wasm::kExprF32UConvertI64: | |
843 op = m->RoundUint64ToFloat32(); | |
844 break; | |
845 case wasm::kExprF64SConvertI64: | |
846 op = m->RoundInt64ToFloat64(); | |
847 break; | |
848 case wasm::kExprF64UConvertI64: | |
849 op = m->RoundUint64ToFloat64(); | |
850 break; | |
851 case wasm::kExprI64SConvertF32: { | 864 case wasm::kExprI64SConvertF32: { |
852 Node* trunc = graph()->NewNode(m->TryTruncateFloat32ToInt64(), input); | 865 Node* trunc = graph()->NewNode(m->TryTruncateFloat32ToInt64(), input); |
853 Node* result = | 866 Node* result = |
854 graph()->NewNode(jsgraph()->common()->Projection(0), trunc); | 867 graph()->NewNode(jsgraph()->common()->Projection(0), trunc); |
855 Node* overflow = | 868 Node* overflow = |
856 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); | 869 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); |
857 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); | 870 trap_->ZeroCheck64(kTrapFloatUnrepresentable, overflow); |
858 return result; | 871 return result; |
859 } | 872 } |
860 case wasm::kExprI64SConvertF64: { | 873 case wasm::kExprI64SConvertF64: { |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1394 jsgraph()->Int64Constant(0x00000000ffffffff)), | 1407 jsgraph()->Int64Constant(0x00000000ffffffff)), |
1395 Binop(wasm::kExprI64And, result, | 1408 Binop(wasm::kExprI64And, result, |
1396 jsgraph()->Int64Constant(0x00000000ffffffff))); | 1409 jsgraph()->Int64Constant(0x00000000ffffffff))); |
1397 | 1410 |
1398 return result; | 1411 return result; |
1399 } | 1412 } |
1400 | 1413 |
1401 Node* WasmGraphBuilder::BuildF32Trunc(Node* input) { | 1414 Node* WasmGraphBuilder::BuildF32Trunc(Node* input) { |
1402 MachineType type = MachineType::Float32(); | 1415 MachineType type = MachineType::Float32(); |
1403 ExternalReference ref = | 1416 ExternalReference ref = |
1404 ExternalReference::f32_trunc_wrapper_function(jsgraph()->isolate()); | 1417 ExternalReference::wasm_f32_trunc(jsgraph()->isolate()); |
1405 return BuildRoundingInstruction(input, ref, type); | 1418 return BuildRoundingInstruction(input, ref, type); |
1406 } | 1419 } |
1407 | 1420 |
1408 Node* WasmGraphBuilder::BuildF32Floor(Node* input) { | 1421 Node* WasmGraphBuilder::BuildF32Floor(Node* input) { |
1409 MachineType type = MachineType::Float32(); | 1422 MachineType type = MachineType::Float32(); |
1410 ExternalReference ref = | 1423 ExternalReference ref = |
1411 ExternalReference::f32_floor_wrapper_function(jsgraph()->isolate()); | 1424 ExternalReference::wasm_f32_floor(jsgraph()->isolate()); |
1412 return BuildRoundingInstruction(input, ref, type); | 1425 return BuildRoundingInstruction(input, ref, type); |
1413 } | 1426 } |
1414 | 1427 |
1415 Node* WasmGraphBuilder::BuildF32Ceil(Node* input) { | 1428 Node* WasmGraphBuilder::BuildF32Ceil(Node* input) { |
1416 MachineType type = MachineType::Float32(); | 1429 MachineType type = MachineType::Float32(); |
1417 ExternalReference ref = | 1430 ExternalReference ref = |
1418 ExternalReference::f32_ceil_wrapper_function(jsgraph()->isolate()); | 1431 ExternalReference::wasm_f32_ceil(jsgraph()->isolate()); |
1419 return BuildRoundingInstruction(input, ref, type); | 1432 return BuildRoundingInstruction(input, ref, type); |
1420 } | 1433 } |
1421 | 1434 |
1422 Node* WasmGraphBuilder::BuildF32NearestInt(Node* input) { | 1435 Node* WasmGraphBuilder::BuildF32NearestInt(Node* input) { |
1423 MachineType type = MachineType::Float32(); | 1436 MachineType type = MachineType::Float32(); |
1424 ExternalReference ref = | 1437 ExternalReference ref = |
1425 ExternalReference::f32_nearest_int_wrapper_function(jsgraph()->isolate()); | 1438 ExternalReference::wasm_f32_nearest_int(jsgraph()->isolate()); |
1426 return BuildRoundingInstruction(input, ref, type); | 1439 return BuildRoundingInstruction(input, ref, type); |
1427 } | 1440 } |
1428 | 1441 |
1429 Node* WasmGraphBuilder::BuildF64Trunc(Node* input) { | 1442 Node* WasmGraphBuilder::BuildF64Trunc(Node* input) { |
1430 MachineType type = MachineType::Float64(); | 1443 MachineType type = MachineType::Float64(); |
1431 ExternalReference ref = | 1444 ExternalReference ref = |
1432 ExternalReference::f64_trunc_wrapper_function(jsgraph()->isolate()); | 1445 ExternalReference::wasm_f64_trunc(jsgraph()->isolate()); |
1433 return BuildRoundingInstruction(input, ref, type); | 1446 return BuildRoundingInstruction(input, ref, type); |
1434 } | 1447 } |
1435 | 1448 |
1436 Node* WasmGraphBuilder::BuildF64Floor(Node* input) { | 1449 Node* WasmGraphBuilder::BuildF64Floor(Node* input) { |
1437 MachineType type = MachineType::Float64(); | 1450 MachineType type = MachineType::Float64(); |
1438 ExternalReference ref = | 1451 ExternalReference ref = |
1439 ExternalReference::f64_floor_wrapper_function(jsgraph()->isolate()); | 1452 ExternalReference::wasm_f64_floor(jsgraph()->isolate()); |
1440 return BuildRoundingInstruction(input, ref, type); | 1453 return BuildRoundingInstruction(input, ref, type); |
1441 } | 1454 } |
1442 | 1455 |
1443 Node* WasmGraphBuilder::BuildF64Ceil(Node* input) { | 1456 Node* WasmGraphBuilder::BuildF64Ceil(Node* input) { |
1444 MachineType type = MachineType::Float64(); | 1457 MachineType type = MachineType::Float64(); |
1445 ExternalReference ref = | 1458 ExternalReference ref = |
1446 ExternalReference::f64_ceil_wrapper_function(jsgraph()->isolate()); | 1459 ExternalReference::wasm_f64_ceil(jsgraph()->isolate()); |
1447 return BuildRoundingInstruction(input, ref, type); | 1460 return BuildRoundingInstruction(input, ref, type); |
1448 } | 1461 } |
1449 | 1462 |
1450 Node* WasmGraphBuilder::BuildF64NearestInt(Node* input) { | 1463 Node* WasmGraphBuilder::BuildF64NearestInt(Node* input) { |
1451 MachineType type = MachineType::Float64(); | 1464 MachineType type = MachineType::Float64(); |
1452 ExternalReference ref = | 1465 ExternalReference ref = |
1453 ExternalReference::f64_nearest_int_wrapper_function(jsgraph()->isolate()); | 1466 ExternalReference::wasm_f64_nearest_int(jsgraph()->isolate()); |
1454 return BuildRoundingInstruction(input, ref, type); | 1467 return BuildRoundingInstruction(input, ref, type); |
1455 } | 1468 } |
1456 | 1469 |
1457 Node* WasmGraphBuilder::BuildRoundingInstruction(Node* input, | 1470 Node* WasmGraphBuilder::BuildRoundingInstruction(Node* input, |
1458 ExternalReference ref, | 1471 ExternalReference ref, |
1459 MachineType type) { | 1472 MachineType type) { |
1460 // We do truncation by calling a C function which calculates the truncation | 1473 // We do truncation by calling a C function which calculates the truncation |
1461 // for us. The input is passed to the C function as a double* to avoid double | 1474 // for us. The input is passed to the C function as a double* to avoid double |
1462 // parameters. For this we reserve a slot on the stack, store the parameter in | 1475 // parameters. For this we reserve a slot on the stack, store the parameter in |
1463 // that slot, pass a pointer to the slot to the C function, and after calling | 1476 // that slot, pass a pointer to the slot to the C function, and after calling |
(...skipping 18 matching lines...) Expand all Loading... | |
1482 | 1495 |
1483 const Operator* load_op = jsgraph()->machine()->Load(type); | 1496 const Operator* load_op = jsgraph()->machine()->Load(type); |
1484 | 1497 |
1485 Node* load = | 1498 Node* load = |
1486 graph()->NewNode(load_op, stack_slot_param, jsgraph()->Int32Constant(0), | 1499 graph()->NewNode(load_op, stack_slot_param, jsgraph()->Int32Constant(0), |
1487 *effect_, *control_); | 1500 *effect_, *control_); |
1488 *effect_ = load; | 1501 *effect_ = load; |
1489 return load; | 1502 return load; |
1490 } | 1503 } |
1491 | 1504 |
1505 Node* WasmGraphBuilder::BuildF32SConvertI64(Node* input) { | |
1506 return BuildConversionInstruction( | |
1507 input, ExternalReference::wasm_int64_to_float32(jsgraph()->isolate()), | |
1508 MachineRepresentation::kWord64, MachineType::Float32()); | |
1509 } | |
1510 | |
1511 Node* WasmGraphBuilder::BuildF32UConvertI64(Node* input) { | |
1512 return BuildConversionInstruction( | |
1513 input, ExternalReference::wasm_uint64_to_float32(jsgraph()->isolate()), | |
1514 MachineRepresentation::kWord64, MachineType::Float32()); | |
1515 } | |
1516 | |
1517 Node* WasmGraphBuilder::BuildF64SConvertI64(Node* input) { | |
1518 return BuildConversionInstruction( | |
1519 input, ExternalReference::wasm_int64_to_float64(jsgraph()->isolate()), | |
1520 MachineRepresentation::kWord64, MachineType::Float64()); | |
1521 } | |
1522 | |
1523 Node* WasmGraphBuilder::BuildF64UConvertI64(Node* input) { | |
1524 return BuildConversionInstruction( | |
1525 input, ExternalReference::wasm_uint64_to_float64(jsgraph()->isolate()), | |
1526 MachineRepresentation::kWord64, MachineType::Float64()); | |
1527 } | |
1528 | |
1529 Node* WasmGraphBuilder::BuildConversionInstruction( | |
1530 Node* input, ExternalReference ref, | |
1531 MachineRepresentation parameter_representation, | |
1532 const MachineType result_type) { | |
1533 Node* stack_slot_param = graph()->NewNode( | |
1534 jsgraph()->machine()->StackSlot(parameter_representation)); | |
1535 Node* stack_slot_result = graph()->NewNode( | |
1536 jsgraph()->machine()->StackSlot(result_type.representation())); | |
1537 const Operator* store_op = jsgraph()->machine()->Store( | |
1538 StoreRepresentation(parameter_representation, kNoWriteBarrier)); | |
1539 *effect_ = | |
1540 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0), | |
1541 input, *effect_, *control_); | |
1542 Signature<MachineType>::Builder sig_builder(jsgraph()->zone(), 0, 2); | |
titzer
2016/02/28 15:26:03
I think you can use the type alias MachineSignatur
ahaas
2016/03/02 14:02:56
Done. I just don't like typedef too much.
| |
1543 sig_builder.AddParam(MachineType::Pointer()); | |
1544 sig_builder.AddParam(MachineType::Pointer()); | |
1545 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); | |
1546 Node* args[] = {function, stack_slot_param, stack_slot_result}; | |
1547 BuildCCall(sig_builder.Build(), args); | |
1548 const Operator* load_op = jsgraph()->machine()->Load(result_type); | |
1549 Node* load = | |
1550 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), | |
1551 *effect_, *control_); | |
1552 *effect_ = load; | |
1553 return load; | |
1554 } | |
1555 | |
1492 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { | 1556 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { |
1493 const size_t params = sig->parameter_count(); | 1557 const size_t params = sig->parameter_count(); |
1494 const size_t extra = 2; // effect and control inputs. | 1558 const size_t extra = 2; // effect and control inputs. |
1495 const size_t count = 1 + params + extra; | 1559 const size_t count = 1 + params + extra; |
1496 | 1560 |
1497 // Reallocate the buffer to make space for extra inputs. | 1561 // Reallocate the buffer to make space for extra inputs. |
1498 args = Realloc(args, count); | 1562 args = Realloc(args, count); |
1499 | 1563 |
1500 // Add effect and control inputs. | 1564 // Add effect and control inputs. |
1501 args[params + 1] = *effect_; | 1565 args[params + 1] = *effect_; |
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2247 module_env->module->GetName(function.name_offset)); | 2311 module_env->module->GetName(function.name_offset)); |
2248 } | 2312 } |
2249 | 2313 |
2250 return code; | 2314 return code; |
2251 } | 2315 } |
2252 | 2316 |
2253 | 2317 |
2254 } // namespace compiler | 2318 } // namespace compiler |
2255 } // namespace internal | 2319 } // namespace internal |
2256 } // namespace v8 | 2320 } // namespace v8 |
OLD | NEW |