| 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 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 int32_t Simulator::get_wregister(Register reg, R31Type r31t) const { | 609 int32_t Simulator::get_wregister(Register reg, R31Type r31t) const { |
| 610 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); | 610 ASSERT((reg >= 0) && (reg < kNumberOfCpuRegisters)); |
| 611 if ((reg == R31) && (r31t == R31IsZR)) { | 611 if ((reg == R31) && (r31t == R31IsZR)) { |
| 612 return 0; | 612 return 0; |
| 613 } else { | 613 } else { |
| 614 return registers_[reg]; | 614 return registers_[reg]; |
| 615 } | 615 } |
| 616 } | 616 } |
| 617 | 617 |
| 618 | 618 |
| 619 int64_t Simulator::get_vregisterd(VRegister reg) { | 619 int64_t Simulator::get_vregisterd(VRegister reg) const { |
| 620 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); | 620 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); |
| 621 return vregisters_[reg].lo; | 621 return vregisters_[reg].lo; |
| 622 } | 622 } |
| 623 | 623 |
| 624 | 624 |
| 625 void Simulator::set_vregisterd(VRegister reg, int64_t value) { | 625 void Simulator::set_vregisterd(VRegister reg, int64_t value) { |
| 626 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); | 626 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); |
| 627 vregisters_[reg].lo = value; | 627 vregisters_[reg].lo = value; |
| 628 vregisters_[reg].hi = 0; | 628 vregisters_[reg].hi = 0; |
| 629 } | 629 } |
| 630 | 630 |
| 631 | 631 |
| 632 void Simulator::get_vregister(VRegister reg, simd_value_t* value) const { |
| 633 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); |
| 634 value->lo = vregisters_[reg].lo; |
| 635 value->hi = vregisters_[reg].hi; |
| 636 } |
| 637 |
| 638 |
| 639 void Simulator::set_vregister(VRegister reg, const simd_value_t& value) { |
| 640 ASSERT((reg >= 0) && (reg < kNumberOfVRegisters)); |
| 641 vregisters_[reg].lo = value.lo; |
| 642 vregisters_[reg].hi = value.hi; |
| 643 } |
| 644 |
| 645 |
| 632 // Raw access to the PC register. | 646 // Raw access to the PC register. |
| 633 void Simulator::set_pc(int64_t value) { | 647 void Simulator::set_pc(int64_t value) { |
| 634 pc_modified_ = true; | 648 pc_modified_ = true; |
| 635 last_pc_ = pc_; | 649 last_pc_ = pc_; |
| 636 pc_ = value; | 650 pc_ = value; |
| 637 } | 651 } |
| 638 | 652 |
| 639 | 653 |
| 640 // Raw access to the pc. | 654 // Raw access to the pc. |
| 641 int64_t Simulator::get_pc() const { | 655 int64_t Simulator::get_pc() const { |
| (...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1402 } | 1416 } |
| 1403 } | 1417 } |
| 1404 | 1418 |
| 1405 | 1419 |
| 1406 void Simulator::DecodeLoadStoreReg(Instr* instr) { | 1420 void Simulator::DecodeLoadStoreReg(Instr* instr) { |
| 1407 // Calculate the address. | 1421 // Calculate the address. |
| 1408 const Register rn = instr->RnField(); | 1422 const Register rn = instr->RnField(); |
| 1409 const Register rt = instr->RtField(); | 1423 const Register rt = instr->RtField(); |
| 1410 const VRegister vt = instr->VtField(); | 1424 const VRegister vt = instr->VtField(); |
| 1411 const int64_t rn_val = get_register(rn, R31IsSP); | 1425 const int64_t rn_val = get_register(rn, R31IsSP); |
| 1412 const uint32_t size = instr->SzField(); | 1426 const uint32_t size = |
| 1427 (instr->Bit(26) == 1) ? ((instr->Bit(23) << 2) | instr->SzField()) |
| 1428 : instr->SzField(); |
| 1413 uword address = 0; | 1429 uword address = 0; |
| 1414 uword wb_address = 0; | 1430 uword wb_address = 0; |
| 1415 bool wb = false; | 1431 bool wb = false; |
| 1416 if (instr->Bit(24) == 1) { | 1432 if (instr->Bit(24) == 1) { |
| 1417 // addr = rn + scaled unsigned 12-bit immediate offset. | 1433 // addr = rn + scaled unsigned 12-bit immediate offset. |
| 1418 const uint32_t imm12 = static_cast<uint32_t>(instr->Imm12Field()); | 1434 const uint32_t imm12 = static_cast<uint32_t>(instr->Imm12Field()); |
| 1419 const uint32_t offset = imm12 << size; | 1435 const uint32_t offset = imm12 << size; |
| 1420 address = rn_val + offset; | 1436 address = rn_val + offset; |
| 1421 } else if (instr->Bits(10, 2) == 0) { | 1437 } else if (instr->Bits(10, 2) == 0) { |
| 1422 // addr = rn + signed 9-bit immediate offset. | 1438 // addr = rn + signed 9-bit immediate offset. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1451 return; | 1467 return; |
| 1452 } | 1468 } |
| 1453 | 1469 |
| 1454 // Check the address. | 1470 // Check the address. |
| 1455 if (IsIllegalAddress(address)) { | 1471 if (IsIllegalAddress(address)) { |
| 1456 HandleIllegalAccess(address, instr); | 1472 HandleIllegalAccess(address, instr); |
| 1457 return; | 1473 return; |
| 1458 } | 1474 } |
| 1459 | 1475 |
| 1460 // Do access. | 1476 // Do access. |
| 1461 if (instr->Bits(22, 2) == 0) { | 1477 if (instr->Bit(26) == 1) { |
| 1462 if (instr->Bit(26) == 1) { | 1478 if (instr->Bit(22) == 0) { |
| 1463 // Format(instr, "vstrd 'vt, 'memop"); | 1479 // Format(instr, "fstr'fsz 'vt, 'memop"); |
| 1464 if (size != 3) { | 1480 const int64_t vt_val = get_vregisterd(vt); |
| 1465 UnimplementedInstruction(instr); | 1481 switch (size) { |
| 1466 return; | 1482 case 2: |
| 1483 WriteW(address, vt_val & kWRegMask, instr); |
| 1484 break; |
| 1485 case 3: |
| 1486 WriteX(address, vt_val, instr); |
| 1487 break; |
| 1488 case 4: { |
| 1489 simd_value_t val; |
| 1490 get_vregister(vt, &val); |
| 1491 WriteX(address, val.lo, instr); |
| 1492 WriteX(address + kWordSize, val.hi, instr); |
| 1493 break; |
| 1494 } |
| 1495 default: |
| 1496 UnimplementedInstruction(instr); |
| 1497 return; |
| 1467 } | 1498 } |
| 1468 const int64_t vt_val = get_vregisterd(vt); | |
| 1469 WriteX(address, vt_val, instr); | |
| 1470 } else { | 1499 } else { |
| 1500 // Format(instr, "fldr'fsz 'vt, 'memop"); |
| 1501 switch (size) { |
| 1502 case 2: |
| 1503 set_vregisterd(vt, static_cast<int64_t>(ReadWU(address, instr))); |
| 1504 break; |
| 1505 case 3: |
| 1506 set_vregisterd(vt, ReadX(address, instr)); |
| 1507 break; |
| 1508 case 4: { |
| 1509 simd_value_t val; |
| 1510 val.lo = ReadX(address, instr); |
| 1511 val.hi = ReadX(address + kWordSize, instr); |
| 1512 set_vregister(vt, val); |
| 1513 break; |
| 1514 } |
| 1515 default: |
| 1516 UnimplementedInstruction(instr); |
| 1517 return; |
| 1518 } |
| 1519 } |
| 1520 } else { |
| 1521 if (instr->Bits(22, 2) == 0) { |
| 1471 // Format(instr, "str'sz 'rt, 'memop"); | 1522 // Format(instr, "str'sz 'rt, 'memop"); |
| 1472 const int32_t rt_val32 = get_wregister(rt, R31IsZR); | 1523 const int32_t rt_val32 = get_wregister(rt, R31IsZR); |
| 1473 switch (size) { | 1524 switch (size) { |
| 1474 case 0: { | 1525 case 0: { |
| 1475 const uint8_t val = static_cast<uint8_t>(rt_val32); | 1526 const uint8_t val = static_cast<uint8_t>(rt_val32); |
| 1476 WriteB(address, val); | 1527 WriteB(address, val); |
| 1477 break; | 1528 break; |
| 1478 } | 1529 } |
| 1479 case 1: { | 1530 case 1: { |
| 1480 const uint16_t val = static_cast<uint16_t>(rt_val32); | 1531 const uint16_t val = static_cast<uint16_t>(rt_val32); |
| 1481 WriteH(address, val, instr); | 1532 WriteH(address, val, instr); |
| 1482 break; | 1533 break; |
| 1483 } | 1534 } |
| 1484 case 2: { | 1535 case 2: { |
| 1485 const uint32_t val = static_cast<uint32_t>(rt_val32); | 1536 const uint32_t val = static_cast<uint32_t>(rt_val32); |
| 1486 WriteW(address, val, instr); | 1537 WriteW(address, val, instr); |
| 1487 break; | 1538 break; |
| 1488 } | 1539 } |
| 1489 case 3: { | 1540 case 3: { |
| 1490 const int64_t val = get_register(rt, R31IsZR); | 1541 const int64_t val = get_register(rt, R31IsZR); |
| 1491 WriteX(address, val, instr); | 1542 WriteX(address, val, instr); |
| 1492 break; | 1543 break; |
| 1493 } | 1544 } |
| 1494 default: | 1545 default: |
| 1495 UNREACHABLE(); | 1546 UNREACHABLE(); |
| 1496 break; | 1547 break; |
| 1497 } | 1548 } |
| 1498 } | |
| 1499 } else { | |
| 1500 if (instr->Bit(26) == 1) { | |
| 1501 // Format(instr, "ldrd 'vt, 'memop"); | |
| 1502 if ((size != 3) || (instr->Bit(23) != 0)) { | |
| 1503 UnimplementedInstruction(instr); | |
| 1504 return; | |
| 1505 } | |
| 1506 const int64_t val = ReadX(address, instr); | |
| 1507 set_vregisterd(vt, val); | |
| 1508 } else { | 1549 } else { |
| 1509 // Format(instr, "ldr'sz 'rt, 'memop"); | 1550 // Format(instr, "ldr'sz 'rt, 'memop"); |
| 1510 // Undefined case. | 1551 // Undefined case. |
| 1511 if ((size == 3) && (instr->Bits(22, 2) == 3)) { | 1552 if ((size == 3) && (instr->Bits(22, 2) == 3)) { |
| 1512 UnimplementedInstruction(instr); | 1553 UnimplementedInstruction(instr); |
| 1513 return; | 1554 return; |
| 1514 } | 1555 } |
| 1515 | 1556 |
| 1516 // Read the value. | 1557 // Read the value. |
| 1517 const bool signd = instr->Bit(23) == 1; | 1558 const bool signd = instr->Bit(23) == 1; |
| (...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2078 // Format(instr, "fcvtzds 'rd, 'vn"); | 2119 // Format(instr, "fcvtzds 'rd, 'vn"); |
| 2079 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn)); | 2120 const double vn_val = bit_cast<double, int64_t>(get_vregisterd(vn)); |
| 2080 set_register(rd, static_cast<int64_t>(vn_val), instr->RdMode()); | 2121 set_register(rd, static_cast<int64_t>(vn_val), instr->RdMode()); |
| 2081 } else { | 2122 } else { |
| 2082 UnimplementedInstruction(instr); | 2123 UnimplementedInstruction(instr); |
| 2083 } | 2124 } |
| 2084 } | 2125 } |
| 2085 | 2126 |
| 2086 | 2127 |
| 2087 void Simulator::DecodeFPOneSource(Instr* instr) { | 2128 void Simulator::DecodeFPOneSource(Instr* instr) { |
| 2088 const int opc = instr->Bits(15, 2); | 2129 const int opc = instr->Bits(15, 6); |
| 2089 const VRegister vd = instr->VdField(); | 2130 const VRegister vd = instr->VdField(); |
| 2090 const VRegister vn = instr->VnField(); | 2131 const VRegister vn = instr->VnField(); |
| 2091 const int64_t vn_val = get_vregisterd(vn); | 2132 const int64_t vn_val = get_vregisterd(vn); |
| 2133 const int32_t vn_val32 = vn_val & kWRegMask; |
| 2092 const double vn_dbl = bit_cast<double, int64_t>(vn_val); | 2134 const double vn_dbl = bit_cast<double, int64_t>(vn_val); |
| 2135 const float vn_flt = bit_cast<float, int32_t>(vn_val32); |
| 2136 |
| 2137 if ((opc != 5) && (instr->Bit(22) != 1)) { |
| 2138 // Source is interpreted as single-precision only if we're doing a |
| 2139 // conversion from single -> double. |
| 2140 UnimplementedInstruction(instr); |
| 2141 return; |
| 2142 } |
| 2093 | 2143 |
| 2094 int64_t res_val = 0; | 2144 int64_t res_val = 0; |
| 2095 switch (opc) { | 2145 switch (opc) { |
| 2096 case 0: | 2146 case 0: |
| 2097 // Format("fmovdd 'vd, 'vn"); | 2147 // Format("fmovdd 'vd, 'vn"); |
| 2098 res_val = get_vregisterd(vn); | 2148 res_val = get_vregisterd(vn); |
| 2099 break; | 2149 break; |
| 2100 case 1: | 2150 case 1: |
| 2101 // Format("fabsd 'vd, 'vn"); | 2151 // Format("fabsd 'vd, 'vn"); |
| 2102 res_val = bit_cast<int64_t, double>(fabs(vn_dbl)); | 2152 res_val = bit_cast<int64_t, double>(fabs(vn_dbl)); |
| 2103 break; | 2153 break; |
| 2104 case 2: | 2154 case 2: |
| 2105 // Format("fnegd 'vd, 'vn"); | 2155 // Format("fnegd 'vd, 'vn"); |
| 2106 res_val = bit_cast<int64_t, double>(-vn_dbl); | 2156 res_val = bit_cast<int64_t, double>(-vn_dbl); |
| 2107 break; | 2157 break; |
| 2108 case 3: | 2158 case 3: |
| 2109 // Format("fsqrtd 'vd, 'vn"); | 2159 // Format("fsqrtd 'vd, 'vn"); |
| 2110 res_val = bit_cast<int64_t, double>(sqrt(vn_dbl)); | 2160 res_val = bit_cast<int64_t, double>(sqrt(vn_dbl)); |
| 2111 break; | 2161 break; |
| 2162 case 4: { |
| 2163 // Format(instr, "fcvtsd 'vd, 'vn"); |
| 2164 const uint32_t val = |
| 2165 bit_cast<uint32_t, float>(static_cast<float>(vn_dbl)); |
| 2166 res_val = static_cast<int64_t>(val); |
| 2167 break; |
| 2168 } |
| 2169 case 5: |
| 2170 // Format(instr, "fcvtds 'vd, 'vn"); |
| 2171 res_val = bit_cast<int64_t, double>(static_cast<double>(vn_flt)); |
| 2172 break; |
| 2112 default: | 2173 default: |
| 2113 UNREACHABLE(); | 2174 UnimplementedInstruction(instr); |
| 2114 break; | 2175 break; |
| 2115 } | 2176 } |
| 2116 | 2177 |
| 2117 set_vregisterd(vd, res_val); | 2178 set_vregisterd(vd, res_val); |
| 2118 } | 2179 } |
| 2119 | 2180 |
| 2120 | 2181 |
| 2121 void Simulator::DecodeFPTwoSource(Instr* instr) { | 2182 void Simulator::DecodeFPTwoSource(Instr* instr) { |
| 2122 if (instr->Bits(22, 2) != 1) { | 2183 if (instr->Bits(22, 2) != 1) { |
| 2123 UnimplementedInstruction(instr); | 2184 UnimplementedInstruction(instr); |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2411 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); | 2472 set_register(kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); |
| 2412 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); | 2473 set_register(kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); |
| 2413 buf->Longjmp(); | 2474 buf->Longjmp(); |
| 2414 } | 2475 } |
| 2415 | 2476 |
| 2416 } // namespace dart | 2477 } // namespace dart |
| 2417 | 2478 |
| 2418 #endif // !defined(HOST_ARCH_ARM64) | 2479 #endif // !defined(HOST_ARCH_ARM64) |
| 2419 | 2480 |
| 2420 #endif // defined TARGET_ARCH_ARM64 | 2481 #endif // defined TARGET_ARCH_ARM64 |
| OLD | NEW |