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

Side by Side Diff: runtime/vm/intrinsifier_ia32.cc

Issue 8355041: Some performance improvements to make raytracer faster (e.g, support intensified operation in mix... (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 9 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/parser.h » ('j') | runtime/vm/parser.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 // 4 //
5 // The intrinsic code below is executed before a method has built its frame. 5 // The intrinsic code below is executed before a method has built its frame.
6 // The return address is on the stack and the arguments below it. 6 // The return address is on the stack and the arguments below it.
7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved.
8 // Each intrinsification method returns true if the corresponding 8 // Each intrinsification method returns true if the corresponding
9 // Dart method was intrinsified. 9 // Dart method was intrinsified.
10 10
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 V(Double, >=, Double_greaterEqualThan) \ 55 V(Double, >=, Double_greaterEqualThan) \
56 V(Double, <, Double_lessThan) \ 56 V(Double, <, Double_lessThan) \
57 V(Double, <=, Double_lessEqualThan) \ 57 V(Double, <=, Double_lessEqualThan) \
58 V(Double, ==, Double_equal) \ 58 V(Double, ==, Double_equal) \
59 V(Double, +, Double_add) \ 59 V(Double, +, Double_add) \
60 V(Double, -, Double_sub) \ 60 V(Double, -, Double_sub) \
61 V(Double, *, Double_mul) \ 61 V(Double, *, Double_mul) \
62 V(Double, /, Double_div) \ 62 V(Double, /, Double_div) \
63 V(Double, toDouble, Double_toDouble) \ 63 V(Double, toDouble, Double_toDouble) \
64 V(Double, mulFromInteger, Double_mulFromInteger) \ 64 V(Double, mulFromInteger, Double_mulFromInteger) \
65 V(Double, Double.fromInteger, Double_fromInteger) \
65 V(ObjectArray, ObjectArray., ObjectArray_Allocate) \ 66 V(ObjectArray, ObjectArray., ObjectArray_Allocate) \
66 V(ObjectArray, get:length, Array_getLength) \ 67 V(ObjectArray, get:length, Array_getLength) \
67 V(ObjectArray, [], Array_getIndexed) \ 68 V(ObjectArray, [], Array_getIndexed) \
68 V(ObjectArray, []=, Array_setIndexed) \ 69 V(ObjectArray, []=, Array_setIndexed) \
69 V(GrowableObjectArray, get:length, GrowableArray_getLength) \ 70 V(GrowableObjectArray, get:length, GrowableArray_getLength) \
70 V(GrowableObjectArray, [], GrowableArray_getIndexed) \ 71 V(GrowableObjectArray, [], GrowableArray_getIndexed) \
71 V(ImmutableArray, [], Array_getIndexed) \ 72 V(ImmutableArray, [], Array_getIndexed) \
72 V(ImmutableArray, get:length, Array_getLength) \ 73 V(ImmutableArray, get:length, Array_getLength) \
73 V(Math, sqrt, Math_sqrt) \ 74 V(Math, sqrt, Math_sqrt) \
74 V(Object, ==, Object_equal) \ 75 V(Object, ==, Object_equal) \
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 __ testl(EAX, Immediate(kSmiTagMask)); 580 __ testl(EAX, Immediate(kSmiTagMask));
580 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi. 581 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi.
581 __ notl(EAX); 582 __ notl(EAX);
582 __ andl(EAX, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. 583 __ andl(EAX, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
583 __ ret(); 584 __ ret();
584 __ Bind(&fall_through); 585 __ Bind(&fall_through);
585 return false; 586 return false;
586 } 587 }
587 588
588 589
589 // Check if the last argument is a double, otherwise jumps to Label 590 // Check if the last argument is a double, jump to label is_smi if smi
590 // 'not_double'. Returns the last argument in EAX. 591 // (easy to convert to double), otherwise jump to label 'not_double_smi',
591 static void TestLastArgumentsIsDouble(Assembler* assembler, Label* not_double) { 592 // Returns the last argument in EAX.
593 static void TestLastArgumentIsDouble(Assembler* assembler,
594 Label* is_smi,
595 Label* not_double_smi) {
592 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 596 __ movl(EAX, Address(ESP, + 1 * kWordSize));
593 __ testl(EAX, Immediate(kSmiTagMask)); 597 __ testl(EAX, Immediate(kSmiTagMask));
594 __ j(ZERO, not_double, Assembler::kNearJump); // Jump if Smi. 598 __ j(ZERO, is_smi, Assembler::kNearJump); // Jump if Smi.
595 __ LoadObject(EBX, Class::ZoneHandle( 599 __ LoadObject(EBX, Class::ZoneHandle(
596 Isolate::Current()->object_store()->double_class())); 600 Isolate::Current()->object_store()->double_class()));
597 __ cmpl(EBX, FieldAddress(EAX, Object::class_offset())); 601 __ cmpl(EBX, FieldAddress(EAX, Object::class_offset()));
598 __ j(NOT_EQUAL, not_double, Assembler::kNearJump); // Jump if not double. 602 __ j(NOT_EQUAL, not_double_smi, Assembler::kNearJump); // Jump if not double.
599 // Fall through if double. 603 // Fall through if double.
600 } 604 }
601 605
602 606
603 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown 607 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown
604 // type. Return true or false object in the register EAX. Any NaN argument 608 // type. Return true or false object in the register EAX. Any NaN argument
605 // returns false. Any non-double arg1 causes control flow to fall through to the 609 // returns false. Any non-double arg1 causes control flow to fall through to the
606 // slow case (compiled method body). 610 // slow case (compiled method body).
607 static bool CompareDoubles(Assembler* assembler, Condition true_condition) { 611 static bool CompareDoubles(Assembler* assembler, Condition true_condition) {
608 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 612 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
609 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 613 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
610 Label fall_through, is_false, is_true; 614 Label fall_through, is_false, is_true, is_smi, double_op;
611 TestLastArgumentsIsDouble(assembler, &fall_through); 615 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
612 // Both arguments are double, right operand is in EAX. 616 // Both arguments are double, right operand is in EAX.
613 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); 617 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
618 __ Bind(&double_op);
614 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left argument. 619 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left argument.
615 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); 620 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
616 __ comisd(XMM0, XMM1); 621 __ comisd(XMM0, XMM1);
617 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false; 622 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false;
618 __ j(true_condition, &is_true, Assembler::kNearJump); 623 __ j(true_condition, &is_true, Assembler::kNearJump);
619 // Fall through false. 624 // Fall through false.
620 __ Bind(&is_false); 625 __ Bind(&is_false);
621 __ LoadObject(EAX, bool_false); 626 __ LoadObject(EAX, bool_false);
622 __ ret(); 627 __ ret();
623 __ Bind(&is_true); 628 __ Bind(&is_true);
624 __ LoadObject(EAX, bool_true); 629 __ LoadObject(EAX, bool_true);
625 __ ret(); 630 __ ret();
631 __ Bind(&is_smi);
632 __ SmiUntag(EAX);
633 __ cvtsi2sd(XMM1, EAX);
634 __ jmp(&double_op);
626 __ Bind(&fall_through); 635 __ Bind(&fall_through);
627 return false; 636 return false;
628 } 637 }
629 638
630 639
631 // arg0 is Double, arg1 is unknown. 640 // arg0 is Double, arg1 is unknown.
632 static bool Double_greaterThan(Assembler* assembler) { 641 static bool Double_greaterThan(Assembler* assembler) {
633 return CompareDoubles(assembler, ABOVE); 642 return CompareDoubles(assembler, ABOVE);
634 } 643 }
635 644
(...skipping 26 matching lines...) Expand all
662 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 671 __ movl(EAX, Address(ESP, + 1 * kWordSize));
663 __ ret(); 672 __ ret();
664 return true; 673 return true;
665 } 674 }
666 675
667 676
668 // Expects EAX to contain right argument, left argument is on stack. Left 677 // Expects EAX to contain right argument, left argument is on stack. Left
669 // argument is double, right argument is of unknown type. 678 // argument is double, right argument is of unknown type.
670 static bool DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { 679 static bool DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
671 Label fall_through; 680 Label fall_through;
672 TestLastArgumentsIsDouble(assembler, &fall_through); 681 TestLastArgumentIsDouble(assembler, &fall_through, &fall_through);
673 // Both arguments are double, right operand is in EAX, class in EBX. 682 // Both arguments are double, right operand is in EAX, class in EBX.
674 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); 683 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
675 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left argument. 684 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left argument.
676 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); 685 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
677 switch (kind) { 686 switch (kind) {
678 case Token::kADD: __ addsd(XMM0, XMM1); break; 687 case Token::kADD: __ addsd(XMM0, XMM1); break;
679 case Token::kSUB: __ subsd(XMM0, XMM1); break; 688 case Token::kSUB: __ subsd(XMM0, XMM1); break;
680 case Token::kMUL: __ mulsd(XMM0, XMM1); break; 689 case Token::kMUL: __ mulsd(XMM0, XMM1); break;
681 case Token::kDIV: __ divsd(XMM0, XMM1); break; 690 case Token::kDIV: __ divsd(XMM0, XMM1); break;
682 default: UNREACHABLE(); 691 default: UNREACHABLE();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 EBX, // Class register. 745 EBX, // Class register.
737 &fall_through, 746 &fall_through,
738 EAX); // Result register. 747 EAX); // Result register.
739 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); 748 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
740 __ ret(); 749 __ ret();
741 __ Bind(&fall_through); 750 __ Bind(&fall_through);
742 return false; 751 return false;
743 } 752 }
744 753
745 754
755 static bool Double_fromInteger(Assembler* assembler) {
756 Label fall_through;
757 __ movl(EAX, Address(ESP, +1 * kWordSize));
758 __ testl(EAX, Immediate(kSmiTagMask));
759 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
760 // Is Smi.
761 __ SmiUntag(EAX);
762 __ cvtsi2sd(XMM0, EAX);
763 const Class& double_class = Class::ZoneHandle(
764 Isolate::Current()->object_store()->double_class());
765 __ LoadObject(EBX, double_class);
766 AssemblerMacros::TryAllocate(assembler,
767 double_class,
768 EBX, // Class register.
769 &fall_through,
770 EAX); // Result register.
771 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
772 __ ret();
773 __ Bind(&fall_through);
774 return false;
775 }
776
777
746 // Argument type is not known 778 // Argument type is not known
747 static bool Math_sqrt(Assembler* assembler) { 779 static bool Math_sqrt(Assembler* assembler) {
748 Label fall_through; 780 Label fall_through, is_smi, double_op;
749 TestLastArgumentsIsDouble(assembler, &fall_through); 781 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
750 // Argument is double and is in EAX, class in EBX. 782 // Argument is double and is in EAX, class in EBX.
751 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); 783 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
784 __ Bind(&double_op);
752 __ sqrtsd(XMM0, XMM1); 785 __ sqrtsd(XMM0, XMM1);
753 const Class& double_class = Class::ZoneHandle( 786 const Class& double_class = Class::ZoneHandle(
754 Isolate::Current()->object_store()->double_class()); 787 Isolate::Current()->object_store()->double_class());
755 AssemblerMacros::TryAllocate(assembler, 788 AssemblerMacros::TryAllocate(assembler,
756 double_class, 789 double_class,
757 EBX, // Class register. 790 EBX, // Class register.
758 &fall_through, 791 &fall_through,
759 EAX); // Result register. 792 EAX); // Result register.
760 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); 793 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
761 __ ret(); 794 __ ret();
795 __ Bind(&is_smi);
796 __ SmiUntag(EAX);
797 __ cvtsi2sd(XMM1, EAX);
798 __ jmp(&double_op);
762 __ Bind(&fall_through); 799 __ Bind(&fall_through);
763 return false; 800 return false;
764 } 801 }
765 802
766 803
767 // Identity comparison. 804 // Identity comparison.
768 static bool Object_equal(Assembler* assembler) { 805 static bool Object_equal(Assembler* assembler) {
769 Label is_true; 806 Label is_true;
770 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 807 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
771 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 808 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 } \ 912 } \
876 913
877 INTRINSIC_LIST(FIND_INTRINSICS); 914 INTRINSIC_LIST(FIND_INTRINSICS);
878 #undef FIND_INTRINSICS 915 #undef FIND_INTRINSICS
879 return false; 916 return false;
880 } 917 }
881 918
882 } // namespace dart 919 } // namespace dart
883 920
884 #endif // defined TARGET_ARCH_IA32 921 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/parser.h » ('j') | runtime/vm/parser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698