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 |