1// Copyright 2010 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28// A Disassembler object is used to disassemble a block of code instruction by 29// instruction. The default implementation of the NameConverter object can be 30// overriden to modify register names or to do symbol lookup on addresses. 31// 32// The example below will disassemble a block of code and print it to stdout. 33// 34// NameConverter converter; 35// Disassembler d(converter); 36// for (byte* pc = begin; pc < end;) { 37// char buffer[128]; 38// buffer[0] = '\0'; 39// byte* prev_pc = pc; 40// pc += d.InstructionDecode(buffer, sizeof buffer, pc); 41// printf("%p %08x %s\n", 42// prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer); 43// } 44// 45// The Disassembler class also has a convenience method to disassemble a block 46// of code into a FILE*, meaning that the above functionality could also be 47// achieved by just calling Disassembler::Disassemble(stdout, begin, end); 48 49 50#include <assert.h> 51#include <stdio.h> 52#include <stdarg.h> 53#include <string.h> 54#ifndef WIN32 55#include <stdint.h> 56#endif 57 58#include "v8.h" 59 60#include "constants-arm.h" 61#include "disasm.h" 62#include "macro-assembler.h" 63#include "platform.h" 64 65 66namespace assembler { 67namespace arm { 68 69namespace v8i = v8::internal; 70 71 72//------------------------------------------------------------------------------ 73 74// Decoder decodes and disassembles instructions into an output buffer. 75// It uses the converter to convert register names and call destinations into 76// more informative description. 77class Decoder { 78 public: 79 Decoder(const disasm::NameConverter& converter, 80 v8::internal::Vector<char> out_buffer) 81 : converter_(converter), 82 out_buffer_(out_buffer), 83 out_buffer_pos_(0) { 84 out_buffer_[out_buffer_pos_] = '\0'; 85 } 86 87 ~Decoder() {} 88 89 // Writes one disassembled instruction into 'buffer' (0-terminated). 90 // Returns the length of the disassembled machine instruction in bytes. 91 int InstructionDecode(byte* instruction); 92 93 private: 94 // Bottleneck functions to print into the out_buffer. 95 void PrintChar(const char ch); 96 void Print(const char* str); 97 98 // Printing of common values. 99 void PrintRegister(int reg); 100 void PrintSRegister(int reg); 101 void PrintDRegister(int reg); 102 int FormatVFPRegister(Instr* instr, const char* format); 103 int FormatVFPinstruction(Instr* instr, const char* format); 104 void PrintCondition(Instr* instr); 105 void PrintShiftRm(Instr* instr); 106 void PrintShiftImm(Instr* instr); 107 void PrintPU(Instr* instr); 108 void PrintSoftwareInterrupt(SoftwareInterruptCodes swi); 109 110 // Handle formatting of instructions and their options. 111 int FormatRegister(Instr* instr, const char* option); 112 int FormatOption(Instr* instr, const char* option); 113 void Format(Instr* instr, const char* format); 114 void Unknown(Instr* instr); 115 116 // Each of these functions decodes one particular instruction type, a 3-bit 117 // field in the instruction encoding. 118 // Types 0 and 1 are combined as they are largely the same except for the way 119 // they interpret the shifter operand. 120 void DecodeType01(Instr* instr); 121 void DecodeType2(Instr* instr); 122 void DecodeType3(Instr* instr); 123 void DecodeType4(Instr* instr); 124 void DecodeType5(Instr* instr); 125 void DecodeType6(Instr* instr); 126 void DecodeType7(Instr* instr); 127 void DecodeUnconditional(Instr* instr); 128 // For VFP support. 129 void DecodeTypeVFP(Instr* instr); 130 void DecodeType6CoprocessorIns(Instr* instr); 131 132 133 const disasm::NameConverter& converter_; 134 v8::internal::Vector<char> out_buffer_; 135 int out_buffer_pos_; 136 137 DISALLOW_COPY_AND_ASSIGN(Decoder); 138}; 139 140 141// Support for assertions in the Decoder formatting functions. 142#define STRING_STARTS_WITH(string, compare_string) \ 143 (strncmp(string, compare_string, strlen(compare_string)) == 0) 144 145 146// Append the ch to the output buffer. 147void Decoder::PrintChar(const char ch) { 148 out_buffer_[out_buffer_pos_++] = ch; 149} 150 151 152// Append the str to the output buffer. 153void Decoder::Print(const char* str) { 154 char cur = *str++; 155 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 156 PrintChar(cur); 157 cur = *str++; 158 } 159 out_buffer_[out_buffer_pos_] = 0; 160} 161 162 163// These condition names are defined in a way to match the native disassembler 164// formatting. See for example the command "objdump -d <binary file>". 165static const char* cond_names[max_condition] = { 166 "eq", "ne", "cs" , "cc" , "mi" , "pl" , "vs" , "vc" , 167 "hi", "ls", "ge", "lt", "gt", "le", "", "invalid", 168}; 169 170 171// Print the condition guarding the instruction. 172void Decoder::PrintCondition(Instr* instr) { 173 Print(cond_names[instr->ConditionField()]); 174} 175 176 177// Print the register name according to the active name converter. 178void Decoder::PrintRegister(int reg) { 179 Print(converter_.NameOfCPURegister(reg)); 180} 181 182// Print the VFP S register name according to the active name converter. 183void Decoder::PrintSRegister(int reg) { 184 Print(assembler::arm::VFPRegisters::Name(reg)); 185} 186 187// Print the VFP D register name according to the active name converter. 188void Decoder::PrintDRegister(int reg) { 189 Print(assembler::arm::VFPRegisters::Name(reg + 32)); 190} 191 192 193// These shift names are defined in a way to match the native disassembler 194// formatting. See for example the command "objdump -d <binary file>". 195static const char* shift_names[max_shift] = { 196 "lsl", "lsr", "asr", "ror" 197}; 198 199 200// Print the register shift operands for the instruction. Generally used for 201// data processing instructions. 202void Decoder::PrintShiftRm(Instr* instr) { 203 Shift shift = instr->ShiftField(); 204 int shift_amount = instr->ShiftAmountField(); 205 int rm = instr->RmField(); 206 207 PrintRegister(rm); 208 209 if ((instr->RegShiftField() == 0) && (shift == LSL) && (shift_amount == 0)) { 210 // Special case for using rm only. 211 return; 212 } 213 if (instr->RegShiftField() == 0) { 214 // by immediate 215 if ((shift == ROR) && (shift_amount == 0)) { 216 Print(", RRX"); 217 return; 218 } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) { 219 shift_amount = 32; 220 } 221 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 222 ", %s #%d", 223 shift_names[shift], shift_amount); 224 } else { 225 // by register 226 int rs = instr->RsField(); 227 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 228 ", %s ", shift_names[shift]); 229 PrintRegister(rs); 230 } 231} 232 233 234// Print the immediate operand for the instruction. Generally used for data 235// processing instructions. 236void Decoder::PrintShiftImm(Instr* instr) { 237 int rotate = instr->RotateField() * 2; 238 int immed8 = instr->Immed8Field(); 239 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate)); 240 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 241 "#%d", imm); 242} 243 244 245// Print PU formatting to reduce complexity of FormatOption. 246void Decoder::PrintPU(Instr* instr) { 247 switch (instr->PUField()) { 248 case 0: { 249 Print("da"); 250 break; 251 } 252 case 1: { 253 Print("ia"); 254 break; 255 } 256 case 2: { 257 Print("db"); 258 break; 259 } 260 case 3: { 261 Print("ib"); 262 break; 263 } 264 default: { 265 UNREACHABLE(); 266 break; 267 } 268 } 269} 270 271 272// Print SoftwareInterrupt codes. Factoring this out reduces the complexity of 273// the FormatOption method. 274void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes swi) { 275 switch (swi) { 276 case call_rt_redirected: 277 Print("call_rt_redirected"); 278 return; 279 case break_point: 280 Print("break_point"); 281 return; 282 default: 283 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 284 "%d", 285 swi); 286 return; 287 } 288} 289 290 291// Handle all register based formatting in this function to reduce the 292// complexity of FormatOption. 293int Decoder::FormatRegister(Instr* instr, const char* format) { 294 ASSERT(format[0] == 'r'); 295 if (format[1] == 'n') { // 'rn: Rn register 296 int reg = instr->RnField(); 297 PrintRegister(reg); 298 return 2; 299 } else if (format[1] == 'd') { // 'rd: Rd register 300 int reg = instr->RdField(); 301 PrintRegister(reg); 302 return 2; 303 } else if (format[1] == 's') { // 'rs: Rs register 304 int reg = instr->RsField(); 305 PrintRegister(reg); 306 return 2; 307 } else if (format[1] == 'm') { // 'rm: Rm register 308 int reg = instr->RmField(); 309 PrintRegister(reg); 310 return 2; 311 } else if (format[1] == 't') { // 'rt: Rt register 312 int reg = instr->RtField(); 313 PrintRegister(reg); 314 return 2; 315 } else if (format[1] == 'l') { 316 // 'rlist: register list for load and store multiple instructions 317 ASSERT(STRING_STARTS_WITH(format, "rlist")); 318 int rlist = instr->RlistField(); 319 int reg = 0; 320 Print("{"); 321 // Print register list in ascending order, by scanning the bit mask. 322 while (rlist != 0) { 323 if ((rlist & 1) != 0) { 324 PrintRegister(reg); 325 if ((rlist >> 1) != 0) { 326 Print(", "); 327 } 328 } 329 reg++; 330 rlist >>= 1; 331 } 332 Print("}"); 333 return 5; 334 } 335 UNREACHABLE(); 336 return -1; 337} 338 339 340// Handle all VFP register based formatting in this function to reduce the 341// complexity of FormatOption. 342int Decoder::FormatVFPRegister(Instr* instr, const char* format) { 343 ASSERT((format[0] == 'S') || (format[0] == 'D')); 344 345 if (format[1] == 'n') { 346 int reg = instr->VnField(); 347 if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->NField())); 348 if (format[0] == 'D') PrintDRegister(reg); 349 return 2; 350 } else if (format[1] == 'm') { 351 int reg = instr->VmField(); 352 if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->MField())); 353 if (format[0] == 'D') PrintDRegister(reg); 354 return 2; 355 } else if (format[1] == 'd') { 356 int reg = instr->VdField(); 357 if (format[0] == 'S') PrintSRegister(((reg << 1) | instr->DField())); 358 if (format[0] == 'D') PrintDRegister(reg); 359 return 2; 360 } 361 362 UNREACHABLE(); 363 return -1; 364} 365 366 367int Decoder::FormatVFPinstruction(Instr* instr, const char* format) { 368 Print(format); 369 return 0; 370} 371 372 373// FormatOption takes a formatting string and interprets it based on 374// the current instructions. The format string points to the first 375// character of the option string (the option escape has already been 376// consumed by the caller.) FormatOption returns the number of 377// characters that were consumed from the formatting string. 378int Decoder::FormatOption(Instr* instr, const char* format) { 379 switch (format[0]) { 380 case 'a': { // 'a: accumulate multiplies 381 if (instr->Bit(21) == 0) { 382 Print("ul"); 383 } else { 384 Print("la"); 385 } 386 return 1; 387 } 388 case 'b': { // 'b: byte loads or stores 389 if (instr->HasB()) { 390 Print("b"); 391 } 392 return 1; 393 } 394 case 'c': { // 'cond: conditional execution 395 ASSERT(STRING_STARTS_WITH(format, "cond")); 396 PrintCondition(instr); 397 return 4; 398 } 399 case 'h': { // 'h: halfword operation for extra loads and stores 400 if (instr->HasH()) { 401 Print("h"); 402 } else { 403 Print("b"); 404 } 405 return 1; 406 } 407 case 'l': { // 'l: branch and link 408 if (instr->HasLink()) { 409 Print("l"); 410 } 411 return 1; 412 } 413 case 'm': { 414 if (format[1] == 'e') { // 'memop: load/store instructions 415 ASSERT(STRING_STARTS_WITH(format, "memop")); 416 if (instr->HasL()) { 417 Print("ldr"); 418 } else { 419 Print("str"); 420 } 421 return 5; 422 } 423 // 'msg: for simulator break instructions 424 ASSERT(STRING_STARTS_WITH(format, "msg")); 425 byte* str = 426 reinterpret_cast<byte*>(instr->InstructionBits() & 0x0fffffff); 427 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 428 "%s", converter_.NameInCode(str)); 429 return 3; 430 } 431 case 'o': { 432 if ((format[3] == '1') && (format[4] == '2')) { 433 // 'off12: 12-bit offset for load and store instructions 434 ASSERT(STRING_STARTS_WITH(format, "off12")); 435 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 436 "%d", instr->Offset12Field()); 437 return 5; 438 } else if ((format[3] == '1') && (format[4] == '6')) { 439 ASSERT(STRING_STARTS_WITH(format, "off16to20")); 440 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 441 "%d", instr->Bits(20, 16) +1); 442 return 9; 443 } else if (format[3] == '7') { 444 ASSERT(STRING_STARTS_WITH(format, "off7to11")); 445 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 446 "%d", instr->ShiftAmountField()); 447 return 8; 448 } 449 // 'off8: 8-bit offset for extra load and store instructions 450 ASSERT(STRING_STARTS_WITH(format, "off8")); 451 int offs8 = (instr->ImmedHField() << 4) | instr->ImmedLField(); 452 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 453 "%d", offs8); 454 return 4; 455 } 456 case 'p': { // 'pu: P and U bits for load and store instructions 457 ASSERT(STRING_STARTS_WITH(format, "pu")); 458 PrintPU(instr); 459 return 2; 460 } 461 case 'r': { 462 return FormatRegister(instr, format); 463 } 464 case 's': { 465 if (format[1] == 'h') { // 'shift_op or 'shift_rm 466 if (format[6] == 'o') { // 'shift_op 467 ASSERT(STRING_STARTS_WITH(format, "shift_op")); 468 if (instr->TypeField() == 0) { 469 PrintShiftRm(instr); 470 } else { 471 ASSERT(instr->TypeField() == 1); 472 PrintShiftImm(instr); 473 } 474 return 8; 475 } else { // 'shift_rm 476 ASSERT(STRING_STARTS_WITH(format, "shift_rm")); 477 PrintShiftRm(instr); 478 return 8; 479 } 480 } else if (format[1] == 'w') { // 'swi 481 ASSERT(STRING_STARTS_WITH(format, "swi")); 482 PrintSoftwareInterrupt(instr->SwiField()); 483 return 3; 484 } else if (format[1] == 'i') { // 'sign: signed extra loads and stores 485 ASSERT(STRING_STARTS_WITH(format, "sign")); 486 if (instr->HasSign()) { 487 Print("s"); 488 } 489 return 4; 490 } 491 // 's: S field of data processing instructions 492 if (instr->HasS()) { 493 Print("s"); 494 } 495 return 1; 496 } 497 case 't': { // 'target: target of branch instructions 498 ASSERT(STRING_STARTS_WITH(format, "target")); 499 int off = (instr->SImmed24Field() << 2) + 8; 500 out_buffer_pos_ += v8i::OS::SNPrintF( 501 out_buffer_ + out_buffer_pos_, 502 "%+d -> %s", 503 off, 504 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off)); 505 return 6; 506 } 507 case 'u': { // 'u: signed or unsigned multiplies 508 // The manual gets the meaning of bit 22 backwards in the multiply 509 // instruction overview on page A3.16.2. The instructions that 510 // exist in u and s variants are the following: 511 // smull A4.1.87 512 // umull A4.1.129 513 // umlal A4.1.128 514 // smlal A4.1.76 515 // For these 0 means u and 1 means s. As can be seen on their individual 516 // pages. The other 18 mul instructions have the bit set or unset in 517 // arbitrary ways that are unrelated to the signedness of the instruction. 518 // None of these 18 instructions exist in both a 'u' and an 's' variant. 519 520 if (instr->Bit(22) == 0) { 521 Print("u"); 522 } else { 523 Print("s"); 524 } 525 return 1; 526 } 527 case 'v': { 528 return FormatVFPinstruction(instr, format); 529 } 530 case 'S': 531 case 'D': { 532 return FormatVFPRegister(instr, format); 533 } 534 case 'w': { // 'w: W field of load and store instructions 535 if (instr->HasW()) { 536 Print("!"); 537 } 538 return 1; 539 } 540 default: { 541 UNREACHABLE(); 542 break; 543 } 544 } 545 UNREACHABLE(); 546 return -1; 547} 548 549 550// Format takes a formatting string for a whole instruction and prints it into 551// the output buffer. All escaped options are handed to FormatOption to be 552// parsed further. 553void Decoder::Format(Instr* instr, const char* format) { 554 char cur = *format++; 555 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 556 if (cur == '\'') { // Single quote is used as the formatting escape. 557 format += FormatOption(instr, format); 558 } else { 559 out_buffer_[out_buffer_pos_++] = cur; 560 } 561 cur = *format++; 562 } 563 out_buffer_[out_buffer_pos_] = '\0'; 564} 565 566 567// For currently unimplemented decodings the disassembler calls Unknown(instr) 568// which will just print "unknown" of the instruction bits. 569void Decoder::Unknown(Instr* instr) { 570 Format(instr, "unknown"); 571} 572 573 574void Decoder::DecodeType01(Instr* instr) { 575 int type = instr->TypeField(); 576 if ((type == 0) && instr->IsSpecialType0()) { 577 // multiply instruction or extra loads and stores 578 if (instr->Bits(7, 4) == 9) { 579 if (instr->Bit(24) == 0) { 580 // multiply instructions 581 if (instr->Bit(23) == 0) { 582 if (instr->Bit(21) == 0) { 583 // The MUL instruction description (A 4.1.33) refers to Rd as being 584 // the destination for the operation, but it confusingly uses the 585 // Rn field to encode it. 586 Format(instr, "mul'cond's 'rn, 'rm, 'rs"); 587 } else { 588 // The MLA instruction description (A 4.1.28) refers to the order 589 // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the 590 // Rn field to encode the Rd register and the Rd field to encode 591 // the Rn register. 592 Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd"); 593 } 594 } else { 595 // The signed/long multiply instructions use the terms RdHi and RdLo 596 // when referring to the target registers. They are mapped to the Rn 597 // and Rd fields as follows: 598 // RdLo == Rd field 599 // RdHi == Rn field 600 // The order of registers is: <RdLo>, <RdHi>, <Rm>, <Rs> 601 Format(instr, "'um'al'cond's 'rd, 'rn, 'rm, 'rs"); 602 } 603 } else { 604 Unknown(instr); // not used by V8 605 } 606 } else { 607 // extra load/store instructions 608 switch (instr->PUField()) { 609 case 0: { 610 if (instr->Bit(22) == 0) { 611 Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm"); 612 } else { 613 Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8"); 614 } 615 break; 616 } 617 case 1: { 618 if (instr->Bit(22) == 0) { 619 Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm"); 620 } else { 621 Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8"); 622 } 623 break; 624 } 625 case 2: { 626 if (instr->Bit(22) == 0) { 627 Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w"); 628 } else { 629 Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w"); 630 } 631 break; 632 } 633 case 3: { 634 if (instr->Bit(22) == 0) { 635 Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w"); 636 } else { 637 Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w"); 638 } 639 break; 640 } 641 default: { 642 // The PU field is a 2-bit field. 643 UNREACHABLE(); 644 break; 645 } 646 } 647 return; 648 } 649 } else { 650 switch (instr->OpcodeField()) { 651 case AND: { 652 Format(instr, "and'cond's 'rd, 'rn, 'shift_op"); 653 break; 654 } 655 case EOR: { 656 Format(instr, "eor'cond's 'rd, 'rn, 'shift_op"); 657 break; 658 } 659 case SUB: { 660 Format(instr, "sub'cond's 'rd, 'rn, 'shift_op"); 661 break; 662 } 663 case RSB: { 664 Format(instr, "rsb'cond's 'rd, 'rn, 'shift_op"); 665 break; 666 } 667 case ADD: { 668 Format(instr, "add'cond's 'rd, 'rn, 'shift_op"); 669 break; 670 } 671 case ADC: { 672 Format(instr, "adc'cond's 'rd, 'rn, 'shift_op"); 673 break; 674 } 675 case SBC: { 676 Format(instr, "sbc'cond's 'rd, 'rn, 'shift_op"); 677 break; 678 } 679 case RSC: { 680 Format(instr, "rsc'cond's 'rd, 'rn, 'shift_op"); 681 break; 682 } 683 case TST: { 684 if (instr->HasS()) { 685 Format(instr, "tst'cond 'rn, 'shift_op"); 686 } else { 687 Unknown(instr); // not used by V8 688 } 689 break; 690 } 691 case TEQ: { 692 if (instr->HasS()) { 693 Format(instr, "teq'cond 'rn, 'shift_op"); 694 } else { 695 switch (instr->Bits(7, 4)) { 696 case BX: 697 Format(instr, "bx'cond 'rm"); 698 break; 699 case BLX: 700 Format(instr, "blx'cond 'rm"); 701 break; 702 default: 703 Unknown(instr); // not used by V8 704 break; 705 } 706 } 707 break; 708 } 709 case CMP: { 710 if (instr->HasS()) { 711 Format(instr, "cmp'cond 'rn, 'shift_op"); 712 } else { 713 Unknown(instr); // not used by V8 714 } 715 break; 716 } 717 case CMN: { 718 if (instr->HasS()) { 719 Format(instr, "cmn'cond 'rn, 'shift_op"); 720 } else { 721 switch (instr->Bits(7, 4)) { 722 case CLZ: 723 Format(instr, "clz'cond 'rd, 'rm"); 724 break; 725 default: 726 Unknown(instr); // not used by V8 727 break; 728 } 729 } 730 break; 731 } 732 case ORR: { 733 Format(instr, "orr'cond's 'rd, 'rn, 'shift_op"); 734 break; 735 } 736 case MOV: { 737 Format(instr, "mov'cond's 'rd, 'shift_op"); 738 break; 739 } 740 case BIC: { 741 Format(instr, "bic'cond's 'rd, 'rn, 'shift_op"); 742 break; 743 } 744 case MVN: { 745 Format(instr, "mvn'cond's 'rd, 'shift_op"); 746 break; 747 } 748 default: { 749 // The Opcode field is a 4-bit field. 750 UNREACHABLE(); 751 break; 752 } 753 } 754 } 755} 756 757 758void Decoder::DecodeType2(Instr* instr) { 759 switch (instr->PUField()) { 760 case 0: { 761 if (instr->HasW()) { 762 Unknown(instr); // not used in V8 763 } 764 Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12"); 765 break; 766 } 767 case 1: { 768 if (instr->HasW()) { 769 Unknown(instr); // not used in V8 770 } 771 Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12"); 772 break; 773 } 774 case 2: { 775 Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w"); 776 break; 777 } 778 case 3: { 779 Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w"); 780 break; 781 } 782 default: { 783 // The PU field is a 2-bit field. 784 UNREACHABLE(); 785 break; 786 } 787 } 788} 789 790 791void Decoder::DecodeType3(Instr* instr) { 792 switch (instr->PUField()) { 793 case 0: { 794 ASSERT(!instr->HasW()); 795 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm"); 796 break; 797 } 798 case 1: { 799 ASSERT(!instr->HasW()); 800 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm"); 801 break; 802 } 803 case 2: { 804 Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w"); 805 break; 806 } 807 case 3: { 808 if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) { 809 uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16)); 810 uint32_t lsbit = static_cast<uint32_t>(instr->ShiftAmountField()); 811 uint32_t msbit = widthminus1 + lsbit; 812 if (msbit <= 31) { 813 Format(instr, "ubfx'cond 'rd, 'rm, #'off7to11, #'off16to20"); 814 } else { 815 UNREACHABLE(); 816 } 817 } else { 818 Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w"); 819 } 820 break; 821 } 822 default: { 823 // The PU field is a 2-bit field. 824 UNREACHABLE(); 825 break; 826 } 827 } 828} 829 830 831void Decoder::DecodeType4(Instr* instr) { 832 ASSERT(instr->Bit(22) == 0); // Privileged mode currently not supported. 833 if (instr->HasL()) { 834 Format(instr, "ldm'cond'pu 'rn'w, 'rlist"); 835 } else { 836 Format(instr, "stm'cond'pu 'rn'w, 'rlist"); 837 } 838} 839 840 841void Decoder::DecodeType5(Instr* instr) { 842 Format(instr, "b'l'cond 'target"); 843} 844 845 846void Decoder::DecodeType6(Instr* instr) { 847 DecodeType6CoprocessorIns(instr); 848} 849 850 851void Decoder::DecodeType7(Instr* instr) { 852 if (instr->Bit(24) == 1) { 853 Format(instr, "swi'cond 'swi"); 854 } else { 855 DecodeTypeVFP(instr); 856 } 857} 858 859void Decoder::DecodeUnconditional(Instr* instr) { 860 if (instr->Bits(7, 4) == 0xB && instr->Bits(27, 25) == 0 && instr->HasL()) { 861 Format(instr, "'memop'h'pu 'rd, "); 862 bool immediate = instr->HasB(); 863 switch (instr->PUField()) { 864 case 0: { 865 // Post index, negative. 866 if (instr->HasW()) { 867 Unknown(instr); 868 break; 869 } 870 if (immediate) { 871 Format(instr, "['rn], #-'imm12"); 872 } else { 873 Format(instr, "['rn], -'rm"); 874 } 875 break; 876 } 877 case 1: { 878 // Post index, positive. 879 if (instr->HasW()) { 880 Unknown(instr); 881 break; 882 } 883 if (immediate) { 884 Format(instr, "['rn], #+'imm12"); 885 } else { 886 Format(instr, "['rn], +'rm"); 887 } 888 break; 889 } 890 case 2: { 891 // Pre index or offset, negative. 892 if (immediate) { 893 Format(instr, "['rn, #-'imm12]'w"); 894 } else { 895 Format(instr, "['rn, -'rm]'w"); 896 } 897 break; 898 } 899 case 3: { 900 // Pre index or offset, positive. 901 if (immediate) { 902 Format(instr, "['rn, #+'imm12]'w"); 903 } else { 904 Format(instr, "['rn, +'rm]'w"); 905 } 906 break; 907 } 908 default: { 909 // The PU field is a 2-bit field. 910 UNREACHABLE(); 911 break; 912 } 913 } 914 return; 915 } 916 Format(instr, "break 'msg"); 917} 918 919 920// void Decoder::DecodeTypeVFP(Instr* instr) 921// vmov: Sn = Rt 922// vmov: Rt = Sn 923// vcvt: Dd = Sm 924// vcvt: Sd = Dm 925// Dd = vadd(Dn, Dm) 926// Dd = vsub(Dn, Dm) 927// Dd = vmul(Dn, Dm) 928// Dd = vdiv(Dn, Dm) 929// vcmp(Dd, Dm) 930// VMRS 931void Decoder::DecodeTypeVFP(Instr* instr) { 932 ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) ); 933 934 if (instr->Bit(23) == 1) { 935 if ((instr->Bits(21, 19) == 0x7) && 936 (instr->Bits(18, 16) == 0x5) && 937 (instr->Bits(11, 9) == 0x5) && 938 (instr->Bit(8) == 1) && 939 (instr->Bit(6) == 1) && 940 (instr->Bit(4) == 0)) { 941 Format(instr, "vcvt.s32.f64'cond 'Sd, 'Dm"); 942 } else if ((instr->Bits(21, 19) == 0x7) && 943 (instr->Bits(18, 16) == 0x0) && 944 (instr->Bits(11, 9) == 0x5) && 945 (instr->Bit(8) == 1) && 946 (instr->Bit(7) == 1) && 947 (instr->Bit(6) == 1) && 948 (instr->Bit(4) == 0)) { 949 Format(instr, "vcvt.f64.s32'cond 'Dd, 'Sm"); 950 } else if ((instr->Bit(21) == 0x0) && 951 (instr->Bit(20) == 0x0) && 952 (instr->Bits(11, 9) == 0x5) && 953 (instr->Bit(8) == 1) && 954 (instr->Bit(6) == 0) && 955 (instr->Bit(4) == 0)) { 956 Format(instr, "vdiv.f64'cond 'Dd, 'Dn, 'Dm"); 957 } else if ((instr->Bits(21, 20) == 0x3) && 958 (instr->Bits(19, 16) == 0x4) && 959 (instr->Bits(11, 9) == 0x5) && 960 (instr->Bit(8) == 0x1) && 961 (instr->Bit(6) == 0x1) && 962 (instr->Bit(4) == 0x0)) { 963 Format(instr, "vcmp.f64'cond 'Dd, 'Dm"); 964 } else if ((instr->Bits(23, 20) == 0xF) && 965 (instr->Bits(19, 16) == 0x1) && 966 (instr->Bits(11, 8) == 0xA) && 967 (instr->Bits(7, 5) == 0x0) && 968 (instr->Bit(4) == 0x1) && 969 (instr->Bits(3, 0) == 0x0)) { 970 if (instr->Bits(15, 12) == 0xF) 971 Format(instr, "vmrs'cond APSR, FPSCR"); 972 else 973 Unknown(instr); // Not used by V8. 974 } else { 975 Unknown(instr); // Not used by V8. 976 } 977 } else if (instr->Bit(21) == 1) { 978 if ((instr->Bit(20) == 0x1) && 979 (instr->Bits(11, 9) == 0x5) && 980 (instr->Bit(8) == 0x1) && 981 (instr->Bit(6) == 0) && 982 (instr->Bit(4) == 0)) { 983 Format(instr, "vadd.f64'cond 'Dd, 'Dn, 'Dm"); 984 } else if ((instr->Bit(20) == 0x1) && 985 (instr->Bits(11, 9) == 0x5) && 986 (instr->Bit(8) == 0x1) && 987 (instr->Bit(6) == 1) && 988 (instr->Bit(4) == 0)) { 989 Format(instr, "vsub.f64'cond 'Dd, 'Dn, 'Dm"); 990 } else if ((instr->Bit(20) == 0x0) && 991 (instr->Bits(11, 9) == 0x5) && 992 (instr->Bit(8) == 0x1) && 993 (instr->Bit(6) == 0) && 994 (instr->Bit(4) == 0)) { 995 Format(instr, "vmul.f64'cond 'Dd, 'Dn, 'Dm"); 996 } else { 997 Unknown(instr); // Not used by V8. 998 } 999 } else { 1000 if ((instr->Bit(20) == 0x0) && 1001 (instr->Bits(11, 8) == 0xA) && 1002 (instr->Bits(6, 5) == 0x0) && 1003 (instr->Bit(4) == 1) && 1004 (instr->Bits(3, 0) == 0x0)) { 1005 Format(instr, "vmov'cond 'Sn, 'rt"); 1006 } else if ((instr->Bit(20) == 0x1) && 1007 (instr->Bits(11, 8) == 0xA) && 1008 (instr->Bits(6, 5) == 0x0) && 1009 (instr->Bit(4) == 1) && 1010 (instr->Bits(3, 0) == 0x0)) { 1011 Format(instr, "vmov'cond 'rt, 'Sn"); 1012 } else { 1013 Unknown(instr); // Not used by V8. 1014 } 1015 } 1016} 1017 1018 1019// Decode Type 6 coprocessor instructions. 1020// Dm = vmov(Rt, Rt2) 1021// <Rt, Rt2> = vmov(Dm) 1022// Ddst = MEM(Rbase + 4*offset). 1023// MEM(Rbase + 4*offset) = Dsrc. 1024void Decoder::DecodeType6CoprocessorIns(Instr* instr) { 1025 ASSERT((instr->TypeField() == 6)); 1026 1027 if (instr->CoprocessorField() != 0xB) { 1028 Unknown(instr); // Not used by V8. 1029 } else { 1030 switch (instr->OpcodeField()) { 1031 case 0x2: 1032 // Load and store double to two GP registers 1033 if (instr->Bits(7, 4) != 0x1) { 1034 Unknown(instr); // Not used by V8. 1035 } else if (instr->HasL()) { 1036 Format(instr, "vmov'cond 'rt, 'rn, 'Dm"); 1037 } else { 1038 Format(instr, "vmov'cond 'Dm, 'rt, 'rn"); 1039 } 1040 break; 1041 case 0x8: 1042 if (instr->HasL()) { 1043 Format(instr, "vldr'cond 'Dd, ['rn - 4*'off8]"); 1044 } else { 1045 Format(instr, "vstr'cond 'Dd, ['rn - 4*'off8]"); 1046 } 1047 break; 1048 case 0xC: 1049 if (instr->HasL()) { 1050 Format(instr, "vldr'cond 'Dd, ['rn + 4*'off8]"); 1051 } else { 1052 Format(instr, "vstr'cond 'Dd, ['rn + 4*'off8]"); 1053 } 1054 break; 1055 default: 1056 Unknown(instr); // Not used by V8. 1057 break; 1058 } 1059 } 1060} 1061 1062 1063// Disassemble the instruction at *instr_ptr into the output buffer. 1064int Decoder::InstructionDecode(byte* instr_ptr) { 1065 Instr* instr = Instr::At(instr_ptr); 1066 // Print raw instruction bytes. 1067 out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_, 1068 "%08x ", 1069 instr->InstructionBits()); 1070 if (instr->ConditionField() == special_condition) { 1071 DecodeUnconditional(instr); 1072 return Instr::kInstrSize; 1073 } 1074 switch (instr->TypeField()) { 1075 case 0: 1076 case 1: { 1077 DecodeType01(instr); 1078 break; 1079 } 1080 case 2: { 1081 DecodeType2(instr); 1082 break; 1083 } 1084 case 3: { 1085 DecodeType3(instr); 1086 break; 1087 } 1088 case 4: { 1089 DecodeType4(instr); 1090 break; 1091 } 1092 case 5: { 1093 DecodeType5(instr); 1094 break; 1095 } 1096 case 6: { 1097 DecodeType6(instr); 1098 break; 1099 } 1100 case 7: { 1101 DecodeType7(instr); 1102 break; 1103 } 1104 default: { 1105 // The type field is 3-bits in the ARM encoding. 1106 UNREACHABLE(); 1107 break; 1108 } 1109 } 1110 return Instr::kInstrSize; 1111} 1112 1113 1114} } // namespace assembler::arm 1115 1116 1117 1118//------------------------------------------------------------------------------ 1119 1120namespace disasm { 1121 1122namespace v8i = v8::internal; 1123 1124 1125const char* NameConverter::NameOfAddress(byte* addr) const { 1126 static v8::internal::EmbeddedVector<char, 32> tmp_buffer; 1127 v8::internal::OS::SNPrintF(tmp_buffer, "%p", addr); 1128 return tmp_buffer.start(); 1129} 1130 1131 1132const char* NameConverter::NameOfConstant(byte* addr) const { 1133 return NameOfAddress(addr); 1134} 1135 1136 1137const char* NameConverter::NameOfCPURegister(int reg) const { 1138 return assembler::arm::Registers::Name(reg); 1139} 1140 1141 1142const char* NameConverter::NameOfByteCPURegister(int reg) const { 1143 UNREACHABLE(); // ARM does not have the concept of a byte register 1144 return "nobytereg"; 1145} 1146 1147 1148const char* NameConverter::NameOfXMMRegister(int reg) const { 1149 UNREACHABLE(); // ARM does not have any XMM registers 1150 return "noxmmreg"; 1151} 1152 1153 1154const char* NameConverter::NameInCode(byte* addr) const { 1155 // The default name converter is called for unknown code. So we will not try 1156 // to access any memory. 1157 return ""; 1158} 1159 1160 1161//------------------------------------------------------------------------------ 1162 1163Disassembler::Disassembler(const NameConverter& converter) 1164 : converter_(converter) {} 1165 1166 1167Disassembler::~Disassembler() {} 1168 1169 1170int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, 1171 byte* instruction) { 1172 assembler::arm::Decoder d(converter_, buffer); 1173 return d.InstructionDecode(instruction); 1174} 1175 1176 1177int Disassembler::ConstantPoolSizeAt(byte* instruction) { 1178 int instruction_bits = *(reinterpret_cast<int*>(instruction)); 1179 if ((instruction_bits & 0xfff00000) == 0x03000000) { 1180 return instruction_bits & 0x0000ffff; 1181 } else { 1182 return -1; 1183 } 1184} 1185 1186 1187void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { 1188 NameConverter converter; 1189 Disassembler d(converter); 1190 for (byte* pc = begin; pc < end;) { 1191 v8::internal::EmbeddedVector<char, 128> buffer; 1192 buffer[0] = '\0'; 1193 byte* prev_pc = pc; 1194 pc += d.InstructionDecode(buffer, pc); 1195 fprintf(f, "%p %08x %s\n", 1196 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); 1197 } 1198} 1199 1200 1201} // namespace disasm 1202