| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 // Class for intrinsifying functions. | 4 // Class for intrinsifying functions. |
| 5 | 5 |
| 6 #include "vm/assembler.h" | 6 #include "vm/assembler.h" |
| 7 #include "vm/compiler.h" | 7 #include "vm/compiler.h" |
| 8 #include "vm/cpu.h" | 8 #include "vm/cpu.h" |
| 9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
| 10 #include "vm/flow_graph.h" | 10 #include "vm/flow_graph.h" |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 } | 258 } |
| 259 | 259 |
| 260 | 260 |
| 261 #if !defined(TARGET_ARCH_DBC) | 261 #if !defined(TARGET_ARCH_DBC) |
| 262 static intptr_t CidForRepresentation(Representation rep) { | 262 static intptr_t CidForRepresentation(Representation rep) { |
| 263 switch (rep) { | 263 switch (rep) { |
| 264 case kUnboxedDouble: | 264 case kUnboxedDouble: |
| 265 return kDoubleCid; | 265 return kDoubleCid; |
| 266 case kUnboxedFloat32x4: | 266 case kUnboxedFloat32x4: |
| 267 return kFloat32x4Cid; | 267 return kFloat32x4Cid; |
| 268 case kUnboxedInt32x4: |
| 269 return kInt32x4Cid; |
| 270 case kUnboxedFloat64x2: |
| 271 return kFloat64x2Cid; |
| 268 case kUnboxedUint32: | 272 case kUnboxedUint32: |
| 269 return kDynamicCid; // smi or mint. | 273 return kDynamicCid; // smi or mint. |
| 270 default: | 274 default: |
| 271 UNREACHABLE(); | 275 UNREACHABLE(); |
| 272 return kIllegalCid; | 276 return kIllegalCid; |
| 273 } | 277 } |
| 274 } | 278 } |
| 275 | 279 |
| 276 | 280 |
| 277 // Notes about the graph intrinsics: | 281 // Notes about the graph intrinsics: |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 BoxInstr::Create(kUnboxedUint32, new Value(result))); | 432 BoxInstr::Create(kUnboxedUint32, new Value(result))); |
| 429 break; | 433 break; |
| 430 case kTypedDataFloat32ArrayCid: | 434 case kTypedDataFloat32ArrayCid: |
| 431 result = builder.AddDefinition( | 435 result = builder.AddDefinition( |
| 432 new FloatToDoubleInstr(new Value(result), Thread::kNoDeoptId)); | 436 new FloatToDoubleInstr(new Value(result), Thread::kNoDeoptId)); |
| 433 // Fall through. | 437 // Fall through. |
| 434 case kTypedDataFloat64ArrayCid: | 438 case kTypedDataFloat64ArrayCid: |
| 435 result = builder.AddDefinition( | 439 result = builder.AddDefinition( |
| 436 BoxInstr::Create(kUnboxedDouble, new Value(result))); | 440 BoxInstr::Create(kUnboxedDouble, new Value(result))); |
| 437 break; | 441 break; |
| 442 case kTypedDataFloat32x4ArrayCid: |
| 443 result = builder.AddDefinition( |
| 444 BoxInstr::Create(kUnboxedFloat32x4, new Value(result))); |
| 445 break; |
| 446 case kTypedDataInt32x4ArrayCid: |
| 447 result = builder.AddDefinition( |
| 448 BoxInstr::Create(kUnboxedInt32x4, new Value(result))); |
| 449 break; |
| 450 case kTypedDataFloat64x2ArrayCid: |
| 451 result = builder.AddDefinition( |
| 452 BoxInstr::Create(kUnboxedFloat64x2, new Value(result))); |
| 453 break; |
| 438 case kArrayCid: | 454 case kArrayCid: |
| 439 case kImmutableArrayCid: | 455 case kImmutableArrayCid: |
| 440 case kTypedDataInt8ArrayCid: | 456 case kTypedDataInt8ArrayCid: |
| 441 case kTypedDataUint8ArrayCid: | 457 case kTypedDataUint8ArrayCid: |
| 442 case kExternalTypedDataUint8ArrayCid: | 458 case kExternalTypedDataUint8ArrayCid: |
| 443 case kTypedDataUint8ClampedArrayCid: | 459 case kTypedDataUint8ClampedArrayCid: |
| 444 case kExternalTypedDataUint8ClampedArrayCid: | 460 case kExternalTypedDataUint8ClampedArrayCid: |
| 445 case kTypedDataInt16ArrayCid: | 461 case kTypedDataInt16ArrayCid: |
| 446 case kTypedDataUint16ArrayCid: | 462 case kTypedDataUint16ArrayCid: |
| 447 // Nothing to do. | 463 // Nothing to do. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 // Use same truncating unbox-instruction for int32 and uint32. | 508 // Use same truncating unbox-instruction for int32 and uint32. |
| 493 // Fall-through. | 509 // Fall-through. |
| 494 case kTypedDataUint32ArrayCid: | 510 case kTypedDataUint32ArrayCid: |
| 495 case kExternalTypedDataUint32ArrayCid: | 511 case kExternalTypedDataUint32ArrayCid: |
| 496 // Supports smi and mint, slow-case for bigints. | 512 // Supports smi and mint, slow-case for bigints. |
| 497 value = builder.AddUnboxInstr(kUnboxedUint32, | 513 value = builder.AddUnboxInstr(kUnboxedUint32, |
| 498 new Value(value), | 514 new Value(value), |
| 499 /* is_checked = */ false); | 515 /* is_checked = */ false); |
| 500 break; | 516 break; |
| 501 case kTypedDataFloat32ArrayCid: | 517 case kTypedDataFloat32ArrayCid: |
| 502 case kTypedDataFloat64ArrayCid: { | 518 case kTypedDataFloat64ArrayCid: |
| 519 case kTypedDataFloat32x4ArrayCid: |
| 520 case kTypedDataInt32x4ArrayCid: |
| 521 case kTypedDataFloat64x2ArrayCid: { |
| 522 intptr_t value_check_cid = kDoubleCid; |
| 523 Representation rep = kUnboxedDouble; |
| 524 switch (array_cid) { |
| 525 case kTypedDataFloat32x4ArrayCid: |
| 526 value_check_cid = kFloat32x4Cid; |
| 527 rep = kUnboxedFloat32x4; |
| 528 break; |
| 529 case kTypedDataInt32x4ArrayCid: |
| 530 value_check_cid = kInt32x4Cid; |
| 531 rep = kUnboxedInt32x4; |
| 532 break; |
| 533 case kTypedDataFloat64x2ArrayCid: |
| 534 value_check_cid = kFloat64x2Cid; |
| 535 rep = kUnboxedFloat64x2; |
| 536 break; |
| 537 default: |
| 538 // Float32/Float64 case already handled. |
| 539 break; |
| 540 } |
| 503 const ICData& value_check = ICData::ZoneHandle(ICData::New( | 541 const ICData& value_check = ICData::ZoneHandle(ICData::New( |
| 504 flow_graph->function(), | 542 flow_graph->function(), |
| 505 Symbols::Empty(), // Dummy function name. | 543 Symbols::Empty(), // Dummy function name. |
| 506 Object::empty_array(), // Dummy args. descr. | 544 Object::empty_array(), // Dummy args. descr. |
| 507 Thread::kNoDeoptId, | 545 Thread::kNoDeoptId, |
| 508 1, | 546 1, |
| 509 false)); | 547 false)); |
| 510 value_check.AddReceiverCheck(kDoubleCid, flow_graph->function()); | 548 value_check.AddReceiverCheck(value_check_cid, flow_graph->function()); |
| 511 builder.AddInstruction( | 549 builder.AddInstruction( |
| 512 new CheckClassInstr(new Value(value), | 550 new CheckClassInstr(new Value(value), |
| 513 Thread::kNoDeoptId, | 551 Thread::kNoDeoptId, |
| 514 value_check, | 552 value_check, |
| 515 builder.TokenPos())); | 553 builder.TokenPos())); |
| 516 value = builder.AddUnboxInstr(kUnboxedDouble, | 554 value = builder.AddUnboxInstr(rep, |
| 517 new Value(value), | 555 new Value(value), |
| 518 /* is_checked = */ true); | 556 /* is_checked = */ true); |
| 519 if (array_cid == kTypedDataFloat32ArrayCid) { | 557 if (array_cid == kTypedDataFloat32ArrayCid) { |
| 520 value = builder.AddDefinition( | 558 value = builder.AddDefinition( |
| 521 new DoubleToFloatInstr(new Value(value), Thread::kNoDeoptId)); | 559 new DoubleToFloatInstr(new Value(value), Thread::kNoDeoptId)); |
| 522 } | 560 } |
| 523 break; | 561 break; |
| 524 } | 562 } |
| 525 default: | 563 default: |
| 526 UNREACHABLE(); | 564 UNREACHABLE(); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC(enum_name) | 655 DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC(enum_name) |
| 618 | 656 |
| 619 DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(Float64Array) | 657 DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(Float64Array) |
| 620 DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(Float32Array) | 658 DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS(Float32Array) |
| 621 | 659 |
| 622 #undef DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS | 660 #undef DEFINE_FLOAT_ARRAY_GETTER_SETTER_INTRINSICS |
| 623 #undef DEFINE_FLOAT_ARRAY_GETTER_INTRINSIC | 661 #undef DEFINE_FLOAT_ARRAY_GETTER_INTRINSIC |
| 624 #undef DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC | 662 #undef DEFINE_FLOAT_ARRAY_SETTER_INTRINSIC |
| 625 | 663 |
| 626 | 664 |
| 665 #define DEFINE_SIMD_ARRAY_GETTER_INTRINSIC(enum_name) \ |
| 666 bool Intrinsifier::Build_##enum_name##GetIndexed(FlowGraph* flow_graph) { \ |
| 667 if (!FlowGraphCompiler::SupportsUnboxedSimd128()) { \ |
| 668 return false; \ |
| 669 } \ |
| 670 return IntrinsifyArrayGetIndexed( \ |
| 671 flow_graph, \ |
| 672 MethodRecognizer::MethodKindToReceiverCid( \ |
| 673 MethodRecognizer::k##enum_name##GetIndexed)); \ |
| 674 } |
| 675 |
| 676 |
| 677 #define DEFINE_SIMD_ARRAY_SETTER_INTRINSIC(enum_name) \ |
| 678 bool Intrinsifier::Build_##enum_name##SetIndexed(FlowGraph* flow_graph) { \ |
| 679 if (!FlowGraphCompiler::SupportsUnboxedSimd128()) { \ |
| 680 return false; \ |
| 681 } \ |
| 682 return IntrinsifyArraySetIndexed( \ |
| 683 flow_graph, \ |
| 684 MethodRecognizer::MethodKindToReceiverCid( \ |
| 685 MethodRecognizer::k##enum_name##SetIndexed)); \ |
| 686 } |
| 687 |
| 688 #define DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(enum_name) \ |
| 689 DEFINE_SIMD_ARRAY_GETTER_INTRINSIC(enum_name) \ |
| 690 DEFINE_SIMD_ARRAY_SETTER_INTRINSIC(enum_name) |
| 691 |
| 692 DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(Float32x4Array) |
| 693 DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(Int32x4Array) |
| 694 DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS(Float64x2Array) |
| 695 |
| 696 #undef DEFINE_SIMD_ARRAY_GETTER_SETTER_INTRINSICS |
| 697 #undef DEFINE_SIMD_ARRAY_GETTER_INTRINSIC |
| 698 #undef DEFINE_SIMD_ARRAY_SETTER_INTRINSIC |
| 699 |
| 700 |
| 627 static bool BuildCodeUnitAt(FlowGraph* flow_graph, intptr_t cid) { | 701 static bool BuildCodeUnitAt(FlowGraph* flow_graph, intptr_t cid) { |
| 628 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 702 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
| 629 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 703 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
| 630 BlockBuilder builder(flow_graph, normal_entry); | 704 BlockBuilder builder(flow_graph, normal_entry); |
| 631 | 705 |
| 632 Definition* index = builder.AddParameter(1); | 706 Definition* index = builder.AddParameter(1); |
| 633 Definition* str = builder.AddParameter(2); | 707 Definition* str = builder.AddParameter(2); |
| 634 PrepareIndexedOp(&builder, str, index, String::length_offset()); | 708 PrepareIndexedOp(&builder, str, index, String::length_offset()); |
| 635 | 709 |
| 636 // For external strings: Load external data. | 710 // For external strings: Load external data. |
| (...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 1267 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
| 1194 BlockBuilder builder(flow_graph, normal_entry); | 1268 BlockBuilder builder(flow_graph, normal_entry); |
| 1195 | 1269 |
| 1196 return BuildInvokeMathCFunction(&builder, | 1270 return BuildInvokeMathCFunction(&builder, |
| 1197 MethodRecognizer::kDoubleRound); | 1271 MethodRecognizer::kDoubleRound); |
| 1198 } | 1272 } |
| 1199 #endif // !defined(TARGET_ARCH_DBC) | 1273 #endif // !defined(TARGET_ARCH_DBC) |
| 1200 | 1274 |
| 1201 | 1275 |
| 1202 } // namespace dart | 1276 } // namespace dart |
| OLD | NEW |