1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 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 7 // overriden to modify register names or to do symbol lookup on addresses. 8 // 9 // The example below will disassemble a block of code and print it to stdout. 10 // 11 // NameConverter converter; 12 // Disassembler d(converter); 13 // for (byte* pc = begin; pc < end;) { 14 // v8::internal::EmbeddedVector<char, 256> buffer; 15 // byte* prev_pc = pc; 16 // pc += d.InstructionDecode(buffer, pc); 17 // printf("%p %08x %s\n", 18 // prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer); 19 // } 20 // 21 // The Disassembler class also has a convenience method to disassemble a block 22 // of code into a FILE*, meaning that the above functionality could also be 23 // achieved by just calling Disassembler::Disassemble(stdout, begin, end); 24 25 26 #include <assert.h> 27 #include <stdarg.h> 28 #include <stdio.h> 29 #include <string.h> 30 31 #include "src/v8.h" 32 33 #if V8_TARGET_ARCH_ARM 34 35 #include "src/arm/constants-arm.h" 36 #include "src/base/platform/platform.h" 37 #include "src/disasm.h" 38 #include "src/macro-assembler.h" 39 40 41 namespace v8 { 42 namespace internal { 43 44 45 //------------------------------------------------------------------------------ 46 47 // Decoder decodes and disassembles instructions into an output buffer. 48 // It uses the converter to convert register names and call destinations into 49 // more informative description. 50 class Decoder { 51 public: 52 Decoder(const disasm::NameConverter& converter, 53 Vector<char> out_buffer) 54 : converter_(converter), 55 out_buffer_(out_buffer), 56 out_buffer_pos_(0) { 57 out_buffer_[out_buffer_pos_] = '\0'; 58 } 59 60 ~Decoder() {} 61 62 // Writes one disassembled instruction into 'buffer' (0-terminated). 63 // Returns the length of the disassembled machine instruction in bytes. 64 int InstructionDecode(byte* instruction); 65 66 static bool IsConstantPoolAt(byte* instr_ptr); 67 static int ConstantPoolSizeAt(byte* instr_ptr); 68 69 private: 70 // Bottleneck functions to print into the out_buffer. 71 void PrintChar(const char ch); 72 void Print(const char* str); 73 74 // Printing of common values. 75 void PrintRegister(int reg); 76 void PrintSRegister(int reg); 77 void PrintDRegister(int reg); 78 int FormatVFPRegister(Instruction* instr, const char* format); 79 void PrintMovwMovt(Instruction* instr); 80 int FormatVFPinstruction(Instruction* instr, const char* format); 81 void PrintCondition(Instruction* instr); 82 void PrintShiftRm(Instruction* instr); 83 void PrintShiftImm(Instruction* instr); 84 void PrintShiftSat(Instruction* instr); 85 void PrintPU(Instruction* instr); 86 void PrintSoftwareInterrupt(SoftwareInterruptCodes svc); 87 88 // Handle formatting of instructions and their options. 89 int FormatRegister(Instruction* instr, const char* option); 90 void FormatNeonList(int Vd, int type); 91 void FormatNeonMemory(int Rn, int align, int Rm); 92 int FormatOption(Instruction* instr, const char* option); 93 void Format(Instruction* instr, const char* format); 94 void Unknown(Instruction* instr); 95 96 // Each of these functions decodes one particular instruction type, a 3-bit 97 // field in the instruction encoding. 98 // Types 0 and 1 are combined as they are largely the same except for the way 99 // they interpret the shifter operand. 100 void DecodeType01(Instruction* instr); 101 void DecodeType2(Instruction* instr); 102 void DecodeType3(Instruction* instr); 103 void DecodeType4(Instruction* instr); 104 void DecodeType5(Instruction* instr); 105 void DecodeType6(Instruction* instr); 106 // Type 7 includes special Debugger instructions. 107 int DecodeType7(Instruction* instr); 108 // For VFP support. 109 void DecodeTypeVFP(Instruction* instr); 110 void DecodeType6CoprocessorIns(Instruction* instr); 111 112 void DecodeSpecialCondition(Instruction* instr); 113 114 void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instruction* instr); 115 void DecodeVCMP(Instruction* instr); 116 void DecodeVCVTBetweenDoubleAndSingle(Instruction* instr); 117 void DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr); 118 119 const disasm::NameConverter& converter_; 120 Vector<char> out_buffer_; 121 int out_buffer_pos_; 122 123 DISALLOW_COPY_AND_ASSIGN(Decoder); 124 }; 125 126 127 // Support for assertions in the Decoder formatting functions. 128 #define STRING_STARTS_WITH(string, compare_string) \ 129 (strncmp(string, compare_string, strlen(compare_string)) == 0) 130 131 132 // Append the ch to the output buffer. 133 void Decoder::PrintChar(const char ch) { 134 out_buffer_[out_buffer_pos_++] = ch; 135 } 136 137 138 // Append the str to the output buffer. 139 void Decoder::Print(const char* str) { 140 char cur = *str++; 141 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 142 PrintChar(cur); 143 cur = *str++; 144 } 145 out_buffer_[out_buffer_pos_] = 0; 146 } 147 148 149 // These condition names are defined in a way to match the native disassembler 150 // formatting. See for example the command "objdump -d <binary file>". 151 static const char* cond_names[kNumberOfConditions] = { 152 "eq", "ne", "cs" , "cc" , "mi" , "pl" , "vs" , "vc" , 153 "hi", "ls", "ge", "lt", "gt", "le", "", "invalid", 154 }; 155 156 157 // Print the condition guarding the instruction. 158 void Decoder::PrintCondition(Instruction* instr) { 159 Print(cond_names[instr->ConditionValue()]); 160 } 161 162 163 // Print the register name according to the active name converter. 164 void Decoder::PrintRegister(int reg) { 165 Print(converter_.NameOfCPURegister(reg)); 166 } 167 168 169 // Print the VFP S register name according to the active name converter. 170 void Decoder::PrintSRegister(int reg) { 171 Print(VFPRegisters::Name(reg, false)); 172 } 173 174 175 // Print the VFP D register name according to the active name converter. 176 void Decoder::PrintDRegister(int reg) { 177 Print(VFPRegisters::Name(reg, true)); 178 } 179 180 181 // These shift names are defined in a way to match the native disassembler 182 // formatting. See for example the command "objdump -d <binary file>". 183 static const char* const shift_names[kNumberOfShifts] = { 184 "lsl", "lsr", "asr", "ror" 185 }; 186 187 188 // Print the register shift operands for the instruction. Generally used for 189 // data processing instructions. 190 void Decoder::PrintShiftRm(Instruction* instr) { 191 ShiftOp shift = instr->ShiftField(); 192 int shift_index = instr->ShiftValue(); 193 int shift_amount = instr->ShiftAmountValue(); 194 int rm = instr->RmValue(); 195 196 PrintRegister(rm); 197 198 if ((instr->RegShiftValue() == 0) && (shift == LSL) && (shift_amount == 0)) { 199 // Special case for using rm only. 200 return; 201 } 202 if (instr->RegShiftValue() == 0) { 203 // by immediate 204 if ((shift == ROR) && (shift_amount == 0)) { 205 Print(", RRX"); 206 return; 207 } else if (((shift == LSR) || (shift == ASR)) && (shift_amount == 0)) { 208 shift_amount = 32; 209 } 210 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 211 ", %s #%d", 212 shift_names[shift_index], 213 shift_amount); 214 } else { 215 // by register 216 int rs = instr->RsValue(); 217 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 218 ", %s ", shift_names[shift_index]); 219 PrintRegister(rs); 220 } 221 } 222 223 224 // Print the immediate operand for the instruction. Generally used for data 225 // processing instructions. 226 void Decoder::PrintShiftImm(Instruction* instr) { 227 int rotate = instr->RotateValue() * 2; 228 int immed8 = instr->Immed8Value(); 229 int imm = (immed8 >> rotate) | (immed8 << (32 - rotate)); 230 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "#%d", imm); 231 } 232 233 234 // Print the optional shift and immediate used by saturating instructions. 235 void Decoder::PrintShiftSat(Instruction* instr) { 236 int shift = instr->Bits(11, 7); 237 if (shift > 0) { 238 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 239 ", %s #%d", 240 shift_names[instr->Bit(6) * 2], 241 instr->Bits(11, 7)); 242 } 243 } 244 245 246 // Print PU formatting to reduce complexity of FormatOption. 247 void Decoder::PrintPU(Instruction* instr) { 248 switch (instr->PUField()) { 249 case da_x: { 250 Print("da"); 251 break; 252 } 253 case ia_x: { 254 Print("ia"); 255 break; 256 } 257 case db_x: { 258 Print("db"); 259 break; 260 } 261 case ib_x: { 262 Print("ib"); 263 break; 264 } 265 default: { 266 UNREACHABLE(); 267 break; 268 } 269 } 270 } 271 272 273 // Print SoftwareInterrupt codes. Factoring this out reduces the complexity of 274 // the FormatOption method. 275 void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) { 276 switch (svc) { 277 case kCallRtRedirected: 278 Print("call rt redirected"); 279 return; 280 case kBreakpoint: 281 Print("breakpoint"); 282 return; 283 default: 284 if (svc >= kStopCode) { 285 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 286 "%d - 0x%x", 287 svc & kStopCodeMask, 288 svc & kStopCodeMask); 289 } else { 290 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 291 "%d", 292 svc); 293 } 294 return; 295 } 296 } 297 298 299 // Handle all register based formatting in this function to reduce the 300 // complexity of FormatOption. 301 int Decoder::FormatRegister(Instruction* instr, const char* format) { 302 DCHECK(format[0] == 'r'); 303 if (format[1] == 'n') { // 'rn: Rn register 304 int reg = instr->RnValue(); 305 PrintRegister(reg); 306 return 2; 307 } else if (format[1] == 'd') { // 'rd: Rd register 308 int reg = instr->RdValue(); 309 PrintRegister(reg); 310 return 2; 311 } else if (format[1] == 's') { // 'rs: Rs register 312 int reg = instr->RsValue(); 313 PrintRegister(reg); 314 return 2; 315 } else if (format[1] == 'm') { // 'rm: Rm register 316 int reg = instr->RmValue(); 317 PrintRegister(reg); 318 return 2; 319 } else if (format[1] == 't') { // 'rt: Rt register 320 int reg = instr->RtValue(); 321 PrintRegister(reg); 322 return 2; 323 } else if (format[1] == 'l') { 324 // 'rlist: register list for load and store multiple instructions 325 DCHECK(STRING_STARTS_WITH(format, "rlist")); 326 int rlist = instr->RlistValue(); 327 int reg = 0; 328 Print("{"); 329 // Print register list in ascending order, by scanning the bit mask. 330 while (rlist != 0) { 331 if ((rlist & 1) != 0) { 332 PrintRegister(reg); 333 if ((rlist >> 1) != 0) { 334 Print(", "); 335 } 336 } 337 reg++; 338 rlist >>= 1; 339 } 340 Print("}"); 341 return 5; 342 } 343 UNREACHABLE(); 344 return -1; 345 } 346 347 348 // Handle all VFP register based formatting in this function to reduce the 349 // complexity of FormatOption. 350 int Decoder::FormatVFPRegister(Instruction* instr, const char* format) { 351 DCHECK((format[0] == 'S') || (format[0] == 'D')); 352 353 VFPRegPrecision precision = 354 format[0] == 'D' ? kDoublePrecision : kSinglePrecision; 355 356 int retval = 2; 357 int reg = -1; 358 if (format[1] == 'n') { 359 reg = instr->VFPNRegValue(precision); 360 } else if (format[1] == 'm') { 361 reg = instr->VFPMRegValue(precision); 362 } else if (format[1] == 'd') { 363 if ((instr->TypeValue() == 7) && 364 (instr->Bit(24) == 0x0) && 365 (instr->Bits(11, 9) == 0x5) && 366 (instr->Bit(4) == 0x1)) { 367 // vmov.32 has Vd in a different place. 368 reg = instr->Bits(19, 16) | (instr->Bit(7) << 4); 369 } else { 370 reg = instr->VFPDRegValue(precision); 371 } 372 373 if (format[2] == '+') { 374 int immed8 = instr->Immed8Value(); 375 if (format[0] == 'S') reg += immed8 - 1; 376 if (format[0] == 'D') reg += (immed8 / 2 - 1); 377 } 378 if (format[2] == '+') retval = 3; 379 } else { 380 UNREACHABLE(); 381 } 382 383 if (precision == kSinglePrecision) { 384 PrintSRegister(reg); 385 } else { 386 PrintDRegister(reg); 387 } 388 389 return retval; 390 } 391 392 393 int Decoder::FormatVFPinstruction(Instruction* instr, const char* format) { 394 Print(format); 395 return 0; 396 } 397 398 399 void Decoder::FormatNeonList(int Vd, int type) { 400 if (type == nlt_1) { 401 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 402 "{d%d}", Vd); 403 } else if (type == nlt_2) { 404 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 405 "{d%d, d%d}", Vd, Vd + 1); 406 } else if (type == nlt_3) { 407 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 408 "{d%d, d%d, d%d}", Vd, Vd + 1, Vd + 2); 409 } else if (type == nlt_4) { 410 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 411 "{d%d, d%d, d%d, d%d}", Vd, Vd + 1, Vd + 2, Vd + 3); 412 } 413 } 414 415 416 void Decoder::FormatNeonMemory(int Rn, int align, int Rm) { 417 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 418 "[r%d", Rn); 419 if (align != 0) { 420 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 421 ":%d", (1 << align) << 6); 422 } 423 if (Rm == 15) { 424 Print("]"); 425 } else if (Rm == 13) { 426 Print("]!"); 427 } else { 428 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 429 "], r%d", Rm); 430 } 431 } 432 433 434 // Print the movw or movt instruction. 435 void Decoder::PrintMovwMovt(Instruction* instr) { 436 int imm = instr->ImmedMovwMovtValue(); 437 int rd = instr->RdValue(); 438 PrintRegister(rd); 439 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, ", #%d", imm); 440 } 441 442 443 // FormatOption takes a formatting string and interprets it based on 444 // the current instructions. The format string points to the first 445 // character of the option string (the option escape has already been 446 // consumed by the caller.) FormatOption returns the number of 447 // characters that were consumed from the formatting string. 448 int Decoder::FormatOption(Instruction* instr, const char* format) { 449 switch (format[0]) { 450 case 'a': { // 'a: accumulate multiplies 451 if (instr->Bit(21) == 0) { 452 Print("ul"); 453 } else { 454 Print("la"); 455 } 456 return 1; 457 } 458 case 'b': { // 'b: byte loads or stores 459 if (instr->HasB()) { 460 Print("b"); 461 } 462 return 1; 463 } 464 case 'c': { // 'cond: conditional execution 465 DCHECK(STRING_STARTS_WITH(format, "cond")); 466 PrintCondition(instr); 467 return 4; 468 } 469 case 'd': { // 'd: vmov double immediate. 470 double d = instr->DoubleImmedVmov(); 471 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "#%g", d); 472 return 1; 473 } 474 case 'f': { // 'f: bitfield instructions - v7 and above. 475 uint32_t lsbit = instr->Bits(11, 7); 476 uint32_t width = instr->Bits(20, 16) + 1; 477 if (instr->Bit(21) == 0) { 478 // BFC/BFI: 479 // Bits 20-16 represent most-significant bit. Covert to width. 480 width -= lsbit; 481 DCHECK(width > 0); 482 } 483 DCHECK((width + lsbit) <= 32); 484 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 485 "#%d, #%d", lsbit, width); 486 return 1; 487 } 488 case 'h': { // 'h: halfword operation for extra loads and stores 489 if (instr->HasH()) { 490 Print("h"); 491 } else { 492 Print("b"); 493 } 494 return 1; 495 } 496 case 'i': { // 'i: immediate value from adjacent bits. 497 // Expects tokens in the form imm%02d@%02d, i.e. imm05@07, imm10@16 498 int width = (format[3] - '0') * 10 + (format[4] - '0'); 499 int lsb = (format[6] - '0') * 10 + (format[7] - '0'); 500 501 DCHECK((width >= 1) && (width <= 32)); 502 DCHECK((lsb >= 0) && (lsb <= 31)); 503 DCHECK((width + lsb) <= 32); 504 505 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 506 "%d", 507 instr->Bits(width + lsb - 1, lsb)); 508 return 8; 509 } 510 case 'l': { // 'l: branch and link 511 if (instr->HasLink()) { 512 Print("l"); 513 } 514 return 1; 515 } 516 case 'm': { 517 if (format[1] == 'w') { 518 // 'mw: movt/movw instructions. 519 PrintMovwMovt(instr); 520 return 2; 521 } 522 if (format[1] == 'e') { // 'memop: load/store instructions. 523 DCHECK(STRING_STARTS_WITH(format, "memop")); 524 if (instr->HasL()) { 525 Print("ldr"); 526 } else { 527 if ((instr->Bits(27, 25) == 0) && (instr->Bit(20) == 0) && 528 (instr->Bits(7, 6) == 3) && (instr->Bit(4) == 1)) { 529 if (instr->Bit(5) == 1) { 530 Print("strd"); 531 } else { 532 Print("ldrd"); 533 } 534 return 5; 535 } 536 Print("str"); 537 } 538 return 5; 539 } 540 // 'msg: for simulator break instructions 541 DCHECK(STRING_STARTS_WITH(format, "msg")); 542 byte* str = 543 reinterpret_cast<byte*>(instr->InstructionBits() & 0x0fffffff); 544 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 545 "%s", converter_.NameInCode(str)); 546 return 3; 547 } 548 case 'o': { 549 if ((format[3] == '1') && (format[4] == '2')) { 550 // 'off12: 12-bit offset for load and store instructions 551 DCHECK(STRING_STARTS_WITH(format, "off12")); 552 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 553 "%d", instr->Offset12Value()); 554 return 5; 555 } else if (format[3] == '0') { 556 // 'off0to3and8to19 16-bit immediate encoded in bits 19-8 and 3-0. 557 DCHECK(STRING_STARTS_WITH(format, "off0to3and8to19")); 558 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 559 "%d", 560 (instr->Bits(19, 8) << 4) + 561 instr->Bits(3, 0)); 562 return 15; 563 } 564 // 'off8: 8-bit offset for extra load and store instructions 565 DCHECK(STRING_STARTS_WITH(format, "off8")); 566 int offs8 = (instr->ImmedHValue() << 4) | instr->ImmedLValue(); 567 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", offs8); 568 return 4; 569 } 570 case 'p': { // 'pu: P and U bits for load and store instructions 571 DCHECK(STRING_STARTS_WITH(format, "pu")); 572 PrintPU(instr); 573 return 2; 574 } 575 case 'r': { 576 return FormatRegister(instr, format); 577 } 578 case 's': { 579 if (format[1] == 'h') { // 'shift_op or 'shift_rm or 'shift_sat. 580 if (format[6] == 'o') { // 'shift_op 581 DCHECK(STRING_STARTS_WITH(format, "shift_op")); 582 if (instr->TypeValue() == 0) { 583 PrintShiftRm(instr); 584 } else { 585 DCHECK(instr->TypeValue() == 1); 586 PrintShiftImm(instr); 587 } 588 return 8; 589 } else if (format[6] == 's') { // 'shift_sat. 590 DCHECK(STRING_STARTS_WITH(format, "shift_sat")); 591 PrintShiftSat(instr); 592 return 9; 593 } else { // 'shift_rm 594 DCHECK(STRING_STARTS_WITH(format, "shift_rm")); 595 PrintShiftRm(instr); 596 return 8; 597 } 598 } else if (format[1] == 'v') { // 'svc 599 DCHECK(STRING_STARTS_WITH(format, "svc")); 600 PrintSoftwareInterrupt(instr->SvcValue()); 601 return 3; 602 } else if (format[1] == 'i') { // 'sign: signed extra loads and stores 603 DCHECK(STRING_STARTS_WITH(format, "sign")); 604 if (instr->HasSign()) { 605 Print("s"); 606 } 607 return 4; 608 } 609 // 's: S field of data processing instructions 610 if (instr->HasS()) { 611 Print("s"); 612 } 613 return 1; 614 } 615 case 't': { // 'target: target of branch instructions 616 DCHECK(STRING_STARTS_WITH(format, "target")); 617 int off = (instr->SImmed24Value() << 2) + 8; 618 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 619 "%+d -> %s", 620 off, 621 converter_.NameOfAddress( 622 reinterpret_cast<byte*>(instr) + off)); 623 return 6; 624 } 625 case 'u': { // 'u: signed or unsigned multiplies 626 // The manual gets the meaning of bit 22 backwards in the multiply 627 // instruction overview on page A3.16.2. The instructions that 628 // exist in u and s variants are the following: 629 // smull A4.1.87 630 // umull A4.1.129 631 // umlal A4.1.128 632 // smlal A4.1.76 633 // For these 0 means u and 1 means s. As can be seen on their individual 634 // pages. The other 18 mul instructions have the bit set or unset in 635 // arbitrary ways that are unrelated to the signedness of the instruction. 636 // None of these 18 instructions exist in both a 'u' and an 's' variant. 637 638 if (instr->Bit(22) == 0) { 639 Print("u"); 640 } else { 641 Print("s"); 642 } 643 return 1; 644 } 645 case 'v': { 646 return FormatVFPinstruction(instr, format); 647 } 648 case 'S': 649 case 'D': { 650 return FormatVFPRegister(instr, format); 651 } 652 case 'w': { // 'w: W field of load and store instructions 653 if (instr->HasW()) { 654 Print("!"); 655 } 656 return 1; 657 } 658 default: { 659 UNREACHABLE(); 660 break; 661 } 662 } 663 UNREACHABLE(); 664 return -1; 665 } 666 667 668 // Format takes a formatting string for a whole instruction and prints it into 669 // the output buffer. All escaped options are handed to FormatOption to be 670 // parsed further. 671 void Decoder::Format(Instruction* instr, const char* format) { 672 char cur = *format++; 673 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 674 if (cur == '\'') { // Single quote is used as the formatting escape. 675 format += FormatOption(instr, format); 676 } else { 677 out_buffer_[out_buffer_pos_++] = cur; 678 } 679 cur = *format++; 680 } 681 out_buffer_[out_buffer_pos_] = '\0'; 682 } 683 684 685 // The disassembler may end up decoding data inlined in the code. We do not want 686 // it to crash if the data does not ressemble any known instruction. 687 #define VERIFY(condition) \ 688 if(!(condition)) { \ 689 Unknown(instr); \ 690 return; \ 691 } 692 693 694 // For currently unimplemented decodings the disassembler calls Unknown(instr) 695 // which will just print "unknown" of the instruction bits. 696 void Decoder::Unknown(Instruction* instr) { 697 Format(instr, "unknown"); 698 } 699 700 701 void Decoder::DecodeType01(Instruction* instr) { 702 int type = instr->TypeValue(); 703 if ((type == 0) && instr->IsSpecialType0()) { 704 // multiply instruction or extra loads and stores 705 if (instr->Bits(7, 4) == 9) { 706 if (instr->Bit(24) == 0) { 707 // multiply instructions 708 if (instr->Bit(23) == 0) { 709 if (instr->Bit(21) == 0) { 710 // The MUL instruction description (A 4.1.33) refers to Rd as being 711 // the destination for the operation, but it confusingly uses the 712 // Rn field to encode it. 713 Format(instr, "mul'cond's 'rn, 'rm, 'rs"); 714 } else { 715 if (instr->Bit(22) == 0) { 716 // The MLA instruction description (A 4.1.28) refers to the order 717 // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the 718 // Rn field to encode the Rd register and the Rd field to encode 719 // the Rn register. 720 Format(instr, "mla'cond's 'rn, 'rm, 'rs, 'rd"); 721 } else { 722 // The MLS instruction description (A 4.1.29) refers to the order 723 // of registers as "Rd, Rm, Rs, Rn". But confusingly it uses the 724 // Rn field to encode the Rd register and the Rd field to encode 725 // the Rn register. 726 Format(instr, "mls'cond's 'rn, 'rm, 'rs, 'rd"); 727 } 728 } 729 } else { 730 // The signed/long multiply instructions use the terms RdHi and RdLo 731 // when referring to the target registers. They are mapped to the Rn 732 // and Rd fields as follows: 733 // RdLo == Rd field 734 // RdHi == Rn field 735 // The order of registers is: <RdLo>, <RdHi>, <Rm>, <Rs> 736 Format(instr, "'um'al'cond's 'rd, 'rn, 'rm, 'rs"); 737 } 738 } else { 739 Unknown(instr); // not used by V8 740 } 741 } else if ((instr->Bit(20) == 0) && ((instr->Bits(7, 4) & 0xd) == 0xd)) { 742 // ldrd, strd 743 switch (instr->PUField()) { 744 case da_x: { 745 if (instr->Bit(22) == 0) { 746 Format(instr, "'memop'cond's 'rd, ['rn], -'rm"); 747 } else { 748 Format(instr, "'memop'cond's 'rd, ['rn], #-'off8"); 749 } 750 break; 751 } 752 case ia_x: { 753 if (instr->Bit(22) == 0) { 754 Format(instr, "'memop'cond's 'rd, ['rn], +'rm"); 755 } else { 756 Format(instr, "'memop'cond's 'rd, ['rn], #+'off8"); 757 } 758 break; 759 } 760 case db_x: { 761 if (instr->Bit(22) == 0) { 762 Format(instr, "'memop'cond's 'rd, ['rn, -'rm]'w"); 763 } else { 764 Format(instr, "'memop'cond's 'rd, ['rn, #-'off8]'w"); 765 } 766 break; 767 } 768 case ib_x: { 769 if (instr->Bit(22) == 0) { 770 Format(instr, "'memop'cond's 'rd, ['rn, +'rm]'w"); 771 } else { 772 Format(instr, "'memop'cond's 'rd, ['rn, #+'off8]'w"); 773 } 774 break; 775 } 776 default: { 777 // The PU field is a 2-bit field. 778 UNREACHABLE(); 779 break; 780 } 781 } 782 } else { 783 // extra load/store instructions 784 switch (instr->PUField()) { 785 case da_x: { 786 if (instr->Bit(22) == 0) { 787 Format(instr, "'memop'cond'sign'h 'rd, ['rn], -'rm"); 788 } else { 789 Format(instr, "'memop'cond'sign'h 'rd, ['rn], #-'off8"); 790 } 791 break; 792 } 793 case ia_x: { 794 if (instr->Bit(22) == 0) { 795 Format(instr, "'memop'cond'sign'h 'rd, ['rn], +'rm"); 796 } else { 797 Format(instr, "'memop'cond'sign'h 'rd, ['rn], #+'off8"); 798 } 799 break; 800 } 801 case db_x: { 802 if (instr->Bit(22) == 0) { 803 Format(instr, "'memop'cond'sign'h 'rd, ['rn, -'rm]'w"); 804 } else { 805 Format(instr, "'memop'cond'sign'h 'rd, ['rn, #-'off8]'w"); 806 } 807 break; 808 } 809 case ib_x: { 810 if (instr->Bit(22) == 0) { 811 Format(instr, "'memop'cond'sign'h 'rd, ['rn, +'rm]'w"); 812 } else { 813 Format(instr, "'memop'cond'sign'h 'rd, ['rn, #+'off8]'w"); 814 } 815 break; 816 } 817 default: { 818 // The PU field is a 2-bit field. 819 UNREACHABLE(); 820 break; 821 } 822 } 823 return; 824 } 825 } else if ((type == 0) && instr->IsMiscType0()) { 826 if (instr->Bits(22, 21) == 1) { 827 switch (instr->BitField(7, 4)) { 828 case BX: 829 Format(instr, "bx'cond 'rm"); 830 break; 831 case BLX: 832 Format(instr, "blx'cond 'rm"); 833 break; 834 case BKPT: 835 Format(instr, "bkpt 'off0to3and8to19"); 836 break; 837 default: 838 Unknown(instr); // not used by V8 839 break; 840 } 841 } else if (instr->Bits(22, 21) == 3) { 842 switch (instr->BitField(7, 4)) { 843 case CLZ: 844 Format(instr, "clz'cond 'rd, 'rm"); 845 break; 846 default: 847 Unknown(instr); // not used by V8 848 break; 849 } 850 } else { 851 Unknown(instr); // not used by V8 852 } 853 } else if ((type == 1) && instr->IsNopType1()) { 854 Format(instr, "nop'cond"); 855 } else { 856 switch (instr->OpcodeField()) { 857 case AND: { 858 Format(instr, "and'cond's 'rd, 'rn, 'shift_op"); 859 break; 860 } 861 case EOR: { 862 Format(instr, "eor'cond's 'rd, 'rn, 'shift_op"); 863 break; 864 } 865 case SUB: { 866 Format(instr, "sub'cond's 'rd, 'rn, 'shift_op"); 867 break; 868 } 869 case RSB: { 870 Format(instr, "rsb'cond's 'rd, 'rn, 'shift_op"); 871 break; 872 } 873 case ADD: { 874 Format(instr, "add'cond's 'rd, 'rn, 'shift_op"); 875 break; 876 } 877 case ADC: { 878 Format(instr, "adc'cond's 'rd, 'rn, 'shift_op"); 879 break; 880 } 881 case SBC: { 882 Format(instr, "sbc'cond's 'rd, 'rn, 'shift_op"); 883 break; 884 } 885 case RSC: { 886 Format(instr, "rsc'cond's 'rd, 'rn, 'shift_op"); 887 break; 888 } 889 case TST: { 890 if (instr->HasS()) { 891 Format(instr, "tst'cond 'rn, 'shift_op"); 892 } else { 893 Format(instr, "movw'cond 'mw"); 894 } 895 break; 896 } 897 case TEQ: { 898 if (instr->HasS()) { 899 Format(instr, "teq'cond 'rn, 'shift_op"); 900 } else { 901 // Other instructions matching this pattern are handled in the 902 // miscellaneous instructions part above. 903 UNREACHABLE(); 904 } 905 break; 906 } 907 case CMP: { 908 if (instr->HasS()) { 909 Format(instr, "cmp'cond 'rn, 'shift_op"); 910 } else { 911 Format(instr, "movt'cond 'mw"); 912 } 913 break; 914 } 915 case CMN: { 916 if (instr->HasS()) { 917 Format(instr, "cmn'cond 'rn, 'shift_op"); 918 } else { 919 // Other instructions matching this pattern are handled in the 920 // miscellaneous instructions part above. 921 UNREACHABLE(); 922 } 923 break; 924 } 925 case ORR: { 926 Format(instr, "orr'cond's 'rd, 'rn, 'shift_op"); 927 break; 928 } 929 case MOV: { 930 Format(instr, "mov'cond's 'rd, 'shift_op"); 931 break; 932 } 933 case BIC: { 934 Format(instr, "bic'cond's 'rd, 'rn, 'shift_op"); 935 break; 936 } 937 case MVN: { 938 Format(instr, "mvn'cond's 'rd, 'shift_op"); 939 break; 940 } 941 default: { 942 // The Opcode field is a 4-bit field. 943 UNREACHABLE(); 944 break; 945 } 946 } 947 } 948 } 949 950 951 void Decoder::DecodeType2(Instruction* instr) { 952 switch (instr->PUField()) { 953 case da_x: { 954 if (instr->HasW()) { 955 Unknown(instr); // not used in V8 956 return; 957 } 958 Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12"); 959 break; 960 } 961 case ia_x: { 962 if (instr->HasW()) { 963 Unknown(instr); // not used in V8 964 return; 965 } 966 Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12"); 967 break; 968 } 969 case db_x: { 970 Format(instr, "'memop'cond'b 'rd, ['rn, #-'off12]'w"); 971 break; 972 } 973 case ib_x: { 974 Format(instr, "'memop'cond'b 'rd, ['rn, #+'off12]'w"); 975 break; 976 } 977 default: { 978 // The PU field is a 2-bit field. 979 UNREACHABLE(); 980 break; 981 } 982 } 983 } 984 985 986 void Decoder::DecodeType3(Instruction* instr) { 987 switch (instr->PUField()) { 988 case da_x: { 989 VERIFY(!instr->HasW()); 990 Format(instr, "'memop'cond'b 'rd, ['rn], -'shift_rm"); 991 break; 992 } 993 case ia_x: { 994 if (instr->Bit(4) == 0) { 995 Format(instr, "'memop'cond'b 'rd, ['rn], +'shift_rm"); 996 } else { 997 if (instr->Bit(5) == 0) { 998 switch (instr->Bits(22, 21)) { 999 case 0: 1000 if (instr->Bit(20) == 0) { 1001 if (instr->Bit(6) == 0) { 1002 Format(instr, "pkhbt'cond 'rd, 'rn, 'rm, lsl #'imm05@07"); 1003 } else { 1004 if (instr->Bits(11, 7) == 0) { 1005 Format(instr, "pkhtb'cond 'rd, 'rn, 'rm, asr #32"); 1006 } else { 1007 Format(instr, "pkhtb'cond 'rd, 'rn, 'rm, asr #'imm05@07"); 1008 } 1009 } 1010 } else { 1011 UNREACHABLE(); 1012 } 1013 break; 1014 case 1: 1015 UNREACHABLE(); 1016 break; 1017 case 2: 1018 UNREACHABLE(); 1019 break; 1020 case 3: 1021 Format(instr, "usat 'rd, #'imm05@16, 'rm'shift_sat"); 1022 break; 1023 } 1024 } else { 1025 switch (instr->Bits(22, 21)) { 1026 case 0: 1027 UNREACHABLE(); 1028 break; 1029 case 1: 1030 UNREACHABLE(); 1031 break; 1032 case 2: 1033 if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) { 1034 if (instr->Bits(19, 16) == 0xF) { 1035 switch (instr->Bits(11, 10)) { 1036 case 0: 1037 Format(instr, "uxtb16'cond 'rd, 'rm"); 1038 break; 1039 case 1: 1040 Format(instr, "uxtb16'cond 'rd, 'rm, ror #8"); 1041 break; 1042 case 2: 1043 Format(instr, "uxtb16'cond 'rd, 'rm, ror #16"); 1044 break; 1045 case 3: 1046 Format(instr, "uxtb16'cond 'rd, 'rm, ror #24"); 1047 break; 1048 } 1049 } else { 1050 UNREACHABLE(); 1051 } 1052 } else { 1053 UNREACHABLE(); 1054 } 1055 break; 1056 case 3: 1057 if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) { 1058 if (instr->Bits(19, 16) == 0xF) { 1059 switch (instr->Bits(11, 10)) { 1060 case 0: 1061 Format(instr, "uxtb'cond 'rd, 'rm"); 1062 break; 1063 case 1: 1064 Format(instr, "uxtb'cond 'rd, 'rm, ror #8"); 1065 break; 1066 case 2: 1067 Format(instr, "uxtb'cond 'rd, 'rm, ror #16"); 1068 break; 1069 case 3: 1070 Format(instr, "uxtb'cond 'rd, 'rm, ror #24"); 1071 break; 1072 } 1073 } else { 1074 switch (instr->Bits(11, 10)) { 1075 case 0: 1076 Format(instr, "uxtab'cond 'rd, 'rn, 'rm"); 1077 break; 1078 case 1: 1079 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #8"); 1080 break; 1081 case 2: 1082 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #16"); 1083 break; 1084 case 3: 1085 Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #24"); 1086 break; 1087 } 1088 } 1089 } else { 1090 UNREACHABLE(); 1091 } 1092 break; 1093 } 1094 } 1095 } 1096 break; 1097 } 1098 case db_x: { 1099 if (FLAG_enable_sudiv) { 1100 if (instr->Bits(5, 4) == 0x1) { 1101 if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) { 1102 if (instr->Bit(21) == 0x1) { 1103 // UDIV (in V8 notation matching ARM ISA format) rn = rm/rs 1104 Format(instr, "udiv'cond'b 'rn, 'rm, 'rs"); 1105 } else { 1106 // SDIV (in V8 notation matching ARM ISA format) rn = rm/rs 1107 Format(instr, "sdiv'cond'b 'rn, 'rm, 'rs"); 1108 } 1109 break; 1110 } 1111 } 1112 } 1113 Format(instr, "'memop'cond'b 'rd, ['rn, -'shift_rm]'w"); 1114 break; 1115 } 1116 case ib_x: { 1117 if (instr->HasW() && (instr->Bits(6, 4) == 0x5)) { 1118 uint32_t widthminus1 = static_cast<uint32_t>(instr->Bits(20, 16)); 1119 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7)); 1120 uint32_t msbit = widthminus1 + lsbit; 1121 if (msbit <= 31) { 1122 if (instr->Bit(22)) { 1123 Format(instr, "ubfx'cond 'rd, 'rm, 'f"); 1124 } else { 1125 Format(instr, "sbfx'cond 'rd, 'rm, 'f"); 1126 } 1127 } else { 1128 UNREACHABLE(); 1129 } 1130 } else if (!instr->HasW() && (instr->Bits(6, 4) == 0x1)) { 1131 uint32_t lsbit = static_cast<uint32_t>(instr->Bits(11, 7)); 1132 uint32_t msbit = static_cast<uint32_t>(instr->Bits(20, 16)); 1133 if (msbit >= lsbit) { 1134 if (instr->RmValue() == 15) { 1135 Format(instr, "bfc'cond 'rd, 'f"); 1136 } else { 1137 Format(instr, "bfi'cond 'rd, 'rm, 'f"); 1138 } 1139 } else { 1140 UNREACHABLE(); 1141 } 1142 } else { 1143 Format(instr, "'memop'cond'b 'rd, ['rn, +'shift_rm]'w"); 1144 } 1145 break; 1146 } 1147 default: { 1148 // The PU field is a 2-bit field. 1149 UNREACHABLE(); 1150 break; 1151 } 1152 } 1153 } 1154 1155 1156 void Decoder::DecodeType4(Instruction* instr) { 1157 if (instr->Bit(22) != 0) { 1158 // Privileged mode currently not supported. 1159 Unknown(instr); 1160 } else { 1161 if (instr->HasL()) { 1162 Format(instr, "ldm'cond'pu 'rn'w, 'rlist"); 1163 } else { 1164 Format(instr, "stm'cond'pu 'rn'w, 'rlist"); 1165 } 1166 } 1167 } 1168 1169 1170 void Decoder::DecodeType5(Instruction* instr) { 1171 Format(instr, "b'l'cond 'target"); 1172 } 1173 1174 1175 void Decoder::DecodeType6(Instruction* instr) { 1176 DecodeType6CoprocessorIns(instr); 1177 } 1178 1179 1180 int Decoder::DecodeType7(Instruction* instr) { 1181 if (instr->Bit(24) == 1) { 1182 if (instr->SvcValue() >= kStopCode) { 1183 Format(instr, "stop'cond 'svc"); 1184 // Also print the stop message. Its address is encoded 1185 // in the following 4 bytes. 1186 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1187 "\n %p %08x stop message: %s", 1188 reinterpret_cast<void*>(instr 1189 + Instruction::kInstrSize), 1190 *reinterpret_cast<uint32_t*>(instr 1191 + Instruction::kInstrSize), 1192 *reinterpret_cast<char**>(instr 1193 + Instruction::kInstrSize)); 1194 // We have decoded 2 * Instruction::kInstrSize bytes. 1195 return 2 * Instruction::kInstrSize; 1196 } else { 1197 Format(instr, "svc'cond 'svc"); 1198 } 1199 } else { 1200 DecodeTypeVFP(instr); 1201 } 1202 return Instruction::kInstrSize; 1203 } 1204 1205 1206 // void Decoder::DecodeTypeVFP(Instruction* instr) 1207 // vmov: Sn = Rt 1208 // vmov: Rt = Sn 1209 // vcvt: Dd = Sm 1210 // vcvt: Sd = Dm 1211 // vcvt.f64.s32 Dd, Dd, #<fbits> 1212 // Dd = vabs(Dm) 1213 // Dd = vneg(Dm) 1214 // Dd = vadd(Dn, Dm) 1215 // Dd = vsub(Dn, Dm) 1216 // Dd = vmul(Dn, Dm) 1217 // Dd = vmla(Dn, Dm) 1218 // Dd = vmls(Dn, Dm) 1219 // Dd = vdiv(Dn, Dm) 1220 // vcmp(Dd, Dm) 1221 // vmrs 1222 // vmsr 1223 // Dd = vsqrt(Dm) 1224 void Decoder::DecodeTypeVFP(Instruction* instr) { 1225 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) ); 1226 VERIFY(instr->Bits(11, 9) == 0x5); 1227 1228 if (instr->Bit(4) == 0) { 1229 if (instr->Opc1Value() == 0x7) { 1230 // Other data processing instructions 1231 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) { 1232 // vmov register to register. 1233 if (instr->SzValue() == 0x1) { 1234 Format(instr, "vmov'cond.f64 'Dd, 'Dm"); 1235 } else { 1236 Format(instr, "vmov'cond.f32 'Sd, 'Sm"); 1237 } 1238 } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) { 1239 // vabs 1240 Format(instr, "vabs'cond.f64 'Dd, 'Dm"); 1241 } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) { 1242 // vneg 1243 Format(instr, "vneg'cond.f64 'Dd, 'Dm"); 1244 } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) { 1245 DecodeVCVTBetweenDoubleAndSingle(instr); 1246 } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) { 1247 DecodeVCVTBetweenFloatingPointAndInteger(instr); 1248 } else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) && 1249 (instr->Bit(8) == 1)) { 1250 // vcvt.f64.s32 Dd, Dd, #<fbits> 1251 int fraction_bits = 32 - ((instr->Bits(3, 0) << 1) | instr->Bit(5)); 1252 Format(instr, "vcvt'cond.f64.s32 'Dd, 'Dd"); 1253 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1254 ", #%d", fraction_bits); 1255 } else if (((instr->Opc2Value() >> 1) == 0x6) && 1256 (instr->Opc3Value() & 0x1)) { 1257 DecodeVCVTBetweenFloatingPointAndInteger(instr); 1258 } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && 1259 (instr->Opc3Value() & 0x1)) { 1260 DecodeVCMP(instr); 1261 } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) { 1262 Format(instr, "vsqrt'cond.f64 'Dd, 'Dm"); 1263 } else if (instr->Opc3Value() == 0x0) { 1264 if (instr->SzValue() == 0x1) { 1265 Format(instr, "vmov'cond.f64 'Dd, 'd"); 1266 } else { 1267 Unknown(instr); // Not used by V8. 1268 } 1269 } else { 1270 Unknown(instr); // Not used by V8. 1271 } 1272 } else if (instr->Opc1Value() == 0x3) { 1273 if (instr->SzValue() == 0x1) { 1274 if (instr->Opc3Value() & 0x1) { 1275 Format(instr, "vsub'cond.f64 'Dd, 'Dn, 'Dm"); 1276 } else { 1277 Format(instr, "vadd'cond.f64 'Dd, 'Dn, 'Dm"); 1278 } 1279 } else { 1280 Unknown(instr); // Not used by V8. 1281 } 1282 } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) { 1283 if (instr->SzValue() == 0x1) { 1284 Format(instr, "vmul'cond.f64 'Dd, 'Dn, 'Dm"); 1285 } else { 1286 Unknown(instr); // Not used by V8. 1287 } 1288 } else if ((instr->Opc1Value() == 0x0) && !(instr->Opc3Value() & 0x1)) { 1289 if (instr->SzValue() == 0x1) { 1290 Format(instr, "vmla'cond.f64 'Dd, 'Dn, 'Dm"); 1291 } else { 1292 Unknown(instr); // Not used by V8. 1293 } 1294 } else if ((instr->Opc1Value() == 0x0) && (instr->Opc3Value() & 0x1)) { 1295 if (instr->SzValue() == 0x1) { 1296 Format(instr, "vmls'cond.f64 'Dd, 'Dn, 'Dm"); 1297 } else { 1298 Unknown(instr); // Not used by V8. 1299 } 1300 } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) { 1301 if (instr->SzValue() == 0x1) { 1302 Format(instr, "vdiv'cond.f64 'Dd, 'Dn, 'Dm"); 1303 } else { 1304 Unknown(instr); // Not used by V8. 1305 } 1306 } else { 1307 Unknown(instr); // Not used by V8. 1308 } 1309 } else { 1310 if ((instr->VCValue() == 0x0) && 1311 (instr->VAValue() == 0x0)) { 1312 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); 1313 } else if ((instr->VLValue() == 0x0) && 1314 (instr->VCValue() == 0x1) && 1315 (instr->Bit(23) == 0x0)) { 1316 if (instr->Bit(21) == 0x0) { 1317 Format(instr, "vmov'cond.32 'Dd[0], 'rt"); 1318 } else { 1319 Format(instr, "vmov'cond.32 'Dd[1], 'rt"); 1320 } 1321 } else if ((instr->VLValue() == 0x1) && 1322 (instr->VCValue() == 0x1) && 1323 (instr->Bit(23) == 0x0)) { 1324 if (instr->Bit(21) == 0x0) { 1325 Format(instr, "vmov'cond.32 'rt, 'Dd[0]"); 1326 } else { 1327 Format(instr, "vmov'cond.32 'rt, 'Dd[1]"); 1328 } 1329 } else if ((instr->VCValue() == 0x0) && 1330 (instr->VAValue() == 0x7) && 1331 (instr->Bits(19, 16) == 0x1)) { 1332 if (instr->VLValue() == 0) { 1333 if (instr->Bits(15, 12) == 0xF) { 1334 Format(instr, "vmsr'cond FPSCR, APSR"); 1335 } else { 1336 Format(instr, "vmsr'cond FPSCR, 'rt"); 1337 } 1338 } else { 1339 if (instr->Bits(15, 12) == 0xF) { 1340 Format(instr, "vmrs'cond APSR, FPSCR"); 1341 } else { 1342 Format(instr, "vmrs'cond 'rt, FPSCR"); 1343 } 1344 } 1345 } 1346 } 1347 } 1348 1349 1350 void Decoder::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters( 1351 Instruction* instr) { 1352 VERIFY((instr->Bit(4) == 1) && (instr->VCValue() == 0x0) && 1353 (instr->VAValue() == 0x0)); 1354 1355 bool to_arm_register = (instr->VLValue() == 0x1); 1356 1357 if (to_arm_register) { 1358 Format(instr, "vmov'cond 'rt, 'Sn"); 1359 } else { 1360 Format(instr, "vmov'cond 'Sn, 'rt"); 1361 } 1362 } 1363 1364 1365 void Decoder::DecodeVCMP(Instruction* instr) { 1366 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); 1367 VERIFY(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && 1368 (instr->Opc3Value() & 0x1)); 1369 1370 // Comparison. 1371 bool dp_operation = (instr->SzValue() == 1); 1372 bool raise_exception_for_qnan = (instr->Bit(7) == 0x1); 1373 1374 if (dp_operation && !raise_exception_for_qnan) { 1375 if (instr->Opc2Value() == 0x4) { 1376 Format(instr, "vcmp'cond.f64 'Dd, 'Dm"); 1377 } else if (instr->Opc2Value() == 0x5) { 1378 Format(instr, "vcmp'cond.f64 'Dd, #0.0"); 1379 } else { 1380 Unknown(instr); // invalid 1381 } 1382 } else { 1383 Unknown(instr); // Not used by V8. 1384 } 1385 } 1386 1387 1388 void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) { 1389 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); 1390 VERIFY((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)); 1391 1392 bool double_to_single = (instr->SzValue() == 1); 1393 1394 if (double_to_single) { 1395 Format(instr, "vcvt'cond.f32.f64 'Sd, 'Dm"); 1396 } else { 1397 Format(instr, "vcvt'cond.f64.f32 'Dd, 'Sm"); 1398 } 1399 } 1400 1401 1402 void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instruction* instr) { 1403 VERIFY((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); 1404 VERIFY(((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) || 1405 (((instr->Opc2Value() >> 1) == 0x6) && (instr->Opc3Value() & 0x1))); 1406 1407 bool to_integer = (instr->Bit(18) == 1); 1408 bool dp_operation = (instr->SzValue() == 1); 1409 if (to_integer) { 1410 bool unsigned_integer = (instr->Bit(16) == 0); 1411 1412 if (dp_operation) { 1413 if (unsigned_integer) { 1414 Format(instr, "vcvt'cond.u32.f64 'Sd, 'Dm"); 1415 } else { 1416 Format(instr, "vcvt'cond.s32.f64 'Sd, 'Dm"); 1417 } 1418 } else { 1419 if (unsigned_integer) { 1420 Format(instr, "vcvt'cond.u32.f32 'Sd, 'Sm"); 1421 } else { 1422 Format(instr, "vcvt'cond.s32.f32 'Sd, 'Sm"); 1423 } 1424 } 1425 } else { 1426 bool unsigned_integer = (instr->Bit(7) == 0); 1427 1428 if (dp_operation) { 1429 if (unsigned_integer) { 1430 Format(instr, "vcvt'cond.f64.u32 'Dd, 'Sm"); 1431 } else { 1432 Format(instr, "vcvt'cond.f64.s32 'Dd, 'Sm"); 1433 } 1434 } else { 1435 if (unsigned_integer) { 1436 Format(instr, "vcvt'cond.f32.u32 'Sd, 'Sm"); 1437 } else { 1438 Format(instr, "vcvt'cond.f32.s32 'Sd, 'Sm"); 1439 } 1440 } 1441 } 1442 } 1443 1444 1445 // Decode Type 6 coprocessor instructions. 1446 // Dm = vmov(Rt, Rt2) 1447 // <Rt, Rt2> = vmov(Dm) 1448 // Ddst = MEM(Rbase + 4*offset). 1449 // MEM(Rbase + 4*offset) = Dsrc. 1450 void Decoder::DecodeType6CoprocessorIns(Instruction* instr) { 1451 VERIFY(instr->TypeValue() == 6); 1452 1453 if (instr->CoprocessorValue() == 0xA) { 1454 switch (instr->OpcodeValue()) { 1455 case 0x8: 1456 case 0xA: 1457 if (instr->HasL()) { 1458 Format(instr, "vldr'cond 'Sd, ['rn - 4*'imm08@00]"); 1459 } else { 1460 Format(instr, "vstr'cond 'Sd, ['rn - 4*'imm08@00]"); 1461 } 1462 break; 1463 case 0xC: 1464 case 0xE: 1465 if (instr->HasL()) { 1466 Format(instr, "vldr'cond 'Sd, ['rn + 4*'imm08@00]"); 1467 } else { 1468 Format(instr, "vstr'cond 'Sd, ['rn + 4*'imm08@00]"); 1469 } 1470 break; 1471 case 0x4: 1472 case 0x5: 1473 case 0x6: 1474 case 0x7: 1475 case 0x9: 1476 case 0xB: { 1477 bool to_vfp_register = (instr->VLValue() == 0x1); 1478 if (to_vfp_register) { 1479 Format(instr, "vldm'cond'pu 'rn'w, {'Sd-'Sd+}"); 1480 } else { 1481 Format(instr, "vstm'cond'pu 'rn'w, {'Sd-'Sd+}"); 1482 } 1483 break; 1484 } 1485 default: 1486 Unknown(instr); // Not used by V8. 1487 } 1488 } else if (instr->CoprocessorValue() == 0xB) { 1489 switch (instr->OpcodeValue()) { 1490 case 0x2: 1491 // Load and store double to two GP registers 1492 if (instr->Bits(7, 6) != 0 || instr->Bit(4) != 1) { 1493 Unknown(instr); // Not used by V8. 1494 } else if (instr->HasL()) { 1495 Format(instr, "vmov'cond 'rt, 'rn, 'Dm"); 1496 } else { 1497 Format(instr, "vmov'cond 'Dm, 'rt, 'rn"); 1498 } 1499 break; 1500 case 0x8: 1501 case 0xA: 1502 if (instr->HasL()) { 1503 Format(instr, "vldr'cond 'Dd, ['rn - 4*'imm08@00]"); 1504 } else { 1505 Format(instr, "vstr'cond 'Dd, ['rn - 4*'imm08@00]"); 1506 } 1507 break; 1508 case 0xC: 1509 case 0xE: 1510 if (instr->HasL()) { 1511 Format(instr, "vldr'cond 'Dd, ['rn + 4*'imm08@00]"); 1512 } else { 1513 Format(instr, "vstr'cond 'Dd, ['rn + 4*'imm08@00]"); 1514 } 1515 break; 1516 case 0x4: 1517 case 0x5: 1518 case 0x6: 1519 case 0x7: 1520 case 0x9: 1521 case 0xB: { 1522 bool to_vfp_register = (instr->VLValue() == 0x1); 1523 if (to_vfp_register) { 1524 Format(instr, "vldm'cond'pu 'rn'w, {'Dd-'Dd+}"); 1525 } else { 1526 Format(instr, "vstm'cond'pu 'rn'w, {'Dd-'Dd+}"); 1527 } 1528 break; 1529 } 1530 default: 1531 Unknown(instr); // Not used by V8. 1532 } 1533 } else { 1534 Unknown(instr); // Not used by V8. 1535 } 1536 } 1537 1538 1539 void Decoder::DecodeSpecialCondition(Instruction* instr) { 1540 switch (instr->SpecialValue()) { 1541 case 5: 1542 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && 1543 (instr->Bit(4) == 1)) { 1544 // vmovl signed 1545 if ((instr->VdValue() & 1) != 0) Unknown(instr); 1546 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); 1547 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); 1548 int imm3 = instr->Bits(21, 19); 1549 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1550 "vmovl.s%d q%d, d%d", imm3*8, Vd, Vm); 1551 } else { 1552 Unknown(instr); 1553 } 1554 break; 1555 case 7: 1556 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && 1557 (instr->Bit(4) == 1)) { 1558 // vmovl unsigned 1559 if ((instr->VdValue() & 1) != 0) Unknown(instr); 1560 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); 1561 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); 1562 int imm3 = instr->Bits(21, 19); 1563 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1564 "vmovl.u%d q%d, d%d", imm3*8, Vd, Vm); 1565 } else { 1566 Unknown(instr); 1567 } 1568 break; 1569 case 8: 1570 if (instr->Bits(21, 20) == 0) { 1571 // vst1 1572 int Vd = (instr->Bit(22) << 4) | instr->VdValue(); 1573 int Rn = instr->VnValue(); 1574 int type = instr->Bits(11, 8); 1575 int size = instr->Bits(7, 6); 1576 int align = instr->Bits(5, 4); 1577 int Rm = instr->VmValue(); 1578 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1579 "vst1.%d ", (1 << size) << 3); 1580 FormatNeonList(Vd, type); 1581 Print(", "); 1582 FormatNeonMemory(Rn, align, Rm); 1583 } else if (instr->Bits(21, 20) == 2) { 1584 // vld1 1585 int Vd = (instr->Bit(22) << 4) | instr->VdValue(); 1586 int Rn = instr->VnValue(); 1587 int type = instr->Bits(11, 8); 1588 int size = instr->Bits(7, 6); 1589 int align = instr->Bits(5, 4); 1590 int Rm = instr->VmValue(); 1591 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1592 "vld1.%d ", (1 << size) << 3); 1593 FormatNeonList(Vd, type); 1594 Print(", "); 1595 FormatNeonMemory(Rn, align, Rm); 1596 } else { 1597 Unknown(instr); 1598 } 1599 break; 1600 case 0xA: 1601 case 0xB: 1602 if ((instr->Bits(22, 20) == 5) && (instr->Bits(15, 12) == 0xf)) { 1603 int Rn = instr->Bits(19, 16); 1604 int offset = instr->Bits(11, 0); 1605 if (offset == 0) { 1606 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1607 "pld [r%d]", Rn); 1608 } else if (instr->Bit(23) == 0) { 1609 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1610 "pld [r%d, #-%d]", Rn, offset); 1611 } else { 1612 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1613 "pld [r%d, #+%d]", Rn, offset); 1614 } 1615 } else { 1616 Unknown(instr); 1617 } 1618 break; 1619 default: 1620 Unknown(instr); 1621 break; 1622 } 1623 } 1624 1625 #undef VERIFIY 1626 1627 bool Decoder::IsConstantPoolAt(byte* instr_ptr) { 1628 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); 1629 return (instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker; 1630 } 1631 1632 1633 int Decoder::ConstantPoolSizeAt(byte* instr_ptr) { 1634 if (IsConstantPoolAt(instr_ptr)) { 1635 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); 1636 return DecodeConstantPoolLength(instruction_bits); 1637 } else { 1638 return -1; 1639 } 1640 } 1641 1642 1643 // Disassemble the instruction at *instr_ptr into the output buffer. 1644 int Decoder::InstructionDecode(byte* instr_ptr) { 1645 Instruction* instr = Instruction::At(instr_ptr); 1646 // Print raw instruction bytes. 1647 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1648 "%08x ", 1649 instr->InstructionBits()); 1650 if (instr->ConditionField() == kSpecialCondition) { 1651 DecodeSpecialCondition(instr); 1652 return Instruction::kInstrSize; 1653 } 1654 int instruction_bits = *(reinterpret_cast<int*>(instr_ptr)); 1655 if ((instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker) { 1656 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1657 "constant pool begin (length %d)", 1658 DecodeConstantPoolLength(instruction_bits)); 1659 return Instruction::kInstrSize; 1660 } else if (instruction_bits == kCodeAgeJumpInstruction) { 1661 // The code age prologue has a constant immediatly following the jump 1662 // instruction. 1663 Instruction* target = Instruction::At(instr_ptr + Instruction::kInstrSize); 1664 DecodeType2(instr); 1665 SNPrintF(out_buffer_ + out_buffer_pos_, 1666 " (0x%08x)", target->InstructionBits()); 1667 return 2 * Instruction::kInstrSize; 1668 } 1669 switch (instr->TypeValue()) { 1670 case 0: 1671 case 1: { 1672 DecodeType01(instr); 1673 break; 1674 } 1675 case 2: { 1676 DecodeType2(instr); 1677 break; 1678 } 1679 case 3: { 1680 DecodeType3(instr); 1681 break; 1682 } 1683 case 4: { 1684 DecodeType4(instr); 1685 break; 1686 } 1687 case 5: { 1688 DecodeType5(instr); 1689 break; 1690 } 1691 case 6: { 1692 DecodeType6(instr); 1693 break; 1694 } 1695 case 7: { 1696 return DecodeType7(instr); 1697 } 1698 default: { 1699 // The type field is 3-bits in the ARM encoding. 1700 UNREACHABLE(); 1701 break; 1702 } 1703 } 1704 return Instruction::kInstrSize; 1705 } 1706 1707 1708 } } // namespace v8::internal 1709 1710 1711 1712 //------------------------------------------------------------------------------ 1713 1714 namespace disasm { 1715 1716 1717 const char* NameConverter::NameOfAddress(byte* addr) const { 1718 v8::internal::SNPrintF(tmp_buffer_, "%p", addr); 1719 return tmp_buffer_.start(); 1720 } 1721 1722 1723 const char* NameConverter::NameOfConstant(byte* addr) const { 1724 return NameOfAddress(addr); 1725 } 1726 1727 1728 const char* NameConverter::NameOfCPURegister(int reg) const { 1729 return v8::internal::Registers::Name(reg); 1730 } 1731 1732 1733 const char* NameConverter::NameOfByteCPURegister(int reg) const { 1734 UNREACHABLE(); // ARM does not have the concept of a byte register 1735 return "nobytereg"; 1736 } 1737 1738 1739 const char* NameConverter::NameOfXMMRegister(int reg) const { 1740 UNREACHABLE(); // ARM does not have any XMM registers 1741 return "noxmmreg"; 1742 } 1743 1744 1745 const char* NameConverter::NameInCode(byte* addr) const { 1746 // The default name converter is called for unknown code. So we will not try 1747 // to access any memory. 1748 return ""; 1749 } 1750 1751 1752 //------------------------------------------------------------------------------ 1753 1754 Disassembler::Disassembler(const NameConverter& converter) 1755 : converter_(converter) {} 1756 1757 1758 Disassembler::~Disassembler() {} 1759 1760 1761 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer, 1762 byte* instruction) { 1763 v8::internal::Decoder d(converter_, buffer); 1764 return d.InstructionDecode(instruction); 1765 } 1766 1767 1768 int Disassembler::ConstantPoolSizeAt(byte* instruction) { 1769 return v8::internal::Decoder::ConstantPoolSizeAt(instruction); 1770 } 1771 1772 1773 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) { 1774 NameConverter converter; 1775 Disassembler d(converter); 1776 for (byte* pc = begin; pc < end;) { 1777 v8::internal::EmbeddedVector<char, 128> buffer; 1778 buffer[0] = '\0'; 1779 byte* prev_pc = pc; 1780 pc += d.InstructionDecode(buffer, pc); 1781 v8::internal::PrintF( 1782 f, "%p %08x %s\n", 1783 prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); 1784 } 1785 } 1786 1787 1788 } // namespace disasm 1789 1790 #endif // V8_TARGET_ARCH_ARM 1791