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

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

Issue 10704192: Implement the remaining methods in intrinsifier_x64.cc (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 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/intrinsifier_x64.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 (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 // 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 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 bool Intrinsifier::Integer_lessEqualThan(Assembler* assembler) { 797 bool Intrinsifier::Integer_lessEqualThan(Assembler* assembler) {
798 return CompareIntegers(assembler, LESS_EQUAL); 798 return CompareIntegers(assembler, LESS_EQUAL);
799 } 799 }
800 800
801 801
802 bool Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) { 802 bool Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
803 return CompareIntegers(assembler, GREATER_EQUAL); 803 return CompareIntegers(assembler, GREATER_EQUAL);
804 } 804 }
805 805
806 806
807 // This is called for Smi, Mint and Bigint receivers. Bigints are not handled. 807 // This is called for Smi, Mint and Bigint receivers. The right argument
808 // can be Smi, Mint, Bigint or double.
808 bool Intrinsifier::Integer_equalToInteger(Assembler* assembler) { 809 bool Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
809 Label fall_through, true_label, check_for_mint; 810 Label fall_through, true_label, check_for_mint;
810 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 811 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
811 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 812 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
812 // For integer receiver '===' check first. 813 // For integer receiver '===' check first.
813 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 814 __ movl(EAX, Address(ESP, + 1 * kWordSize));
814 __ cmpl(EAX, Address(ESP, + 2 * kWordSize)); 815 __ cmpl(EAX, Address(ESP, + 2 * kWordSize));
815 __ j(EQUAL, &true_label, Assembler::kNearJump); 816 __ j(EQUAL, &true_label, Assembler::kNearJump);
816 __ movl(EBX, Address(ESP, + 2 * kWordSize)); 817 __ movl(EBX, Address(ESP, + 2 * kWordSize));
817 __ orl(EAX, EBX); 818 __ orl(EAX, EBX);
818 __ testl(EAX, Immediate(kSmiTagMask)); 819 __ testl(EAX, Immediate(kSmiTagMask));
819 __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump); 820 __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump);
820 // Both arguments are smi, '===' is good enough. 821 // Both arguments are smi, '===' is good enough.
821 __ LoadObject(EAX, bool_false); 822 __ LoadObject(EAX, bool_false);
822 __ ret(); 823 __ ret();
823 __ Bind(&true_label); 824 __ Bind(&true_label);
824 __ LoadObject(EAX, bool_true); 825 __ LoadObject(EAX, bool_true);
825 __ ret(); 826 __ ret();
826 827
827 // At least one of the arguments was not Smi, inline code for Smi/Mint 828 // At least one of the arguments was not Smi.
828 // equality comparison.
829 Label receiver_not_smi; 829 Label receiver_not_smi;
830 __ Bind(&check_for_mint); 830 __ Bind(&check_for_mint);
831 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Receiver. 831 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Receiver.
832 __ testl(EAX, Immediate(kSmiTagMask)); 832 __ testl(EAX, Immediate(kSmiTagMask));
833 __ j(NOT_ZERO, &receiver_not_smi); 833 __ j(NOT_ZERO, &receiver_not_smi);
834 834
835 // Note that an instance of Mint never contains a value that can be 835 // Left (receiver) is Smi, return false if right is not Double.
836 // Note that an instance of Mint or Bigint never contains a value that can be
836 // represented by Smi. 837 // represented by Smi.
837 // Left is Smi, return false if right is Mint, otherwise fall through.
838 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Right argument. 838 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Right argument.
839 __ CompareClassId(EAX, kMint, EDI); 839 __ CompareClassId(EAX, kDouble, EDI);
840 __ j(NOT_EQUAL, &fall_through); 840 __ j(EQUAL, &fall_through);
841 __ LoadObject(EAX, bool_false); // Smi == Mint -> false. 841 __ LoadObject(EAX, bool_false); // Smi == Mint -> false.
842 __ ret(); 842 __ ret();
843 843
844 __ Bind(&receiver_not_smi); 844 __ Bind(&receiver_not_smi);
845 // EAX:: receiver. 845 // EAX:: receiver.
846 __ CompareClassId(EAX, kMint, EDI); 846 __ CompareClassId(EAX, kMint, EDI);
847 __ j(NOT_EQUAL, &fall_through); 847 __ j(NOT_EQUAL, &fall_through);
848 // Receiver is Mint, return false if right is Smi. 848 // Receiver is Mint, return false if right is Smi.
849 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Right argument. 849 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Right argument.
850 __ testl(EAX, Immediate(kSmiTagMask)); 850 __ testl(EAX, Immediate(kSmiTagMask));
851 __ j(NOT_ZERO, &fall_through); 851 __ j(NOT_ZERO, &fall_through);
852 __ LoadObject(EAX, bool_false); // Smi == Mint -> false. 852 __ LoadObject(EAX, bool_false);
853 __ ret(); 853 __ ret();
854 // TODO(srdjan): Implement Mint == Mint comparison. 854 // TODO(srdjan): Implement Mint == Mint comparison.
855 855
856 __ Bind(&fall_through); 856 __ Bind(&fall_through);
857 return false; 857 return false;
858 } 858 }
859 859
860 860
861 bool Intrinsifier::Integer_equal(Assembler* assembler) { 861 bool Intrinsifier::Integer_equal(Assembler* assembler) {
862 return Integer_equalToInteger(assembler); 862 return Integer_equalToInteger(assembler);
(...skipping 20 matching lines...) Expand all
883 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Value. 883 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Value.
884 __ SmiUntag(EAX); // Value. 884 __ SmiUntag(EAX); // Value.
885 __ sarl(EAX, ECX); 885 __ sarl(EAX, ECX);
886 __ SmiTag(EAX); 886 __ SmiTag(EAX);
887 __ ret(); 887 __ ret();
888 __ Bind(&fall_through); 888 __ Bind(&fall_through);
889 return false; 889 return false;
890 } 890 }
891 891
892 892
893 // Argument is Smi (receiver).
893 bool Intrinsifier::Smi_bitNegate(Assembler* assembler) { 894 bool Intrinsifier::Smi_bitNegate(Assembler* assembler) {
894 Label fall_through;
895 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Index. 895 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Index.
896 __ testl(EAX, Immediate(kSmiTagMask));
897 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi.
898 __ notl(EAX); 896 __ notl(EAX);
899 __ andl(EAX, Immediate(~kSmiTagMask)); // Remove inverted smi-tag. 897 __ andl(EAX, Immediate(~kSmiTagMask)); // Remove inverted smi-tag.
900 __ ret(); 898 __ ret();
901 __ Bind(&fall_through); 899 return true;
902 return false;
903 } 900 }
904 901
905 902
906 // Check if the last argument is a double, jump to label 'is_smi' if smi 903 // Check if the last argument is a double, jump to label 'is_smi' if smi
907 // (easy to convert to double), otherwise jump to label 'not_double_smi', 904 // (easy to convert to double), otherwise jump to label 'not_double_smi',
908 // Returns the last argument in EAX. 905 // Returns the last argument in EAX.
909 static void TestLastArgumentIsDouble(Assembler* assembler, 906 static void TestLastArgumentIsDouble(Assembler* assembler,
910 Label* is_smi, 907 Label* is_smi,
911 Label* not_double_smi) { 908 Label* not_double_smi) {
912 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 909 __ movl(EAX, Address(ESP, + 1 * kWordSize));
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
981 } 978 }
982 979
983 980
984 bool Intrinsifier::Double_toDouble(Assembler* assembler) { 981 bool Intrinsifier::Double_toDouble(Assembler* assembler) {
985 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 982 __ movl(EAX, Address(ESP, + 1 * kWordSize));
986 __ ret(); 983 __ ret();
987 return true; 984 return true;
988 } 985 }
989 986
990 987
991 // Expects EAX to contain right argument, left argument is on stack. Left 988 // Expects left argument to be double (receiver). Right argument is unknown.
992 // argument is double, right argument is of unknown type. 989 // Both arguments are on stack.
993 static bool DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { 990 static bool DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) {
994 Label fall_through; 991 Label fall_through;
995 TestLastArgumentIsDouble(assembler, &fall_through, &fall_through); 992 TestLastArgumentIsDouble(assembler, &fall_through, &fall_through);
996 // Both arguments are double, right operand is in EAX, class in EBX. 993 // Both arguments are double, right operand is in EAX.
997 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); 994 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
998 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left argument. 995 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left argument.
999 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); 996 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
1000 switch (kind) { 997 switch (kind) {
1001 case Token::kADD: __ addsd(XMM0, XMM1); break; 998 case Token::kADD: __ addsd(XMM0, XMM1); break;
1002 case Token::kSUB: __ subsd(XMM0, XMM1); break; 999 case Token::kSUB: __ subsd(XMM0, XMM1); break;
1003 case Token::kMUL: __ mulsd(XMM0, XMM1); break; 1000 case Token::kMUL: __ mulsd(XMM0, XMM1); break;
1004 case Token::kDIV: __ divsd(XMM0, XMM1); break; 1001 case Token::kDIV: __ divsd(XMM0, XMM1); break;
1005 default: UNREACHABLE(); 1002 default: UNREACHABLE();
1006 } 1003 }
(...skipping 23 matching lines...) Expand all
1030 bool Intrinsifier::Double_sub(Assembler* assembler) { 1027 bool Intrinsifier::Double_sub(Assembler* assembler) {
1031 return DoubleArithmeticOperations(assembler, Token::kSUB); 1028 return DoubleArithmeticOperations(assembler, Token::kSUB);
1032 } 1029 }
1033 1030
1034 1031
1035 bool Intrinsifier::Double_div(Assembler* assembler) { 1032 bool Intrinsifier::Double_div(Assembler* assembler) {
1036 return DoubleArithmeticOperations(assembler, Token::kDIV); 1033 return DoubleArithmeticOperations(assembler, Token::kDIV);
1037 } 1034 }
1038 1035
1039 1036
1040 // Left is double right is integer (bigint or Smi) 1037 // Left is double right is integer (Bigint, Mint or Smi)
1041 bool Intrinsifier::Double_mulFromInteger(Assembler* assembler) { 1038 bool Intrinsifier::Double_mulFromInteger(Assembler* assembler) {
1042 Label fall_through; 1039 Label fall_through;
1043 // Only Smi-s allowed. 1040 // Only Smi-s allowed.
1044 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 1041 __ movl(EAX, Address(ESP, + 1 * kWordSize));
1045 __ testl(EAX, Immediate(kSmiTagMask)); 1042 __ testl(EAX, Immediate(kSmiTagMask));
1046 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); 1043 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
1047 // Is Smi. 1044 // Is Smi.
1048 __ SmiUntag(EAX); 1045 __ SmiUntag(EAX);
1049 __ cvtsi2sd(XMM1, EAX); 1046 __ cvtsi2sd(XMM1, EAX);
1050 __ movl(EAX, Address(ESP, + 2 * kWordSize)); 1047 __ movl(EAX, Address(ESP, + 2 * kWordSize));
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 __ Bind(&is_true); 1361 __ Bind(&is_true);
1365 __ LoadObject(EAX, bool_true); 1362 __ LoadObject(EAX, bool_true);
1366 __ ret(); 1363 __ ret();
1367 return true; 1364 return true;
1368 } 1365 }
1369 1366
1370 #undef __ 1367 #undef __
1371 } // namespace dart 1368 } // namespace dart
1372 1369
1373 #endif // defined TARGET_ARCH_IA32 1370 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intrinsifier_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698