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 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 format += FormatOption(instr, format); | 655 format += FormatOption(instr, format); |
656 } else { | 656 } else { |
657 out_buffer_[out_buffer_pos_++] = cur; | 657 out_buffer_[out_buffer_pos_++] = cur; |
658 } | 658 } |
659 cur = *format++; | 659 cur = *format++; |
660 } | 660 } |
661 out_buffer_[out_buffer_pos_] = '\0'; | 661 out_buffer_[out_buffer_pos_] = '\0'; |
662 } | 662 } |
663 | 663 |
664 | 664 |
| 665 // The disassembler may end up decoding data inlined in the code. We do not want |
| 666 // it to crash if the data does not ressemble any known instruction. |
| 667 #define VERIFY(condition) \ |
| 668 if(!(condition)) { \ |
| 669 Unknown(instr); \ |
| 670 return; \ |
| 671 } |
| 672 |
| 673 |
665 // For currently unimplemented decodings the disassembler calls Unknown(instr) | 674 // For currently unimplemented decodings the disassembler calls Unknown(instr) |
666 // which will just print "unknown" of the instruction bits. | 675 // which will just print "unknown" of the instruction bits. |
667 void Decoder::Unknown(Instruction* instr) { | 676 void Decoder::Unknown(Instruction* instr) { |
668 Format(instr, "unknown"); | 677 Format(instr, "unknown"); |
669 } | 678 } |
670 | 679 |
671 | 680 |
672 void Decoder::DecodeType01(Instruction* instr) { | 681 void Decoder::DecodeType01(Instruction* instr) { |
673 int type = instr->TypeValue(); | 682 int type = instr->TypeValue(); |
674 if ((type == 0) && instr->IsSpecialType0()) { | 683 if ((type == 0) && instr->IsSpecialType0()) { |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
940 UNREACHABLE(); | 949 UNREACHABLE(); |
941 break; | 950 break; |
942 } | 951 } |
943 } | 952 } |
944 } | 953 } |
945 | 954 |
946 | 955 |
947 void Decoder::DecodeType3(Instruction* instr) { | 956 void Decoder::DecodeType3(Instruction* instr) { |
948 switch (instr->PUField()) { | 957 switch (instr->PUField()) { |
949 case da_x: { | 958 case da_x: { |
950 ASSERT(!instr->HasW()); | 959 VERIFY(!instr->HasW()); |
951 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm"); | 960 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm"); |
952 break; | 961 break; |
953 } | 962 } |
954 case ia_x: { | 963 case ia_x: { |
955 if (instr->HasW()) { | 964 if (instr->HasW()) { |
956 ASSERT(instr->Bits(5, 4) == 0x1); | 965 VERIFY(instr->Bits(5, 4) == 0x1); |
957 if (instr->Bit(22) == 0x1) { | 966 if (instr->Bit(22) == 0x1) { |
958 Format(instr, "usat 'rd, #'imm05@16, 'rm'shift_sat"); | 967 Format(instr, "usat 'rd, #'imm05@16, 'rm'shift_sat"); |
959 } else { | 968 } else { |
960 UNREACHABLE(); // SSAT. | 969 UNREACHABLE(); // SSAT. |
961 } | 970 } |
962 } else { | 971 } else { |
963 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm"); | 972 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm"); |
964 } | 973 } |
965 break; | 974 break; |
966 } | 975 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 // Dd = vneg(Dm) | 1076 // Dd = vneg(Dm) |
1068 // Dd = vadd(Dn, Dm) | 1077 // Dd = vadd(Dn, Dm) |
1069 // Dd = vsub(Dn, Dm) | 1078 // Dd = vsub(Dn, Dm) |
1070 // Dd = vmul(Dn, Dm) | 1079 // Dd = vmul(Dn, Dm) |
1071 // Dd = vdiv(Dn, Dm) | 1080 // Dd = vdiv(Dn, Dm) |
1072 // vcmp(Dd, Dm) | 1081 // vcmp(Dd, Dm) |
1073 // vmrs | 1082 // vmrs |
1074 // vmsr | 1083 // vmsr |
1075 // Dd = vsqrt(Dm) | 1084 // Dd = vsqrt(Dm) |
1076 void Decoder::DecodeTypeVFP(Instruction* instr) { | 1085 void Decoder::DecodeTypeVFP(Instruction* instr) { |
1077 ASSERT((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) ); | 1086 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) ); |
1078 ASSERT(instr->Bits(11, 9) == 0x5); | 1087 VERIFY(instr->Bits(11, 9) == 0x5); |
1079 | 1088 |
1080 if (instr->Bit(4) == 0) { | 1089 if (instr->Bit(4) == 0) { |
1081 if (instr->Opc1Value() == 0x7) { | 1090 if (instr->Opc1Value() == 0x7) { |
1082 // Other data processing instructions | 1091 // Other data processing instructions |
1083 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) { | 1092 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) { |
1084 // vmov register to register. | 1093 // vmov register to register. |
1085 if (instr->SzValue() == 0x1) { | 1094 if (instr->SzValue() == 0x1) { |
1086 Format(instr, "vmov.f64'cond 'Dd, 'Dm"); | 1095 Format(instr, "vmov.f64'cond 'Dd, 'Dm"); |
1087 } else { | 1096 } else { |
1088 Format(instr, "vmov.f32'cond 'Sd, 'Sm"); | 1097 Format(instr, "vmov.f32'cond 'Sd, 'Sm"); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1159 Format(instr, "vmrs'cond 'rt, FPSCR"); | 1168 Format(instr, "vmrs'cond 'rt, FPSCR"); |
1160 } | 1169 } |
1161 } | 1170 } |
1162 } | 1171 } |
1163 } | 1172 } |
1164 } | 1173 } |
1165 | 1174 |
1166 | 1175 |
1167 void Decoder::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters( | 1176 void Decoder::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters( |
1168 Instruction* instr) { | 1177 Instruction* instr) { |
1169 ASSERT((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) && | 1178 VERIFY((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) && |
1170 (instr->VAValue() == 0x0)); | 1179 (instr->VAValue() == 0x0)); |
1171 | 1180 |
1172 bool to_arm_register = (instr->VLValue() == 0x1); | 1181 bool to_arm_register = (instr->VLValue() == 0x1); |
1173 | 1182 |
1174 if (to_arm_register) { | 1183 if (to_arm_register) { |
1175 Format(instr, "vmov'cond 'rt, 'Sn"); | 1184 Format(instr, "vmov'cond 'rt, 'Sn"); |
1176 } else { | 1185 } else { |
1177 Format(instr, "vmov'cond 'Sn, 'rt"); | 1186 Format(instr, "vmov'cond 'Sn, 'rt"); |
1178 } | 1187 } |
1179 } | 1188 } |
1180 | 1189 |
1181 | 1190 |
1182 void Decoder::DecodeVCMP(Instruction* instr) { | 1191 void Decoder::DecodeVCMP(Instruction* instr) { |
1183 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); | 1192 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); |
1184 ASSERT(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && | 1193 VERIFY(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && |
1185 (instr->Opc3Value() & 0x1)); | 1194 (instr->Opc3Value() & 0x1)); |
1186 | 1195 |
1187 // Comparison. | 1196 // Comparison. |
1188 bool dp_operation = (instr->SzValue() == 1); | 1197 bool dp_operation = (instr->SzValue() == 1); |
1189 bool raise_exception_for_qnan = (instr->Bit(7) == 0x1); | 1198 bool raise_exception_for_qnan = (instr->Bit(7) == 0x1); |
1190 | 1199 |
1191 if (dp_operation && !raise_exception_for_qnan) { | 1200 if (dp_operation && !raise_exception_for_qnan) { |
1192 if (instr->Opc2Value() == 0x4) { | 1201 if (instr->Opc2Value() == 0x4) { |
1193 Format(instr, "vcmp.f64'cond 'Dd, 'Dm"); | 1202 Format(instr, "vcmp.f64'cond 'Dd, 'Dm"); |
1194 } else if (instr->Opc2Value() == 0x5) { | 1203 } else if (instr->Opc2Value() == 0x5) { |
1195 Format(instr, "vcmp.f64'cond 'Dd, #0.0"); | 1204 Format(instr, "vcmp.f64'cond 'Dd, #0.0"); |
1196 } else { | 1205 } else { |
1197 Unknown(instr); // invalid | 1206 Unknown(instr); // invalid |
1198 } | 1207 } |
1199 } else { | 1208 } else { |
1200 Unknown(instr); // Not used by V8. | 1209 Unknown(instr); // Not used by V8. |
1201 } | 1210 } |
1202 } | 1211 } |
1203 | 1212 |
1204 | 1213 |
1205 void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) { | 1214 void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) { |
1206 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); | 1215 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); |
1207 ASSERT((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)); | 1216 VERIFY((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)); |
1208 | 1217 |
1209 bool double_to_single = (instr->SzValue() == 1); | 1218 bool double_to_single = (instr->SzValue() == 1); |
1210 | 1219 |
1211 if (double_to_single) { | 1220 if (double_to_single) { |
1212 Format(instr, "vcvt.f32.f64'cond 'Sd, 'Dm"); | 1221 Format(instr, "vcvt.f32.f64'cond 'Sd, 'Dm"); |
1213 } else { | 1222 } else { |
1214 Format(instr, "vcvt.f64.f32'cond 'Dd, 'Sm"); | 1223 Format(instr, "vcvt.f64.f32'cond 'Dd, 'Sm"); |
1215 } | 1224 } |
1216 } | 1225 } |
1217 | 1226 |
1218 | 1227 |
1219 void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) { | 1228 void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) { |
1220 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); | 1229 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); |
1221 ASSERT(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) || | 1230 VERIFY(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) || |
1222 (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1))); | 1231 (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1))); |
1223 | 1232 |
1224 bool to_integer = (instr->Bit(18) == 1); | 1233 bool to_integer = (instr->Bit(18) == 1); |
1225 bool dp_operation = (instr->SzValue() == 1); | 1234 bool dp_operation = (instr->SzValue() == 1); |
1226 if (to_integer) { | 1235 if (to_integer) { |
1227 bool unsigned_integer = (instr->Bit(16) == 0); | 1236 bool unsigned_integer = (instr->Bit(16) == 0); |
1228 | 1237 |
1229 if (dp_operation) { | 1238 if (dp_operation) { |
1230 if (unsigned_integer) { | 1239 if (unsigned_integer) { |
1231 Format(instr, "vcvt.u32.f64'cond 'Sd, 'Dm"); | 1240 Format(instr, "vcvt.u32.f64'cond 'Sd, 'Dm"); |
(...skipping 26 matching lines...) Expand all Loading... |
1258 } | 1267 } |
1259 } | 1268 } |
1260 | 1269 |
1261 | 1270 |
1262 // Decode Type 6 coprocessor instructions. | 1271 // Decode Type 6 coprocessor instructions. |
1263 // Dm = vmov(Rt, Rt2) | 1272 // Dm = vmov(Rt, Rt2) |
1264 // <Rt, Rt2> = vmov(Dm) | 1273 // <Rt, Rt2> = vmov(Dm) |
1265 // Ddst = MEM(Rbase + 4*offset). | 1274 // Ddst = MEM(Rbase + 4*offset). |
1266 // MEM(Rbase + 4*offset) = Dsrc. | 1275 // MEM(Rbase + 4*offset) = Dsrc. |
1267 void Decoder::DecodeType6CoprocessorIns(Instruction* instr) { | 1276 void Decoder::DecodeType6CoprocessorIns(Instruction* instr) { |
1268 ASSERT(instr->TypeValue() == 6); | 1277 VERIFY(instr->TypeValue() == 6); |
1269 | 1278 |
1270 if (instr->CoprocessorValue() == 0xA) { | 1279 if (instr->CoprocessorValue() == 0xA) { |
1271 switch (instr->OpcodeValue()) { | 1280 switch (instr->OpcodeValue()) { |
1272 case 0x8: | 1281 case 0x8: |
1273 case 0xA: | 1282 case 0xA: |
1274 if (instr->HasL()) { | 1283 if (instr->HasL()) { |
1275 Format(instr, "vldr'cond 'Sd, ['rn - 4*'imm08@00]"); | 1284 Format(instr, "vldr'cond 'Sd, ['rn - 4*'imm08@00]"); |
1276 } else { | 1285 } else { |
1277 Format(instr, "vstr'cond 'Sd, ['rn - 4*'imm08@00]"); | 1286 Format(instr, "vstr'cond 'Sd, ['rn - 4*'imm08@00]"); |
1278 } | 1287 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1340 break; | 1349 break; |
1341 } | 1350 } |
1342 default: | 1351 default: |
1343 Unknown(instr); // Not used by V8. | 1352 Unknown(instr); // Not used by V8. |
1344 } | 1353 } |
1345 } else { | 1354 } else { |
1346 Unknown(instr); // Not used by V8. | 1355 Unknown(instr); // Not used by V8. |
1347 } | 1356 } |
1348 } | 1357 } |
1349 | 1358 |
| 1359 #undef VERIFIY |
1350 | 1360 |
1351 bool Decoder::IsConstantPoolAt(byte* instr_ptr) { | 1361 bool Decoder::IsConstantPoolAt(byte* instr_ptr) { |
1352 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); | 1362 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); |
1353 return (instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker; | 1363 return (instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker; |
1354 } | 1364 } |
1355 | 1365 |
1356 | 1366 |
1357 int Decoder::ConstantPoolSizeAt(byte* instr_ptr) { | 1367 int Decoder::ConstantPoolSizeAt(byte* instr_ptr) { |
1358 if (IsConstantPoolAt(instr_ptr)) { | 1368 if (IsConstantPoolAt(instr_ptr)) { |
1359 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); | 1369 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1497 pc += d.InstructionDecode(buffer, pc); | 1507 pc += d.InstructionDecode(buffer, pc); |
1498 fprintf(f, "%p %08x %s\n", | 1508 fprintf(f, "%p %08x %s\n", |
1499 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1509 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1500 } | 1510 } |
1501 } | 1511 } |
1502 | 1512 |
1503 | 1513 |
1504 } // namespace disasm | 1514 } // namespace disasm |
1505 | 1515 |
1506 #endif // V8_TARGET_ARCH_ARM | 1516 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |