| 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 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 fregisters_[reg + 1] = Utils::High32Bits(value); | 675 fregisters_[reg + 1] = Utils::High32Bits(value); |
| 676 } | 676 } |
| 677 | 677 |
| 678 | 678 |
| 679 void Simulator::set_fregister_double(FRegister reg, double value) { | 679 void Simulator::set_fregister_double(FRegister reg, double value) { |
| 680 const int64_t ival = bit_cast<int64_t, double>(value); | 680 const int64_t ival = bit_cast<int64_t, double>(value); |
| 681 set_fregister_long(reg, ival); | 681 set_fregister_long(reg, ival); |
| 682 } | 682 } |
| 683 | 683 |
| 684 | 684 |
| 685 void Simulator::set_dregister(DRegister reg, int64_t value) { |
| 686 ASSERT(reg >= 0); |
| 687 ASSERT(reg < kNumberOfDRegisters); |
| 688 FRegister lo = static_cast<FRegister>(reg * 2); |
| 689 FRegister hi = static_cast<FRegister>((reg * 2) + 1); |
| 690 set_fregister(lo, Utils::Low32Bits(value)); |
| 691 set_fregister(hi, Utils::High32Bits(value)); |
| 692 } |
| 693 |
| 694 |
| 695 void Simulator::set_dregister_double(DRegister reg, double value) { |
| 696 ASSERT(reg >= 0); |
| 697 ASSERT(reg < kNumberOfDRegisters); |
| 698 set_dregister(reg, bit_cast<int64_t, double>(value)); |
| 699 } |
| 700 |
| 701 |
| 685 // Get the register from the architecture state. | 702 // Get the register from the architecture state. |
| 686 int32_t Simulator::get_register(Register reg) const { | 703 int32_t Simulator::get_register(Register reg) const { |
| 687 if (reg == R0) { | 704 if (reg == R0) { |
| 688 return 0; | 705 return 0; |
| 689 } | 706 } |
| 690 return registers_[reg]; | 707 return registers_[reg]; |
| 691 } | 708 } |
| 692 | 709 |
| 693 | 710 |
| 694 int32_t Simulator::get_fregister(FRegister reg) const { | 711 int32_t Simulator::get_fregister(FRegister reg) const { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 717 | 734 |
| 718 double Simulator::get_fregister_double(FRegister reg) const { | 735 double Simulator::get_fregister_double(FRegister reg) const { |
| 719 ASSERT(reg >= 0); | 736 ASSERT(reg >= 0); |
| 720 ASSERT(reg < kNumberOfFRegisters); | 737 ASSERT(reg < kNumberOfFRegisters); |
| 721 ASSERT((reg & 1) == 0); | 738 ASSERT((reg & 1) == 0); |
| 722 const int64_t value = get_fregister_long(reg); | 739 const int64_t value = get_fregister_long(reg); |
| 723 return bit_cast<double, int64_t>(value); | 740 return bit_cast<double, int64_t>(value); |
| 724 } | 741 } |
| 725 | 742 |
| 726 | 743 |
| 744 int64_t Simulator::get_dregister(DRegister reg) const { |
| 745 ASSERT(reg >= 0); |
| 746 ASSERT(reg < kNumberOfDRegisters); |
| 747 FRegister lo = static_cast<FRegister>(reg * 2); |
| 748 FRegister hi = static_cast<FRegister>((reg * 2) + 1); |
| 749 return Utils::LowHighTo64Bits(get_fregister(lo), get_fregister(hi)); |
| 750 } |
| 751 |
| 752 |
| 753 double Simulator::get_dregister_double(DRegister reg) const { |
| 754 ASSERT(reg >= 0); |
| 755 ASSERT(reg < kNumberOfDRegisters); |
| 756 const int64_t value = get_dregister(reg); |
| 757 return bit_cast<double, int64_t>(value); |
| 758 } |
| 759 |
| 760 |
| 727 void Simulator::UnimplementedInstruction(Instr* instr) { | 761 void Simulator::UnimplementedInstruction(Instr* instr) { |
| 728 char buffer[64]; | 762 char buffer[64]; |
| 729 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr); | 763 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr); |
| 730 SimulatorDebugger dbg(this); | 764 SimulatorDebugger dbg(this); |
| 731 dbg.Stop(instr, buffer); | 765 dbg.Stop(instr, buffer); |
| 732 FATAL("Cannot continue execution after unimplemented instruction."); | 766 FATAL("Cannot continue execution after unimplemented instruction."); |
| 733 } | 767 } |
| 734 | 768 |
| 735 | 769 |
| 736 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) { | 770 void Simulator::HandleIllegalAccess(uword addr, Instr* instr) { |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 979 | 1013 |
| 980 set_register(A0, icount_); | 1014 set_register(A0, icount_); |
| 981 set_register(A1, icount_); | 1015 set_register(A1, icount_); |
| 982 set_register(A2, icount_); | 1016 set_register(A2, icount_); |
| 983 set_register(A3, icount_); | 1017 set_register(A3, icount_); |
| 984 set_register(TMP, icount_); | 1018 set_register(TMP, icount_); |
| 985 set_register(RA, icount_); | 1019 set_register(RA, icount_); |
| 986 | 1020 |
| 987 // Zap floating point registers. | 1021 // Zap floating point registers. |
| 988 int32_t zap_dvalue = icount_; | 1022 int32_t zap_dvalue = icount_; |
| 989 for (int i = F0; i <= F31; i++) { | 1023 for (int i = F0; i <= F18; i++) { |
| 990 set_fregister(static_cast<FRegister>(i), zap_dvalue); | 1024 set_fregister(static_cast<FRegister>(i), zap_dvalue); |
| 991 } | 1025 } |
| 992 | 1026 |
| 993 // Return. Subtract to account for pc_ increment after return. | 1027 // Return. Subtract to account for pc_ increment after return. |
| 994 set_pc(saved_ra - Instr::kInstrSize); | 1028 set_pc(saved_ra - Instr::kInstrSize); |
| 995 } else { | 1029 } else { |
| 996 // Coming via long jump from a throw. Continue to exception handler. | 1030 // Coming via long jump from a throw. Continue to exception handler. |
| 997 set_top_exit_frame_info(0); | 1031 set_top_exit_frame_info(0); |
| 998 // Adjust for extra pc increment. | 1032 // Adjust for extra pc increment. |
| 999 set_pc(get_pc() - Instr::kInstrSize); | 1033 set_pc(get_pc() - Instr::kInstrSize); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1030 DoBreak(instr); | 1064 DoBreak(instr); |
| 1031 break; | 1065 break; |
| 1032 } | 1066 } |
| 1033 case DIV: { | 1067 case DIV: { |
| 1034 ASSERT(instr->RdField() == 0); | 1068 ASSERT(instr->RdField() == 0); |
| 1035 ASSERT(instr->SaField() == 0); | 1069 ASSERT(instr->SaField() == 0); |
| 1036 // Format(instr, "div 'rs, 'rt"); | 1070 // Format(instr, "div 'rs, 'rt"); |
| 1037 int32_t rs_val = get_register(instr->RsField()); | 1071 int32_t rs_val = get_register(instr->RsField()); |
| 1038 int32_t rt_val = get_register(instr->RtField()); | 1072 int32_t rt_val = get_register(instr->RtField()); |
| 1039 if (rt_val == 0) { | 1073 if (rt_val == 0) { |
| 1040 // Results are unpredictable. | 1074 // Results are unpredictable, but there is no arithmetic exception. |
| 1041 set_hi_register(0); | 1075 set_hi_register(icount_); |
| 1042 set_lo_register(0); | 1076 set_lo_register(icount_); |
| 1043 // TODO(zra): Drop into the debugger here. | |
| 1044 break; | 1077 break; |
| 1045 } | 1078 } |
| 1046 | 1079 |
| 1047 if ((rs_val == static_cast<int32_t>(0x80000000)) && | 1080 if ((rs_val == static_cast<int32_t>(0x80000000)) && |
| 1048 (rt_val == static_cast<int32_t>(0xffffffff))) { | 1081 (rt_val == static_cast<int32_t>(0xffffffff))) { |
| 1049 set_lo_register(0x80000000); | 1082 set_lo_register(0x80000000); |
| 1050 set_hi_register(0); | 1083 set_hi_register(0); |
| 1051 } else { | 1084 } else { |
| 1052 set_lo_register(rs_val / rt_val); | 1085 set_lo_register(rs_val / rt_val); |
| 1053 set_hi_register(rs_val % rt_val); | 1086 set_hi_register(rs_val % rt_val); |
| 1054 } | 1087 } |
| 1055 break; | 1088 break; |
| 1056 } | 1089 } |
| 1057 case DIVU: { | 1090 case DIVU: { |
| 1058 ASSERT(instr->RdField() == 0); | 1091 ASSERT(instr->RdField() == 0); |
| 1059 ASSERT(instr->SaField() == 0); | 1092 ASSERT(instr->SaField() == 0); |
| 1060 // Format(instr, "divu 'rs, 'rt"); | 1093 // Format(instr, "divu 'rs, 'rt"); |
| 1061 uint32_t rs_val = get_register(instr->RsField()); | 1094 uint32_t rs_val = get_register(instr->RsField()); |
| 1062 uint32_t rt_val = get_register(instr->RtField()); | 1095 uint32_t rt_val = get_register(instr->RtField()); |
| 1063 if (rt_val == 0) { | 1096 if (rt_val == 0) { |
| 1064 // Results are unpredictable. | 1097 // Results are unpredictable, but there is no arithmetic exception. |
| 1065 set_hi_register(0); | 1098 set_hi_register(icount_); |
| 1066 set_lo_register(0); | 1099 set_lo_register(icount_); |
| 1067 // TODO(zra): Drop into the debugger here. | |
| 1068 break; | 1100 break; |
| 1069 } | 1101 } |
| 1070 set_lo_register(rs_val / rt_val); | 1102 set_lo_register(rs_val / rt_val); |
| 1071 set_hi_register(rs_val % rt_val); | 1103 set_hi_register(rs_val % rt_val); |
| 1072 break; | 1104 break; |
| 1073 } | 1105 } |
| 1074 case JALR: { | 1106 case JALR: { |
| 1075 ASSERT(instr->RtField() == R0); | 1107 ASSERT(instr->RtField() == R0); |
| 1076 ASSERT(instr->RsField() != instr->RdField()); | 1108 ASSERT(instr->RsField() != instr->RdField()); |
| 1077 ASSERT(!delay_slot_); | 1109 ASSERT(!delay_slot_); |
| (...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1934 } | 1966 } |
| 1935 } | 1967 } |
| 1936 } | 1968 } |
| 1937 } | 1969 } |
| 1938 | 1970 |
| 1939 | 1971 |
| 1940 int64_t Simulator::Call(int32_t entry, | 1972 int64_t Simulator::Call(int32_t entry, |
| 1941 int32_t parameter0, | 1973 int32_t parameter0, |
| 1942 int32_t parameter1, | 1974 int32_t parameter1, |
| 1943 int32_t parameter2, | 1975 int32_t parameter2, |
| 1944 int32_t parameter3) { | 1976 int32_t parameter3, |
| 1977 bool fp_return) { |
| 1945 // Save the SP register before the call so we can restore it. | 1978 // Save the SP register before the call so we can restore it. |
| 1946 int32_t sp_before_call = get_register(SP); | 1979 int32_t sp_before_call = get_register(SP); |
| 1947 | 1980 |
| 1948 // Setup parameters. | 1981 // Setup parameters. |
| 1949 set_register(A0, parameter0); | 1982 set_register(A0, parameter0); |
| 1950 set_register(A1, parameter1); | 1983 set_register(A1, parameter1); |
| 1951 set_register(A2, parameter2); | 1984 set_register(A2, parameter2); |
| 1952 set_register(A3, parameter3); | 1985 set_register(A3, parameter3); |
| 1953 | 1986 |
| 1954 // Make sure the activation frames are properly aligned. | 1987 // Make sure the activation frames are properly aligned. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1971 // simulator code and therefore is regarded as a callee-saved register. | 2004 // simulator code and therefore is regarded as a callee-saved register. |
| 1972 int32_t r16_val = get_register(R16); | 2005 int32_t r16_val = get_register(R16); |
| 1973 int32_t r17_val = get_register(R17); | 2006 int32_t r17_val = get_register(R17); |
| 1974 int32_t r18_val = get_register(R18); | 2007 int32_t r18_val = get_register(R18); |
| 1975 int32_t r19_val = get_register(R19); | 2008 int32_t r19_val = get_register(R19); |
| 1976 int32_t r20_val = get_register(R20); | 2009 int32_t r20_val = get_register(R20); |
| 1977 int32_t r21_val = get_register(R21); | 2010 int32_t r21_val = get_register(R21); |
| 1978 int32_t r22_val = get_register(R22); | 2011 int32_t r22_val = get_register(R22); |
| 1979 int32_t r23_val = get_register(R23); | 2012 int32_t r23_val = get_register(R23); |
| 1980 | 2013 |
| 2014 int64_t d10_val = get_dregister(D10); |
| 2015 int64_t d11_val = get_dregister(D11); |
| 2016 int64_t d12_val = get_dregister(D12); |
| 2017 int64_t d13_val = get_dregister(D13); |
| 2018 int64_t d14_val = get_dregister(D14); |
| 2019 int64_t d15_val = get_dregister(D15); |
| 2020 |
| 1981 // Setup the callee-saved registers with a known value. To be able to check | 2021 // Setup the callee-saved registers with a known value. To be able to check |
| 1982 // that they are preserved properly across dart execution. | 2022 // that they are preserved properly across dart execution. |
| 1983 int32_t callee_saved_value = icount_; | 2023 int32_t callee_saved_value = icount_; |
| 1984 set_register(R16, callee_saved_value); | 2024 set_register(R16, callee_saved_value); |
| 1985 set_register(R17, callee_saved_value); | 2025 set_register(R17, callee_saved_value); |
| 1986 set_register(R18, callee_saved_value); | 2026 set_register(R18, callee_saved_value); |
| 1987 set_register(R19, callee_saved_value); | 2027 set_register(R19, callee_saved_value); |
| 1988 set_register(R20, callee_saved_value); | 2028 set_register(R20, callee_saved_value); |
| 1989 set_register(R21, callee_saved_value); | 2029 set_register(R21, callee_saved_value); |
| 1990 set_register(R22, callee_saved_value); | 2030 set_register(R22, callee_saved_value); |
| 1991 set_register(R23, callee_saved_value); | 2031 set_register(R23, callee_saved_value); |
| 1992 | 2032 |
| 2033 set_dregister(D10, callee_saved_value); |
| 2034 set_dregister(D11, callee_saved_value); |
| 2035 set_dregister(D12, callee_saved_value); |
| 2036 set_dregister(D13, callee_saved_value); |
| 2037 set_dregister(D14, callee_saved_value); |
| 2038 set_dregister(D15, callee_saved_value); |
| 2039 |
| 1993 // Start the simulation | 2040 // Start the simulation |
| 1994 Execute(); | 2041 Execute(); |
| 1995 | 2042 |
| 1996 // Check that the callee-saved registers have been preserved. | 2043 // Check that the callee-saved registers have been preserved. |
| 1997 ASSERT(callee_saved_value == get_register(R16)); | 2044 ASSERT(callee_saved_value == get_register(R16)); |
| 1998 ASSERT(callee_saved_value == get_register(R17)); | 2045 ASSERT(callee_saved_value == get_register(R17)); |
| 1999 ASSERT(callee_saved_value == get_register(R18)); | 2046 ASSERT(callee_saved_value == get_register(R18)); |
| 2000 ASSERT(callee_saved_value == get_register(R19)); | 2047 ASSERT(callee_saved_value == get_register(R19)); |
| 2001 ASSERT(callee_saved_value == get_register(R20)); | 2048 ASSERT(callee_saved_value == get_register(R20)); |
| 2002 ASSERT(callee_saved_value == get_register(R21)); | 2049 ASSERT(callee_saved_value == get_register(R21)); |
| 2003 ASSERT(callee_saved_value == get_register(R22)); | 2050 ASSERT(callee_saved_value == get_register(R22)); |
| 2004 ASSERT(callee_saved_value == get_register(R23)); | 2051 ASSERT(callee_saved_value == get_register(R23)); |
| 2005 | 2052 |
| 2053 ASSERT(callee_saved_value == get_dregister(D10)); |
| 2054 ASSERT(callee_saved_value == get_dregister(D11)); |
| 2055 ASSERT(callee_saved_value == get_dregister(D12)); |
| 2056 ASSERT(callee_saved_value == get_dregister(D13)); |
| 2057 ASSERT(callee_saved_value == get_dregister(D14)); |
| 2058 ASSERT(callee_saved_value == get_dregister(D15)); |
| 2059 |
| 2006 // Restore callee-saved registers with the original value. | 2060 // Restore callee-saved registers with the original value. |
| 2007 set_register(R16, r16_val); | 2061 set_register(R16, r16_val); |
| 2008 set_register(R17, r17_val); | 2062 set_register(R17, r17_val); |
| 2009 set_register(R18, r18_val); | 2063 set_register(R18, r18_val); |
| 2010 set_register(R19, r19_val); | 2064 set_register(R19, r19_val); |
| 2011 set_register(R20, r20_val); | 2065 set_register(R20, r20_val); |
| 2012 set_register(R21, r21_val); | 2066 set_register(R21, r21_val); |
| 2013 set_register(R22, r22_val); | 2067 set_register(R22, r22_val); |
| 2014 set_register(R23, r23_val); | 2068 set_register(R23, r23_val); |
| 2015 | 2069 |
| 2070 set_dregister(D10, d10_val); |
| 2071 set_dregister(D11, d11_val); |
| 2072 set_dregister(D12, d12_val); |
| 2073 set_dregister(D13, d13_val); |
| 2074 set_dregister(D14, d14_val); |
| 2075 set_dregister(D15, d15_val); |
| 2076 |
| 2016 // Restore the SP register and return V1:V0. | 2077 // Restore the SP register and return V1:V0. |
| 2017 set_register(SP, sp_before_call); | 2078 set_register(SP, sp_before_call); |
| 2018 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1)); | 2079 int64_t return_value; |
| 2080 if (fp_return) { |
| 2081 return_value = Utils::LowHighTo64Bits(get_fregister(F0), get_fregister(F1)); |
| 2082 } else { |
| 2083 return_value = Utils::LowHighTo64Bits(get_register(V0), get_register(V1)); |
| 2084 } |
| 2085 return return_value; |
| 2019 } | 2086 } |
| 2020 | 2087 |
| 2021 | 2088 |
| 2022 void Simulator::Longjmp(uword pc, | 2089 void Simulator::Longjmp(uword pc, |
| 2023 uword sp, | 2090 uword sp, |
| 2024 uword fp, | 2091 uword fp, |
| 2025 RawObject* raw_exception, | 2092 RawObject* raw_exception, |
| 2026 RawObject* raw_stacktrace) { | 2093 RawObject* raw_stacktrace) { |
| 2027 // Walk over all setjmp buffers (simulated --> C++ transitions) | 2094 // Walk over all setjmp buffers (simulated --> C++ transitions) |
| 2028 // and try to find the setjmp associated with the simulated stack pointer. | 2095 // and try to find the setjmp associated with the simulated stack pointer. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2052 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); | 2119 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); |
| 2053 } | 2120 } |
| 2054 buf->Longjmp(); | 2121 buf->Longjmp(); |
| 2055 } | 2122 } |
| 2056 | 2123 |
| 2057 } // namespace dart | 2124 } // namespace dart |
| 2058 | 2125 |
| 2059 #endif // !defined(HOST_ARCH_MIPS) | 2126 #endif // !defined(HOST_ARCH_MIPS) |
| 2060 | 2127 |
| 2061 #endif // defined TARGET_ARCH_MIPS | 2128 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |