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 |