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 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 __ movl(EAX, EBX); | 747 __ movl(EAX, EBX); |
748 __ shll(EBX, ECX); | 748 __ shll(EBX, ECX); |
749 __ xorl(EDI, EDI); | 749 __ xorl(EDI, EDI); |
750 __ shld(EDI, EAX); | 750 __ shld(EDI, EAX); |
751 // Result in EDI (high) and EBX (low). | 751 // Result in EDI (high) and EBX (low). |
752 const Class& mint_class = Class::Handle( | 752 const Class& mint_class = Class::Handle( |
753 Isolate::Current()->object_store()->mint_class()); | 753 Isolate::Current()->object_store()->mint_class()); |
754 AssemblerMacros::TryAllocate(assembler, | 754 AssemblerMacros::TryAllocate(assembler, |
755 mint_class, | 755 mint_class, |
756 &fall_through, | 756 &fall_through, |
| 757 Assembler::kNearJump, |
757 EAX); // Result register. | 758 EAX); // Result register. |
758 // EBX and EDI are not objects but integer values. | 759 // EBX and EDI are not objects but integer values. |
759 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX); | 760 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX); |
760 __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI); | 761 __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI); |
761 __ ret(); | 762 __ ret(); |
762 __ Bind(&fall_through); | 763 __ Bind(&fall_through); |
763 return false; | 764 return false; |
764 } | 765 } |
765 | 766 |
766 | 767 |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 case Token::kSUB: __ subsd(XMM0, XMM1); break; | 1003 case Token::kSUB: __ subsd(XMM0, XMM1); break; |
1003 case Token::kMUL: __ mulsd(XMM0, XMM1); break; | 1004 case Token::kMUL: __ mulsd(XMM0, XMM1); break; |
1004 case Token::kDIV: __ divsd(XMM0, XMM1); break; | 1005 case Token::kDIV: __ divsd(XMM0, XMM1); break; |
1005 default: UNREACHABLE(); | 1006 default: UNREACHABLE(); |
1006 } | 1007 } |
1007 const Class& double_class = Class::Handle( | 1008 const Class& double_class = Class::Handle( |
1008 Isolate::Current()->object_store()->double_class()); | 1009 Isolate::Current()->object_store()->double_class()); |
1009 AssemblerMacros::TryAllocate(assembler, | 1010 AssemblerMacros::TryAllocate(assembler, |
1010 double_class, | 1011 double_class, |
1011 &fall_through, | 1012 &fall_through, |
| 1013 Assembler::kNearJump, |
1012 EAX); // Result register. | 1014 EAX); // Result register. |
1013 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 1015 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
1014 __ ret(); | 1016 __ ret(); |
1015 __ Bind(&fall_through); | 1017 __ Bind(&fall_through); |
1016 return false; | 1018 return false; |
1017 } | 1019 } |
1018 | 1020 |
1019 | 1021 |
1020 bool Intrinsifier::Double_add(Assembler* assembler) { | 1022 bool Intrinsifier::Double_add(Assembler* assembler) { |
1021 return DoubleArithmeticOperations(assembler, Token::kADD); | 1023 return DoubleArithmeticOperations(assembler, Token::kADD); |
(...skipping 26 matching lines...) Expand all Loading... |
1048 __ SmiUntag(EAX); | 1050 __ SmiUntag(EAX); |
1049 __ cvtsi2sd(XMM1, EAX); | 1051 __ cvtsi2sd(XMM1, EAX); |
1050 __ movl(EAX, Address(ESP, + 2 * kWordSize)); | 1052 __ movl(EAX, Address(ESP, + 2 * kWordSize)); |
1051 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); | 1053 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); |
1052 __ mulsd(XMM0, XMM1); | 1054 __ mulsd(XMM0, XMM1); |
1053 const Class& double_class = Class::Handle( | 1055 const Class& double_class = Class::Handle( |
1054 Isolate::Current()->object_store()->double_class()); | 1056 Isolate::Current()->object_store()->double_class()); |
1055 AssemblerMacros::TryAllocate(assembler, | 1057 AssemblerMacros::TryAllocate(assembler, |
1056 double_class, | 1058 double_class, |
1057 &fall_through, | 1059 &fall_through, |
| 1060 Assembler::kNearJump, |
1058 EAX); // Result register. | 1061 EAX); // Result register. |
1059 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 1062 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
1060 __ ret(); | 1063 __ ret(); |
1061 __ Bind(&fall_through); | 1064 __ Bind(&fall_through); |
1062 return false; | 1065 return false; |
1063 } | 1066 } |
1064 | 1067 |
1065 | 1068 |
1066 bool Intrinsifier::Double_fromInteger(Assembler* assembler) { | 1069 bool Intrinsifier::Double_fromInteger(Assembler* assembler) { |
1067 Label fall_through; | 1070 Label fall_through; |
1068 __ movl(EAX, Address(ESP, +1 * kWordSize)); | 1071 __ movl(EAX, Address(ESP, +1 * kWordSize)); |
1069 __ testl(EAX, Immediate(kSmiTagMask)); | 1072 __ testl(EAX, Immediate(kSmiTagMask)); |
1070 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); | 1073 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); |
1071 // Is Smi. | 1074 // Is Smi. |
1072 __ SmiUntag(EAX); | 1075 __ SmiUntag(EAX); |
1073 __ cvtsi2sd(XMM0, EAX); | 1076 __ cvtsi2sd(XMM0, EAX); |
1074 const Class& double_class = Class::Handle( | 1077 const Class& double_class = Class::Handle( |
1075 Isolate::Current()->object_store()->double_class()); | 1078 Isolate::Current()->object_store()->double_class()); |
1076 AssemblerMacros::TryAllocate(assembler, | 1079 AssemblerMacros::TryAllocate(assembler, |
1077 double_class, | 1080 double_class, |
1078 &fall_through, | 1081 &fall_through, |
| 1082 Assembler::kNearJump, |
1079 EAX); // Result register. | 1083 EAX); // Result register. |
1080 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 1084 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
1081 __ ret(); | 1085 __ ret(); |
1082 __ Bind(&fall_through); | 1086 __ Bind(&fall_through); |
1083 return false; | 1087 return false; |
1084 } | 1088 } |
1085 | 1089 |
1086 | 1090 |
1087 bool Intrinsifier::Double_isNaN(Assembler* assembler) { | 1091 bool Intrinsifier::Double_isNaN(Assembler* assembler) { |
1088 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 1092 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); | 1138 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); |
1135 // Argument is double and is in EAX. | 1139 // Argument is double and is in EAX. |
1136 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); | 1140 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); |
1137 __ Bind(&double_op); | 1141 __ Bind(&double_op); |
1138 __ sqrtsd(XMM0, XMM1); | 1142 __ sqrtsd(XMM0, XMM1); |
1139 const Class& double_class = Class::Handle( | 1143 const Class& double_class = Class::Handle( |
1140 Isolate::Current()->object_store()->double_class()); | 1144 Isolate::Current()->object_store()->double_class()); |
1141 AssemblerMacros::TryAllocate(assembler, | 1145 AssemblerMacros::TryAllocate(assembler, |
1142 double_class, | 1146 double_class, |
1143 &fall_through, | 1147 &fall_through, |
| 1148 Assembler::kNearJump, |
1144 EAX); // Result register. | 1149 EAX); // Result register. |
1145 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 1150 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
1146 __ ret(); | 1151 __ ret(); |
1147 __ Bind(&is_smi); | 1152 __ Bind(&is_smi); |
1148 __ SmiUntag(EAX); | 1153 __ SmiUntag(EAX); |
1149 __ cvtsi2sd(XMM1, EAX); | 1154 __ cvtsi2sd(XMM1, EAX); |
1150 __ jmp(&double_op); | 1155 __ jmp(&double_op); |
1151 __ Bind(&fall_through); | 1156 __ Bind(&fall_through); |
1152 return false; | 1157 return false; |
1153 } | 1158 } |
(...skipping 17 matching lines...) Expand all Loading... |
1171 case kCosine: __ fcos(); break; | 1176 case kCosine: __ fcos(); break; |
1172 default: | 1177 default: |
1173 UNREACHABLE(); | 1178 UNREACHABLE(); |
1174 } | 1179 } |
1175 const Class& double_class = Class::Handle( | 1180 const Class& double_class = Class::Handle( |
1176 Isolate::Current()->object_store()->double_class()); | 1181 Isolate::Current()->object_store()->double_class()); |
1177 Label alloc_failed; | 1182 Label alloc_failed; |
1178 AssemblerMacros::TryAllocate(assembler, | 1183 AssemblerMacros::TryAllocate(assembler, |
1179 double_class, | 1184 double_class, |
1180 &alloc_failed, | 1185 &alloc_failed, |
| 1186 Assembler::kNearJump, |
1181 EAX); // Result register. | 1187 EAX); // Result register. |
1182 __ fstpl(FieldAddress(EAX, Double::value_offset())); | 1188 __ fstpl(FieldAddress(EAX, Double::value_offset())); |
1183 __ ret(); | 1189 __ ret(); |
1184 | 1190 |
1185 __ Bind(&is_smi); // smi -> double. | 1191 __ Bind(&is_smi); // smi -> double. |
1186 __ SmiUntag(EAX); | 1192 __ SmiUntag(EAX); |
1187 __ pushl(EAX); | 1193 __ pushl(EAX); |
1188 __ filds(Address(ESP, 0)); | 1194 __ filds(Address(ESP, 0)); |
1189 __ popl(EAX); | 1195 __ popl(EAX); |
1190 __ jmp(&double_op); | 1196 __ jmp(&double_op); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 __ Bind(&is_true); | 1370 __ Bind(&is_true); |
1365 __ LoadObject(EAX, bool_true); | 1371 __ LoadObject(EAX, bool_true); |
1366 __ ret(); | 1372 __ ret(); |
1367 return true; | 1373 return true; |
1368 } | 1374 } |
1369 | 1375 |
1370 #undef __ | 1376 #undef __ |
1371 } // namespace dart | 1377 } // namespace dart |
1372 | 1378 |
1373 #endif // defined TARGET_ARCH_IA32 | 1379 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |