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" |
(...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1288 | 1288 |
1289 | 1289 |
1290 void Intrinsifier::Double_lessEqualThan(Assembler* assembler) { | 1290 void Intrinsifier::Double_lessEqualThan(Assembler* assembler) { |
1291 CompareDoubles(assembler, BELOW_EQUAL); | 1291 CompareDoubles(assembler, BELOW_EQUAL); |
1292 } | 1292 } |
1293 | 1293 |
1294 | 1294 |
1295 // Expects left argument to be double (receiver). Right argument is unknown. | 1295 // Expects left argument to be double (receiver). Right argument is unknown. |
1296 // Both arguments are on stack. | 1296 // Both arguments are on stack. |
1297 static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { | 1297 static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { |
1298 Label fall_through; | 1298 Label fall_through, is_smi, double_op; |
1299 TestLastArgumentIsDouble(assembler, &fall_through, &fall_through); | 1299 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); |
1300 // Both arguments are double, right operand is in RAX. | 1300 // Both arguments are double, right operand is in RAX. |
1301 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); | 1301 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); |
| 1302 __ Bind(&double_op); |
1302 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Left argument. | 1303 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Left argument. |
1303 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); | 1304 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); |
1304 switch (kind) { | 1305 switch (kind) { |
1305 case Token::kADD: __ addsd(XMM0, XMM1); break; | 1306 case Token::kADD: __ addsd(XMM0, XMM1); break; |
1306 case Token::kSUB: __ subsd(XMM0, XMM1); break; | 1307 case Token::kSUB: __ subsd(XMM0, XMM1); break; |
1307 case Token::kMUL: __ mulsd(XMM0, XMM1); break; | 1308 case Token::kMUL: __ mulsd(XMM0, XMM1); break; |
1308 case Token::kDIV: __ divsd(XMM0, XMM1); break; | 1309 case Token::kDIV: __ divsd(XMM0, XMM1); break; |
1309 default: UNREACHABLE(); | 1310 default: UNREACHABLE(); |
1310 } | 1311 } |
1311 const Class& double_class = Class::Handle( | 1312 const Class& double_class = Class::Handle( |
1312 Isolate::Current()->object_store()->double_class()); | 1313 Isolate::Current()->object_store()->double_class()); |
1313 __ TryAllocate(double_class, | 1314 __ TryAllocate(double_class, |
1314 &fall_through, | 1315 &fall_through, |
1315 Assembler::kFarJump, | 1316 Assembler::kFarJump, |
1316 RAX, // Result register. | 1317 RAX, // Result register. |
1317 R13); | 1318 R13); |
1318 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); | 1319 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); |
1319 __ ret(); | 1320 __ ret(); |
| 1321 __ Bind(&is_smi); |
| 1322 __ SmiUntag(RAX); |
| 1323 __ cvtsi2sdq(XMM1, RAX); |
| 1324 __ jmp(&double_op); |
1320 __ Bind(&fall_through); | 1325 __ Bind(&fall_through); |
1321 } | 1326 } |
1322 | 1327 |
1323 | 1328 |
1324 void Intrinsifier::Double_add(Assembler* assembler) { | 1329 void Intrinsifier::Double_add(Assembler* assembler) { |
1325 DoubleArithmeticOperations(assembler, Token::kADD); | 1330 DoubleArithmeticOperations(assembler, Token::kADD); |
1326 } | 1331 } |
1327 | 1332 |
1328 | 1333 |
1329 void Intrinsifier::Double_mul(Assembler* assembler) { | 1334 void Intrinsifier::Double_mul(Assembler* assembler) { |
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2100 __ LoadIsolate(RAX); | 2105 __ LoadIsolate(RAX); |
2101 __ movq(RAX, Address(RAX, Isolate::current_tag_offset())); | 2106 __ movq(RAX, Address(RAX, Isolate::current_tag_offset())); |
2102 __ ret(); | 2107 __ ret(); |
2103 } | 2108 } |
2104 | 2109 |
2105 #undef __ | 2110 #undef __ |
2106 | 2111 |
2107 } // namespace dart | 2112 } // namespace dart |
2108 | 2113 |
2109 #endif // defined TARGET_ARCH_X64 | 2114 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |