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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 PrintBp2(Instruction* instr); | 84 void PrintBp2(Instruction* instr); |
85 void PrintFunction(Instruction* instr); | 85 void PrintFunction(Instruction* instr); |
86 void PrintSecondaryField(Instruction* instr); | 86 void PrintSecondaryField(Instruction* instr); |
87 void PrintUImm16(Instruction* instr); | 87 void PrintUImm16(Instruction* instr); |
88 void PrintSImm16(Instruction* instr); | 88 void PrintSImm16(Instruction* instr); |
89 void PrintXImm16(Instruction* instr); | 89 void PrintXImm16(Instruction* instr); |
| 90 void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits); |
90 void PrintXImm18(Instruction* instr); | 91 void PrintXImm18(Instruction* instr); |
91 void PrintSImm18(Instruction* instr); | 92 void PrintSImm18(Instruction* instr); |
92 void PrintXImm19(Instruction* instr); | 93 void PrintXImm19(Instruction* instr); |
93 void PrintSImm19(Instruction* instr); | 94 void PrintSImm19(Instruction* instr); |
94 void PrintXImm21(Instruction* instr); | 95 void PrintXImm21(Instruction* instr); |
95 void PrintSImm21(Instruction* instr); | 96 void PrintSImm21(Instruction* instr); |
| 97 void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits); |
96 void PrintXImm26(Instruction* instr); | 98 void PrintXImm26(Instruction* instr); |
97 void PrintSImm26(Instruction* instr); | 99 void PrintSImm26(Instruction* instr); |
| 100 void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits); |
| 101 void PrintPCImm26(Instruction* instr); |
98 void PrintCode(Instruction* instr); // For break and trap instructions. | 102 void PrintCode(Instruction* instr); // For break and trap instructions. |
99 void PrintFormat(Instruction* instr); // For floating format postfix. | 103 void PrintFormat(Instruction* instr); // For floating format postfix. |
100 // Printing of instruction name. | 104 // Printing of instruction name. |
101 void PrintInstructionName(Instruction* instr); | 105 void PrintInstructionName(Instruction* instr); |
102 | 106 |
103 // Handle formatting of instructions and their options. | 107 // Handle formatting of instructions and their options. |
104 int FormatRegister(Instruction* instr, const char* option); | 108 int FormatRegister(Instruction* instr, const char* option); |
105 int FormatFPURegister(Instruction* instr, const char* option); | 109 int FormatFPURegister(Instruction* instr, const char* option); |
106 int FormatOption(Instruction* instr, const char* option); | 110 int FormatOption(Instruction* instr, const char* option); |
107 void Format(Instruction* instr, const char* format); | 111 void Format(Instruction* instr, const char* format); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 } | 267 } |
264 | 268 |
265 | 269 |
266 // Print 16-bit hexa immediate value. | 270 // Print 16-bit hexa immediate value. |
267 void Decoder::PrintXImm16(Instruction* instr) { | 271 void Decoder::PrintXImm16(Instruction* instr) { |
268 int32_t imm = instr->Imm16Value(); | 272 int32_t imm = instr->Imm16Value(); |
269 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); | 273 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
270 } | 274 } |
271 | 275 |
272 | 276 |
| 277 // Print absoulte address for 16-bit offset or immediate value. |
| 278 // The absolute address is calculated according following expression: |
| 279 // PC + delta_pc + (offset << n_bits) |
| 280 void Decoder::PrintPCImm16(Instruction* instr, int delta_pc, int n_bits) { |
| 281 int16_t offset = instr->Imm16Value(); |
| 282 out_buffer_pos_ += |
| 283 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
| 284 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + |
| 285 delta_pc + (offset << n_bits))); |
| 286 } |
| 287 |
| 288 |
273 // Print 18-bit signed immediate value. | 289 // Print 18-bit signed immediate value. |
274 void Decoder::PrintSImm18(Instruction* instr) { | 290 void Decoder::PrintSImm18(Instruction* instr) { |
275 int32_t imm = | 291 int32_t imm = |
276 ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits); | 292 ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits); |
277 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); | 293 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); |
278 } | 294 } |
279 | 295 |
280 | 296 |
281 // Print 18-bit hexa immediate value. | 297 // Print 18-bit hexa immediate value. |
282 void Decoder::PrintXImm18(Instruction* instr) { | 298 void Decoder::PrintXImm18(Instruction* instr) { |
(...skipping 29 matching lines...) Expand all Loading... |
312 // Print 21-bit signed immediate value. | 328 // Print 21-bit signed immediate value. |
313 void Decoder::PrintSImm21(Instruction* instr) { | 329 void Decoder::PrintSImm21(Instruction* instr) { |
314 int32_t imm21 = instr->Imm21Value(); | 330 int32_t imm21 = instr->Imm21Value(); |
315 // set sign | 331 // set sign |
316 imm21 <<= (32 - kImm21Bits); | 332 imm21 <<= (32 - kImm21Bits); |
317 imm21 >>= (32 - kImm21Bits); | 333 imm21 >>= (32 - kImm21Bits); |
318 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm21); | 334 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm21); |
319 } | 335 } |
320 | 336 |
321 | 337 |
| 338 // Print absoulte address for 21-bit offset or immediate value. |
| 339 // The absolute address is calculated according following expression: |
| 340 // PC + delta_pc + (offset << n_bits) |
| 341 void Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) { |
| 342 int32_t imm21 = instr->Imm21Value(); |
| 343 // set sign |
| 344 imm21 <<= (32 - kImm21Bits); |
| 345 imm21 >>= (32 - kImm21Bits); |
| 346 out_buffer_pos_ += |
| 347 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
| 348 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + |
| 349 delta_pc + (imm21 << n_bits))); |
| 350 } |
| 351 |
| 352 |
322 // Print 26-bit hex immediate value. | 353 // Print 26-bit hex immediate value. |
323 void Decoder::PrintXImm26(Instruction* instr) { | 354 void Decoder::PrintXImm26(Instruction* instr) { |
324 uint32_t imm = instr->Imm26Value() << kImmFieldShift; | 355 uint32_t imm = instr->Imm26Value() << kImmFieldShift; |
325 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); | 356 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
326 } | 357 } |
327 | 358 |
328 | 359 |
329 // Print 26-bit signed immediate value. | 360 // Print 26-bit signed immediate value. |
330 void Decoder::PrintSImm26(Instruction* instr) { | 361 void Decoder::PrintSImm26(Instruction* instr) { |
331 int32_t imm26 = instr->Imm26Value(); | 362 int32_t imm26 = instr->Imm26Value(); |
332 // set sign | 363 // set sign |
333 imm26 <<= (32 - kImm26Bits); | 364 imm26 <<= (32 - kImm26Bits); |
334 imm26 >>= (32 - kImm26Bits); | 365 imm26 >>= (32 - kImm26Bits); |
335 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm26); | 366 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm26); |
336 } | 367 } |
337 | 368 |
338 | 369 |
| 370 // Print absoulte address for 26-bit offset or immediate value. |
| 371 // The absolute address is calculated according following expression: |
| 372 // PC + delta_pc + (offset << n_bits) |
| 373 void Decoder::PrintPCImm26(Instruction* instr, int delta_pc, int n_bits) { |
| 374 int32_t imm26 = instr->Imm26Value(); |
| 375 // set sign |
| 376 imm26 <<= (32 - kImm26Bits); |
| 377 imm26 >>= (32 - kImm26Bits); |
| 378 out_buffer_pos_ += |
| 379 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
| 380 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + |
| 381 delta_pc + (imm26 << n_bits))); |
| 382 } |
| 383 |
| 384 |
| 385 // Print absoulte address for 26-bit offset or immediate value. |
| 386 // The absolute address is calculated according following expression: |
| 387 // PC[GPRLEN-1 .. 28] || instr_index26 || 00 |
| 388 void Decoder::PrintPCImm26(Instruction* instr) { |
| 389 int32_t imm26 = instr->Imm26Value(); |
| 390 uint32_t pc_mask = ~0xfffffff; |
| 391 uint32_t pc = ((uint32_t)(instr + 1) & pc_mask) | (imm26 << 2); |
| 392 out_buffer_pos_ += |
| 393 SNPrintF(out_buffer_ + out_buffer_pos_, "%s", |
| 394 converter_.NameOfAddress((reinterpret_cast<byte*>(pc)))); |
| 395 } |
| 396 |
| 397 |
339 // Print 26-bit immediate value. | 398 // Print 26-bit immediate value. |
340 void Decoder::PrintCode(Instruction* instr) { | 399 void Decoder::PrintCode(Instruction* instr) { |
341 if (instr->OpcodeFieldRaw() != SPECIAL) | 400 if (instr->OpcodeFieldRaw() != SPECIAL) |
342 return; // Not a break or trap instruction. | 401 return; // Not a break or trap instruction. |
343 switch (instr->FunctionFieldRaw()) { | 402 switch (instr->FunctionFieldRaw()) { |
344 case BREAK: { | 403 case BREAK: { |
345 int32_t code = instr->Bits(25, 6); | 404 int32_t code = instr->Bits(25, 6); |
346 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | 405 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
347 "0x%05x (%d)", code, code); | 406 "0x%05x (%d)", code, code); |
348 break; | 407 break; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 PrintSImm16(instr); | 521 PrintSImm16(instr); |
463 break; | 522 break; |
464 case 'u': | 523 case 'u': |
465 DCHECK(STRING_STARTS_WITH(format, "imm16u")); | 524 DCHECK(STRING_STARTS_WITH(format, "imm16u")); |
466 PrintSImm16(instr); | 525 PrintSImm16(instr); |
467 break; | 526 break; |
468 case 'x': | 527 case 'x': |
469 DCHECK(STRING_STARTS_WITH(format, "imm16x")); | 528 DCHECK(STRING_STARTS_WITH(format, "imm16x")); |
470 PrintXImm16(instr); | 529 PrintXImm16(instr); |
471 break; | 530 break; |
| 531 case 'p': { // The PC relative address. |
| 532 DCHECK(STRING_STARTS_WITH(format, "imm16p")); |
| 533 int delta_pc = 0; |
| 534 int n_bits = 0; |
| 535 switch (format[6]) { |
| 536 case '4': { |
| 537 DCHECK(STRING_STARTS_WITH(format, "imm16p4")); |
| 538 delta_pc = 4; |
| 539 switch (format[8]) { |
| 540 case '2': |
| 541 DCHECK(STRING_STARTS_WITH(format, "imm16p4s2")); |
| 542 n_bits = 2; |
| 543 PrintPCImm16(instr, delta_pc, n_bits); |
| 544 return 9; |
| 545 } |
| 546 } |
| 547 } |
| 548 } |
472 } | 549 } |
473 return 6; | 550 return 6; |
474 } else if (format[4] == '8') { | 551 } else if (format[4] == '8') { |
475 DCHECK(STRING_STARTS_WITH(format, "imm18")); | 552 DCHECK(STRING_STARTS_WITH(format, "imm18")); |
476 switch (format[5]) { | 553 switch (format[5]) { |
477 case 's': | 554 case 's': |
478 DCHECK(STRING_STARTS_WITH(format, "imm18s")); | 555 DCHECK(STRING_STARTS_WITH(format, "imm18s")); |
479 PrintSImm18(instr); | 556 PrintSImm18(instr); |
480 break; | 557 break; |
481 case 'x': | 558 case 'x': |
(...skipping 20 matching lines...) Expand all Loading... |
502 DCHECK(STRING_STARTS_WITH(format, "imm21")); | 579 DCHECK(STRING_STARTS_WITH(format, "imm21")); |
503 switch (format[5]) { | 580 switch (format[5]) { |
504 case 's': | 581 case 's': |
505 DCHECK(STRING_STARTS_WITH(format, "imm21s")); | 582 DCHECK(STRING_STARTS_WITH(format, "imm21s")); |
506 PrintSImm21(instr); | 583 PrintSImm21(instr); |
507 break; | 584 break; |
508 case 'x': | 585 case 'x': |
509 DCHECK(STRING_STARTS_WITH(format, "imm21x")); | 586 DCHECK(STRING_STARTS_WITH(format, "imm21x")); |
510 PrintXImm21(instr); | 587 PrintXImm21(instr); |
511 break; | 588 break; |
| 589 case 'p': { // The PC relative address. |
| 590 DCHECK(STRING_STARTS_WITH(format, "imm21p")); |
| 591 int delta_pc = 0; |
| 592 int n_bits = 0; |
| 593 switch (format[6]) { |
| 594 case '4': { |
| 595 DCHECK(STRING_STARTS_WITH(format, "imm21p4")); |
| 596 delta_pc = 4; |
| 597 switch (format[8]) { |
| 598 case '2': |
| 599 DCHECK(STRING_STARTS_WITH(format, "imm21p4s2")); |
| 600 n_bits = 2; |
| 601 PrintPCImm21(instr, delta_pc, n_bits); |
| 602 return 9; |
| 603 } |
| 604 } |
| 605 } |
| 606 } |
512 } | 607 } |
513 return 6; | 608 return 6; |
514 } else if (format[3] == '2' && format[4] == '6') { | 609 } else if (format[3] == '2' && format[4] == '6') { |
515 DCHECK(STRING_STARTS_WITH(format, "imm26")); | 610 DCHECK(STRING_STARTS_WITH(format, "imm26")); |
516 switch (format[5]) { | 611 switch (format[5]) { |
517 case 's': | 612 case 's': |
518 DCHECK(STRING_STARTS_WITH(format, "imm26s")); | 613 DCHECK(STRING_STARTS_WITH(format, "imm26s")); |
519 PrintSImm26(instr); | 614 PrintSImm26(instr); |
520 break; | 615 break; |
521 case 'x': | 616 case 'x': |
522 DCHECK(STRING_STARTS_WITH(format, "imm26x")); | 617 DCHECK(STRING_STARTS_WITH(format, "imm26x")); |
523 PrintXImm26(instr); | 618 PrintXImm26(instr); |
524 break; | 619 break; |
| 620 case 'p': { // The PC relative address. |
| 621 DCHECK(STRING_STARTS_WITH(format, "imm26p")); |
| 622 int delta_pc = 0; |
| 623 int n_bits = 0; |
| 624 switch (format[6]) { |
| 625 case '4': { |
| 626 DCHECK(STRING_STARTS_WITH(format, "imm26p4")); |
| 627 delta_pc = 4; |
| 628 switch (format[8]) { |
| 629 case '2': |
| 630 DCHECK(STRING_STARTS_WITH(format, "imm26p4s2")); |
| 631 n_bits = 2; |
| 632 PrintPCImm26(instr, delta_pc, n_bits); |
| 633 return 9; |
| 634 } |
| 635 } |
| 636 } |
| 637 } |
| 638 case 'j': { // Absolute address for jump instructions. |
| 639 DCHECK(STRING_STARTS_WITH(format, "imm26j")); |
| 640 PrintPCImm26(instr); |
| 641 break; |
| 642 } |
525 } | 643 } |
526 return 6; | 644 return 6; |
527 } | 645 } |
528 } | 646 } |
529 case 'r': { // 'r: registers. | 647 case 'r': { // 'r: registers. |
530 return FormatRegister(instr, format); | 648 return FormatRegister(instr, format); |
531 } | 649 } |
532 case 'f': { // 'f: FPUregisters. | 650 case 'f': { // 'f: FPUregisters. |
533 return FormatFPURegister(instr, format); | 651 return FormatFPURegister(instr, format); |
534 } | 652 } |
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1193 } | 1311 } |
1194 } | 1312 } |
1195 | 1313 |
1196 | 1314 |
1197 void Decoder::DecodeTypeImmediate(Instruction* instr) { | 1315 void Decoder::DecodeTypeImmediate(Instruction* instr) { |
1198 switch (instr->OpcodeFieldRaw()) { | 1316 switch (instr->OpcodeFieldRaw()) { |
1199 case COP1: | 1317 case COP1: |
1200 switch (instr->RsFieldRaw()) { | 1318 switch (instr->RsFieldRaw()) { |
1201 case BC1: | 1319 case BC1: |
1202 if (instr->FBtrueValue()) { | 1320 if (instr->FBtrueValue()) { |
1203 Format(instr, "bc1t 'bc, 'imm16u"); | 1321 Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2"); |
1204 } else { | 1322 } else { |
1205 Format(instr, "bc1f 'bc, 'imm16u"); | 1323 Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2"); |
1206 } | 1324 } |
1207 break; | 1325 break; |
1208 case BC1EQZ: | 1326 case BC1EQZ: |
1209 Format(instr, "bc1eqz 'ft, 'imm16u"); | 1327 Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2"); |
1210 break; | 1328 break; |
1211 case BC1NEZ: | 1329 case BC1NEZ: |
1212 Format(instr, "bc1nez 'ft, 'imm16u"); | 1330 Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2"); |
1213 break; | 1331 break; |
1214 default: | 1332 default: |
1215 UNREACHABLE(); | 1333 UNREACHABLE(); |
1216 } | 1334 } |
1217 | 1335 |
1218 break; // Case COP1. | 1336 break; // Case COP1. |
1219 // ------------- REGIMM class. | 1337 // ------------- REGIMM class. |
1220 case REGIMM: | 1338 case REGIMM: |
1221 switch (instr->RtFieldRaw()) { | 1339 switch (instr->RtFieldRaw()) { |
1222 case BLTZ: | 1340 case BLTZ: |
1223 Format(instr, "bltz 'rs, 'imm16u"); | 1341 Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2"); |
1224 break; | 1342 break; |
1225 case BLTZAL: | 1343 case BLTZAL: |
1226 Format(instr, "bltzal 'rs, 'imm16u"); | 1344 Format(instr, "bltzal 'rs, 'imm16u -> 'imm16p4s2"); |
1227 break; | 1345 break; |
1228 case BGEZ: | 1346 case BGEZ: |
1229 Format(instr, "bgez 'rs, 'imm16u"); | 1347 Format(instr, "bgez 'rs, 'imm16u -> 'imm16p4s2"); |
1230 break; | 1348 break; |
1231 case BGEZAL: | 1349 case BGEZAL: |
1232 Format(instr, "bgezal 'rs, 'imm16u"); | 1350 Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2"); |
1233 break; | 1351 break; |
1234 case BGEZALL: | 1352 case BGEZALL: |
1235 Format(instr, "bgezall 'rs, 'imm16u"); | 1353 Format(instr, "bgezall 'rs, 'imm16u -> 'imm16p4s2"); |
1236 break; | 1354 break; |
1237 default: | 1355 default: |
1238 UNREACHABLE(); | 1356 UNREACHABLE(); |
1239 } | 1357 } |
1240 break; // Case REGIMM. | 1358 break; // Case REGIMM. |
1241 // ------------- Branch instructions. | 1359 // ------------- Branch instructions. |
1242 case BEQ: | 1360 case BEQ: |
1243 Format(instr, "beq 'rs, 'rt, 'imm16u"); | 1361 Format(instr, "beq 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1244 break; | 1362 break; |
1245 case BC: | 1363 case BC: |
1246 Format(instr, "bc 'imm26s"); | 1364 Format(instr, "bc 'imm26s -> 'imm26p4s2"); |
1247 break; | 1365 break; |
1248 case BALC: | 1366 case BALC: |
1249 Format(instr, "balc 'imm26s"); | 1367 Format(instr, "balc 'imm26s -> 'imm26p4s2"); |
1250 break; | 1368 break; |
1251 case BNE: | 1369 case BNE: |
1252 Format(instr, "bne 'rs, 'rt, 'imm16u"); | 1370 Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1253 break; | 1371 break; |
1254 case BLEZ: | 1372 case BLEZ: |
1255 if ((instr->RtFieldRaw() == 0) | 1373 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { |
1256 && (instr->RsFieldRaw() != 0)) { | 1374 Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2"); |
1257 Format(instr, "blez 'rs, 'imm16u"); | 1375 } else if ((instr->RtValue() != instr->RsValue()) && |
1258 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1376 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1259 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1377 Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1260 Format(instr, "bgeuc 'rs, 'rt, 'imm16u"); | 1378 } else if ((instr->RtValue() == instr->RsValue()) && |
1261 } else if ((instr->RtFieldRaw() == instr->RsFieldRaw()) | 1379 (instr->RtValue() != 0)) { |
1262 && (instr->RtFieldRaw() != 0)) { | 1380 Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2"); |
1263 Format(instr, "bgezalc 'rs, 'imm16u"); | 1381 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
1264 } else if ((instr->RsFieldRaw() == 0) | 1382 Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2"); |
1265 && (instr->RtFieldRaw() != 0)) { | |
1266 Format(instr, "blezalc 'rs, 'imm16u"); | |
1267 } else { | 1383 } else { |
1268 UNREACHABLE(); | 1384 UNREACHABLE(); |
1269 } | 1385 } |
1270 break; | 1386 break; |
1271 case BGTZ: | 1387 case BGTZ: |
1272 if ((instr->RtFieldRaw() == 0) | 1388 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { |
1273 && (instr->RsFieldRaw() != 0)) { | 1389 Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2"); |
1274 Format(instr, "bgtz 'rs, 'imm16u"); | 1390 } else if ((instr->RtValue() != instr->RsValue()) && |
1275 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1391 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1276 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1392 Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1277 Format(instr, "bltuc 'rs, 'rt, 'imm16u"); | 1393 } else if ((instr->RtValue() == instr->RsValue()) && |
1278 } else if ((instr->RtFieldRaw() == instr->RsFieldRaw()) | 1394 (instr->RtValue() != 0)) { |
1279 && (instr->RtFieldRaw() != 0)) { | 1395 Format(instr, "bltzalc 'rt, 'imm16u -> 'imm16p4s2"); |
1280 Format(instr, "bltzalc 'rt, 'imm16u"); | 1396 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
1281 } else if ((instr->RsFieldRaw() == 0) | 1397 Format(instr, "bgtzalc 'rt, 'imm16u -> 'imm16p4s2"); |
1282 && (instr->RtFieldRaw() != 0)) { | |
1283 Format(instr, "bgtzalc 'rt, 'imm16u"); | |
1284 } else { | 1398 } else { |
1285 UNREACHABLE(); | 1399 UNREACHABLE(); |
1286 } | 1400 } |
1287 break; | 1401 break; |
1288 case BLEZL: | 1402 case BLEZL: |
1289 if ((instr->RtFieldRaw() == instr->RsFieldRaw()) | 1403 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { |
1290 && (instr->RtFieldRaw() != 0)) { | 1404 Format(instr, "bgezc 'rt, 'imm16u -> 'imm16p4s2"); |
1291 Format(instr, "bgezc 'rt, 'imm16u"); | 1405 } else if ((instr->RtValue() != instr->RsValue()) && |
1292 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1406 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1293 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1407 Format(instr, "bgec 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1294 Format(instr, "bgec 'rs, 'rt, 'imm16u"); | 1408 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
1295 } else if ((instr->RsFieldRaw() == 0) | 1409 Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2"); |
1296 && (instr->RtFieldRaw() != 0)) { | |
1297 Format(instr, "blezc 'rt, 'imm16u"); | |
1298 } else { | 1410 } else { |
1299 UNREACHABLE(); | 1411 UNREACHABLE(); |
1300 } | 1412 } |
1301 break; | 1413 break; |
1302 case BGTZL: | 1414 case BGTZL: |
1303 if ((instr->RtFieldRaw() == instr->RsFieldRaw()) | 1415 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { |
1304 && (instr->RtFieldRaw() != 0)) { | 1416 Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2"); |
1305 Format(instr, "bltzc 'rt, 'imm16u"); | 1417 } else if ((instr->RtValue() != instr->RsValue()) && |
1306 } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) | 1418 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { |
1307 && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { | 1419 Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); |
1308 Format(instr, "bltc 'rs, 'rt, 'imm16u"); | 1420 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { |
1309 } else if ((instr->RsFieldRaw() == 0) | 1421 Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2"); |
1310 && (instr->RtFieldRaw() != 0)) { | |
1311 Format(instr, "bgtzc 'rt, 'imm16u"); | |
1312 } else { | 1422 } else { |
1313 UNREACHABLE(); | 1423 UNREACHABLE(); |
1314 } | 1424 } |
1315 break; | 1425 break; |
1316 case POP66: | 1426 case POP66: |
1317 if (instr->RsValue() == JIC) { | 1427 if (instr->RsValue() == JIC) { |
1318 Format(instr, "jic 'rt, 'imm16s"); | 1428 Format(instr, "jic 'rt, 'imm16s"); |
1319 } else { | 1429 } else { |
1320 Format(instr, "beqzc 'rs, 'imm21s"); | 1430 Format(instr, "beqzc 'rs, 'imm21s -> 'imm21p4s2"); |
1321 } | 1431 } |
1322 break; | 1432 break; |
1323 case POP76: | 1433 case POP76: |
1324 if (instr->RsValue() == JIALC) { | 1434 if (instr->RsValue() == JIALC) { |
1325 Format(instr, "jialc 'rt, 'imm16x"); | 1435 Format(instr, "jialc 'rt, 'imm16x"); |
1326 } else { | 1436 } else { |
1327 Format(instr, "bnezc 'rs, 'imm21x"); | 1437 Format(instr, "bnezc 'rs, 'imm21x -> 'imm21p4s2"); |
1328 } | 1438 } |
1329 break; | 1439 break; |
1330 // ------------- Arithmetic instructions. | 1440 // ------------- Arithmetic instructions. |
1331 case ADDI: | 1441 case ADDI: |
1332 if (!IsMipsArchVariant(kMips32r6)) { | 1442 if (!IsMipsArchVariant(kMips32r6)) { |
1333 Format(instr, "addi 'rt, 'rs, 'imm16s"); | 1443 Format(instr, "addi 'rt, 'rs, 'imm16s"); |
1334 } else { | 1444 } else { |
1335 // Check if BOVC or BEQC instruction. | 1445 // Check if BOVC or BEQC instruction. |
1336 if (instr->RsFieldRaw() >= instr->RtFieldRaw()) { | 1446 if (instr->RsValue() >= instr->RtValue()) { |
1337 Format(instr, "bovc 'rs, 'rt, 'imm16s"); | 1447 Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
1338 } else if (instr->RsFieldRaw() < instr->RtFieldRaw()) { | 1448 } else if (instr->RsValue() < instr->RtValue()) { |
1339 Format(instr, "beqc 'rs, 'rt, 'imm16s"); | 1449 Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
1340 } else { | 1450 } else { |
1341 UNREACHABLE(); | 1451 UNREACHABLE(); |
1342 } | 1452 } |
1343 } | 1453 } |
1344 break; | 1454 break; |
1345 case DADDI: | 1455 case DADDI: |
1346 if (IsMipsArchVariant(kMips32r6)) { | 1456 if (IsMipsArchVariant(kMips32r6)) { |
1347 // Check if BNVC or BNEC instruction. | 1457 // Check if BNVC or BNEC instruction. |
1348 if (instr->RsFieldRaw() >= instr->RtFieldRaw()) { | 1458 if (instr->RsValue() >= instr->RtValue()) { |
1349 Format(instr, "bnvc 'rs, 'rt, 'imm16s"); | 1459 Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
1350 } else if (instr->RsFieldRaw() < instr->RtFieldRaw()) { | 1460 } else if (instr->RsValue() < instr->RtValue()) { |
1351 Format(instr, "bnec 'rs, 'rt, 'imm16s"); | 1461 Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2"); |
1352 } else { | 1462 } else { |
1353 UNREACHABLE(); | 1463 UNREACHABLE(); |
1354 } | 1464 } |
1355 } | 1465 } |
1356 break; | 1466 break; |
1357 case ADDIU: | 1467 case ADDIU: |
1358 Format(instr, "addiu 'rt, 'rs, 'imm16s"); | 1468 Format(instr, "addiu 'rt, 'rs, 'imm16s"); |
1359 break; | 1469 break; |
1360 case SLTI: | 1470 case SLTI: |
1361 Format(instr, "slti 'rt, 'rs, 'imm16s"); | 1471 Format(instr, "slti 'rt, 'rs, 'imm16s"); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1468 printf("a 0x%x \n", instr->OpcodeFieldRaw()); | 1578 printf("a 0x%x \n", instr->OpcodeFieldRaw()); |
1469 UNREACHABLE(); | 1579 UNREACHABLE(); |
1470 break; | 1580 break; |
1471 } | 1581 } |
1472 } | 1582 } |
1473 | 1583 |
1474 | 1584 |
1475 void Decoder::DecodeTypeJump(Instruction* instr) { | 1585 void Decoder::DecodeTypeJump(Instruction* instr) { |
1476 switch (instr->OpcodeFieldRaw()) { | 1586 switch (instr->OpcodeFieldRaw()) { |
1477 case J: | 1587 case J: |
1478 Format(instr, "j 'imm26x"); | 1588 Format(instr, "j 'imm26x -> 'imm26j"); |
1479 break; | 1589 break; |
1480 case JAL: | 1590 case JAL: |
1481 Format(instr, "jal 'imm26x"); | 1591 Format(instr, "jal 'imm26x -> 'imm26j"); |
1482 break; | 1592 break; |
1483 default: | 1593 default: |
1484 UNREACHABLE(); | 1594 UNREACHABLE(); |
1485 } | 1595 } |
1486 } | 1596 } |
1487 | 1597 |
1488 | 1598 |
1489 // Disassemble the instruction at *instr_ptr into the output buffer. | 1599 // Disassemble the instruction at *instr_ptr into the output buffer. |
1490 int Decoder::InstructionDecode(byte* instr_ptr) { | 1600 int Decoder::InstructionDecode(byte* instr_ptr) { |
1491 Instruction* instr = Instruction::At(instr_ptr); | 1601 Instruction* instr = Instruction::At(instr_ptr); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1591 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1701 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1592 } | 1702 } |
1593 } | 1703 } |
1594 | 1704 |
1595 | 1705 |
1596 #undef UNSUPPORTED | 1706 #undef UNSUPPORTED |
1597 | 1707 |
1598 } // namespace disasm | 1708 } // namespace disasm |
1599 | 1709 |
1600 #endif // V8_TARGET_ARCH_MIPS | 1710 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |