Chromium Code Reviews| 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/intrinsifier.h" | 7 #include "vm/intrinsifier.h" |
| 8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/object.h" | 9 #include "vm/object.h" |
| 10 #include "vm/symbols.h" | 10 #include "vm/symbols.h" |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 494 kTypedDataFloat64ArrayCid, | 494 kTypedDataFloat64ArrayCid, |
| 495 Isolate::kNoDeoptId, | 495 Isolate::kNoDeoptId, |
| 496 builder.TokenPos())); | 496 builder.TokenPos())); |
| 497 Definition* result = builder.AddDefinition( | 497 Definition* result = builder.AddDefinition( |
| 498 BoxInstr::Create(kUnboxedDouble, new Value(unboxed_value))); | 498 BoxInstr::Create(kUnboxedDouble, new Value(unboxed_value))); |
| 499 builder.AddIntrinsicReturn(new Value(result)); | 499 builder.AddIntrinsicReturn(new Value(result)); |
| 500 return true; | 500 return true; |
| 501 } | 501 } |
| 502 | 502 |
| 503 | 503 |
| 504 static bool BuildBinaryFloat32x4Op(FlowGraph* flow_graph, Token::Kind kind) { | |
| 505 if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false; | |
| 506 | |
| 507 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | |
| 508 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | |
| 509 BlockBuilder builder(flow_graph, normal_entry); | |
| 510 | |
| 511 Definition* right = builder.AddParameter(1); | |
| 512 Definition* left = builder.AddParameter(2); | |
| 513 | |
| 514 const ICData& value_check = ICData::ZoneHandle(ICData::New( | |
| 515 flow_graph->function(), | |
| 516 String::Handle(flow_graph->function().name()), | |
| 517 Object::empty_array(), // Dummy args. descr. | |
| 518 Isolate::kNoDeoptId, | |
| 519 1)); | |
| 520 value_check.AddReceiverCheck(kFloat32x4Cid, flow_graph->function()); | |
| 521 // Check argument. Receiver (left) is known to be a Float32x4. | |
| 522 builder.AddInstruction( | |
| 523 new CheckClassInstr(new Value(right), | |
| 524 Isolate::kNoDeoptId, | |
| 525 value_check, | |
| 526 builder.TokenPos())); | |
| 527 Definition* left_simd = builder.AddDefinition( | |
| 528 UnboxInstr::Create(kUnboxedFloat32x4, | |
| 529 new Value(left), | |
|
Cutch
2015/09/22 15:48:05
What about creating a helper:
Definition* Unbox(R
Florian Schneider
2015/09/22 16:13:38
Done.
| |
| 530 Isolate::kNoDeoptId)); | |
| 531 // Manually adjust reaching type because there is no type propagation | |
| 532 // when building intrinsics. | |
| 533 left_simd->AsUnbox()->value()->SetReachingType( | |
| 534 ZoneCompileType::Wrap(CompileType::FromCid(kFloat32x4Cid))); | |
| 535 | |
| 536 Definition* right_simd = builder.AddDefinition( | |
| 537 UnboxInstr::Create(kUnboxedFloat32x4, | |
| 538 new Value(right), | |
| 539 Isolate::kNoDeoptId)); | |
| 540 // Manually adjust reaching type because there is no type propagation | |
| 541 // when building intrinsics. | |
| 542 right_simd->AsUnbox()->value()->SetReachingType( | |
| 543 ZoneCompileType::Wrap(CompileType::FromCid(kFloat32x4Cid))); | |
| 544 Definition* unboxed_result = builder.AddDefinition( | |
| 545 new BinaryFloat32x4OpInstr(kind, | |
| 546 new Value(left_simd), | |
| 547 new Value(right_simd), | |
| 548 Isolate::kNoDeoptId)); | |
| 549 Definition* result = builder.AddDefinition( | |
| 550 BoxInstr::Create(kUnboxedFloat32x4, new Value(unboxed_result))); | |
| 551 builder.AddIntrinsicReturn(new Value(result)); | |
| 552 return true; | |
| 553 } | |
| 554 | |
| 555 | |
| 556 bool Intrinsifier::Build_Float32x4Mul(FlowGraph* flow_graph) { | |
| 557 return BuildBinaryFloat32x4Op(flow_graph, Token::kMUL); | |
| 558 } | |
| 559 | |
| 560 | |
| 561 bool Intrinsifier::Build_Float32x4Sub(FlowGraph* flow_graph) { | |
| 562 return BuildBinaryFloat32x4Op(flow_graph, Token::kSUB); | |
| 563 } | |
| 564 | |
| 565 | |
| 566 bool Intrinsifier::Build_Float32x4Add(FlowGraph* flow_graph) { | |
| 567 return BuildBinaryFloat32x4Op(flow_graph, Token::kADD); | |
| 568 } | |
| 569 | |
| 570 | |
| 571 static bool BuildFloat32x4Shuffle(FlowGraph* flow_graph, | |
| 572 MethodRecognizer::Kind kind) { | |
| 573 if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false; | |
| 574 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | |
| 575 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | |
| 576 BlockBuilder builder(flow_graph, normal_entry); | |
| 577 | |
| 578 Definition* receiver = builder.AddParameter(1); | |
| 579 | |
| 580 Definition* unboxed_receiver = builder.AddDefinition( | |
| 581 UnboxInstr::Create(kUnboxedFloat32x4, | |
| 582 new Value(receiver), | |
| 583 Isolate::kNoDeoptId)); | |
| 584 // Manually adjust reaching type because there is no type propagation | |
| 585 // when building intrinsics. | |
| 586 unboxed_receiver->AsUnbox()->value()->SetReachingType( | |
| 587 ZoneCompileType::Wrap(CompileType::FromCid(kFloat32x4Cid))); | |
|
Cutch
2015/09/22 15:48:05
Use helper here too
Florian Schneider
2015/09/22 16:13:38
Done.
| |
| 588 | |
| 589 Definition* unboxed_result = builder.AddDefinition( | |
| 590 new Simd32x4ShuffleInstr(kind, | |
| 591 new Value(unboxed_receiver), | |
| 592 0, | |
| 593 Isolate::kNoDeoptId)); | |
| 594 | |
| 595 Definition* result = builder.AddDefinition( | |
| 596 BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result))); | |
| 597 builder.AddIntrinsicReturn(new Value(result)); | |
| 598 return true; | |
| 599 } | |
| 600 | |
| 601 | |
| 602 bool Intrinsifier::Build_Float32x4ShuffleX(FlowGraph* flow_graph) { | |
| 603 return BuildFloat32x4Shuffle(flow_graph, | |
| 604 MethodRecognizer::kFloat32x4ShuffleX); | |
| 605 } | |
| 606 | |
| 607 | |
| 608 bool Intrinsifier::Build_Float32x4ShuffleY(FlowGraph* flow_graph) { | |
| 609 return BuildFloat32x4Shuffle(flow_graph, | |
| 610 MethodRecognizer::kFloat32x4ShuffleY); | |
| 611 } | |
| 612 | |
| 613 | |
| 614 bool Intrinsifier::Build_Float32x4ShuffleZ(FlowGraph* flow_graph) { | |
| 615 return BuildFloat32x4Shuffle(flow_graph, | |
| 616 MethodRecognizer::kFloat32x4ShuffleZ); | |
| 617 } | |
| 618 | |
| 619 | |
| 620 bool Intrinsifier::Build_Float32x4ShuffleW(FlowGraph* flow_graph) { | |
| 621 return BuildFloat32x4Shuffle(flow_graph, | |
| 622 MethodRecognizer::kFloat32x4ShuffleW); | |
| 623 } | |
| 624 | |
| 625 | |
| 504 static bool BuildLoadField(FlowGraph* flow_graph, intptr_t offset) { | 626 static bool BuildLoadField(FlowGraph* flow_graph, intptr_t offset) { |
| 505 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 627 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
| 506 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 628 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
| 507 BlockBuilder builder(flow_graph, normal_entry); | 629 BlockBuilder builder(flow_graph, normal_entry); |
| 508 | 630 |
| 509 Definition* array = builder.AddParameter(1); | 631 Definition* array = builder.AddParameter(1); |
| 510 | 632 |
| 511 Definition* length = builder.AddDefinition( | 633 Definition* length = builder.AddDefinition( |
| 512 new LoadFieldInstr(new Value(array), | 634 new LoadFieldInstr(new Value(array), |
| 513 offset, | 635 offset, |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 682 new Value(growable_array), | 804 new Value(growable_array), |
| 683 new Value(length), | 805 new Value(length), |
| 684 kNoStoreBarrier, | 806 kNoStoreBarrier, |
| 685 builder.TokenPos())); | 807 builder.TokenPos())); |
| 686 Definition* null_def = builder.AddNullDefinition(); | 808 Definition* null_def = builder.AddNullDefinition(); |
| 687 builder.AddIntrinsicReturn(new Value(null_def)); | 809 builder.AddIntrinsicReturn(new Value(null_def)); |
| 688 return true; | 810 return true; |
| 689 } | 811 } |
| 690 | 812 |
| 691 } // namespace dart | 813 } // namespace dart |
| OLD | NEW |