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 // | 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 |