OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 } | 236 } |
237 return 1; | 237 return 1; |
238 } | 238 } |
239 case 'a': { | 239 case 'a': { |
240 // Absolute Address Bit 1 | 240 // Absolute Address Bit 1 |
241 if (instr->Bit(1) == 1) { | 241 if (instr->Bit(1) == 1) { |
242 Print("a"); | 242 Print("a"); |
243 } | 243 } |
244 return 1; | 244 return 1; |
245 } | 245 } |
| 246 case 'c': { // 'cr: condition register of branch instruction |
| 247 int code = instr->Bits(20, 18); |
| 248 if (code != 7) { |
| 249 out_buffer_pos_ += |
| 250 SNPrintF(out_buffer_ + out_buffer_pos_, " cr%d", code); |
| 251 } |
| 252 return 2; |
| 253 } |
246 case 't': { // 'target: target of branch instructions | 254 case 't': { // 'target: target of branch instructions |
247 // target26 or target16 | 255 // target26 or target16 |
248 DCHECK(STRING_STARTS_WITH(format, "target")); | 256 DCHECK(STRING_STARTS_WITH(format, "target")); |
249 if ((format[6] == '2') && (format[7] == '6')) { | 257 if ((format[6] == '2') && (format[7] == '6')) { |
250 int off = ((instr->Bits(25, 2)) << 8) >> 6; | 258 int off = ((instr->Bits(25, 2)) << 8) >> 6; |
251 out_buffer_pos_ += SNPrintF( | 259 out_buffer_pos_ += SNPrintF( |
252 out_buffer_ + out_buffer_pos_, "%+d -> %s", off, | 260 out_buffer_ + out_buffer_pos_, "%+d -> %s", off, |
253 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off)); | 261 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off)); |
254 return 8; | 262 return 8; |
255 } else if ((format[6] == '1') && (format[7] == '6')) { | 263 } else if ((format[6] == '1') && (format[7] == '6')) { |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 } | 367 } |
360 | 368 |
361 | 369 |
362 void Decoder::DecodeExt1(Instruction* instr) { | 370 void Decoder::DecodeExt1(Instruction* instr) { |
363 switch (instr->Bits(10, 1) << 1) { | 371 switch (instr->Bits(10, 1) << 1) { |
364 case MCRF: { | 372 case MCRF: { |
365 UnknownFormat(instr, "mcrf"); // not used by V8 | 373 UnknownFormat(instr, "mcrf"); // not used by V8 |
366 break; | 374 break; |
367 } | 375 } |
368 case BCLRX: { | 376 case BCLRX: { |
369 switch (instr->Bits(25, 21) << 21) { | 377 int bo = instr->Bits(25, 21) << 21; |
| 378 int bi = instr->Bits(20, 16); |
| 379 CRBit cond = static_cast<CRBit>(bi & (CRWIDTH - 1)); |
| 380 switch (bo) { |
370 case DCBNZF: { | 381 case DCBNZF: { |
371 UnknownFormat(instr, "bclrx-dcbnzf"); | 382 UnknownFormat(instr, "bclrx-dcbnzf"); |
372 break; | 383 break; |
373 } | 384 } |
374 case DCBEZF: { | 385 case DCBEZF: { |
375 UnknownFormat(instr, "bclrx-dcbezf"); | 386 UnknownFormat(instr, "bclrx-dcbezf"); |
376 break; | 387 break; |
377 } | 388 } |
378 case BF: { | 389 case BF: { |
379 UnknownFormat(instr, "bclrx-bf"); | 390 switch (cond) { |
| 391 case CR_EQ: |
| 392 Format(instr, "bnelr'l'cr"); |
| 393 break; |
| 394 case CR_GT: |
| 395 Format(instr, "blelr'l'cr"); |
| 396 break; |
| 397 case CR_LT: |
| 398 Format(instr, "bgelr'l'cr"); |
| 399 break; |
| 400 case CR_SO: |
| 401 Format(instr, "bnsolr'l'cr"); |
| 402 break; |
| 403 } |
380 break; | 404 break; |
381 } | 405 } |
382 case DCBNZT: { | 406 case DCBNZT: { |
383 UnknownFormat(instr, "bclrx-dcbbzt"); | 407 UnknownFormat(instr, "bclrx-dcbbzt"); |
384 break; | 408 break; |
385 } | 409 } |
386 case DCBEZT: { | 410 case DCBEZT: { |
387 UnknownFormat(instr, "bclrx-dcbnezt"); | 411 UnknownFormat(instr, "bclrx-dcbnezt"); |
388 break; | 412 break; |
389 } | 413 } |
390 case BT: { | 414 case BT: { |
391 UnknownFormat(instr, "bclrx-bt"); | 415 switch (cond) { |
| 416 case CR_EQ: |
| 417 Format(instr, "beqlr'l'cr"); |
| 418 break; |
| 419 case CR_GT: |
| 420 Format(instr, "bgtlr'l'cr"); |
| 421 break; |
| 422 case CR_LT: |
| 423 Format(instr, "bltlr'l'cr"); |
| 424 break; |
| 425 case CR_SO: |
| 426 Format(instr, "bsolr'l'cr"); |
| 427 break; |
| 428 } |
392 break; | 429 break; |
393 } | 430 } |
394 case DCBNZ: { | 431 case DCBNZ: { |
395 UnknownFormat(instr, "bclrx-dcbnz"); | 432 UnknownFormat(instr, "bclrx-dcbnz"); |
396 break; | 433 break; |
397 } | 434 } |
398 case DCBEZ: { | 435 case DCBEZ: { |
399 UnknownFormat(instr, "bclrx-dcbez"); // not used by V8 | 436 UnknownFormat(instr, "bclrx-dcbez"); // not used by V8 |
400 break; | 437 break; |
401 } | 438 } |
402 case BA: { | 439 case BA: { |
403 if (instr->Bit(0) == 1) { | 440 Format(instr, "blr'l"); |
404 Format(instr, "blrl"); | |
405 } else { | |
406 Format(instr, "blr"); | |
407 } | |
408 break; | 441 break; |
409 } | 442 } |
410 } | 443 } |
411 break; | 444 break; |
412 } | 445 } |
413 case BCCTRX: { | 446 case BCCTRX: { |
414 switch (instr->Bits(25, 21) << 21) { | 447 switch (instr->Bits(25, 21) << 21) { |
415 case DCBNZF: { | 448 case DCBNZF: { |
416 UnknownFormat(instr, "bcctrx-dcbnzf"); | 449 UnknownFormat(instr, "bcctrx-dcbnzf"); |
417 break; | 450 break; |
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 if (instr->RAValue() == 0) { | 1088 if (instr->RAValue() == 0) { |
1056 Format(instr, "lis 'rt, 'int16"); | 1089 Format(instr, "lis 'rt, 'int16"); |
1057 } else { | 1090 } else { |
1058 Format(instr, "addis 'rt, 'ra, 'int16"); | 1091 Format(instr, "addis 'rt, 'ra, 'int16"); |
1059 } | 1092 } |
1060 break; | 1093 break; |
1061 } | 1094 } |
1062 case BCX: { | 1095 case BCX: { |
1063 int bo = instr->Bits(25, 21) << 21; | 1096 int bo = instr->Bits(25, 21) << 21; |
1064 int bi = instr->Bits(20, 16); | 1097 int bi = instr->Bits(20, 16); |
1065 switch (bi) { | 1098 CRBit cond = static_cast<CRBit>(bi & (CRWIDTH - 1)); |
1066 case 2: | 1099 switch (bo) { |
1067 case 30: | 1100 case BT: { // Branch if condition true |
1068 if (BT == bo) { | 1101 switch (cond) { |
1069 Format(instr, "beq'l'a 'target16"); | 1102 case CR_EQ: |
1070 break; | 1103 Format(instr, "beq'l'a'cr 'target16"); |
| 1104 break; |
| 1105 case CR_GT: |
| 1106 Format(instr, "bgt'l'a'cr 'target16"); |
| 1107 break; |
| 1108 case CR_LT: |
| 1109 Format(instr, "blt'l'a'cr 'target16"); |
| 1110 break; |
| 1111 case CR_SO: |
| 1112 Format(instr, "bso'l'a'cr 'target16"); |
| 1113 break; |
1071 } | 1114 } |
1072 if (BF == bo) { | 1115 break; |
1073 Format(instr, "bne'l'a 'target16"); | 1116 } |
1074 break; | 1117 case BF: { // Branch if condition false |
| 1118 switch (cond) { |
| 1119 case CR_EQ: |
| 1120 Format(instr, "bne'l'a'cr 'target16"); |
| 1121 break; |
| 1122 case CR_GT: |
| 1123 Format(instr, "ble'l'a'cr 'target16"); |
| 1124 break; |
| 1125 case CR_LT: |
| 1126 Format(instr, "bge'l'a'cr 'target16"); |
| 1127 break; |
| 1128 case CR_SO: |
| 1129 Format(instr, "bnso'l'a'cr 'target16"); |
| 1130 break; |
1075 } | 1131 } |
1076 Format(instr, "bc'l'a 'target16"); | |
1077 break; | 1132 break; |
1078 case 29: | 1133 } |
1079 if (BT == bo) { | 1134 case DCBNZ: { // Decrement CTR; branch if CTR != 0 |
1080 Format(instr, "bgt'l'a 'target16"); | 1135 Format(instr, "bdnz'l'a 'target16"); |
1081 break; | |
1082 } | |
1083 if (BF == bo) { | |
1084 Format(instr, "ble'l'a 'target16"); | |
1085 break; | |
1086 } | |
1087 Format(instr, "bc'l'a 'target16"); | |
1088 break; | 1136 break; |
1089 case 28: | 1137 } |
1090 if (BT == bo) { | |
1091 Format(instr, "blt'l'a 'target16"); | |
1092 break; | |
1093 } | |
1094 if (BF == bo) { | |
1095 Format(instr, "bge'l'a 'target16"); | |
1096 break; | |
1097 } | |
1098 Format(instr, "bc'l'a 'target16"); | |
1099 break; | |
1100 default: | 1138 default: |
1101 Format(instr, "bc'l'a 'target16"); | 1139 Format(instr, "bc'l'a'cr 'target16"); |
1102 break; | 1140 break; |
1103 } | 1141 } |
1104 break; | 1142 break; |
1105 } | 1143 } |
1106 case SC: { | 1144 case SC: { |
1107 UnknownFormat(instr, "sc"); | 1145 UnknownFormat(instr, "sc"); |
1108 break; | 1146 break; |
1109 } | 1147 } |
1110 case BX: { | 1148 case BX: { |
1111 Format(instr, "b'l'a 'target26"); | 1149 Format(instr, "b'l'a 'target26"); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 pc += d.InstructionDecode(buffer, pc); | 1402 pc += d.InstructionDecode(buffer, pc); |
1365 v8::internal::PrintF(f, "%p %08x %s\n", prev_pc, | 1403 v8::internal::PrintF(f, "%p %08x %s\n", prev_pc, |
1366 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 1404 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
1367 } | 1405 } |
1368 } | 1406 } |
1369 | 1407 |
1370 | 1408 |
1371 } // namespace disasm | 1409 } // namespace disasm |
1372 | 1410 |
1373 #endif // V8_TARGET_ARCH_PPC | 1411 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |