| 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 // A Disassembler object is used to disassemble a block of code instruction by | 5 // A Disassembler object is used to disassemble a block of code instruction by |
| 6 // instruction. The default implementation of the NameConverter object can be | 6 // instruction. The default implementation of the NameConverter object can be |
| 7 // overriden to modify register names or to do symbol lookup on addresses. | 7 // overriden to modify register names or to do symbol lookup on addresses. |
| 8 // | 8 // |
| 9 // The example below will disassemble a block of code and print it to stdout. | 9 // The example below will disassemble a block of code and print it to stdout. |
| 10 // | 10 // |
| (...skipping 1306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1317 } | 1317 } |
| 1318 | 1318 |
| 1319 | 1319 |
| 1320 // void Decoder::DecodeTypeVFP(Instruction* instr) | 1320 // void Decoder::DecodeTypeVFP(Instruction* instr) |
| 1321 // vmov: Sn = Rt | 1321 // vmov: Sn = Rt |
| 1322 // vmov: Rt = Sn | 1322 // vmov: Rt = Sn |
| 1323 // vcvt: Dd = Sm | 1323 // vcvt: Dd = Sm |
| 1324 // vcvt: Sd = Dm | 1324 // vcvt: Sd = Dm |
| 1325 // vcvt.f64.s32 Dd, Dd, #<fbits> | 1325 // vcvt.f64.s32 Dd, Dd, #<fbits> |
| 1326 // Dd = vabs(Dm) | 1326 // Dd = vabs(Dm) |
| 1327 // Sd = vabs(Sm) |
| 1327 // Dd = vneg(Dm) | 1328 // Dd = vneg(Dm) |
| 1329 // Sd = vneg(Sm) |
| 1328 // Dd = vadd(Dn, Dm) | 1330 // Dd = vadd(Dn, Dm) |
| 1331 // Sd = vadd(Sn, Sm) |
| 1329 // Dd = vsub(Dn, Dm) | 1332 // Dd = vsub(Dn, Dm) |
| 1333 // Sd = vsub(Sn, Sm) |
| 1330 // Dd = vmul(Dn, Dm) | 1334 // Dd = vmul(Dn, Dm) |
| 1335 // Sd = vmul(Sn, Sm) |
| 1331 // Dd = vmla(Dn, Dm) | 1336 // Dd = vmla(Dn, Dm) |
| 1337 // Sd = vmla(Sn, Sm) |
| 1332 // Dd = vmls(Dn, Dm) | 1338 // Dd = vmls(Dn, Dm) |
| 1339 // Sd = vmls(Sn, Sm) |
| 1333 // Dd = vdiv(Dn, Dm) | 1340 // Dd = vdiv(Dn, Dm) |
| 1341 // Sd = vdiv(Sn, Sm) |
| 1334 // vcmp(Dd, Dm) | 1342 // vcmp(Dd, Dm) |
| 1343 // vcmp(Sd, Sm) |
| 1344 // Dd = vsqrt(Dm) |
| 1345 // Sd = vsqrt(Sm) |
| 1335 // vmrs | 1346 // vmrs |
| 1336 // vmsr | 1347 // vmsr |
| 1337 // Dd = vsqrt(Dm) | |
| 1338 void Decoder::DecodeTypeVFP(Instruction* instr) { | 1348 void Decoder::DecodeTypeVFP(Instruction* instr) { |
| 1339 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) ); | 1349 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) ); |
| 1340 VERIFY(instr->Bits(11, 9) == 0x5); | 1350 VERIFY(instr->Bits(11, 9) == 0x5); |
| 1341 | 1351 |
| 1342 if (instr->Bit(4) == 0) { | 1352 if (instr->Bit(4) == 0) { |
| 1343 if (instr->Opc1Value() == 0x7) { | 1353 if (instr->Opc1Value() == 0x7) { |
| 1344 // Other data processing instructions | 1354 // Other data processing instructions |
| 1345 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) { | 1355 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) { |
| 1346 // vmov register to register. | 1356 // vmov register to register. |
| 1347 if (instr->SzValue() == 0x1) { | 1357 if (instr->SzValue() == 0x1) { |
| 1348 Format(instr, "vmov'cond.f64 'Dd, 'Dm"); | 1358 Format(instr, "vmov'cond.f64 'Dd, 'Dm"); |
| 1349 } else { | 1359 } else { |
| 1350 Format(instr, "vmov'cond.f32 'Sd, 'Sm"); | 1360 Format(instr, "vmov'cond.f32 'Sd, 'Sm"); |
| 1351 } | 1361 } |
| 1352 } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) { | 1362 } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) { |
| 1353 // vabs | 1363 // vabs |
| 1354 Format(instr, "vabs'cond.f64 'Dd, 'Dm"); | 1364 if (instr->SzValue() == 0x1) { |
| 1365 Format(instr, "vabs'cond.f64 'Dd, 'Dm"); |
| 1366 } else { |
| 1367 Format(instr, "vabs'cond.f32 'Sd, 'Sm"); |
| 1368 } |
| 1355 } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) { | 1369 } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) { |
| 1356 // vneg | 1370 // vneg |
| 1357 Format(instr, "vneg'cond.f64 'Dd, 'Dm"); | 1371 if (instr->SzValue() == 0x1) { |
| 1372 Format(instr, "vneg'cond.f64 'Dd, 'Dm"); |
| 1373 } else { |
| 1374 Format(instr, "vneg'cond.f32 'Sd, 'Sm"); |
| 1375 } |
| 1358 } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) { | 1376 } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) { |
| 1359 DecodeVCVTBetweenDoubleAndSingle(instr); | 1377 DecodeVCVTBetweenDoubleAndSingle(instr); |
| 1360 } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) { | 1378 } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) { |
| 1361 DecodeVCVTBetweenFloatingPointAndInteger(instr); | 1379 DecodeVCVTBetweenFloatingPointAndInteger(instr); |
| 1362 } else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) && | 1380 } else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) && |
| 1363 (instr->Bit(8) == 1)) { | 1381 (instr->Bit(8) == 1)) { |
| 1364 // vcvt.f64.s32 Dd, Dd, #<fbits> | 1382 // vcvt.f64.s32 Dd, Dd, #<fbits> |
| 1365 int fraction_bits = 32 - ((instr->Bits(3, 0) << 1) | instr->Bit(5)); | 1383 int fraction_bits = 32 - ((instr->Bits(3, 0) << 1) | instr->Bit(5)); |
| 1366 Format(instr, "vcvt'cond.f64.s32 'Dd, 'Dd"); | 1384 Format(instr, "vcvt'cond.f64.s32 'Dd, 'Dd"); |
| 1367 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | 1385 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| 1368 ", #%d", fraction_bits); | 1386 ", #%d", fraction_bits); |
| 1369 } else if (((instr->Opc2Value() >> 1) == 0x6) && | 1387 } else if (((instr->Opc2Value() >> 1) == 0x6) && |
| 1370 (instr->Opc3Value() & 0x1)) { | 1388 (instr->Opc3Value() & 0x1)) { |
| 1371 DecodeVCVTBetweenFloatingPointAndInteger(instr); | 1389 DecodeVCVTBetweenFloatingPointAndInteger(instr); |
| 1372 } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && | 1390 } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && |
| 1373 (instr->Opc3Value() & 0x1)) { | 1391 (instr->Opc3Value() & 0x1)) { |
| 1374 DecodeVCMP(instr); | 1392 DecodeVCMP(instr); |
| 1375 } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) { | 1393 } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) { |
| 1376 Format(instr, "vsqrt'cond.f64 'Dd, 'Dm"); | 1394 if (instr->SzValue() == 0x1) { |
| 1395 Format(instr, "vsqrt'cond.f64 'Dd, 'Dm"); |
| 1396 } else { |
| 1397 Format(instr, "vsqrt'cond.f32 'Sd, 'Sm"); |
| 1398 } |
| 1377 } else if (instr->Opc3Value() == 0x0) { | 1399 } else if (instr->Opc3Value() == 0x0) { |
| 1378 if (instr->SzValue() == 0x1) { | 1400 if (instr->SzValue() == 0x1) { |
| 1379 Format(instr, "vmov'cond.f64 'Dd, 'd"); | 1401 Format(instr, "vmov'cond.f64 'Dd, 'd"); |
| 1380 } else { | 1402 } else { |
| 1381 Unknown(instr); // Not used by V8. | 1403 Unknown(instr); // Not used by V8. |
| 1382 } | 1404 } |
| 1383 } else if (((instr->Opc2Value() == 0x6)) && instr->Opc3Value() == 0x3) { | 1405 } else if (((instr->Opc2Value() == 0x6)) && instr->Opc3Value() == 0x3) { |
| 1384 bool dp_operation = (instr->SzValue() == 1); | |
| 1385 // vrintz - round towards zero (truncate) | 1406 // vrintz - round towards zero (truncate) |
| 1386 if (dp_operation) { | 1407 if (instr->SzValue() == 0x1) { |
| 1387 Format(instr, "vrintz'cond.f64.f64 'Dd, 'Dm"); | 1408 Format(instr, "vrintz'cond.f64.f64 'Dd, 'Dm"); |
| 1388 } else { | 1409 } else { |
| 1389 Unknown(instr); // Not used by V8. | 1410 Format(instr, "vrintz'cond.f32.f32 'Sd, 'Sm"); |
| 1390 } | 1411 } |
| 1391 } else { | 1412 } else { |
| 1392 Unknown(instr); // Not used by V8. | 1413 Unknown(instr); // Not used by V8. |
| 1393 } | 1414 } |
| 1394 } else if (instr->Opc1Value() == 0x3) { | 1415 } else if (instr->Opc1Value() == 0x3) { |
| 1395 if (instr->SzValue() == 0x1) { | 1416 if (instr->SzValue() == 0x1) { |
| 1396 if (instr->Opc3Value() & 0x1) { | 1417 if (instr->Opc3Value() & 0x1) { |
| 1397 Format(instr, "vsub'cond.f64 'Dd, 'Dn, 'Dm"); | 1418 Format(instr, "vsub'cond.f64 'Dd, 'Dn, 'Dm"); |
| 1398 } else { | 1419 } else { |
| 1399 Format(instr, "vadd'cond.f64 'Dd, 'Dn, 'Dm"); | 1420 Format(instr, "vadd'cond.f64 'Dd, 'Dn, 'Dm"); |
| 1400 } | 1421 } |
| 1401 } else { | 1422 } else { |
| 1402 Unknown(instr); // Not used by V8. | 1423 if (instr->Opc3Value() & 0x1) { |
| 1424 Format(instr, "vsub'cond.f32 'Sd, 'Sn, 'Sm"); |
| 1425 } else { |
| 1426 Format(instr, "vadd'cond.f32 'Sd, 'Sn, 'Sm"); |
| 1427 } |
| 1403 } | 1428 } |
| 1404 } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) { | 1429 } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) { |
| 1405 if (instr->SzValue() == 0x1) { | 1430 if (instr->SzValue() == 0x1) { |
| 1406 Format(instr, "vmul'cond.f64 'Dd, 'Dn, 'Dm"); | 1431 Format(instr, "vmul'cond.f64 'Dd, 'Dn, 'Dm"); |
| 1407 } else { | 1432 } else { |
| 1408 Unknown(instr); // Not used by V8. | 1433 Format(instr, "vmul'cond.f32 'Sd, 'Sn, 'Sm"); |
| 1409 } | 1434 } |
| 1410 } else if ((instr->Opc1Value() == 0x0) && !(instr->Opc3Value() & 0x1)) { | 1435 } else if ((instr->Opc1Value() == 0x0) && !(instr->Opc3Value() & 0x1)) { |
| 1411 if (instr->SzValue() == 0x1) { | 1436 if (instr->SzValue() == 0x1) { |
| 1412 Format(instr, "vmla'cond.f64 'Dd, 'Dn, 'Dm"); | 1437 Format(instr, "vmla'cond.f64 'Dd, 'Dn, 'Dm"); |
| 1413 } else { | 1438 } else { |
| 1414 Unknown(instr); // Not used by V8. | 1439 Format(instr, "vmla'cond.f32 'Sd, 'Sn, 'Sm"); |
| 1415 } | 1440 } |
| 1416 } else if ((instr->Opc1Value() == 0x0) && (instr->Opc3Value() & 0x1)) { | 1441 } else if ((instr->Opc1Value() == 0x0) && (instr->Opc3Value() & 0x1)) { |
| 1417 if (instr->SzValue() == 0x1) { | 1442 if (instr->SzValue() == 0x1) { |
| 1418 Format(instr, "vmls'cond.f64 'Dd, 'Dn, 'Dm"); | 1443 Format(instr, "vmls'cond.f64 'Dd, 'Dn, 'Dm"); |
| 1419 } else { | 1444 } else { |
| 1420 Unknown(instr); // Not used by V8. | 1445 Format(instr, "vmls'cond.f32 'Sd, 'Sn, 'Sm"); |
| 1421 } | 1446 } |
| 1422 } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) { | 1447 } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) { |
| 1423 if (instr->SzValue() == 0x1) { | 1448 if (instr->SzValue() == 0x1) { |
| 1424 Format(instr, "vdiv'cond.f64 'Dd, 'Dn, 'Dm"); | 1449 Format(instr, "vdiv'cond.f64 'Dd, 'Dn, 'Dm"); |
| 1425 } else { | 1450 } else { |
| 1426 Unknown(instr); // Not used by V8. | 1451 Format(instr, "vdiv'cond.f32 'Sd, 'Sn, 'Sm"); |
| 1427 } | 1452 } |
| 1428 } else { | 1453 } else { |
| 1429 Unknown(instr); // Not used by V8. | 1454 Unknown(instr); // Not used by V8. |
| 1430 } | 1455 } |
| 1431 } else { | 1456 } else { |
| 1432 if ((instr->VCValue() == 0x0) && | 1457 if ((instr->VCValue() == 0x0) && |
| 1433 (instr->VAValue() == 0x0)) { | 1458 (instr->VAValue() == 0x0)) { |
| 1434 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); | 1459 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); |
| 1435 } else if ((instr->VLValue() == 0x0) && | 1460 } else if ((instr->VLValue() == 0x0) && |
| 1436 (instr->VCValue() == 0x1) && | 1461 (instr->VCValue() == 0x1) && |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1494 bool raise_exception_for_qnan = (instr->Bit(7) == 0x1); | 1519 bool raise_exception_for_qnan = (instr->Bit(7) == 0x1); |
| 1495 | 1520 |
| 1496 if (dp_operation && !raise_exception_for_qnan) { | 1521 if (dp_operation && !raise_exception_for_qnan) { |
| 1497 if (instr->Opc2Value() == 0x4) { | 1522 if (instr->Opc2Value() == 0x4) { |
| 1498 Format(instr, "vcmp'cond.f64 'Dd, 'Dm"); | 1523 Format(instr, "vcmp'cond.f64 'Dd, 'Dm"); |
| 1499 } else if (instr->Opc2Value() == 0x5) { | 1524 } else if (instr->Opc2Value() == 0x5) { |
| 1500 Format(instr, "vcmp'cond.f64 'Dd, #0.0"); | 1525 Format(instr, "vcmp'cond.f64 'Dd, #0.0"); |
| 1501 } else { | 1526 } else { |
| 1502 Unknown(instr); // invalid | 1527 Unknown(instr); // invalid |
| 1503 } | 1528 } |
| 1529 } else if (!raise_exception_for_qnan) { |
| 1530 if (instr->Opc2Value() == 0x4) { |
| 1531 Format(instr, "vcmp'cond.f32 'Sd, 'Sm"); |
| 1532 } else if (instr->Opc2Value() == 0x5) { |
| 1533 Format(instr, "vcmp'cond.f32 'Sd, #0.0"); |
| 1534 } else { |
| 1535 Unknown(instr); // invalid |
| 1536 } |
| 1504 } else { | 1537 } else { |
| 1505 Unknown(instr); // Not used by V8. | 1538 Unknown(instr); // Not used by V8. |
| 1506 } | 1539 } |
| 1507 } | 1540 } |
| 1508 | 1541 |
| 1509 | 1542 |
| 1510 void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) { | 1543 void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) { |
| 1511 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); | 1544 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); |
| 1512 VERIFY((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)); | 1545 VERIFY((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)); |
| 1513 | 1546 |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1947 v8::internal::PrintF( | 1980 v8::internal::PrintF( |
| 1948 f, "%p %08x %s\n", | 1981 f, "%p %08x %s\n", |
| 1949 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1982 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
| 1950 } | 1983 } |
| 1951 } | 1984 } |
| 1952 | 1985 |
| 1953 | 1986 |
| 1954 } // namespace disasm | 1987 } // namespace disasm |
| 1955 | 1988 |
| 1956 #endif // V8_TARGET_ARCH_ARM | 1989 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |