00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <assert.h>
00029 #include <stdio.h>
00030 #include <stdarg.h>
00031 #include <string.h>
00032 #ifndef WIN32
00033 #include <stdint.h>
00034 #endif
00035
00036 #include "v8.h"
00037
00038 #include "disasm.h"
00039 #include "macro-assembler.h"
00040 #include "platform.h"
00041
00042 namespace assembler { namespace arm {
00043
00044 namespace v8i = v8::internal;
00045
00046
00047
00048
00049
00050
00051
00052 class Decoder {
00053 public:
00054 Decoder(const disasm::NameConverter& converter,
00055 v8::internal::Vector<char> out_buffer)
00056 : converter_(converter),
00057 out_buffer_(out_buffer),
00058 out_buffer_pos_(0) {
00059 out_buffer_[out_buffer_pos_] = '\0';
00060 }
00061
00062 ~Decoder() {}
00063
00064
00065
00066 int InstructionDecode(byte* instruction);
00067
00068 private:
00069 const disasm::NameConverter& converter_;
00070 v8::internal::Vector<char> out_buffer_;
00071 int out_buffer_pos_;
00072
00073 void PrintChar(const char ch);
00074 void Print(const char* str);
00075
00076 void PrintRegister(int reg);
00077 void PrintCondition(Instr* instr);
00078 void PrintShiftRm(Instr* instr);
00079 void PrintShiftImm(Instr* instr);
00080
00081 int FormatOption(Instr* instr, const char* option);
00082 void Format(Instr* instr, const char* format);
00083 void Unknown(Instr* instr);
00084
00085 void DecodeType0(Instr* instr);
00086 void DecodeType1(Instr* instr);
00087 void DecodeType2(Instr* instr);
00088 void DecodeType3(Instr* instr);
00089 void DecodeType4(Instr* instr);
00090 void DecodeType5(Instr* instr);
00091 void DecodeType6(Instr* instr);
00092 void DecodeType7(Instr* instr);
00093 };
00094
00095
00096
00097 void Decoder::PrintChar(const char ch) {
00098 out_buffer_[out_buffer_pos_++] = ch;
00099 }
00100
00101
00102
00103 void Decoder::Print(const char* str) {
00104 char cur = *str++;
00105 while (cur != 0 && (out_buffer_pos_ < (out_buffer_.length()-1))) {
00106 PrintChar(cur);
00107 cur = *str++;
00108 }
00109 out_buffer_[out_buffer_pos_] = 0;
00110 }
00111
00112
00113 static const char* cond_names[16] = {
00114 "eq", "ne", "cs" , "cc" , "mi" , "pl" , "vs" , "vc" ,
00115 "hi", "ls", "ge", "lt", "gt", "le", "", "invalid",
00116 };
00117
00118
00119
00120 void Decoder::PrintCondition(Instr* instr) {
00121 Print(cond_names[instr->ConditionField()]);
00122 }
00123
00124
00125
00126 void Decoder::PrintRegister(int reg) {
00127 Print(converter_.NameOfCPURegister(reg));
00128 }
00129
00130
00131 static const char* shift_names[4] = {
00132 "lsl", "lsr", "asr", "ror"
00133 };
00134
00135
00136
00137
00138 void Decoder::PrintShiftRm(Instr* instr) {
00139 Shift shift = instr->ShiftField();
00140 int shift_amount = instr->ShiftAmountField();
00141 int rm = instr->RmField();
00142
00143 PrintRegister(rm);
00144
00145 if ((instr->RegShiftField() == 0) && (shift == LSL) && (shift_amount == 0)) {
00146
00147 return;
00148 }
00149 if (instr->RegShiftField() == 0) {
00150
00151 if ((shift == ROR) && (shift_amount == 0)) {
00152 Print(", RRX");
00153 return;
00154 } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) {
00155 shift_amount = 32;
00156 }
00157 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
00158 ", %s #%d",
00159 shift_names[shift], shift_amount);
00160 } else {
00161
00162 int rs = instr->RsField();
00163 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
00164 ", %s ", shift_names[shift]);
00165 PrintRegister(rs);
00166 }
00167 }
00168
00169
00170
00171
00172 void Decoder::PrintShiftImm(Instr* instr) {
00173 int rotate = instr->RotateField() * 2;
00174 int immed8 = instr->Immed8Field();
00175 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate));
00176 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
00177 "#%d", imm);
00178 }
00179
00180
00181
00182
00183
00184
00185
00186 int Decoder::FormatOption(Instr* instr, const char* format) {
00187 switch (format[0]) {
00188 case 'a': {
00189 if (instr->Bit(21) == 0) {
00190 Print("ul");
00191 } else {
00192 Print("la");
00193 }
00194 return 1;
00195 break;
00196 }
00197 case 'b': {
00198 if (instr->HasB()) {
00199 Print("b");
00200 }
00201 return 1;
00202 break;
00203 }
00204 case 'c': {
00205 ASSERT((format[1] == 'o') && (format[2] == 'n') && (format[3] =='d'));
00206 PrintCondition(instr);
00207 return 4;
00208 break;
00209 }
00210 case 'h': {
00211 if (instr->HasH()) {
00212 Print("h");
00213 } else {
00214 Print("b");
00215 }
00216 return 1;
00217 break;
00218 }
00219 case 'i': {
00220 ASSERT((format[1] == 'm') && (format[2] == 'm'));
00221 PrintShiftImm(instr);
00222 return 3;
00223 break;
00224 }
00225 case 'l': {
00226 if (instr->HasLink()) {
00227 Print("l");
00228 }
00229 return 1;
00230 break;
00231 }
00232 case 'm': {
00233 if (format[1] == 'e') {
00234 ASSERT((format[2] == 'm') && (format[3] == 'o') && (format[4] == 'p'));
00235 if (instr->HasL()) {
00236 Print("ldr");
00237 } else {
00238 Print("str");
00239 }
00240 return 5;
00241 } else {
00242 ASSERT(format[1] == 's' && format[2] == 'g');
00243 byte* str =
00244 reinterpret_cast<byte*>(instr->InstructionBits() & 0x0fffffff);
00245 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
00246 "%s", converter_.NameInCode(str));
00247 return 3;
00248 }
00249 break;
00250 }
00251 case 'o': {
00252 ASSERT(format[1] == 'f' && format[2] == 'f');
00253 if (format[3] == '1') {
00254
00255 ASSERT(format[4] == '2');
00256 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
00257 "%d", instr->Offset12Field());
00258 return 5;
00259 } else {
00260
00261 ASSERT(format[3] == '8');
00262 int offs8 = (instr->ImmedHField() << 4) | instr->ImmedLField();
00263 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
00264 "%d", offs8);
00265 return 4;
00266 }
00267 break;
00268 }
00269 case 'p': {
00270 ASSERT(format[1] == 'u');
00271 switch (instr->PUField()) {
00272 case 0: {
00273 Print("da");
00274 break;
00275 }
00276 case 1: {
00277 Print("ia");
00278 break;
00279 }
00280 case 2: {
00281 Print("db");
00282 break;
00283 }
00284 case 3: {
00285 Print("ib");
00286 break;
00287 }
00288 default: {
00289 UNREACHABLE();
00290 break;
00291 }
00292 }
00293 return 2;
00294 break;
00295 }
00296 case 'r': {
00297 if (format[1] == 'n') {
00298 int reg = instr->RnField();
00299 PrintRegister(reg);
00300 return 2;
00301 } else if (format[1] == 'd') {
00302 int reg = instr->RdField();
00303 PrintRegister(reg);
00304 return 2;
00305 } else if (format[1] == 's') {
00306 int reg = instr->RsField();
00307 PrintRegister(reg);
00308 return 2;
00309 } else if (format[1] == 'm') {
00310 int reg = instr->RmField();
00311 PrintRegister(reg);
00312 return 2;
00313 } else if (format[1] == 'l') {
00314
00315 ASSERT(format[2] == 'i' && format[3] == 's' && format[4] == 't');
00316 int rlist = instr->RlistField();
00317 int reg = 0;
00318 Print("{");
00319 while (rlist != 0) {
00320 if ((rlist & 1) != 0) {
00321 PrintRegister(reg);
00322 if ((rlist >> 1) != 0) {
00323 Print(", ");
00324 }
00325 }
00326 reg++;
00327 rlist >>= 1;
00328 }
00329 Print("}");
00330 return 5;
00331 } else {
00332 UNREACHABLE();
00333 }
00334 UNREACHABLE();
00335 return -1;
00336 break;
00337 }
00338 case 's': {
00339 if (format[1] == 'h') {
00340 ASSERT(format[2] == 'i' && format[3] == 'f' && format[4] == 't'
00341 && format[5] == '_' && format[6] == 'r' && format[7] == 'm');
00342 PrintShiftRm(instr);
00343 return 8;
00344 } else if (format[1] == 'w') {
00345 ASSERT(format[2] == 'i');
00346 SoftwareInterruptCodes swi = instr->SwiField();
00347 switch (swi) {
00348 case call_rt_r5:
00349 Print("call_rt_r5");
00350 break;
00351 case call_rt_r2:
00352 Print("call_rt_r2");
00353 break;
00354 case break_point:
00355 Print("break_point");
00356 break;
00357 default:
00358 out_buffer_pos_ += v8i::OS::SNPrintF(
00359 out_buffer_ + out_buffer_pos_,
00360 "%d",
00361 swi);
00362 break;
00363 }
00364 return 3;
00365 } else if (format[1] == 'i') {
00366 ASSERT(format[2] == 'g' && format[3] == 'n');
00367 if (instr->HasSign()) {
00368 Print("s");
00369 }
00370 return 4;
00371 break;
00372 } else {
00373 if (instr->HasS()) {
00374 Print("s");
00375 }
00376 return 1;
00377 }
00378 break;
00379 }
00380 case 't': {
00381 ASSERT(format[1] == 'a' && format[2] == 'r' && format[3] == 'g'
00382 && format[4] == 'e' && format[5] == 't');
00383 int off = (instr->SImmed24Field() << 2) + 8;
00384 out_buffer_pos_ += v8i::OS::SNPrintF(
00385 out_buffer_ + out_buffer_pos_,
00386 "%+d -> %s",
00387 off,
00388 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off));
00389 return 6;
00390 break;
00391 }
00392 case 'u': {
00393 if (instr->Bit(22) == 0) {
00394 Print("u");
00395 } else {
00396 Print("s");
00397 }
00398 return 1;
00399 break;
00400 }
00401 case 'w': {
00402 if (instr->HasW()) {
00403 Print("!");
00404 }
00405 return 1;
00406 break;
00407 }
00408 default: {
00409 UNREACHABLE();
00410 break;
00411 }
00412 }
00413 UNREACHABLE();
00414 return -1;
00415 }
00416
00417
00418
00419
00420
00421 void Decoder::Format(Instr* instr, const char* format) {
00422 char cur = *format++;
00423 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
00424 if (cur == '\'') {
00425 format += FormatOption(instr, format);
00426 } else {
00427 out_buffer_[out_buffer_pos_++] = cur;
00428 }
00429 cur = *format++;
00430 }
00431 out_buffer_[out_buffer_pos_] = '\0';
00432 }
00433
00434
00435
00436
00437 void Decoder::Unknown(Instr* instr) {
00438 Format(instr, "unknown");
00439 }
00440
00441
00442 void Decoder::DecodeType0(Instr* instr) {
00443 if (instr->IsSpecialType0()) {
00444
00445 if (instr->Bits(7, 4) == 9) {
00446 if (instr->Bit(24) == 0) {
00447
00448 if (instr->Bit(23) == 0) {
00449 if (instr->Bit(21) == 0) {
00450 Format(instr, "mul'cond's 'rd, 'rm, 'rs");
00451 } else {
00452 Format(instr, "mla'cond's 'rd, 'rm, 'rs, 'rn");
00453 }
00454 } else {
00455 Format(instr, "'um'al'cond's 'rn, 'rd, 'rs, 'rm");
00456 }
00457 } else {
00458 Unknown(instr);
00459 }
00460 } else {
00461
00462 switch (instr->PUField()) {
00463 case 0: {
00464 if (instr->Bit(22) == 0) {
00465 Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm");
00466 } else {
00467 Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8");
00468 }
00469 break;
00470 }
00471 case 1: {
00472 if (instr->Bit(22) == 0) {
00473 Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm");
00474 } else {
00475 Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8");
00476 }
00477 break;
00478 }
00479 case 2: {
00480 if (instr->Bit(22) == 0) {
00481 Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w");
00482 } else {
00483 Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w");
00484 }
00485 break;
00486 }
00487 case 3: {
00488 if (instr->Bit(22) == 0) {
00489 Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w");
00490 } else {
00491 Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w");
00492 }
00493 break;
00494 }
00495 default: {
00496
00497 UNREACHABLE();
00498 break;
00499 }
00500 }
00501 return;
00502 }
00503 } else {
00504 switch (instr->OpcodeField()) {
00505 case AND: {
00506 Format(instr, "and'cond's 'rd, 'rn, 'shift_rm");
00507 break;
00508 }
00509 case EOR: {
00510 Format(instr, "eor'cond's 'rd, 'rn, 'shift_rm");
00511 break;
00512 }
00513 case SUB: {
00514 Format(instr, "sub'cond's 'rd, 'rn, 'shift_rm");
00515 break;
00516 }
00517 case RSB: {
00518 Format(instr, "rsb'cond's 'rd, 'rn, 'shift_rm");
00519 break;
00520 }
00521 case ADD: {
00522 Format(instr, "add'cond's 'rd, 'rn, 'shift_rm");
00523 break;
00524 }
00525 case ADC: {
00526 Format(instr, "adc'cond's 'rd, 'rn, 'shift_rm");
00527 break;
00528 }
00529 case SBC: {
00530 Format(instr, "sbc'cond's 'rd, 'rn, 'shift_rm");
00531 break;
00532 }
00533 case RSC: {
00534 Format(instr, "rsc'cond's 'rd, 'rn, 'shift_rm");
00535 break;
00536 }
00537 case TST: {
00538 if (instr->HasS()) {
00539 Format(instr, "tst'cond 'rn, 'shift_rm");
00540 } else {
00541 Unknown(instr);
00542 return;
00543 }
00544 break;
00545 }
00546 case TEQ: {
00547 if (instr->HasS()) {
00548 Format(instr, "teq'cond 'rn, 'shift_rm");
00549 } else {
00550 Unknown(instr);
00551 return;
00552 }
00553 break;
00554 }
00555 case CMP: {
00556 if (instr->HasS()) {
00557 Format(instr, "cmp'cond 'rn, 'shift_rm");
00558 } else {
00559 Unknown(instr);
00560 return;
00561 }
00562 break;
00563 }
00564 case CMN: {
00565 if (instr->HasS()) {
00566 Format(instr, "cmn'cond 'rn, 'shift_rm");
00567 } else {
00568 Unknown(instr);
00569 return;
00570 }
00571 break;
00572 }
00573 case ORR: {
00574 Format(instr, "orr'cond's 'rd, 'rn, 'shift_rm");
00575 break;
00576 }
00577 case MOV: {
00578 Format(instr, "mov'cond's 'rd, 'shift_rm");
00579 break;
00580 }
00581 case BIC: {
00582 Format(instr, "bic'cond's 'rd, 'rn, 'shift_rm");
00583 break;
00584 }
00585 case MVN: {
00586 Format(instr, "mvn'cond's 'rd, 'shift_rm");
00587 break;
00588 }
00589 default: {
00590
00591 UNREACHABLE();
00592 break;
00593 }
00594 }
00595 }
00596 }
00597
00598
00599 void Decoder::DecodeType1(Instr* instr) {
00600 switch (instr->OpcodeField()) {
00601 case AND: {
00602 Format(instr, "and'cond's 'rd, 'rn, 'imm");
00603 break;
00604 }
00605 case EOR: {
00606 Format(instr, "eor'cond's 'rd, 'rn, 'imm");
00607 break;
00608 }
00609 case SUB: {
00610 Format(instr, "sub'cond's 'rd, 'rn, 'imm");
00611 break;
00612 }
00613 case RSB: {
00614 Format(instr, "rsb'cond's 'rd, 'rn, 'imm");
00615 break;
00616 }
00617 case ADD: {
00618 Format(instr, "add'cond's 'rd, 'rn, 'imm");
00619 break;
00620 }
00621 case ADC: {
00622 Format(instr, "adc'cond's 'rd, 'rn, 'imm");
00623 break;
00624 }
00625 case SBC: {
00626 Format(instr, "sbc'cond's 'rd, 'rn, 'imm");
00627 break;
00628 }
00629 case RSC: {
00630 Format(instr, "rsc'cond's 'rd, 'rn, 'imm");
00631 break;
00632 }
00633 case TST: {
00634 if (instr->HasS()) {
00635 Format(instr, "tst'cond 'rn, 'imm");
00636 } else {
00637 Unknown(instr);
00638 return;
00639 }
00640 break;
00641 }
00642 case TEQ: {
00643 if (instr->HasS()) {
00644 Format(instr, "teq'cond 'rn, 'imm");
00645 } else {
00646 Unknown(instr);
00647 return;
00648 }
00649 break;
00650 }
00651 case CMP: {
00652 if (instr->HasS()) {
00653 Format(instr, "cmp'cond 'rn, 'imm");
00654 } else {
00655 Unknown(instr);
00656 return;
00657 }
00658 break;
00659 }
00660 case CMN: {
00661 if (instr->HasS()) {
00662 Format(instr, "cmn'cond 'rn, 'imm");
00663 } else {
00664 Unknown(instr);
00665 return;
00666 }
00667 break;
00668 }
00669 case ORR: {
00670 Format(instr, "orr'cond's 'rd, 'rn, 'imm");
00671 break;
00672 }
00673 case MOV: {
00674 Format(instr, "mov'cond's 'rd, 'imm");
00675 break;
00676 }
00677 case BIC: {
00678 Format(instr, "bic'cond's 'rd, 'rn, 'imm");
00679 break;
00680 }
00681 case MVN: {
00682 Format(instr, "mvn'cond's 'rd, 'imm");
00683 break;
00684 }
00685 default: {
00686
00687 UNREACHABLE();
00688 break;
00689 }
00690 }
00691 }
00692
00693
00694 void Decoder::DecodeType2(Instr* instr) {
00695 switch (instr->PUField()) {
00696 case 0: {
00697 if (instr->HasW()) {
00698 Unknown(instr);
00699 return;
00700 }
00701 Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
00702 break;
00703 }
00704 case 1: {
00705 if (instr->HasW()) {
00706 Unknown(instr);
00707 return;
00708 }
00709 Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
00710 break;
00711 }
00712 case 2: {
00713 Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w");
00714 break;
00715 }
00716 case 3: {
00717 Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w");
00718 break;
00719 }
00720 default: {
00721
00722 UNREACHABLE();
00723 break;
00724 }
00725 }
00726 }
00727
00728
00729 void Decoder::DecodeType3(Instr* instr) {
00730 switch (instr->PUField()) {
00731 case 0: {
00732 ASSERT(!instr->HasW());
00733 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm");
00734 break;
00735 }
00736 case 1: {
00737 ASSERT(!instr->HasW());
00738 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm");
00739 break;
00740 }
00741 case 2: {
00742 Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w");
00743 break;
00744 }
00745 case 3: {
00746 Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w");
00747 break;
00748 }
00749 default: {
00750
00751 UNREACHABLE();
00752 break;
00753 }
00754 }
00755 }
00756
00757
00758 void Decoder::DecodeType4(Instr* instr) {
00759 ASSERT(instr->Bit(22) == 0);
00760 if (instr->HasL()) {
00761 Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
00762 } else {
00763 Format(instr, "stm'cond'pu 'rn'w, 'rlist");
00764 }
00765 }
00766
00767
00768 void Decoder::DecodeType5(Instr* instr) {
00769 Format(instr, "b'l'cond 'target");
00770 }
00771
00772
00773 void Decoder::DecodeType6(Instr* instr) {
00774
00775 Unknown(instr);
00776 }
00777
00778
00779 void Decoder::DecodeType7(Instr* instr) {
00780 if (instr->Bit(24) == 1) {
00781 Format(instr, "swi'cond 'swi");
00782 } else {
00783
00784 Unknown(instr);
00785 }
00786 }
00787
00788
00789
00790 int Decoder::InstructionDecode(byte* instr_ptr) {
00791 Instr* instr = Instr::At(instr_ptr);
00792
00793 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
00794 "%08x ",
00795 instr->InstructionBits());
00796 if (instr->ConditionField() == special_condition) {
00797 Format(instr, "break 'msg");
00798 return Instr::kInstrSize;
00799 }
00800 switch (instr->TypeField()) {
00801 case 0: {
00802 DecodeType0(instr);
00803 break;
00804 }
00805 case 1: {
00806 DecodeType1(instr);
00807 break;
00808 }
00809 case 2: {
00810 DecodeType2(instr);
00811 break;
00812 }
00813 case 3: {
00814 DecodeType3(instr);
00815 break;
00816 }
00817 case 4: {
00818 DecodeType4(instr);
00819 break;
00820 }
00821 case 5: {
00822 DecodeType5(instr);
00823 break;
00824 }
00825 case 6: {
00826 DecodeType6(instr);
00827 break;
00828 }
00829 case 7: {
00830 DecodeType7(instr);
00831 break;
00832 }
00833 default: {
00834
00835 UNREACHABLE();
00836 break;
00837 }
00838 }
00839 return Instr::kInstrSize;
00840 }
00841
00842
00843 } }
00844
00845
00846
00847
00848
00849 namespace disasm {
00850
00851 static const char* reg_names[16] = {
00852 "r0", "r1", "r2" , "r3" , "r4" , "r5" , "r6" , "r7" ,
00853 "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc",
00854 };
00855
00856
00857 const char* NameConverter::NameOfAddress(byte* addr) const {
00858 static v8::internal::EmbeddedVector<char, 32> tmp_buffer;
00859 v8::internal::OS::SNPrintF(tmp_buffer, "%p", addr);
00860 return tmp_buffer.start();
00861 }
00862
00863
00864 const char* NameConverter::NameOfConstant(byte* addr) const {
00865 return NameOfAddress(addr);
00866 }
00867
00868
00869 const char* NameConverter::NameOfCPURegister(int reg) const {
00870 const char* result;
00871 if ((0 <= reg) && (reg < 16)) {
00872 result = reg_names[reg];
00873 } else {
00874 result = "noreg";
00875 }
00876 return result;
00877 }
00878
00879
00880 const char* NameConverter::NameOfXMMRegister(int reg) const {
00881 UNREACHABLE();
00882 return "noxmmreg";
00883 }
00884
00885
00886 const char* NameConverter::NameInCode(byte* addr) const {
00887
00888
00889 return "";
00890 }
00891
00892
00893
00894
00895 static NameConverter defaultConverter;
00896
00897 Disassembler::Disassembler() : converter_(defaultConverter) {}
00898
00899
00900 Disassembler::Disassembler(const NameConverter& converter)
00901 : converter_(converter) {}
00902
00903
00904 Disassembler::~Disassembler() {}
00905
00906
00907 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
00908 byte* instruction) {
00909 assembler::arm::Decoder d(converter_, buffer);
00910 return d.InstructionDecode(instruction);
00911 }
00912
00913
00914 int Disassembler::ConstantPoolSizeAt(byte* instruction) {
00915 int instruction_bits = *(reinterpret_cast<int*>(instruction));
00916 if ((instruction_bits & 0xfff00000) == 0x03000000) {
00917 return instruction_bits & 0x0000ffff;
00918 } else {
00919 return -1;
00920 }
00921 }
00922
00923
00924 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
00925 Disassembler d;
00926 for (byte* pc = begin; pc < end;) {
00927 v8::internal::EmbeddedVector<char, 128> buffer;
00928 buffer[0] = '\0';
00929 byte* prev_pc = pc;
00930 pc += d.InstructionDecode(buffer, pc);
00931 fprintf(f, "%p %08x %s\n",
00932 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
00933 }
00934 }
00935
00936
00937 }