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

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

Issue 616223005: Adds back arm ldrex strex. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 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/simulator_arm.h ('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) 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 <setjmp.h> 5 #include <setjmp.h>
6 #include <stdlib.h> 6 #include <stdlib.h>
7 7
8 #include "vm/globals.h" 8 #include "vm/globals.h"
9 #if defined(TARGET_ARCH_ARM) 9 #if defined(TARGET_ARCH_ARM)
10 10
11 // Only build the simulator if not compiling for real ARM hardware. 11 // Only build the simulator if not compiling for real ARM hardware.
12 #if !defined(HOST_ARCH_ARM) 12 #if !defined(HOST_ARCH_ARM)
13 13
14 #include "vm/simulator.h" 14 #include "vm/simulator.h"
15 15
16 #include "vm/assembler.h" 16 #include "vm/assembler.h"
17 #include "vm/constants_arm.h" 17 #include "vm/constants_arm.h"
18 #include "vm/cpu.h" 18 #include "vm/cpu.h"
19 #include "vm/disassembler.h" 19 #include "vm/disassembler.h"
20 #include "vm/lockers.h"
20 #include "vm/native_arguments.h" 21 #include "vm/native_arguments.h"
21 #include "vm/stack_frame.h" 22 #include "vm/stack_frame.h"
22 #include "vm/thread.h" 23 #include "vm/thread.h"
23 24
24 namespace dart { 25 namespace dart {
25 26
26 DEFINE_FLAG(bool, trace_sim, false, "Trace simulator execution."); 27 DEFINE_FLAG(bool, trace_sim, false, "Trace simulator execution.");
27 DEFINE_FLAG(int, stop_sim_at, 0, "Address to stop simulator at."); 28 DEFINE_FLAG(int, stop_sim_at, 0, "Address to stop simulator at.");
28 29
29 30
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 // Copy the newly read line into the result. 669 // Copy the newly read line into the result.
669 memmove(result + offset, line_buf, len); 670 memmove(result + offset, line_buf, len);
670 offset += len; 671 offset += len;
671 } 672 }
672 ASSERT(result != NULL); 673 ASSERT(result != NULL);
673 result[offset] = '\0'; 674 result[offset] = '\0';
674 return result; 675 return result;
675 } 676 }
676 677
677 678
678 void Simulator::InitOnce() {} 679 // Synchronization primitives support.
680 Mutex* Simulator::exclusive_access_lock_ = NULL;
681 Simulator::AddressTag Simulator::exclusive_access_state_[kNumAddressTags];
682 int Simulator::next_address_tag_;
683
684
685 void Simulator::SetExclusiveAccess(uword addr) {
686 Isolate* isolate = Isolate::Current();
687 ASSERT(isolate != NULL);
688 int i = 0;
689 while ((i < kNumAddressTags) &&
690 (exclusive_access_state_[i].isolate != isolate)) {
691 i++;
692 }
693 if (i == kNumAddressTags) {
694 i = next_address_tag_;
695 if (++next_address_tag_ == kNumAddressTags) next_address_tag_ = 0;
696 exclusive_access_state_[i].isolate = isolate;
697 }
698 exclusive_access_state_[i].addr = addr;
699 }
700
701
702 bool Simulator::HasExclusiveAccessAndOpen(uword addr) {
703 Isolate* isolate = Isolate::Current();
704 ASSERT(isolate != NULL);
705 bool result = false;
706 for (int i = 0; i < kNumAddressTags; i++) {
707 if (exclusive_access_state_[i].isolate == isolate) {
708 if (exclusive_access_state_[i].addr == addr) {
709 result = true;
710 }
711 exclusive_access_state_[i].addr = NULL;
712 continue;
713 }
714 if (exclusive_access_state_[i].addr == addr) {
715 exclusive_access_state_[i].addr = NULL;
716 }
717 }
718 return result;
719 }
720
721
722 void Simulator::InitOnce() {
723 // Setup exclusive access state.
724 exclusive_access_lock_ = new Mutex();
725 for (int i = 0; i < kNumAddressTags; i++) {
726 exclusive_access_state_[i].isolate = NULL;
727 exclusive_access_state_[i].addr = NULL;
728 }
729 next_address_tag_ = 0;
730 }
679 731
680 732
681 Simulator::Simulator() { 733 Simulator::Simulator() {
682 // Setup simulator support first. Some of this information is needed to 734 // Setup simulator support first. Some of this information is needed to
683 // setup the architecture state. 735 // setup the architecture state.
684 // We allocate the stack here, the size is computed as the sum of 736 // We allocate the stack here, the size is computed as the sum of
685 // the size specified by the user and the buffer space needed for 737 // the size specified by the user and the buffer space needed for
686 // handling stack overflow exceptions. To be safe in potential 738 // handling stack overflow exceptions. To be safe in potential
687 // stack underflows we also add some underflow buffer space. 739 // stack underflows we also add some underflow buffer space.
688 stack_ = new char[(Isolate::GetSpecifiedStackSize() + 740 stack_ = new char[(Isolate::GetSpecifiedStackSize() +
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 1104
1053 1105
1054 void Simulator::WriteB(uword addr, uint8_t value) { 1106 void Simulator::WriteB(uword addr, uint8_t value) {
1055 static StatsCounter counter_write_b("Simulated byte writes"); 1107 static StatsCounter counter_write_b("Simulated byte writes");
1056 counter_write_b.Increment(); 1108 counter_write_b.Increment();
1057 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); 1109 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
1058 *ptr = value; 1110 *ptr = value;
1059 } 1111 }
1060 1112
1061 1113
1114 // Synchronization primitives support.
1115 void Simulator::ClearExclusive() {
1116 // This lock is initialized in Simulator::InitOnce().
1117 MutexLocker ml(exclusive_access_lock_);
1118 // Set exclusive access to open state for this isolate.
1119 HasExclusiveAccessAndOpen(NULL);
1120 }
1121
1122
1123 intptr_t Simulator::ReadExclusiveW(uword addr, Instr* instr) {
1124 // This lock is initialized in Simulator::InitOnce().
1125 MutexLocker ml(exclusive_access_lock_);
1126 SetExclusiveAccess(addr);
1127 return ReadW(addr, instr);
1128 }
1129
1130
1131 intptr_t Simulator::WriteExclusiveW(uword addr, intptr_t value, Instr* instr) {
1132 // This lock is initialized in Simulator::InitOnce().
1133 MutexLocker ml(exclusive_access_lock_);
1134 bool write_allowed = HasExclusiveAccessAndOpen(addr);
1135 if (write_allowed) {
1136 WriteW(addr, value, instr);
1137 return 0; // Success.
1138 }
1139 return 1; // Failure.
1140 }
1141
1142
1143 uword Simulator::CompareExchange(uword* address,
1144 uword compare_value,
1145 uword new_value) {
1146 // This lock is initialized in Simulator::InitOnce().
1147 MutexLocker ml(exclusive_access_lock_);
1148 uword value = *address;
1149 if (value == compare_value) {
1150 *address = new_value;
1151 // Same effect on exclusive access state as a successful STREX.
1152 HasExclusiveAccessAndOpen(reinterpret_cast<uword>(address));
1153 } else {
1154 // Same effect on exclusive access state as an LDREX.
1155 SetExclusiveAccess(reinterpret_cast<uword>(address));
1156 }
1157 return value;
1158 }
1159
1160
1062 // Returns the top of the stack area to enable checking for stack pointer 1161 // Returns the top of the stack area to enable checking for stack pointer
1063 // validity. 1162 // validity.
1064 uword Simulator::StackTop() const { 1163 uword Simulator::StackTop() const {
1065 // To be safe in potential stack underflows we leave some buffer above and 1164 // To be safe in potential stack underflows we leave some buffer above and
1066 // set the stack top. 1165 // set the stack top.
1067 return reinterpret_cast<uword>(stack_) + 1166 return reinterpret_cast<uword>(stack_) +
1068 (Isolate::GetSpecifiedStackSize() + Isolate::kStackSizeBuffer); 1167 (Isolate::GetSpecifiedStackSize() + Isolate::kStackSizeBuffer);
1069 } 1168 }
1070 1169
1071 1170
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after
1732 SetNZFlags(hi_res); 1831 SetNZFlags(hi_res);
1733 } 1832 }
1734 break; 1833 break;
1735 } 1834 }
1736 default: { 1835 default: {
1737 UnimplementedInstruction(instr); 1836 UnimplementedInstruction(instr);
1738 break; 1837 break;
1739 } 1838 }
1740 } 1839 }
1741 } else { 1840 } else {
1742 UnimplementedInstruction(instr); 1841 if (TargetCPUFeatures::arm_version() == ARMv5TE) {
1842 UnimplementedInstruction(instr);
1843 return;
1844 }
1845 // synchronization primitives
1846 Register rd = instr->RdField();
1847 Register rn = instr->RnField();
1848 uword addr = get_register(rn);
1849 switch (instr->Bits(20, 4)) {
1850 case 8: {
1851 // Format(instr, "strex'cond 'rd, 'rm, ['rn]");
1852 if (IsIllegalAddress(addr)) {
1853 HandleIllegalAccess(addr, instr);
1854 } else {
1855 Register rm = instr->RmField();
1856 set_register(rd, WriteExclusiveW(addr, get_register(rm), instr));
1857 }
1858 break;
1859 }
1860 case 9: {
1861 // Format(instr, "ldrex'cond 'rd, ['rn]");
1862 if (IsIllegalAddress(addr)) {
1863 HandleIllegalAccess(addr, instr);
1864 } else {
1865 set_register(rd, ReadExclusiveW(addr, instr));
1866 }
1867 break;
1868 }
1869 default: {
1870 UnimplementedInstruction(instr);
1871 break;
1872 }
1873 }
1743 } 1874 }
1744 } else if (instr->Bit(25) == 1) { 1875 } else if (instr->Bit(25) == 1) {
1745 // 16-bit immediate loads, msr (immediate), and hints 1876 // 16-bit immediate loads, msr (immediate), and hints
1746 switch (instr->Bits(20, 5)) { 1877 switch (instr->Bits(20, 5)) {
1747 case 16: 1878 case 16:
1748 case 20: { 1879 case 20: {
1749 if (TargetCPUFeatures::arm_version() == ARMv7) { 1880 if (TargetCPUFeatures::arm_version() == ARMv7) {
1750 uint16_t imm16 = instr->MovwField(); 1881 uint16_t imm16 = instr->MovwField();
1751 Register rd = instr->RdField(); 1882 Register rd = instr->RdField();
1752 if (instr->Bit(22) == 0) { 1883 if (instr->Bit(22) == 0) {
(...skipping 1691 matching lines...) Expand 10 before | Expand all | Expand 10 after
3444 void Simulator::InstructionDecode(Instr* instr) { 3575 void Simulator::InstructionDecode(Instr* instr) {
3445 pc_modified_ = false; 3576 pc_modified_ = false;
3446 if (FLAG_trace_sim) { 3577 if (FLAG_trace_sim) {
3447 const uword start = reinterpret_cast<uword>(instr); 3578 const uword start = reinterpret_cast<uword>(instr);
3448 const uword end = start + Instr::kInstrSize; 3579 const uword end = start + Instr::kInstrSize;
3449 Disassembler::Disassemble(start, end); 3580 Disassembler::Disassemble(start, end);
3450 } 3581 }
3451 if (instr->ConditionField() == kSpecialCondition) { 3582 if (instr->ConditionField() == kSpecialCondition) {
3452 if (instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) { 3583 if (instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) {
3453 // Format(instr, "clrex"); 3584 // Format(instr, "clrex");
3454 UnimplementedInstruction(instr); 3585 ClearExclusive();
3455 } else { 3586 } else {
3456 if (instr->IsSIMDDataProcessing()) { 3587 if (instr->IsSIMDDataProcessing()) {
3457 DecodeSIMDDataProcessing(instr); 3588 DecodeSIMDDataProcessing(instr);
3458 } else { 3589 } else {
3459 UnimplementedInstruction(instr); 3590 UnimplementedInstruction(instr);
3460 } 3591 }
3461 } 3592 }
3462 } else if (ConditionallyExecute(instr)) { 3593 } else if (ConditionallyExecute(instr)) {
3463 switch (instr->TypeField()) { 3594 switch (instr->TypeField()) {
3464 case 0: 3595 case 0:
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
3735 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); 3866 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
3736 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); 3867 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
3737 buf->Longjmp(); 3868 buf->Longjmp();
3738 } 3869 }
3739 3870
3740 } // namespace dart 3871 } // namespace dart
3741 3872
3742 #endif // !defined(HOST_ARCH_ARM) 3873 #endif // !defined(HOST_ARCH_ARM)
3743 3874
3744 #endif // defined TARGET_ARCH_ARM 3875 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/simulator_arm.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698