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

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

Issue 1661463002: [wasm] Provide backoff implementations for the Fxx rounding instructions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@trunc64-external-reference
Patch Set: rebase. Created 4 years, 10 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/serialize.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 724 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 } 735 }
736 case wasm::kExprI32Popcnt: { 736 case wasm::kExprI32Popcnt: {
737 if (m->Word32Popcnt().IsSupported()) { 737 if (m->Word32Popcnt().IsSupported()) {
738 op = m->Word32Popcnt().op(); 738 op = m->Word32Popcnt().op();
739 break; 739 break;
740 } else { 740 } else {
741 return BuildI32Popcnt(input); 741 return BuildI32Popcnt(input);
742 } 742 }
743 } 743 }
744 case wasm::kExprF32Floor: { 744 case wasm::kExprF32Floor: {
745 if (m->Float32RoundDown().IsSupported()) { 745 if (!m->Float32RoundDown().IsSupported()) return BuildF32Floor(input);
746 op = m->Float32RoundDown().op(); 746 op = m->Float32RoundDown().op();
747 break; 747 break;
748 } else {
749 op = UnsupportedOpcode(opcode);
750 break;
751 }
752 } 748 }
753 case wasm::kExprF32Ceil: { 749 case wasm::kExprF32Ceil: {
754 if (m->Float32RoundUp().IsSupported()) { 750 if (!m->Float32RoundUp().IsSupported()) return BuildF32Ceil(input);
755 op = m->Float32RoundUp().op(); 751 op = m->Float32RoundUp().op();
756 break; 752 break;
757 } else {
758 op = UnsupportedOpcode(opcode);
759 break;
760 }
761 } 753 }
762 case wasm::kExprF32Trunc: { 754 case wasm::kExprF32Trunc: {
763 if (m->Float32RoundTruncate().IsSupported()) { 755 if (!m->Float32RoundTruncate().IsSupported()) return BuildF32Trunc(input);
764 op = m->Float32RoundTruncate().op(); 756 op = m->Float32RoundTruncate().op();
765 } else {
766 return BuildF32Trunc(input);
767 }
768 break; 757 break;
769 } 758 }
770 case wasm::kExprF32NearestInt: { 759 case wasm::kExprF32NearestInt: {
771 if (m->Float32RoundTiesEven().IsSupported()) { 760 if (!m->Float32RoundTiesEven().IsSupported())
772 op = m->Float32RoundTiesEven().op(); 761 return BuildF32NearestInt(input);
773 break; 762 op = m->Float32RoundTiesEven().op();
774 } else { 763 break;
775 op = UnsupportedOpcode(opcode);
776 break;
777 }
778 } 764 }
779 case wasm::kExprF64Floor: { 765 case wasm::kExprF64Floor: {
780 if (m->Float64RoundDown().IsSupported()) { 766 if (!m->Float64RoundDown().IsSupported()) return BuildF64Floor(input);
781 op = m->Float64RoundDown().op(); 767 op = m->Float64RoundDown().op();
782 break; 768 break;
783 } else {
784 op = UnsupportedOpcode(opcode);
785 break;
786 }
787 } 769 }
788 case wasm::kExprF64Ceil: { 770 case wasm::kExprF64Ceil: {
789 if (m->Float64RoundUp().IsSupported()) { 771 if (!m->Float64RoundUp().IsSupported()) return BuildF64Ceil(input);
790 op = m->Float64RoundUp().op(); 772 op = m->Float64RoundUp().op();
791 break; 773 break;
792 } else {
793 op = UnsupportedOpcode(opcode);
794 break;
795 }
796 } 774 }
797 case wasm::kExprF64Trunc: { 775 case wasm::kExprF64Trunc: {
798 if (!m->Float64RoundTruncate().IsSupported()) return BuildF64Trunc(input); 776 if (!m->Float64RoundTruncate().IsSupported()) return BuildF64Trunc(input);
799 op = m->Float64RoundTruncate().op(); 777 op = m->Float64RoundTruncate().op();
800 break; 778 break;
801 } 779 }
802 case wasm::kExprF64NearestInt: { 780 case wasm::kExprF64NearestInt: {
803 if (m->Float64RoundTiesEven().IsSupported()) { 781 if (!m->Float64RoundTiesEven().IsSupported())
804 op = m->Float64RoundTiesEven().op(); 782 return BuildF64NearestInt(input);
805 break; 783 op = m->Float64RoundTiesEven().op();
806 } else { 784 break;
807 op = UnsupportedOpcode(opcode);
808 break;
809 }
810 } 785 }
811 786
812 #if WASM_64 787 #if WASM_64
813 // Opcodes only supported on 64-bit platforms. 788 // Opcodes only supported on 64-bit platforms.
814 // TODO(titzer): query the machine operator builder here instead of #ifdef. 789 // TODO(titzer): query the machine operator builder here instead of #ifdef.
815 case wasm::kExprI32ConvertI64: 790 case wasm::kExprI32ConvertI64:
816 op = m->TruncateInt64ToInt32(); 791 op = m->TruncateInt64ToInt32();
817 break; 792 break;
818 case wasm::kExprI64SConvertI32: 793 case wasm::kExprI64SConvertI32:
819 op = m->ChangeInt32ToInt64(); 794 op = m->ChangeInt32ToInt64();
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
1358 result = Binop(wasm::kExprI64Add, 1333 result = Binop(wasm::kExprI64Add,
1359 Binop(wasm::kExprI64And, Binop(wasm::kExprI64ShrU, result, 1334 Binop(wasm::kExprI64And, Binop(wasm::kExprI64ShrU, result,
1360 jsgraph()->Int64Constant(32)), 1335 jsgraph()->Int64Constant(32)),
1361 jsgraph()->Int64Constant(0x00000000ffffffff)), 1336 jsgraph()->Int64Constant(0x00000000ffffffff)),
1362 Binop(wasm::kExprI64And, result, 1337 Binop(wasm::kExprI64And, result,
1363 jsgraph()->Int64Constant(0x00000000ffffffff))); 1338 jsgraph()->Int64Constant(0x00000000ffffffff)));
1364 1339
1365 return result; 1340 return result;
1366 } 1341 }
1367 1342
1343 Node* WasmGraphBuilder::BuildF32Trunc(Node* input) {
1344 MachineType type = MachineType::Float32();
1345 ExternalReference ref =
1346 ExternalReference::f32_trunc_wrapper_function(jsgraph()->isolate());
1347 return BuildRoundingInstruction(input, ref, type);
1348 }
1368 1349
1369 Node* WasmGraphBuilder::BuildF32Trunc(Node* input) { 1350 Node* WasmGraphBuilder::BuildF32Floor(Node* input) {
1370 // int32_t int_input = bitftoi(input); 1351 MachineType type = MachineType::Float32();
1371 // int32_t exponent = int_input & 0x7f800000; 1352 ExternalReference ref =
1372 // if (exponent >= ((23 + 127) << 23)) { 1353 ExternalReference::f32_floor_wrapper_function(jsgraph()->isolate());
1373 // if (input != input) { 1354 return BuildRoundingInstruction(input, ref, type);
1374 // return bititof(int_input | (1 << 22)); 1355 }
1375 // }
1376 // return input;
1377 // }
1378 // int32_t sign = int_input & 0x80000000;
1379 // if (exponent < (127 << 23)) {
1380 // return bititof(sign);
1381 // }
1382 // int32_t mantissa = int_input & 0x007fffff;
1383 // int32_t shift = (127 + 23) - (exponent >> 23);
1384 // int32_t new_mantissa = (mantissa >> shift) << shift;
1385 // int32_t result = new_mantissa | exponent | sign;
1386 // return bititof(result);
1387 1356
1388 Node* int_input = Unop(wasm::kExprI32ReinterpretF32, input); 1357 Node* WasmGraphBuilder::BuildF32Ceil(Node* input) {
1389 Node* exponent = 1358 MachineType type = MachineType::Float32();
1390 Binop(wasm::kExprI32And, int_input, jsgraph()->Int32Constant(0x7f800000)); 1359 ExternalReference ref =
1360 ExternalReference::f32_ceil_wrapper_function(jsgraph()->isolate());
1361 return BuildRoundingInstruction(input, ref, type);
1362 }
1391 1363
1392 Node* sign = 1364 Node* WasmGraphBuilder::BuildF32NearestInt(Node* input) {
1393 Binop(wasm::kExprI32And, int_input, jsgraph()->Int32Constant(0x80000000)); 1365 MachineType type = MachineType::Float32();
1394 1366 ExternalReference ref =
1395 Node* result_out_of_range = int_input; 1367 ExternalReference::f32_nearest_int_wrapper_function(jsgraph()->isolate());
1396 1368 return BuildRoundingInstruction(input, ref, type);
1397 Node* result_nan =
1398 Binop(wasm::kExprI32Ior, int_input, jsgraph()->Int32Constant(1 << 22));
1399
1400 Node* result_zero = sign;
1401
1402 Node* mantissa =
1403 Binop(wasm::kExprI32And, int_input, jsgraph()->Int32Constant(0x007fffff));
1404 Node* shift =
1405 Binop(wasm::kExprI32Sub, jsgraph()->Int32Constant(23 + 127),
1406 Binop(wasm::kExprI32ShrU, exponent, jsgraph()->Int32Constant(23)));
1407 Node* new_mantissa = Binop(wasm::kExprI32Shl,
1408 Binop(wasm::kExprI32ShrU, mantissa, shift), shift);
1409 Node* result_truncate =
1410 Binop(wasm::kExprI32Ior, Binop(wasm::kExprI32Ior, new_mantissa, exponent),
1411 sign);
1412
1413 Diamond is_zero(
1414 graph(), jsgraph()->common(),
1415 Binop(wasm::kExprI32LtU, exponent, jsgraph()->Int32Constant(127 << 23)));
1416
1417 Node* result_within_range =
1418 is_zero.Phi(wasm::kAstI32, result_zero, result_truncate);
1419
1420 Diamond input_nan(graph(), jsgraph()->common(),
1421 Binop(wasm::kExprF32Ne, input, input));
1422 Node* result_exponent_geq_23 =
1423 input_nan.Phi(wasm::kAstI32, result_nan, result_out_of_range);
1424
1425 Diamond exponent_geq_23(graph(), jsgraph()->common(),
1426 Binop(wasm::kExprI32GeU, exponent,
1427 jsgraph()->Int32Constant((23 + 127) << 23)));
1428
1429 Node* result = exponent_geq_23.Phi(wasm::kAstI32, result_exponent_geq_23,
1430 result_within_range);
1431
1432 return Unop(wasm::kExprF32ReinterpretI32, result);
1433 } 1369 }
1434 1370
1435 Node* WasmGraphBuilder::BuildF64Trunc(Node* input) { 1371 Node* WasmGraphBuilder::BuildF64Trunc(Node* input) {
1372 MachineType type = MachineType::Float64();
1373 ExternalReference ref =
1374 ExternalReference::f64_trunc_wrapper_function(jsgraph()->isolate());
1375 return BuildRoundingInstruction(input, ref, type);
1376 }
1377
1378 Node* WasmGraphBuilder::BuildF64Floor(Node* input) {
1379 MachineType type = MachineType::Float64();
1380 ExternalReference ref =
1381 ExternalReference::f64_floor_wrapper_function(jsgraph()->isolate());
1382 return BuildRoundingInstruction(input, ref, type);
1383 }
1384
1385 Node* WasmGraphBuilder::BuildF64Ceil(Node* input) {
1386 MachineType type = MachineType::Float64();
1387 ExternalReference ref =
1388 ExternalReference::f64_ceil_wrapper_function(jsgraph()->isolate());
1389 return BuildRoundingInstruction(input, ref, type);
1390 }
1391
1392 Node* WasmGraphBuilder::BuildF64NearestInt(Node* input) {
1393 MachineType type = MachineType::Float64();
1394 ExternalReference ref =
1395 ExternalReference::f64_nearest_int_wrapper_function(jsgraph()->isolate());
1396 return BuildRoundingInstruction(input, ref, type);
1397 }
1398
1399 Node* WasmGraphBuilder::BuildRoundingInstruction(Node* input,
1400 ExternalReference ref,
1401 MachineType type) {
1436 // We do truncation by calling a C function which calculates the truncation 1402 // We do truncation by calling a C function which calculates the truncation
1437 // for us. The input is passed to the C function as a double* to avoid double 1403 // for us. The input is passed to the C function as a double* to avoid double
1438 // parameters. For this we reserve a slot on the stack, store the parameter in 1404 // parameters. For this we reserve a slot on the stack, store the parameter in
1439 // that slot, pass a pointer to the slot to the C function, and after calling 1405 // that slot, pass a pointer to the slot to the C function, and after calling
1440 // the C function we collect the return value from the stack slot. 1406 // the C function we collect the return value from the stack slot.
1441 1407
1442 Node* stack_slot_param = graph()->NewNode( 1408 Node* stack_slot_param =
1443 jsgraph()->machine()->StackSlot(MachineRepresentation::kFloat64)); 1409 graph()->NewNode(jsgraph()->machine()->StackSlot(type.representation()));
1444 1410
1445 const Operator* store_op = jsgraph()->machine()->Store( 1411 const Operator* store_op = jsgraph()->machine()->Store(
1446 StoreRepresentation(MachineRepresentation::kFloat64, kNoWriteBarrier)); 1412 StoreRepresentation(type.representation(), kNoWriteBarrier));
1447 *effect_ = 1413 *effect_ =
1448 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0), 1414 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0),
1449 input, *effect_, *control_); 1415 input, *effect_, *control_);
1450 1416
1451 Signature<MachineType>::Builder sig_builder(jsgraph()->zone(), 0, 1); 1417 Signature<MachineType>::Builder sig_builder(jsgraph()->zone(), 0, 1);
1452 sig_builder.AddParam(MachineType::Pointer()); 1418 sig_builder.AddParam(MachineType::Pointer());
1453 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant( 1419 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
1454 ExternalReference::trunc64_wrapper_function(jsgraph()->isolate())));
1455 1420
1456 Node* args[] = {function, stack_slot_param}; 1421 Node* args[] = {function, stack_slot_param};
1457 1422
1458 BuildCCall(sig_builder.Build(), args); 1423 BuildCCall(sig_builder.Build(), args);
1459 1424
1460 const Operator* load_op = jsgraph()->machine()->Load(MachineType::Float64()); 1425 const Operator* load_op = jsgraph()->machine()->Load(type);
1461 1426
1462 Node* load = 1427 Node* load =
1463 graph()->NewNode(load_op, stack_slot_param, jsgraph()->Int32Constant(0), 1428 graph()->NewNode(load_op, stack_slot_param, jsgraph()->Int32Constant(0),
1464 *effect_, *control_); 1429 *effect_, *control_);
1465 *effect_ = load; 1430 *effect_ = load;
1466 return load; 1431 return load;
1467 } 1432 }
1468 1433
1469 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { 1434 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) {
1470 const size_t params = sig->parameter_count(); 1435 const size_t params = sig->parameter_count();
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
2165 module_env->module->GetName(function.name_offset)); 2130 module_env->module->GetName(function.name_offset));
2166 } 2131 }
2167 2132
2168 return code; 2133 return code;
2169 } 2134 }
2170 2135
2171 2136
2172 } // namespace compiler 2137 } // namespace compiler
2173 } // namespace internal 2138 } // namespace internal
2174 } // namespace v8 2139 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/snapshot/serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698