| OLD | NEW |
| 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 <math.h> // for isnan. | 5 #include <math.h> // for isnan. |
| 6 #include <setjmp.h> | 6 #include <setjmp.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
| 10 #if defined(TARGET_ARCH_MIPS) | 10 #if defined(TARGET_ARCH_MIPS) |
| (...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 fregisters_[reg + 1] = Utils::High32Bits(value); | 720 fregisters_[reg + 1] = Utils::High32Bits(value); |
| 721 } | 721 } |
| 722 | 722 |
| 723 | 723 |
| 724 void Simulator::set_fregister_double(FRegister reg, double value) { | 724 void Simulator::set_fregister_double(FRegister reg, double value) { |
| 725 const int64_t ival = bit_cast<int64_t, double>(value); | 725 const int64_t ival = bit_cast<int64_t, double>(value); |
| 726 set_fregister_long(reg, ival); | 726 set_fregister_long(reg, ival); |
| 727 } | 727 } |
| 728 | 728 |
| 729 | 729 |
| 730 void Simulator::set_dregister_bits(DRegister reg, int64_t value) { |
| 731 ASSERT(reg >= 0); |
| 732 ASSERT(reg < kNumberOfDRegisters); |
| 733 FRegister lo = static_cast<FRegister>(reg * 2); |
| 734 FRegister hi = static_cast<FRegister>((reg * 2) + 1); |
| 735 set_fregister(lo, Utils::Low32Bits(value)); |
| 736 set_fregister(hi, Utils::High32Bits(value)); |
| 737 } |
| 738 |
| 739 |
| 740 void Simulator::set_dregister(DRegister reg, double value) { |
| 741 ASSERT(reg >= 0); |
| 742 ASSERT(reg < kNumberOfDRegisters); |
| 743 set_dregister_bits(reg, bit_cast<int64_t, double>(value)); |
| 744 } |
| 745 |
| 746 |
| 730 // Get the register from the architecture state. | 747 // Get the register from the architecture state. |
| 731 int32_t Simulator::get_register(Register reg) const { | 748 int32_t Simulator::get_register(Register reg) const { |
| 732 if (reg == R0) { | 749 if (reg == R0) { |
| 733 return 0; | 750 return 0; |
| 734 } | 751 } |
| 735 return registers_[reg]; | 752 return registers_[reg]; |
| 736 } | 753 } |
| 737 | 754 |
| 738 | 755 |
| 739 int32_t Simulator::get_fregister(FRegister reg) const { | 756 int32_t Simulator::get_fregister(FRegister reg) const { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 762 | 779 |
| 763 double Simulator::get_fregister_double(FRegister reg) const { | 780 double Simulator::get_fregister_double(FRegister reg) const { |
| 764 ASSERT(reg >= 0); | 781 ASSERT(reg >= 0); |
| 765 ASSERT(reg < kNumberOfFRegisters); | 782 ASSERT(reg < kNumberOfFRegisters); |
| 766 ASSERT((reg & 1) == 0); | 783 ASSERT((reg & 1) == 0); |
| 767 const int64_t value = get_fregister_long(reg); | 784 const int64_t value = get_fregister_long(reg); |
| 768 return bit_cast<double, int64_t>(value); | 785 return bit_cast<double, int64_t>(value); |
| 769 } | 786 } |
| 770 | 787 |
| 771 | 788 |
| 789 int64_t Simulator::get_dregister_bits(DRegister reg) const { |
| 790 ASSERT(reg >= 0); |
| 791 ASSERT(reg < kNumberOfDRegisters); |
| 792 FRegister lo = static_cast<FRegister>(reg * 2); |
| 793 FRegister hi = static_cast<FRegister>((reg * 2) + 1); |
| 794 return Utils::LowHighTo64Bits(get_fregister(lo), get_fregister(hi)); |
| 795 } |
| 796 |
| 797 |
| 798 double Simulator::get_dregister(DRegister reg) const { |
| 799 ASSERT(reg >= 0); |
| 800 ASSERT(reg < kNumberOfDRegisters); |
| 801 const int64_t value = get_dregister_bits(reg); |
| 802 return bit_cast<double, int64_t>(value); |
| 803 } |
| 804 |
| 805 |
| 772 void Simulator::UnimplementedInstruction(Instr* instr) { | 806 void Simulator::UnimplementedInstruction(Instr* instr) { |
| 773 char buffer[64]; | 807 char buffer[64]; |
| 774 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr); | 808 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr); |
| 775 SimulatorDebugger dbg(this); | 809 SimulatorDebugger dbg(this); |
| 776 dbg.Stop(instr, buffer); | 810 dbg.Stop(instr, buffer); |
| 777 FATAL("Cannot continue execution after unimplemented instruction."); | 811 FATAL("Cannot continue execution after unimplemented instruction."); |
| 778 } | 812 } |
| 779 | 813 |
| 780 | 814 |
| 781 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) { | 815 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) { |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1090 DoBreak(instr); | 1124 DoBreak(instr); |
| 1091 break; | 1125 break; |
| 1092 } | 1126 } |
| 1093 case DIV: { | 1127 case DIV: { |
| 1094 ASSERT(instr->RdField() == 0); | 1128 ASSERT(instr->RdField() == 0); |
| 1095 ASSERT(instr->SaField() == 0); | 1129 ASSERT(instr->SaField() == 0); |
| 1096 // Format(instr, "div 'rs, 'rt"); | 1130 // Format(instr, "div 'rs, 'rt"); |
| 1097 int32_t rs_val = get_register(instr->RsField()); | 1131 int32_t rs_val = get_register(instr->RsField()); |
| 1098 int32_t rt_val = get_register(instr->RtField()); | 1132 int32_t rt_val = get_register(instr->RtField()); |
| 1099 if (rt_val == 0) { | 1133 if (rt_val == 0) { |
| 1100 // Results are unpredictable. | 1134 // Results are unpredictable, but there is no arithmetic exception. |
| 1101 set_hi_register(0); | 1135 set_hi_register(icount_); |
| 1102 set_lo_register(0); | 1136 set_lo_register(icount_); |
| 1103 // TODO(zra): Drop into the debugger here. | |
| 1104 break; | 1137 break; |
| 1105 } | 1138 } |
| 1106 | 1139 |
| 1107 if ((rs_val == static_cast<int32_t>(0x80000000)) && | 1140 if ((rs_val == static_cast<int32_t>(0x80000000)) && |
| 1108 (rt_val == static_cast<int32_t>(0xffffffff))) { | 1141 (rt_val == static_cast<int32_t>(0xffffffff))) { |
| 1109 set_lo_register(0x80000000); | 1142 set_lo_register(0x80000000); |
| 1110 set_hi_register(0); | 1143 set_hi_register(0); |
| 1111 } else { | 1144 } else { |
| 1112 set_lo_register(rs_val / rt_val); | 1145 set_lo_register(rs_val / rt_val); |
| 1113 set_hi_register(rs_val % rt_val); | 1146 set_hi_register(rs_val % rt_val); |
| 1114 } | 1147 } |
| 1115 break; | 1148 break; |
| 1116 } | 1149 } |
| 1117 case DIVU: { | 1150 case DIVU: { |
| 1118 ASSERT(instr->RdField() == 0); | 1151 ASSERT(instr->RdField() == 0); |
| 1119 ASSERT(instr->SaField() == 0); | 1152 ASSERT(instr->SaField() == 0); |
| 1120 // Format(instr, "divu 'rs, 'rt"); | 1153 // Format(instr, "divu 'rs, 'rt"); |
| 1121 uint32_t rs_val = get_register(instr->RsField()); | 1154 uint32_t rs_val = get_register(instr->RsField()); |
| 1122 uint32_t rt_val = get_register(instr->RtField()); | 1155 uint32_t rt_val = get_register(instr->RtField()); |
| 1123 if (rt_val == 0) { | 1156 if (rt_val == 0) { |
| 1124 // Results are unpredictable. | 1157 // Results are unpredictable, but there is no arithmetic exception. |
| 1125 set_hi_register(0); | 1158 set_hi_register(icount_); |
| 1126 set_lo_register(0); | 1159 set_lo_register(icount_); |
| 1127 // TODO(zra): Drop into the debugger here. | |
| 1128 break; | 1160 break; |
| 1129 } | 1161 } |
| 1130 set_lo_register(rs_val / rt_val); | 1162 set_lo_register(rs_val / rt_val); |
| 1131 set_hi_register(rs_val % rt_val); | 1163 set_hi_register(rs_val % rt_val); |
| 1132 break; | 1164 break; |
| 1133 } | 1165 } |
| 1134 case JALR: { | 1166 case JALR: { |
| 1135 ASSERT(instr->RtField() == R0); | 1167 ASSERT(instr->RtField() == R0); |
| 1136 ASSERT(instr->RsField() != instr->RdField()); | 1168 ASSERT(instr->RsField() != instr->RdField()); |
| 1137 ASSERT(!delay_slot_); | 1169 ASSERT(!delay_slot_); |
| (...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2014 } | 2046 } |
| 2015 } | 2047 } |
| 2016 } | 2048 } |
| 2017 } | 2049 } |
| 2018 | 2050 |
| 2019 | 2051 |
| 2020 int64_t Simulator::Call(int32_t entry, | 2052 int64_t Simulator::Call(int32_t entry, |
| 2021 int32_t parameter0, | 2053 int32_t parameter0, |
| 2022 int32_t parameter1, | 2054 int32_t parameter1, |
| 2023 int32_t parameter2, | 2055 int32_t parameter2, |
| 2024 int32_t parameter3) { | 2056 int32_t parameter3, |
| 2057 bool fp_return) { |
| 2025 // Save the SP register before the call so we can restore it. | 2058 // Save the SP register before the call so we can restore it. |
| 2026 int32_t sp_before_call = get_register(SP); | 2059 int32_t sp_before_call = get_register(SP); |
| 2027 | 2060 |
| 2028 // Setup parameters. | 2061 // Setup parameters. |
| 2029 set_register(A0, parameter0); | 2062 set_register(A0, parameter0); |
| 2030 set_register(A1, parameter1); | 2063 set_register(A1, parameter1); |
| 2031 set_register(A2, parameter2); | 2064 set_register(A2, parameter2); |
| 2032 set_register(A3, parameter3); | 2065 set_register(A3, parameter3); |
| 2033 | 2066 |
| 2034 // Make sure the activation frames are properly aligned. | 2067 // Make sure the activation frames are properly aligned. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2051 // simulator code and therefore is regarded as a callee-saved register. | 2084 // simulator code and therefore is regarded as a callee-saved register. |
| 2052 int32_t r16_val = get_register(R16); | 2085 int32_t r16_val = get_register(R16); |
| 2053 int32_t r17_val = get_register(R17); | 2086 int32_t r17_val = get_register(R17); |
| 2054 int32_t r18_val = get_register(R18); | 2087 int32_t r18_val = get_register(R18); |
| 2055 int32_t r19_val = get_register(R19); | 2088 int32_t r19_val = get_register(R19); |
| 2056 int32_t r20_val = get_register(R20); | 2089 int32_t r20_val = get_register(R20); |
| 2057 int32_t r21_val = get_register(R21); | 2090 int32_t r21_val = get_register(R21); |
| 2058 int32_t r22_val = get_register(R22); | 2091 int32_t r22_val = get_register(R22); |
| 2059 int32_t r23_val = get_register(R23); | 2092 int32_t r23_val = get_register(R23); |
| 2060 | 2093 |
| 2094 double d10_val = get_dregister(D10); |
| 2095 double d11_val = get_dregister(D11); |
| 2096 double d12_val = get_dregister(D12); |
| 2097 double d13_val = get_dregister(D13); |
| 2098 double d14_val = get_dregister(D14); |
| 2099 double d15_val = get_dregister(D15); |
| 2100 |
| 2061 // Setup the callee-saved registers with a known value. To be able to check | 2101 // Setup the callee-saved registers with a known value. To be able to check |
| 2062 // that they are preserved properly across dart execution. | 2102 // that they are preserved properly across dart execution. |
| 2063 int32_t callee_saved_value = icount_; | 2103 int32_t callee_saved_value = icount_; |
| 2064 set_register(R16, callee_saved_value); | 2104 set_register(R16, callee_saved_value); |
| 2065 set_register(R17, callee_saved_value); | 2105 set_register(R17, callee_saved_value); |
| 2066 set_register(R18, callee_saved_value); | 2106 set_register(R18, callee_saved_value); |
| 2067 set_register(R19, callee_saved_value); | 2107 set_register(R19, callee_saved_value); |
| 2068 set_register(R20, callee_saved_value); | 2108 set_register(R20, callee_saved_value); |
| 2069 set_register(R21, callee_saved_value); | 2109 set_register(R21, callee_saved_value); |
| 2070 set_register(R22, callee_saved_value); | 2110 set_register(R22, callee_saved_value); |
| 2071 set_register(R23, callee_saved_value); | 2111 set_register(R23, callee_saved_value); |
| 2072 | 2112 |
| 2113 set_dregister_bits(D10, callee_saved_value); |
| 2114 set_dregister_bits(D11, callee_saved_value); |
| 2115 set_dregister_bits(D12, callee_saved_value); |
| 2116 set_dregister_bits(D13, callee_saved_value); |
| 2117 set_dregister_bits(D14, callee_saved_value); |
| 2118 set_dregister_bits(D15, callee_saved_value); |
| 2119 |
| 2073 // Start the simulation | 2120 // Start the simulation |
| 2074 Execute(); | 2121 Execute(); |
| 2075 | 2122 |
| 2076 // Check that the callee-saved registers have been preserved. | 2123 // Check that the callee-saved registers have been preserved. |
| 2077 ASSERT(callee_saved_value == get_register(R16)); | 2124 ASSERT(callee_saved_value == get_register(R16)); |
| 2078 ASSERT(callee_saved_value == get_register(R17)); | 2125 ASSERT(callee_saved_value == get_register(R17)); |
| 2079 ASSERT(callee_saved_value == get_register(R18)); | 2126 ASSERT(callee_saved_value == get_register(R18)); |
| 2080 ASSERT(callee_saved_value == get_register(R19)); | 2127 ASSERT(callee_saved_value == get_register(R19)); |
| 2081 ASSERT(callee_saved_value == get_register(R20)); | 2128 ASSERT(callee_saved_value == get_register(R20)); |
| 2082 ASSERT(callee_saved_value == get_register(R21)); | 2129 ASSERT(callee_saved_value == get_register(R21)); |
| 2083 ASSERT(callee_saved_value == get_register(R22)); | 2130 ASSERT(callee_saved_value == get_register(R22)); |
| 2084 ASSERT(callee_saved_value == get_register(R23)); | 2131 ASSERT(callee_saved_value == get_register(R23)); |
| 2085 | 2132 |
| 2133 ASSERT(callee_saved_value == get_dregister_bits(D10)); |
| 2134 ASSERT(callee_saved_value == get_dregister_bits(D11)); |
| 2135 ASSERT(callee_saved_value == get_dregister_bits(D12)); |
| 2136 ASSERT(callee_saved_value == get_dregister_bits(D13)); |
| 2137 ASSERT(callee_saved_value == get_dregister_bits(D14)); |
| 2138 ASSERT(callee_saved_value == get_dregister_bits(D15)); |
| 2139 |
| 2086 // Restore callee-saved registers with the original value. | 2140 // Restore callee-saved registers with the original value. |
| 2087 set_register(R16, r16_val); | 2141 set_register(R16, r16_val); |
| 2088 set_register(R17, r17_val); | 2142 set_register(R17, r17_val); |
| 2089 set_register(R18, r18_val); | 2143 set_register(R18, r18_val); |
| 2090 set_register(R19, r19_val); | 2144 set_register(R19, r19_val); |
| 2091 set_register(R20, r20_val); | 2145 set_register(R20, r20_val); |
| 2092 set_register(R21, r21_val); | 2146 set_register(R21, r21_val); |
| 2093 set_register(R22, r22_val); | 2147 set_register(R22, r22_val); |
| 2094 set_register(R23, r23_val); | 2148 set_register(R23, r23_val); |
| 2095 | 2149 |
| 2150 set_dregister(D10, d10_val); |
| 2151 set_dregister(D11, d11_val); |
| 2152 set_dregister(D12, d12_val); |
| 2153 set_dregister(D13, d13_val); |
| 2154 set_dregister(D14, d14_val); |
| 2155 set_dregister(D15, d15_val); |
| 2156 |
| 2096 // Restore the SP register and return V1:V0. | 2157 // Restore the SP register and return V1:V0. |
| 2097 set_register(SP, sp_before_call); | 2158 set_register(SP, sp_before_call); |
| 2098 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1)); | 2159 int64_t return_value; |
| 2160 if (fp_return) { |
| 2161 return_value = Utils::LowHighTo64Bits(get_fregister(F0), get_fregister(F1)); |
| 2162 } else { |
| 2163 return_value = Utils::LowHighTo64Bits(get_register(V0), get_register(V1)); |
| 2164 } |
| 2165 return return_value; |
| 2099 } | 2166 } |
| 2100 | 2167 |
| 2101 | 2168 |
| 2102 void Simulator::Longjmp(uword pc, | 2169 void Simulator::Longjmp(uword pc, |
| 2103 uword sp, | 2170 uword sp, |
| 2104 uword fp, | 2171 uword fp, |
| 2105 RawObject* raw_exception, | 2172 RawObject* raw_exception, |
| 2106 RawObject* raw_stacktrace) { | 2173 RawObject* raw_stacktrace) { |
| 2107 // Walk over all setjmp buffers (simulated --> C++ transitions) | 2174 // Walk over all setjmp buffers (simulated --> C++ transitions) |
| 2108 // and try to find the setjmp associated with the simulated stack pointer. | 2175 // and try to find the setjmp associated with the simulated stack pointer. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2132 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); | 2199 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); |
| 2133 } | 2200 } |
| 2134 buf->Longjmp(); | 2201 buf->Longjmp(); |
| 2135 } | 2202 } |
| 2136 | 2203 |
| 2137 } // namespace dart | 2204 } // namespace dart |
| 2138 | 2205 |
| 2139 #endif // !defined(HOST_ARCH_MIPS) | 2206 #endif // !defined(HOST_ARCH_MIPS) |
| 2140 | 2207 |
| 2141 #endif // defined TARGET_ARCH_MIPS | 2208 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |