| 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 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 778 __ movl(EAX, EBX); | 778 __ movl(EAX, EBX); |
| 779 __ shll(EBX, ECX); | 779 __ shll(EBX, ECX); |
| 780 __ xorl(EDI, EDI); | 780 __ xorl(EDI, EDI); |
| 781 __ shld(EDI, EAX); | 781 __ shld(EDI, EAX); |
| 782 // Result in EDI (high) and EBX (low). | 782 // Result in EDI (high) and EBX (low). |
| 783 const Class& mint_class = Class::Handle( | 783 const Class& mint_class = Class::Handle( |
| 784 Isolate::Current()->object_store()->mint_class()); | 784 Isolate::Current()->object_store()->mint_class()); |
| 785 AssemblerMacros::TryAllocate(assembler, | 785 AssemblerMacros::TryAllocate(assembler, |
| 786 mint_class, | 786 mint_class, |
| 787 &fall_through, | 787 &fall_through, |
| 788 Assembler::kNearJump, |
| 788 EAX); // Result register. | 789 EAX); // Result register. |
| 789 // EBX and EDI are not objects but integer values. | 790 // EBX and EDI are not objects but integer values. |
| 790 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX); | 791 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX); |
| 791 __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI); | 792 __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI); |
| 792 __ ret(); | 793 __ ret(); |
| 793 __ Bind(&fall_through); | 794 __ Bind(&fall_through); |
| 794 return false; | 795 return false; |
| 795 } | 796 } |
| 796 | 797 |
| 797 | 798 |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1033 case Token::kSUB: __ subsd(XMM0, XMM1); break; | 1034 case Token::kSUB: __ subsd(XMM0, XMM1); break; |
| 1034 case Token::kMUL: __ mulsd(XMM0, XMM1); break; | 1035 case Token::kMUL: __ mulsd(XMM0, XMM1); break; |
| 1035 case Token::kDIV: __ divsd(XMM0, XMM1); break; | 1036 case Token::kDIV: __ divsd(XMM0, XMM1); break; |
| 1036 default: UNREACHABLE(); | 1037 default: UNREACHABLE(); |
| 1037 } | 1038 } |
| 1038 const Class& double_class = Class::Handle( | 1039 const Class& double_class = Class::Handle( |
| 1039 Isolate::Current()->object_store()->double_class()); | 1040 Isolate::Current()->object_store()->double_class()); |
| 1040 AssemblerMacros::TryAllocate(assembler, | 1041 AssemblerMacros::TryAllocate(assembler, |
| 1041 double_class, | 1042 double_class, |
| 1042 &fall_through, | 1043 &fall_through, |
| 1044 Assembler::kNearJump, |
| 1043 EAX); // Result register. | 1045 EAX); // Result register. |
| 1044 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 1046 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
| 1045 __ ret(); | 1047 __ ret(); |
| 1046 __ Bind(&fall_through); | 1048 __ Bind(&fall_through); |
| 1047 return false; | 1049 return false; |
| 1048 } | 1050 } |
| 1049 | 1051 |
| 1050 | 1052 |
| 1051 bool Intrinsifier::Double_add(Assembler* assembler) { | 1053 bool Intrinsifier::Double_add(Assembler* assembler) { |
| 1052 return DoubleArithmeticOperations(assembler, Token::kADD); | 1054 return DoubleArithmeticOperations(assembler, Token::kADD); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1079 __ SmiUntag(EAX); | 1081 __ SmiUntag(EAX); |
| 1080 __ cvtsi2sd(XMM1, EAX); | 1082 __ cvtsi2sd(XMM1, EAX); |
| 1081 __ movl(EAX, Address(ESP, + 2 * kWordSize)); | 1083 __ movl(EAX, Address(ESP, + 2 * kWordSize)); |
| 1082 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); | 1084 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); |
| 1083 __ mulsd(XMM0, XMM1); | 1085 __ mulsd(XMM0, XMM1); |
| 1084 const Class& double_class = Class::Handle( | 1086 const Class& double_class = Class::Handle( |
| 1085 Isolate::Current()->object_store()->double_class()); | 1087 Isolate::Current()->object_store()->double_class()); |
| 1086 AssemblerMacros::TryAllocate(assembler, | 1088 AssemblerMacros::TryAllocate(assembler, |
| 1087 double_class, | 1089 double_class, |
| 1088 &fall_through, | 1090 &fall_through, |
| 1091 Assembler::kNearJump, |
| 1089 EAX); // Result register. | 1092 EAX); // Result register. |
| 1090 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 1093 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
| 1091 __ ret(); | 1094 __ ret(); |
| 1092 __ Bind(&fall_through); | 1095 __ Bind(&fall_through); |
| 1093 return false; | 1096 return false; |
| 1094 } | 1097 } |
| 1095 | 1098 |
| 1096 | 1099 |
| 1097 bool Intrinsifier::Double_fromInteger(Assembler* assembler) { | 1100 bool Intrinsifier::Double_fromInteger(Assembler* assembler) { |
| 1098 Label fall_through; | 1101 Label fall_through; |
| 1099 __ movl(EAX, Address(ESP, +1 * kWordSize)); | 1102 __ movl(EAX, Address(ESP, +1 * kWordSize)); |
| 1100 __ testl(EAX, Immediate(kSmiTagMask)); | 1103 __ testl(EAX, Immediate(kSmiTagMask)); |
| 1101 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); | 1104 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); |
| 1102 // Is Smi. | 1105 // Is Smi. |
| 1103 __ SmiUntag(EAX); | 1106 __ SmiUntag(EAX); |
| 1104 __ cvtsi2sd(XMM0, EAX); | 1107 __ cvtsi2sd(XMM0, EAX); |
| 1105 const Class& double_class = Class::Handle( | 1108 const Class& double_class = Class::Handle( |
| 1106 Isolate::Current()->object_store()->double_class()); | 1109 Isolate::Current()->object_store()->double_class()); |
| 1107 AssemblerMacros::TryAllocate(assembler, | 1110 AssemblerMacros::TryAllocate(assembler, |
| 1108 double_class, | 1111 double_class, |
| 1109 &fall_through, | 1112 &fall_through, |
| 1113 Assembler::kNearJump, |
| 1110 EAX); // Result register. | 1114 EAX); // Result register. |
| 1111 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 1115 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
| 1112 __ ret(); | 1116 __ ret(); |
| 1113 __ Bind(&fall_through); | 1117 __ Bind(&fall_through); |
| 1114 return false; | 1118 return false; |
| 1115 } | 1119 } |
| 1116 | 1120 |
| 1117 | 1121 |
| 1118 bool Intrinsifier::Double_isNaN(Assembler* assembler) { | 1122 bool Intrinsifier::Double_isNaN(Assembler* assembler) { |
| 1119 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 1123 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1165 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); | 1169 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); |
| 1166 // Argument is double and is in EAX. | 1170 // Argument is double and is in EAX. |
| 1167 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); | 1171 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); |
| 1168 __ Bind(&double_op); | 1172 __ Bind(&double_op); |
| 1169 __ sqrtsd(XMM0, XMM1); | 1173 __ sqrtsd(XMM0, XMM1); |
| 1170 const Class& double_class = Class::Handle( | 1174 const Class& double_class = Class::Handle( |
| 1171 Isolate::Current()->object_store()->double_class()); | 1175 Isolate::Current()->object_store()->double_class()); |
| 1172 AssemblerMacros::TryAllocate(assembler, | 1176 AssemblerMacros::TryAllocate(assembler, |
| 1173 double_class, | 1177 double_class, |
| 1174 &fall_through, | 1178 &fall_through, |
| 1179 Assembler::kNearJump, |
| 1175 EAX); // Result register. | 1180 EAX); // Result register. |
| 1176 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 1181 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
| 1177 __ ret(); | 1182 __ ret(); |
| 1178 __ Bind(&is_smi); | 1183 __ Bind(&is_smi); |
| 1179 __ SmiUntag(EAX); | 1184 __ SmiUntag(EAX); |
| 1180 __ cvtsi2sd(XMM1, EAX); | 1185 __ cvtsi2sd(XMM1, EAX); |
| 1181 __ jmp(&double_op); | 1186 __ jmp(&double_op); |
| 1182 __ Bind(&fall_through); | 1187 __ Bind(&fall_through); |
| 1183 return false; | 1188 return false; |
| 1184 } | 1189 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1202 case kCosine: __ fcos(); break; | 1207 case kCosine: __ fcos(); break; |
| 1203 default: | 1208 default: |
| 1204 UNREACHABLE(); | 1209 UNREACHABLE(); |
| 1205 } | 1210 } |
| 1206 const Class& double_class = Class::Handle( | 1211 const Class& double_class = Class::Handle( |
| 1207 Isolate::Current()->object_store()->double_class()); | 1212 Isolate::Current()->object_store()->double_class()); |
| 1208 Label alloc_failed; | 1213 Label alloc_failed; |
| 1209 AssemblerMacros::TryAllocate(assembler, | 1214 AssemblerMacros::TryAllocate(assembler, |
| 1210 double_class, | 1215 double_class, |
| 1211 &alloc_failed, | 1216 &alloc_failed, |
| 1217 Assembler::kNearJump, |
| 1212 EAX); // Result register. | 1218 EAX); // Result register. |
| 1213 __ fstpl(FieldAddress(EAX, Double::value_offset())); | 1219 __ fstpl(FieldAddress(EAX, Double::value_offset())); |
| 1214 __ ret(); | 1220 __ ret(); |
| 1215 | 1221 |
| 1216 __ Bind(&is_smi); // smi -> double. | 1222 __ Bind(&is_smi); // smi -> double. |
| 1217 __ SmiUntag(EAX); | 1223 __ SmiUntag(EAX); |
| 1218 __ pushl(EAX); | 1224 __ pushl(EAX); |
| 1219 __ filds(Address(ESP, 0)); | 1225 __ filds(Address(ESP, 0)); |
| 1220 __ popl(EAX); | 1226 __ popl(EAX); |
| 1221 __ jmp(&double_op); | 1227 __ jmp(&double_op); |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1395 __ Bind(&is_true); | 1401 __ Bind(&is_true); |
| 1396 __ LoadObject(EAX, bool_true); | 1402 __ LoadObject(EAX, bool_true); |
| 1397 __ ret(); | 1403 __ ret(); |
| 1398 return true; | 1404 return true; |
| 1399 } | 1405 } |
| 1400 | 1406 |
| 1401 #undef __ | 1407 #undef __ |
| 1402 } // namespace dart | 1408 } // namespace dart |
| 1403 | 1409 |
| 1404 #endif // defined TARGET_ARCH_IA32 | 1410 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |