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

Side by Side Diff: src/mips/simulator-mips.cc

Issue 6993054: MIPS: Fixed FPU rounding checks and related errors in the Simulator. (Closed)
Patch Set: Created 9 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 1152
1153 1153
1154 bool Simulator::test_fcsr_bit(uint32_t cc) { 1154 bool Simulator::test_fcsr_bit(uint32_t cc) {
1155 return FCSR_ & (1 << cc); 1155 return FCSR_ & (1 << cc);
1156 } 1156 }
1157 1157
1158 1158
1159 // Sets the rounding error codes in FCSR based on the result of the rounding. 1159 // Sets the rounding error codes in FCSR based on the result of the rounding.
1160 // Returns true if the operation was invalid. 1160 // Returns true if the operation was invalid.
1161 bool Simulator::set_fcsr_round_error(double original, double rounded) { 1161 bool Simulator::set_fcsr_round_error(double original, double rounded) {
1162 if (!isfinite(original) || 1162 bool ret = false;
1163 rounded > LONG_MAX || 1163
1164 rounded < LONG_MIN) { 1164 if (!isfinite(original) || !isfinite(rounded)) {
1165 set_fcsr_bit(6, true); // Invalid operation. 1165 set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
1166 return true; 1166 ret = true;
1167 } else if (original != static_cast<double>(rounded)) {
1168 set_fcsr_bit(2, true); // Inexact.
1169 } 1167 }
1170 return false; 1168
1169 if (original != rounded) {
1170 set_fcsr_bit(kFCSRInexactFlagBit, true);
1171 }
1172
1173 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
1174 set_fcsr_bit(kFCSRUnderflowFlagBit, true);
1175 ret = true;
1176 }
1177
1178 if (rounded > INT_MAX || rounded < INT_MIN) {
1179 set_fcsr_bit(kFCSROverflowFlagBit, true);
1180 // The reference is not really clear but it seems this is required:
1181 set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
1182 ret = true;
1183 }
1184
1185 return ret;
1171 } 1186 }
1172 1187
1173 1188
1174 // Raw access to the PC register. 1189 // Raw access to the PC register.
1175 void Simulator::set_pc(int32_t value) { 1190 void Simulator::set_pc(int32_t value) {
1176 pc_modified_ = true; 1191 pc_modified_ = true;
1177 registers_[pc] = value; 1192 registers_[pc] = value;
1178 } 1193 }
1179 1194
1180 1195
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
2047 double rounded = fs > 0 ? floor(fs + 0.5) : ceil(fs - 0.5); 2062 double rounded = fs > 0 ? floor(fs + 0.5) : ceil(fs - 0.5);
2048 int32_t result = static_cast<int32_t>(rounded); 2063 int32_t result = static_cast<int32_t>(rounded);
2049 set_fpu_register(fd_reg, result); 2064 set_fpu_register(fd_reg, result);
2050 if (set_fcsr_round_error(fs, rounded)) { 2065 if (set_fcsr_round_error(fs, rounded)) {
2051 set_fpu_register(fd_reg, kFPUInvalidResult); 2066 set_fpu_register(fd_reg, kFPUInvalidResult);
2052 } 2067 }
2053 } 2068 }
2054 break; 2069 break;
2055 case TRUNC_W_D: // Truncate double to word (round towards 0). 2070 case TRUNC_W_D: // Truncate double to word (round towards 0).
2056 { 2071 {
2057 int32_t result = static_cast<int32_t>(fs); 2072 double rounded = trunc(fs);
2073 int32_t result = static_cast<int32_t>(rounded);
2058 set_fpu_register(fd_reg, result); 2074 set_fpu_register(fd_reg, result);
2059 if (set_fcsr_round_error(fs, static_cast<double>(result))) { 2075 if (set_fcsr_round_error(fs, rounded)) {
2060 set_fpu_register(fd_reg, kFPUInvalidResult); 2076 set_fpu_register(fd_reg, kFPUInvalidResult);
2061 } 2077 }
2062 } 2078 }
2063 break; 2079 break;
2064 case FLOOR_W_D: // Round double to word towards negative infinity. 2080 case FLOOR_W_D: // Round double to word towards negative infinity.
2065 { 2081 {
2066 double rounded = floor(fs); 2082 double rounded = floor(fs);
2067 int32_t result = static_cast<int32_t>(rounded); 2083 int32_t result = static_cast<int32_t>(rounded);
2068 set_fpu_register(fd_reg, result); 2084 set_fpu_register(fd_reg, result);
2069 if (set_fcsr_round_error(fs, rounded)) { 2085 if (set_fcsr_round_error(fs, rounded)) {
2070 set_fpu_register(fd_reg, kFPUInvalidResult); 2086 set_fpu_register(fd_reg, kFPUInvalidResult);
2071 } 2087 }
2072 } 2088 }
2073 break; 2089 break;
2074 case CEIL_W_D: // Round double to word towards positive infinity. 2090 case CEIL_W_D: // Round double to word towards positive infinity.
2075 { 2091 {
2076 double rounded = ceil(fs); 2092 double rounded = ceil(fs);
2077 int32_t result = static_cast<int32_t>(rounded); 2093 int32_t result = static_cast<int32_t>(rounded);
2078 set_fpu_register(fd_reg, result); 2094 set_fpu_register(fd_reg, result);
2079 if (set_fcsr_round_error(fs, rounded)) { 2095 if (set_fcsr_round_error(fs, rounded)) {
2080 set_fpu_register(fd_reg, kFPUInvalidResult); 2096 set_fpu_register(fd_reg, kFPUInvalidResult);
2081 } 2097 }
2082 } 2098 }
2083 break; 2099 break;
2084 case CVT_S_D: // Convert double to float (single). 2100 case CVT_S_D: // Convert double to float (single).
2085 set_fpu_register_float(fd_reg, static_cast<float>(fs)); 2101 set_fpu_register_float(fd_reg, static_cast<float>(fs));
2086 break; 2102 break;
2087 case CVT_L_D: // Mips32r2: Truncate double to 64-bit long-word. 2103 case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word.
2088 i64 = static_cast<int64_t>(fs); 2104 double rounded = trunc(fs);
2105 i64 = static_cast<int64_t>(rounded);
2089 set_fpu_register(fd_reg, i64 & 0xffffffff); 2106 set_fpu_register(fd_reg, i64 & 0xffffffff);
2090 set_fpu_register(fd_reg + 1, i64 >> 32); 2107 set_fpu_register(fd_reg + 1, i64 >> 32);
2091 break; 2108 break;
2092 case TRUNC_L_D: // Mips32r2 instruction. 2109 }
2093 i64 = static_cast<int64_t>(fs); 2110 case TRUNC_L_D: { // Mips32r2 instruction.
2111 double rounded = trunc(fs);
2112 i64 = static_cast<int64_t>(rounded);
2094 set_fpu_register(fd_reg, i64 & 0xffffffff); 2113 set_fpu_register(fd_reg, i64 & 0xffffffff);
2095 set_fpu_register(fd_reg + 1, i64 >> 32); 2114 set_fpu_register(fd_reg + 1, i64 >> 32);
2096 break; 2115 break;
2116 }
2097 case ROUND_L_D: { // Mips32r2 instruction. 2117 case ROUND_L_D: { // Mips32r2 instruction.
2098 double rounded = fs > 0 ? floor(fs + 0.5) : ceil(fs - 0.5); 2118 double rounded = fs > 0 ? floor(fs + 0.5) : ceil(fs - 0.5);
2099 i64 = static_cast<int64_t>(rounded); 2119 i64 = static_cast<int64_t>(rounded);
2100 set_fpu_register(fd_reg, i64 & 0xffffffff); 2120 set_fpu_register(fd_reg, i64 & 0xffffffff);
2101 set_fpu_register(fd_reg + 1, i64 >> 32); 2121 set_fpu_register(fd_reg + 1, i64 >> 32);
2102 break; 2122 break;
2103 } 2123 }
2104 case FLOOR_L_D: // Mips32r2 instruction. 2124 case FLOOR_L_D: // Mips32r2 instruction.
2105 i64 = static_cast<int64_t>(floor(fs)); 2125 i64 = static_cast<int64_t>(floor(fs));
2106 set_fpu_register(fd_reg, i64 & 0xffffffff); 2126 set_fpu_register(fd_reg, i64 & 0xffffffff);
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
2801 } 2821 }
2802 2822
2803 2823
2804 #undef UNSUPPORTED 2824 #undef UNSUPPORTED
2805 2825
2806 } } // namespace v8::internal 2826 } } // namespace v8::internal
2807 2827
2808 #endif // USE_SIMULATOR 2828 #endif // USE_SIMULATOR
2809 2829
2810 #endif // V8_TARGET_ARCH_MIPS 2830 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698