| OLD | NEW |
| 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 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1369 } | 1369 } |
| 1370 } | 1370 } |
| 1371 } | 1371 } |
| 1372 | 1372 |
| 1373 | 1373 |
| 1374 void Simulator::DecodeCop1(Instr* instr) { | 1374 void Simulator::DecodeCop1(Instr* instr) { |
| 1375 ASSERT(instr->OpcodeField() == COP1); | 1375 ASSERT(instr->OpcodeField() == COP1); |
| 1376 if (instr->HasFormat()) { | 1376 if (instr->HasFormat()) { |
| 1377 // If the rs field is a valid format, then the function field identifies the | 1377 // If the rs field is a valid format, then the function field identifies the |
| 1378 // instruction. | 1378 // instruction. |
| 1379 ASSERT(instr->FormatField() == FMT_D); // Only D supported. | |
| 1380 double fs_val = get_fregister_double(instr->FsField()); | 1379 double fs_val = get_fregister_double(instr->FsField()); |
| 1381 double ft_val = get_fregister_double(instr->FtField()); | 1380 double ft_val = get_fregister_double(instr->FtField()); |
| 1382 uint32_t cc, fcsr_cc; | 1381 uint32_t cc, fcsr_cc; |
| 1383 cc = instr->FpuCCField(); | 1382 cc = instr->FpuCCField(); |
| 1384 fcsr_cc = get_fcsr_condition_bit(cc); | 1383 fcsr_cc = get_fcsr_condition_bit(cc); |
| 1385 switch (instr->Cop1FunctionField()) { | 1384 switch (instr->Cop1FunctionField()) { |
| 1386 case COP1_ADD: { | 1385 case COP1_ADD: { |
| 1387 // Format(instr, "add.'fmt 'fd, 'fs, 'ft"); | 1386 // Format(instr, "add.'fmt 'fd, 'fs, 'ft"); |
| 1387 ASSERT(instr->FormatField() == FMT_D); // Only D supported. |
| 1388 set_fregister_double(instr->FdField(), fs_val + ft_val); | 1388 set_fregister_double(instr->FdField(), fs_val + ft_val); |
| 1389 break; | 1389 break; |
| 1390 } | 1390 } |
| 1391 case COP1_MOV: { | 1391 case COP1_MOV: { |
| 1392 // Format(instr, "mov.'fmt 'fd, 'fs"); | 1392 // Format(instr, "mov.'fmt 'fd, 'fs"); |
| 1393 ASSERT(instr->FormatField() == FMT_D); // Only D supported. |
| 1393 set_fregister_double(instr->FdField(), fs_val); | 1394 set_fregister_double(instr->FdField(), fs_val); |
| 1394 break; | 1395 break; |
| 1395 } | 1396 } |
| 1396 case COP1_C_F: { | 1397 case COP1_C_F: { |
| 1398 ASSERT(instr->FormatField() == FMT_D); // Only D supported. |
| 1397 ASSERT(instr->FdField() == F0); | 1399 ASSERT(instr->FdField() == F0); |
| 1398 set_fcsr_bit(fcsr_cc, false); | 1400 set_fcsr_bit(fcsr_cc, false); |
| 1399 break; | 1401 break; |
| 1400 } | 1402 } |
| 1401 case COP1_C_UN: { | 1403 case COP1_C_UN: { |
| 1404 ASSERT(instr->FormatField() == FMT_D); // Only D supported. |
| 1402 ASSERT(instr->FdField() == F0); | 1405 ASSERT(instr->FdField() == F0); |
| 1403 set_fcsr_bit(fcsr_cc, isnan(fs_val) || isnan(ft_val)); | 1406 set_fcsr_bit(fcsr_cc, isnan(fs_val) || isnan(ft_val)); |
| 1404 break; | 1407 break; |
| 1405 } | 1408 } |
| 1406 case COP1_C_EQ: { | 1409 case COP1_C_EQ: { |
| 1410 ASSERT(instr->FormatField() == FMT_D); // Only D supported. |
| 1407 ASSERT(instr->FdField() == F0); | 1411 ASSERT(instr->FdField() == F0); |
| 1408 set_fcsr_bit(fcsr_cc, (fs_val == ft_val)); | 1412 set_fcsr_bit(fcsr_cc, (fs_val == ft_val)); |
| 1409 break; | 1413 break; |
| 1410 } | 1414 } |
| 1411 case COP1_C_UEQ: { | 1415 case COP1_C_UEQ: { |
| 1416 ASSERT(instr->FormatField() == FMT_D); // Only D supported. |
| 1412 ASSERT(instr->FdField() == F0); | 1417 ASSERT(instr->FdField() == F0); |
| 1413 set_fcsr_bit(fcsr_cc, | 1418 set_fcsr_bit(fcsr_cc, |
| 1414 (fs_val == ft_val) || isnan(fs_val) || isnan(ft_val)); | 1419 (fs_val == ft_val) || isnan(fs_val) || isnan(ft_val)); |
| 1415 break; | 1420 break; |
| 1416 } | 1421 } |
| 1417 case COP1_C_OLT: { | 1422 case COP1_C_OLT: { |
| 1423 ASSERT(instr->FormatField() == FMT_D); // Only D supported. |
| 1418 ASSERT(instr->FdField() == F0); | 1424 ASSERT(instr->FdField() == F0); |
| 1419 set_fcsr_bit(fcsr_cc, (fs_val < ft_val)); | 1425 set_fcsr_bit(fcsr_cc, (fs_val < ft_val)); |
| 1420 break; | 1426 break; |
| 1421 } | 1427 } |
| 1422 case COP1_C_ULT: { | 1428 case COP1_C_ULT: { |
| 1429 ASSERT(instr->FormatField() == FMT_D); // Only D supported. |
| 1423 ASSERT(instr->FdField() == F0); | 1430 ASSERT(instr->FdField() == F0); |
| 1424 set_fcsr_bit(fcsr_cc, | 1431 set_fcsr_bit(fcsr_cc, |
| 1425 (fs_val < ft_val) || isnan(fs_val) || isnan(ft_val)); | 1432 (fs_val < ft_val) || isnan(fs_val) || isnan(ft_val)); |
| 1426 break; | 1433 break; |
| 1427 } | 1434 } |
| 1428 case COP1_C_OLE: { | 1435 case COP1_C_OLE: { |
| 1436 ASSERT(instr->FormatField() == FMT_D); // Only D supported. |
| 1429 ASSERT(instr->FdField() == F0); | 1437 ASSERT(instr->FdField() == F0); |
| 1430 set_fcsr_bit(fcsr_cc, (fs_val <= ft_val)); | 1438 set_fcsr_bit(fcsr_cc, (fs_val <= ft_val)); |
| 1431 break; | 1439 break; |
| 1432 } | 1440 } |
| 1433 case COP1_C_ULE: { | 1441 case COP1_C_ULE: { |
| 1442 ASSERT(instr->FormatField() == FMT_D); // Only D supported. |
| 1434 ASSERT(instr->FdField() == F0); | 1443 ASSERT(instr->FdField() == F0); |
| 1435 set_fcsr_bit(fcsr_cc, | 1444 set_fcsr_bit(fcsr_cc, |
| 1436 (fs_val <= ft_val) || isnan(fs_val) || isnan(ft_val)); | 1445 (fs_val <= ft_val) || isnan(fs_val) || isnan(ft_val)); |
| 1437 break; | 1446 break; |
| 1438 } | 1447 } |
| 1448 case COP1_CVT_D: { |
| 1449 switch (instr->FormatField()) { |
| 1450 case FMT_W: { |
| 1451 int32_t fs_int = get_fregister(instr->FsField()); |
| 1452 double fs_dbl = static_cast<double>(fs_int); |
| 1453 set_fregister_double(instr->FdField(), fs_dbl); |
| 1454 break; |
| 1455 } |
| 1456 case FMT_L: { |
| 1457 int64_t fs_int = get_fregister_long(instr->FsField()); |
| 1458 double fs_dbl = static_cast<double>(fs_int); |
| 1459 set_fregister_double(instr->FdField(), fs_dbl); |
| 1460 break; |
| 1461 } |
| 1462 default: { |
| 1463 OS::PrintErr("DecodeCop1: 0x%x\n", instr->InstructionBits()); |
| 1464 UnimplementedInstruction(instr); |
| 1465 break; |
| 1466 } |
| 1467 } |
| 1468 break; |
| 1469 } |
| 1439 default: { | 1470 default: { |
| 1440 OS::PrintErr("DecodeCop1: 0x%x\n", instr->InstructionBits()); | 1471 OS::PrintErr("DecodeCop1: 0x%x\n", instr->InstructionBits()); |
| 1441 UnimplementedInstruction(instr); | 1472 UnimplementedInstruction(instr); |
| 1442 break; | 1473 break; |
| 1443 } | 1474 } |
| 1444 } | 1475 } |
| 1445 } else { | 1476 } else { |
| 1446 // If the rs field isn't a valid format, then it must be a sub-op. | 1477 // If the rs field isn't a valid format, then it must be a sub-op. |
| 1447 switch (instr->Cop1SubField()) { | 1478 switch (instr->Cop1SubField()) { |
| 1448 case COP1_MF: { | 1479 case COP1_MF: { |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1924 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); | 1955 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); |
| 1925 } | 1956 } |
| 1926 buf->Longjmp(); | 1957 buf->Longjmp(); |
| 1927 } | 1958 } |
| 1928 | 1959 |
| 1929 } // namespace dart | 1960 } // namespace dart |
| 1930 | 1961 |
| 1931 #endif // !defined(HOST_ARCH_MIPS) | 1962 #endif // !defined(HOST_ARCH_MIPS) |
| 1932 | 1963 |
| 1933 #endif // defined TARGET_ARCH_MIPS | 1964 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |