| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1380 // R6: points directly to the first ic data array element. | 1380 // R6: points directly to the first ic data array element. |
| 1381 | 1381 |
| 1382 // Get the receiver's class ID (first read number of arguments from | 1382 // Get the receiver's class ID (first read number of arguments from |
| 1383 // arguments descriptor array and then access the receiver from the stack). | 1383 // arguments descriptor array and then access the receiver from the stack). |
| 1384 __ LoadFieldFromOffset(R7, R4, ArgumentsDescriptor::count_offset(), kNoPP); | 1384 __ LoadFieldFromOffset(R7, R4, ArgumentsDescriptor::count_offset(), kNoPP); |
| 1385 __ SmiUntag(R7); // Untag so we can use the LSL 3 addressing mode. | 1385 __ SmiUntag(R7); // Untag so we can use the LSL 3 addressing mode. |
| 1386 __ sub(R7, R7, Operand(1)); | 1386 __ sub(R7, R7, Operand(1)); |
| 1387 | 1387 |
| 1388 // R0 <- [SP + (R7 << 3)] | 1388 // R0 <- [SP + (R7 << 3)] |
| 1389 __ ldr(R0, Address(SP, R7, UXTX, Address::Scaled)); | 1389 __ ldr(R0, Address(SP, R7, UXTX, Address::Scaled)); |
| 1390 | 1390 __ LoadTaggedClassIdMayBeSmi(R0, R0); |
| 1391 { | |
| 1392 // TODO(zra): Put this code in a subroutine call as with other architectures | |
| 1393 // when we have a bl(Label& l) instruction. | |
| 1394 // Instance in R0, return its class-id in R0 as Smi. | |
| 1395 // Test if Smi -> load Smi class for comparison. | |
| 1396 Label not_smi, done; | |
| 1397 __ tsti(R0, kSmiTagMask); | |
| 1398 __ b(¬_smi, NE); | |
| 1399 __ LoadImmediate(R0, Smi::RawValue(kSmiCid), kNoPP); | |
| 1400 __ b(&done); | |
| 1401 | |
| 1402 __ Bind(¬_smi); | |
| 1403 __ LoadClassId(R0, R0, kNoPP); | |
| 1404 __ SmiTag(R0); | |
| 1405 __ Bind(&done); | |
| 1406 } | |
| 1407 | 1391 |
| 1408 // R7: argument_count - 1 (untagged). | 1392 // R7: argument_count - 1 (untagged). |
| 1409 // R0: receiver's class ID (smi). | 1393 // R0: receiver's class ID (smi). |
| 1410 __ ldr(R1, Address(R6)); // First class id (smi) to check. | 1394 __ ldr(R1, Address(R6)); // First class id (smi) to check. |
| 1411 __ b(&test); | 1395 __ b(&test); |
| 1412 | 1396 |
| 1413 __ Bind(&loop); | 1397 __ Bind(&loop); |
| 1414 for (int i = 0; i < num_args; i++) { | 1398 for (int i = 0; i < num_args; i++) { |
| 1415 if (i > 0) { | 1399 if (i > 0) { |
| 1416 // If not the first, load the next argument's class ID. | 1400 // If not the first, load the next argument's class ID. |
| 1417 __ AddImmediate(R0, R7, -i, kNoPP); | 1401 __ AddImmediate(R0, R7, -i, kNoPP); |
| 1418 // R0 <- [SP + (R0 << 3)] | 1402 // R0 <- [SP + (R0 << 3)] |
| 1419 __ ldr(R0, Address(SP, R0, UXTX, Address::Scaled)); | 1403 __ ldr(R0, Address(SP, R0, UXTX, Address::Scaled)); |
| 1420 { | 1404 __ LoadTaggedClassIdMayBeSmi(R0, R0); |
| 1421 // Instance in R0, return its class-id in R0 as Smi. | |
| 1422 // Test if Smi -> load Smi class for comparison. | |
| 1423 Label not_smi, done; | |
| 1424 __ tsti(R0, kSmiTagMask); | |
| 1425 __ b(¬_smi, NE); | |
| 1426 __ LoadImmediate(R0, Smi::RawValue(kSmiCid), kNoPP); | |
| 1427 __ b(&done); | |
| 1428 | |
| 1429 __ Bind(¬_smi); | |
| 1430 __ LoadClassId(R0, R0, kNoPP); | |
| 1431 __ SmiTag(R0); | |
| 1432 __ Bind(&done); | |
| 1433 } | |
| 1434 // R0: next argument class ID (smi). | 1405 // R0: next argument class ID (smi). |
| 1435 __ LoadFromOffset(R1, R6, i * kWordSize, kNoPP); | 1406 __ LoadFromOffset(R1, R6, i * kWordSize, kNoPP); |
| 1436 // R1: next class ID to check (smi). | 1407 // R1: next class ID to check (smi). |
| 1437 } | 1408 } |
| 1438 __ CompareRegisters(R0, R1); // Class id match? | 1409 __ CompareRegisters(R0, R1); // Class id match? |
| 1439 if (i < (num_args - 1)) { | 1410 if (i < (num_args - 1)) { |
| 1440 __ b(&update, NE); // Continue. | 1411 __ b(&update, NE); // Continue. |
| 1441 } else { | 1412 } else { |
| 1442 // Last check, all checks before matched. | 1413 // Last check, all checks before matched. |
| 1443 __ b(&found, EQ); // Break. | 1414 __ b(&found, EQ); // Break. |
| 1444 } | 1415 } |
| 1445 } | 1416 } |
| 1446 __ Bind(&update); | 1417 __ Bind(&update); |
| 1447 // Reload receiver class ID. It has not been destroyed when num_args == 1. | 1418 // Reload receiver class ID. It has not been destroyed when num_args == 1. |
| 1448 if (num_args > 1) { | 1419 if (num_args > 1) { |
| 1449 __ ldr(R0, Address(SP, R7, UXTX, Address::Scaled)); | 1420 __ ldr(R0, Address(SP, R7, UXTX, Address::Scaled)); |
| 1450 { | 1421 __ LoadTaggedClassIdMayBeSmi(R0, R0); |
| 1451 // Instance in R0, return its class-id in R0 as Smi. | |
| 1452 // Test if Smi -> load Smi class for comparison. | |
| 1453 Label not_smi, done; | |
| 1454 __ tsti(R0, kSmiTagMask); | |
| 1455 __ b(¬_smi, NE); | |
| 1456 __ LoadImmediate(R0, Smi::RawValue(kSmiCid), kNoPP); | |
| 1457 __ b(&done); | |
| 1458 | |
| 1459 __ Bind(¬_smi); | |
| 1460 __ LoadClassId(R0, R0, kNoPP); | |
| 1461 __ SmiTag(R0); | |
| 1462 __ Bind(&done); | |
| 1463 } | |
| 1464 } | 1422 } |
| 1465 | 1423 |
| 1466 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; | 1424 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; |
| 1467 __ AddImmediate(R6, R6, entry_size, kNoPP); // Next entry. | 1425 __ AddImmediate(R6, R6, entry_size, kNoPP); // Next entry. |
| 1468 __ ldr(R1, Address(R6)); // Next class ID. | 1426 __ ldr(R1, Address(R6)); // Next class ID. |
| 1469 | 1427 |
| 1470 __ Bind(&test); | 1428 __ Bind(&test); |
| 1471 __ CompareImmediate(R1, Smi::RawValue(kIllegalCid), kNoPP); // Done? | 1429 __ CompareImmediate(R1, Smi::RawValue(kIllegalCid), kNoPP); // Done? |
| 1472 __ b(&loop, NE); | 1430 __ b(&loop, NE); |
| 1473 | 1431 |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1963 const Register right = R0; | 1921 const Register right = R0; |
| 1964 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); | 1922 __ LoadFromOffset(left, SP, 1 * kWordSize, kNoPP); |
| 1965 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); | 1923 __ LoadFromOffset(right, SP, 0 * kWordSize, kNoPP); |
| 1966 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1924 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
| 1967 __ ret(); | 1925 __ ret(); |
| 1968 } | 1926 } |
| 1969 | 1927 |
| 1970 } // namespace dart | 1928 } // namespace dart |
| 1971 | 1929 |
| 1972 #endif // defined TARGET_ARCH_ARM64 | 1930 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |