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 |