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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 // Types 0 and 1 are combined as they are largely the same except for the way | 98 // Types 0 and 1 are combined as they are largely the same except for the way |
99 // they interpret the shifter operand. | 99 // they interpret the shifter operand. |
100 void DecodeType01(Instruction* instr); | 100 void DecodeType01(Instruction* instr); |
101 void DecodeType2(Instruction* instr); | 101 void DecodeType2(Instruction* instr); |
102 void DecodeType3(Instruction* instr); | 102 void DecodeType3(Instruction* instr); |
103 void DecodeType4(Instruction* instr); | 103 void DecodeType4(Instruction* instr); |
104 void DecodeType5(Instruction* instr); | 104 void DecodeType5(Instruction* instr); |
105 void DecodeType6(Instruction* instr); | 105 void DecodeType6(Instruction* instr); |
106 // Type 7 includes special Debugger instructions. | 106 // Type 7 includes special Debugger instructions. |
107 int DecodeType7(Instruction* instr); | 107 int DecodeType7(Instruction* instr); |
| 108 // CP15 coprocessor instructions. |
| 109 void DecodeTypeCP15(Instruction* instr); |
108 // For VFP support. | 110 // For VFP support. |
109 void DecodeTypeVFP(Instruction* instr); | 111 void DecodeTypeVFP(Instruction* instr); |
110 void DecodeType6CoprocessorIns(Instruction* instr); | 112 void DecodeType6CoprocessorIns(Instruction* instr); |
111 | 113 |
112 void DecodeSpecialCondition(Instruction* instr); | 114 void DecodeSpecialCondition(Instruction* instr); |
113 | 115 |
114 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr); | 116 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr); |
115 void DecodeVCMP(Instruction* instr); | 117 void DecodeVCMP(Instruction* instr); |
116 void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr); | 118 void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr); |
117 void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr); | 119 void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr); |
(...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1365 out_buffer_pos_ += SNPrintF( | 1367 out_buffer_pos_ += SNPrintF( |
1366 out_buffer_ + out_buffer_pos_, "\n %p %08x", | 1368 out_buffer_ + out_buffer_pos_, "\n %p %08x", |
1367 reinterpret_cast<void*>(instr + Instruction::kInstrSize), | 1369 reinterpret_cast<void*>(instr + Instruction::kInstrSize), |
1368 *reinterpret_cast<uint32_t*>(instr + Instruction::kInstrSize)); | 1370 *reinterpret_cast<uint32_t*>(instr + Instruction::kInstrSize)); |
1369 // We have decoded 2 * Instruction::kInstrSize bytes. | 1371 // We have decoded 2 * Instruction::kInstrSize bytes. |
1370 return 2 * Instruction::kInstrSize; | 1372 return 2 * Instruction::kInstrSize; |
1371 } else { | 1373 } else { |
1372 Format(instr, "svc'cond 'svc"); | 1374 Format(instr, "svc'cond 'svc"); |
1373 } | 1375 } |
1374 } else { | 1376 } else { |
1375 DecodeTypeVFP(instr); | 1377 switch (instr->CoprocessorValue()) { |
| 1378 case 10: // Fall through. |
| 1379 case 11: |
| 1380 DecodeTypeVFP(instr); |
| 1381 break; |
| 1382 case 15: |
| 1383 DecodeTypeCP15(instr); |
| 1384 break; |
| 1385 default: |
| 1386 Unknown(instr); |
| 1387 break; |
| 1388 } |
1376 } | 1389 } |
1377 return Instruction::kInstrSize; | 1390 return Instruction::kInstrSize; |
1378 } | 1391 } |
1379 | 1392 |
1380 | 1393 |
1381 // void Decoder::DecodeTypeVFP(Instruction* instr) | 1394 // void Decoder::DecodeTypeVFP(Instruction* instr) |
1382 // vmov: Sn = Rt | 1395 // vmov: Sn = Rt |
1383 // vmov: Rt = Sn | 1396 // vmov: Rt = Sn |
1384 // vcvt: Dd = Sm | 1397 // vcvt: Dd = Sm |
1385 // vcvt: Sd = Dm | 1398 // vcvt: Sd = Dm |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1547 if (instr->Bits(15, 12) == 0xF) { | 1560 if (instr->Bits(15, 12) == 0xF) { |
1548 Format(instr, "vmrs'cond APSR, FPSCR"); | 1561 Format(instr, "vmrs'cond APSR, FPSCR"); |
1549 } else { | 1562 } else { |
1550 Format(instr, "vmrs'cond 'rt, FPSCR"); | 1563 Format(instr, "vmrs'cond 'rt, FPSCR"); |
1551 } | 1564 } |
1552 } | 1565 } |
1553 } | 1566 } |
1554 } | 1567 } |
1555 } | 1568 } |
1556 | 1569 |
| 1570 void Decoder::DecodeTypeCP15(Instruction* instr) { |
| 1571 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0)); |
| 1572 VERIFY(instr->CoprocessorValue() == 15); |
| 1573 |
| 1574 if (instr->Bit(4) == 1) { |
| 1575 int crn = instr->Bits(19, 16); |
| 1576 int crm = instr->Bits(3, 0); |
| 1577 int opc1 = instr->Bits(23, 21); |
| 1578 int opc2 = instr->Bits(7, 5); |
| 1579 if ((opc1 == 0) && (crn == 7)) { |
| 1580 // ARMv6 memory barrier operations. |
| 1581 // Details available in ARM DDI 0406C.b, B3-1750. |
| 1582 if ((crm == 10) && (opc2 == 5)) { |
| 1583 Format(instr, "mcr'cond (CP15DMB)"); |
| 1584 } else if ((crm == 10) && (opc2 == 4)) { |
| 1585 Format(instr, "mcr'cond (CP15DSB)"); |
| 1586 } else if ((crm == 5) && (opc2 == 4)) { |
| 1587 Format(instr, "mcr'cond (CP15ISB)"); |
| 1588 } else { |
| 1589 Unknown(instr); |
| 1590 } |
| 1591 } else { |
| 1592 Unknown(instr); |
| 1593 } |
| 1594 } else { |
| 1595 Unknown(instr); |
| 1596 } |
| 1597 } |
1557 | 1598 |
1558 void Decoder::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters( | 1599 void Decoder::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters( |
1559 Instruction* instr) { | 1600 Instruction* instr) { |
1560 VERIFY((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) && | 1601 VERIFY((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) && |
1561 (instr->VAValue() == 0x0)); | 1602 (instr->VAValue() == 0x0)); |
1562 | 1603 |
1563 bool to_arm_register = (instr->VLValue() == 0x1); | 1604 bool to_arm_register = (instr->VLValue() == 0x1); |
1564 | 1605 |
1565 if (to_arm_register) { | 1606 if (to_arm_register) { |
1566 Format(instr, "vmov'cond 'rt, 'Sn"); | 1607 Format(instr, "vmov'cond 'rt, 'Sn"); |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2106 pc += d.InstructionDecode(buffer, pc); | 2147 pc += d.InstructionDecode(buffer, pc); |
2107 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc), | 2148 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc), |
2108 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 2149 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
2109 } | 2150 } |
2110 } | 2151 } |
2111 | 2152 |
2112 | 2153 |
2113 } // namespace disasm | 2154 } // namespace disasm |
2114 | 2155 |
2115 #endif // V8_TARGET_ARCH_ARM | 2156 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |