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

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
« no previous file with comments | « runtime/vm/simulator_mips.h ('k') | runtime/vm/unit_test.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/simulator_mips.h ('k') | runtime/vm/unit_test.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698