OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 int FormatVFPinstruction(Instruction* instr, const char* format); | 106 int FormatVFPinstruction(Instruction* instr, const char* format); |
107 void PrintCondition(Instruction* instr); | 107 void PrintCondition(Instruction* instr); |
108 void PrintShiftRm(Instruction* instr); | 108 void PrintShiftRm(Instruction* instr); |
109 void PrintShiftImm(Instruction* instr); | 109 void PrintShiftImm(Instruction* instr); |
110 void PrintShiftSat(Instruction* instr); | 110 void PrintShiftSat(Instruction* instr); |
111 void PrintPU(Instruction* instr); | 111 void PrintPU(Instruction* instr); |
112 void PrintSoftwareInterrupt(SoftwareInterruptCodes svc); | 112 void PrintSoftwareInterrupt(SoftwareInterruptCodes svc); |
113 | 113 |
114 // Handle formatting of instructions and their options. | 114 // Handle formatting of instructions and their options. |
115 int FormatRegister(Instruction* instr, const char* option); | 115 int FormatRegister(Instruction* instr, const char* option); |
116 void FormatNeonList(int Vd, int type); | |
117 void FormatNeonMemory(int Rn, int align, int Rm); | |
116 int FormatOption(Instruction* instr, const char* option); | 118 int FormatOption(Instruction* instr, const char* option); |
117 void Format(Instruction* instr, const char* format); | 119 void Format(Instruction* instr, const char* format); |
118 void Unknown(Instruction* instr); | 120 void Unknown(Instruction* instr); |
119 | 121 |
120 // Each of these functions decodes one particular instruction type, a 3-bit | 122 // Each of these functions decodes one particular instruction type, a 3-bit |
121 // field in the instruction encoding. | 123 // field in the instruction encoding. |
122 // Types 0 and 1 are combined as they are largely the same except for the way | 124 // Types 0 and 1 are combined as they are largely the same except for the way |
123 // they interpret the shifter operand. | 125 // they interpret the shifter operand. |
124 void DecodeType01(Instruction* instr); | 126 void DecodeType01(Instruction* instr); |
125 void DecodeType2(Instruction* instr); | 127 void DecodeType2(Instruction* instr); |
126 void DecodeType3(Instruction* instr); | 128 void DecodeType3(Instruction* instr); |
127 void DecodeType4(Instruction* instr); | 129 void DecodeType4(Instruction* instr); |
128 void DecodeType5(Instruction* instr); | 130 void DecodeType5(Instruction* instr); |
129 void DecodeType6(Instruction* instr); | 131 void DecodeType6(Instruction* instr); |
130 // Type 7 includes special Debugger instructions. | 132 // Type 7 includes special Debugger instructions. |
131 int DecodeType7(Instruction* instr); | 133 int DecodeType7(Instruction* instr); |
132 // For VFP support. | 134 // For VFP support. |
133 void DecodeTypeVFP(Instruction* instr); | 135 void DecodeTypeVFP(Instruction* instr); |
134 void DecodeType6CoprocessorIns(Instruction* instr); | 136 void DecodeType6CoprocessorIns(Instruction* instr); |
135 | 137 |
138 void DecodeSpecialCondition(Instruction* instr); | |
139 | |
136 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr); | 140 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr); |
137 void DecodeVCMP(Instruction* instr); | 141 void DecodeVCMP(Instruction* instr); |
138 void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr); | 142 void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr); |
139 void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr); | 143 void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr); |
140 | 144 |
141 const disasm::NameConverter& converter_; | 145 const disasm::NameConverter& converter_; |
142 Vector<char> out_buffer_; | 146 Vector<char> out_buffer_; |
143 int out_buffer_pos_; | 147 int out_buffer_pos_; |
144 | 148 |
145 DISALLOW_COPY_AND_ASSIGN(Decoder); | 149 DISALLOW_COPY_AND_ASSIGN(Decoder); |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
410 return retval; | 414 return retval; |
411 } | 415 } |
412 | 416 |
413 | 417 |
414 int Decoder::FormatVFPinstruction(Instruction* instr, const char* format) { | 418 int Decoder::FormatVFPinstruction(Instruction* instr, const char* format) { |
415 Print(format); | 419 Print(format); |
416 return 0; | 420 return 0; |
417 } | 421 } |
418 | 422 |
419 | 423 |
424 void Decoder::FormatNeonList(int Vd, int type) { | |
425 if (type == nlt_1) { | |
426 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
427 "{d%d}", Vd); | |
428 } else if (type == nlt_2) { | |
429 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
430 "{d%d, d%d}", Vd, Vd + 1); | |
431 } else if (type == nlt_3) { | |
432 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
433 "{d%d, d%d, d%d}", Vd, Vd + 1, Vd + 2); | |
434 } else if (type == nlt_4) { | |
435 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
436 "{d%d, d%d, d%d, d%d}", Vd, Vd + 1, Vd + 2, Vd + 3); | |
437 } | |
438 } | |
439 | |
440 | |
441 void Decoder::FormatNeonMemory(int Rn, int align, int Rm) { | |
442 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
443 "[r%d", Rn); | |
444 if (align != 0) { | |
445 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
446 ":%d", (1<<align)<<6); | |
ulan
2013/06/28 15:07:43
Spaces around "<<".
Rodolph Perfetta
2013/07/03 16:59:39
Done.
vincent.belliard.fr
2013/07/10 15:30:37
Done.
| |
447 } | |
448 if (Rm == 15) { | |
449 Print("]"); | |
450 } else if (Rm == 13) { | |
451 Print("]!"); | |
452 } else { | |
453 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
454 "], r%d", Rm); | |
455 } | |
456 } | |
457 | |
458 | |
420 // Print the movw or movt instruction. | 459 // Print the movw or movt instruction. |
421 void Decoder::PrintMovwMovt(Instruction* instr) { | 460 void Decoder::PrintMovwMovt(Instruction* instr) { |
422 int imm = instr->ImmedMovwMovtValue(); | 461 int imm = instr->ImmedMovwMovtValue(); |
423 int rd = instr->RdValue(); | 462 int rd = instr->RdValue(); |
424 PrintRegister(rd); | 463 PrintRegister(rd); |
425 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | 464 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, |
426 ", #%d", imm); | 465 ", #%d", imm); |
427 } | 466 } |
428 | 467 |
429 | 468 |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
973 | 1012 |
974 | 1013 |
975 void Decoder::DecodeType3(Instruction* instr) { | 1014 void Decoder::DecodeType3(Instruction* instr) { |
976 switch (instr->PUField()) { | 1015 switch (instr->PUField()) { |
977 case da_x: { | 1016 case da_x: { |
978 VERIFY(!instr->HasW()); | 1017 VERIFY(!instr->HasW()); |
979 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm"); | 1018 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm"); |
980 break; | 1019 break; |
981 } | 1020 } |
982 case ia_x: { | 1021 case ia_x: { |
983 if (instr->HasW()) { | 1022 if (instr->Bit(4) == 0) { |
984 VERIFY(instr->Bits(5, 4) == 0x1); | 1023 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm"); |
985 if (instr->Bit(22) == 0x1) { | 1024 } else { |
986 Format(instr, "usat 'rd, #'imm05@16, 'rm'shift_sat"); | 1025 if (instr->Bit(5) == 0) { |
1026 switch (instr->Bits(22, 21)) { | |
1027 case 0: | |
1028 if (instr->Bit(20) == 0) { | |
1029 if (instr->Bit(6) == 0) { | |
1030 Format(instr, "pkhbt'cond 'rd, 'rn, 'rm, lsl #'imm05@07"); | |
1031 } else { | |
1032 if (instr->Bits(11, 7) == 0) { | |
1033 Format(instr, "pkhtb'cond 'rd, 'rn, 'rm, asr #32"); | |
1034 } else { | |
1035 Format(instr, "pkhtb'cond 'rd, 'rn, 'rm, asr #'imm05@07"); | |
1036 } | |
1037 } | |
1038 } else { | |
1039 UNREACHABLE(); | |
1040 } | |
1041 break; | |
1042 case 1: | |
1043 UNREACHABLE(); | |
1044 break; | |
1045 case 2: | |
1046 UNREACHABLE(); | |
1047 break; | |
1048 case 3: | |
1049 Format(instr, "usat 'rd, #'imm05@16, 'rm'shift_sat"); | |
1050 break; | |
1051 } | |
987 } else { | 1052 } else { |
988 UNREACHABLE(); // SSAT. | 1053 switch (instr->Bits(22, 21)) { |
1054 case 0: | |
1055 UNREACHABLE(); | |
1056 break; | |
1057 case 1: | |
1058 UNREACHABLE(); | |
1059 break; | |
1060 case 2: | |
1061 if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) { | |
1062 if (instr->Bits(19, 16) == 0xF) { | |
1063 switch (instr->Bits(11, 10)) { | |
1064 case 0: | |
1065 Format(instr, "uxtb16'cond 'rd, 'rm, ror #0"); | |
1066 break; | |
1067 case 1: | |
1068 Format(instr, "uxtb16'cond 'rd, 'rm, ror #8"); | |
1069 break; | |
1070 case 2: | |
1071 Format(instr, "uxtb16'cond 'rd, 'rm, ror #16"); | |
1072 break; | |
1073 case 3: | |
1074 Format(instr, "uxtb16'cond 'rd, 'rm, ror #24"); | |
1075 break; | |
1076 } | |
1077 } else { | |
1078 UNREACHABLE(); | |
1079 } | |
1080 } else { | |
1081 UNREACHABLE(); | |
1082 } | |
1083 break; | |
1084 case 3: | |
1085 if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) { | |
1086 if (instr->Bits(19, 16) == 0xF) { | |
1087 switch (instr->Bits(11, 10)) { | |
1088 case 0: | |
1089 Format(instr, "uxtb'cond 'rd, 'rm, ror #0"); | |
1090 break; | |
1091 case 1: | |
1092 Format(instr, "uxtb'cond 'rd, 'rm, ror #8"); | |
1093 break; | |
1094 case 2: | |
1095 Format(instr, "uxtb'cond 'rd, 'rm, ror #16"); | |
1096 break; | |
1097 case 3: | |
1098 Format(instr, "uxtb'cond 'rd, 'rm, ror #24"); | |
1099 break; | |
1100 } | |
1101 } else { | |
1102 switch (instr->Bits(11, 10)) { | |
1103 case 0: | |
1104 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #0"); | |
1105 break; | |
1106 case 1: | |
1107 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #8"); | |
1108 break; | |
1109 case 2: | |
1110 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #16"); | |
1111 break; | |
1112 case 3: | |
1113 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #24"); | |
1114 break; | |
1115 } | |
1116 } | |
1117 } else { | |
1118 UNREACHABLE(); | |
1119 } | |
1120 break; | |
1121 } | |
989 } | 1122 } |
990 } else { | |
991 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm"); | |
992 } | 1123 } |
993 break; | 1124 break; |
994 } | 1125 } |
995 case db_x: { | 1126 case db_x: { |
996 if (FLAG_enable_sudiv) { | 1127 if (FLAG_enable_sudiv) { |
997 if (!instr->HasW()) { | 1128 if (!instr->HasW()) { |
998 if (instr->Bits(5, 4) == 0x1) { | 1129 if (instr->Bits(5, 4) == 0x1) { |
999 if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) { | 1130 if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) { |
1000 // SDIV (in V8 notation matching ARM ISA format) rn = rm/rs | 1131 // SDIV (in V8 notation matching ARM ISA format) rn = rm/rs |
1001 Format(instr, "sdiv'cond'b 'rn, 'rm, 'rs"); | 1132 Format(instr, "sdiv'cond'b 'rn, 'rm, 'rs"); |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1414 break; | 1545 break; |
1415 } | 1546 } |
1416 default: | 1547 default: |
1417 Unknown(instr); // Not used by V8. | 1548 Unknown(instr); // Not used by V8. |
1418 } | 1549 } |
1419 } else { | 1550 } else { |
1420 Unknown(instr); // Not used by V8. | 1551 Unknown(instr); // Not used by V8. |
1421 } | 1552 } |
1422 } | 1553 } |
1423 | 1554 |
1555 void Decoder::DecodeSpecialCondition(Instruction* instr) { | |
1556 switch (instr->SpecialValue()) { | |
1557 case 5: | |
1558 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && | |
1559 (instr->Bit(4) == 1)) { | |
1560 // vmovl signed | |
1561 int Vd = (instr->Bit(22) << 4) | instr->VdValue(); | |
1562 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); | |
1563 int imm3 = instr->Bits(21, 19); | |
1564 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
1565 "vmovl.s%d q%d, d%d", imm3*8, Vd, Vm); | |
1566 } else { | |
1567 Unknown(instr); | |
1568 } | |
1569 break; | |
1570 case 7: | |
1571 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && | |
1572 (instr->Bit(4) == 1)) { | |
1573 // vmovl unsigned | |
1574 int Vd = (instr->Bit(22) << 4) | instr->VdValue(); | |
1575 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); | |
1576 int imm3 = instr->Bits(21, 19); | |
1577 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
1578 "vmovl.u%d q%d, d%d", imm3*8, Vd, Vm); | |
1579 } else { | |
1580 Unknown(instr); | |
1581 } | |
1582 break; | |
1583 case 8: | |
1584 if (instr->Bits(21, 20) == 0) { | |
1585 // vst1 | |
1586 int Vd = (instr->Bit(22) << 4) | instr->VdValue(); | |
1587 int Rn = instr->VnValue(); | |
1588 int type = instr->Bits(11, 8); | |
1589 int size = instr->Bits(7, 6); | |
1590 int align = instr->Bits(5, 4); | |
1591 int Rm = instr->VmValue(); | |
1592 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
1593 "vst1.%d ", (1 << size) << 3); | |
1594 FormatNeonList(Vd, type); | |
1595 Print(", "); | |
1596 FormatNeonMemory(Rn, align, Rm); | |
1597 } else if (instr->Bits(21, 20) == 2) { | |
1598 // vld1 | |
1599 int Vd = (instr->Bit(22) << 4) | instr->VdValue(); | |
1600 int Rn = instr->VnValue(); | |
1601 int type = instr->Bits(11, 8); | |
1602 int size = instr->Bits(7, 6); | |
1603 int align = instr->Bits(5, 4); | |
1604 int Rm = instr->VmValue(); | |
1605 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
1606 "vld1.%d ", (1 << size) << 3); | |
1607 FormatNeonList(Vd, type); | |
1608 Print(", "); | |
1609 FormatNeonMemory(Rn, align, Rm); | |
1610 } else { | |
1611 Unknown(instr); | |
1612 } | |
1613 break; | |
1614 case 0xA: | |
1615 case 0xB: | |
1616 if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) { | |
1617 int Rn = instr->Bits(19, 16); | |
1618 int offset = instr->Bits(11, 0); | |
1619 if (offset == 0) { | |
1620 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
1621 "pld [r%d]", Rn); | |
1622 } else if (instr->Bit(23) == 0) { | |
1623 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
1624 "pld [r%d, #-%d]", Rn, offset); | |
1625 } else { | |
1626 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | |
1627 "pld [r%d, #+%d]", Rn, offset); | |
1628 } | |
1629 } else { | |
1630 Unknown(instr); | |
1631 } | |
1632 break; | |
1633 default: | |
1634 Unknown(instr); | |
1635 break; | |
1636 } | |
1637 } | |
1638 | |
1424 #undef VERIFIY | 1639 #undef VERIFIY |
1425 | 1640 |
1426 bool Decoder::IsConstantPoolAt(byte* instr_ptr) { | 1641 bool Decoder::IsConstantPoolAt(byte* instr_ptr) { |
1427 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); | 1642 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); |
1428 return (instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker; | 1643 return (instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker; |
1429 } | 1644 } |
1430 | 1645 |
1431 | 1646 |
1432 int Decoder::ConstantPoolSizeAt(byte* instr_ptr) { | 1647 int Decoder::ConstantPoolSizeAt(byte* instr_ptr) { |
1433 if (IsConstantPoolAt(instr_ptr)) { | 1648 if (IsConstantPoolAt(instr_ptr)) { |
1434 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); | 1649 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); |
1435 return DecodeConstantPoolLength(instruction_bits); | 1650 return DecodeConstantPoolLength(instruction_bits); |
1436 } else { | 1651 } else { |
1437 return -1; | 1652 return -1; |
1438 } | 1653 } |
1439 } | 1654 } |
1440 | 1655 |
1441 | 1656 |
1442 // Disassemble the instruction at *instr_ptr into the output buffer. | 1657 // Disassemble the instruction at *instr_ptr into the output buffer. |
1443 int Decoder::InstructionDecode(byte* instr_ptr) { | 1658 int Decoder::InstructionDecode(byte* instr_ptr) { |
1444 Instruction* instr = Instruction::At(instr_ptr); | 1659 Instruction* instr = Instruction::At(instr_ptr); |
1445 // Print raw instruction bytes. | 1660 // Print raw instruction bytes. |
1446 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | 1661 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, |
1447 "%08x ", | 1662 "%08x ", |
1448 instr->InstructionBits()); | 1663 instr->InstructionBits()); |
1449 if (instr->ConditionField() == kSpecialCondition) { | 1664 if (instr->ConditionField() == kSpecialCondition) { |
1450 Unknown(instr); | 1665 DecodeSpecialCondition(instr); |
1451 return Instruction::kInstrSize; | 1666 return Instruction::kInstrSize; |
1452 } | 1667 } |
1453 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); | 1668 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); |
1454 if ((instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker) { | 1669 if ((instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker) { |
1455 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, | 1670 out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_, |
1456 "constant pool begin (length %d)", | 1671 "constant pool begin (length %d)", |
1457 DecodeConstantPoolLength(instruction_bits)); | 1672 DecodeConstantPoolLength(instruction_bits)); |
1458 return Instruction::kInstrSize; | 1673 return Instruction::kInstrSize; |
1459 } | 1674 } |
1460 switch (instr->TypeValue()) { | 1675 switch (instr->TypeValue()) { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1572 v8::internal::PrintF( | 1787 v8::internal::PrintF( |
1573 f, "%p %08x %s\n", | 1788 f, "%p %08x %s\n", |
1574 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1789 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1575 } | 1790 } |
1576 } | 1791 } |
1577 | 1792 |
1578 | 1793 |
1579 } // namespace disasm | 1794 } // namespace disasm |
1580 | 1795 |
1581 #endif // V8_TARGET_ARCH_ARM | 1796 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |