| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <limits.h> | 5 #include <limits.h> |
| 6 #include <stdarg.h> | 6 #include <stdarg.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #include "src/v8.h" | 10 #include "src/v8.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 } | 117 } |
| 118 | 118 |
| 119 | 119 |
| 120 void MipsDebugger::Stop(Instruction* instr) { | 120 void MipsDebugger::Stop(Instruction* instr) { |
| 121 // Get the stop code. | 121 // Get the stop code. |
| 122 uint32_t code = instr->Bits(25, 6); | 122 uint32_t code = instr->Bits(25, 6); |
| 123 // Retrieve the encoded address, which comes just after this stop. | 123 // Retrieve the encoded address, which comes just after this stop. |
| 124 char** msg_address = | 124 char** msg_address = |
| 125 reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize); | 125 reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize); |
| 126 char* msg = *msg_address; | 126 char* msg = *msg_address; |
| 127 ASSERT(msg != NULL); | 127 DCHECK(msg != NULL); |
| 128 | 128 |
| 129 // Update this stop description. | 129 // Update this stop description. |
| 130 if (!watched_stops_[code].desc) { | 130 if (!watched_stops_[code].desc) { |
| 131 watched_stops_[code].desc = msg; | 131 watched_stops_[code].desc = msg; |
| 132 } | 132 } |
| 133 | 133 |
| 134 if (strlen(msg) > 0) { | 134 if (strlen(msg) > 0) { |
| 135 if (coverage_log != NULL) { | 135 if (coverage_log != NULL) { |
| 136 fprintf(coverage_log, "%s\n", str); | 136 fprintf(coverage_log, "%s\n", str); |
| 137 fflush(coverage_log); | 137 fflush(coverage_log); |
| (...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 | 763 |
| 764 #undef COMMAND_SIZE | 764 #undef COMMAND_SIZE |
| 765 #undef ARG_SIZE | 765 #undef ARG_SIZE |
| 766 | 766 |
| 767 #undef STR | 767 #undef STR |
| 768 #undef XSTR | 768 #undef XSTR |
| 769 } | 769 } |
| 770 | 770 |
| 771 | 771 |
| 772 static bool ICacheMatch(void* one, void* two) { | 772 static bool ICacheMatch(void* one, void* two) { |
| 773 ASSERT((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0); | 773 DCHECK((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0); |
| 774 ASSERT((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0); | 774 DCHECK((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0); |
| 775 return one == two; | 775 return one == two; |
| 776 } | 776 } |
| 777 | 777 |
| 778 | 778 |
| 779 static uint32_t ICacheHash(void* key) { | 779 static uint32_t ICacheHash(void* key) { |
| 780 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2; | 780 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2; |
| 781 } | 781 } |
| 782 | 782 |
| 783 | 783 |
| 784 static bool AllOnOnePage(uintptr_t start, int size) { | 784 static bool AllOnOnePage(uintptr_t start, int size) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 801 int64_t intra_line = (start & CachePage::kLineMask); | 801 int64_t intra_line = (start & CachePage::kLineMask); |
| 802 start -= intra_line; | 802 start -= intra_line; |
| 803 size += intra_line; | 803 size += intra_line; |
| 804 size = ((size - 1) | CachePage::kLineMask) + 1; | 804 size = ((size - 1) | CachePage::kLineMask) + 1; |
| 805 int offset = (start & CachePage::kPageMask); | 805 int offset = (start & CachePage::kPageMask); |
| 806 while (!AllOnOnePage(start, size - 1)) { | 806 while (!AllOnOnePage(start, size - 1)) { |
| 807 int bytes_to_flush = CachePage::kPageSize - offset; | 807 int bytes_to_flush = CachePage::kPageSize - offset; |
| 808 FlushOnePage(i_cache, start, bytes_to_flush); | 808 FlushOnePage(i_cache, start, bytes_to_flush); |
| 809 start += bytes_to_flush; | 809 start += bytes_to_flush; |
| 810 size -= bytes_to_flush; | 810 size -= bytes_to_flush; |
| 811 ASSERT_EQ((uint64_t)0, start & CachePage::kPageMask); | 811 DCHECK_EQ((uint64_t)0, start & CachePage::kPageMask); |
| 812 offset = 0; | 812 offset = 0; |
| 813 } | 813 } |
| 814 if (size != 0) { | 814 if (size != 0) { |
| 815 FlushOnePage(i_cache, start, size); | 815 FlushOnePage(i_cache, start, size); |
| 816 } | 816 } |
| 817 } | 817 } |
| 818 | 818 |
| 819 | 819 |
| 820 CachePage* Simulator::GetCachePage(v8::internal::HashMap* i_cache, void* page) { | 820 CachePage* Simulator::GetCachePage(v8::internal::HashMap* i_cache, void* page) { |
| 821 v8::internal::HashMap::Entry* entry = i_cache->Lookup(page, | 821 v8::internal::HashMap::Entry* entry = i_cache->Lookup(page, |
| 822 ICacheHash(page), | 822 ICacheHash(page), |
| 823 true); | 823 true); |
| 824 if (entry->value == NULL) { | 824 if (entry->value == NULL) { |
| 825 CachePage* new_page = new CachePage(); | 825 CachePage* new_page = new CachePage(); |
| 826 entry->value = new_page; | 826 entry->value = new_page; |
| 827 } | 827 } |
| 828 return reinterpret_cast<CachePage*>(entry->value); | 828 return reinterpret_cast<CachePage*>(entry->value); |
| 829 } | 829 } |
| 830 | 830 |
| 831 | 831 |
| 832 // Flush from start up to and not including start + size. | 832 // Flush from start up to and not including start + size. |
| 833 void Simulator::FlushOnePage(v8::internal::HashMap* i_cache, | 833 void Simulator::FlushOnePage(v8::internal::HashMap* i_cache, |
| 834 intptr_t start, | 834 intptr_t start, |
| 835 int size) { | 835 int size) { |
| 836 ASSERT(size <= CachePage::kPageSize); | 836 DCHECK(size <= CachePage::kPageSize); |
| 837 ASSERT(AllOnOnePage(start, size - 1)); | 837 DCHECK(AllOnOnePage(start, size - 1)); |
| 838 ASSERT((start & CachePage::kLineMask) == 0); | 838 DCHECK((start & CachePage::kLineMask) == 0); |
| 839 ASSERT((size & CachePage::kLineMask) == 0); | 839 DCHECK((size & CachePage::kLineMask) == 0); |
| 840 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask)); | 840 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask)); |
| 841 int offset = (start & CachePage::kPageMask); | 841 int offset = (start & CachePage::kPageMask); |
| 842 CachePage* cache_page = GetCachePage(i_cache, page); | 842 CachePage* cache_page = GetCachePage(i_cache, page); |
| 843 char* valid_bytemap = cache_page->ValidityByte(offset); | 843 char* valid_bytemap = cache_page->ValidityByte(offset); |
| 844 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift); | 844 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift); |
| 845 } | 845 } |
| 846 | 846 |
| 847 | 847 |
| 848 void Simulator::CheckICache(v8::internal::HashMap* i_cache, | 848 void Simulator::CheckICache(v8::internal::HashMap* i_cache, |
| 849 Instruction* instr) { | 849 Instruction* instr) { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 ExternalReference::Type type) { | 989 ExternalReference::Type type) { |
| 990 Redirection* redirection = Redirection::Get(external_function, type); | 990 Redirection* redirection = Redirection::Get(external_function, type); |
| 991 return redirection->address_of_swi_instruction(); | 991 return redirection->address_of_swi_instruction(); |
| 992 } | 992 } |
| 993 | 993 |
| 994 | 994 |
| 995 // Get the active Simulator for the current thread. | 995 // Get the active Simulator for the current thread. |
| 996 Simulator* Simulator::current(Isolate* isolate) { | 996 Simulator* Simulator::current(Isolate* isolate) { |
| 997 v8::internal::Isolate::PerIsolateThreadData* isolate_data = | 997 v8::internal::Isolate::PerIsolateThreadData* isolate_data = |
| 998 isolate->FindOrAllocatePerThreadDataForThisThread(); | 998 isolate->FindOrAllocatePerThreadDataForThisThread(); |
| 999 ASSERT(isolate_data != NULL); | 999 DCHECK(isolate_data != NULL); |
| 1000 ASSERT(isolate_data != NULL); | 1000 DCHECK(isolate_data != NULL); |
| 1001 | 1001 |
| 1002 Simulator* sim = isolate_data->simulator(); | 1002 Simulator* sim = isolate_data->simulator(); |
| 1003 if (sim == NULL) { | 1003 if (sim == NULL) { |
| 1004 // TODO(146): delete the simulator object when a thread/isolate goes away. | 1004 // TODO(146): delete the simulator object when a thread/isolate goes away. |
| 1005 sim = new Simulator(isolate); | 1005 sim = new Simulator(isolate); |
| 1006 isolate_data->set_simulator(sim); | 1006 isolate_data->set_simulator(sim); |
| 1007 } | 1007 } |
| 1008 return sim; | 1008 return sim; |
| 1009 } | 1009 } |
| 1010 | 1010 |
| 1011 | 1011 |
| 1012 // Sets the register in the architecture state. It will also deal with updating | 1012 // Sets the register in the architecture state. It will also deal with updating |
| 1013 // Simulator internal state for special registers such as PC. | 1013 // Simulator internal state for special registers such as PC. |
| 1014 void Simulator::set_register(int reg, int64_t value) { | 1014 void Simulator::set_register(int reg, int64_t value) { |
| 1015 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); | 1015 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); |
| 1016 if (reg == pc) { | 1016 if (reg == pc) { |
| 1017 pc_modified_ = true; | 1017 pc_modified_ = true; |
| 1018 } | 1018 } |
| 1019 | 1019 |
| 1020 // Zero register always holds 0. | 1020 // Zero register always holds 0. |
| 1021 registers_[reg] = (reg == 0) ? 0 : value; | 1021 registers_[reg] = (reg == 0) ? 0 : value; |
| 1022 } | 1022 } |
| 1023 | 1023 |
| 1024 | 1024 |
| 1025 void Simulator::set_dw_register(int reg, const int* dbl) { | 1025 void Simulator::set_dw_register(int reg, const int* dbl) { |
| 1026 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); | 1026 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); |
| 1027 registers_[reg] = dbl[1]; | 1027 registers_[reg] = dbl[1]; |
| 1028 registers_[reg] = registers_[reg] << 32; | 1028 registers_[reg] = registers_[reg] << 32; |
| 1029 registers_[reg] += dbl[0]; | 1029 registers_[reg] += dbl[0]; |
| 1030 } | 1030 } |
| 1031 | 1031 |
| 1032 | 1032 |
| 1033 void Simulator::set_fpu_register(int fpureg, int64_t value) { | 1033 void Simulator::set_fpu_register(int fpureg, int64_t value) { |
| 1034 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1034 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
| 1035 FPUregisters_[fpureg] = value; | 1035 FPUregisters_[fpureg] = value; |
| 1036 } | 1036 } |
| 1037 | 1037 |
| 1038 | 1038 |
| 1039 void Simulator::set_fpu_register_word(int fpureg, int32_t value) { | 1039 void Simulator::set_fpu_register_word(int fpureg, int32_t value) { |
| 1040 // Set ONLY lower 32-bits, leaving upper bits untouched. | 1040 // Set ONLY lower 32-bits, leaving upper bits untouched. |
| 1041 // TODO(plind): big endian issue. | 1041 // TODO(plind): big endian issue. |
| 1042 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1042 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
| 1043 int32_t *pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]); | 1043 int32_t *pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]); |
| 1044 *pword = value; | 1044 *pword = value; |
| 1045 } | 1045 } |
| 1046 | 1046 |
| 1047 | 1047 |
| 1048 void Simulator::set_fpu_register_hi_word(int fpureg, int32_t value) { | 1048 void Simulator::set_fpu_register_hi_word(int fpureg, int32_t value) { |
| 1049 // Set ONLY upper 32-bits, leaving lower bits untouched. | 1049 // Set ONLY upper 32-bits, leaving lower bits untouched. |
| 1050 // TODO(plind): big endian issue. | 1050 // TODO(plind): big endian issue. |
| 1051 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1051 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
| 1052 int32_t *phiword = (reinterpret_cast<int32_t*>(&FPUregisters_[fpureg])) + 1; | 1052 int32_t *phiword = (reinterpret_cast<int32_t*>(&FPUregisters_[fpureg])) + 1; |
| 1053 *phiword = value; | 1053 *phiword = value; |
| 1054 } | 1054 } |
| 1055 | 1055 |
| 1056 | 1056 |
| 1057 void Simulator::set_fpu_register_float(int fpureg, float value) { | 1057 void Simulator::set_fpu_register_float(int fpureg, float value) { |
| 1058 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1058 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
| 1059 *BitCast<float*>(&FPUregisters_[fpureg]) = value; | 1059 *BitCast<float*>(&FPUregisters_[fpureg]) = value; |
| 1060 } | 1060 } |
| 1061 | 1061 |
| 1062 | 1062 |
| 1063 void Simulator::set_fpu_register_double(int fpureg, double value) { | 1063 void Simulator::set_fpu_register_double(int fpureg, double value) { |
| 1064 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1064 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
| 1065 *BitCast<double*>(&FPUregisters_[fpureg]) = value; | 1065 *BitCast<double*>(&FPUregisters_[fpureg]) = value; |
| 1066 } | 1066 } |
| 1067 | 1067 |
| 1068 | 1068 |
| 1069 // Get the register from the architecture state. This function does handle | 1069 // Get the register from the architecture state. This function does handle |
| 1070 // the special case of accessing the PC register. | 1070 // the special case of accessing the PC register. |
| 1071 int64_t Simulator::get_register(int reg) const { | 1071 int64_t Simulator::get_register(int reg) const { |
| 1072 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); | 1072 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); |
| 1073 if (reg == 0) | 1073 if (reg == 0) |
| 1074 return 0; | 1074 return 0; |
| 1075 else | 1075 else |
| 1076 return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0); | 1076 return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0); |
| 1077 } | 1077 } |
| 1078 | 1078 |
| 1079 | 1079 |
| 1080 double Simulator::get_double_from_register_pair(int reg) { | 1080 double Simulator::get_double_from_register_pair(int reg) { |
| 1081 // TODO(plind): bad ABI stuff, refactor or remove. | 1081 // TODO(plind): bad ABI stuff, refactor or remove. |
| 1082 ASSERT((reg >= 0) && (reg < kNumSimuRegisters) && ((reg % 2) == 0)); | 1082 DCHECK((reg >= 0) && (reg < kNumSimuRegisters) && ((reg % 2) == 0)); |
| 1083 | 1083 |
| 1084 double dm_val = 0.0; | 1084 double dm_val = 0.0; |
| 1085 // Read the bits from the unsigned integer register_[] array | 1085 // Read the bits from the unsigned integer register_[] array |
| 1086 // into the double precision floating point value and return it. | 1086 // into the double precision floating point value and return it. |
| 1087 char buffer[sizeof(registers_[0])]; | 1087 char buffer[sizeof(registers_[0])]; |
| 1088 memcpy(buffer, ®isters_[reg], sizeof(registers_[0])); | 1088 memcpy(buffer, ®isters_[reg], sizeof(registers_[0])); |
| 1089 memcpy(&dm_val, buffer, sizeof(registers_[0])); | 1089 memcpy(&dm_val, buffer, sizeof(registers_[0])); |
| 1090 return(dm_val); | 1090 return(dm_val); |
| 1091 } | 1091 } |
| 1092 | 1092 |
| 1093 | 1093 |
| 1094 int64_t Simulator::get_fpu_register(int fpureg) const { | 1094 int64_t Simulator::get_fpu_register(int fpureg) const { |
| 1095 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1095 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
| 1096 return FPUregisters_[fpureg]; | 1096 return FPUregisters_[fpureg]; |
| 1097 } | 1097 } |
| 1098 | 1098 |
| 1099 | 1099 |
| 1100 int32_t Simulator::get_fpu_register_word(int fpureg) const { | 1100 int32_t Simulator::get_fpu_register_word(int fpureg) const { |
| 1101 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1101 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
| 1102 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff); | 1102 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff); |
| 1103 } | 1103 } |
| 1104 | 1104 |
| 1105 | 1105 |
| 1106 int32_t Simulator::get_fpu_register_signed_word(int fpureg) const { | 1106 int32_t Simulator::get_fpu_register_signed_word(int fpureg) const { |
| 1107 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1107 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
| 1108 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff); | 1108 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff); |
| 1109 } | 1109 } |
| 1110 | 1110 |
| 1111 | 1111 |
| 1112 uint32_t Simulator::get_fpu_register_hi_word(int fpureg) const { | 1112 uint32_t Simulator::get_fpu_register_hi_word(int fpureg) const { |
| 1113 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1113 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
| 1114 return static_cast<uint32_t>((FPUregisters_[fpureg] >> 32) & 0xffffffff); | 1114 return static_cast<uint32_t>((FPUregisters_[fpureg] >> 32) & 0xffffffff); |
| 1115 } | 1115 } |
| 1116 | 1116 |
| 1117 | 1117 |
| 1118 float Simulator::get_fpu_register_float(int fpureg) const { | 1118 float Simulator::get_fpu_register_float(int fpureg) const { |
| 1119 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1119 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
| 1120 return *BitCast<float*>( | 1120 return *BitCast<float*>( |
| 1121 const_cast<int64_t*>(&FPUregisters_[fpureg])); | 1121 const_cast<int64_t*>(&FPUregisters_[fpureg])); |
| 1122 } | 1122 } |
| 1123 | 1123 |
| 1124 | 1124 |
| 1125 double Simulator::get_fpu_register_double(int fpureg) const { | 1125 double Simulator::get_fpu_register_double(int fpureg) const { |
| 1126 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1126 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
| 1127 return *BitCast<double*>(&FPUregisters_[fpureg]); | 1127 return *BitCast<double*>(&FPUregisters_[fpureg]); |
| 1128 } | 1128 } |
| 1129 | 1129 |
| 1130 | 1130 |
| 1131 // Runtime FP routines take up to two double arguments and zero | 1131 // Runtime FP routines take up to two double arguments and zero |
| 1132 // or one integer arguments. All are constructed here, | 1132 // or one integer arguments. All are constructed here, |
| 1133 // from a0-a3 or f12 and f13 (n64), or f14 (O32). | 1133 // from a0-a3 or f12 and f13 (n64), or f14 (O32). |
| 1134 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { | 1134 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { |
| 1135 if (!IsMipsSoftFloatABI) { | 1135 if (!IsMipsSoftFloatABI) { |
| 1136 const int fparg2 = (kMipsAbi == kN64) ? 13 : 14; | 1136 const int fparg2 = (kMipsAbi == kN64) ? 13 : 14; |
| (...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1849 | 1849 |
| 1850 | 1850 |
| 1851 bool Simulator::IsStopInstruction(Instruction* instr) { | 1851 bool Simulator::IsStopInstruction(Instruction* instr) { |
| 1852 int32_t func = instr->FunctionFieldRaw(); | 1852 int32_t func = instr->FunctionFieldRaw(); |
| 1853 uint32_t code = static_cast<uint32_t>(instr->Bits(25, 6)); | 1853 uint32_t code = static_cast<uint32_t>(instr->Bits(25, 6)); |
| 1854 return (func == BREAK) && code > kMaxWatchpointCode && code <= kMaxStopCode; | 1854 return (func == BREAK) && code > kMaxWatchpointCode && code <= kMaxStopCode; |
| 1855 } | 1855 } |
| 1856 | 1856 |
| 1857 | 1857 |
| 1858 bool Simulator::IsEnabledStop(uint64_t code) { | 1858 bool Simulator::IsEnabledStop(uint64_t code) { |
| 1859 ASSERT(code <= kMaxStopCode); | 1859 DCHECK(code <= kMaxStopCode); |
| 1860 ASSERT(code > kMaxWatchpointCode); | 1860 DCHECK(code > kMaxWatchpointCode); |
| 1861 return !(watched_stops_[code].count & kStopDisabledBit); | 1861 return !(watched_stops_[code].count & kStopDisabledBit); |
| 1862 } | 1862 } |
| 1863 | 1863 |
| 1864 | 1864 |
| 1865 void Simulator::EnableStop(uint64_t code) { | 1865 void Simulator::EnableStop(uint64_t code) { |
| 1866 if (!IsEnabledStop(code)) { | 1866 if (!IsEnabledStop(code)) { |
| 1867 watched_stops_[code].count &= ~kStopDisabledBit; | 1867 watched_stops_[code].count &= ~kStopDisabledBit; |
| 1868 } | 1868 } |
| 1869 } | 1869 } |
| 1870 | 1870 |
| 1871 | 1871 |
| 1872 void Simulator::DisableStop(uint64_t code) { | 1872 void Simulator::DisableStop(uint64_t code) { |
| 1873 if (IsEnabledStop(code)) { | 1873 if (IsEnabledStop(code)) { |
| 1874 watched_stops_[code].count |= kStopDisabledBit; | 1874 watched_stops_[code].count |= kStopDisabledBit; |
| 1875 } | 1875 } |
| 1876 } | 1876 } |
| 1877 | 1877 |
| 1878 | 1878 |
| 1879 void Simulator::IncreaseStopCounter(uint64_t code) { | 1879 void Simulator::IncreaseStopCounter(uint64_t code) { |
| 1880 ASSERT(code <= kMaxStopCode); | 1880 DCHECK(code <= kMaxStopCode); |
| 1881 if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) { | 1881 if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) { |
| 1882 PrintF("Stop counter for code %ld has overflowed.\n" | 1882 PrintF("Stop counter for code %ld has overflowed.\n" |
| 1883 "Enabling this code and reseting the counter to 0.\n", code); | 1883 "Enabling this code and reseting the counter to 0.\n", code); |
| 1884 watched_stops_[code].count = 0; | 1884 watched_stops_[code].count = 0; |
| 1885 EnableStop(code); | 1885 EnableStop(code); |
| 1886 } else { | 1886 } else { |
| 1887 watched_stops_[code].count++; | 1887 watched_stops_[code].count++; |
| 1888 } | 1888 } |
| 1889 } | 1889 } |
| 1890 | 1890 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1950 | 1950 |
| 1951 const int32_t fs_reg = instr->FsValue(); | 1951 const int32_t fs_reg = instr->FsValue(); |
| 1952 | 1952 |
| 1953 | 1953 |
| 1954 // ---------- Configuration. | 1954 // ---------- Configuration. |
| 1955 switch (op) { | 1955 switch (op) { |
| 1956 case COP1: // Coprocessor instructions. | 1956 case COP1: // Coprocessor instructions. |
| 1957 switch (instr->RsFieldRaw()) { | 1957 switch (instr->RsFieldRaw()) { |
| 1958 case CFC1: | 1958 case CFC1: |
| 1959 // At the moment only FCSR is supported. | 1959 // At the moment only FCSR is supported. |
| 1960 ASSERT(fs_reg == kFCSRRegister); | 1960 DCHECK(fs_reg == kFCSRRegister); |
| 1961 *alu_out = FCSR_; | 1961 *alu_out = FCSR_; |
| 1962 break; | 1962 break; |
| 1963 case MFC1: | 1963 case MFC1: |
| 1964 *alu_out = static_cast<int64_t>(get_fpu_register_word(fs_reg)); | 1964 *alu_out = static_cast<int64_t>(get_fpu_register_word(fs_reg)); |
| 1965 break; | 1965 break; |
| 1966 case DMFC1: | 1966 case DMFC1: |
| 1967 *alu_out = get_fpu_register(fs_reg); | 1967 *alu_out = get_fpu_register(fs_reg); |
| 1968 break; | 1968 break; |
| 1969 case MFHC1: | 1969 case MFHC1: |
| 1970 *alu_out = get_fpu_register_hi_word(fs_reg); | 1970 *alu_out = get_fpu_register_hi_word(fs_reg); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2062 } | 2062 } |
| 2063 break; | 2063 break; |
| 2064 case SRAV: | 2064 case SRAV: |
| 2065 *alu_out = (int32_t)rt >> rs; | 2065 *alu_out = (int32_t)rt >> rs; |
| 2066 break; | 2066 break; |
| 2067 case DSRAV: | 2067 case DSRAV: |
| 2068 *alu_out = rt >> rs; | 2068 *alu_out = rt >> rs; |
| 2069 break; | 2069 break; |
| 2070 case MFHI: // MFHI == CLZ on R6. | 2070 case MFHI: // MFHI == CLZ on R6. |
| 2071 if (kArchVariant != kMips64r6) { | 2071 if (kArchVariant != kMips64r6) { |
| 2072 ASSERT(instr->SaValue() == 0); | 2072 DCHECK(instr->SaValue() == 0); |
| 2073 *alu_out = get_register(HI); | 2073 *alu_out = get_register(HI); |
| 2074 } else { | 2074 } else { |
| 2075 // MIPS spec: If no bits were set in GPR rs, the result written to | 2075 // MIPS spec: If no bits were set in GPR rs, the result written to |
| 2076 // GPR rd is 32. | 2076 // GPR rd is 32. |
| 2077 // GCC __builtin_clz: If input is 0, the result is undefined. | 2077 // GCC __builtin_clz: If input is 0, the result is undefined. |
| 2078 ASSERT(instr->SaValue() == 1); | 2078 DCHECK(instr->SaValue() == 1); |
| 2079 *alu_out = | 2079 *alu_out = |
| 2080 rs_u == 0 ? 32 : CompilerIntrinsics::CountLeadingZeros(rs_u); | 2080 rs_u == 0 ? 32 : CompilerIntrinsics::CountLeadingZeros(rs_u); |
| 2081 } | 2081 } |
| 2082 break; | 2082 break; |
| 2083 case MFLO: | 2083 case MFLO: |
| 2084 *alu_out = get_register(LO); | 2084 *alu_out = get_register(LO); |
| 2085 break; | 2085 break; |
| 2086 case MULT: // MULT == D_MUL_MUH. | 2086 case MULT: // MULT == D_MUL_MUH. |
| 2087 // TODO(plind) - Unify MULT/DMULT with single set of 64-bit HI/Lo | 2087 // TODO(plind) - Unify MULT/DMULT with single set of 64-bit HI/Lo |
| 2088 // regs. | 2088 // regs. |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2322 case CFC1: | 2322 case CFC1: |
| 2323 set_register(rt_reg, alu_out); | 2323 set_register(rt_reg, alu_out); |
| 2324 break; | 2324 break; |
| 2325 case MFC1: | 2325 case MFC1: |
| 2326 case DMFC1: | 2326 case DMFC1: |
| 2327 case MFHC1: | 2327 case MFHC1: |
| 2328 set_register(rt_reg, alu_out); | 2328 set_register(rt_reg, alu_out); |
| 2329 break; | 2329 break; |
| 2330 case CTC1: | 2330 case CTC1: |
| 2331 // At the moment only FCSR is supported. | 2331 // At the moment only FCSR is supported. |
| 2332 ASSERT(fs_reg == kFCSRRegister); | 2332 DCHECK(fs_reg == kFCSRRegister); |
| 2333 FCSR_ = registers_[rt_reg]; | 2333 FCSR_ = registers_[rt_reg]; |
| 2334 break; | 2334 break; |
| 2335 case MTC1: | 2335 case MTC1: |
| 2336 // Hardware writes upper 32-bits to zero on mtc1. | 2336 // Hardware writes upper 32-bits to zero on mtc1. |
| 2337 set_fpu_register_hi_word(fs_reg, 0); | 2337 set_fpu_register_hi_word(fs_reg, 0); |
| 2338 set_fpu_register_word(fs_reg, registers_[rt_reg]); | 2338 set_fpu_register_word(fs_reg, registers_[rt_reg]); |
| 2339 break; | 2339 break; |
| 2340 case DMTC1: | 2340 case DMTC1: |
| 2341 set_fpu_register(fs_reg, registers_[rt_reg]); | 2341 set_fpu_register(fs_reg, registers_[rt_reg]); |
| 2342 break; | 2342 break; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2408 break; | 2408 break; |
| 2409 case C_OLE_D: | 2409 case C_OLE_D: |
| 2410 set_fcsr_bit(fcsr_cc, (fs <= ft)); | 2410 set_fcsr_bit(fcsr_cc, (fs <= ft)); |
| 2411 break; | 2411 break; |
| 2412 case C_ULE_D: | 2412 case C_ULE_D: |
| 2413 set_fcsr_bit(fcsr_cc, | 2413 set_fcsr_bit(fcsr_cc, |
| 2414 (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); | 2414 (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); |
| 2415 break; | 2415 break; |
| 2416 case CVT_W_D: // Convert double to word. | 2416 case CVT_W_D: // Convert double to word. |
| 2417 // Rounding modes are not yet supported. | 2417 // Rounding modes are not yet supported. |
| 2418 ASSERT((FCSR_ & 3) == 0); | 2418 DCHECK((FCSR_ & 3) == 0); |
| 2419 // In rounding mode 0 it should behave like ROUND. | 2419 // In rounding mode 0 it should behave like ROUND. |
| 2420 // No break. | 2420 // No break. |
| 2421 case ROUND_W_D: // Round double to word (round half to even). | 2421 case ROUND_W_D: // Round double to word (round half to even). |
| 2422 { | 2422 { |
| 2423 double rounded = std::floor(fs + 0.5); | 2423 double rounded = std::floor(fs + 0.5); |
| 2424 int32_t result = static_cast<int32_t>(rounded); | 2424 int32_t result = static_cast<int32_t>(rounded); |
| 2425 if ((result & 1) != 0 && result - fs == 0.5) { | 2425 if ((result & 1) != 0 && result - fs == 0.5) { |
| 2426 // If the number is halfway between two integers, | 2426 // If the number is halfway between two integers, |
| 2427 // round to the even one. | 2427 // round to the even one. |
| 2428 result--; | 2428 result--; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2461 if (set_fcsr_round_error(fs, rounded)) { | 2461 if (set_fcsr_round_error(fs, rounded)) { |
| 2462 set_fpu_register(fd_reg, kFPUInvalidResult); | 2462 set_fpu_register(fd_reg, kFPUInvalidResult); |
| 2463 } | 2463 } |
| 2464 } | 2464 } |
| 2465 break; | 2465 break; |
| 2466 case CVT_S_D: // Convert double to float (single). | 2466 case CVT_S_D: // Convert double to float (single). |
| 2467 set_fpu_register_float(fd_reg, static_cast<float>(fs)); | 2467 set_fpu_register_float(fd_reg, static_cast<float>(fs)); |
| 2468 break; | 2468 break; |
| 2469 case CVT_L_D: // Mips64r2: Truncate double to 64-bit long-word. | 2469 case CVT_L_D: // Mips64r2: Truncate double to 64-bit long-word. |
| 2470 // Rounding modes are not yet supported. | 2470 // Rounding modes are not yet supported. |
| 2471 ASSERT((FCSR_ & 3) == 0); | 2471 DCHECK((FCSR_ & 3) == 0); |
| 2472 // In rounding mode 0 it should behave like ROUND. | 2472 // In rounding mode 0 it should behave like ROUND. |
| 2473 // No break. | 2473 // No break. |
| 2474 case ROUND_L_D: { // Mips64r2 instruction. | 2474 case ROUND_L_D: { // Mips64r2 instruction. |
| 2475 // check error cases | 2475 // check error cases |
| 2476 double rounded = fs > 0 ? floor(fs + 0.5) : ceil(fs - 0.5); | 2476 double rounded = fs > 0 ? floor(fs + 0.5) : ceil(fs - 0.5); |
| 2477 int64_t result = static_cast<int64_t>(rounded); | 2477 int64_t result = static_cast<int64_t>(rounded); |
| 2478 set_fpu_register(fd_reg, result); | 2478 set_fpu_register(fd_reg, result); |
| 2479 if (set_fcsr_round64_error(fs, rounded)) { | 2479 if (set_fcsr_round64_error(fs, rounded)) { |
| 2480 set_fpu_register(fd_reg, kFPU64InvalidResult); | 2480 set_fpu_register(fd_reg, kFPU64InvalidResult); |
| 2481 } | 2481 } |
| (...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3349 } | 3349 } |
| 3350 | 3350 |
| 3351 | 3351 |
| 3352 int64_t Simulator::Call(byte* entry, int argument_count, ...) { | 3352 int64_t Simulator::Call(byte* entry, int argument_count, ...) { |
| 3353 const int kRegisterPassedArguments = (kMipsAbi == kN64) ? 8 : 4; | 3353 const int kRegisterPassedArguments = (kMipsAbi == kN64) ? 8 : 4; |
| 3354 va_list parameters; | 3354 va_list parameters; |
| 3355 va_start(parameters, argument_count); | 3355 va_start(parameters, argument_count); |
| 3356 // Set up arguments. | 3356 // Set up arguments. |
| 3357 | 3357 |
| 3358 // First four arguments passed in registers in both ABI's. | 3358 // First four arguments passed in registers in both ABI's. |
| 3359 ASSERT(argument_count >= 4); | 3359 DCHECK(argument_count >= 4); |
| 3360 set_register(a0, va_arg(parameters, int64_t)); | 3360 set_register(a0, va_arg(parameters, int64_t)); |
| 3361 set_register(a1, va_arg(parameters, int64_t)); | 3361 set_register(a1, va_arg(parameters, int64_t)); |
| 3362 set_register(a2, va_arg(parameters, int64_t)); | 3362 set_register(a2, va_arg(parameters, int64_t)); |
| 3363 set_register(a3, va_arg(parameters, int64_t)); | 3363 set_register(a3, va_arg(parameters, int64_t)); |
| 3364 | 3364 |
| 3365 if (kMipsAbi == kN64) { | 3365 if (kMipsAbi == kN64) { |
| 3366 // Up to eight arguments passed in registers in N64 ABI. | 3366 // Up to eight arguments passed in registers in N64 ABI. |
| 3367 // TODO(plind): N64 ABI calls these regs a4 - a7. Clarify this. | 3367 // TODO(plind): N64 ABI calls these regs a4 - a7. Clarify this. |
| 3368 if (argument_count >= 5) set_register(a4, va_arg(parameters, int64_t)); | 3368 if (argument_count >= 5) set_register(a4, va_arg(parameters, int64_t)); |
| 3369 if (argument_count >= 6) set_register(a5, va_arg(parameters, int64_t)); | 3369 if (argument_count >= 6) set_register(a5, va_arg(parameters, int64_t)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3402 } | 3402 } |
| 3403 | 3403 |
| 3404 | 3404 |
| 3405 double Simulator::CallFP(byte* entry, double d0, double d1) { | 3405 double Simulator::CallFP(byte* entry, double d0, double d1) { |
| 3406 if (!IsMipsSoftFloatABI) { | 3406 if (!IsMipsSoftFloatABI) { |
| 3407 const FPURegister fparg2 = (kMipsAbi == kN64) ? f13 : f14; | 3407 const FPURegister fparg2 = (kMipsAbi == kN64) ? f13 : f14; |
| 3408 set_fpu_register_double(f12, d0); | 3408 set_fpu_register_double(f12, d0); |
| 3409 set_fpu_register_double(fparg2, d1); | 3409 set_fpu_register_double(fparg2, d1); |
| 3410 } else { | 3410 } else { |
| 3411 int buffer[2]; | 3411 int buffer[2]; |
| 3412 ASSERT(sizeof(buffer[0]) * 2 == sizeof(d0)); | 3412 DCHECK(sizeof(buffer[0]) * 2 == sizeof(d0)); |
| 3413 memcpy(buffer, &d0, sizeof(d0)); | 3413 memcpy(buffer, &d0, sizeof(d0)); |
| 3414 set_dw_register(a0, buffer); | 3414 set_dw_register(a0, buffer); |
| 3415 memcpy(buffer, &d1, sizeof(d1)); | 3415 memcpy(buffer, &d1, sizeof(d1)); |
| 3416 set_dw_register(a2, buffer); | 3416 set_dw_register(a2, buffer); |
| 3417 } | 3417 } |
| 3418 CallInternal(entry); | 3418 CallInternal(entry); |
| 3419 if (!IsMipsSoftFloatABI) { | 3419 if (!IsMipsSoftFloatABI) { |
| 3420 return get_fpu_register_double(f0); | 3420 return get_fpu_register_double(f0); |
| 3421 } else { | 3421 } else { |
| 3422 return get_double_from_register_pair(v0); | 3422 return get_double_from_register_pair(v0); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3442 } | 3442 } |
| 3443 | 3443 |
| 3444 | 3444 |
| 3445 #undef UNSUPPORTED | 3445 #undef UNSUPPORTED |
| 3446 | 3446 |
| 3447 } } // namespace v8::internal | 3447 } } // namespace v8::internal |
| 3448 | 3448 |
| 3449 #endif // USE_SIMULATOR | 3449 #endif // USE_SIMULATOR |
| 3450 | 3450 |
| 3451 #endif // V8_TARGET_ARCH_MIPS64 | 3451 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |