Chromium Code Reviews| 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 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 908 | 908 |
| 909 void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) { | 909 void Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) { |
| 910 return CompareIntegers(assembler, GREATER_EQUAL); | 910 return CompareIntegers(assembler, GREATER_EQUAL); |
| 911 } | 911 } |
| 912 | 912 |
| 913 | 913 |
| 914 // This is called for Smi, Mint and Bigint receivers. The right argument | 914 // This is called for Smi, Mint and Bigint receivers. The right argument |
| 915 // can be Smi, Mint, Bigint or double. | 915 // can be Smi, Mint, Bigint or double. |
| 916 void Intrinsifier::Integer_equalToInteger(Assembler* assembler) { | 916 void Intrinsifier::Integer_equalToInteger(Assembler* assembler) { |
| 917 Label fall_through, true_label, check_for_mint; | 917 Label fall_through, true_label, check_for_mint; |
| 918 const intptr_t kReceiverOffset = 2; | |
|
rmacnak
2013/09/18 21:04:24
Perhaps constants like these deserve to be defined
siva
2013/09/19 00:45:37
I prefer leaving the constants in each intrinsic,
| |
| 919 const intptr_t kArgumentOffset = 1; | |
| 920 | |
|
siva
2013/09/19 00:45:37
I think we should also add a comment that these in
| |
| 918 // For integer receiver '===' check first. | 921 // For integer receiver '===' check first. |
| 919 // Entering a dart frame so we can use the PP for loading True and False. | 922 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize)); |
| 920 __ EnterDartFrame(0); | 923 __ movq(RCX, Address(RSP, + kReceiverOffset * kWordSize)); |
| 921 __ movq(RAX, Address(RSP, + 4 * kWordSize)); | |
| 922 __ movq(RCX, Address(RSP, + 5 * kWordSize)); | |
| 923 __ cmpq(RAX, RCX); | 924 __ cmpq(RAX, RCX); |
| 924 __ j(EQUAL, &true_label, Assembler::kNearJump); | 925 __ j(EQUAL, &true_label, Assembler::kNearJump); |
| 925 __ orq(RAX, RCX); | 926 __ orq(RAX, RCX); |
| 926 __ testq(RAX, Immediate(kSmiTagMask)); | 927 __ testq(RAX, Immediate(kSmiTagMask)); |
| 927 __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump); | 928 __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump); |
| 928 // Both arguments are smi, '===' is good enough. | 929 // Both arguments are smi, '===' is good enough. |
| 929 __ LoadObject(RAX, Bool::False(), PP); | 930 __ LoadObject(RAX, Bool::False(), PP); |
| 930 __ LeaveFrameWithPP(); | |
| 931 __ ret(); | 931 __ ret(); |
| 932 __ Bind(&true_label); | 932 __ Bind(&true_label); |
| 933 __ LoadObject(RAX, Bool::True(), PP); | 933 __ LoadObject(RAX, Bool::True(), PP); |
| 934 __ LeaveFrameWithPP(); | |
| 935 __ ret(); | 934 __ ret(); |
| 936 | 935 |
| 937 // At least one of the arguments was not Smi. | 936 // At least one of the arguments was not Smi. |
| 938 Label receiver_not_smi; | 937 Label receiver_not_smi; |
| 939 __ Bind(&check_for_mint); | 938 __ Bind(&check_for_mint); |
| 940 __ movq(RAX, Address(RSP, + 5 * kWordSize)); // Receiver. | 939 __ movq(RAX, Address(RSP, + kReceiverOffset * kWordSize)); |
| 941 __ testq(RAX, Immediate(kSmiTagMask)); | 940 __ testq(RAX, Immediate(kSmiTagMask)); |
| 942 __ j(NOT_ZERO, &receiver_not_smi); | 941 __ j(NOT_ZERO, &receiver_not_smi); |
| 943 | 942 |
| 944 // Left (receiver) is Smi, return false if right is not Double. | 943 // Left (receiver) is Smi, return false if right is not Double. |
| 945 // Note that an instance of Mint or Bigint never contains a value that can be | 944 // Note that an instance of Mint or Bigint never contains a value that can be |
| 946 // represented by Smi. | 945 // represented by Smi. |
| 947 __ movq(RAX, Address(RSP, + 4 * kWordSize)); | 946 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize)); |
| 948 __ CompareClassId(RAX, kDoubleCid); | 947 __ CompareClassId(RAX, kDoubleCid); |
| 949 __ j(EQUAL, &fall_through); | 948 __ j(EQUAL, &fall_through); |
| 950 __ LoadObject(RAX, Bool::False(), PP); | 949 __ LoadObject(RAX, Bool::False(), PP); |
| 951 __ LeaveFrameWithPP(); | |
| 952 __ ret(); | 950 __ ret(); |
| 953 | 951 |
| 954 __ Bind(&receiver_not_smi); | 952 __ Bind(&receiver_not_smi); |
| 955 // RAX:: receiver. | 953 // RAX:: receiver. |
| 956 __ CompareClassId(RAX, kMintCid); | 954 __ CompareClassId(RAX, kMintCid); |
| 957 __ j(NOT_EQUAL, &fall_through); | 955 __ j(NOT_EQUAL, &fall_through); |
| 958 // Receiver is Mint, return false if right is Smi. | 956 // Receiver is Mint, return false if right is Smi. |
| 959 __ movq(RAX, Address(RSP, + 4 * kWordSize)); // Right argument. | 957 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize)); |
| 960 __ testq(RAX, Immediate(kSmiTagMask)); | 958 __ testq(RAX, Immediate(kSmiTagMask)); |
| 961 __ j(NOT_ZERO, &fall_through); | 959 __ j(NOT_ZERO, &fall_through); |
| 962 // Smi == Mint -> false. | 960 // Smi == Mint -> false. |
| 963 __ LoadObject(RAX, Bool::False(), PP); | 961 __ LoadObject(RAX, Bool::False(), PP); |
| 964 __ LeaveFrameWithPP(); | |
| 965 __ ret(); | 962 __ ret(); |
| 966 // TODO(srdjan): Implement Mint == Mint comparison. | 963 // TODO(srdjan): Implement Mint == Mint comparison. |
| 967 | 964 |
| 968 __ Bind(&fall_through); | 965 __ Bind(&fall_through); |
| 969 __ LeaveFrameWithPP(); | |
| 970 } | 966 } |
| 971 | 967 |
| 972 | 968 |
| 973 void Intrinsifier::Integer_equal(Assembler* assembler) { | 969 void Intrinsifier::Integer_equal(Assembler* assembler) { |
| 974 return Integer_equalToInteger(assembler); | 970 return Integer_equalToInteger(assembler); |
| 975 } | 971 } |
| 976 | 972 |
| 977 | 973 |
| 978 void Intrinsifier::Integer_sar(Assembler* assembler) { | 974 void Intrinsifier::Integer_sar(Assembler* assembler) { |
| 979 Label fall_through, shift_count_ok; | 975 Label fall_through, shift_count_ok; |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1344 __ movl(RCX, addr_0); | 1340 __ movl(RCX, addr_0); |
| 1345 __ imulq(RCX, RAX); | 1341 __ imulq(RCX, RAX); |
| 1346 __ movl(RDX, addr_1); | 1342 __ movl(RDX, addr_1); |
| 1347 __ addq(RDX, RCX); | 1343 __ addq(RDX, RCX); |
| 1348 __ movl(addr_0, RDX); | 1344 __ movl(addr_0, RDX); |
| 1349 __ shrq(RDX, Immediate(32)); | 1345 __ shrq(RDX, Immediate(32)); |
| 1350 __ movl(addr_1, RDX); | 1346 __ movl(addr_1, RDX); |
| 1351 __ ret(); | 1347 __ ret(); |
| 1352 } | 1348 } |
| 1353 | 1349 |
| 1354 | |
| 1355 // Identity comparison. | 1350 // Identity comparison. |
| 1356 void Intrinsifier::Object_equal(Assembler* assembler) { | 1351 void Intrinsifier::Object_equal(Assembler* assembler) { |
| 1357 Label is_true; | 1352 Label is_true; |
| 1358 // This intrinsic is used from the API even when we have not entered any | 1353 const intptr_t kReceiverOffset = 2; |
| 1359 // Dart frame, yet, so the PP would otherwise be null in this case unless | 1354 const intptr_t kArgumentOffset = 1; |
| 1360 // we enter a Dart frame here. | 1355 |
| 1361 __ EnterDartFrame(0); | 1356 __ movq(RAX, Address(RSP, + kArgumentOffset * kWordSize)); |
| 1362 __ movq(RAX, Address(RSP, + 4 * kWordSize)); | 1357 __ cmpq(RAX, Address(RSP, + kReceiverOffset * kWordSize)); |
| 1363 __ cmpq(RAX, Address(RSP, + 5 * kWordSize)); | |
| 1364 __ j(EQUAL, &is_true, Assembler::kNearJump); | 1358 __ j(EQUAL, &is_true, Assembler::kNearJump); |
| 1365 __ movq(RAX, Immediate(reinterpret_cast<int64_t>(Bool::False().raw()))); | |
| 1366 __ LoadObject(RAX, Bool::False(), PP); | 1359 __ LoadObject(RAX, Bool::False(), PP); |
| 1367 __ LeaveFrameWithPP(); | |
| 1368 __ ret(); | 1360 __ ret(); |
| 1369 __ Bind(&is_true); | 1361 __ Bind(&is_true); |
| 1370 __ LoadObject(RAX, Bool::True(), PP); | 1362 __ LoadObject(RAX, Bool::True(), PP); |
| 1371 __ LeaveFrameWithPP(); | |
| 1372 __ ret(); | 1363 __ ret(); |
| 1373 } | 1364 } |
| 1374 | 1365 |
| 1375 | 1366 |
| 1376 void Intrinsifier::String_getHashCode(Assembler* assembler) { | 1367 void Intrinsifier::String_getHashCode(Assembler* assembler) { |
| 1377 Label fall_through; | 1368 Label fall_through; |
| 1378 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object. | 1369 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object. |
| 1379 __ movq(RAX, FieldAddress(RAX, String::hash_offset())); | 1370 __ movq(RAX, FieldAddress(RAX, String::hash_offset())); |
| 1380 __ cmpq(RAX, Immediate(0)); | 1371 __ cmpq(RAX, Immediate(0)); |
| 1381 __ j(EQUAL, &fall_through, Assembler::kNearJump); | 1372 __ j(EQUAL, &fall_through, Assembler::kNearJump); |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1649 | 1640 |
| 1650 __ Bind(&fall_through); | 1641 __ Bind(&fall_through); |
| 1651 } | 1642 } |
| 1652 | 1643 |
| 1653 | 1644 |
| 1654 #undef __ | 1645 #undef __ |
| 1655 | 1646 |
| 1656 } // namespace dart | 1647 } // namespace dart |
| 1657 | 1648 |
| 1658 #endif // defined TARGET_ARCH_X64 | 1649 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |