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); |
| 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 |