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