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 // | 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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 __ Bind(&size_tag_overflow); | 82 __ Bind(&size_tag_overflow); |
83 __ movl(EDI, Immediate(0)); | 83 __ movl(EDI, Immediate(0)); |
84 __ Bind(&done); | 84 __ Bind(&done); |
85 | 85 |
86 // Get the class index and insert it into the tags. | 86 // Get the class index and insert it into the tags. |
87 const Class& cls = Class::Handle(isolate->object_store()->array_class()); | 87 const Class& cls = Class::Handle(isolate->object_store()->array_class()); |
88 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cls.id()))); | 88 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cls.id()))); |
89 __ movl(FieldAddress(EAX, Array::tags_offset()), EDI); // Tags. | 89 __ movl(FieldAddress(EAX, Array::tags_offset()), EDI); // Tags. |
90 } | 90 } |
91 | 91 |
92 // Store class value for array. | |
93 // EAX: new object start as a tagged pointer. | 92 // EAX: new object start as a tagged pointer. |
94 // EBX: new object end address. | 93 // EBX: new object end address. |
95 __ movl(EDI, FieldAddress(CTX, Context::isolate_offset())); | |
96 __ movl(EDI, Address(EDI, Isolate::object_store_offset())); | |
97 __ movl(EDI, Address(EDI, ObjectStore::array_class_offset())); | |
98 __ StoreIntoObject(EAX, FieldAddress(EAX, Array::class_offset()), EDI); | |
99 | |
100 // Store the type argument field. | 94 // Store the type argument field. |
101 __ movl(EDI, Address(ESP, kTypeArgumentsOffset)); // type argument. | 95 __ movl(EDI, Address(ESP, kTypeArgumentsOffset)); // type argument. |
102 __ StoreIntoObject(EAX, | 96 __ StoreIntoObject(EAX, |
103 FieldAddress(EAX, Array::type_arguments_offset()), | 97 FieldAddress(EAX, Array::type_arguments_offset()), |
104 EDI); | 98 EDI); |
105 | 99 |
106 // Set the length field. | 100 // Set the length field. |
107 __ movl(EDI, Address(ESP, kArrayLengthOffset)); // Array Length. | 101 __ movl(EDI, Address(ESP, kArrayLengthOffset)); // Array Length. |
108 __ StoreIntoObject(EAX, FieldAddress(EAX, Array::length_offset()), EDI); | 102 __ StoreIntoObject(EAX, FieldAddress(EAX, Array::length_offset()), EDI); |
109 | 103 |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
296 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 290 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
297 __ movl(FieldAddress(EAX, GrowableObjectArray::tags_offset()), | 291 __ movl(FieldAddress(EAX, GrowableObjectArray::tags_offset()), |
298 Immediate(tags)); | 292 Immediate(tags)); |
299 | 293 |
300 // Store backing array object in growable array object. | 294 // Store backing array object in growable array object. |
301 __ movl(EBX, Address(ESP, kArrayOffset)); // data argument. | 295 __ movl(EBX, Address(ESP, kArrayOffset)); // data argument. |
302 __ StoreIntoObject(EAX, | 296 __ StoreIntoObject(EAX, |
303 FieldAddress(EAX, GrowableObjectArray::data_offset()), | 297 FieldAddress(EAX, GrowableObjectArray::data_offset()), |
304 EBX); | 298 EBX); |
305 | 299 |
306 // Store class value for the growable array object. | |
307 // EAX: new growable array object start as a tagged pointer. | 300 // EAX: new growable array object start as a tagged pointer. |
308 __ movl(EBX, FieldAddress(CTX, Context::isolate_offset())); | |
309 __ movl(EBX, Address(EBX, Isolate::object_store_offset())); | |
310 __ movl(EBX, Address(EBX, ObjectStore::growable_object_array_class_offset())); | |
311 __ StoreIntoObject(EAX, | |
312 FieldAddress(EAX, GrowableObjectArray::class_offset()), | |
313 EBX); | |
314 | |
315 // Store the type argument field in the growable array object. | 301 // Store the type argument field in the growable array object. |
316 __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument. | 302 __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument. |
317 __ StoreIntoObject(EAX, | 303 __ StoreIntoObject(EAX, |
318 FieldAddress(EAX, | 304 FieldAddress(EAX, |
319 GrowableObjectArray::type_arguments_offset()), | 305 GrowableObjectArray::type_arguments_offset()), |
320 EBX); | 306 EBX); |
321 | 307 |
322 // Set the length field in the growable array object to 0. | 308 // Set the length field in the growable array object to 0. |
323 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), | 309 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), |
324 Immediate(0)); | 310 Immediate(0)); |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
649 // Arguments are Smi but the shift produced an overflow to Mint. | 635 // Arguments are Smi but the shift produced an overflow to Mint. |
650 __ cmpl(EBX, Immediate(0)); | 636 __ cmpl(EBX, Immediate(0)); |
651 // TODO(srdjan): Implement negative values, for now fall through. | 637 // TODO(srdjan): Implement negative values, for now fall through. |
652 __ j(LESS, &fall_through, Assembler::kNearJump); | 638 __ j(LESS, &fall_through, Assembler::kNearJump); |
653 __ SmiUntag(EBX); | 639 __ SmiUntag(EBX); |
654 __ movl(EAX, EBX); | 640 __ movl(EAX, EBX); |
655 __ shll(EBX, ECX); | 641 __ shll(EBX, ECX); |
656 __ xorl(EDI, EDI); | 642 __ xorl(EDI, EDI); |
657 __ shld(EDI, EAX); | 643 __ shld(EDI, EAX); |
658 // Result in EDI (high) and EBX (low). | 644 // Result in EDI (high) and EBX (low). |
659 const Class& mint_class = Class::ZoneHandle( | 645 const Class& mint_class = Class::ZoneHandle( |
Ivan Posva
2012/06/06 13:42:11
Does still need to be a ZoneHandle?
| |
660 Isolate::Current()->object_store()->mint_class()); | 646 Isolate::Current()->object_store()->mint_class()); |
661 __ LoadObject(ECX, mint_class); | |
662 AssemblerMacros::TryAllocate(assembler, | 647 AssemblerMacros::TryAllocate(assembler, |
663 mint_class, | 648 mint_class, |
664 ECX, // Class register. | |
665 &fall_through, | 649 &fall_through, |
666 EAX); // Result register. | 650 EAX); // Result register. |
667 // EBX and EDI are not objects but integer values. | 651 // EBX and EDI are not objects but integer values. |
668 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX); | 652 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX); |
669 __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI); | 653 __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI); |
670 __ ret(); | 654 __ ret(); |
671 __ Bind(&fall_through); | 655 __ Bind(&fall_through); |
672 return false; | 656 return false; |
673 } | 657 } |
674 | 658 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
909 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); | 893 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); |
910 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left argument. | 894 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left argument. |
911 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); | 895 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); |
912 switch (kind) { | 896 switch (kind) { |
913 case Token::kADD: __ addsd(XMM0, XMM1); break; | 897 case Token::kADD: __ addsd(XMM0, XMM1); break; |
914 case Token::kSUB: __ subsd(XMM0, XMM1); break; | 898 case Token::kSUB: __ subsd(XMM0, XMM1); break; |
915 case Token::kMUL: __ mulsd(XMM0, XMM1); break; | 899 case Token::kMUL: __ mulsd(XMM0, XMM1); break; |
916 case Token::kDIV: __ divsd(XMM0, XMM1); break; | 900 case Token::kDIV: __ divsd(XMM0, XMM1); break; |
917 default: UNREACHABLE(); | 901 default: UNREACHABLE(); |
918 } | 902 } |
919 const Class& double_class = Class::ZoneHandle( | 903 const Class& double_class = Class::ZoneHandle( |
Ivan Posva
2012/06/06 13:42:11
Ditto here and many other places.
| |
920 Isolate::Current()->object_store()->double_class()); | 904 Isolate::Current()->object_store()->double_class()); |
921 __ LoadObject(EBX, double_class); | |
922 AssemblerMacros::TryAllocate(assembler, | 905 AssemblerMacros::TryAllocate(assembler, |
923 double_class, | 906 double_class, |
924 EBX, // Class register. | |
925 &fall_through, | 907 &fall_through, |
926 EAX); // Result register. | 908 EAX); // Result register. |
927 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 909 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
928 __ ret(); | 910 __ ret(); |
929 __ Bind(&fall_through); | 911 __ Bind(&fall_through); |
930 return false; | 912 return false; |
931 } | 913 } |
932 | 914 |
933 | 915 |
934 bool Intrinsifier::Double_add(Assembler* assembler) { | 916 bool Intrinsifier::Double_add(Assembler* assembler) { |
(...skipping 24 matching lines...) Expand all Loading... | |
959 __ testl(EAX, Immediate(kSmiTagMask)); | 941 __ testl(EAX, Immediate(kSmiTagMask)); |
960 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); | 942 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); |
961 // Is Smi. | 943 // Is Smi. |
962 __ SmiUntag(EAX); | 944 __ SmiUntag(EAX); |
963 __ cvtsi2sd(XMM1, EAX); | 945 __ cvtsi2sd(XMM1, EAX); |
964 __ movl(EAX, Address(ESP, + 2 * kWordSize)); | 946 __ movl(EAX, Address(ESP, + 2 * kWordSize)); |
965 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); | 947 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); |
966 __ mulsd(XMM0, XMM1); | 948 __ mulsd(XMM0, XMM1); |
967 const Class& double_class = Class::ZoneHandle( | 949 const Class& double_class = Class::ZoneHandle( |
968 Isolate::Current()->object_store()->double_class()); | 950 Isolate::Current()->object_store()->double_class()); |
969 __ LoadObject(EBX, double_class); | |
970 AssemblerMacros::TryAllocate(assembler, | 951 AssemblerMacros::TryAllocate(assembler, |
971 double_class, | 952 double_class, |
972 EBX, // Class register. | |
973 &fall_through, | 953 &fall_through, |
974 EAX); // Result register. | 954 EAX); // Result register. |
975 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 955 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
976 __ ret(); | 956 __ ret(); |
977 __ Bind(&fall_through); | 957 __ Bind(&fall_through); |
978 return false; | 958 return false; |
979 } | 959 } |
980 | 960 |
981 | 961 |
982 bool Intrinsifier::Double_fromInteger(Assembler* assembler) { | 962 bool Intrinsifier::Double_fromInteger(Assembler* assembler) { |
983 Label fall_through; | 963 Label fall_through; |
984 __ movl(EAX, Address(ESP, +1 * kWordSize)); | 964 __ movl(EAX, Address(ESP, +1 * kWordSize)); |
985 __ testl(EAX, Immediate(kSmiTagMask)); | 965 __ testl(EAX, Immediate(kSmiTagMask)); |
986 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); | 966 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); |
987 // Is Smi. | 967 // Is Smi. |
988 __ SmiUntag(EAX); | 968 __ SmiUntag(EAX); |
989 __ cvtsi2sd(XMM0, EAX); | 969 __ cvtsi2sd(XMM0, EAX); |
990 const Class& double_class = Class::ZoneHandle( | 970 const Class& double_class = Class::ZoneHandle( |
991 Isolate::Current()->object_store()->double_class()); | 971 Isolate::Current()->object_store()->double_class()); |
992 __ LoadObject(EBX, double_class); | |
993 AssemblerMacros::TryAllocate(assembler, | 972 AssemblerMacros::TryAllocate(assembler, |
994 double_class, | 973 double_class, |
995 EBX, // Class register. | |
996 &fall_through, | 974 &fall_through, |
997 EAX); // Result register. | 975 EAX); // Result register. |
998 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 976 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
999 __ ret(); | 977 __ ret(); |
1000 __ Bind(&fall_through); | 978 __ Bind(&fall_through); |
1001 return false; | 979 return false; |
1002 } | 980 } |
1003 | 981 |
1004 | 982 |
1005 bool Intrinsifier::Double_isNaN(Assembler* assembler) { | 983 bool Intrinsifier::Double_isNaN(Assembler* assembler) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1049 // Argument type is not known | 1027 // Argument type is not known |
1050 bool Intrinsifier::Math_sqrt(Assembler* assembler) { | 1028 bool Intrinsifier::Math_sqrt(Assembler* assembler) { |
1051 Label fall_through, is_smi, double_op; | 1029 Label fall_through, is_smi, double_op; |
1052 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); | 1030 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); |
1053 // Argument is double and is in EAX, class in EBX. | 1031 // Argument is double and is in EAX, class in EBX. |
1054 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); | 1032 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); |
1055 __ Bind(&double_op); | 1033 __ Bind(&double_op); |
1056 __ sqrtsd(XMM0, XMM1); | 1034 __ sqrtsd(XMM0, XMM1); |
1057 const Class& double_class = Class::ZoneHandle( | 1035 const Class& double_class = Class::ZoneHandle( |
1058 Isolate::Current()->object_store()->double_class()); | 1036 Isolate::Current()->object_store()->double_class()); |
1059 __ LoadObject(EBX, double_class); | |
1060 AssemblerMacros::TryAllocate(assembler, | 1037 AssemblerMacros::TryAllocate(assembler, |
1061 double_class, | 1038 double_class, |
1062 EBX, // Class register. | |
1063 &fall_through, | 1039 &fall_through, |
1064 EAX); // Result register. | 1040 EAX); // Result register. |
1065 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 1041 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
1066 __ ret(); | 1042 __ ret(); |
1067 __ Bind(&is_smi); | 1043 __ Bind(&is_smi); |
1068 __ SmiUntag(EAX); | 1044 __ SmiUntag(EAX); |
1069 __ cvtsi2sd(XMM1, EAX); | 1045 __ cvtsi2sd(XMM1, EAX); |
1070 __ jmp(&double_op); | 1046 __ jmp(&double_op); |
1071 __ Bind(&fall_through); | 1047 __ Bind(&fall_through); |
1072 return false; | 1048 return false; |
(...skipping 14 matching lines...) Expand all Loading... | |
1087 __ fldl(FieldAddress(EAX, Double::value_offset())); | 1063 __ fldl(FieldAddress(EAX, Double::value_offset())); |
1088 __ Bind(&double_op); | 1064 __ Bind(&double_op); |
1089 switch (kind) { | 1065 switch (kind) { |
1090 case kSine: __ fsin(); break; | 1066 case kSine: __ fsin(); break; |
1091 case kCosine: __ fcos(); break; | 1067 case kCosine: __ fcos(); break; |
1092 default: | 1068 default: |
1093 UNREACHABLE(); | 1069 UNREACHABLE(); |
1094 } | 1070 } |
1095 const Class& double_class = Class::ZoneHandle( | 1071 const Class& double_class = Class::ZoneHandle( |
1096 Isolate::Current()->object_store()->double_class()); | 1072 Isolate::Current()->object_store()->double_class()); |
1097 __ LoadObject(EBX, double_class); | |
1098 Label alloc_failed; | 1073 Label alloc_failed; |
1099 AssemblerMacros::TryAllocate(assembler, | 1074 AssemblerMacros::TryAllocate(assembler, |
1100 double_class, | 1075 double_class, |
1101 EBX, // Class register. | |
1102 &alloc_failed, | 1076 &alloc_failed, |
1103 EAX); // Result register. | 1077 EAX); // Result register. |
1104 __ fstpl(FieldAddress(EAX, Double::value_offset())); | 1078 __ fstpl(FieldAddress(EAX, Double::value_offset())); |
1105 __ ret(); | 1079 __ ret(); |
1106 | 1080 |
1107 __ Bind(&is_smi); // smi -> double. | 1081 __ Bind(&is_smi); // smi -> double. |
1108 __ SmiUntag(EAX); | 1082 __ SmiUntag(EAX); |
1109 __ pushl(EAX); | 1083 __ pushl(EAX); |
1110 __ filds(Address(ESP, 0)); | 1084 __ filds(Address(ESP, 0)); |
1111 __ popl(EAX); | 1085 __ popl(EAX); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1284 __ Bind(&is_true); | 1258 __ Bind(&is_true); |
1285 __ LoadObject(EAX, bool_true); | 1259 __ LoadObject(EAX, bool_true); |
1286 __ ret(); | 1260 __ ret(); |
1287 return true; | 1261 return true; |
1288 } | 1262 } |
1289 | 1263 |
1290 #undef __ | 1264 #undef __ |
1291 } // namespace dart | 1265 } // namespace dart |
1292 | 1266 |
1293 #endif // defined TARGET_ARCH_IA32 | 1267 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |