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