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