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 // 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 1423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1434 | 1434 |
1435 // arg0 is Double, arg1 is unknown. | 1435 // arg0 is Double, arg1 is unknown. |
1436 void Intrinsifier::Double_lessEqualThan(Assembler* assembler) { | 1436 void Intrinsifier::Double_lessEqualThan(Assembler* assembler) { |
1437 CompareDoubles(assembler, BELOW_EQUAL); | 1437 CompareDoubles(assembler, BELOW_EQUAL); |
1438 } | 1438 } |
1439 | 1439 |
1440 | 1440 |
1441 // Expects left argument to be double (receiver). Right argument is unknown. | 1441 // Expects left argument to be double (receiver). Right argument is unknown. |
1442 // Both arguments are on stack. | 1442 // Both arguments are on stack. |
1443 static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { | 1443 static void DoubleArithmeticOperations(Assembler* assembler, Token::Kind kind) { |
1444 Label fall_through; | 1444 Label fall_through, is_smi, double_op; |
1445 TestLastArgumentIsDouble(assembler, &fall_through, &fall_through); | 1445 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); |
1446 // Both arguments are double, right operand is in EAX. | 1446 // Both arguments are double, right operand is in EAX. |
1447 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); | 1447 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); |
| 1448 __ Bind(&double_op); |
1448 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left argument. | 1449 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left argument. |
1449 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); | 1450 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); |
1450 switch (kind) { | 1451 switch (kind) { |
1451 case Token::kADD: __ addsd(XMM0, XMM1); break; | 1452 case Token::kADD: __ addsd(XMM0, XMM1); break; |
1452 case Token::kSUB: __ subsd(XMM0, XMM1); break; | 1453 case Token::kSUB: __ subsd(XMM0, XMM1); break; |
1453 case Token::kMUL: __ mulsd(XMM0, XMM1); break; | 1454 case Token::kMUL: __ mulsd(XMM0, XMM1); break; |
1454 case Token::kDIV: __ divsd(XMM0, XMM1); break; | 1455 case Token::kDIV: __ divsd(XMM0, XMM1); break; |
1455 default: UNREACHABLE(); | 1456 default: UNREACHABLE(); |
1456 } | 1457 } |
1457 const Class& double_class = Class::Handle( | 1458 const Class& double_class = Class::Handle( |
1458 Isolate::Current()->object_store()->double_class()); | 1459 Isolate::Current()->object_store()->double_class()); |
1459 __ TryAllocate(double_class, | 1460 __ TryAllocate(double_class, |
1460 &fall_through, | 1461 &fall_through, |
1461 Assembler::kNearJump, | 1462 Assembler::kNearJump, |
1462 EAX, // Result register. | 1463 EAX, // Result register. |
1463 EBX); | 1464 EBX); |
1464 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 1465 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
1465 __ ret(); | 1466 __ ret(); |
| 1467 __ Bind(&is_smi); |
| 1468 __ SmiUntag(EAX); |
| 1469 __ cvtsi2sd(XMM1, EAX); |
| 1470 __ jmp(&double_op); |
1466 __ Bind(&fall_through); | 1471 __ Bind(&fall_through); |
1467 } | 1472 } |
1468 | 1473 |
1469 | 1474 |
1470 void Intrinsifier::Double_add(Assembler* assembler) { | 1475 void Intrinsifier::Double_add(Assembler* assembler) { |
1471 DoubleArithmeticOperations(assembler, Token::kADD); | 1476 DoubleArithmeticOperations(assembler, Token::kADD); |
1472 } | 1477 } |
1473 | 1478 |
1474 | 1479 |
1475 void Intrinsifier::Double_mul(Assembler* assembler) { | 1480 void Intrinsifier::Double_mul(Assembler* assembler) { |
(...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2142 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { | 2147 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { |
2143 __ LoadIsolate(EAX); | 2148 __ LoadIsolate(EAX); |
2144 __ movl(EAX, Address(EAX, Isolate::current_tag_offset())); | 2149 __ movl(EAX, Address(EAX, Isolate::current_tag_offset())); |
2145 __ ret(); | 2150 __ ret(); |
2146 } | 2151 } |
2147 | 2152 |
2148 #undef __ | 2153 #undef __ |
2149 } // namespace dart | 2154 } // namespace dart |
2150 | 2155 |
2151 #endif // defined TARGET_ARCH_IA32 | 2156 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |