| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <limits.h> | 5 #include <limits.h> |
| 6 #include <stdarg.h> | 6 #include <stdarg.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #include "src/v8.h" | 10 #include "src/v8.h" |
| (...skipping 1264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1275 void Simulator::set_fcsr_rounding_mode(FPURoundingMode mode) { | 1275 void Simulator::set_fcsr_rounding_mode(FPURoundingMode mode) { |
| 1276 FCSR_ |= mode & kFPURoundingModeMask; | 1276 FCSR_ |= mode & kFPURoundingModeMask; |
| 1277 } | 1277 } |
| 1278 | 1278 |
| 1279 | 1279 |
| 1280 unsigned int Simulator::get_fcsr_rounding_mode() { | 1280 unsigned int Simulator::get_fcsr_rounding_mode() { |
| 1281 return FCSR_ & kFPURoundingModeMask; | 1281 return FCSR_ & kFPURoundingModeMask; |
| 1282 } | 1282 } |
| 1283 | 1283 |
| 1284 | 1284 |
| 1285 // Sets the rounding error codes in FCSR based on the result of the rounding. | |
| 1286 // Returns true if the operation was invalid. | |
| 1287 bool Simulator::set_fcsr_round_error(double original, double rounded) { | 1285 bool Simulator::set_fcsr_round_error(double original, double rounded) { |
| 1288 bool ret = false; | 1286 bool ret = false; |
| 1289 double max_int32 = std::numeric_limits<int32_t>::max(); | 1287 double max_int32 = std::numeric_limits<int32_t>::max(); |
| 1290 double min_int32 = std::numeric_limits<int32_t>::min(); | 1288 double min_int32 = std::numeric_limits<int32_t>::min(); |
| 1291 | 1289 |
| 1292 if (!std::isfinite(original) || !std::isfinite(rounded)) { | 1290 if (!std::isfinite(original) || !std::isfinite(rounded)) { |
| 1293 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); | 1291 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
| 1294 ret = true; | 1292 ret = true; |
| 1295 } | 1293 } |
| 1296 | 1294 |
| 1297 if (original != rounded) { | 1295 if (original != rounded) { |
| 1298 set_fcsr_bit(kFCSRInexactFlagBit, true); | 1296 set_fcsr_bit(kFCSRInexactFlagBit, true); |
| 1299 } | 1297 } |
| 1300 | 1298 |
| 1301 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) { | 1299 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) { |
| 1302 set_fcsr_bit(kFCSRUnderflowFlagBit, true); | 1300 set_fcsr_bit(kFCSRUnderflowFlagBit, true); |
| 1303 ret = true; | 1301 ret = true; |
| 1304 } | 1302 } |
| 1305 | 1303 |
| 1306 if (rounded > max_int32 || rounded < min_int32) { | 1304 if (rounded >= max_int32 || rounded <= min_int32) { |
| 1307 set_fcsr_bit(kFCSROverflowFlagBit, true); | 1305 set_fcsr_bit(kFCSROverflowFlagBit, true); |
| 1308 // The reference is not really clear but it seems this is required: | 1306 // The reference is not really clear but it seems this is required: |
| 1309 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); | 1307 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
| 1308 ret = true; |
| 1309 } |
| 1310 |
| 1311 return ret; |
| 1312 } |
| 1313 |
| 1314 |
| 1315 // Sets the rounding error codes in FCSR based on the result of the rounding. |
| 1316 // Returns true if the operation was invalid. |
| 1317 bool Simulator::set_fcsr_round64_error(double original, double rounded) { |
| 1318 bool ret = false; |
| 1319 double max_int64 = std::numeric_limits<int64_t>::max(); |
| 1320 double min_int64 = std::numeric_limits<int64_t>::min(); |
| 1321 |
| 1322 if (!std::isfinite(original) || !std::isfinite(rounded)) { |
| 1323 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
| 1324 ret = true; |
| 1325 } |
| 1326 |
| 1327 if (original != rounded) { |
| 1328 set_fcsr_bit(kFCSRInexactFlagBit, true); |
| 1329 } |
| 1330 |
| 1331 if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) { |
| 1332 set_fcsr_bit(kFCSRUnderflowFlagBit, true); |
| 1333 ret = true; |
| 1334 } |
| 1335 |
| 1336 if (rounded >= max_int64 || rounded <= min_int64) { |
| 1337 set_fcsr_bit(kFCSROverflowFlagBit, true); |
| 1338 // The reference is not really clear but it seems this is required: |
| 1339 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
| 1340 ret = true; |
| 1341 } |
| 1342 |
| 1343 return ret; |
| 1344 } |
| 1345 |
| 1346 |
| 1347 bool Simulator::set_fcsr_round_error(float original, float rounded) { |
| 1348 bool ret = false; |
| 1349 double max_int32 = std::numeric_limits<int32_t>::max(); |
| 1350 double min_int32 = std::numeric_limits<int32_t>::min(); |
| 1351 |
| 1352 if (!std::isfinite(original) || !std::isfinite(rounded)) { |
| 1353 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
| 1354 ret = true; |
| 1355 } |
| 1356 |
| 1357 if (original != rounded) { |
| 1358 set_fcsr_bit(kFCSRInexactFlagBit, true); |
| 1359 } |
| 1360 |
| 1361 if (rounded < FLT_MIN && rounded > -FLT_MIN && rounded != 0) { |
| 1362 set_fcsr_bit(kFCSRUnderflowFlagBit, true); |
| 1363 ret = true; |
| 1364 } |
| 1365 |
| 1366 if (rounded >= max_int32 || rounded <= min_int32) { |
| 1367 set_fcsr_bit(kFCSROverflowFlagBit, true); |
| 1368 // The reference is not really clear but it seems this is required: |
| 1369 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
| 1370 ret = true; |
| 1371 } |
| 1372 |
| 1373 return ret; |
| 1374 } |
| 1375 |
| 1376 |
| 1377 // Sets the rounding error codes in FCSR based on the result of the rounding. |
| 1378 // Returns true if the operation was invalid. |
| 1379 bool Simulator::set_fcsr_round64_error(float original, float rounded) { |
| 1380 bool ret = false; |
| 1381 double max_int64 = std::numeric_limits<int64_t>::max(); |
| 1382 double min_int64 = std::numeric_limits<int64_t>::min(); |
| 1383 |
| 1384 if (!std::isfinite(original) || !std::isfinite(rounded)) { |
| 1385 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
| 1386 ret = true; |
| 1387 } |
| 1388 |
| 1389 if (original != rounded) { |
| 1390 set_fcsr_bit(kFCSRInexactFlagBit, true); |
| 1391 } |
| 1392 |
| 1393 if (rounded < FLT_MIN && rounded > -FLT_MIN && rounded != 0) { |
| 1394 set_fcsr_bit(kFCSRUnderflowFlagBit, true); |
| 1395 ret = true; |
| 1396 } |
| 1397 |
| 1398 if (rounded >= max_int64 || rounded <= min_int64) { |
| 1399 set_fcsr_bit(kFCSROverflowFlagBit, true); |
| 1400 // The reference is not really clear but it seems this is required: |
| 1401 set_fcsr_bit(kFCSRInvalidOpFlagBit, true); |
| 1310 ret = true; | 1402 ret = true; |
| 1311 } | 1403 } |
| 1312 | 1404 |
| 1313 return ret; | 1405 return ret; |
| 1314 } | 1406 } |
| 1315 | 1407 |
| 1316 | 1408 |
| 1317 void Simulator::round_according_to_fcsr(double toRound, double& rounded, | 1409 void Simulator::round_according_to_fcsr(double toRound, double& rounded, |
| 1318 int32_t& rounded_int, double fs) { | 1410 int32_t& rounded_int, double fs) { |
| 1319 // 0 RN (round to nearest): Round a result to the nearest | 1411 // 0 RN (round to nearest): Round a result to the nearest |
| (...skipping 864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2184 | 2276 |
| 2185 void Simulator::DecodeTypeRegisterDRsType(Instruction* instr, | 2277 void Simulator::DecodeTypeRegisterDRsType(Instruction* instr, |
| 2186 const int32_t& fr_reg, | 2278 const int32_t& fr_reg, |
| 2187 const int32_t& fs_reg, | 2279 const int32_t& fs_reg, |
| 2188 const int32_t& ft_reg, | 2280 const int32_t& ft_reg, |
| 2189 const int32_t& fd_reg) { | 2281 const int32_t& fd_reg) { |
| 2190 double ft, fs, fd; | 2282 double ft, fs, fd; |
| 2191 uint32_t cc, fcsr_cc; | 2283 uint32_t cc, fcsr_cc; |
| 2192 int64_t i64; | 2284 int64_t i64; |
| 2193 fs = get_fpu_register_double(fs_reg); | 2285 fs = get_fpu_register_double(fs_reg); |
| 2194 ft = get_fpu_register_double(ft_reg); | 2286 if (instr->FunctionFieldRaw() != MOVF) { |
| 2287 ft = get_fpu_register_double(ft_reg); |
| 2288 } |
| 2289 fd = get_fpu_register_double(fd_reg); |
| 2195 int64_t ft_int = bit_cast<int64_t>(ft); | 2290 int64_t ft_int = bit_cast<int64_t>(ft); |
| 2196 int64_t fd_int = bit_cast<int64_t>(fd); | 2291 int64_t fd_int = bit_cast<int64_t>(fd); |
| 2197 cc = instr->FCccValue(); | 2292 cc = instr->FCccValue(); |
| 2198 fcsr_cc = get_fcsr_condition_bit(cc); | 2293 fcsr_cc = get_fcsr_condition_bit(cc); |
| 2199 switch (instr->FunctionFieldRaw()) { | 2294 switch (instr->FunctionFieldRaw()) { |
| 2200 case RINT: { | 2295 case RINT: { |
| 2201 DCHECK(IsMipsArchVariant(kMips32r6)); | 2296 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2202 double result, temp, temp_result; | 2297 double result, temp, temp_result; |
| 2203 double upper = std::ceil(fs); | 2298 double upper = std::ceil(fs); |
| 2204 double lower = std::floor(fs); | 2299 double lower = std::floor(fs); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2239 set_fpu_register_double(fd_reg, (fd_int & 0x1) == 0 ? fs : ft); | 2334 set_fpu_register_double(fd_reg, (fd_int & 0x1) == 0 ? fs : ft); |
| 2240 break; | 2335 break; |
| 2241 case SELEQZ_C: | 2336 case SELEQZ_C: |
| 2242 DCHECK(IsMipsArchVariant(kMips32r6)); | 2337 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2243 set_fpu_register_double(fd_reg, (ft_int & 0x1) == 0 ? fs : 0.0); | 2338 set_fpu_register_double(fd_reg, (ft_int & 0x1) == 0 ? fs : 0.0); |
| 2244 break; | 2339 break; |
| 2245 case SELNEZ_C: | 2340 case SELNEZ_C: |
| 2246 DCHECK(IsMipsArchVariant(kMips32r6)); | 2341 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2247 set_fpu_register_double(fd_reg, (ft_int & 0x1) != 0 ? fs : 0.0); | 2342 set_fpu_register_double(fd_reg, (ft_int & 0x1) != 0 ? fs : 0.0); |
| 2248 break; | 2343 break; |
| 2344 case MOVZ_C: { |
| 2345 DCHECK(IsMipsArchVariant(kMips32r2)); |
| 2346 int32_t rt_reg = instr->RtValue(); |
| 2347 int32_t rt = get_register(rt_reg); |
| 2348 if (rt == 0) { |
| 2349 set_fpu_register_double(fd_reg, fs); |
| 2350 } |
| 2351 break; |
| 2352 } |
| 2353 case MOVN_C: { |
| 2354 DCHECK(IsMipsArchVariant(kMips32r2)); |
| 2355 int32_t rt_reg = instr->RtValue(); |
| 2356 int32_t rt = get_register(rt_reg); |
| 2357 if (rt != 0) { |
| 2358 set_fpu_register_double(fd_reg, fs); |
| 2359 } |
| 2360 break; |
| 2361 } |
| 2362 case MOVF: { |
| 2363 // Same function field for MOVT.D and MOVF.D |
| 2364 uint32_t ft_cc = (ft_reg >> 2) & 0x7; |
| 2365 ft_cc = get_fcsr_condition_bit(ft_cc); |
| 2366 if (instr->Bit(16)) { // Read Tf bit. |
| 2367 // MOVT.D |
| 2368 if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg, fs); |
| 2369 } else { |
| 2370 // MOVF.D |
| 2371 if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg, fs); |
| 2372 } |
| 2373 break; |
| 2374 } |
| 2249 case MIN: | 2375 case MIN: |
| 2250 DCHECK(IsMipsArchVariant(kMips32r6)); | 2376 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2251 fs = get_fpu_register_double(fs_reg); | 2377 fs = get_fpu_register_double(fs_reg); |
| 2252 if (std::isnan(fs) && std::isnan(ft)) { | 2378 if (std::isnan(fs) && std::isnan(ft)) { |
| 2253 set_fpu_register_double(fd_reg, fs); | 2379 set_fpu_register_double(fd_reg, fs); |
| 2254 } else if (std::isnan(fs) && !std::isnan(ft)) { | 2380 } else if (std::isnan(fs) && !std::isnan(ft)) { |
| 2255 set_fpu_register_double(fd_reg, ft); | 2381 set_fpu_register_double(fd_reg, ft); |
| 2256 } else if (!std::isnan(fs) && std::isnan(ft)) { | 2382 } else if (!std::isnan(fs) && std::isnan(ft)) { |
| 2257 set_fpu_register_double(fd_reg, fs); | 2383 set_fpu_register_double(fd_reg, fs); |
| 2258 } else { | 2384 } else { |
| 2259 set_fpu_register_double(fd_reg, (fs >= ft) ? ft : fs); | 2385 set_fpu_register_double(fd_reg, (fs >= ft) ? ft : fs); |
| 2260 } | 2386 } |
| 2261 break; | 2387 break; |
| 2388 case MINA: |
| 2389 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2390 fs = get_fpu_register_double(fs_reg); |
| 2391 if (std::isnan(fs) && std::isnan(ft)) { |
| 2392 set_fpu_register_double(fd_reg, fs); |
| 2393 } else if (std::isnan(fs) && !std::isnan(ft)) { |
| 2394 set_fpu_register_double(fd_reg, ft); |
| 2395 } else if (!std::isnan(fs) && std::isnan(ft)) { |
| 2396 set_fpu_register_double(fd_reg, fs); |
| 2397 } else { |
| 2398 double result; |
| 2399 if (fabs(fs) > fabs(ft)) { |
| 2400 result = ft; |
| 2401 } else if (fabs(fs) < fabs(ft)) { |
| 2402 result = fs; |
| 2403 } else { |
| 2404 result = (fs > ft ? fs : ft); |
| 2405 } |
| 2406 set_fpu_register_double(fd_reg, result); |
| 2407 } |
| 2408 break; |
| 2409 case MAXA: |
| 2410 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2411 fs = get_fpu_register_double(fs_reg); |
| 2412 if (std::isnan(fs) && std::isnan(ft)) { |
| 2413 set_fpu_register_double(fd_reg, fs); |
| 2414 } else if (std::isnan(fs) && !std::isnan(ft)) { |
| 2415 set_fpu_register_double(fd_reg, ft); |
| 2416 } else if (!std::isnan(fs) && std::isnan(ft)) { |
| 2417 set_fpu_register_double(fd_reg, fs); |
| 2418 } else { |
| 2419 double result; |
| 2420 if (fabs(fs) < fabs(ft)) { |
| 2421 result = ft; |
| 2422 } else if (fabs(fs) > fabs(ft)) { |
| 2423 result = fs; |
| 2424 } else { |
| 2425 result = (fs > ft ? fs : ft); |
| 2426 } |
| 2427 set_fpu_register_double(fd_reg, result); |
| 2428 } |
| 2429 break; |
| 2262 case MAX: | 2430 case MAX: |
| 2263 DCHECK(IsMipsArchVariant(kMips32r6)); | 2431 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2264 fs = get_fpu_register_double(fs_reg); | 2432 fs = get_fpu_register_double(fs_reg); |
| 2265 if (std::isnan(fs) && std::isnan(ft)) { | 2433 if (std::isnan(fs) && std::isnan(ft)) { |
| 2266 set_fpu_register_double(fd_reg, fs); | 2434 set_fpu_register_double(fd_reg, fs); |
| 2267 } else if (std::isnan(fs) && !std::isnan(ft)) { | 2435 } else if (std::isnan(fs) && !std::isnan(ft)) { |
| 2268 set_fpu_register_double(fd_reg, ft); | 2436 set_fpu_register_double(fd_reg, ft); |
| 2269 } else if (!std::isnan(fs) && std::isnan(ft)) { | 2437 } else if (!std::isnan(fs) && std::isnan(ft)) { |
| 2270 set_fpu_register_double(fd_reg, fs); | 2438 set_fpu_register_double(fd_reg, fs); |
| 2271 } else { | 2439 } else { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2290 break; | 2458 break; |
| 2291 case MOV_D: | 2459 case MOV_D: |
| 2292 set_fpu_register_double(fd_reg, fs); | 2460 set_fpu_register_double(fd_reg, fs); |
| 2293 break; | 2461 break; |
| 2294 case NEG_D: | 2462 case NEG_D: |
| 2295 set_fpu_register_double(fd_reg, -fs); | 2463 set_fpu_register_double(fd_reg, -fs); |
| 2296 break; | 2464 break; |
| 2297 case SQRT_D: | 2465 case SQRT_D: |
| 2298 set_fpu_register_double(fd_reg, fast_sqrt(fs)); | 2466 set_fpu_register_double(fd_reg, fast_sqrt(fs)); |
| 2299 break; | 2467 break; |
| 2468 case RSQRT_D: { |
| 2469 double result = 1.0 / fast_sqrt(fs); |
| 2470 set_fpu_register_double(fd_reg, result); |
| 2471 break; |
| 2472 } |
| 2473 case RECIP: { |
| 2474 double result = 1.0 / fs; |
| 2475 set_fpu_register_double(fd_reg, result); |
| 2476 break; |
| 2477 } |
| 2300 case C_UN_D: | 2478 case C_UN_D: |
| 2301 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); | 2479 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); |
| 2302 break; | 2480 break; |
| 2303 case C_EQ_D: | 2481 case C_EQ_D: |
| 2304 set_fcsr_bit(fcsr_cc, (fs == ft)); | 2482 set_fcsr_bit(fcsr_cc, (fs == ft)); |
| 2305 break; | 2483 break; |
| 2306 case C_UEQ_D: | 2484 case C_UEQ_D: |
| 2307 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); | 2485 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); |
| 2308 break; | 2486 break; |
| 2309 case C_OLT_D: | 2487 case C_OLT_D: |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2380 set_fpu_register_word(fd_reg, i64 & 0xffffffff); | 2558 set_fpu_register_word(fd_reg, i64 & 0xffffffff); |
| 2381 set_fpu_register_word(fd_reg + 1, i64 >> 32); | 2559 set_fpu_register_word(fd_reg + 1, i64 >> 32); |
| 2382 } | 2560 } |
| 2383 break; | 2561 break; |
| 2384 } | 2562 } |
| 2385 case TRUNC_L_D: { // Mips32r2 instruction. | 2563 case TRUNC_L_D: { // Mips32r2 instruction. |
| 2386 double rounded = trunc(fs); | 2564 double rounded = trunc(fs); |
| 2387 i64 = static_cast<int64_t>(rounded); | 2565 i64 = static_cast<int64_t>(rounded); |
| 2388 if (IsFp64Mode()) { | 2566 if (IsFp64Mode()) { |
| 2389 set_fpu_register(fd_reg, i64); | 2567 set_fpu_register(fd_reg, i64); |
| 2568 if (set_fcsr_round64_error(fs, rounded)) { |
| 2569 set_fpu_register(fd_reg, kFPU64InvalidResult); |
| 2570 } |
| 2390 } else { | 2571 } else { |
| 2391 set_fpu_register_word(fd_reg, i64 & 0xffffffff); | 2572 set_fpu_register_word(fd_reg, i64 & 0xffffffff); |
| 2392 set_fpu_register_word(fd_reg + 1, i64 >> 32); | 2573 set_fpu_register_word(fd_reg + 1, i64 >> 32); |
| 2574 if (set_fcsr_round64_error(fs, rounded)) { |
| 2575 set_fpu_register_word(fd_reg, kFPU64InvalidResult & 0xffffffff); |
| 2576 set_fpu_register_word(fd_reg + 1, kFPU64InvalidResult >> 32); |
| 2577 } |
| 2393 } | 2578 } |
| 2394 break; | 2579 break; |
| 2395 } | 2580 } |
| 2396 case ROUND_L_D: { // Mips32r2 instruction. | 2581 case ROUND_L_D: { // Mips32r2 instruction. |
| 2397 double rounded = fs > 0 ? std::floor(fs + 0.5) : std::ceil(fs - 0.5); | 2582 double rounded = std::floor(fs + 0.5); |
| 2398 i64 = static_cast<int64_t>(rounded); | 2583 int64_t result = static_cast<int64_t>(rounded); |
| 2584 if ((result & 1) != 0 && result - fs == 0.5) { |
| 2585 // If the number is halfway between two integers, |
| 2586 // round to the even one. |
| 2587 result--; |
| 2588 } |
| 2589 int64_t i64 = static_cast<int64_t>(result); |
| 2399 if (IsFp64Mode()) { | 2590 if (IsFp64Mode()) { |
| 2400 set_fpu_register(fd_reg, i64); | 2591 set_fpu_register(fd_reg, i64); |
| 2592 if (set_fcsr_round64_error(fs, rounded)) { |
| 2593 set_fpu_register(fd_reg, kFPU64InvalidResult); |
| 2594 } |
| 2401 } else { | 2595 } else { |
| 2402 set_fpu_register_word(fd_reg, i64 & 0xffffffff); | 2596 set_fpu_register_word(fd_reg, i64 & 0xffffffff); |
| 2403 set_fpu_register_word(fd_reg + 1, i64 >> 32); | 2597 set_fpu_register_word(fd_reg + 1, i64 >> 32); |
| 2598 if (set_fcsr_round64_error(fs, rounded)) { |
| 2599 set_fpu_register_word(fd_reg, kFPU64InvalidResult & 0xffffffff); |
| 2600 set_fpu_register_word(fd_reg + 1, kFPU64InvalidResult >> 32); |
| 2601 } |
| 2404 } | 2602 } |
| 2405 break; | 2603 break; |
| 2406 } | 2604 } |
| 2407 case FLOOR_L_D: // Mips32r2 instruction. | 2605 case FLOOR_L_D: { // Mips32r2 instruction. |
| 2408 i64 = static_cast<int64_t>(std::floor(fs)); | 2606 double rounded = std::floor(fs); |
| 2607 int64_t i64 = static_cast<int64_t>(rounded); |
| 2409 if (IsFp64Mode()) { | 2608 if (IsFp64Mode()) { |
| 2410 set_fpu_register(fd_reg, i64); | 2609 set_fpu_register(fd_reg, i64); |
| 2610 if (set_fcsr_round64_error(fs, rounded)) { |
| 2611 set_fpu_register(fd_reg, kFPU64InvalidResult); |
| 2612 } |
| 2411 } else { | 2613 } else { |
| 2412 set_fpu_register_word(fd_reg, i64 & 0xffffffff); | 2614 set_fpu_register_word(fd_reg, i64 & 0xffffffff); |
| 2413 set_fpu_register_word(fd_reg + 1, i64 >> 32); | 2615 set_fpu_register_word(fd_reg + 1, i64 >> 32); |
| 2616 if (set_fcsr_round64_error(fs, rounded)) { |
| 2617 set_fpu_register_word(fd_reg, kFPU64InvalidResult & 0xffffffff); |
| 2618 set_fpu_register_word(fd_reg + 1, kFPU64InvalidResult >> 32); |
| 2619 } |
| 2414 } | 2620 } |
| 2415 break; | 2621 break; |
| 2416 case CEIL_L_D: // Mips32r2 instruction. | 2622 } |
| 2417 i64 = static_cast<int64_t>(std::ceil(fs)); | 2623 case CEIL_L_D: { // Mips32r2 instruction. |
| 2624 double rounded = std::ceil(fs); |
| 2625 int64_t i64 = static_cast<int64_t>(rounded); |
| 2418 if (IsFp64Mode()) { | 2626 if (IsFp64Mode()) { |
| 2419 set_fpu_register(fd_reg, i64); | 2627 set_fpu_register(fd_reg, i64); |
| 2628 if (set_fcsr_round64_error(fs, rounded)) { |
| 2629 set_fpu_register(fd_reg, kFPU64InvalidResult); |
| 2630 } |
| 2420 } else { | 2631 } else { |
| 2421 set_fpu_register_word(fd_reg, i64 & 0xffffffff); | 2632 set_fpu_register_word(fd_reg, i64 & 0xffffffff); |
| 2422 set_fpu_register_word(fd_reg + 1, i64 >> 32); | 2633 set_fpu_register_word(fd_reg + 1, i64 >> 32); |
| 2634 if (set_fcsr_round64_error(fs, rounded)) { |
| 2635 set_fpu_register_word(fd_reg, kFPU64InvalidResult & 0xffffffff); |
| 2636 set_fpu_register_word(fd_reg + 1, kFPU64InvalidResult >> 32); |
| 2637 } |
| 2423 } | 2638 } |
| 2424 break; | 2639 break; |
| 2640 } |
| 2425 case C_F_D: | 2641 case C_F_D: |
| 2426 UNIMPLEMENTED_MIPS(); | 2642 UNIMPLEMENTED_MIPS(); |
| 2427 break; | 2643 break; |
| 2428 default: | 2644 default: |
| 2429 UNREACHABLE(); | 2645 UNREACHABLE(); |
| 2430 } | 2646 } |
| 2431 } | 2647 } |
| 2432 | 2648 |
| 2433 | 2649 |
| 2434 void Simulator::DecodeTypeRegisterWRsType(Instruction* instr, int32_t& alu_out, | 2650 void Simulator::DecodeTypeRegisterWRsType(Instruction* instr, int32_t& alu_out, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2446 default: // Mips64r6 CMP.S instructions unimplemented. | 2662 default: // Mips64r6 CMP.S instructions unimplemented. |
| 2447 UNREACHABLE(); | 2663 UNREACHABLE(); |
| 2448 } | 2664 } |
| 2449 } | 2665 } |
| 2450 | 2666 |
| 2451 | 2667 |
| 2452 void Simulator::DecodeTypeRegisterSRsType(Instruction* instr, | 2668 void Simulator::DecodeTypeRegisterSRsType(Instruction* instr, |
| 2453 const int32_t& ft_reg, | 2669 const int32_t& ft_reg, |
| 2454 const int32_t& fs_reg, | 2670 const int32_t& fs_reg, |
| 2455 const int32_t& fd_reg) { | 2671 const int32_t& fd_reg) { |
| 2456 float fs, ft; | 2672 float fs, ft, fd; |
| 2457 fs = get_fpu_register_float(fs_reg); | 2673 fs = get_fpu_register_float(fs_reg); |
| 2458 ft = get_fpu_register_float(ft_reg); | 2674 ft = get_fpu_register_float(ft_reg); |
| 2459 int64_t ft_int = static_cast<int64_t>(get_fpu_register_double(ft_reg)); | 2675 fd = get_fpu_register_float(fd_reg); |
| 2676 int32_t ft_int = bit_cast<int32_t>(ft); |
| 2677 int32_t fd_int = bit_cast<int32_t>(fd); |
| 2460 uint32_t cc, fcsr_cc; | 2678 uint32_t cc, fcsr_cc; |
| 2461 cc = instr->FCccValue(); | 2679 cc = instr->FCccValue(); |
| 2462 fcsr_cc = get_fcsr_condition_bit(cc); | 2680 fcsr_cc = get_fcsr_condition_bit(cc); |
| 2463 switch (instr->FunctionFieldRaw()) { | 2681 switch (instr->FunctionFieldRaw()) { |
| 2682 case RINT: { |
| 2683 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2684 float result, temp_result; |
| 2685 double temp; |
| 2686 float upper = std::ceil(fs); |
| 2687 float lower = std::floor(fs); |
| 2688 switch (get_fcsr_rounding_mode()) { |
| 2689 case kRoundToNearest: |
| 2690 if (upper - fs < fs - lower) { |
| 2691 result = upper; |
| 2692 } else if (upper - fs > fs - lower) { |
| 2693 result = lower; |
| 2694 } else { |
| 2695 temp_result = upper / 2; |
| 2696 float reminder = modf(temp_result, &temp); |
| 2697 if (reminder == 0) { |
| 2698 result = upper; |
| 2699 } else { |
| 2700 result = lower; |
| 2701 } |
| 2702 } |
| 2703 break; |
| 2704 case kRoundToZero: |
| 2705 result = (fs > 0 ? lower : upper); |
| 2706 break; |
| 2707 case kRoundToPlusInf: |
| 2708 result = upper; |
| 2709 break; |
| 2710 case kRoundToMinusInf: |
| 2711 result = lower; |
| 2712 break; |
| 2713 } |
| 2714 set_fpu_register_float(fd_reg, result); |
| 2715 if (result != fs) { |
| 2716 set_fcsr_bit(kFCSRInexactFlagBit, true); |
| 2717 } |
| 2718 break; |
| 2719 } |
| 2464 case ADD_D: | 2720 case ADD_D: |
| 2465 set_fpu_register_float(fd_reg, fs + ft); | 2721 set_fpu_register_float(fd_reg, fs + ft); |
| 2466 break; | 2722 break; |
| 2467 case SUB_D: | 2723 case SUB_D: |
| 2468 set_fpu_register_float(fd_reg, fs - ft); | 2724 set_fpu_register_float(fd_reg, fs - ft); |
| 2469 break; | 2725 break; |
| 2470 case MUL_D: | 2726 case MUL_D: |
| 2471 set_fpu_register_float(fd_reg, fs * ft); | 2727 set_fpu_register_float(fd_reg, fs * ft); |
| 2472 break; | 2728 break; |
| 2473 case DIV_D: | 2729 case DIV_D: |
| 2474 set_fpu_register_float(fd_reg, fs / ft); | 2730 set_fpu_register_float(fd_reg, fs / ft); |
| 2475 break; | 2731 break; |
| 2476 case ABS_D: | 2732 case ABS_D: |
| 2477 set_fpu_register_float(fd_reg, fabs(fs)); | 2733 set_fpu_register_float(fd_reg, fabs(fs)); |
| 2478 break; | 2734 break; |
| 2479 case MOV_D: | 2735 case MOV_D: |
| 2480 set_fpu_register_float(fd_reg, fs); | 2736 set_fpu_register_float(fd_reg, fs); |
| 2481 break; | 2737 break; |
| 2482 case NEG_D: | 2738 case NEG_D: |
| 2483 set_fpu_register_float(fd_reg, -fs); | 2739 set_fpu_register_float(fd_reg, -fs); |
| 2484 break; | 2740 break; |
| 2485 case SQRT_D: | 2741 case SQRT_D: |
| 2486 set_fpu_register_float(fd_reg, fast_sqrt(fs)); | 2742 set_fpu_register_float(fd_reg, fast_sqrt(fs)); |
| 2487 break; | 2743 break; |
| 2744 case RSQRT_D: { |
| 2745 float result = 1.0 / fast_sqrt(fs); |
| 2746 set_fpu_register_float(fd_reg, result); |
| 2747 break; |
| 2748 } |
| 2749 case RECIP: { |
| 2750 float result = 1.0 / fs; |
| 2751 set_fpu_register_float(fd_reg, result); |
| 2752 break; |
| 2753 } |
| 2488 case C_UN_D: | 2754 case C_UN_D: |
| 2489 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); | 2755 set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft)); |
| 2490 break; | 2756 break; |
| 2491 case C_EQ_D: | 2757 case C_EQ_D: |
| 2492 set_fcsr_bit(fcsr_cc, (fs == ft)); | 2758 set_fcsr_bit(fcsr_cc, (fs == ft)); |
| 2493 break; | 2759 break; |
| 2494 case C_UEQ_D: | 2760 case C_UEQ_D: |
| 2495 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); | 2761 set_fcsr_bit(fcsr_cc, (fs == ft) || (std::isnan(fs) || std::isnan(ft))); |
| 2496 break; | 2762 break; |
| 2497 case C_OLT_D: | 2763 case C_OLT_D: |
| 2498 set_fcsr_bit(fcsr_cc, (fs < ft)); | 2764 set_fcsr_bit(fcsr_cc, (fs < ft)); |
| 2499 break; | 2765 break; |
| 2500 case C_ULT_D: | 2766 case C_ULT_D: |
| 2501 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); | 2767 set_fcsr_bit(fcsr_cc, (fs < ft) || (std::isnan(fs) || std::isnan(ft))); |
| 2502 break; | 2768 break; |
| 2503 case C_OLE_D: | 2769 case C_OLE_D: |
| 2504 set_fcsr_bit(fcsr_cc, (fs <= ft)); | 2770 set_fcsr_bit(fcsr_cc, (fs <= ft)); |
| 2505 break; | 2771 break; |
| 2506 case C_ULE_D: | 2772 case C_ULE_D: |
| 2507 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); | 2773 set_fcsr_bit(fcsr_cc, (fs <= ft) || (std::isnan(fs) || std::isnan(ft))); |
| 2508 break; | 2774 break; |
| 2509 case CVT_D_S: | 2775 case CVT_D_S: |
| 2510 set_fpu_register_double(fd_reg, static_cast<double>(fs)); | 2776 set_fpu_register_double(fd_reg, static_cast<double>(fs)); |
| 2511 break; | 2777 break; |
| 2778 case SEL: |
| 2779 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2780 set_fpu_register_float(fd_reg, (fd_int & 0x1) == 0 ? fs : ft); |
| 2781 break; |
| 2512 case SELEQZ_C: | 2782 case SELEQZ_C: |
| 2513 DCHECK(IsMipsArchVariant(kMips32r6)); | 2783 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2514 set_fpu_register_double( | 2784 set_fpu_register_float( |
| 2515 fd_reg, (ft_int & 0x1) == 0 ? get_fpu_register_double(fs_reg) : 0.0); | 2785 fd_reg, (ft_int & 0x1) == 0 ? get_fpu_register_float(fs_reg) : 0.0); |
| 2516 break; | 2786 break; |
| 2517 case SELNEZ_C: | 2787 case SELNEZ_C: |
| 2518 DCHECK(IsMipsArchVariant(kMips32r6)); | 2788 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2519 set_fpu_register_double( | 2789 set_fpu_register_float( |
| 2520 fd_reg, (ft_int & 0x1) != 0 ? get_fpu_register_double(fs_reg) : 0.0); | 2790 fd_reg, (ft_int & 0x1) != 0 ? get_fpu_register_float(fs_reg) : 0.0); |
| 2791 break; |
| 2792 case MOVZ_C: { |
| 2793 DCHECK(IsMipsArchVariant(kMips32r2)); |
| 2794 int32_t rt_reg = instr->RtValue(); |
| 2795 int32_t rt = get_register(rt_reg); |
| 2796 if (rt == 0) { |
| 2797 set_fpu_register_float(fd_reg, fs); |
| 2798 } |
| 2799 break; |
| 2800 } |
| 2801 case MOVN_C: { |
| 2802 DCHECK(IsMipsArchVariant(kMips32r2)); |
| 2803 int32_t rt_reg = instr->RtValue(); |
| 2804 int32_t rt = get_register(rt_reg); |
| 2805 if (rt != 0) { |
| 2806 set_fpu_register_float(fd_reg, fs); |
| 2807 } |
| 2808 break; |
| 2809 } |
| 2810 case MOVF: { |
| 2811 // Same function field for MOVT.D and MOVF.D |
| 2812 uint32_t ft_cc = (ft_reg >> 2) & 0x7; |
| 2813 ft_cc = get_fcsr_condition_bit(ft_cc); |
| 2814 |
| 2815 if (instr->Bit(16)) { // Read Tf bit. |
| 2816 // MOVT.D |
| 2817 if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg, fs); |
| 2818 } else { |
| 2819 // MOVF.D |
| 2820 if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg, fs); |
| 2821 } |
| 2822 break; |
| 2823 } |
| 2824 case TRUNC_W_S: { // Truncate single to word (round towards 0). |
| 2825 float rounded = trunc(fs); |
| 2826 int32_t result = static_cast<int32_t>(rounded); |
| 2827 set_fpu_register_word(fd_reg, result); |
| 2828 if (set_fcsr_round_error(fs, rounded)) { |
| 2829 set_fpu_register_word(fd_reg, kFPUInvalidResult); |
| 2830 } |
| 2831 } break; |
| 2832 case TRUNC_L_S: { // Mips32r2 instruction. |
| 2833 float rounded = trunc(fs); |
| 2834 int64_t i64 = static_cast<int64_t>(rounded); |
| 2835 if (IsFp64Mode()) { |
| 2836 set_fpu_register(fd_reg, i64); |
| 2837 if (set_fcsr_round64_error(fs, rounded)) { |
| 2838 set_fpu_register(fd_reg, kFPU64InvalidResult); |
| 2839 } |
| 2840 } else { |
| 2841 set_fpu_register_word(fd_reg, i64 & 0xffffffff); |
| 2842 set_fpu_register_word(fd_reg + 1, i64 >> 32); |
| 2843 if (set_fcsr_round64_error(fs, rounded)) { |
| 2844 set_fpu_register_word(fd_reg, kFPU64InvalidResult & 0xffffffff); |
| 2845 set_fpu_register_word(fd_reg + 1, kFPU64InvalidResult >> 32); |
| 2846 } |
| 2847 } |
| 2848 break; |
| 2849 } |
| 2850 case FLOOR_W_S: // Round double to word towards negative infinity. |
| 2851 { |
| 2852 float rounded = std::floor(fs); |
| 2853 int32_t result = static_cast<int32_t>(rounded); |
| 2854 set_fpu_register_word(fd_reg, result); |
| 2855 if (set_fcsr_round_error(fs, rounded)) { |
| 2856 set_fpu_register_word(fd_reg, kFPUInvalidResult); |
| 2857 } |
| 2858 } break; |
| 2859 case FLOOR_L_D: { // Mips32r2 instruction. |
| 2860 float rounded = std::floor(fs); |
| 2861 int64_t i64 = static_cast<int64_t>(rounded); |
| 2862 if (IsFp64Mode()) { |
| 2863 set_fpu_register(fd_reg, i64); |
| 2864 if (set_fcsr_round64_error(fs, rounded)) { |
| 2865 set_fpu_register(fd_reg, kFPU64InvalidResult); |
| 2866 } |
| 2867 } else { |
| 2868 set_fpu_register_word(fd_reg, i64 & 0xffffffff); |
| 2869 set_fpu_register_word(fd_reg + 1, i64 >> 32); |
| 2870 if (set_fcsr_round64_error(fs, rounded)) { |
| 2871 set_fpu_register_word(fd_reg, kFPU64InvalidResult & 0xffffffff); |
| 2872 set_fpu_register_word(fd_reg + 1, kFPU64InvalidResult >> 32); |
| 2873 } |
| 2874 } |
| 2875 break; |
| 2876 } |
| 2877 case ROUND_W_S: { |
| 2878 float rounded = std::floor(fs + 0.5); |
| 2879 int32_t result = static_cast<int32_t>(rounded); |
| 2880 if ((result & 1) != 0 && result - fs == 0.5) { |
| 2881 // If the number is halfway between two integers, |
| 2882 // round to the even one. |
| 2883 result--; |
| 2884 } |
| 2885 set_fpu_register_word(fd_reg, result); |
| 2886 if (set_fcsr_round_error(fs, rounded)) { |
| 2887 set_fpu_register_word(fd_reg, kFPUInvalidResult); |
| 2888 } |
| 2889 break; |
| 2890 } |
| 2891 case ROUND_L_S: { // Mips32r2 instruction. |
| 2892 float rounded = std::floor(fs + 0.5); |
| 2893 int64_t result = static_cast<int64_t>(rounded); |
| 2894 if ((result & 1) != 0 && result - fs == 0.5) { |
| 2895 // If the number is halfway between two integers, |
| 2896 // round to the even one. |
| 2897 result--; |
| 2898 } |
| 2899 int64_t i64 = static_cast<int64_t>(result); |
| 2900 if (IsFp64Mode()) { |
| 2901 set_fpu_register(fd_reg, i64); |
| 2902 if (set_fcsr_round64_error(fs, rounded)) { |
| 2903 set_fpu_register(fd_reg, kFPU64InvalidResult); |
| 2904 } |
| 2905 } else { |
| 2906 set_fpu_register_word(fd_reg, i64 & 0xffffffff); |
| 2907 set_fpu_register_word(fd_reg + 1, i64 >> 32); |
| 2908 if (set_fcsr_round64_error(fs, rounded)) { |
| 2909 set_fpu_register_word(fd_reg, kFPU64InvalidResult & 0xffffffff); |
| 2910 set_fpu_register_word(fd_reg + 1, kFPU64InvalidResult >> 32); |
| 2911 } |
| 2912 } |
| 2913 break; |
| 2914 } |
| 2915 case CEIL_W_S: // Round double to word towards positive infinity. |
| 2916 { |
| 2917 float rounded = std::ceil(fs); |
| 2918 int32_t result = static_cast<int32_t>(rounded); |
| 2919 set_fpu_register_word(fd_reg, result); |
| 2920 if (set_fcsr_round_error(fs, rounded)) { |
| 2921 set_fpu_register_word(fd_reg, kFPUInvalidResult); |
| 2922 } |
| 2923 } break; |
| 2924 case CEIL_L_S: { // Mips32r2 instruction. |
| 2925 float rounded = std::ceil(fs); |
| 2926 int64_t i64 = static_cast<int64_t>(rounded); |
| 2927 if (IsFp64Mode()) { |
| 2928 set_fpu_register(fd_reg, i64); |
| 2929 if (set_fcsr_round64_error(fs, rounded)) { |
| 2930 set_fpu_register(fd_reg, kFPU64InvalidResult); |
| 2931 } |
| 2932 } else { |
| 2933 set_fpu_register_word(fd_reg, i64 & 0xffffffff); |
| 2934 set_fpu_register_word(fd_reg + 1, i64 >> 32); |
| 2935 if (set_fcsr_round64_error(fs, rounded)) { |
| 2936 set_fpu_register_word(fd_reg, kFPU64InvalidResult & 0xffffffff); |
| 2937 set_fpu_register_word(fd_reg + 1, kFPU64InvalidResult >> 32); |
| 2938 } |
| 2939 } |
| 2940 break; |
| 2941 } |
| 2942 case MIN: |
| 2943 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2944 fs = get_fpu_register_float(fs_reg); |
| 2945 if (std::isnan(fs) && std::isnan(ft)) { |
| 2946 set_fpu_register_float(fd_reg, fs); |
| 2947 } else if (std::isnan(fs) && !std::isnan(ft)) { |
| 2948 set_fpu_register_float(fd_reg, ft); |
| 2949 } else if (!std::isnan(fs) && std::isnan(ft)) { |
| 2950 set_fpu_register_float(fd_reg, fs); |
| 2951 } else { |
| 2952 set_fpu_register_float(fd_reg, (fs >= ft) ? ft : fs); |
| 2953 } |
| 2954 break; |
| 2955 case MAX: |
| 2956 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2957 fs = get_fpu_register_float(fs_reg); |
| 2958 if (std::isnan(fs) && std::isnan(ft)) { |
| 2959 set_fpu_register_float(fd_reg, fs); |
| 2960 } else if (std::isnan(fs) && !std::isnan(ft)) { |
| 2961 set_fpu_register_float(fd_reg, ft); |
| 2962 } else if (!std::isnan(fs) && std::isnan(ft)) { |
| 2963 set_fpu_register_float(fd_reg, fs); |
| 2964 } else { |
| 2965 set_fpu_register_float(fd_reg, (fs <= ft) ? ft : fs); |
| 2966 } |
| 2967 break; |
| 2968 case MINA: |
| 2969 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2970 fs = get_fpu_register_float(fs_reg); |
| 2971 if (std::isnan(fs) && std::isnan(ft)) { |
| 2972 set_fpu_register_float(fd_reg, fs); |
| 2973 } else if (std::isnan(fs) && !std::isnan(ft)) { |
| 2974 set_fpu_register_float(fd_reg, ft); |
| 2975 } else if (!std::isnan(fs) && std::isnan(ft)) { |
| 2976 set_fpu_register_float(fd_reg, fs); |
| 2977 } else { |
| 2978 float result; |
| 2979 if (fabs(fs) > fabs(ft)) { |
| 2980 result = ft; |
| 2981 } else if (fabs(fs) < fabs(ft)) { |
| 2982 result = fs; |
| 2983 } else { |
| 2984 result = (fs > ft ? fs : ft); |
| 2985 } |
| 2986 set_fpu_register_float(fd_reg, result); |
| 2987 } |
| 2988 break; |
| 2989 case MAXA: |
| 2990 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 2991 fs = get_fpu_register_float(fs_reg); |
| 2992 if (std::isnan(fs) && std::isnan(ft)) { |
| 2993 set_fpu_register_float(fd_reg, fs); |
| 2994 } else if (std::isnan(fs) && !std::isnan(ft)) { |
| 2995 set_fpu_register_float(fd_reg, ft); |
| 2996 } else if (!std::isnan(fs) && std::isnan(ft)) { |
| 2997 set_fpu_register_float(fd_reg, fs); |
| 2998 } else { |
| 2999 float result; |
| 3000 if (fabs(fs) < fabs(ft)) { |
| 3001 result = ft; |
| 3002 } else if (fabs(fs) > fabs(ft)) { |
| 3003 result = fs; |
| 3004 } else { |
| 3005 result = (fs > ft ? fs : ft); |
| 3006 } |
| 3007 set_fpu_register_float(fd_reg, result); |
| 3008 } |
| 2521 break; | 3009 break; |
| 2522 default: | 3010 default: |
| 2523 // CVT_W_S CVT_L_S TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S | 3011 // CVT_W_S CVT_L_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S |
| 2524 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. | 3012 // CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented. |
| 2525 UNREACHABLE(); | 3013 UNREACHABLE(); |
| 2526 } | 3014 } |
| 2527 } | 3015 } |
| 2528 | 3016 |
| 2529 | 3017 |
| 2530 void Simulator::DecodeTypeRegisterLRsType(Instruction* instr, | 3018 void Simulator::DecodeTypeRegisterLRsType(Instruction* instr, |
| 2531 const int32_t& ft_reg, | 3019 const int32_t& ft_reg, |
| 2532 const int32_t& fs_reg, | 3020 const int32_t& fs_reg, |
| 2533 const int32_t& fd_reg) { | 3021 const int32_t& fd_reg) { |
| (...skipping 1000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3534 } | 4022 } |
| 3535 | 4023 |
| 3536 | 4024 |
| 3537 #undef UNSUPPORTED | 4025 #undef UNSUPPORTED |
| 3538 | 4026 |
| 3539 } } // namespace v8::internal | 4027 } } // namespace v8::internal |
| 3540 | 4028 |
| 3541 #endif // USE_SIMULATOR | 4029 #endif // USE_SIMULATOR |
| 3542 | 4030 |
| 3543 #endif // V8_TARGET_ARCH_MIPS | 4031 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |