| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/intrinsifier.h" | 8 #include "vm/intrinsifier.h" |
| 9 | 9 |
| 10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
| 11 #include "vm/assembler_macros.h" | |
| 12 #include "vm/instructions.h" | 11 #include "vm/instructions.h" |
| 13 #include "vm/object_store.h" | 12 #include "vm/object_store.h" |
| 14 #include "vm/symbols.h" | 13 #include "vm/symbols.h" |
| 15 | 14 |
| 16 namespace dart { | 15 namespace dart { |
| 17 | 16 |
| 18 DECLARE_FLAG(bool, enable_type_checks); | 17 DECLARE_FLAG(bool, enable_type_checks); |
| 19 | 18 |
| 20 // When entering intrinsics code: | 19 // When entering intrinsics code: |
| 21 // RBX: IC Data | 20 // RBX: IC Data |
| (...skipping 1138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1160 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); | 1159 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); |
| 1161 switch (kind) { | 1160 switch (kind) { |
| 1162 case Token::kADD: __ addsd(XMM0, XMM1); break; | 1161 case Token::kADD: __ addsd(XMM0, XMM1); break; |
| 1163 case Token::kSUB: __ subsd(XMM0, XMM1); break; | 1162 case Token::kSUB: __ subsd(XMM0, XMM1); break; |
| 1164 case Token::kMUL: __ mulsd(XMM0, XMM1); break; | 1163 case Token::kMUL: __ mulsd(XMM0, XMM1); break; |
| 1165 case Token::kDIV: __ divsd(XMM0, XMM1); break; | 1164 case Token::kDIV: __ divsd(XMM0, XMM1); break; |
| 1166 default: UNREACHABLE(); | 1165 default: UNREACHABLE(); |
| 1167 } | 1166 } |
| 1168 const Class& double_class = Class::Handle( | 1167 const Class& double_class = Class::Handle( |
| 1169 Isolate::Current()->object_store()->double_class()); | 1168 Isolate::Current()->object_store()->double_class()); |
| 1170 AssemblerMacros::TryAllocate(assembler, | 1169 __ TryAllocate(double_class, |
| 1171 double_class, | 1170 &fall_through, |
| 1172 &fall_through, | 1171 Assembler::kNearJump, |
| 1173 Assembler::kNearJump, | 1172 RAX); // Result register. |
| 1174 RAX); // Result register. | |
| 1175 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 1173 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
| 1176 __ ret(); | 1174 __ ret(); |
| 1177 __ Bind(&fall_through); | 1175 __ Bind(&fall_through); |
| 1178 return false; | 1176 return false; |
| 1179 } | 1177 } |
| 1180 | 1178 |
| 1181 | 1179 |
| 1182 bool Intrinsifier::Double_add(Assembler* assembler) { | 1180 bool Intrinsifier::Double_add(Assembler* assembler) { |
| 1183 return DoubleArithmeticOperations(assembler, Token::kADD); | 1181 return DoubleArithmeticOperations(assembler, Token::kADD); |
| 1184 } | 1182 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1206 __ testq(RAX, Immediate(kSmiTagMask)); | 1204 __ testq(RAX, Immediate(kSmiTagMask)); |
| 1207 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); | 1205 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); |
| 1208 // Is Smi. | 1206 // Is Smi. |
| 1209 __ SmiUntag(RAX); | 1207 __ SmiUntag(RAX); |
| 1210 __ cvtsi2sd(XMM1, RAX); | 1208 __ cvtsi2sd(XMM1, RAX); |
| 1211 __ movq(RAX, Address(RSP, + 2 * kWordSize)); | 1209 __ movq(RAX, Address(RSP, + 2 * kWordSize)); |
| 1212 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); | 1210 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); |
| 1213 __ mulsd(XMM0, XMM1); | 1211 __ mulsd(XMM0, XMM1); |
| 1214 const Class& double_class = Class::Handle( | 1212 const Class& double_class = Class::Handle( |
| 1215 Isolate::Current()->object_store()->double_class()); | 1213 Isolate::Current()->object_store()->double_class()); |
| 1216 AssemblerMacros::TryAllocate(assembler, | 1214 __ TryAllocate(double_class, |
| 1217 double_class, | 1215 &fall_through, |
| 1218 &fall_through, | 1216 Assembler::kNearJump, |
| 1219 Assembler::kNearJump, | 1217 RAX); // Result register. |
| 1220 RAX); // Result register. | |
| 1221 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 1218 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
| 1222 __ ret(); | 1219 __ ret(); |
| 1223 __ Bind(&fall_through); | 1220 __ Bind(&fall_through); |
| 1224 return false; | 1221 return false; |
| 1225 } | 1222 } |
| 1226 | 1223 |
| 1227 | 1224 |
| 1228 // Left is double right is integer (Bigint, Mint or Smi) | 1225 // Left is double right is integer (Bigint, Mint or Smi) |
| 1229 bool Intrinsifier::Double_fromInteger(Assembler* assembler) { | 1226 bool Intrinsifier::Double_fromInteger(Assembler* assembler) { |
| 1230 Label fall_through; | 1227 Label fall_through; |
| 1231 __ movq(RAX, Address(RSP, +1 * kWordSize)); | 1228 __ movq(RAX, Address(RSP, +1 * kWordSize)); |
| 1232 __ testq(RAX, Immediate(kSmiTagMask)); | 1229 __ testq(RAX, Immediate(kSmiTagMask)); |
| 1233 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); | 1230 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); |
| 1234 // Is Smi. | 1231 // Is Smi. |
| 1235 __ SmiUntag(RAX); | 1232 __ SmiUntag(RAX); |
| 1236 __ cvtsi2sd(XMM0, RAX); | 1233 __ cvtsi2sd(XMM0, RAX); |
| 1237 const Class& double_class = Class::Handle( | 1234 const Class& double_class = Class::Handle( |
| 1238 Isolate::Current()->object_store()->double_class()); | 1235 Isolate::Current()->object_store()->double_class()); |
| 1239 AssemblerMacros::TryAllocate(assembler, | 1236 __ TryAllocate(double_class, |
| 1240 double_class, | 1237 &fall_through, |
| 1241 &fall_through, | 1238 Assembler::kNearJump, |
| 1242 Assembler::kNearJump, | 1239 RAX); // Result register. |
| 1243 RAX); // Result register. | |
| 1244 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 1240 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
| 1245 __ ret(); | 1241 __ ret(); |
| 1246 __ Bind(&fall_through); | 1242 __ Bind(&fall_through); |
| 1247 return false; | 1243 return false; |
| 1248 } | 1244 } |
| 1249 | 1245 |
| 1250 | 1246 |
| 1251 bool Intrinsifier::Double_getIsNaN(Assembler* assembler) { | 1247 bool Intrinsifier::Double_getIsNaN(Assembler* assembler) { |
| 1252 Label is_true; | 1248 Label is_true; |
| 1253 __ movq(RAX, Address(RSP, +1 * kWordSize)); | 1249 __ movq(RAX, Address(RSP, +1 * kWordSize)); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1303 __ Bind(&double_op); | 1299 __ Bind(&double_op); |
| 1304 switch (kind) { | 1300 switch (kind) { |
| 1305 case kSine: __ fsin(); break; | 1301 case kSine: __ fsin(); break; |
| 1306 case kCosine: __ fcos(); break; | 1302 case kCosine: __ fcos(); break; |
| 1307 default: | 1303 default: |
| 1308 UNREACHABLE(); | 1304 UNREACHABLE(); |
| 1309 } | 1305 } |
| 1310 const Class& double_class = Class::Handle( | 1306 const Class& double_class = Class::Handle( |
| 1311 Isolate::Current()->object_store()->double_class()); | 1307 Isolate::Current()->object_store()->double_class()); |
| 1312 Label alloc_failed; | 1308 Label alloc_failed; |
| 1313 AssemblerMacros::TryAllocate(assembler, | 1309 __ TryAllocate(double_class, |
| 1314 double_class, | 1310 &alloc_failed, |
| 1315 &alloc_failed, | 1311 Assembler::kNearJump, |
| 1316 Assembler::kNearJump, | 1312 RAX); // Result register. |
| 1317 RAX); // Result register. | |
| 1318 __ fstpl(FieldAddress(RAX, Double::value_offset())); | 1313 __ fstpl(FieldAddress(RAX, Double::value_offset())); |
| 1319 __ ret(); | 1314 __ ret(); |
| 1320 | 1315 |
| 1321 __ Bind(&is_smi); // smi -> double. | 1316 __ Bind(&is_smi); // smi -> double. |
| 1322 __ SmiUntag(RAX); | 1317 __ SmiUntag(RAX); |
| 1323 __ pushq(RAX); | 1318 __ pushq(RAX); |
| 1324 __ fildl(Address(RSP, 0)); | 1319 __ fildl(Address(RSP, 0)); |
| 1325 __ popq(RAX); | 1320 __ popq(RAX); |
| 1326 __ jmp(&double_op); | 1321 __ jmp(&double_op); |
| 1327 | 1322 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1352 | 1347 |
| 1353 bool Intrinsifier::Math_sqrt(Assembler* assembler) { | 1348 bool Intrinsifier::Math_sqrt(Assembler* assembler) { |
| 1354 Label fall_through, is_smi, double_op; | 1349 Label fall_through, is_smi, double_op; |
| 1355 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); | 1350 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); |
| 1356 // Argument is double and is in RAX. | 1351 // Argument is double and is in RAX. |
| 1357 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); | 1352 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); |
| 1358 __ Bind(&double_op); | 1353 __ Bind(&double_op); |
| 1359 __ sqrtsd(XMM0, XMM1); | 1354 __ sqrtsd(XMM0, XMM1); |
| 1360 const Class& double_class = Class::Handle( | 1355 const Class& double_class = Class::Handle( |
| 1361 Isolate::Current()->object_store()->double_class()); | 1356 Isolate::Current()->object_store()->double_class()); |
| 1362 AssemblerMacros::TryAllocate(assembler, | 1357 __ TryAllocate(double_class, |
| 1363 double_class, | 1358 &fall_through, |
| 1364 &fall_through, | 1359 Assembler::kNearJump, |
| 1365 Assembler::kNearJump, | 1360 RAX); // Result register. |
| 1366 RAX); // Result register. | |
| 1367 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 1361 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
| 1368 __ ret(); | 1362 __ ret(); |
| 1369 __ Bind(&is_smi); | 1363 __ Bind(&is_smi); |
| 1370 __ SmiUntag(RAX); | 1364 __ SmiUntag(RAX); |
| 1371 __ cvtsi2sd(XMM1, RAX); | 1365 __ cvtsi2sd(XMM1, RAX); |
| 1372 __ jmp(&double_op); | 1366 __ jmp(&double_op); |
| 1373 __ Bind(&fall_through); | 1367 __ Bind(&fall_through); |
| 1374 return false; | 1368 return false; |
| 1375 } | 1369 } |
| 1376 | 1370 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1529 __ ret(); | 1523 __ ret(); |
| 1530 return true; | 1524 return true; |
| 1531 } | 1525 } |
| 1532 | 1526 |
| 1533 | 1527 |
| 1534 #undef __ | 1528 #undef __ |
| 1535 | 1529 |
| 1536 } // namespace dart | 1530 } // namespace dart |
| 1537 | 1531 |
| 1538 #endif // defined TARGET_ARCH_X64 | 1532 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |