Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1367)

Side by Side Diff: runtime/vm/simulator_arm64.cc

Issue 264943007: Adds double load and store to arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/disassembler_arm64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/disassembler_arm64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698