OLD | NEW |
1 // Copyright 2007-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2009 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 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 ASSERT(STRING_STARTS_WITH(format, "target")); | 431 ASSERT(STRING_STARTS_WITH(format, "target")); |
432 int off = (instr->SImmed24Field() << 2) + 8; | 432 int off = (instr->SImmed24Field() << 2) + 8; |
433 out_buffer_pos_ += v8i::OS::SNPrintF( | 433 out_buffer_pos_ += v8i::OS::SNPrintF( |
434 out_buffer_ + out_buffer_pos_, | 434 out_buffer_ + out_buffer_pos_, |
435 "%+d -> %s", | 435 "%+d -> %s", |
436 off, | 436 off, |
437 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off)); | 437 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off)); |
438 return 6; | 438 return 6; |
439 } | 439 } |
440 case 'u': { // 'u: signed or unsigned multiplies | 440 case 'u': { // 'u: signed or unsigned multiplies |
441 if (instr->Bit(22) == 1) { | 441 // The manual gets the meaning of bit 22 backwards in the multiply |
| 442 // instruction overview on page A3.16.2. The instructions that |
| 443 // exist in u and s variants are the following: |
| 444 // smull A4.1.87 |
| 445 // umull A4.1.129 |
| 446 // umlal A4.1.128 |
| 447 // smlal A4.1.76 |
| 448 // For these 0 means u and 1 means s. As can be seen on their individual |
| 449 // pages. The other 18 mul instructions have the bit set or unset in |
| 450 // arbitrary ways that are unrelated to the signedness of the instruction. |
| 451 // None of these 18 instructions exist in both a 'u' and an 's' variant. |
| 452 |
| 453 if (instr->Bit(22) == 0) { |
442 Print("u"); | 454 Print("u"); |
443 } else { | 455 } else { |
444 Print("s"); | 456 Print("s"); |
445 } | 457 } |
446 return 1; | 458 return 1; |
447 } | 459 } |
448 case 'w': { // 'w: W field of load and store instructions | 460 case 'w': { // 'w: W field of load and store instructions |
449 if (instr->HasW()) { | 461 if (instr->HasW()) { |
450 Print("!"); | 462 Print("!"); |
451 } | 463 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 | 499 |
488 void Decoder::DecodeType01(Instr* instr) { | 500 void Decoder::DecodeType01(Instr* instr) { |
489 int type = instr->TypeField(); | 501 int type = instr->TypeField(); |
490 if ((type == 0) && instr->IsSpecialType0()) { | 502 if ((type == 0) && instr->IsSpecialType0()) { |
491 // multiply instruction or extra loads and stores | 503 // multiply instruction or extra loads and stores |
492 if (instr->Bits(7, 4) == 9) { | 504 if (instr->Bits(7, 4) == 9) { |
493 if (instr->Bit(24) == 0) { | 505 if (instr->Bit(24) == 0) { |
494 // multiply instructions | 506 // multiply instructions |
495 if (instr->Bit(23) == 0) { | 507 if (instr->Bit(23) == 0) { |
496 if (instr->Bit(21) == 0) { | 508 if (instr->Bit(21) == 0) { |
497 Format(instr, "mul'cond's 'rd, 'rm, 'rs"); | 509 // Mul calls it Rd. Everyone else calls it Rn. |
| 510 Format(instr, "mul'cond's 'rn, 'rm, 'rs"); |
498 } else { | 511 } else { |
499 Format(instr, "mla'cond's 'rd, 'rm, 'rs, 'rn"); | 512 // In the manual the order is rd, rm, rs, rn. But mla swaps the |
| 513 // positions of rn and rd in the encoding. |
| 514 Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd"); |
500 } | 515 } |
501 } else { | 516 } else { |
| 517 // In the manual the order is RdHi, RdLo, Rm, Rs. |
| 518 // RdHi is what other instructions call Rn and RdLo is Rd. |
502 Format(instr, "'um'al'cond's 'rn, 'rd, 'rm, 'rs"); | 519 Format(instr, "'um'al'cond's 'rn, 'rd, 'rm, 'rs"); |
503 } | 520 } |
504 } else { | 521 } else { |
505 Unknown(instr); // not used by V8 | 522 Unknown(instr); // not used by V8 |
506 } | 523 } |
507 } else { | 524 } else { |
508 // extra load/store instructions | 525 // extra load/store instructions |
509 switch (instr->PUField()) { | 526 switch (instr->PUField()) { |
510 case 0: { | 527 case 0: { |
511 if (instr->Bit(22) == 0) { | 528 if (instr->Bit(22) == 0) { |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 buffer[0] = '\0'; | 914 buffer[0] = '\0'; |
898 byte* prev_pc = pc; | 915 byte* prev_pc = pc; |
899 pc += d.InstructionDecode(buffer, pc); | 916 pc += d.InstructionDecode(buffer, pc); |
900 fprintf(f, "%p %08x %s\n", | 917 fprintf(f, "%p %08x %s\n", |
901 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 918 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
902 } | 919 } |
903 } | 920 } |
904 | 921 |
905 | 922 |
906 } // namespace disasm | 923 } // namespace disasm |
OLD | NEW |