| 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 <math.h> // for isnan. | 5 #include <math.h> // for isnan. |
| 6 #include <setjmp.h> | 6 #include <setjmp.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
| 10 #if defined(TARGET_ARCH_ARM64) | 10 #if defined(TARGET_ARCH_ARM64) |
| (...skipping 1383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1394 DecodeUnconditionalBranch(instr); | 1394 DecodeUnconditionalBranch(instr); |
| 1395 } else if (instr->IsUnconditionalBranchRegOp()) { | 1395 } else if (instr->IsUnconditionalBranchRegOp()) { |
| 1396 DecodeUnconditionalBranchReg(instr); | 1396 DecodeUnconditionalBranchReg(instr); |
| 1397 } else { | 1397 } else { |
| 1398 UnimplementedInstruction(instr); | 1398 UnimplementedInstruction(instr); |
| 1399 } | 1399 } |
| 1400 } | 1400 } |
| 1401 | 1401 |
| 1402 | 1402 |
| 1403 void Simulator::DecodeLoadStoreReg(Instr* instr) { | 1403 void Simulator::DecodeLoadStoreReg(Instr* instr) { |
| 1404 // TODO(zra): SIMD loads and stores have bit 26 (V) set. | |
| 1405 // (bit 25 is never set for loads and stores). | |
| 1406 if (instr->Bits(25, 2) != 0) { | |
| 1407 UnimplementedInstruction(instr); | |
| 1408 return; | |
| 1409 } | |
| 1410 | |
| 1411 // Calculate the address. | 1404 // Calculate the address. |
| 1412 const Register rn = instr->RnField(); | 1405 const Register rn = instr->RnField(); |
| 1413 const Register rt = instr->RtField(); | 1406 const Register rt = instr->RtField(); |
| 1407 const VRegister vt = instr->VtField(); |
| 1414 const int64_t rn_val = get_register(rn, R31IsSP); | 1408 const int64_t rn_val = get_register(rn, R31IsSP); |
| 1415 const uint32_t size = instr->SzField(); | 1409 const uint32_t size = instr->SzField(); |
| 1416 uword address = 0; | 1410 uword address = 0; |
| 1417 uword wb_address = 0; | 1411 uword wb_address = 0; |
| 1418 bool wb = false; | 1412 bool wb = false; |
| 1419 if (instr->Bit(24) == 1) { | 1413 if (instr->Bit(24) == 1) { |
| 1420 // addr = rn + scaled unsigned 12-bit immediate offset. | 1414 // addr = rn + scaled unsigned 12-bit immediate offset. |
| 1421 const uint32_t imm12 = static_cast<uint32_t>(instr->Imm12Field()); | 1415 const uint32_t imm12 = static_cast<uint32_t>(instr->Imm12Field()); |
| 1422 const uint32_t offset = imm12 << size; | 1416 const uint32_t offset = imm12 << size; |
| 1423 address = rn_val + offset; | 1417 address = rn_val + offset; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1444 // addr = rn + (rm EXT optionally scaled by operand instruction size). | 1438 // addr = rn + (rm EXT optionally scaled by operand instruction size). |
| 1445 const Register rm = instr->RmField(); | 1439 const Register rm = instr->RmField(); |
| 1446 const Extend ext = instr->ExtendTypeField(); | 1440 const Extend ext = instr->ExtendTypeField(); |
| 1447 const uint8_t scale = | 1441 const uint8_t scale = |
| 1448 (ext == UXTX) && (instr->Bit(12) == 1) ? size : 0; | 1442 (ext == UXTX) && (instr->Bit(12) == 1) ? size : 0; |
| 1449 const int64_t rm_val = get_register(rm, R31IsZR); | 1443 const int64_t rm_val = get_register(rm, R31IsZR); |
| 1450 const int64_t offset = ExtendOperand(kXRegSizeInBits, rm_val, ext, scale); | 1444 const int64_t offset = ExtendOperand(kXRegSizeInBits, rm_val, ext, scale); |
| 1451 address = rn_val + offset; | 1445 address = rn_val + offset; |
| 1452 } else { | 1446 } else { |
| 1453 UnimplementedInstruction(instr); | 1447 UnimplementedInstruction(instr); |
| 1448 return; |
| 1454 } | 1449 } |
| 1455 | 1450 |
| 1456 // Check the address. | 1451 // Check the address. |
| 1457 if (IsIllegalAddress(address)) { | 1452 if (IsIllegalAddress(address)) { |
| 1458 HandleIllegalAccess(address, instr); | 1453 HandleIllegalAccess(address, instr); |
| 1459 return; | 1454 return; |
| 1460 } | 1455 } |
| 1461 | 1456 |
| 1462 // Do access. | 1457 // Do access. |
| 1463 if (instr->Bits(22, 2) == 0) { | 1458 if (instr->Bits(22, 2) == 0) { |
| 1464 // Format(instr, "str'sz 'rt, 'memop"); | 1459 if (instr->Bit(26) == 1) { |
| 1465 int32_t rt_val32 = get_wregister(rt, R31IsZR); | 1460 // Format(instr, "vstrd 'vt, 'memop"); |
| 1466 switch (size) { | 1461 if (size != 3) { |
| 1467 case 0: { | 1462 UnimplementedInstruction(instr); |
| 1468 uint8_t val = static_cast<uint8_t>(rt_val32); | 1463 return; |
| 1469 WriteB(address, val); | |
| 1470 break; | |
| 1471 } | 1464 } |
| 1472 case 1: { | 1465 const int64_t vt_val = get_vregisterd(vt); |
| 1473 uint16_t val = static_cast<uint16_t>(rt_val32); | 1466 WriteX(address, vt_val, instr); |
| 1474 WriteH(address, val, instr); | 1467 } else { |
| 1475 break; | 1468 // Format(instr, "str'sz 'rt, 'memop"); |
| 1469 const int32_t rt_val32 = get_wregister(rt, R31IsZR); |
| 1470 switch (size) { |
| 1471 case 0: { |
| 1472 const uint8_t val = static_cast<uint8_t>(rt_val32); |
| 1473 WriteB(address, val); |
| 1474 break; |
| 1475 } |
| 1476 case 1: { |
| 1477 const uint16_t val = static_cast<uint16_t>(rt_val32); |
| 1478 WriteH(address, val, instr); |
| 1479 break; |
| 1480 } |
| 1481 case 2: { |
| 1482 const uint32_t val = static_cast<uint32_t>(rt_val32); |
| 1483 WriteW(address, val, instr); |
| 1484 break; |
| 1485 } |
| 1486 case 3: { |
| 1487 const int64_t val = get_register(rt, R31IsZR); |
| 1488 WriteX(address, val, instr); |
| 1489 break; |
| 1490 } |
| 1491 default: |
| 1492 UNREACHABLE(); |
| 1493 break; |
| 1476 } | 1494 } |
| 1477 case 2: { | |
| 1478 uint32_t val = static_cast<uint32_t>(rt_val32); | |
| 1479 WriteW(address, val, instr); | |
| 1480 break; | |
| 1481 } | |
| 1482 case 3: { | |
| 1483 int64_t val = get_register(rt, R31IsZR); | |
| 1484 WriteX(address, val, instr); | |
| 1485 break; | |
| 1486 } | |
| 1487 default: | |
| 1488 UNREACHABLE(); | |
| 1489 break; | |
| 1490 } | 1495 } |
| 1491 } else { | 1496 } else { |
| 1492 // Format(instr, "ldr'sz 'rt, 'memop"); | 1497 if (instr->Bit(26) == 1) { |
| 1493 // Undefined case. | 1498 // Format(instr, "ldrd 'vt, 'memop"); |
| 1494 if ((size == 3) && (instr->Bits(22, 0) == 3)) { | 1499 if ((size != 3) || (instr->Bit(23) != 0)) { |
| 1495 UnimplementedInstruction(instr); | 1500 UnimplementedInstruction(instr); |
| 1496 return; | 1501 return; |
| 1497 } | 1502 } |
| 1503 const int64_t val = ReadX(address, instr); |
| 1504 set_vregisterd(vt, val); |
| 1505 } else { |
| 1506 // Format(instr, "ldr'sz 'rt, 'memop"); |
| 1507 // Undefined case. |
| 1508 if ((size == 3) && (instr->Bits(22, 2) == 3)) { |
| 1509 UnimplementedInstruction(instr); |
| 1510 return; |
| 1511 } |
| 1498 | 1512 |
| 1499 // Read the value. | 1513 // Read the value. |
| 1500 const bool signd = instr->Bit(23) == 1; | 1514 const bool signd = instr->Bit(23) == 1; |
| 1501 // Write the W register for signed values when size < 2. | 1515 // Write the W register for signed values when size < 2. |
| 1502 // Write the W register for unsigned values when size == 2. | 1516 // Write the W register for unsigned values when size == 2. |
| 1503 const bool use_w = | 1517 const bool use_w = |
| 1504 (signd && (instr->Bit(22) == 1)) || (!signd && (size == 2)); | 1518 (signd && (instr->Bit(22) == 1)) || (!signd && (size == 2)); |
| 1505 int64_t val = 0; // Sign extend into an int64_t. | 1519 int64_t val = 0; // Sign extend into an int64_t. |
| 1506 switch (size) { | 1520 switch (size) { |
| 1507 case 0: { | 1521 case 0: { |
| 1508 if (signd) { | 1522 if (signd) { |
| 1509 val = static_cast<int64_t>(ReadB(address)); | 1523 val = static_cast<int64_t>(ReadB(address)); |
| 1510 } else { | 1524 } else { |
| 1511 val = static_cast<int64_t>(ReadBU(address)); | 1525 val = static_cast<int64_t>(ReadBU(address)); |
| 1526 } |
| 1527 break; |
| 1512 } | 1528 } |
| 1513 break; | 1529 case 1: { |
| 1530 if (signd) { |
| 1531 val = static_cast<int64_t>(ReadH(address, instr)); |
| 1532 } else { |
| 1533 val = static_cast<int64_t>(ReadHU(address, instr)); |
| 1534 } |
| 1535 break; |
| 1536 } |
| 1537 case 2: { |
| 1538 if (signd) { |
| 1539 val = static_cast<int64_t>(ReadW(address, instr)); |
| 1540 } else { |
| 1541 val = static_cast<int64_t>(ReadWU(address, instr)); |
| 1542 } |
| 1543 break; |
| 1544 } |
| 1545 case 3: |
| 1546 val = ReadX(address, instr); |
| 1547 break; |
| 1548 default: |
| 1549 UNREACHABLE(); |
| 1550 break; |
| 1514 } | 1551 } |
| 1515 case 1: { | 1552 |
| 1516 if (signd) { | 1553 // Write to register. |
| 1517 val = static_cast<int64_t>(ReadH(address, instr)); | 1554 if (use_w) { |
| 1518 } else { | 1555 set_wregister(rt, static_cast<int32_t>(val), R31IsZR); |
| 1519 val = static_cast<int64_t>(ReadHU(address, instr)); | 1556 } else { |
| 1520 } | 1557 set_register(rt, val, R31IsZR); |
| 1521 break; | |
| 1522 } | 1558 } |
| 1523 case 2: { | |
| 1524 if (signd) { | |
| 1525 val = static_cast<int64_t>(ReadW(address, instr)); | |
| 1526 } else { | |
| 1527 val = static_cast<int64_t>(ReadWU(address, instr)); | |
| 1528 } | |
| 1529 break; | |
| 1530 } | |
| 1531 case 3: | |
| 1532 val = ReadX(address, instr); | |
| 1533 break; | |
| 1534 default: | |
| 1535 UNREACHABLE(); | |
| 1536 break; | |
| 1537 } | |
| 1538 | |
| 1539 // Write to register. | |
| 1540 if (use_w) { | |
| 1541 set_wregister(rt, static_cast<int32_t>(val), R31IsZR); | |
| 1542 } else { | |
| 1543 set_register(rt, val, R31IsZR); | |
| 1544 } | 1559 } |
| 1545 } | 1560 } |
| 1546 | 1561 |
| 1547 // Do writeback. | 1562 // Do writeback. |
| 1548 if (wb) { | 1563 if (wb) { |
| 1549 set_register(rn, wb_address, R31IsSP); | 1564 set_register(rn, wb_address, R31IsSP); |
| 1550 } | 1565 } |
| 1551 } | 1566 } |
| 1552 | 1567 |
| 1553 | 1568 |
| (...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2228 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); | 2243 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); |
| 2229 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); | 2244 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); |
| 2230 buf->Longjmp(); | 2245 buf->Longjmp(); |
| 2231 } | 2246 } |
| 2232 | 2247 |
| 2233 } // namespace dart | 2248 } // namespace dart |
| 2234 | 2249 |
| 2235 #endif // !defined(HOST_ARCH_ARM64) | 2250 #endif // !defined(HOST_ARCH_ARM64) |
| 2236 | 2251 |
| 2237 #endif // defined TARGET_ARCH_ARM64 | 2252 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |