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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 } | 100 } |
101 | 101 |
102 | 102 |
103 void MipsDebugger::Stop(Instruction* instr) { | 103 void MipsDebugger::Stop(Instruction* instr) { |
104 // Get the stop code. | 104 // Get the stop code. |
105 uint32_t code = instr->Bits(25, 6); | 105 uint32_t code = instr->Bits(25, 6); |
106 // Retrieve the encoded address, which comes just after this stop. | 106 // Retrieve the encoded address, which comes just after this stop. |
107 char** msg_address = | 107 char** msg_address = |
108 reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize); | 108 reinterpret_cast<char**>(sim_->get_pc() + Instr::kInstrSize); |
109 char* msg = *msg_address; | 109 char* msg = *msg_address; |
110 ASSERT(msg != NULL); | 110 DCHECK(msg != NULL); |
111 | 111 |
112 // Update this stop description. | 112 // Update this stop description. |
113 if (!watched_stops_[code].desc) { | 113 if (!watched_stops_[code].desc) { |
114 watched_stops_[code].desc = msg; | 114 watched_stops_[code].desc = msg; |
115 } | 115 } |
116 | 116 |
117 if (strlen(msg) > 0) { | 117 if (strlen(msg) > 0) { |
118 if (coverage_log != NULL) { | 118 if (coverage_log != NULL) { |
119 fprintf(coverage_log, "%s\n", str); | 119 fprintf(coverage_log, "%s\n", str); |
120 fflush(coverage_log); | 120 fflush(coverage_log); |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 | 747 |
748 #undef COMMAND_SIZE | 748 #undef COMMAND_SIZE |
749 #undef ARG_SIZE | 749 #undef ARG_SIZE |
750 | 750 |
751 #undef STR | 751 #undef STR |
752 #undef XSTR | 752 #undef XSTR |
753 } | 753 } |
754 | 754 |
755 | 755 |
756 static bool ICacheMatch(void* one, void* two) { | 756 static bool ICacheMatch(void* one, void* two) { |
757 ASSERT((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0); | 757 DCHECK((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0); |
758 ASSERT((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0); | 758 DCHECK((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0); |
759 return one == two; | 759 return one == two; |
760 } | 760 } |
761 | 761 |
762 | 762 |
763 static uint32_t ICacheHash(void* key) { | 763 static uint32_t ICacheHash(void* key) { |
764 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2; | 764 return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2; |
765 } | 765 } |
766 | 766 |
767 | 767 |
768 static bool AllOnOnePage(uintptr_t start, int size) { | 768 static bool AllOnOnePage(uintptr_t start, int size) { |
(...skipping 16 matching lines...) Expand all Loading... |
785 int intra_line = (start & CachePage::kLineMask); | 785 int intra_line = (start & CachePage::kLineMask); |
786 start -= intra_line; | 786 start -= intra_line; |
787 size += intra_line; | 787 size += intra_line; |
788 size = ((size - 1) | CachePage::kLineMask) + 1; | 788 size = ((size - 1) | CachePage::kLineMask) + 1; |
789 int offset = (start & CachePage::kPageMask); | 789 int offset = (start & CachePage::kPageMask); |
790 while (!AllOnOnePage(start, size - 1)) { | 790 while (!AllOnOnePage(start, size - 1)) { |
791 int bytes_to_flush = CachePage::kPageSize - offset; | 791 int bytes_to_flush = CachePage::kPageSize - offset; |
792 FlushOnePage(i_cache, start, bytes_to_flush); | 792 FlushOnePage(i_cache, start, bytes_to_flush); |
793 start += bytes_to_flush; | 793 start += bytes_to_flush; |
794 size -= bytes_to_flush; | 794 size -= bytes_to_flush; |
795 ASSERT_EQ(0, start & CachePage::kPageMask); | 795 DCHECK_EQ(0, start & CachePage::kPageMask); |
796 offset = 0; | 796 offset = 0; |
797 } | 797 } |
798 if (size != 0) { | 798 if (size != 0) { |
799 FlushOnePage(i_cache, start, size); | 799 FlushOnePage(i_cache, start, size); |
800 } | 800 } |
801 } | 801 } |
802 | 802 |
803 | 803 |
804 CachePage* Simulator::GetCachePage(v8::internal::HashMap* i_cache, void* page) { | 804 CachePage* Simulator::GetCachePage(v8::internal::HashMap* i_cache, void* page) { |
805 v8::internal::HashMap::Entry* entry = i_cache->Lookup(page, | 805 v8::internal::HashMap::Entry* entry = i_cache->Lookup(page, |
806 ICacheHash(page), | 806 ICacheHash(page), |
807 true); | 807 true); |
808 if (entry->value == NULL) { | 808 if (entry->value == NULL) { |
809 CachePage* new_page = new CachePage(); | 809 CachePage* new_page = new CachePage(); |
810 entry->value = new_page; | 810 entry->value = new_page; |
811 } | 811 } |
812 return reinterpret_cast<CachePage*>(entry->value); | 812 return reinterpret_cast<CachePage*>(entry->value); |
813 } | 813 } |
814 | 814 |
815 | 815 |
816 // Flush from start up to and not including start + size. | 816 // Flush from start up to and not including start + size. |
817 void Simulator::FlushOnePage(v8::internal::HashMap* i_cache, | 817 void Simulator::FlushOnePage(v8::internal::HashMap* i_cache, |
818 intptr_t start, | 818 intptr_t start, |
819 int size) { | 819 int size) { |
820 ASSERT(size <= CachePage::kPageSize); | 820 DCHECK(size <= CachePage::kPageSize); |
821 ASSERT(AllOnOnePage(start, size - 1)); | 821 DCHECK(AllOnOnePage(start, size - 1)); |
822 ASSERT((start & CachePage::kLineMask) == 0); | 822 DCHECK((start & CachePage::kLineMask) == 0); |
823 ASSERT((size & CachePage::kLineMask) == 0); | 823 DCHECK((size & CachePage::kLineMask) == 0); |
824 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask)); | 824 void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask)); |
825 int offset = (start & CachePage::kPageMask); | 825 int offset = (start & CachePage::kPageMask); |
826 CachePage* cache_page = GetCachePage(i_cache, page); | 826 CachePage* cache_page = GetCachePage(i_cache, page); |
827 char* valid_bytemap = cache_page->ValidityByte(offset); | 827 char* valid_bytemap = cache_page->ValidityByte(offset); |
828 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift); | 828 memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift); |
829 } | 829 } |
830 | 830 |
831 | 831 |
832 void Simulator::CheckICache(v8::internal::HashMap* i_cache, | 832 void Simulator::CheckICache(v8::internal::HashMap* i_cache, |
833 Instruction* instr) { | 833 Instruction* instr) { |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 ExternalReference::Type type) { | 972 ExternalReference::Type type) { |
973 Redirection* redirection = Redirection::Get(external_function, type); | 973 Redirection* redirection = Redirection::Get(external_function, type); |
974 return redirection->address_of_swi_instruction(); | 974 return redirection->address_of_swi_instruction(); |
975 } | 975 } |
976 | 976 |
977 | 977 |
978 // Get the active Simulator for the current thread. | 978 // Get the active Simulator for the current thread. |
979 Simulator* Simulator::current(Isolate* isolate) { | 979 Simulator* Simulator::current(Isolate* isolate) { |
980 v8::internal::Isolate::PerIsolateThreadData* isolate_data = | 980 v8::internal::Isolate::PerIsolateThreadData* isolate_data = |
981 isolate->FindOrAllocatePerThreadDataForThisThread(); | 981 isolate->FindOrAllocatePerThreadDataForThisThread(); |
982 ASSERT(isolate_data != NULL); | 982 DCHECK(isolate_data != NULL); |
983 ASSERT(isolate_data != NULL); | 983 DCHECK(isolate_data != NULL); |
984 | 984 |
985 Simulator* sim = isolate_data->simulator(); | 985 Simulator* sim = isolate_data->simulator(); |
986 if (sim == NULL) { | 986 if (sim == NULL) { |
987 // TODO(146): delete the simulator object when a thread/isolate goes away. | 987 // TODO(146): delete the simulator object when a thread/isolate goes away. |
988 sim = new Simulator(isolate); | 988 sim = new Simulator(isolate); |
989 isolate_data->set_simulator(sim); | 989 isolate_data->set_simulator(sim); |
990 } | 990 } |
991 return sim; | 991 return sim; |
992 } | 992 } |
993 | 993 |
994 | 994 |
995 // Sets the register in the architecture state. It will also deal with updating | 995 // Sets the register in the architecture state. It will also deal with updating |
996 // Simulator internal state for special registers such as PC. | 996 // Simulator internal state for special registers such as PC. |
997 void Simulator::set_register(int reg, int32_t value) { | 997 void Simulator::set_register(int reg, int32_t value) { |
998 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); | 998 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); |
999 if (reg == pc) { | 999 if (reg == pc) { |
1000 pc_modified_ = true; | 1000 pc_modified_ = true; |
1001 } | 1001 } |
1002 | 1002 |
1003 // Zero register always holds 0. | 1003 // Zero register always holds 0. |
1004 registers_[reg] = (reg == 0) ? 0 : value; | 1004 registers_[reg] = (reg == 0) ? 0 : value; |
1005 } | 1005 } |
1006 | 1006 |
1007 | 1007 |
1008 void Simulator::set_dw_register(int reg, const int* dbl) { | 1008 void Simulator::set_dw_register(int reg, const int* dbl) { |
1009 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); | 1009 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); |
1010 registers_[reg] = dbl[0]; | 1010 registers_[reg] = dbl[0]; |
1011 registers_[reg + 1] = dbl[1]; | 1011 registers_[reg + 1] = dbl[1]; |
1012 } | 1012 } |
1013 | 1013 |
1014 | 1014 |
1015 void Simulator::set_fpu_register(int fpureg, int32_t value) { | 1015 void Simulator::set_fpu_register(int fpureg, int32_t value) { |
1016 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1016 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1017 FPUregisters_[fpureg] = value; | 1017 FPUregisters_[fpureg] = value; |
1018 } | 1018 } |
1019 | 1019 |
1020 | 1020 |
1021 void Simulator::set_fpu_register_float(int fpureg, float value) { | 1021 void Simulator::set_fpu_register_float(int fpureg, float value) { |
1022 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1022 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1023 *BitCast<float*>(&FPUregisters_[fpureg]) = value; | 1023 *BitCast<float*>(&FPUregisters_[fpureg]) = value; |
1024 } | 1024 } |
1025 | 1025 |
1026 | 1026 |
1027 void Simulator::set_fpu_register_double(int fpureg, double value) { | 1027 void Simulator::set_fpu_register_double(int fpureg, double value) { |
1028 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); | 1028 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); |
1029 *BitCast<double*>(&FPUregisters_[fpureg]) = value; | 1029 *BitCast<double*>(&FPUregisters_[fpureg]) = value; |
1030 } | 1030 } |
1031 | 1031 |
1032 | 1032 |
1033 // Get the register from the architecture state. This function does handle | 1033 // Get the register from the architecture state. This function does handle |
1034 // the special case of accessing the PC register. | 1034 // the special case of accessing the PC register. |
1035 int32_t Simulator::get_register(int reg) const { | 1035 int32_t Simulator::get_register(int reg) const { |
1036 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); | 1036 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); |
1037 if (reg == 0) | 1037 if (reg == 0) |
1038 return 0; | 1038 return 0; |
1039 else | 1039 else |
1040 return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0); | 1040 return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0); |
1041 } | 1041 } |
1042 | 1042 |
1043 | 1043 |
1044 double Simulator::get_double_from_register_pair(int reg) { | 1044 double Simulator::get_double_from_register_pair(int reg) { |
1045 ASSERT((reg >= 0) && (reg < kNumSimuRegisters) && ((reg % 2) == 0)); | 1045 DCHECK((reg >= 0) && (reg < kNumSimuRegisters) && ((reg % 2) == 0)); |
1046 | 1046 |
1047 double dm_val = 0.0; | 1047 double dm_val = 0.0; |
1048 // Read the bits from the unsigned integer register_[] array | 1048 // Read the bits from the unsigned integer register_[] array |
1049 // into the double precision floating point value and return it. | 1049 // into the double precision floating point value and return it. |
1050 char buffer[2 * sizeof(registers_[0])]; | 1050 char buffer[2 * sizeof(registers_[0])]; |
1051 memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); | 1051 memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); |
1052 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); | 1052 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); |
1053 return(dm_val); | 1053 return(dm_val); |
1054 } | 1054 } |
1055 | 1055 |
1056 | 1056 |
1057 int32_t Simulator::get_fpu_register(int fpureg) const { | 1057 int32_t Simulator::get_fpu_register(int fpureg) const { |
1058 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1058 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1059 return FPUregisters_[fpureg]; | 1059 return FPUregisters_[fpureg]; |
1060 } | 1060 } |
1061 | 1061 |
1062 | 1062 |
1063 int64_t Simulator::get_fpu_register_long(int fpureg) const { | 1063 int64_t Simulator::get_fpu_register_long(int fpureg) const { |
1064 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); | 1064 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); |
1065 return *BitCast<int64_t*>( | 1065 return *BitCast<int64_t*>( |
1066 const_cast<int32_t*>(&FPUregisters_[fpureg])); | 1066 const_cast<int32_t*>(&FPUregisters_[fpureg])); |
1067 } | 1067 } |
1068 | 1068 |
1069 | 1069 |
1070 float Simulator::get_fpu_register_float(int fpureg) const { | 1070 float Simulator::get_fpu_register_float(int fpureg) const { |
1071 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1071 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1072 return *BitCast<float*>( | 1072 return *BitCast<float*>( |
1073 const_cast<int32_t*>(&FPUregisters_[fpureg])); | 1073 const_cast<int32_t*>(&FPUregisters_[fpureg])); |
1074 } | 1074 } |
1075 | 1075 |
1076 | 1076 |
1077 double Simulator::get_fpu_register_double(int fpureg) const { | 1077 double Simulator::get_fpu_register_double(int fpureg) const { |
1078 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); | 1078 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); |
1079 return *BitCast<double*>(const_cast<int32_t*>(&FPUregisters_[fpureg])); | 1079 return *BitCast<double*>(const_cast<int32_t*>(&FPUregisters_[fpureg])); |
1080 } | 1080 } |
1081 | 1081 |
1082 | 1082 |
1083 // Runtime FP routines take up to two double arguments and zero | 1083 // Runtime FP routines take up to two double arguments and zero |
1084 // or one integer arguments. All are constructed here, | 1084 // or one integer arguments. All are constructed here, |
1085 // from a0-a3 or f12 and f14. | 1085 // from a0-a3 or f12 and f14. |
1086 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { | 1086 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { |
1087 if (!IsMipsSoftFloatABI) { | 1087 if (!IsMipsSoftFloatABI) { |
1088 *x = get_fpu_register_double(12); | 1088 *x = get_fpu_register_double(12); |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1631 | 1631 |
1632 | 1632 |
1633 bool Simulator::IsStopInstruction(Instruction* instr) { | 1633 bool Simulator::IsStopInstruction(Instruction* instr) { |
1634 int32_t func = instr->FunctionFieldRaw(); | 1634 int32_t func = instr->FunctionFieldRaw(); |
1635 uint32_t code = static_cast<uint32_t>(instr->Bits(25, 6)); | 1635 uint32_t code = static_cast<uint32_t>(instr->Bits(25, 6)); |
1636 return (func == BREAK) && code > kMaxWatchpointCode && code <= kMaxStopCode; | 1636 return (func == BREAK) && code > kMaxWatchpointCode && code <= kMaxStopCode; |
1637 } | 1637 } |
1638 | 1638 |
1639 | 1639 |
1640 bool Simulator::IsEnabledStop(uint32_t code) { | 1640 bool Simulator::IsEnabledStop(uint32_t code) { |
1641 ASSERT(code <= kMaxStopCode); | 1641 DCHECK(code <= kMaxStopCode); |
1642 ASSERT(code > kMaxWatchpointCode); | 1642 DCHECK(code > kMaxWatchpointCode); |
1643 return !(watched_stops_[code].count & kStopDisabledBit); | 1643 return !(watched_stops_[code].count & kStopDisabledBit); |
1644 } | 1644 } |
1645 | 1645 |
1646 | 1646 |
1647 void Simulator::EnableStop(uint32_t code) { | 1647 void Simulator::EnableStop(uint32_t code) { |
1648 if (!IsEnabledStop(code)) { | 1648 if (!IsEnabledStop(code)) { |
1649 watched_stops_[code].count &= ~kStopDisabledBit; | 1649 watched_stops_[code].count &= ~kStopDisabledBit; |
1650 } | 1650 } |
1651 } | 1651 } |
1652 | 1652 |
1653 | 1653 |
1654 void Simulator::DisableStop(uint32_t code) { | 1654 void Simulator::DisableStop(uint32_t code) { |
1655 if (IsEnabledStop(code)) { | 1655 if (IsEnabledStop(code)) { |
1656 watched_stops_[code].count |= kStopDisabledBit; | 1656 watched_stops_[code].count |= kStopDisabledBit; |
1657 } | 1657 } |
1658 } | 1658 } |
1659 | 1659 |
1660 | 1660 |
1661 void Simulator::IncreaseStopCounter(uint32_t code) { | 1661 void Simulator::IncreaseStopCounter(uint32_t code) { |
1662 ASSERT(code <= kMaxStopCode); | 1662 DCHECK(code <= kMaxStopCode); |
1663 if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) { | 1663 if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) { |
1664 PrintF("Stop counter for code %i has overflowed.\n" | 1664 PrintF("Stop counter for code %i has overflowed.\n" |
1665 "Enabling this code and reseting the counter to 0.\n", code); | 1665 "Enabling this code and reseting the counter to 0.\n", code); |
1666 watched_stops_[code].count = 0; | 1666 watched_stops_[code].count = 0; |
1667 EnableStop(code); | 1667 EnableStop(code); |
1668 } else { | 1668 } else { |
1669 watched_stops_[code].count++; | 1669 watched_stops_[code].count++; |
1670 } | 1670 } |
1671 } | 1671 } |
1672 | 1672 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1733 | 1733 |
1734 // ---------- Configuration. | 1734 // ---------- Configuration. |
1735 switch (op) { | 1735 switch (op) { |
1736 case COP1: // Coprocessor instructions. | 1736 case COP1: // Coprocessor instructions. |
1737 switch (instr->RsFieldRaw()) { | 1737 switch (instr->RsFieldRaw()) { |
1738 case BC1: // Handled in DecodeTypeImmed, should never come here. | 1738 case BC1: // Handled in DecodeTypeImmed, should never come here. |
1739 UNREACHABLE(); | 1739 UNREACHABLE(); |
1740 break; | 1740 break; |
1741 case CFC1: | 1741 case CFC1: |
1742 // At the moment only FCSR is supported. | 1742 // At the moment only FCSR is supported. |
1743 ASSERT(fs_reg == kFCSRRegister); | 1743 DCHECK(fs_reg == kFCSRRegister); |
1744 *alu_out = FCSR_; | 1744 *alu_out = FCSR_; |
1745 break; | 1745 break; |
1746 case MFC1: | 1746 case MFC1: |
1747 *alu_out = get_fpu_register(fs_reg); | 1747 *alu_out = get_fpu_register(fs_reg); |
1748 break; | 1748 break; |
1749 case MFHC1: | 1749 case MFHC1: |
1750 UNIMPLEMENTED_MIPS(); | 1750 UNIMPLEMENTED_MIPS(); |
1751 break; | 1751 break; |
1752 case CTC1: | 1752 case CTC1: |
1753 case MTC1: | 1753 case MTC1: |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2004 case CFC1: | 2004 case CFC1: |
2005 set_register(rt_reg, alu_out); | 2005 set_register(rt_reg, alu_out); |
2006 case MFC1: | 2006 case MFC1: |
2007 set_register(rt_reg, alu_out); | 2007 set_register(rt_reg, alu_out); |
2008 break; | 2008 break; |
2009 case MFHC1: | 2009 case MFHC1: |
2010 UNIMPLEMENTED_MIPS(); | 2010 UNIMPLEMENTED_MIPS(); |
2011 break; | 2011 break; |
2012 case CTC1: | 2012 case CTC1: |
2013 // At the moment only FCSR is supported. | 2013 // At the moment only FCSR is supported. |
2014 ASSERT(fs_reg == kFCSRRegister); | 2014 DCHECK(fs_reg == kFCSRRegister); |
2015 FCSR_ = registers_[rt_reg]; | 2015 FCSR_ = registers_[rt_reg]; |
2016 break; | 2016 break; |
2017 case MTC1: | 2017 case MTC1: |
2018 FPUregisters_[fs_reg] = registers_[rt_reg]; | 2018 FPUregisters_[fs_reg] = registers_[rt_reg]; |
2019 break; | 2019 break; |
2020 case MTHC1: | 2020 case MTHC1: |
2021 UNIMPLEMENTED_MIPS(); | 2021 UNIMPLEMENTED_MIPS(); |
2022 break; | 2022 break; |
2023 case S: | 2023 case S: |
2024 float f; | 2024 float f; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2096 break; | 2096 break; |
2097 case C_OLE_D: | 2097 case C_OLE_D: |
2098 set_fcsr_bit(fcsr_cc, (fs <= ft)); | 2098 set_fcsr_bit(fcsr_cc, (fs <= ft)); |
2099 break; | 2099 break; |
2100 case C_ULE_D: | 2100 case C_ULE_D: |
2101 set_fcsr_bit(fcsr_cc, | 2101 set_fcsr_bit(fcsr_cc, |
2102 (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); | 2102 (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); |
2103 break; | 2103 break; |
2104 case CVT_W_D: // Convert double to word. | 2104 case CVT_W_D: // Convert double to word. |
2105 // Rounding modes are not yet supported. | 2105 // Rounding modes are not yet supported. |
2106 ASSERT((FCSR_ & 3) == 0); | 2106 DCHECK((FCSR_ & 3) == 0); |
2107 // In rounding mode 0 it should behave like ROUND. | 2107 // In rounding mode 0 it should behave like ROUND. |
2108 case ROUND_W_D: // Round double to word (round half to even). | 2108 case ROUND_W_D: // Round double to word (round half to even). |
2109 { | 2109 { |
2110 double rounded = std::floor(fs + 0.5); | 2110 double rounded = std::floor(fs + 0.5); |
2111 int32_t result = static_cast<int32_t>(rounded); | 2111 int32_t result = static_cast<int32_t>(rounded); |
2112 if ((result & 1) != 0 && result - fs == 0.5) { | 2112 if ((result & 1) != 0 && result - fs == 0.5) { |
2113 // If the number is halfway between two integers, | 2113 // If the number is halfway between two integers, |
2114 // round to the even one. | 2114 // round to the even one. |
2115 result--; | 2115 result--; |
2116 } | 2116 } |
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2840 set_register(fp, fp_val); | 2840 set_register(fp, fp_val); |
2841 } | 2841 } |
2842 | 2842 |
2843 | 2843 |
2844 int32_t Simulator::Call(byte* entry, int argument_count, ...) { | 2844 int32_t Simulator::Call(byte* entry, int argument_count, ...) { |
2845 va_list parameters; | 2845 va_list parameters; |
2846 va_start(parameters, argument_count); | 2846 va_start(parameters, argument_count); |
2847 // Set up arguments. | 2847 // Set up arguments. |
2848 | 2848 |
2849 // First four arguments passed in registers. | 2849 // First four arguments passed in registers. |
2850 ASSERT(argument_count >= 4); | 2850 DCHECK(argument_count >= 4); |
2851 set_register(a0, va_arg(parameters, int32_t)); | 2851 set_register(a0, va_arg(parameters, int32_t)); |
2852 set_register(a1, va_arg(parameters, int32_t)); | 2852 set_register(a1, va_arg(parameters, int32_t)); |
2853 set_register(a2, va_arg(parameters, int32_t)); | 2853 set_register(a2, va_arg(parameters, int32_t)); |
2854 set_register(a3, va_arg(parameters, int32_t)); | 2854 set_register(a3, va_arg(parameters, int32_t)); |
2855 | 2855 |
2856 // Remaining arguments passed on stack. | 2856 // Remaining arguments passed on stack. |
2857 int original_stack = get_register(sp); | 2857 int original_stack = get_register(sp); |
2858 // Compute position of stack on entry to generated code. | 2858 // Compute position of stack on entry to generated code. |
2859 int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t) | 2859 int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t) |
2860 - kCArgsSlotsSize); | 2860 - kCArgsSlotsSize); |
(...skipping 18 matching lines...) Expand all Loading... |
2879 return result; | 2879 return result; |
2880 } | 2880 } |
2881 | 2881 |
2882 | 2882 |
2883 double Simulator::CallFP(byte* entry, double d0, double d1) { | 2883 double Simulator::CallFP(byte* entry, double d0, double d1) { |
2884 if (!IsMipsSoftFloatABI) { | 2884 if (!IsMipsSoftFloatABI) { |
2885 set_fpu_register_double(f12, d0); | 2885 set_fpu_register_double(f12, d0); |
2886 set_fpu_register_double(f14, d1); | 2886 set_fpu_register_double(f14, d1); |
2887 } else { | 2887 } else { |
2888 int buffer[2]; | 2888 int buffer[2]; |
2889 ASSERT(sizeof(buffer[0]) * 2 == sizeof(d0)); | 2889 DCHECK(sizeof(buffer[0]) * 2 == sizeof(d0)); |
2890 memcpy(buffer, &d0, sizeof(d0)); | 2890 memcpy(buffer, &d0, sizeof(d0)); |
2891 set_dw_register(a0, buffer); | 2891 set_dw_register(a0, buffer); |
2892 memcpy(buffer, &d1, sizeof(d1)); | 2892 memcpy(buffer, &d1, sizeof(d1)); |
2893 set_dw_register(a2, buffer); | 2893 set_dw_register(a2, buffer); |
2894 } | 2894 } |
2895 CallInternal(entry); | 2895 CallInternal(entry); |
2896 if (!IsMipsSoftFloatABI) { | 2896 if (!IsMipsSoftFloatABI) { |
2897 return get_fpu_register_double(f0); | 2897 return get_fpu_register_double(f0); |
2898 } else { | 2898 } else { |
2899 return get_double_from_register_pair(v0); | 2899 return get_double_from_register_pair(v0); |
(...skipping 19 matching lines...) Expand all Loading... |
2919 } | 2919 } |
2920 | 2920 |
2921 | 2921 |
2922 #undef UNSUPPORTED | 2922 #undef UNSUPPORTED |
2923 | 2923 |
2924 } } // namespace v8::internal | 2924 } } // namespace v8::internal |
2925 | 2925 |
2926 #endif // USE_SIMULATOR | 2926 #endif // USE_SIMULATOR |
2927 | 2927 |
2928 #endif // V8_TARGET_ARCH_MIPS | 2928 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |