OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 void PrintSd(Instruction* instr); | 79 void PrintSd(Instruction* instr); |
80 void PrintSs1(Instruction* instr); | 80 void PrintSs1(Instruction* instr); |
81 void PrintSs2(Instruction* instr); | 81 void PrintSs2(Instruction* instr); |
82 void PrintBc(Instruction* instr); | 82 void PrintBc(Instruction* instr); |
83 void PrintCc(Instruction* instr); | 83 void PrintCc(Instruction* instr); |
84 void PrintFunction(Instruction* instr); | 84 void PrintFunction(Instruction* instr); |
85 void PrintSecondaryField(Instruction* instr); | 85 void PrintSecondaryField(Instruction* instr); |
86 void PrintUImm16(Instruction* instr); | 86 void PrintUImm16(Instruction* instr); |
87 void PrintSImm16(Instruction* instr); | 87 void PrintSImm16(Instruction* instr); |
88 void PrintXImm16(Instruction* instr); | 88 void PrintXImm16(Instruction* instr); |
| 89 void PrintXImm18(Instruction* instr); |
| 90 void PrintSImm18(Instruction* instr); |
| 91 void PrintXImm19(Instruction* instr); |
| 92 void PrintSImm19(Instruction* instr); |
89 void PrintXImm21(Instruction* instr); | 93 void PrintXImm21(Instruction* instr); |
90 void PrintXImm26(Instruction* instr); | 94 void PrintXImm26(Instruction* instr); |
| 95 void PrintSImm26(Instruction* instr); |
91 void PrintCode(Instruction* instr); // For break and trap instructions. | 96 void PrintCode(Instruction* instr); // For break and trap instructions. |
92 void PrintFormat(Instruction* instr); // For floating format postfix. | 97 void PrintFormat(Instruction* instr); // For floating format postfix. |
| 98 void PrintBp2(Instruction* instr); |
| 99 void PrintBp3(Instruction* instr); |
93 // Printing of instruction name. | 100 // Printing of instruction name. |
94 void PrintInstructionName(Instruction* instr); | 101 void PrintInstructionName(Instruction* instr); |
95 | 102 |
96 // Handle formatting of instructions and their options. | 103 // Handle formatting of instructions and their options. |
97 int FormatRegister(Instruction* instr, const char* option); | 104 int FormatRegister(Instruction* instr, const char* option); |
98 int FormatFPURegister(Instruction* instr, const char* option); | 105 int FormatFPURegister(Instruction* instr, const char* option); |
99 int FormatOption(Instruction* instr, const char* option); | 106 int FormatOption(Instruction* instr, const char* option); |
100 void Format(Instruction* instr, const char* format); | 107 void Format(Instruction* instr, const char* format); |
101 void Unknown(Instruction* instr); | 108 void Unknown(Instruction* instr); |
102 int DecodeBreakInstr(Instruction* instr); | 109 int DecodeBreakInstr(Instruction* instr); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 | 251 |
245 // Print 16-bit unsigned immediate value. | 252 // Print 16-bit unsigned immediate value. |
246 void Decoder::PrintUImm16(Instruction* instr) { | 253 void Decoder::PrintUImm16(Instruction* instr) { |
247 int32_t imm = instr->Imm16Value(); | 254 int32_t imm = instr->Imm16Value(); |
248 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); | 255 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); |
249 } | 256 } |
250 | 257 |
251 | 258 |
252 // Print 16-bit signed immediate value. | 259 // Print 16-bit signed immediate value. |
253 void Decoder::PrintSImm16(Instruction* instr) { | 260 void Decoder::PrintSImm16(Instruction* instr) { |
254 int32_t imm = ((instr->Imm16Value()) << 16) >> 16; | 261 int32_t imm = |
| 262 ((instr->Imm16Value()) << (32 - kImm16Bits)) >> (32 - kImm16Bits); |
255 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); | 263 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); |
256 } | 264 } |
257 | 265 |
258 | 266 |
259 // Print 16-bit hexa immediate value. | 267 // Print 16-bit hexa immediate value. |
260 void Decoder::PrintXImm16(Instruction* instr) { | 268 void Decoder::PrintXImm16(Instruction* instr) { |
261 int32_t imm = instr->Imm16Value(); | 269 int32_t imm = instr->Imm16Value(); |
262 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); | 270 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
263 } | 271 } |
264 | 272 |
265 | 273 |
| 274 // Print 18-bit signed immediate value. |
| 275 void Decoder::PrintSImm18(Instruction* instr) { |
| 276 int32_t imm = |
| 277 ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits); |
| 278 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); |
| 279 } |
| 280 |
| 281 |
| 282 // Print 18-bit hexa immediate value. |
| 283 void Decoder::PrintXImm18(Instruction* instr) { |
| 284 int32_t imm = instr->Imm18Value(); |
| 285 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
| 286 } |
| 287 |
| 288 |
| 289 // Print 19-bit hexa immediate value. |
| 290 void Decoder::PrintXImm19(Instruction* instr) { |
| 291 int32_t imm = instr->Imm19Value(); |
| 292 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
| 293 } |
| 294 |
| 295 |
| 296 // Print 19-bit signed immediate value. |
| 297 void Decoder::PrintSImm19(Instruction* instr) { |
| 298 int32_t imm19 = instr->Imm19Value(); |
| 299 // set sign |
| 300 imm19 <<= (32 - kImm19Bits); |
| 301 imm19 >>= (32 - kImm19Bits); |
| 302 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm19); |
| 303 } |
| 304 |
| 305 |
266 // Print 21-bit immediate value. | 306 // Print 21-bit immediate value. |
267 void Decoder::PrintXImm21(Instruction* instr) { | 307 void Decoder::PrintXImm21(Instruction* instr) { |
268 uint32_t imm = instr->Imm21Value(); | 308 uint32_t imm = instr->Imm21Value(); |
269 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); | 309 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
270 } | 310 } |
271 | 311 |
272 | 312 |
273 // Print 26-bit immediate value. | 313 // Print 26-bit hex immediate value. |
274 void Decoder::PrintXImm26(Instruction* instr) { | 314 void Decoder::PrintXImm26(Instruction* instr) { |
275 uint32_t imm = static_cast<uint32_t>(instr->Imm26Value()) << kImmFieldShift; | 315 uint32_t imm = static_cast<uint32_t>(instr->Imm26Value()) << kImmFieldShift; |
276 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); | 316 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
277 } | 317 } |
278 | 318 |
279 | 319 |
| 320 // Print 26-bit signed immediate value. |
| 321 void Decoder::PrintSImm26(Instruction* instr) { |
| 322 int32_t imm26 = instr->Imm26Value(); |
| 323 // set sign |
| 324 imm26 <<= (32 - kImm26Bits); |
| 325 imm26 >>= (32 - kImm26Bits); |
| 326 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm26); |
| 327 } |
| 328 |
| 329 |
| 330 void Decoder::PrintBp2(Instruction* instr) { |
| 331 int bp2 = instr->Bp2Value(); |
| 332 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp2); |
| 333 } |
| 334 |
| 335 |
| 336 void Decoder::PrintBp3(Instruction* instr) { |
| 337 int bp3 = instr->Bp3Value(); |
| 338 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp3); |
| 339 } |
| 340 |
| 341 |
280 // Print 26-bit immediate value. | 342 // Print 26-bit immediate value. |
281 void Decoder::PrintCode(Instruction* instr) { | 343 void Decoder::PrintCode(Instruction* instr) { |
282 if (instr->OpcodeFieldRaw() != SPECIAL) | 344 if (instr->OpcodeFieldRaw() != SPECIAL) |
283 return; // Not a break or trap instruction. | 345 return; // Not a break or trap instruction. |
284 switch (instr->FunctionFieldRaw()) { | 346 switch (instr->FunctionFieldRaw()) { |
285 case BREAK: { | 347 case BREAK: { |
286 int32_t code = instr->Bits(25, 6); | 348 int32_t code = instr->Bits(25, 6); |
287 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | 349 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
288 "0x%05x (%d)", code, code); | 350 "0x%05x (%d)", code, code); |
289 break; | 351 break; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 // characters that were consumed from the formatting string. | 450 // characters that were consumed from the formatting string. |
389 int Decoder::FormatOption(Instruction* instr, const char* format) { | 451 int Decoder::FormatOption(Instruction* instr, const char* format) { |
390 switch (format[0]) { | 452 switch (format[0]) { |
391 case 'c': { // 'code for break or trap instructions. | 453 case 'c': { // 'code for break or trap instructions. |
392 DCHECK(STRING_STARTS_WITH(format, "code")); | 454 DCHECK(STRING_STARTS_WITH(format, "code")); |
393 PrintCode(instr); | 455 PrintCode(instr); |
394 return 4; | 456 return 4; |
395 } | 457 } |
396 case 'i': { // 'imm16u or 'imm26. | 458 case 'i': { // 'imm16u or 'imm26. |
397 if (format[3] == '1') { | 459 if (format[3] == '1') { |
398 DCHECK(STRING_STARTS_WITH(format, "imm16")); | 460 if (format[4] == '6') { |
399 if (format[5] == 's') { | 461 DCHECK(STRING_STARTS_WITH(format, "imm16")); |
400 DCHECK(STRING_STARTS_WITH(format, "imm16s")); | 462 switch (format[5]) { |
401 PrintSImm16(instr); | 463 case 's': |
402 } else if (format[5] == 'u') { | 464 DCHECK(STRING_STARTS_WITH(format, "imm16s")); |
403 DCHECK(STRING_STARTS_WITH(format, "imm16u")); | 465 PrintSImm16(instr); |
404 PrintSImm16(instr); | 466 break; |
405 } else { | 467 case 'u': |
406 DCHECK(STRING_STARTS_WITH(format, "imm16x")); | 468 DCHECK(STRING_STARTS_WITH(format, "imm16u")); |
407 PrintXImm16(instr); | 469 PrintSImm16(instr); |
| 470 break; |
| 471 case 'x': |
| 472 DCHECK(STRING_STARTS_WITH(format, "imm16x")); |
| 473 PrintXImm16(instr); |
| 474 break; |
| 475 } |
| 476 return 6; |
| 477 } else if (format[4] == '8') { |
| 478 DCHECK(STRING_STARTS_WITH(format, "imm18")); |
| 479 switch (format[5]) { |
| 480 case 's': |
| 481 DCHECK(STRING_STARTS_WITH(format, "imm18s")); |
| 482 PrintSImm18(instr); |
| 483 break; |
| 484 case 'x': |
| 485 DCHECK(STRING_STARTS_WITH(format, "imm18x")); |
| 486 PrintXImm18(instr); |
| 487 break; |
| 488 } |
| 489 return 6; |
| 490 } else if (format[4] == '9') { |
| 491 DCHECK(STRING_STARTS_WITH(format, "imm19")); |
| 492 switch (format[5]) { |
| 493 case 's': |
| 494 DCHECK(STRING_STARTS_WITH(format, "imm19s")); |
| 495 PrintSImm19(instr); |
| 496 break; |
| 497 case 'x': |
| 498 DCHECK(STRING_STARTS_WITH(format, "imm19x")); |
| 499 PrintXImm19(instr); |
| 500 break; |
| 501 } |
| 502 return 6; |
408 } | 503 } |
409 return 6; | |
410 } else if (format[3] == '2' && format[4] == '1') { | 504 } else if (format[3] == '2' && format[4] == '1') { |
411 DCHECK(STRING_STARTS_WITH(format, "imm21x")); | 505 DCHECK(STRING_STARTS_WITH(format, "imm21x")); |
412 PrintXImm21(instr); | 506 PrintXImm21(instr); |
413 return 6; | 507 return 6; |
414 } else if (format[3] == '2' && format[4] == '6') { | 508 } else if (format[3] == '2' && format[4] == '6') { |
415 DCHECK(STRING_STARTS_WITH(format, "imm26x")); | 509 DCHECK(STRING_STARTS_WITH(format, "imm26")); |
416 PrintXImm26(instr); | 510 switch (format[5]) { |
| 511 case 's': |
| 512 DCHECK(STRING_STARTS_WITH(format, "imm26s")); |
| 513 PrintSImm26(instr); |
| 514 break; |
| 515 case 'x': |
| 516 DCHECK(STRING_STARTS_WITH(format, "imm26x")); |
| 517 PrintXImm26(instr); |
| 518 break; |
| 519 } |
417 return 6; | 520 return 6; |
418 } | 521 } |
419 } | 522 } |
420 case 'r': { // 'r: registers. | 523 case 'r': { // 'r: registers. |
421 return FormatRegister(instr, format); | 524 return FormatRegister(instr, format); |
422 } | 525 } |
423 case 'f': { // 'f: FPUregisters. | 526 case 'f': { // 'f: FPUregisters. |
424 return FormatFPURegister(instr, format); | 527 return FormatFPURegister(instr, format); |
425 } | 528 } |
426 case 's': { // 'sa. | 529 case 's': { // 'sa. |
(...skipping 14 matching lines...) Expand all Loading... |
441 PrintSs1(instr); | 544 PrintSs1(instr); |
442 return 3; | 545 return 3; |
443 } else { | 546 } else { |
444 DCHECK(STRING_STARTS_WITH(format, "ss2")); /* ins size */ | 547 DCHECK(STRING_STARTS_WITH(format, "ss2")); /* ins size */ |
445 PrintSs2(instr); | 548 PrintSs2(instr); |
446 return 3; | 549 return 3; |
447 } | 550 } |
448 } | 551 } |
449 } | 552 } |
450 } | 553 } |
451 case 'b': { // 'bc - Special for bc1 cc field. | 554 case 'b': { |
452 DCHECK(STRING_STARTS_WITH(format, "bc")); | 555 switch (format[1]) { |
453 PrintBc(instr); | 556 case 'c': { // 'bc - Special for bc1 cc field. |
454 return 2; | 557 DCHECK(STRING_STARTS_WITH(format, "bc")); |
| 558 PrintBc(instr); |
| 559 return 2; |
| 560 } |
| 561 case 'p': { |
| 562 switch (format[2]) { |
| 563 case '2': { // 'bp2 |
| 564 DCHECK(STRING_STARTS_WITH(format, "bp2")); |
| 565 PrintBp2(instr); |
| 566 return 3; |
| 567 } |
| 568 case '3': { // 'bp3 |
| 569 DCHECK(STRING_STARTS_WITH(format, "bp3")); |
| 570 PrintBp3(instr); |
| 571 return 3; |
| 572 } |
| 573 } |
| 574 } |
| 575 } |
455 } | 576 } |
456 case 'C': { // 'Cc - Special for c.xx.d cc field. | 577 case 'C': { // 'Cc - Special for c.xx.d cc field. |
457 DCHECK(STRING_STARTS_WITH(format, "Cc")); | 578 DCHECK(STRING_STARTS_WITH(format, "Cc")); |
458 PrintCc(instr); | 579 PrintCc(instr); |
459 return 2; | 580 return 2; |
460 } | 581 } |
461 case 't': | 582 case 't': |
462 PrintFormat(instr); | 583 PrintFormat(instr); |
463 return 1; | 584 return 1; |
464 } | 585 } |
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1128 break; | 1249 break; |
1129 } | 1250 } |
1130 case EXT: { | 1251 case EXT: { |
1131 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); | 1252 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); |
1132 break; | 1253 break; |
1133 } | 1254 } |
1134 case DEXT: { | 1255 case DEXT: { |
1135 Format(instr, "dext 'rt, 'rs, 'sa, 'ss1"); | 1256 Format(instr, "dext 'rt, 'rs, 'sa, 'ss1"); |
1136 break; | 1257 break; |
1137 } | 1258 } |
1138 case BITSWAP: { | 1259 case BSHFL: { |
1139 Format(instr, "bitswap 'rd, 'rt"); | 1260 int sa = instr->SaFieldRaw() >> kSaShift; |
1140 break; | 1261 switch (sa) { |
1141 } | 1262 case BITSWAP: { |
1142 case DBITSWAP: { | 1263 Format(instr, "bitswap 'rd, 'rt"); |
1143 switch (instr->SaFieldRaw()) { | |
1144 case DBITSWAP_SA: | |
1145 Format(instr, "dbitswap 'rd, 'rt"); | |
1146 break; | 1264 break; |
1147 default: | 1265 } |
| 1266 case SEB: |
| 1267 case SEH: |
| 1268 case WSBH: |
1148 UNREACHABLE(); | 1269 UNREACHABLE(); |
| 1270 break; |
| 1271 default: { |
| 1272 sa >>= kBp2Bits; |
| 1273 switch (sa) { |
| 1274 case ALIGN: { |
| 1275 Format(instr, "align 'rd, 'rs, 'rt, 'bp2"); |
| 1276 break; |
| 1277 } |
| 1278 default: |
| 1279 UNREACHABLE(); |
| 1280 break; |
| 1281 } |
| 1282 break; |
| 1283 } |
1149 } | 1284 } |
1150 break; | 1285 break; |
1151 } | 1286 } |
| 1287 case DBSHFL: { |
| 1288 int sa = instr->SaFieldRaw() >> kSaShift; |
| 1289 switch (sa) { |
| 1290 case DBITSWAP: { |
| 1291 switch (instr->SaFieldRaw() >> kSaShift) { |
| 1292 case DBITSWAP_SA: |
| 1293 Format(instr, "dbitswap 'rd, 'rt"); |
| 1294 break; |
| 1295 default: |
| 1296 UNREACHABLE(); |
| 1297 break; |
| 1298 } |
| 1299 break; |
| 1300 } |
| 1301 case DSBH: |
| 1302 case DSHD: |
| 1303 UNREACHABLE(); |
| 1304 break; |
| 1305 default: { |
| 1306 sa >>= kBp3Bits; |
| 1307 switch (sa) { |
| 1308 case DALIGN: { |
| 1309 Format(instr, "dalign 'rd, 'rs, 'rt, 'bp3"); |
| 1310 break; |
| 1311 } |
| 1312 default: |
| 1313 UNREACHABLE(); |
| 1314 break; |
| 1315 } |
| 1316 break; |
| 1317 } |
| 1318 } |
| 1319 break; |
| 1320 } |
1152 default: | 1321 default: |
1153 UNREACHABLE(); | 1322 UNREACHABLE(); |
1154 } | 1323 } |
1155 } | 1324 } |
1156 | 1325 |
1157 | 1326 |
1158 int Decoder::DecodeTypeRegister(Instruction* instr) { | 1327 int Decoder::DecodeTypeRegister(Instruction* instr) { |
1159 switch (instr->OpcodeFieldRaw()) { | 1328 switch (instr->OpcodeFieldRaw()) { |
1160 case COP1: // Coprocessor instructions. | 1329 case COP1: // Coprocessor instructions. |
1161 DecodeTypeRegisterCOP1(instr); | 1330 DecodeTypeRegisterCOP1(instr); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1241 DecodeTypeImmediateCOP1(instr); | 1410 DecodeTypeImmediateCOP1(instr); |
1242 break; // Case COP1. | 1411 break; // Case COP1. |
1243 // ------------- REGIMM class. | 1412 // ------------- REGIMM class. |
1244 case REGIMM: | 1413 case REGIMM: |
1245 | 1414 |
1246 break; // Case REGIMM. | 1415 break; // Case REGIMM. |
1247 // ------------- Branch instructions. | 1416 // ------------- Branch instructions. |
1248 case BEQ: | 1417 case BEQ: |
1249 Format(instr, "beq 'rs, 'rt, 'imm16u"); | 1418 Format(instr, "beq 'rs, 'rt, 'imm16u"); |
1250 break; | 1419 break; |
| 1420 case BC: |
| 1421 Format(instr, "bc 'imm26s"); |
| 1422 break; |
| 1423 case BALC: |
| 1424 Format(instr, "balc 'imm26s"); |
| 1425 break; |
1251 case BNE: | 1426 case BNE: |
1252 Format(instr, "bne 'rs, 'rt, 'imm16u"); | 1427 Format(instr, "bne 'rs, 'rt, 'imm16u"); |
1253 break; | 1428 break; |
1254 case BLEZ: | 1429 case BLEZ: |
1255 if ((instr->RtFieldRaw() == 0) | 1430 if ((instr->RtFieldRaw() == 0) |
1256 && (instr->RsFieldRaw() != 0)) { | 1431 && (instr->RsFieldRaw() != 0)) { |
1257 Format(instr, "blez 'rs, 'imm16u"); | 1432 Format(instr, "blez 'rs, 'imm16u"); |
1258 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1433 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) |
1259 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1434 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { |
1260 Format(instr, "bgeuc 'rs, 'rt, 'imm16u"); | 1435 Format(instr, "bgeuc 'rs, 'rt, 'imm16u"); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1306 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1481 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) |
1307 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1482 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { |
1308 Format(instr, "bltc 'rs, 'rt, 'imm16u"); | 1483 Format(instr, "bltc 'rs, 'rt, 'imm16u"); |
1309 } else if ((instr->RsFieldRaw() == 0) | 1484 } else if ((instr->RsFieldRaw() == 0) |
1310 && (instr->RtFieldRaw() != 0)) { | 1485 && (instr->RtFieldRaw() != 0)) { |
1311 Format(instr, "bgtzc 'rt, 'imm16u"); | 1486 Format(instr, "bgtzc 'rt, 'imm16u"); |
1312 } else { | 1487 } else { |
1313 UNREACHABLE(); | 1488 UNREACHABLE(); |
1314 } | 1489 } |
1315 break; | 1490 break; |
1316 case BEQZC: | 1491 case POP66: |
1317 if (instr->RsFieldRaw() != 0) { | 1492 if (instr->RsValue() == JIC) { |
| 1493 Format(instr, "jic 'rt, 'imm16s"); |
| 1494 } else { |
1318 Format(instr, "beqzc 'rs, 'imm21x"); | 1495 Format(instr, "beqzc 'rs, 'imm21x"); |
1319 } | 1496 } |
1320 break; | 1497 break; |
1321 case BNEZC: | 1498 case POP76: |
1322 if (instr->RsFieldRaw() != 0) { | 1499 if (instr->RsValue() == JIALC) { |
| 1500 Format(instr, "jialc 'rt, 'imm16x"); |
| 1501 } else { |
1323 Format(instr, "bnezc 'rs, 'imm21x"); | 1502 Format(instr, "bnezc 'rs, 'imm21x"); |
1324 } | 1503 } |
1325 break; | 1504 break; |
1326 // ------------- Arithmetic instructions. | 1505 // ------------- Arithmetic instructions. |
1327 case ADDI: | 1506 case ADDI: |
1328 if (kArchVariant != kMips64r6) { | 1507 if (kArchVariant != kMips64r6) { |
1329 Format(instr, "addi 'rt, 'rs, 'imm16s"); | 1508 Format(instr, "addi 'rt, 'rs, 'imm16s"); |
1330 } else { | 1509 } else { |
1331 // Check if BOVC or BEQC instruction. | 1510 // Check if BOVC or BEQC instruction. |
1332 if (instr->RsFieldRaw() >= instr->RtFieldRaw()) { | 1511 if (instr->RsFieldRaw() >= instr->RtFieldRaw()) { |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1447 break; | 1626 break; |
1448 case LDC1: | 1627 case LDC1: |
1449 Format(instr, "ldc1 'ft, 'imm16s('rs)"); | 1628 Format(instr, "ldc1 'ft, 'imm16s('rs)"); |
1450 break; | 1629 break; |
1451 case SWC1: | 1630 case SWC1: |
1452 Format(instr, "swc1 'ft, 'imm16s('rs)"); | 1631 Format(instr, "swc1 'ft, 'imm16s('rs)"); |
1453 break; | 1632 break; |
1454 case SDC1: | 1633 case SDC1: |
1455 Format(instr, "sdc1 'ft, 'imm16s('rs)"); | 1634 Format(instr, "sdc1 'ft, 'imm16s('rs)"); |
1456 break; | 1635 break; |
| 1636 case PCREL: { |
| 1637 int32_t imm21 = instr->Imm21Value(); |
| 1638 // rt field: 5-bits checking |
| 1639 uint8_t rt = (imm21 >> kImm16Bits); |
| 1640 switch (rt) { |
| 1641 case ALUIPC: |
| 1642 Format(instr, "aluipc 'rs, 'imm16s"); |
| 1643 break; |
| 1644 case AUIPC: |
| 1645 Format(instr, "auipc 'rs, 'imm16s"); |
| 1646 break; |
| 1647 default: { |
| 1648 // rt field: checking of the most significant 3-bits |
| 1649 rt = (imm21 >> kImm18Bits); |
| 1650 switch (rt) { |
| 1651 case LDPC: |
| 1652 Format(instr, "ldpc 'rs, 'imm18s"); |
| 1653 break; |
| 1654 default: { |
| 1655 // rt field: checking of the most significant 2-bits |
| 1656 rt = (imm21 >> kImm19Bits); |
| 1657 switch (rt) { |
| 1658 case LWUPC: |
| 1659 Format(instr, "lwupc 'rs, 'imm19s"); |
| 1660 break; |
| 1661 case LWPC: |
| 1662 Format(instr, "lwpc 'rs, 'imm19s"); |
| 1663 break; |
| 1664 case ADDIUPC: |
| 1665 Format(instr, "addiupc 'rs, 'imm19s"); |
| 1666 break; |
| 1667 default: |
| 1668 UNREACHABLE(); |
| 1669 break; |
| 1670 } |
| 1671 break; |
| 1672 } |
| 1673 } |
| 1674 break; |
| 1675 } |
| 1676 } |
| 1677 break; |
| 1678 } |
1457 default: | 1679 default: |
1458 printf("a 0x%x \n", instr->OpcodeFieldRaw()); | 1680 printf("a 0x%x \n", instr->OpcodeFieldRaw()); |
1459 UNREACHABLE(); | 1681 UNREACHABLE(); |
1460 break; | 1682 break; |
1461 } | 1683 } |
1462 } | 1684 } |
1463 | 1685 |
1464 | 1686 |
1465 void Decoder::DecodeTypeJump(Instruction* instr) { | 1687 void Decoder::DecodeTypeJump(Instruction* instr) { |
1466 switch (instr->OpcodeFieldRaw()) { | 1688 switch (instr->OpcodeFieldRaw()) { |
1467 case J: | 1689 case J: |
1468 Format(instr, "j 'imm26x"); | 1690 Format(instr, "j 'imm26x"); |
1469 break; | 1691 break; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1583 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1805 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1584 } | 1806 } |
1585 } | 1807 } |
1586 | 1808 |
1587 | 1809 |
1588 #undef UNSUPPORTED | 1810 #undef UNSUPPORTED |
1589 | 1811 |
1590 } // namespace disasm | 1812 } // namespace disasm |
1591 | 1813 |
1592 #endif // V8_TARGET_ARCH_MIPS64 | 1814 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |