Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(304)

Side by Side Diff: runtime/vm/simulator_mips.cc

Issue 15874005: Fixes buggy FPU tests for MIPS hardware. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698