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 |