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 |