OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |