1// Copyright 2012 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::base::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#include <assert.h> 26#include <stdarg.h> 27#include <stdio.h> 28#include <string.h> 29 30#if V8_TARGET_ARCH_MIPS 31 32#include "src/base/platform/platform.h" 33#include "src/base/strings.h" 34#include "src/base/vector.h" 35#include "src/codegen/macro-assembler.h" 36#include "src/codegen/mips/constants-mips.h" 37#include "src/diagnostics/disasm.h" 38 39namespace v8 { 40namespace internal { 41 42//------------------------------------------------------------------------------ 43 44// Decoder decodes and disassembles instructions into an output buffer. 45// It uses the converter to convert register names and call destinations into 46// more informative description. 47class Decoder { 48 public: 49 Decoder(const disasm::NameConverter& converter, 50 v8::base::Vector<char> out_buffer) 51 : converter_(converter), out_buffer_(out_buffer), out_buffer_pos_(0) { 52 out_buffer_[out_buffer_pos_] = '\0'; 53 } 54 55 ~Decoder() {} 56 57 Decoder(const Decoder&) = delete; 58 Decoder& operator=(const Decoder&) = delete; 59 60 // Writes one disassembled instruction into 'buffer' (0-terminated). 61 // Returns the length of the disassembled machine instruction in bytes. 62 int InstructionDecode(byte* instruction); 63 64 private: 65 // Bottleneck functions to print into the out_buffer. 66 void PrintChar(const char ch); 67 void Print(const char* str); 68 69 // Printing of common values. 70 void PrintRegister(int reg); 71 void PrintFPURegister(int freg); 72 void PrintMSARegister(int wreg); 73 void PrintFPUStatusRegister(int freg); 74 void PrintMSAControlRegister(int creg); 75 void PrintRs(Instruction* instr); 76 void PrintRt(Instruction* instr); 77 void PrintRd(Instruction* instr); 78 void PrintFs(Instruction* instr); 79 void PrintFt(Instruction* instr); 80 void PrintFd(Instruction* instr); 81 void PrintSa(Instruction* instr); 82 void PrintLsaSa(Instruction* instr); 83 void PrintSd(Instruction* instr); 84 void PrintSs1(Instruction* instr); 85 void PrintSs2(Instruction* instr); 86 void PrintBc(Instruction* instr); 87 void PrintCc(Instruction* instr); 88 void PrintBp2(Instruction* instr); 89 void PrintFunction(Instruction* instr); 90 void PrintSecondaryField(Instruction* instr); 91 void PrintUImm9(Instruction* instr); 92 void PrintSImm9(Instruction* instr); 93 void PrintUImm16(Instruction* instr); 94 void PrintSImm16(Instruction* instr); 95 void PrintXImm16(Instruction* instr); 96 void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits); 97 void PrintXImm18(Instruction* instr); 98 void PrintSImm18(Instruction* instr); 99 void PrintXImm19(Instruction* instr); 100 void PrintSImm19(Instruction* instr); 101 void PrintXImm21(Instruction* instr); 102 void PrintSImm21(Instruction* instr); 103 void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits); 104 void PrintXImm26(Instruction* instr); 105 void PrintSImm26(Instruction* instr); 106 void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits); 107 void PrintPCImm26(Instruction* instr); 108 void PrintCode(Instruction* instr); // For break and trap instructions. 109 void PrintFormat(Instruction* instr); // For floating format postfix. 110 void PrintMsaDataFormat(Instruction* instr); 111 void PrintMsaXImm8(Instruction* instr); 112 void PrintMsaImm8(Instruction* instr); 113 void PrintMsaImm5(Instruction* instr); 114 void PrintMsaSImm5(Instruction* instr); 115 void PrintMsaSImm10(Instruction* instr, bool is_mi10 = false); 116 void PrintMsaImmBit(Instruction* instr); 117 void PrintMsaImmElm(Instruction* instr); 118 void PrintMsaCopy(Instruction* instr); 119 // Printing of instruction name. 120 void PrintInstructionName(Instruction* instr); 121 122 // Handle formatting of instructions and their options. 123 int FormatRegister(Instruction* instr, const char* option); 124 int FormatFPURegister(Instruction* instr, const char* option); 125 int FormatMSARegister(Instruction* instr, const char* option); 126 int FormatOption(Instruction* instr, const char* option); 127 void Format(Instruction* instr, const char* format); 128 void Unknown(Instruction* instr); 129 130 // Each of these functions decodes one particular instruction type. 131 bool DecodeTypeRegisterRsType(Instruction* instr); 132 void DecodeTypeRegisterSRsType(Instruction* instr); 133 void DecodeTypeRegisterDRsType(Instruction* instr); 134 void DecodeTypeRegisterLRsType(Instruction* instr); 135 void DecodeTypeRegisterWRsType(Instruction* instr); 136 void DecodeTypeRegisterSPECIAL(Instruction* instr); 137 void DecodeTypeRegisterSPECIAL2(Instruction* instr); 138 void DecodeTypeRegisterSPECIAL3(Instruction* instr); 139 void DecodeTypeRegister(Instruction* instr); 140 void DecodeTypeImmediate(Instruction* instr); 141 void DecodeTypeImmediateSPECIAL3(Instruction* instr); 142 void DecodeTypeJump(Instruction* instr); 143 void DecodeTypeMsaI8(Instruction* instr); 144 void DecodeTypeMsaI5(Instruction* instr); 145 void DecodeTypeMsaI10(Instruction* instr); 146 void DecodeTypeMsaELM(Instruction* instr); 147 void DecodeTypeMsaBIT(Instruction* instr); 148 void DecodeTypeMsaMI10(Instruction* instr); 149 void DecodeTypeMsa3R(Instruction* instr); 150 void DecodeTypeMsa3RF(Instruction* instr); 151 void DecodeTypeMsaVec(Instruction* instr); 152 void DecodeTypeMsa2R(Instruction* instr); 153 void DecodeTypeMsa2RF(Instruction* instr); 154 155 const disasm::NameConverter& converter_; 156 v8::base::Vector<char> out_buffer_; 157 int out_buffer_pos_; 158}; 159 160// Support for assertions in the Decoder formatting functions. 161#define STRING_STARTS_WITH(string, compare_string) \ 162 (strncmp(string, compare_string, strlen(compare_string)) == 0) 163 164// Append the ch to the output buffer. 165void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; } 166 167// Append the str to the output buffer. 168void Decoder::Print(const char* str) { 169 char cur = *str++; 170 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 171 PrintChar(cur); 172 cur = *str++; 173 } 174 out_buffer_[out_buffer_pos_] = 0; 175} 176 177// Print the register name according to the active name converter. 178void Decoder::PrintRegister(int reg) { 179 Print(converter_.NameOfCPURegister(reg)); 180} 181 182void Decoder::PrintRs(Instruction* instr) { 183 int reg = instr->RsValue(); 184 PrintRegister(reg); 185} 186 187void Decoder::PrintRt(Instruction* instr) { 188 int reg = instr->RtValue(); 189 PrintRegister(reg); 190} 191 192void Decoder::PrintRd(Instruction* instr) { 193 int reg = instr->RdValue(); 194 PrintRegister(reg); 195} 196 197// Print the FPUregister name according to the active name converter. 198void Decoder::PrintFPURegister(int freg) { 199 Print(converter_.NameOfXMMRegister(freg)); 200} 201 202void Decoder::PrintMSARegister(int wreg) { Print(MSARegisters::Name(wreg)); } 203 204void Decoder::PrintFPUStatusRegister(int freg) { 205 switch (freg) { 206 case kFCSRRegister: 207 Print("FCSR"); 208 break; 209 default: 210 Print(converter_.NameOfXMMRegister(freg)); 211 } 212} 213 214void Decoder::PrintMSAControlRegister(int creg) { 215 switch (creg) { 216 case kMSAIRRegister: 217 Print("MSAIR"); 218 break; 219 case kMSACSRRegister: 220 Print("MSACSR"); 221 break; 222 default: 223 Print("no_msacreg"); 224 } 225} 226 227void Decoder::PrintFs(Instruction* instr) { 228 int freg = instr->RsValue(); 229 PrintFPURegister(freg); 230} 231 232void Decoder::PrintFt(Instruction* instr) { 233 int freg = instr->RtValue(); 234 PrintFPURegister(freg); 235} 236 237void Decoder::PrintFd(Instruction* instr) { 238 int freg = instr->RdValue(); 239 PrintFPURegister(freg); 240} 241 242// Print the integer value of the sa field. 243void Decoder::PrintSa(Instruction* instr) { 244 int sa = instr->SaValue(); 245 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa); 246} 247 248// Print the integer value of the sa field of a lsa instruction. 249void Decoder::PrintLsaSa(Instruction* instr) { 250 int sa = instr->LsaSaValue() + 1; 251 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa); 252} 253 254// Print the integer value of the rd field, when it is not used as reg. 255void Decoder::PrintSd(Instruction* instr) { 256 int sd = instr->RdValue(); 257 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sd); 258} 259 260// Print the integer value of the rd field, when used as 'ext' size. 261void Decoder::PrintSs1(Instruction* instr) { 262 int ss = instr->RdValue(); 263 out_buffer_pos_ += 264 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss + 1); 265} 266 267// Print the integer value of the rd field, when used as 'ins' size. 268void Decoder::PrintSs2(Instruction* instr) { 269 int ss = instr->RdValue(); 270 int pos = instr->SaValue(); 271 out_buffer_pos_ += 272 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss - pos + 1); 273} 274 275// Print the integer value of the cc field for the bc1t/f instructions. 276void Decoder::PrintBc(Instruction* instr) { 277 int cc = instr->FBccValue(); 278 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", cc); 279} 280 281// Print the integer value of the cc field for the FP compare instructions. 282void Decoder::PrintCc(Instruction* instr) { 283 int cc = instr->FCccValue(); 284 out_buffer_pos_ += 285 base::SNPrintF(out_buffer_ + out_buffer_pos_, "cc(%d)", cc); 286} 287 288void Decoder::PrintBp2(Instruction* instr) { 289 int bp2 = instr->Bp2Value(); 290 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp2); 291} 292 293// Print 9-bit unsigned immediate value. 294void Decoder::PrintUImm9(Instruction* instr) { 295 int32_t imm = instr->Imm9Value(); 296 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); 297} 298 299// Print 9-bit signed immediate value. 300void Decoder::PrintSImm9(Instruction* instr) { 301 int32_t imm = ((instr->Imm9Value()) << 23) >> 23; 302 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); 303} 304 305// Print 16-bit unsigned immediate value. 306void Decoder::PrintUImm16(Instruction* instr) { 307 int32_t imm = instr->Imm16Value(); 308 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); 309} 310 311// Print 16-bit signed immediate value. 312void Decoder::PrintSImm16(Instruction* instr) { 313 int32_t imm = ((instr->Imm16Value()) << 16) >> 16; 314 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); 315} 316 317// Print 16-bit hexa immediate value. 318void Decoder::PrintXImm16(Instruction* instr) { 319 int32_t imm = instr->Imm16Value(); 320 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 321} 322 323// Print absoulte address for 16-bit offset or immediate value. 324// The absolute address is calculated according following expression: 325// PC + delta_pc + (offset << n_bits) 326void Decoder::PrintPCImm16(Instruction* instr, int delta_pc, int n_bits) { 327 int16_t offset = instr->Imm16Value(); 328 out_buffer_pos_ += 329 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%s", 330 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + 331 delta_pc + (offset << n_bits))); 332} 333 334// Print 18-bit signed immediate value. 335void Decoder::PrintSImm18(Instruction* instr) { 336 int32_t imm = 337 ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits); 338 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); 339} 340 341// Print 18-bit hexa immediate value. 342void Decoder::PrintXImm18(Instruction* instr) { 343 int32_t imm = instr->Imm18Value(); 344 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 345} 346 347// Print 19-bit hexa immediate value. 348void Decoder::PrintXImm19(Instruction* instr) { 349 int32_t imm = instr->Imm19Value(); 350 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 351} 352 353// Print 19-bit signed immediate value. 354void Decoder::PrintSImm19(Instruction* instr) { 355 int32_t imm19 = instr->Imm19Value(); 356 // set sign 357 imm19 <<= (32 - kImm19Bits); 358 imm19 >>= (32 - kImm19Bits); 359 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm19); 360} 361 362// Print 21-bit immediate value. 363void Decoder::PrintXImm21(Instruction* instr) { 364 uint32_t imm = instr->Imm21Value(); 365 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 366} 367 368// Print 21-bit signed immediate value. 369void Decoder::PrintSImm21(Instruction* instr) { 370 int32_t imm21 = instr->Imm21Value(); 371 // set sign 372 imm21 <<= (32 - kImm21Bits); 373 imm21 >>= (32 - kImm21Bits); 374 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm21); 375} 376 377// Print absoulte address for 21-bit offset or immediate value. 378// The absolute address is calculated according following expression: 379// PC + delta_pc + (offset << n_bits) 380void Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) { 381 int32_t imm21 = instr->Imm21Value(); 382 // set sign 383 imm21 <<= (32 - kImm21Bits); 384 imm21 >>= (32 - kImm21Bits); 385 out_buffer_pos_ += 386 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%s", 387 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + 388 delta_pc + (imm21 << n_bits))); 389} 390 391// Print 26-bit hex immediate value. 392void Decoder::PrintXImm26(Instruction* instr) { 393 uint32_t target = static_cast<uint32_t>(instr->Imm26Value()) 394 << kImmFieldShift; 395 target = (reinterpret_cast<uint32_t>(instr) & ~0xFFFFFFF) | target; 396 out_buffer_pos_ += 397 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", target); 398} 399 400// Print 26-bit signed immediate value. 401void Decoder::PrintSImm26(Instruction* instr) { 402 int32_t imm26 = instr->Imm26Value(); 403 // set sign 404 imm26 <<= (32 - kImm26Bits); 405 imm26 >>= (32 - kImm26Bits); 406 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm26); 407} 408 409// Print absoulte address for 26-bit offset or immediate value. 410// The absolute address is calculated according following expression: 411// PC + delta_pc + (offset << n_bits) 412void Decoder::PrintPCImm26(Instruction* instr, int delta_pc, int n_bits) { 413 int32_t imm26 = instr->Imm26Value(); 414 // set sign 415 imm26 <<= (32 - kImm26Bits); 416 imm26 >>= (32 - kImm26Bits); 417 out_buffer_pos_ += 418 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%s", 419 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + 420 delta_pc + (imm26 << n_bits))); 421} 422 423// Print absoulte address for 26-bit offset or immediate value. 424// The absolute address is calculated according following expression: 425// PC[GPRLEN-1 .. 28] || instr_index26 || 00 426void Decoder::PrintPCImm26(Instruction* instr) { 427 int32_t imm26 = instr->Imm26Value(); 428 uint32_t pc_mask = ~0xFFFFFFF; 429 uint32_t pc = ((uint32_t)(instr + 1) & pc_mask) | (imm26 << 2); 430 out_buffer_pos_ += 431 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%s", 432 converter_.NameOfAddress((reinterpret_cast<byte*>(pc)))); 433} 434 435// Print 26-bit immediate value. 436void Decoder::PrintCode(Instruction* instr) { 437 if (instr->OpcodeFieldRaw() != SPECIAL) 438 return; // Not a break or trap instruction. 439 switch (instr->FunctionFieldRaw()) { 440 case BREAK: { 441 int32_t code = instr->Bits(25, 6); 442 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, 443 "0x%05x (%d)", code, code); 444 break; 445 } 446 case TGE: 447 case TGEU: 448 case TLT: 449 case TLTU: 450 case TEQ: 451 case TNE: { 452 int32_t code = instr->Bits(15, 6); 453 out_buffer_pos_ += 454 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code); 455 break; 456 } 457 default: // Not a break or trap instruction. 458 break; 459 } 460} 461 462void Decoder::PrintMsaXImm8(Instruction* instr) { 463 int32_t imm = instr->MsaImm8Value(); 464 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 465} 466 467void Decoder::PrintMsaImm8(Instruction* instr) { 468 int32_t imm = instr->MsaImm8Value(); 469 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); 470} 471 472void Decoder::PrintMsaImm5(Instruction* instr) { 473 int32_t imm = instr->MsaImm5Value(); 474 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); 475} 476 477void Decoder::PrintMsaSImm5(Instruction* instr) { 478 int32_t imm = instr->MsaImm5Value(); 479 imm <<= (32 - kMsaImm5Bits); 480 imm >>= (32 - kMsaImm5Bits); 481 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); 482} 483 484void Decoder::PrintMsaSImm10(Instruction* instr, bool is_mi10) { 485 int32_t imm = is_mi10 ? instr->MsaImmMI10Value() : instr->MsaImm10Value(); 486 imm <<= (32 - kMsaImm10Bits); 487 imm >>= (32 - kMsaImm10Bits); 488 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); 489} 490 491void Decoder::PrintMsaImmBit(Instruction* instr) { 492 int32_t m = instr->MsaBitMValue(); 493 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", m); 494} 495 496void Decoder::PrintMsaImmElm(Instruction* instr) { 497 int32_t n = instr->MsaElmNValue(); 498 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", n); 499} 500 501void Decoder::PrintMsaCopy(Instruction* instr) { 502 int32_t rd = instr->WdValue(); 503 int32_t ws = instr->WsValue(); 504 int32_t n = instr->MsaElmNValue(); 505 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%s, %s[%u]", 506 converter_.NameOfCPURegister(rd), 507 MSARegisters::Name(ws), n); 508} 509 510void Decoder::PrintFormat(Instruction* instr) { 511 char formatLetter = ' '; 512 switch (instr->RsFieldRaw()) { 513 case S: 514 formatLetter = 's'; 515 break; 516 case D: 517 formatLetter = 'd'; 518 break; 519 case W: 520 formatLetter = 'w'; 521 break; 522 case L: 523 formatLetter = 'l'; 524 break; 525 default: 526 UNREACHABLE(); 527 } 528 PrintChar(formatLetter); 529} 530 531void Decoder::PrintMsaDataFormat(Instruction* instr) { 532 DCHECK(instr->IsMSAInstr()); 533 char df = ' '; 534 if (instr->IsMSABranchInstr()) { 535 switch (instr->RsFieldRaw()) { 536 case BZ_V: 537 case BNZ_V: 538 df = 'v'; 539 break; 540 case BZ_B: 541 case BNZ_B: 542 df = 'b'; 543 break; 544 case BZ_H: 545 case BNZ_H: 546 df = 'h'; 547 break; 548 case BZ_W: 549 case BNZ_W: 550 df = 'w'; 551 break; 552 case BZ_D: 553 case BNZ_D: 554 df = 'd'; 555 break; 556 default: 557 UNREACHABLE(); 558 } 559 } else { 560 char DF[] = {'b', 'h', 'w', 'd'}; 561 switch (instr->MSAMinorOpcodeField()) { 562 case kMsaMinorI5: 563 case kMsaMinorI10: 564 case kMsaMinor3R: 565 df = DF[instr->Bits(22, 21)]; 566 break; 567 case kMsaMinorMI10: 568 df = DF[instr->Bits(1, 0)]; 569 break; 570 case kMsaMinorBIT: 571 df = DF[instr->MsaBitDf()]; 572 break; 573 case kMsaMinorELM: 574 df = DF[instr->MsaElmDf()]; 575 break; 576 case kMsaMinor3RF: { 577 uint32_t opcode = instr->InstructionBits() & kMsa3RFMask; 578 switch (opcode) { 579 case FEXDO: 580 case FTQ: 581 case MUL_Q: 582 case MADD_Q: 583 case MSUB_Q: 584 case MULR_Q: 585 case MADDR_Q: 586 case MSUBR_Q: 587 df = DF[1 + instr->Bit(21)]; 588 break; 589 default: 590 df = DF[2 + instr->Bit(21)]; 591 break; 592 } 593 } break; 594 case kMsaMinor2R: 595 df = DF[instr->Bits(17, 16)]; 596 break; 597 case kMsaMinor2RF: 598 df = DF[2 + instr->Bit(16)]; 599 break; 600 default: 601 UNREACHABLE(); 602 } 603 } 604 605 PrintChar(df); 606} 607 608// Printing of instruction name. 609void Decoder::PrintInstructionName(Instruction* instr) {} 610 611// Handle all register based formatting in this function to reduce the 612// complexity of FormatOption. 613int Decoder::FormatRegister(Instruction* instr, const char* format) { 614 DCHECK_EQ(format[0], 'r'); 615 if (format[1] == 's') { // 'rs: Rs register. 616 int reg = instr->RsValue(); 617 PrintRegister(reg); 618 return 2; 619 } else if (format[1] == 't') { // 'rt: rt register. 620 int reg = instr->RtValue(); 621 PrintRegister(reg); 622 return 2; 623 } else if (format[1] == 'd') { // 'rd: rd register. 624 int reg = instr->RdValue(); 625 PrintRegister(reg); 626 return 2; 627 } 628 UNREACHABLE(); 629} 630 631// Handle all FPUregister based formatting in this function to reduce the 632// complexity of FormatOption. 633int Decoder::FormatFPURegister(Instruction* instr, const char* format) { 634 DCHECK_EQ(format[0], 'f'); 635 if ((CTC1 == instr->RsFieldRaw()) || (CFC1 == instr->RsFieldRaw())) { 636 if (format[1] == 's') { // 'fs: fs register. 637 int reg = instr->FsValue(); 638 PrintFPUStatusRegister(reg); 639 return 2; 640 } else if (format[1] == 't') { // 'ft: ft register. 641 int reg = instr->FtValue(); 642 PrintFPUStatusRegister(reg); 643 return 2; 644 } else if (format[1] == 'd') { // 'fd: fd register. 645 int reg = instr->FdValue(); 646 PrintFPUStatusRegister(reg); 647 return 2; 648 } else if (format[1] == 'r') { // 'fr: fr register. 649 int reg = instr->FrValue(); 650 PrintFPUStatusRegister(reg); 651 return 2; 652 } 653 } else { 654 if (format[1] == 's') { // 'fs: fs register. 655 int reg = instr->FsValue(); 656 PrintFPURegister(reg); 657 return 2; 658 } else if (format[1] == 't') { // 'ft: ft register. 659 int reg = instr->FtValue(); 660 PrintFPURegister(reg); 661 return 2; 662 } else if (format[1] == 'd') { // 'fd: fd register. 663 int reg = instr->FdValue(); 664 PrintFPURegister(reg); 665 return 2; 666 } else if (format[1] == 'r') { // 'fr: fr register. 667 int reg = instr->FrValue(); 668 PrintFPURegister(reg); 669 return 2; 670 } 671 } 672 UNREACHABLE(); 673} 674 675// Handle all MSARegister based formatting in this function to reduce the 676// complexity of FormatOption. 677int Decoder::FormatMSARegister(Instruction* instr, const char* format) { 678 DCHECK_EQ(format[0], 'w'); 679 if (format[1] == 's') { 680 int reg = instr->WsValue(); 681 PrintMSARegister(reg); 682 return 2; 683 } else if (format[1] == 't') { 684 int reg = instr->WtValue(); 685 PrintMSARegister(reg); 686 return 2; 687 } else if (format[1] == 'd') { 688 int reg = instr->WdValue(); 689 PrintMSARegister(reg); 690 return 2; 691 } 692 693 UNREACHABLE(); 694} 695 696// FormatOption takes a formatting string and interprets it based on 697// the current instructions. The format string points to the first 698// character of the option string (the option escape has already been 699// consumed by the caller.) FormatOption returns the number of 700// characters that were consumed from the formatting string. 701int Decoder::FormatOption(Instruction* instr, const char* format) { 702 switch (format[0]) { 703 case 'c': { // 'code for break or trap instructions. 704 DCHECK(STRING_STARTS_WITH(format, "code")); 705 PrintCode(instr); 706 return 4; 707 } 708 case 'i': { // 'imm16u or 'imm26. 709 if (format[3] == '1') { 710 if (format[4] == '6') { 711 DCHECK(STRING_STARTS_WITH(format, "imm16")); 712 switch (format[5]) { 713 case 's': 714 DCHECK(STRING_STARTS_WITH(format, "imm16s")); 715 PrintSImm16(instr); 716 break; 717 case 'u': 718 DCHECK(STRING_STARTS_WITH(format, "imm16u")); 719 PrintSImm16(instr); 720 break; 721 case 'x': 722 DCHECK(STRING_STARTS_WITH(format, "imm16x")); 723 PrintXImm16(instr); 724 break; 725 case 'p': { // The PC relative address. 726 DCHECK(STRING_STARTS_WITH(format, "imm16p")); 727 int delta_pc = 0; 728 int n_bits = 0; 729 switch (format[6]) { 730 case '4': { 731 DCHECK(STRING_STARTS_WITH(format, "imm16p4")); 732 delta_pc = 4; 733 switch (format[8]) { 734 case '2': 735 DCHECK(STRING_STARTS_WITH(format, "imm16p4s2")); 736 n_bits = 2; 737 PrintPCImm16(instr, delta_pc, n_bits); 738 return 9; 739 } 740 } 741 } 742 } 743 } 744 return 6; 745 } else if (format[4] == '8') { 746 DCHECK(STRING_STARTS_WITH(format, "imm18")); 747 switch (format[5]) { 748 case 's': 749 DCHECK(STRING_STARTS_WITH(format, "imm18s")); 750 PrintSImm18(instr); 751 break; 752 case 'x': 753 DCHECK(STRING_STARTS_WITH(format, "imm18x")); 754 PrintXImm18(instr); 755 break; 756 } 757 return 6; 758 } else if (format[4] == '9') { 759 DCHECK(STRING_STARTS_WITH(format, "imm19")); 760 switch (format[5]) { 761 case 's': 762 DCHECK(STRING_STARTS_WITH(format, "imm19s")); 763 PrintSImm19(instr); 764 break; 765 case 'x': 766 DCHECK(STRING_STARTS_WITH(format, "imm19x")); 767 PrintXImm19(instr); 768 break; 769 } 770 return 6; 771 } else if (format[4] == '0' && format[5] == 's') { 772 DCHECK(STRING_STARTS_WITH(format, "imm10s")); 773 if (format[6] == '1') { 774 DCHECK(STRING_STARTS_WITH(format, "imm10s1")); 775 PrintMsaSImm10(instr, false); 776 } else if (format[6] == '2') { 777 DCHECK(STRING_STARTS_WITH(format, "imm10s2")); 778 PrintMsaSImm10(instr, true); 779 } 780 return 7; 781 } 782 } else if (format[3] == '2' && format[4] == '1') { 783 DCHECK(STRING_STARTS_WITH(format, "imm21")); 784 switch (format[5]) { 785 case 's': 786 DCHECK(STRING_STARTS_WITH(format, "imm21s")); 787 PrintSImm21(instr); 788 break; 789 case 'x': 790 DCHECK(STRING_STARTS_WITH(format, "imm21x")); 791 PrintXImm21(instr); 792 break; 793 case 'p': { // The PC relative address. 794 DCHECK(STRING_STARTS_WITH(format, "imm21p")); 795 int delta_pc = 0; 796 int n_bits = 0; 797 switch (format[6]) { 798 case '4': { 799 DCHECK(STRING_STARTS_WITH(format, "imm21p4")); 800 delta_pc = 4; 801 switch (format[8]) { 802 case '2': 803 DCHECK(STRING_STARTS_WITH(format, "imm21p4s2")); 804 n_bits = 2; 805 PrintPCImm21(instr, delta_pc, n_bits); 806 return 9; 807 } 808 } 809 } 810 } 811 } 812 return 6; 813 } else if (format[3] == '2' && format[4] == '6') { 814 DCHECK(STRING_STARTS_WITH(format, "imm26")); 815 switch (format[5]) { 816 case 's': 817 DCHECK(STRING_STARTS_WITH(format, "imm26s")); 818 PrintSImm26(instr); 819 break; 820 case 'x': 821 DCHECK(STRING_STARTS_WITH(format, "imm26x")); 822 PrintXImm26(instr); 823 break; 824 case 'p': { // The PC relative address. 825 DCHECK(STRING_STARTS_WITH(format, "imm26p")); 826 int delta_pc = 0; 827 int n_bits = 0; 828 switch (format[6]) { 829 case '4': { 830 DCHECK(STRING_STARTS_WITH(format, "imm26p4")); 831 delta_pc = 4; 832 switch (format[8]) { 833 case '2': 834 DCHECK(STRING_STARTS_WITH(format, "imm26p4s2")); 835 n_bits = 2; 836 PrintPCImm26(instr, delta_pc, n_bits); 837 return 9; 838 } 839 } 840 } 841 } 842 case 'j': { // Absolute address for jump instructions. 843 DCHECK(STRING_STARTS_WITH(format, "imm26j")); 844 PrintPCImm26(instr); 845 break; 846 } 847 } 848 return 6; 849 } else if (format[3] == '5') { 850 DCHECK(STRING_STARTS_WITH(format, "imm5")); 851 if (format[4] == 'u') { 852 DCHECK(STRING_STARTS_WITH(format, "imm5u")); 853 PrintMsaImm5(instr); 854 } else if (format[4] == 's') { 855 DCHECK(STRING_STARTS_WITH(format, "imm5s")); 856 PrintMsaSImm5(instr); 857 } 858 return 5; 859 } else if (format[3] == '8') { 860 DCHECK(STRING_STARTS_WITH(format, "imm8")); 861 PrintMsaImm8(instr); 862 return 4; 863 } else if (format[3] == '9') { 864 DCHECK(STRING_STARTS_WITH(format, "imm9")); 865 if (format[4] == 'u') { 866 DCHECK(STRING_STARTS_WITH(format, "imm9u")); 867 PrintUImm9(instr); 868 } else if (format[4] == 's') { 869 DCHECK(STRING_STARTS_WITH(format, "imm9s")); 870 PrintSImm9(instr); 871 } 872 return 5; 873 } else if (format[3] == 'b') { 874 DCHECK(STRING_STARTS_WITH(format, "immb")); 875 PrintMsaImmBit(instr); 876 return 4; 877 } else if (format[3] == 'e') { 878 DCHECK(STRING_STARTS_WITH(format, "imme")); 879 PrintMsaImmElm(instr); 880 return 4; 881 } 882 UNREACHABLE(); 883 } 884 case 'r': { // 'r: registers. 885 return FormatRegister(instr, format); 886 } 887 case 'f': { // 'f: FPUregisters. 888 return FormatFPURegister(instr, format); 889 } 890 case 'w': { // 'w: MSA Register 891 return FormatMSARegister(instr, format); 892 } 893 case 's': { // 'sa. 894 switch (format[1]) { 895 case 'a': 896 if (format[2] == '2') { 897 DCHECK(STRING_STARTS_WITH(format, "sa2")); // 'sa2 898 PrintLsaSa(instr); 899 return 3; 900 } else { 901 DCHECK(STRING_STARTS_WITH(format, "sa")); 902 PrintSa(instr); 903 return 2; 904 } 905 case 'd': { 906 DCHECK(STRING_STARTS_WITH(format, "sd")); 907 PrintSd(instr); 908 return 2; 909 } 910 case 's': { 911 if (format[2] == '1') { 912 DCHECK(STRING_STARTS_WITH(format, "ss1")); /* ext size */ 913 PrintSs1(instr); 914 return 3; 915 } else { 916 DCHECK(STRING_STARTS_WITH(format, "ss2")); /* ins size */ 917 PrintSs2(instr); 918 return 3; 919 } 920 } 921 } 922 } 923 case 'b': { 924 switch (format[1]) { 925 case 'c': { // 'bc - Special for bc1 cc field. 926 DCHECK(STRING_STARTS_WITH(format, "bc")); 927 PrintBc(instr); 928 return 2; 929 } 930 case 'p': { 931 switch (format[2]) { 932 case '2': { // 'bp2 933 DCHECK(STRING_STARTS_WITH(format, "bp2")); 934 PrintBp2(instr); 935 return 3; 936 } 937 } 938 } 939 } 940 } 941 case 'C': { // 'Cc - Special for c.xx.d cc field. 942 DCHECK(STRING_STARTS_WITH(format, "Cc")); 943 PrintCc(instr); 944 return 2; 945 } 946 case 't': 947 if (instr->IsMSAInstr()) { 948 PrintMsaDataFormat(instr); 949 } else { 950 PrintFormat(instr); 951 } 952 return 1; 953 } 954 UNREACHABLE(); 955} 956 957// Format takes a formatting string for a whole instruction and prints it into 958// the output buffer. All escaped options are handed to FormatOption to be 959// parsed further. 960void Decoder::Format(Instruction* instr, const char* format) { 961 char cur = *format++; 962 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 963 if (cur == '\'') { // Single quote is used as the formatting escape. 964 format += FormatOption(instr, format); 965 } else { 966 out_buffer_[out_buffer_pos_++] = cur; 967 } 968 cur = *format++; 969 } 970 out_buffer_[out_buffer_pos_] = '\0'; 971} 972 973// For currently unimplemented decodings the disassembler calls Unknown(instr) 974// which will just print "unknown" of the instruction bits. 975void Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); } 976 977bool Decoder::DecodeTypeRegisterRsType(Instruction* instr) { 978 switch (instr->FunctionFieldRaw()) { 979 case RINT: 980 Format(instr, "rint.'t 'fd, 'fs"); 981 break; 982 case MIN: 983 Format(instr, "min.'t 'fd, 'fs, 'ft"); 984 break; 985 case MAX: 986 Format(instr, "max.'t 'fd, 'fs, 'ft"); 987 break; 988 case MINA: 989 Format(instr, "mina.'t 'fd, 'fs, 'ft"); 990 break; 991 case MAXA: 992 Format(instr, "maxa.'t 'fd, 'fs, 'ft"); 993 break; 994 case SEL: 995 Format(instr, "sel.'t 'fd, 'fs, 'ft"); 996 break; 997 case SELEQZ_C: 998 Format(instr, "seleqz.'t 'fd, 'fs, 'ft"); 999 break; 1000 case SELNEZ_C: 1001 Format(instr, "selnez.'t 'fd, 'fs, 'ft"); 1002 break; 1003 case MOVZ_C: 1004 Format(instr, "movz.'t 'fd, 'fs, 'rt"); 1005 break; 1006 case MOVN_C: 1007 Format(instr, "movn.'t 'fd, 'fs, 'rt"); 1008 break; 1009 case MOVF: 1010 if (instr->Bit(16)) { 1011 Format(instr, "movt.'t 'fd, 'fs, 'Cc"); 1012 } else { 1013 Format(instr, "movf.'t 'fd, 'fs, 'Cc"); 1014 } 1015 break; 1016 case ADD_D: 1017 Format(instr, "add.'t 'fd, 'fs, 'ft"); 1018 break; 1019 case SUB_D: 1020 Format(instr, "sub.'t 'fd, 'fs, 'ft"); 1021 break; 1022 case MUL_D: 1023 Format(instr, "mul.'t 'fd, 'fs, 'ft"); 1024 break; 1025 case DIV_D: 1026 Format(instr, "div.'t 'fd, 'fs, 'ft"); 1027 break; 1028 case ABS_D: 1029 Format(instr, "abs.'t 'fd, 'fs"); 1030 break; 1031 case MOV_D: 1032 Format(instr, "mov.'t 'fd, 'fs"); 1033 break; 1034 case NEG_D: 1035 Format(instr, "neg.'t 'fd, 'fs"); 1036 break; 1037 case SQRT_D: 1038 Format(instr, "sqrt.'t 'fd, 'fs"); 1039 break; 1040 case RECIP_D: 1041 Format(instr, "recip.'t 'fd, 'fs"); 1042 break; 1043 case RSQRT_D: 1044 Format(instr, "rsqrt.'t 'fd, 'fs"); 1045 break; 1046 case CVT_W_D: 1047 Format(instr, "cvt.w.'t 'fd, 'fs"); 1048 break; 1049 case CVT_L_D: 1050 Format(instr, "cvt.l.'t 'fd, 'fs"); 1051 break; 1052 case TRUNC_W_D: 1053 Format(instr, "trunc.w.'t 'fd, 'fs"); 1054 break; 1055 case TRUNC_L_D: 1056 Format(instr, "trunc.l.'t 'fd, 'fs"); 1057 break; 1058 case ROUND_W_D: 1059 Format(instr, "round.w.'t 'fd, 'fs"); 1060 break; 1061 case ROUND_L_D: 1062 Format(instr, "round.l.'t 'fd, 'fs"); 1063 break; 1064 case FLOOR_W_D: 1065 Format(instr, "floor.w.'t 'fd, 'fs"); 1066 break; 1067 case FLOOR_L_D: 1068 Format(instr, "floor.l.'t 'fd, 'fs"); 1069 break; 1070 case CEIL_W_D: 1071 Format(instr, "ceil.w.'t 'fd, 'fs"); 1072 break; 1073 case CLASS_D: 1074 Format(instr, "class.'t 'fd, 'fs"); 1075 break; 1076 case CEIL_L_D: 1077 Format(instr, "ceil.l.'t 'fd, 'fs"); 1078 break; 1079 case CVT_S_D: 1080 Format(instr, "cvt.s.'t 'fd, 'fs"); 1081 break; 1082 case C_F_D: 1083 Format(instr, "c.f.'t 'fs, 'ft, 'Cc"); 1084 break; 1085 case C_UN_D: 1086 Format(instr, "c.un.'t 'fs, 'ft, 'Cc"); 1087 break; 1088 case C_EQ_D: 1089 Format(instr, "c.eq.'t 'fs, 'ft, 'Cc"); 1090 break; 1091 case C_UEQ_D: 1092 Format(instr, "c.ueq.'t 'fs, 'ft, 'Cc"); 1093 break; 1094 case C_OLT_D: 1095 Format(instr, "c.olt.'t 'fs, 'ft, 'Cc"); 1096 break; 1097 case C_ULT_D: 1098 Format(instr, "c.ult.'t 'fs, 'ft, 'Cc"); 1099 break; 1100 case C_OLE_D: 1101 Format(instr, "c.ole.'t 'fs, 'ft, 'Cc"); 1102 break; 1103 case C_ULE_D: 1104 Format(instr, "c.ule.'t 'fs, 'ft, 'Cc"); 1105 break; 1106 default: 1107 return false; 1108 } 1109 return true; 1110} 1111 1112void Decoder::DecodeTypeRegisterSRsType(Instruction* instr) { 1113 if (!DecodeTypeRegisterRsType(instr)) { 1114 switch (instr->FunctionFieldRaw()) { 1115 case CVT_D_S: 1116 Format(instr, "cvt.d.'t 'fd, 'fs"); 1117 break; 1118 case MADDF_S: 1119 Format(instr, "maddf.s 'fd, 'fs, 'ft"); 1120 break; 1121 case MSUBF_S: 1122 Format(instr, "msubf.s 'fd, 'fs, 'ft"); 1123 break; 1124 default: 1125 Format(instr, "unknown.cop1.'t"); 1126 break; 1127 } 1128 } 1129} 1130 1131void Decoder::DecodeTypeRegisterDRsType(Instruction* instr) { 1132 if (!DecodeTypeRegisterRsType(instr)) { 1133 switch (instr->FunctionFieldRaw()) { 1134 case MADDF_D: 1135 Format(instr, "maddf.d 'fd, 'fs, 'ft"); 1136 break; 1137 case MSUBF_D: 1138 Format(instr, "msubf.d 'fd, 'fs, 'ft"); 1139 break; 1140 default: 1141 Format(instr, "unknown.cop1.'t"); 1142 break; 1143 } 1144 } 1145} 1146 1147void Decoder::DecodeTypeRegisterLRsType(Instruction* instr) { 1148 switch (instr->FunctionFieldRaw()) { 1149 case CVT_D_L: 1150 Format(instr, "cvt.d.l 'fd, 'fs"); 1151 break; 1152 case CVT_S_L: 1153 Format(instr, "cvt.s.l 'fd, 'fs"); 1154 break; 1155 case CMP_AF: 1156 Format(instr, "cmp.af.d 'fd, 'fs, 'ft"); 1157 break; 1158 case CMP_UN: 1159 Format(instr, "cmp.un.d 'fd, 'fs, 'ft"); 1160 break; 1161 case CMP_EQ: 1162 Format(instr, "cmp.eq.d 'fd, 'fs, 'ft"); 1163 break; 1164 case CMP_UEQ: 1165 Format(instr, "cmp.ueq.d 'fd, 'fs, 'ft"); 1166 break; 1167 case CMP_LT: 1168 Format(instr, "cmp.lt.d 'fd, 'fs, 'ft"); 1169 break; 1170 case CMP_ULT: 1171 Format(instr, "cmp.ult.d 'fd, 'fs, 'ft"); 1172 break; 1173 case CMP_LE: 1174 Format(instr, "cmp.le.d 'fd, 'fs, 'ft"); 1175 break; 1176 case CMP_ULE: 1177 Format(instr, "cmp.ule.d 'fd, 'fs, 'ft"); 1178 break; 1179 case CMP_OR: 1180 Format(instr, "cmp.or.d 'fd, 'fs, 'ft"); 1181 break; 1182 case CMP_UNE: 1183 Format(instr, "cmp.une.d 'fd, 'fs, 'ft"); 1184 break; 1185 case CMP_NE: 1186 Format(instr, "cmp.ne.d 'fd, 'fs, 'ft"); 1187 break; 1188 default: 1189 UNREACHABLE(); 1190 } 1191} 1192 1193void Decoder::DecodeTypeRegisterWRsType(Instruction* instr) { 1194 switch (instr->FunctionValue()) { 1195 case CVT_S_W: // Convert word to float (single). 1196 Format(instr, "cvt.s.w 'fd, 'fs"); 1197 break; 1198 case CVT_D_W: // Convert word to double. 1199 Format(instr, "cvt.d.w 'fd, 'fs"); 1200 break; 1201 case CMP_AF: 1202 Format(instr, "cmp.af.s 'fd, 'fs, 'ft"); 1203 break; 1204 case CMP_UN: 1205 Format(instr, "cmp.un.s 'fd, 'fs, 'ft"); 1206 break; 1207 case CMP_EQ: 1208 Format(instr, "cmp.eq.s 'fd, 'fs, 'ft"); 1209 break; 1210 case CMP_UEQ: 1211 Format(instr, "cmp.ueq.s 'fd, 'fs, 'ft"); 1212 break; 1213 case CMP_LT: 1214 Format(instr, "cmp.lt.s 'fd, 'fs, 'ft"); 1215 break; 1216 case CMP_ULT: 1217 Format(instr, "cmp.ult.s 'fd, 'fs, 'ft"); 1218 break; 1219 case CMP_LE: 1220 Format(instr, "cmp.le.s 'fd, 'fs, 'ft"); 1221 break; 1222 case CMP_ULE: 1223 Format(instr, "cmp.ule.s 'fd, 'fs, 'ft"); 1224 break; 1225 case CMP_OR: 1226 Format(instr, "cmp.or.s 'fd, 'fs, 'ft"); 1227 break; 1228 case CMP_UNE: 1229 Format(instr, "cmp.une.s 'fd, 'fs, 'ft"); 1230 break; 1231 case CMP_NE: 1232 Format(instr, "cmp.ne.s 'fd, 'fs, 'ft"); 1233 break; 1234 default: 1235 UNREACHABLE(); 1236 } 1237} 1238 1239void Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) { 1240 switch (instr->FunctionFieldRaw()) { 1241 case JR: 1242 Format(instr, "jr 'rs"); 1243 break; 1244 case JALR: 1245 Format(instr, "jalr 'rs, 'rd"); 1246 break; 1247 case SLL: 1248 if (0x0 == static_cast<int>(instr->InstructionBits())) 1249 Format(instr, "nop"); 1250 else 1251 Format(instr, "sll 'rd, 'rt, 'sa"); 1252 break; 1253 case SRL: 1254 if (instr->RsValue() == 0) { 1255 Format(instr, "srl 'rd, 'rt, 'sa"); 1256 } else { 1257 if (IsMipsArchVariant(kMips32r2)) { 1258 Format(instr, "rotr 'rd, 'rt, 'sa"); 1259 } else { 1260 Unknown(instr); 1261 } 1262 } 1263 break; 1264 case SRA: 1265 Format(instr, "sra 'rd, 'rt, 'sa"); 1266 break; 1267 case SLLV: 1268 Format(instr, "sllv 'rd, 'rt, 'rs"); 1269 break; 1270 case SRLV: 1271 if (instr->SaValue() == 0) { 1272 Format(instr, "srlv 'rd, 'rt, 'rs"); 1273 } else { 1274 if (IsMipsArchVariant(kMips32r2)) { 1275 Format(instr, "rotrv 'rd, 'rt, 'rs"); 1276 } else { 1277 Unknown(instr); 1278 } 1279 } 1280 break; 1281 case SRAV: 1282 Format(instr, "srav 'rd, 'rt, 'rs"); 1283 break; 1284 case LSA: 1285 Format(instr, "lsa 'rd, 'rt, 'rs, 'sa2"); 1286 break; 1287 case MFHI: 1288 if (instr->Bits(25, 16) == 0) { 1289 Format(instr, "mfhi 'rd"); 1290 } else { 1291 if ((instr->FunctionFieldRaw() == CLZ_R6) && (instr->FdValue() == 1)) { 1292 Format(instr, "clz 'rd, 'rs"); 1293 } else if ((instr->FunctionFieldRaw() == CLO_R6) && 1294 (instr->FdValue() == 1)) { 1295 Format(instr, "clo 'rd, 'rs"); 1296 } 1297 } 1298 break; 1299 case MFLO: 1300 Format(instr, "mflo 'rd"); 1301 break; 1302 case MULT: // @Mips32r6 == MUL_MUH. 1303 if (!IsMipsArchVariant(kMips32r6)) { 1304 Format(instr, "mult 'rs, 'rt"); 1305 } else { 1306 if (instr->SaValue() == MUL_OP) { 1307 Format(instr, "mul 'rd, 'rs, 'rt"); 1308 } else { 1309 Format(instr, "muh 'rd, 'rs, 'rt"); 1310 } 1311 } 1312 break; 1313 case MULTU: // @Mips32r6 == MUL_MUH_U. 1314 if (!IsMipsArchVariant(kMips32r6)) { 1315 Format(instr, "multu 'rs, 'rt"); 1316 } else { 1317 if (instr->SaValue() == MUL_OP) { 1318 Format(instr, "mulu 'rd, 'rs, 'rt"); 1319 } else { 1320 Format(instr, "muhu 'rd, 'rs, 'rt"); 1321 } 1322 } 1323 break; 1324 case DIV: // @Mips32r6 == DIV_MOD. 1325 if (!IsMipsArchVariant(kMips32r6)) { 1326 Format(instr, "div 'rs, 'rt"); 1327 } else { 1328 if (instr->SaValue() == DIV_OP) { 1329 Format(instr, "div 'rd, 'rs, 'rt"); 1330 } else { 1331 Format(instr, "mod 'rd, 'rs, 'rt"); 1332 } 1333 } 1334 break; 1335 case DIVU: // @Mips32r6 == DIV_MOD_U. 1336 if (!IsMipsArchVariant(kMips32r6)) { 1337 Format(instr, "divu 'rs, 'rt"); 1338 } else { 1339 if (instr->SaValue() == DIV_OP) { 1340 Format(instr, "divu 'rd, 'rs, 'rt"); 1341 } else { 1342 Format(instr, "modu 'rd, 'rs, 'rt"); 1343 } 1344 } 1345 break; 1346 case ADD: 1347 Format(instr, "add 'rd, 'rs, 'rt"); 1348 break; 1349 case ADDU: 1350 Format(instr, "addu 'rd, 'rs, 'rt"); 1351 break; 1352 case SUB: 1353 Format(instr, "sub 'rd, 'rs, 'rt"); 1354 break; 1355 case SUBU: 1356 Format(instr, "subu 'rd, 'rs, 'rt"); 1357 break; 1358 case AND: 1359 Format(instr, "and 'rd, 'rs, 'rt"); 1360 break; 1361 case OR: 1362 if (0 == instr->RsValue()) { 1363 Format(instr, "mov 'rd, 'rt"); 1364 } else if (0 == instr->RtValue()) { 1365 Format(instr, "mov 'rd, 'rs"); 1366 } else { 1367 Format(instr, "or 'rd, 'rs, 'rt"); 1368 } 1369 break; 1370 case XOR: 1371 Format(instr, "xor 'rd, 'rs, 'rt"); 1372 break; 1373 case NOR: 1374 Format(instr, "nor 'rd, 'rs, 'rt"); 1375 break; 1376 case SLT: 1377 Format(instr, "slt 'rd, 'rs, 'rt"); 1378 break; 1379 case SLTU: 1380 Format(instr, "sltu 'rd, 'rs, 'rt"); 1381 break; 1382 case BREAK: 1383 Format(instr, "break, code: 'code"); 1384 break; 1385 case TGE: 1386 Format(instr, "tge 'rs, 'rt, code: 'code"); 1387 break; 1388 case TGEU: 1389 Format(instr, "tgeu 'rs, 'rt, code: 'code"); 1390 break; 1391 case TLT: 1392 Format(instr, "tlt 'rs, 'rt, code: 'code"); 1393 break; 1394 case TLTU: 1395 Format(instr, "tltu 'rs, 'rt, code: 'code"); 1396 break; 1397 case TEQ: 1398 Format(instr, "teq 'rs, 'rt, code: 'code"); 1399 break; 1400 case TNE: 1401 Format(instr, "tne 'rs, 'rt, code: 'code"); 1402 break; 1403 case SYNC: 1404 Format(instr, "sync"); 1405 break; 1406 case MOVZ: 1407 Format(instr, "movz 'rd, 'rs, 'rt"); 1408 break; 1409 case MOVN: 1410 Format(instr, "movn 'rd, 'rs, 'rt"); 1411 break; 1412 case MOVCI: 1413 if (instr->Bit(16)) { 1414 Format(instr, "movt 'rd, 'rs, 'bc"); 1415 } else { 1416 Format(instr, "movf 'rd, 'rs, 'bc"); 1417 } 1418 break; 1419 case SELEQZ_S: 1420 Format(instr, "seleqz 'rd, 'rs, 'rt"); 1421 break; 1422 case SELNEZ_S: 1423 Format(instr, "selnez 'rd, 'rs, 'rt"); 1424 break; 1425 default: 1426 UNREACHABLE(); 1427 } 1428} 1429 1430void Decoder::DecodeTypeRegisterSPECIAL2(Instruction* instr) { 1431 switch (instr->FunctionFieldRaw()) { 1432 case MUL: 1433 Format(instr, "mul 'rd, 'rs, 'rt"); 1434 break; 1435 case CLZ: 1436 if (!IsMipsArchVariant(kMips32r6)) { 1437 Format(instr, "clz 'rd, 'rs"); 1438 } 1439 break; 1440 default: 1441 UNREACHABLE(); 1442 } 1443} 1444 1445void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) { 1446 switch (instr->FunctionFieldRaw()) { 1447 case INS: { 1448 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { 1449 Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); 1450 } else { 1451 Unknown(instr); 1452 } 1453 break; 1454 } 1455 case EXT: { 1456 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { 1457 Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); 1458 } else { 1459 Unknown(instr); 1460 } 1461 break; 1462 } 1463 case BSHFL: { 1464 int sa = instr->SaFieldRaw() >> kSaShift; 1465 switch (sa) { 1466 case BITSWAP: { 1467 if (IsMipsArchVariant(kMips32r6)) { 1468 Format(instr, "bitswap 'rd, 'rt"); 1469 } else { 1470 Unknown(instr); 1471 } 1472 break; 1473 } 1474 case SEB: { 1475 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { 1476 Format(instr, "seb 'rd, 'rt"); 1477 } else { 1478 Unknown(instr); 1479 } 1480 break; 1481 } 1482 case SEH: { 1483 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { 1484 Format(instr, "seh 'rd, 'rt"); 1485 } else { 1486 Unknown(instr); 1487 } 1488 break; 1489 } 1490 case WSBH: { 1491 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { 1492 Format(instr, "wsbh 'rd, 'rt"); 1493 } else { 1494 Unknown(instr); 1495 } 1496 break; 1497 } 1498 case LL_R6: { 1499 DCHECK(IsMipsArchVariant(kMips32r6)); 1500 Format(instr, "llwp 'rd, 'rt, 0('rs)"); 1501 break; 1502 } 1503 case SC_R6: { 1504 DCHECK(IsMipsArchVariant(kMips32r6)); 1505 Format(instr, "scwp 'rd, 'rt, 0('rs)"); 1506 break; 1507 } 1508 default: { 1509 sa >>= kBp2Bits; 1510 switch (sa) { 1511 case ALIGN: { 1512 if (IsMipsArchVariant(kMips32r6)) { 1513 Format(instr, "align 'rd, 'rs, 'rt, 'bp2"); 1514 } else { 1515 Unknown(instr); 1516 } 1517 break; 1518 } 1519 default: 1520 UNREACHABLE(); 1521 } 1522 } 1523 } 1524 break; 1525 } 1526 default: 1527 UNREACHABLE(); 1528 } 1529} 1530 1531void Decoder::DecodeTypeRegister(Instruction* instr) { 1532 switch (instr->OpcodeFieldRaw()) { 1533 case COP1: // Coprocessor instructions. 1534 switch (instr->RsFieldRaw()) { 1535 case BC1: // bc1 handled in DecodeTypeImmediate. 1536 UNREACHABLE(); 1537 case MFC1: 1538 Format(instr, "mfc1 'rt, 'fs"); 1539 break; 1540 case MFHC1: 1541 Format(instr, "mfhc1 'rt, 'fs"); 1542 break; 1543 case MTC1: 1544 Format(instr, "mtc1 'rt, 'fs"); 1545 break; 1546 // These are called "fs" too, although they are not FPU registers. 1547 case CTC1: 1548 Format(instr, "ctc1 'rt, 'fs"); 1549 break; 1550 case CFC1: 1551 Format(instr, "cfc1 'rt, 'fs"); 1552 break; 1553 case MTHC1: 1554 Format(instr, "mthc1 'rt, 'fs"); 1555 break; 1556 case S: 1557 DecodeTypeRegisterSRsType(instr); 1558 break; 1559 case D: 1560 DecodeTypeRegisterDRsType(instr); 1561 break; 1562 case L: 1563 DecodeTypeRegisterLRsType(instr); 1564 break; 1565 case W: 1566 DecodeTypeRegisterWRsType(instr); 1567 break; 1568 case PS: 1569 UNIMPLEMENTED_MIPS(); 1570 break; 1571 default: 1572 UNREACHABLE(); 1573 } 1574 break; 1575 case COP1X: 1576 switch (instr->FunctionFieldRaw()) { 1577 case MADD_S: 1578 Format(instr, "madd.s 'fd, 'fr, 'fs, 'ft"); 1579 break; 1580 case MADD_D: 1581 Format(instr, "madd.d 'fd, 'fr, 'fs, 'ft"); 1582 break; 1583 case MSUB_S: 1584 Format(instr, "msub.s 'fd, 'fr, 'fs, 'ft"); 1585 break; 1586 case MSUB_D: 1587 Format(instr, "msub.d 'fd, 'fr, 'fs, 'ft"); 1588 break; 1589 default: 1590 UNREACHABLE(); 1591 } 1592 break; 1593 case SPECIAL: 1594 DecodeTypeRegisterSPECIAL(instr); 1595 break; 1596 case SPECIAL2: 1597 DecodeTypeRegisterSPECIAL2(instr); 1598 break; 1599 case SPECIAL3: 1600 DecodeTypeRegisterSPECIAL3(instr); 1601 break; 1602 case MSA: 1603 switch (instr->MSAMinorOpcodeField()) { 1604 case kMsaMinor3R: 1605 DecodeTypeMsa3R(instr); 1606 break; 1607 case kMsaMinor3RF: 1608 DecodeTypeMsa3RF(instr); 1609 break; 1610 case kMsaMinorVEC: 1611 DecodeTypeMsaVec(instr); 1612 break; 1613 case kMsaMinor2R: 1614 DecodeTypeMsa2R(instr); 1615 break; 1616 case kMsaMinor2RF: 1617 DecodeTypeMsa2RF(instr); 1618 break; 1619 case kMsaMinorELM: 1620 DecodeTypeMsaELM(instr); 1621 break; 1622 default: 1623 UNREACHABLE(); 1624 } 1625 break; 1626 default: 1627 UNREACHABLE(); 1628 } 1629} 1630 1631void Decoder::DecodeTypeImmediateSPECIAL3(Instruction* instr) { 1632 switch (instr->FunctionFieldRaw()) { 1633 case LL_R6: { 1634 if (IsMipsArchVariant(kMips32r6)) { 1635 if (instr->Bit(6)) { 1636 Format(instr, "llx 'rt, 'imm9s('rs)"); 1637 } else { 1638 Format(instr, "ll 'rt, 'imm9s('rs)"); 1639 } 1640 } else { 1641 Unknown(instr); 1642 } 1643 break; 1644 } 1645 case SC_R6: { 1646 if (IsMipsArchVariant(kMips32r6)) { 1647 if (instr->Bit(6)) { 1648 Format(instr, "scx 'rt, 'imm9s('rs)"); 1649 } else { 1650 Format(instr, "sc 'rt, 'imm9s('rs)"); 1651 } 1652 } else { 1653 Unknown(instr); 1654 } 1655 break; 1656 } 1657 default: 1658 UNREACHABLE(); 1659 } 1660} 1661 1662void Decoder::DecodeTypeImmediate(Instruction* instr) { 1663 switch (instr->OpcodeFieldRaw()) { 1664 case COP1: 1665 switch (instr->RsFieldRaw()) { 1666 case BC1: 1667 if (instr->FBtrueValue()) { 1668 Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2"); 1669 } else { 1670 Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2"); 1671 } 1672 break; 1673 case BC1EQZ: 1674 Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2"); 1675 break; 1676 case BC1NEZ: 1677 Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2"); 1678 break; 1679 case BZ_V: 1680 case BZ_B: 1681 case BZ_H: 1682 case BZ_W: 1683 case BZ_D: 1684 Format(instr, "bz.'t 'wt, 'imm16s -> 'imm16p4s2"); 1685 break; 1686 case BNZ_V: 1687 case BNZ_B: 1688 case BNZ_H: 1689 case BNZ_W: 1690 case BNZ_D: 1691 Format(instr, "bnz.'t 'wt, 'imm16s -> 'imm16p4s2"); 1692 break; 1693 default: 1694 UNREACHABLE(); 1695 } 1696 1697 break; // Case COP1. 1698 // ------------- REGIMM class. 1699 case REGIMM: 1700 switch (instr->RtFieldRaw()) { 1701 case BLTZ: 1702 Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2"); 1703 break; 1704 case BLTZAL: 1705 if (instr->RsValue() == 0) { 1706 Format(instr, "nal"); 1707 } else { 1708 Format(instr, "bltzal 'rs, 'imm16u -> 'imm16p4s2"); 1709 } 1710 break; 1711 case BGEZ: 1712 Format(instr, "bgez 'rs, 'imm16u -> 'imm16p4s2"); 1713 break; 1714 case BGEZAL: { 1715 if (instr->RsValue() == 0) 1716 Format(instr, "bal 'imm16s -> 'imm16p4s2"); 1717 else 1718 Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2"); 1719 break; 1720 } 1721 case BGEZALL: 1722 Format(instr, "bgezall 'rs, 'imm16u -> 'imm16p4s2"); 1723 break; 1724 default: 1725 UNREACHABLE(); 1726 } 1727 break; // Case REGIMM. 1728 // ------------- Branch instructions. 1729 case BEQ: 1730 Format(instr, "beq 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1731 break; 1732 case BC: 1733 Format(instr, "bc 'imm26s -> 'imm26p4s2"); 1734 break; 1735 case BALC: 1736 Format(instr, "balc 'imm26s -> 'imm26p4s2"); 1737 break; 1738 case BNE: 1739 Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1740 break; 1741 case BLEZ: 1742 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { 1743 Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2"); 1744 } else if ((instr->RtValue() != instr->RsValue()) && 1745 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 1746 Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1747 } else if ((instr->RtValue() == instr->RsValue()) && 1748 (instr->RtValue() != 0)) { 1749 Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2"); 1750 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 1751 Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2"); 1752 } else { 1753 UNREACHABLE(); 1754 } 1755 break; 1756 case BGTZ: 1757 if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { 1758 Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2"); 1759 } else if ((instr->RtValue() != instr->RsValue()) && 1760 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 1761 Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1762 } else if ((instr->RtValue() == instr->RsValue()) && 1763 (instr->RtValue() != 0)) { 1764 Format(instr, "bltzalc 'rt, 'imm16u -> 'imm16p4s2"); 1765 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 1766 Format(instr, "bgtzalc 'rt, 'imm16u -> 'imm16p4s2"); 1767 } else { 1768 UNREACHABLE(); 1769 } 1770 break; 1771 case BLEZL: 1772 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { 1773 Format(instr, "bgezc 'rt, 'imm16u -> 'imm16p4s2"); 1774 } else if ((instr->RtValue() != instr->RsValue()) && 1775 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 1776 Format(instr, "bgec 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1777 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 1778 Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2"); 1779 } else { 1780 UNREACHABLE(); 1781 } 1782 break; 1783 case BGTZL: 1784 if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { 1785 Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2"); 1786 } else if ((instr->RtValue() != instr->RsValue()) && 1787 (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 1788 Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 1789 } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 1790 Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2"); 1791 } else { 1792 UNREACHABLE(); 1793 } 1794 break; 1795 case POP66: 1796 if (instr->RsValue() == JIC) { 1797 Format(instr, "jic 'rt, 'imm16s"); 1798 } else { 1799 Format(instr, "beqzc 'rs, 'imm21s -> 'imm21p4s2"); 1800 } 1801 break; 1802 case POP76: 1803 if (instr->RsValue() == JIALC) { 1804 Format(instr, "jialc 'rt, 'imm16s"); 1805 } else { 1806 Format(instr, "bnezc 'rs, 'imm21s -> 'imm21p4s2"); 1807 } 1808 break; 1809 // ------------- Arithmetic instructions. 1810 case ADDI: 1811 if (!IsMipsArchVariant(kMips32r6)) { 1812 Format(instr, "addi 'rt, 'rs, 'imm16s"); 1813 } else { 1814 int rs_reg = instr->RsValue(); 1815 int rt_reg = instr->RtValue(); 1816 // Check if BOVC, BEQZALC or BEQC instruction. 1817 if (rs_reg >= rt_reg) { 1818 Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 1819 } else { 1820 DCHECK_GT(rt_reg, 0); 1821 if (rs_reg == 0) { 1822 Format(instr, "beqzalc 'rt, 'imm16s -> 'imm16p4s2"); 1823 } else { 1824 Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 1825 } 1826 } 1827 } 1828 break; 1829 case DADDI: 1830 if (IsMipsArchVariant(kMips32r6)) { 1831 int rs_reg = instr->RsValue(); 1832 int rt_reg = instr->RtValue(); 1833 // Check if BNVC, BNEZALC or BNEC instruction. 1834 if (rs_reg >= rt_reg) { 1835 Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 1836 } else { 1837 DCHECK_GT(rt_reg, 0); 1838 if (rs_reg == 0) { 1839 Format(instr, "bnezalc 'rt, 'imm16s -> 'imm16p4s2"); 1840 } else { 1841 Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 1842 } 1843 } 1844 } 1845 break; 1846 case ADDIU: 1847 Format(instr, "addiu 'rt, 'rs, 'imm16s"); 1848 break; 1849 case SLTI: 1850 Format(instr, "slti 'rt, 'rs, 'imm16s"); 1851 break; 1852 case SLTIU: 1853 Format(instr, "sltiu 'rt, 'rs, 'imm16u"); 1854 break; 1855 case ANDI: 1856 Format(instr, "andi 'rt, 'rs, 'imm16x"); 1857 break; 1858 case ORI: 1859 Format(instr, "ori 'rt, 'rs, 'imm16x"); 1860 break; 1861 case XORI: 1862 Format(instr, "xori 'rt, 'rs, 'imm16x"); 1863 break; 1864 case LUI: 1865 if (!IsMipsArchVariant(kMips32r6)) { 1866 Format(instr, "lui 'rt, 'imm16x"); 1867 } else { 1868 if (instr->RsValue() != 0) { 1869 Format(instr, "aui 'rt, 'rs, 'imm16x"); 1870 } else { 1871 Format(instr, "lui 'rt, 'imm16x"); 1872 } 1873 } 1874 break; 1875 // ------------- Memory instructions. 1876 case LB: 1877 Format(instr, "lb 'rt, 'imm16s('rs)"); 1878 break; 1879 case LH: 1880 Format(instr, "lh 'rt, 'imm16s('rs)"); 1881 break; 1882 case LWL: 1883 Format(instr, "lwl 'rt, 'imm16s('rs)"); 1884 break; 1885 case LW: 1886 Format(instr, "lw 'rt, 'imm16s('rs)"); 1887 break; 1888 case LBU: 1889 Format(instr, "lbu 'rt, 'imm16s('rs)"); 1890 break; 1891 case LHU: 1892 Format(instr, "lhu 'rt, 'imm16s('rs)"); 1893 break; 1894 case LWR: 1895 Format(instr, "lwr 'rt, 'imm16s('rs)"); 1896 break; 1897 case PREF: 1898 Format(instr, "pref 'rt, 'imm16s('rs)"); 1899 break; 1900 case SB: 1901 Format(instr, "sb 'rt, 'imm16s('rs)"); 1902 break; 1903 case SH: 1904 Format(instr, "sh 'rt, 'imm16s('rs)"); 1905 break; 1906 case SWL: 1907 Format(instr, "swl 'rt, 'imm16s('rs)"); 1908 break; 1909 case SW: 1910 Format(instr, "sw 'rt, 'imm16s('rs)"); 1911 break; 1912 case SWR: 1913 Format(instr, "swr 'rt, 'imm16s('rs)"); 1914 break; 1915 case LL: 1916 if (IsMipsArchVariant(kMips32r6)) { 1917 Unknown(instr); 1918 } else { 1919 Format(instr, "ll 'rt, 'imm16s('rs)"); 1920 } 1921 break; 1922 case SC: 1923 if (IsMipsArchVariant(kMips32r6)) { 1924 Unknown(instr); 1925 } else { 1926 Format(instr, "sc 'rt, 'imm16s('rs)"); 1927 } 1928 break; 1929 case LWC1: 1930 Format(instr, "lwc1 'ft, 'imm16s('rs)"); 1931 break; 1932 case LDC1: 1933 Format(instr, "ldc1 'ft, 'imm16s('rs)"); 1934 break; 1935 case SWC1: 1936 Format(instr, "swc1 'ft, 'imm16s('rs)"); 1937 break; 1938 case SDC1: 1939 Format(instr, "sdc1 'ft, 'imm16s('rs)"); 1940 break; 1941 case PCREL: { 1942 int32_t imm21 = instr->Imm21Value(); 1943 // rt field: 5-bits checking 1944 uint8_t rt = (imm21 >> kImm16Bits); 1945 switch (rt) { 1946 case ALUIPC: 1947 Format(instr, "aluipc 'rs, 'imm16s"); 1948 break; 1949 case AUIPC: 1950 Format(instr, "auipc 'rs, 'imm16s"); 1951 break; 1952 default: { 1953 // rt field: checking of the most significant 2-bits 1954 rt = (imm21 >> kImm19Bits); 1955 switch (rt) { 1956 case LWPC: 1957 Format(instr, "lwpc 'rs, 'imm19s"); 1958 break; 1959 case ADDIUPC: 1960 Format(instr, "addiupc 'rs, 'imm19s"); 1961 break; 1962 default: 1963 UNREACHABLE(); 1964 } 1965 } 1966 } 1967 break; 1968 } 1969 case SPECIAL3: 1970 DecodeTypeImmediateSPECIAL3(instr); 1971 break; 1972 case MSA: 1973 switch (instr->MSAMinorOpcodeField()) { 1974 case kMsaMinorI8: 1975 DecodeTypeMsaI8(instr); 1976 break; 1977 case kMsaMinorI5: 1978 DecodeTypeMsaI5(instr); 1979 break; 1980 case kMsaMinorI10: 1981 DecodeTypeMsaI10(instr); 1982 break; 1983 case kMsaMinorELM: 1984 DecodeTypeMsaELM(instr); 1985 break; 1986 case kMsaMinorBIT: 1987 DecodeTypeMsaBIT(instr); 1988 break; 1989 case kMsaMinorMI10: 1990 DecodeTypeMsaMI10(instr); 1991 break; 1992 default: 1993 UNREACHABLE(); 1994 } 1995 break; 1996 default: 1997 printf("a 0x%x \n", instr->OpcodeFieldRaw()); 1998 UNREACHABLE(); 1999 } 2000} 2001 2002void Decoder::DecodeTypeJump(Instruction* instr) { 2003 switch (instr->OpcodeFieldRaw()) { 2004 case J: 2005 Format(instr, "j 'imm26x -> 'imm26j"); 2006 break; 2007 case JAL: 2008 Format(instr, "jal 'imm26x -> 'imm26j"); 2009 break; 2010 default: 2011 UNREACHABLE(); 2012 } 2013} 2014 2015void Decoder::DecodeTypeMsaI8(Instruction* instr) { 2016 uint32_t opcode = instr->InstructionBits() & kMsaI8Mask; 2017 2018 switch (opcode) { 2019 case ANDI_B: 2020 Format(instr, "andi.b 'wd, 'ws, 'imm8"); 2021 break; 2022 case ORI_B: 2023 Format(instr, "ori.b 'wd, 'ws, 'imm8"); 2024 break; 2025 case NORI_B: 2026 Format(instr, "nori.b 'wd, 'ws, 'imm8"); 2027 break; 2028 case XORI_B: 2029 Format(instr, "xori.b 'wd, 'ws, 'imm8"); 2030 break; 2031 case BMNZI_B: 2032 Format(instr, "bmnzi.b 'wd, 'ws, 'imm8"); 2033 break; 2034 case BMZI_B: 2035 Format(instr, "bmzi.b 'wd, 'ws, 'imm8"); 2036 break; 2037 case BSELI_B: 2038 Format(instr, "bseli.b 'wd, 'ws, 'imm8"); 2039 break; 2040 case SHF_B: 2041 Format(instr, "shf.b 'wd, 'ws, 'imm8"); 2042 break; 2043 case SHF_H: 2044 Format(instr, "shf.h 'wd, 'ws, 'imm8"); 2045 break; 2046 case SHF_W: 2047 Format(instr, "shf.w 'wd, 'ws, 'imm8"); 2048 break; 2049 default: 2050 UNREACHABLE(); 2051 } 2052} 2053 2054void Decoder::DecodeTypeMsaI5(Instruction* instr) { 2055 uint32_t opcode = instr->InstructionBits() & kMsaI5Mask; 2056 2057 switch (opcode) { 2058 case ADDVI: 2059 Format(instr, "addvi.'t 'wd, 'ws, 'imm5u"); 2060 break; 2061 case SUBVI: 2062 Format(instr, "subvi.'t 'wd, 'ws, 'imm5u"); 2063 break; 2064 case MAXI_S: 2065 Format(instr, "maxi_s.'t 'wd, 'ws, 'imm5s"); 2066 break; 2067 case MAXI_U: 2068 Format(instr, "maxi_u.'t 'wd, 'ws, 'imm5u"); 2069 break; 2070 case MINI_S: 2071 Format(instr, "mini_s.'t 'wd, 'ws, 'imm5s"); 2072 break; 2073 case MINI_U: 2074 Format(instr, "mini_u.'t 'wd, 'ws, 'imm5u"); 2075 break; 2076 case CEQI: 2077 Format(instr, "ceqi.'t 'wd, 'ws, 'imm5s"); 2078 break; 2079 case CLTI_S: 2080 Format(instr, "clti_s.'t 'wd, 'ws, 'imm5s"); 2081 break; 2082 case CLTI_U: 2083 Format(instr, "clti_u.'t 'wd, 'ws, 'imm5u"); 2084 break; 2085 case CLEI_S: 2086 Format(instr, "clei_s.'t 'wd, 'ws, 'imm5s"); 2087 break; 2088 case CLEI_U: 2089 Format(instr, "clei_u.'t 'wd, 'ws, 'imm5u"); 2090 break; 2091 default: 2092 UNREACHABLE(); 2093 } 2094} 2095 2096void Decoder::DecodeTypeMsaI10(Instruction* instr) { 2097 uint32_t opcode = instr->InstructionBits() & kMsaI5Mask; 2098 if (opcode == LDI) { 2099 Format(instr, "ldi.'t 'wd, 'imm10s1"); 2100 } else { 2101 UNREACHABLE(); 2102 } 2103} 2104 2105void Decoder::DecodeTypeMsaELM(Instruction* instr) { 2106 uint32_t opcode = instr->InstructionBits() & kMsaELMMask; 2107 switch (opcode) { 2108 case SLDI: 2109 if (instr->Bits(21, 16) == 0x3E) { 2110 Format(instr, "ctcmsa "); 2111 PrintMSAControlRegister(instr->WdValue()); 2112 Print(", "); 2113 PrintRegister(instr->WsValue()); 2114 } else { 2115 Format(instr, "sldi.'t 'wd, 'ws['imme]"); 2116 } 2117 break; 2118 case SPLATI: 2119 if (instr->Bits(21, 16) == 0x3E) { 2120 Format(instr, "cfcmsa "); 2121 PrintRegister(instr->WdValue()); 2122 Print(", "); 2123 PrintMSAControlRegister(instr->WsValue()); 2124 } else { 2125 Format(instr, "splati.'t 'wd, 'ws['imme]"); 2126 } 2127 break; 2128 case COPY_S: 2129 if (instr->Bits(21, 16) == 0x3E) { 2130 Format(instr, "move.v 'wd, 'ws"); 2131 } else { 2132 Format(instr, "copy_s.'t "); 2133 PrintMsaCopy(instr); 2134 } 2135 break; 2136 case COPY_U: 2137 Format(instr, "copy_u.'t "); 2138 PrintMsaCopy(instr); 2139 break; 2140 case INSERT: 2141 Format(instr, "insert.'t 'wd['imme], "); 2142 PrintRegister(instr->WsValue()); 2143 break; 2144 case INSVE: 2145 Format(instr, "insve.'t 'wd['imme], 'ws[0]"); 2146 break; 2147 default: 2148 UNREACHABLE(); 2149 } 2150} 2151 2152void Decoder::DecodeTypeMsaBIT(Instruction* instr) { 2153 uint32_t opcode = instr->InstructionBits() & kMsaBITMask; 2154 2155 switch (opcode) { 2156 case SLLI: 2157 Format(instr, "slli.'t 'wd, 'ws, 'immb"); 2158 break; 2159 case SRAI: 2160 Format(instr, "srai.'t 'wd, 'ws, 'immb"); 2161 break; 2162 case SRLI: 2163 Format(instr, "srli.'t 'wd, 'ws, 'immb"); 2164 break; 2165 case BCLRI: 2166 Format(instr, "bclri.'t 'wd, 'ws, 'immb"); 2167 break; 2168 case BSETI: 2169 Format(instr, "bseti.'t 'wd, 'ws, 'immb"); 2170 break; 2171 case BNEGI: 2172 Format(instr, "bnegi.'t 'wd, 'ws, 'immb"); 2173 break; 2174 case BINSLI: 2175 Format(instr, "binsli.'t 'wd, 'ws, 'immb"); 2176 break; 2177 case BINSRI: 2178 Format(instr, "binsri.'t 'wd, 'ws, 'immb"); 2179 break; 2180 case SAT_S: 2181 Format(instr, "sat_s.'t 'wd, 'ws, 'immb"); 2182 break; 2183 case SAT_U: 2184 Format(instr, "sat_u.'t 'wd, 'ws, 'immb"); 2185 break; 2186 case SRARI: 2187 Format(instr, "srari.'t 'wd, 'ws, 'immb"); 2188 break; 2189 case SRLRI: 2190 Format(instr, "srlri.'t 'wd, 'ws, 'immb"); 2191 break; 2192 default: 2193 UNREACHABLE(); 2194 } 2195} 2196 2197void Decoder::DecodeTypeMsaMI10(Instruction* instr) { 2198 uint32_t opcode = instr->InstructionBits() & kMsaMI10Mask; 2199 if (opcode == MSA_LD) { 2200 Format(instr, "ld.'t 'wd, 'imm10s2("); 2201 PrintRegister(instr->WsValue()); 2202 Print(")"); 2203 } else if (opcode == MSA_ST) { 2204 Format(instr, "st.'t 'wd, 'imm10s2("); 2205 PrintRegister(instr->WsValue()); 2206 Print(")"); 2207 } else { 2208 UNREACHABLE(); 2209 } 2210} 2211 2212void Decoder::DecodeTypeMsa3R(Instruction* instr) { 2213 uint32_t opcode = instr->InstructionBits() & kMsa3RMask; 2214 switch (opcode) { 2215 case SLL_MSA: 2216 Format(instr, "sll.'t 'wd, 'ws, 'wt"); 2217 break; 2218 case SRA_MSA: 2219 Format(instr, "sra.'t 'wd, 'ws, 'wt"); 2220 break; 2221 case SRL_MSA: 2222 Format(instr, "srl.'t 'wd, 'ws, 'wt"); 2223 break; 2224 case BCLR: 2225 Format(instr, "bclr.'t 'wd, 'ws, 'wt"); 2226 break; 2227 case BSET: 2228 Format(instr, "bset.'t 'wd, 'ws, 'wt"); 2229 break; 2230 case BNEG: 2231 Format(instr, "bneg.'t 'wd, 'ws, 'wt"); 2232 break; 2233 case BINSL: 2234 Format(instr, "binsl.'t 'wd, 'ws, 'wt"); 2235 break; 2236 case BINSR: 2237 Format(instr, "binsr.'t 'wd, 'ws, 'wt"); 2238 break; 2239 case ADDV: 2240 Format(instr, "addv.'t 'wd, 'ws, 'wt"); 2241 break; 2242 case SUBV: 2243 Format(instr, "subv.'t 'wd, 'ws, 'wt"); 2244 break; 2245 case MAX_S: 2246 Format(instr, "max_s.'t 'wd, 'ws, 'wt"); 2247 break; 2248 case MAX_U: 2249 Format(instr, "max_u.'t 'wd, 'ws, 'wt"); 2250 break; 2251 case MIN_S: 2252 Format(instr, "min_s.'t 'wd, 'ws, 'wt"); 2253 break; 2254 case MIN_U: 2255 Format(instr, "min_u.'t 'wd, 'ws, 'wt"); 2256 break; 2257 case MAX_A: 2258 Format(instr, "max_a.'t 'wd, 'ws, 'wt"); 2259 break; 2260 case MIN_A: 2261 Format(instr, "min_a.'t 'wd, 'ws, 'wt"); 2262 break; 2263 case CEQ: 2264 Format(instr, "ceq.'t 'wd, 'ws, 'wt"); 2265 break; 2266 case CLT_S: 2267 Format(instr, "clt_s.'t 'wd, 'ws, 'wt"); 2268 break; 2269 case CLT_U: 2270 Format(instr, "clt_u.'t 'wd, 'ws, 'wt"); 2271 break; 2272 case CLE_S: 2273 Format(instr, "cle_s.'t 'wd, 'ws, 'wt"); 2274 break; 2275 case CLE_U: 2276 Format(instr, "cle_u.'t 'wd, 'ws, 'wt"); 2277 break; 2278 case ADD_A: 2279 Format(instr, "add_a.'t 'wd, 'ws, 'wt"); 2280 break; 2281 case ADDS_A: 2282 Format(instr, "adds_a.'t 'wd, 'ws, 'wt"); 2283 break; 2284 case ADDS_S: 2285 Format(instr, "adds_s.'t 'wd, 'ws, 'wt"); 2286 break; 2287 case ADDS_U: 2288 Format(instr, "adds_u.'t 'wd, 'ws, 'wt"); 2289 break; 2290 case AVE_S: 2291 Format(instr, "ave_s.'t 'wd, 'ws, 'wt"); 2292 break; 2293 case AVE_U: 2294 Format(instr, "ave_u.'t 'wd, 'ws, 'wt"); 2295 break; 2296 case AVER_S: 2297 Format(instr, "aver_s.'t 'wd, 'ws, 'wt"); 2298 break; 2299 case AVER_U: 2300 Format(instr, "aver_u.'t 'wd, 'ws, 'wt"); 2301 break; 2302 case SUBS_S: 2303 Format(instr, "subs_s.'t 'wd, 'ws, 'wt"); 2304 break; 2305 case SUBS_U: 2306 Format(instr, "subs_u.'t 'wd, 'ws, 'wt"); 2307 break; 2308 case SUBSUS_U: 2309 Format(instr, "subsus_u.'t 'wd, 'ws, 'wt"); 2310 break; 2311 case SUBSUU_S: 2312 Format(instr, "subsuu_s.'t 'wd, 'ws, 'wt"); 2313 break; 2314 case ASUB_S: 2315 Format(instr, "asub_s.'t 'wd, 'ws, 'wt"); 2316 break; 2317 case ASUB_U: 2318 Format(instr, "asub_u.'t 'wd, 'ws, 'wt"); 2319 break; 2320 case MULV: 2321 Format(instr, "mulv.'t 'wd, 'ws, 'wt"); 2322 break; 2323 case MADDV: 2324 Format(instr, "maddv.'t 'wd, 'ws, 'wt"); 2325 break; 2326 case MSUBV: 2327 Format(instr, "msubv.'t 'wd, 'ws, 'wt"); 2328 break; 2329 case DIV_S_MSA: 2330 Format(instr, "div_s.'t 'wd, 'ws, 'wt"); 2331 break; 2332 case DIV_U: 2333 Format(instr, "div_u.'t 'wd, 'ws, 'wt"); 2334 break; 2335 case MOD_S: 2336 Format(instr, "mod_s.'t 'wd, 'ws, 'wt"); 2337 break; 2338 case MOD_U: 2339 Format(instr, "mod_u.'t 'wd, 'ws, 'wt"); 2340 break; 2341 case DOTP_S: 2342 Format(instr, "dotp_s.'t 'wd, 'ws, 'wt"); 2343 break; 2344 case DOTP_U: 2345 Format(instr, "dotp_u.'t 'wd, 'ws, 'wt"); 2346 break; 2347 case DPADD_S: 2348 Format(instr, "dpadd_s.'t 'wd, 'ws, 'wt"); 2349 break; 2350 case DPADD_U: 2351 Format(instr, "dpadd_u.'t 'wd, 'ws, 'wt"); 2352 break; 2353 case DPSUB_S: 2354 Format(instr, "dpsub_s.'t 'wd, 'ws, 'wt"); 2355 break; 2356 case DPSUB_U: 2357 Format(instr, "dpsub_u.'t 'wd, 'ws, 'wt"); 2358 break; 2359 case SLD: 2360 Format(instr, "sld.'t 'wd, 'ws['rt]"); 2361 break; 2362 case SPLAT: 2363 Format(instr, "splat.'t 'wd, 'ws['rt]"); 2364 break; 2365 case PCKEV: 2366 Format(instr, "pckev.'t 'wd, 'ws, 'wt"); 2367 break; 2368 case PCKOD: 2369 Format(instr, "pckod.'t 'wd, 'ws, 'wt"); 2370 break; 2371 case ILVL: 2372 Format(instr, "ilvl.'t 'wd, 'ws, 'wt"); 2373 break; 2374 case ILVR: 2375 Format(instr, "ilvr.'t 'wd, 'ws, 'wt"); 2376 break; 2377 case ILVEV: 2378 Format(instr, "ilvev.'t 'wd, 'ws, 'wt"); 2379 break; 2380 case ILVOD: 2381 Format(instr, "ilvod.'t 'wd, 'ws, 'wt"); 2382 break; 2383 case VSHF: 2384 Format(instr, "vshf.'t 'wd, 'ws, 'wt"); 2385 break; 2386 case SRAR: 2387 Format(instr, "srar.'t 'wd, 'ws, 'wt"); 2388 break; 2389 case SRLR: 2390 Format(instr, "srlr.'t 'wd, 'ws, 'wt"); 2391 break; 2392 case HADD_S: 2393 Format(instr, "hadd_s.'t 'wd, 'ws, 'wt"); 2394 break; 2395 case HADD_U: 2396 Format(instr, "hadd_u.'t 'wd, 'ws, 'wt"); 2397 break; 2398 case HSUB_S: 2399 Format(instr, "hsub_s.'t 'wd, 'ws, 'wt"); 2400 break; 2401 case HSUB_U: 2402 Format(instr, "hsub_u.'t 'wd, 'ws, 'wt"); 2403 break; 2404 default: 2405 UNREACHABLE(); 2406 } 2407} 2408 2409void Decoder::DecodeTypeMsa3RF(Instruction* instr) { 2410 uint32_t opcode = instr->InstructionBits() & kMsa3RFMask; 2411 switch (opcode) { 2412 case FCAF: 2413 Format(instr, "fcaf.'t 'wd, 'ws, 'wt"); 2414 break; 2415 case FCUN: 2416 Format(instr, "fcun.'t 'wd, 'ws, 'wt"); 2417 break; 2418 case FCEQ: 2419 Format(instr, "fceq.'t 'wd, 'ws, 'wt"); 2420 break; 2421 case FCUEQ: 2422 Format(instr, "fcueq.'t 'wd, 'ws, 'wt"); 2423 break; 2424 case FCLT: 2425 Format(instr, "fclt.'t 'wd, 'ws, 'wt"); 2426 break; 2427 case FCULT: 2428 Format(instr, "fcult.'t 'wd, 'ws, 'wt"); 2429 break; 2430 case FCLE: 2431 Format(instr, "fcle.'t 'wd, 'ws, 'wt"); 2432 break; 2433 case FCULE: 2434 Format(instr, "fcule.'t 'wd, 'ws, 'wt"); 2435 break; 2436 case FSAF: 2437 Format(instr, "fsaf.'t 'wd, 'ws, 'wt"); 2438 break; 2439 case FSUN: 2440 Format(instr, "fsun.'t 'wd, 'ws, 'wt"); 2441 break; 2442 case FSEQ: 2443 Format(instr, "fseq.'t 'wd, 'ws, 'wt"); 2444 break; 2445 case FSUEQ: 2446 Format(instr, "fsueq.'t 'wd, 'ws, 'wt"); 2447 break; 2448 case FSLT: 2449 Format(instr, "fslt.'t 'wd, 'ws, 'wt"); 2450 break; 2451 case FSULT: 2452 Format(instr, "fsult.'t 'wd, 'ws, 'wt"); 2453 break; 2454 case FSLE: 2455 Format(instr, "fsle.'t 'wd, 'ws, 'wt"); 2456 break; 2457 case FSULE: 2458 Format(instr, "fsule.'t 'wd, 'ws, 'wt"); 2459 break; 2460 case FADD: 2461 Format(instr, "fadd.'t 'wd, 'ws, 'wt"); 2462 break; 2463 case FSUB: 2464 Format(instr, "fsub.'t 'wd, 'ws, 'wt"); 2465 break; 2466 case FMUL: 2467 Format(instr, "fmul.'t 'wd, 'ws, 'wt"); 2468 break; 2469 case FDIV: 2470 Format(instr, "fdiv.'t 'wd, 'ws, 'wt"); 2471 break; 2472 case FMADD: 2473 Format(instr, "fmadd.'t 'wd, 'ws, 'wt"); 2474 break; 2475 case FMSUB: 2476 Format(instr, "fmsub.'t 'wd, 'ws, 'wt"); 2477 break; 2478 case FEXP2: 2479 Format(instr, "fexp2.'t 'wd, 'ws, 'wt"); 2480 break; 2481 case FEXDO: 2482 Format(instr, "fexdo.'t 'wd, 'ws, 'wt"); 2483 break; 2484 case FTQ: 2485 Format(instr, "ftq.'t 'wd, 'ws, 'wt"); 2486 break; 2487 case FMIN: 2488 Format(instr, "fmin.'t 'wd, 'ws, 'wt"); 2489 break; 2490 case FMIN_A: 2491 Format(instr, "fmin_a.'t 'wd, 'ws, 'wt"); 2492 break; 2493 case FMAX: 2494 Format(instr, "fmax.'t 'wd, 'ws, 'wt"); 2495 break; 2496 case FMAX_A: 2497 Format(instr, "fmax_a.'t 'wd, 'ws, 'wt"); 2498 break; 2499 case FCOR: 2500 Format(instr, "fcor.'t 'wd, 'ws, 'wt"); 2501 break; 2502 case FCUNE: 2503 Format(instr, "fcune.'t 'wd, 'ws, 'wt"); 2504 break; 2505 case FCNE: 2506 Format(instr, "fcne.'t 'wd, 'ws, 'wt"); 2507 break; 2508 case MUL_Q: 2509 Format(instr, "mul_q.'t 'wd, 'ws, 'wt"); 2510 break; 2511 case MADD_Q: 2512 Format(instr, "madd_q.'t 'wd, 'ws, 'wt"); 2513 break; 2514 case MSUB_Q: 2515 Format(instr, "msub_q.'t 'wd, 'ws, 'wt"); 2516 break; 2517 case FSOR: 2518 Format(instr, "fsor.'t 'wd, 'ws, 'wt"); 2519 break; 2520 case FSUNE: 2521 Format(instr, "fsune.'t 'wd, 'ws, 'wt"); 2522 break; 2523 case FSNE: 2524 Format(instr, "fsne.'t 'wd, 'ws, 'wt"); 2525 break; 2526 case MULR_Q: 2527 Format(instr, "mulr_q.'t 'wd, 'ws, 'wt"); 2528 break; 2529 case MADDR_Q: 2530 Format(instr, "maddr_q.'t 'wd, 'ws, 'wt"); 2531 break; 2532 case MSUBR_Q: 2533 Format(instr, "msubr_q.'t 'wd, 'ws, 'wt"); 2534 break; 2535 default: 2536 UNREACHABLE(); 2537 } 2538} 2539 2540void Decoder::DecodeTypeMsaVec(Instruction* instr) { 2541 uint32_t opcode = instr->InstructionBits() & kMsaVECMask; 2542 switch (opcode) { 2543 case AND_V: 2544 Format(instr, "and.v 'wd, 'ws, 'wt"); 2545 break; 2546 case OR_V: 2547 Format(instr, "or.v 'wd, 'ws, 'wt"); 2548 break; 2549 case NOR_V: 2550 Format(instr, "nor.v 'wd, 'ws, 'wt"); 2551 break; 2552 case XOR_V: 2553 Format(instr, "xor.v 'wd, 'ws, 'wt"); 2554 break; 2555 case BMNZ_V: 2556 Format(instr, "bmnz.v 'wd, 'ws, 'wt"); 2557 break; 2558 case BMZ_V: 2559 Format(instr, "bmz.v 'wd, 'ws, 'wt"); 2560 break; 2561 case BSEL_V: 2562 Format(instr, "bsel.v 'wd, 'ws, 'wt"); 2563 break; 2564 default: 2565 UNREACHABLE(); 2566 } 2567} 2568 2569void Decoder::DecodeTypeMsa2R(Instruction* instr) { 2570 uint32_t opcode = instr->InstructionBits() & kMsa2RMask; 2571 switch (opcode) { 2572 case FILL: { 2573 Format(instr, "fill.'t 'wd, "); 2574 PrintRegister(instr->WsValue()); // rs value is in ws field 2575 } break; 2576 case PCNT: 2577 Format(instr, "pcnt.'t 'wd, 'ws"); 2578 break; 2579 case NLOC: 2580 Format(instr, "nloc.'t 'wd, 'ws"); 2581 break; 2582 case NLZC: 2583 Format(instr, "nlzc.'t 'wd, 'ws"); 2584 break; 2585 default: 2586 UNREACHABLE(); 2587 } 2588} 2589 2590void Decoder::DecodeTypeMsa2RF(Instruction* instr) { 2591 uint32_t opcode = instr->InstructionBits() & kMsa2RFMask; 2592 switch (opcode) { 2593 case FCLASS: 2594 Format(instr, "fclass.'t 'wd, 'ws"); 2595 break; 2596 case FTRUNC_S: 2597 Format(instr, "ftrunc_s.'t 'wd, 'ws"); 2598 break; 2599 case FTRUNC_U: 2600 Format(instr, "ftrunc_u.'t 'wd, 'ws"); 2601 break; 2602 case FSQRT: 2603 Format(instr, "fsqrt.'t 'wd, 'ws"); 2604 break; 2605 case FRSQRT: 2606 Format(instr, "frsqrt.'t 'wd, 'ws"); 2607 break; 2608 case FRCP: 2609 Format(instr, "frcp.'t 'wd, 'ws"); 2610 break; 2611 case FRINT: 2612 Format(instr, "frint.'t 'wd, 'ws"); 2613 break; 2614 case FLOG2: 2615 Format(instr, "flog2.'t 'wd, 'ws"); 2616 break; 2617 case FEXUPL: 2618 Format(instr, "fexupl.'t 'wd, 'ws"); 2619 break; 2620 case FEXUPR: 2621 Format(instr, "fexupr.'t 'wd, 'ws"); 2622 break; 2623 case FFQL: 2624 Format(instr, "ffql.'t 'wd, 'ws"); 2625 break; 2626 case FFQR: 2627 Format(instr, "ffqr.'t 'wd, 'ws"); 2628 break; 2629 case FTINT_S: 2630 Format(instr, "ftint_s.'t 'wd, 'ws"); 2631 break; 2632 case FTINT_U: 2633 Format(instr, "ftint_u.'t 'wd, 'ws"); 2634 break; 2635 case FFINT_S: 2636 Format(instr, "ffint_s.'t 'wd, 'ws"); 2637 break; 2638 case FFINT_U: 2639 Format(instr, "ffint_u.'t 'wd, 'ws"); 2640 break; 2641 default: 2642 UNREACHABLE(); 2643 } 2644} 2645 2646// Disassemble the instruction at *instr_ptr into the output buffer. 2647int Decoder::InstructionDecode(byte* instr_ptr) { 2648 Instruction* instr = Instruction::At(instr_ptr); 2649 // Print raw instruction bytes. 2650 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, 2651 "%08x ", instr->InstructionBits()); 2652 switch (instr->InstructionType()) { 2653 case Instruction::kRegisterType: { 2654 DecodeTypeRegister(instr); 2655 break; 2656 } 2657 case Instruction::kImmediateType: { 2658 DecodeTypeImmediate(instr); 2659 break; 2660 } 2661 case Instruction::kJumpType: { 2662 DecodeTypeJump(instr); 2663 break; 2664 } 2665 default: { 2666 Format(instr, "UNSUPPORTED"); 2667 UNSUPPORTED_MIPS(); 2668 } 2669 } 2670 return kInstrSize; 2671} 2672 2673} // namespace internal 2674} // namespace v8 2675 2676//------------------------------------------------------------------------------ 2677 2678namespace disasm { 2679 2680const char* NameConverter::NameOfAddress(byte* addr) const { 2681 v8::base::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr)); 2682 return tmp_buffer_.begin(); 2683} 2684 2685const char* NameConverter::NameOfConstant(byte* addr) const { 2686 return NameOfAddress(addr); 2687} 2688 2689const char* NameConverter::NameOfCPURegister(int reg) const { 2690 return v8::internal::Registers::Name(reg); 2691} 2692 2693const char* NameConverter::NameOfXMMRegister(int reg) const { 2694 return v8::internal::FPURegisters::Name(reg); 2695} 2696 2697const char* NameConverter::NameOfByteCPURegister(int reg) const { 2698 UNREACHABLE(); // MIPS does not have the concept of a byte register. 2699} 2700 2701const char* NameConverter::NameInCode(byte* addr) const { 2702 // The default name converter is called for unknown code. So we will not try 2703 // to access any memory. 2704 return ""; 2705} 2706 2707//------------------------------------------------------------------------------ 2708 2709int Disassembler::InstructionDecode(v8::base::Vector<char> buffer, 2710 byte* instruction) { 2711 v8::internal::Decoder d(converter_, buffer); 2712 return d.InstructionDecode(instruction); 2713} 2714 2715// The MIPS assembler does not currently use constant pools. 2716int Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; } 2717 2718void Disassembler::Disassemble(FILE* f, byte* begin, byte* end, 2719 UnimplementedOpcodeAction unimplemented_action) { 2720 NameConverter converter; 2721 Disassembler d(converter, unimplemented_action); 2722 for (byte* pc = begin; pc < end;) { 2723 v8::base::EmbeddedVector<char, 128> buffer; 2724 buffer[0] = '\0'; 2725 byte* prev_pc = pc; 2726 pc += d.InstructionDecode(buffer, pc); 2727 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc), 2728 *reinterpret_cast<int32_t*>(prev_pc), buffer.begin()); 2729 } 2730} 2731 2732#undef STRING_STARTS_WITH 2733 2734} // namespace disasm 2735 2736#endif // V8_TARGET_ARCH_MIPS 2737