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 |