1// Copyright 2014 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_S390 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/register-configuration.h" 37#include "src/codegen/s390/constants-s390.h" 38#include "src/diagnostics/disasm.h" 39 40namespace v8 { 41namespace internal { 42 43//------------------------------------------------------------------------------ 44 45// Decoder decodes and disassembles instructions into an output buffer. 46// It uses the converter to convert register names and call destinations into 47// more informative description. 48class Decoder { 49 public: 50 Decoder(const disasm::NameConverter& converter, 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 PrintDRegister(int reg); 72 void PrintSoftwareInterrupt(SoftwareInterruptCodes svc); 73 74 // Handle formatting of instructions and their options. 75 int FormatRegister(Instruction* instr, const char* option); 76 int FormatFloatingRegister(Instruction* instr, const char* option); 77 int FormatMask(Instruction* instr, const char* option); 78 int FormatDisplacement(Instruction* instr, const char* option); 79 int FormatImmediate(Instruction* instr, const char* option); 80 int FormatOption(Instruction* instr, const char* option); 81 void Format(Instruction* instr, const char* format); 82 void Unknown(Instruction* instr); 83 void UnknownFormat(Instruction* instr, const char* opcname); 84 85 bool DecodeSpecial(Instruction* instr); 86 bool DecodeGeneric(Instruction* instr); 87 88 const disasm::NameConverter& converter_; 89 base::Vector<char> out_buffer_; 90 int out_buffer_pos_; 91}; 92 93// Support for assertions in the Decoder formatting functions. 94#define STRING_STARTS_WITH(string, compare_string) \ 95 (strncmp(string, compare_string, strlen(compare_string)) == 0) 96 97// Append the ch to the output buffer. 98void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; } 99 100// Append the str to the output buffer. 101void Decoder::Print(const char* str) { 102 char cur = *str++; 103 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 104 PrintChar(cur); 105 cur = *str++; 106 } 107 out_buffer_[out_buffer_pos_] = 0; 108} 109 110// Print the register name according to the active name converter. 111void Decoder::PrintRegister(int reg) { 112 Print(converter_.NameOfCPURegister(reg)); 113} 114 115// Print the double FP register name according to the active name converter. 116void Decoder::PrintDRegister(int reg) { 117 Print(RegisterName(DoubleRegister::from_code(reg))); 118} 119 120// Print SoftwareInterrupt codes. Factoring this out reduces the complexity of 121// the FormatOption method. 122void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) { 123 switch (svc) { 124 case kCallRtRedirected: 125 Print("call rt redirected"); 126 return; 127 case kBreakpoint: 128 Print("breakpoint"); 129 return; 130 default: 131 if (svc >= kStopCode) { 132 out_buffer_pos_ += 133 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d - 0x%x", 134 svc & kStopCodeMask, svc & kStopCodeMask); 135 } else { 136 out_buffer_pos_ += 137 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", svc); 138 } 139 return; 140 } 141} 142 143// Handle all register based formatting in this function to reduce the 144// complexity of FormatOption. 145int Decoder::FormatRegister(Instruction* instr, const char* format) { 146 DCHECK_EQ(format[0], 'r'); 147 148 if (format[1] == '1') { // 'r1: register resides in bit 8-11 149 int reg = instr->Bits<SixByteInstr, int>(39, 36); 150 PrintRegister(reg); 151 return 2; 152 } else if (format[1] == '2') { // 'r2: register resides in bit 12-15 153 int reg = instr->Bits<SixByteInstr, int>(35, 32); 154 // indicating it is a r0 for displacement, in which case the offset 155 // should be 0. 156 if (format[2] == 'd') { 157 if (reg == 0) return 4; 158 PrintRegister(reg); 159 return 3; 160 } else { 161 PrintRegister(reg); 162 return 2; 163 } 164 } else if (format[1] == '3') { // 'r3: register resides in bit 16-19 165 int reg = instr->Bits<SixByteInstr, int>(31, 28); 166 PrintRegister(reg); 167 return 2; 168 } else if (format[1] == '4') { // 'r4: register resides in bit 20-23 169 int reg = instr->Bits<SixByteInstr, int>(27, 24); 170 PrintRegister(reg); 171 return 2; 172 } else if (format[1] == '5') { // 'r5: register resides in bit 24-27 173 int reg = instr->Bits<SixByteInstr, int>(23, 20); 174 PrintRegister(reg); 175 return 2; 176 } else if (format[1] == '6') { // 'r6: register resides in bit 28-31 177 int reg = instr->Bits<SixByteInstr, int>(19, 16); 178 PrintRegister(reg); 179 return 2; 180 } else if (format[1] == '7') { // 'r6: register resides in bit 32-35 181 int reg = instr->Bits<SixByteInstr, int>(15, 12); 182 PrintRegister(reg); 183 return 2; 184 } 185 186 UNREACHABLE(); 187} 188 189int Decoder::FormatFloatingRegister(Instruction* instr, const char* format) { 190 DCHECK_EQ(format[0], 'f'); 191 192 // reuse 1, 5 and 6 because it is coresponding 193 if (format[1] == '1') { // 'r1: register resides in bit 8-11 194 RRInstruction* rrinstr = reinterpret_cast<RRInstruction*>(instr); 195 int reg = rrinstr->R1Value(); 196 PrintDRegister(reg); 197 return 2; 198 } else if (format[1] == '2') { // 'f2: register resides in bit 12-15 199 RRInstruction* rrinstr = reinterpret_cast<RRInstruction*>(instr); 200 int reg = rrinstr->R2Value(); 201 PrintDRegister(reg); 202 return 2; 203 } else if (format[1] == '3') { // 'f3: register resides in bit 16-19 204 RRDInstruction* rrdinstr = reinterpret_cast<RRDInstruction*>(instr); 205 int reg = rrdinstr->R1Value(); 206 PrintDRegister(reg); 207 return 2; 208 } else if (format[1] == '5') { // 'f5: register resides in bit 24-28 209 RREInstruction* rreinstr = reinterpret_cast<RREInstruction*>(instr); 210 int reg = rreinstr->R1Value(); 211 PrintDRegister(reg); 212 return 2; 213 } else if (format[1] == '6') { // 'f6: register resides in bit 29-32 214 RREInstruction* rreinstr = reinterpret_cast<RREInstruction*>(instr); 215 int reg = rreinstr->R2Value(); 216 PrintDRegister(reg); 217 return 2; 218 } else if (format[1] == '4') { 219 VRR_E_Instruction* vrreinstr = reinterpret_cast<VRR_E_Instruction*>(instr); 220 int reg = vrreinstr->R4Value(); 221 PrintDRegister(reg); 222 return 2; 223 } 224 UNREACHABLE(); 225} 226 227// FormatOption takes a formatting string and interprets it based on 228// the current instructions. The format string points to the first 229// character of the option string (the option escape has already been 230// consumed by the caller.) FormatOption returns the number of 231// characters that were consumed from the formatting string. 232int Decoder::FormatOption(Instruction* instr, const char* format) { 233 switch (format[0]) { 234 case 'o': { 235 if (instr->Bit(10) == 1) { 236 Print("o"); 237 } 238 return 1; 239 } 240 case '.': { 241 if (instr->Bit(0) == 1) { 242 Print("."); 243 } else { 244 Print(" "); // ensure consistent spacing 245 } 246 return 1; 247 } 248 case 'r': { 249 return FormatRegister(instr, format); 250 } 251 case 'f': { 252 return FormatFloatingRegister(instr, format); 253 } 254 case 'i': { // int16 255 return FormatImmediate(instr, format); 256 } 257 case 'u': { // uint16 258 int32_t value = instr->Bits(15, 0); 259 out_buffer_pos_ += 260 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 261 return 6; 262 } 263 case 'l': { 264 // Link (LK) Bit 0 265 if (instr->Bit(0) == 1) { 266 Print("l"); 267 } 268 return 1; 269 } 270 case 'a': { 271 // Absolute Address Bit 1 272 if (instr->Bit(1) == 1) { 273 Print("a"); 274 } 275 return 1; 276 } 277 case 't': { // 'target: target of branch instructions 278 // target26 or target16 279 DCHECK(STRING_STARTS_WITH(format, "target")); 280 if ((format[6] == '2') && (format[7] == '6')) { 281 int off = ((instr->Bits(25, 2)) << 8) >> 6; 282 out_buffer_pos_ += base::SNPrintF( 283 out_buffer_ + out_buffer_pos_, "%+d -> %s", off, 284 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off)); 285 return 8; 286 } else if ((format[6] == '1') && (format[7] == '6')) { 287 int off = ((instr->Bits(15, 2)) << 18) >> 16; 288 out_buffer_pos_ += base::SNPrintF( 289 out_buffer_ + out_buffer_pos_, "%+d -> %s", off, 290 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off)); 291 return 8; 292 } 293 break; 294 case 'm': { 295 return FormatMask(instr, format); 296 } 297 } 298 case 'd': { // ds value for offset 299 return FormatDisplacement(instr, format); 300 } 301 default: { 302 UNREACHABLE(); 303 } 304 } 305 306 UNREACHABLE(); 307} 308 309int Decoder::FormatMask(Instruction* instr, const char* format) { 310 DCHECK_EQ(format[0], 'm'); 311 int32_t value = 0; 312 if ((format[1] == '1')) { // prints the mask format in bits 8-12 313 value = reinterpret_cast<RRInstruction*>(instr)->R1Value(); 314 out_buffer_pos_ += 315 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value); 316 return 2; 317 } else if (format[1] == '2') { // mask format in bits 16-19 318 value = reinterpret_cast<RXInstruction*>(instr)->B2Value(); 319 out_buffer_pos_ += 320 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value); 321 return 2; 322 } else if (format[1] == '3') { // mask format in bits 20-23 323 value = reinterpret_cast<RRFInstruction*>(instr)->M4Value(); 324 out_buffer_pos_ += 325 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value); 326 return 2; 327 } else if (format[1] == '4') { // mask format in bits 32-35 328 value = reinterpret_cast<VRR_C_Instruction*>(instr)->M4Value(); 329 out_buffer_pos_ += 330 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value); 331 return 2; 332 } else if (format[1] == '5') { // mask format in bits 28-31 333 value = reinterpret_cast<VRR_C_Instruction*>(instr)->M5Value(); 334 out_buffer_pos_ += 335 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value); 336 return 2; 337 } else if (format[1] == '6') { // mask format in bits 24-27 338 value = reinterpret_cast<VRR_C_Instruction*>(instr)->M6Value(); 339 out_buffer_pos_ += 340 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value); 341 return 2; 342 } 343 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 344 return 2; 345} 346 347int Decoder::FormatDisplacement(Instruction* instr, const char* format) { 348 DCHECK_EQ(format[0], 'd'); 349 350 if (format[1] == '1') { // displacement in 20-31 351 RSInstruction* rsinstr = reinterpret_cast<RSInstruction*>(instr); 352 uint16_t value = rsinstr->D2Value(); 353 out_buffer_pos_ += 354 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 355 356 return 2; 357 } else if (format[1] == '2') { // displacement in 20-39 358 RXYInstruction* rxyinstr = reinterpret_cast<RXYInstruction*>(instr); 359 int32_t value = rxyinstr->D2Value(); 360 out_buffer_pos_ += 361 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 362 return 2; 363 } else if (format[1] == '4') { // SS displacement 2 36-47 364 SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr); 365 uint16_t value = ssInstr->D2Value(); 366 out_buffer_pos_ += 367 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 368 return 2; 369 } else if (format[1] == '3') { // SS displacement 1 20 - 32 370 SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr); 371 uint16_t value = ssInstr->D1Value(); 372 out_buffer_pos_ += 373 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 374 return 2; 375 } else { // s390 specific 376 int32_t value = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3); 377 out_buffer_pos_ += 378 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 379 return 1; 380 } 381} 382 383int Decoder::FormatImmediate(Instruction* instr, const char* format) { 384 DCHECK_EQ(format[0], 'i'); 385 386 if (format[1] == '1') { // immediate in 16-31 387 RIInstruction* riinstr = reinterpret_cast<RIInstruction*>(instr); 388 int16_t value = riinstr->I2Value(); 389 out_buffer_pos_ += 390 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 391 return 2; 392 } else if (format[1] == '2') { // immediate in 16-48 393 RILInstruction* rilinstr = reinterpret_cast<RILInstruction*>(instr); 394 int32_t value = rilinstr->I2Value(); 395 out_buffer_pos_ += 396 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 397 return 2; 398 } else if (format[1] == '3') { // immediate in I format 399 IInstruction* iinstr = reinterpret_cast<IInstruction*>(instr); 400 int8_t value = iinstr->IValue(); 401 out_buffer_pos_ += 402 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 403 return 2; 404 } else if (format[1] == '4') { // immediate in 16-31, but outputs as offset 405 RIInstruction* riinstr = reinterpret_cast<RIInstruction*>(instr); 406 int16_t value = riinstr->I2Value() * 2; 407 if (value >= 0) 408 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "*+"); 409 else 410 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "*"); 411 412 out_buffer_pos_ += base::SNPrintF( 413 out_buffer_ + out_buffer_pos_, "%d -> %s", value, 414 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + value)); 415 return 2; 416 } else if (format[1] == '5') { // immediate in 16-31, but outputs as offset 417 RILInstruction* rilinstr = reinterpret_cast<RILInstruction*>(instr); 418 int32_t value = rilinstr->I2Value() * 2; 419 if (value >= 0) 420 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "*+"); 421 else 422 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "*"); 423 424 out_buffer_pos_ += base::SNPrintF( 425 out_buffer_ + out_buffer_pos_, "%d -> %s", value, 426 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + value)); 427 return 2; 428 } else if (format[1] == '6') { // unsigned immediate in 16-31 429 RIInstruction* riinstr = reinterpret_cast<RIInstruction*>(instr); 430 uint16_t value = riinstr->I2UnsignedValue(); 431 out_buffer_pos_ += 432 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 433 return 2; 434 } else if (format[1] == '7') { // unsigned immediate in 16-47 435 RILInstruction* rilinstr = reinterpret_cast<RILInstruction*>(instr); 436 uint32_t value = rilinstr->I2UnsignedValue(); 437 out_buffer_pos_ += 438 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 439 return 2; 440 } else if (format[1] == '8') { // unsigned immediate in 8-15 441 SSInstruction* ssinstr = reinterpret_cast<SSInstruction*>(instr); 442 uint8_t value = ssinstr->Length(); 443 out_buffer_pos_ += 444 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 445 return 2; 446 } else if (format[1] == '9') { // unsigned immediate in 16-23 447 RIEInstruction* rie_instr = reinterpret_cast<RIEInstruction*>(instr); 448 uint8_t value = rie_instr->I3Value(); 449 out_buffer_pos_ += 450 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 451 return 2; 452 } else if (format[1] == 'a') { // unsigned immediate in 24-31 453 RIEInstruction* rie_instr = reinterpret_cast<RIEInstruction*>(instr); 454 uint8_t value = rie_instr->I4Value(); 455 out_buffer_pos_ += 456 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 457 return 2; 458 } else if (format[1] == 'b') { // unsigned immediate in 32-39 459 RIEInstruction* rie_instr = reinterpret_cast<RIEInstruction*>(instr); 460 uint8_t value = rie_instr->I5Value(); 461 out_buffer_pos_ += 462 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 463 return 2; 464 } else if (format[1] == 'c') { // signed immediate in 8-15 465 SSInstruction* ssinstr = reinterpret_cast<SSInstruction*>(instr); 466 int8_t value = ssinstr->Length(); 467 out_buffer_pos_ += 468 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 469 return 2; 470 } else if (format[1] == 'd') { // signed immediate in 32-47 471 SILInstruction* silinstr = reinterpret_cast<SILInstruction*>(instr); 472 int16_t value = silinstr->I2Value(); 473 out_buffer_pos_ += 474 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value); 475 return 2; 476 } else if (format[1] == 'e') { // immediate in 16-47, but outputs as offset 477 RILInstruction* rilinstr = reinterpret_cast<RILInstruction*>(instr); 478 int32_t value = rilinstr->I2Value() * 2; 479 if (value >= 0) 480 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "*+"); 481 else 482 out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "*"); 483 484 out_buffer_pos_ += base::SNPrintF( 485 out_buffer_ + out_buffer_pos_, "%d -> %s", value, 486 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + value)); 487 return 2; 488 } 489 490 UNREACHABLE(); 491} 492 493// Format takes a formatting string for a whole instruction and prints it into 494// the output buffer. All escaped options are handed to FormatOption to be 495// parsed further. 496void Decoder::Format(Instruction* instr, const char* format) { 497 char cur = *format++; 498 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 499 if (cur == '\'') { // Single quote is used as the formatting escape. 500 format += FormatOption(instr, format); 501 } else { 502 out_buffer_[out_buffer_pos_++] = cur; 503 } 504 cur = *format++; 505 } 506 out_buffer_[out_buffer_pos_] = '\0'; 507} 508 509// The disassembler may end up decoding data inlined in the code. We do not want 510// it to crash if the data does not resemble any known instruction. 511#define VERIFY(condition) \ 512 if (!(condition)) { \ 513 Unknown(instr); \ 514 return; \ 515 } 516 517// For currently unimplemented decodings the disassembler calls Unknown(instr) 518// which will just print "unknown" of the instruction bits. 519void Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); } 520 521// For currently unimplemented decodings the disassembler calls 522// UnknownFormat(instr) which will just print opcode name of the 523// instruction bits. 524void Decoder::UnknownFormat(Instruction* instr, const char* name) { 525 char buffer[100]; 526 snprintf(buffer, sizeof(buffer), "%s (unknown-format)", name); 527 Format(instr, buffer); 528} 529 530#undef VERIFY 531#undef STRING_STARTS_WITH 532 533// Handles special cases of instructions; 534// @return true if successfully decoded 535bool Decoder::DecodeSpecial(Instruction* instr) { 536 Opcode opcode = instr->S390OpcodeValue(); 537 switch (opcode) { 538 case BKPT: 539 Format(instr, "bkpt"); 540 break; 541 case DUMY: 542 Format(instr, "dumy\t'r1, 'd2 ( 'r2d, 'r3 )"); 543 break; 544 /* RR format */ 545 case LDR: 546 Format(instr, "ldr\t'f1,'f2"); 547 break; 548 case BCR: 549 Format(instr, "bcr\t'm1,'r2"); 550 break; 551 case OR: 552 Format(instr, "or\t'r1,'r2"); 553 break; 554 case CR: 555 Format(instr, "cr\t'r1,'r2"); 556 break; 557 case MR: 558 Format(instr, "mr\t'r1,'r2"); 559 break; 560 case HER_Z: 561 Format(instr, "her\t'r1,'r2"); 562 break; 563 /* RI-b format */ 564 case BRAS: 565 Format(instr, "bras\t'r1,'i1"); 566 break; 567 /* RRE format */ 568 case MDBR: 569 Format(instr, "mdbr\t'f5,'f6"); 570 break; 571 case SDBR: 572 Format(instr, "sdbr\t'f5,'f6"); 573 break; 574 case ADBR: 575 Format(instr, "adbr\t'f5,'f6"); 576 break; 577 case CDBR: 578 Format(instr, "cdbr\t'f5,'f6"); 579 break; 580 case MEEBR: 581 Format(instr, "meebr\t'f5,'f6"); 582 break; 583 case SQDBR: 584 Format(instr, "sqdbr\t'f5,'f6"); 585 break; 586 case SQEBR: 587 Format(instr, "sqebr\t'f5,'f6"); 588 break; 589 case LCDBR: 590 Format(instr, "lcdbr\t'f5,'f6"); 591 break; 592 case LCEBR: 593 Format(instr, "lcebr\t'f5,'f6"); 594 break; 595 case LTEBR: 596 Format(instr, "ltebr\t'f5,'f6"); 597 break; 598 case LDEBR: 599 Format(instr, "ldebr\t'f5,'f6"); 600 break; 601 case CEBR: 602 Format(instr, "cebr\t'f5,'f6"); 603 break; 604 case AEBR: 605 Format(instr, "aebr\t'f5,'f6"); 606 break; 607 case SEBR: 608 Format(instr, "sebr\t'f5,'f6"); 609 break; 610 case DEBR: 611 Format(instr, "debr\t'f5,'f6"); 612 break; 613 case LTDBR: 614 Format(instr, "ltdbr\t'f5,'f6"); 615 break; 616 case LDGR: 617 Format(instr, "ldgr\t'f5,'f6"); 618 break; 619 case DDBR: 620 Format(instr, "ddbr\t'f5,'f6"); 621 break; 622 case LZDR: 623 Format(instr, "lzdr\t'f5"); 624 break; 625 /* RRF-e format */ 626 case FIEBRA: 627 Format(instr, "fiebra\t'f5,'m2,'f6,'m3"); 628 break; 629 case FIDBRA: 630 Format(instr, "fidbra\t'f5,'m2,'f6,'m3"); 631 break; 632 /* RX-a format */ 633 case IC_z: 634 Format(instr, "ic\t'r1,'d1('r2d,'r3)"); 635 break; 636 case AL: 637 Format(instr, "al\t'r1,'d1('r2d,'r3)"); 638 break; 639 case LE: 640 Format(instr, "le\t'f1,'d1('r2d,'r3)"); 641 break; 642 case LD: 643 Format(instr, "ld\t'f1,'d1('r2d,'r3)"); 644 break; 645 case STE: 646 Format(instr, "ste\t'f1,'d1('r2d,'r3)"); 647 break; 648 case STD: 649 Format(instr, "std\t'f1,'d1('r2d,'r3)"); 650 break; 651 /* S format */ 652 // TRAP4 is used in calling to native function. it will not be generated 653 // in native code. 654 case TRAP4: 655 Format(instr, "trap4"); 656 break; 657 /* RIL-a format */ 658 case CFI: 659 Format(instr, "cfi\t'r1,'i2"); 660 break; 661 case CGFI: 662 Format(instr, "cgfi\t'r1,'i2"); 663 break; 664 case AFI: 665 Format(instr, "afi\t'r1,'i2"); 666 break; 667 case AGFI: 668 Format(instr, "agfi\t'r1,'i2"); 669 break; 670 case MSFI: 671 Format(instr, "msfi\t'r1,'i2"); 672 break; 673 case MSGFI: 674 Format(instr, "msgfi\t'r1,'i2"); 675 break; 676 case ALSIH: 677 Format(instr, "alsih\t'r1,'i2"); 678 break; 679 case ALSIHN: 680 Format(instr, "alsihn\t'r1,'i2"); 681 break; 682 case CIH: 683 Format(instr, "cih\t'r1,'i2"); 684 break; 685 case AIH: 686 Format(instr, "aih\t'r1,'i2"); 687 break; 688 case LGFI: 689 Format(instr, "lgfi\t'r1,'i2"); 690 break; 691 /* SIY format */ 692 case ASI: 693 Format(instr, "asi\t'd2('r3),'ic"); 694 break; 695 case AGSI: 696 Format(instr, "agsi\t'd2('r3),'ic"); 697 break; 698 /* RXY-a format */ 699 case LT: 700 Format(instr, "lt\t'r1,'d2('r2d,'r3)"); 701 break; 702 case LDY: 703 Format(instr, "ldy\t'f1,'d2('r2d,'r3)"); 704 break; 705 case LEY: 706 Format(instr, "ley\t'f1,'d2('r2d,'r3)"); 707 break; 708 case STDY: 709 Format(instr, "stdy\t'f1,'d2('r2d,'r3)"); 710 break; 711 case STEY: 712 Format(instr, "stey\t'f1,'d2('r2d,'r3)"); 713 break; 714 /* RXE format */ 715 case LDEB: 716 Format(instr, "ldeb\t'f1,'d2('r2d,'r3)"); 717 break; 718 default: 719 return false; 720 } 721 return true; 722} 723 724// Handles common cases of instructions; 725// @return true if successfully decoded 726bool Decoder::DecodeGeneric(Instruction* instr) { 727 Opcode opcode = instr->S390OpcodeValue(); 728 switch (opcode) { 729 /* 2 bytes */ 730#define DECODE_RR_INSTRUCTIONS(name, opcode_name, opcode_value) \ 731 case opcode_name: \ 732 Format(instr, #name "\t'r1,'r2"); \ 733 break; 734 S390_RR_OPCODE_LIST(DECODE_RR_INSTRUCTIONS) 735#undef DECODE_RR_INSTRUCTIONS 736 737 /* 4 bytes */ 738#define DECODE_RS_A_INSTRUCTIONS(name, opcode_name, opcode_value) \ 739 case opcode_name: \ 740 Format(instr, #name "\t'r1,'r2,'d1('r3)"); \ 741 break; 742 S390_RS_A_OPCODE_LIST(DECODE_RS_A_INSTRUCTIONS) 743#undef DECODE_RS_A_INSTRUCTIONS 744 745#define DECODE_RSI_INSTRUCTIONS(name, opcode_name, opcode_value) \ 746 case opcode_name: \ 747 Format(instr, #name "\t'r1,'r2,'i4"); \ 748 break; 749 S390_RSI_OPCODE_LIST(DECODE_RSI_INSTRUCTIONS) 750#undef DECODE_RSI_INSTRUCTIONS 751 752#define DECODE_RI_A_INSTRUCTIONS(name, opcode_name, opcode_value) \ 753 case opcode_name: \ 754 Format(instr, #name "\t'r1,'i1"); \ 755 break; 756 S390_RI_A_OPCODE_LIST(DECODE_RI_A_INSTRUCTIONS) 757#undef DECODE_RI_A_INSTRUCTIONS 758 759#define DECODE_RI_B_INSTRUCTIONS(name, opcode_name, opcode_value) \ 760 case opcode_name: \ 761 Format(instr, #name "\t'r1,'i4"); \ 762 break; 763 S390_RI_B_OPCODE_LIST(DECODE_RI_B_INSTRUCTIONS) 764#undef DECODE_RI_B_INSTRUCTIONS 765 766#define DECODE_RI_C_INSTRUCTIONS(name, opcode_name, opcode_value) \ 767 case opcode_name: \ 768 Format(instr, #name "\t'm1,'i4"); \ 769 break; 770 S390_RI_C_OPCODE_LIST(DECODE_RI_C_INSTRUCTIONS) 771#undef DECODE_RI_C_INSTRUCTIONS 772 773#define DECODE_RRE_INSTRUCTIONS(name, opcode_name, opcode_value) \ 774 case opcode_name: \ 775 Format(instr, #name "\t'r5,'r6"); \ 776 break; 777 S390_RRE_OPCODE_LIST(DECODE_RRE_INSTRUCTIONS) 778#undef DECODE_RRE_INSTRUCTIONS 779 780#define DECODE_RRF_A_INSTRUCTIONS(name, opcode_name, opcode_val) \ 781 case opcode_name: \ 782 Format(instr, #name "\t'r5,'r6,'r3"); \ 783 break; 784 S390_RRF_A_OPCODE_LIST(DECODE_RRF_A_INSTRUCTIONS) 785#undef DECODE_RRF_A_INSTRUCTIONS 786 787#define DECODE_RRF_C_INSTRUCTIONS(name, opcode_name, opcode_val) \ 788 case opcode_name: \ 789 Format(instr, #name "\t'r5,'r6,'m2"); \ 790 break; 791 S390_RRF_C_OPCODE_LIST(DECODE_RRF_C_INSTRUCTIONS) 792#undef DECODE_RRF_C_INSTRUCTIONS 793 794#define DECODE_RRF_E_INSTRUCTIONS(name, opcode_name, opcode_val) \ 795 case opcode_name: \ 796 Format(instr, #name "\t'r5,'m2,'f6"); \ 797 break; 798 S390_RRF_E_OPCODE_LIST(DECODE_RRF_E_INSTRUCTIONS) 799#undef DECODE_RRF_E_INSTRUCTIONS 800 801#define DECODE_RX_A_INSTRUCTIONS(name, opcode_name, opcode_value) \ 802 case opcode_name: \ 803 Format(instr, #name "\t'r1,'d1('r2d,'r3)"); \ 804 break; 805 S390_RX_A_OPCODE_LIST(DECODE_RX_A_INSTRUCTIONS) 806#undef DECODE_RX_A_INSTRUCTIONS 807 808#define DECODE_RX_B_INSTRUCTIONS(name, opcode_name, opcode_value) \ 809 case opcode_name: \ 810 Format(instr, #name "\t'm1,'d1('r2d,'r3)"); \ 811 break; 812 S390_RX_B_OPCODE_LIST(DECODE_RX_B_INSTRUCTIONS) 813#undef DECODE_RX_B_INSTRUCTIONS 814 815#define DECODE_RRD_INSTRUCTIONS(name, opcode_name, opcode_value) \ 816 case opcode_name: \ 817 Format(instr, #name "\t'f3,'f5,'f6"); \ 818 break; 819 S390_RRD_OPCODE_LIST(DECODE_RRD_INSTRUCTIONS) 820#undef DECODE_RRD_INSTRUCTIONS 821 822#define DECODE_SI_INSTRUCTIONS(name, opcode_name, opcode_value) \ 823 case opcode_name: \ 824 Format(instr, #name "\t'd1('r3),'i8"); \ 825 break; 826 S390_SI_OPCODE_LIST(DECODE_SI_INSTRUCTIONS) 827#undef DECODE_SI_INSTRUCTIONS 828 829 /* 6 bytes */ 830#define DECODE_VRR_A_INSTRUCTIONS(name, opcode_name, opcode_value) \ 831 case opcode_name: \ 832 Format(instr, #name "\t'f1,'f2,'m4,'m5,'m6"); \ 833 break; 834 S390_VRR_A_OPCODE_LIST(DECODE_VRR_A_INSTRUCTIONS) 835#undef DECODE_VRR_A_INSTRUCTIONS 836 837#define DECODE_VRR_B_INSTRUCTIONS(name, opcode_name, opcode_value) \ 838 case opcode_name: \ 839 Format(instr, #name "\t'f1,'f2,'f3,'m4,'m6"); \ 840 break; 841 S390_VRR_B_OPCODE_LIST(DECODE_VRR_B_INSTRUCTIONS) 842#undef DECODE_VRR_B_INSTRUCTIONS 843 844#define DECODE_VRR_C_INSTRUCTIONS(name, opcode_name, opcode_value) \ 845 case opcode_name: \ 846 Format(instr, #name "\t'f1,'f2,'f3,'m4"); \ 847 break; 848 S390_VRR_C_OPCODE_LIST(DECODE_VRR_C_INSTRUCTIONS) 849#undef DECODE_VRR_C_INSTRUCTIONS 850 851#define DECODE_VRR_E_INSTRUCTIONS(name, opcode_name, opcode_value) \ 852 case opcode_name: \ 853 Format(instr, #name "\t'f1,'f2,'f3,'f4,'m5,'m3"); \ 854 break; 855 S390_VRR_E_OPCODE_LIST(DECODE_VRR_E_INSTRUCTIONS) 856#undef DECODE_VRR_E_INSTRUCTIONS 857 858#define DECODE_VRR_F_INSTRUCTIONS(name, opcode_name, opcode_value) \ 859 case opcode_name: \ 860 Format(instr, #name "\t'f1,'r1,'r2"); \ 861 break; 862 S390_VRR_F_OPCODE_LIST(DECODE_VRR_F_INSTRUCTIONS) 863#undef DECODE_VRR_F_INSTRUCTIONS 864 865#define DECODE_VRX_INSTRUCTIONS(name, opcode_name, opcode_value) \ 866 case opcode_name: \ 867 Format(instr, #name "\t'f1,'d1('r2d,'r3),'m4"); \ 868 break; 869 S390_VRX_OPCODE_LIST(DECODE_VRX_INSTRUCTIONS) 870#undef DECODE_VRX_INSTRUCTIONS 871 872#define DECODE_VRS_A_INSTRUCTIONS(name, opcode_name, opcode_value) \ 873 case opcode_name: \ 874 Format(instr, #name "\t'f1,'f2,'d1('r3),'m4"); \ 875 break; 876 S390_VRS_A_OPCODE_LIST(DECODE_VRS_A_INSTRUCTIONS) 877#undef DECODE_VRS_A_INSTRUCTIONS 878 879#define DECODE_VRS_B_INSTRUCTIONS(name, opcode_name, opcode_value) \ 880 case opcode_name: \ 881 Format(instr, #name "\t'f1,'r2,'d1('r3),'m4"); \ 882 break; 883 S390_VRS_B_OPCODE_LIST(DECODE_VRS_B_INSTRUCTIONS) 884#undef DECODE_VRS_B_INSTRUCTIONS 885 886#define DECODE_VRS_C_INSTRUCTIONS(name, opcode_name, opcode_value) \ 887 case opcode_name: \ 888 Format(instr, #name "\t'r1,'f2,'d1('r3),'m4"); \ 889 break; 890 S390_VRS_C_OPCODE_LIST(DECODE_VRS_C_INSTRUCTIONS) 891#undef DECODE_VRS_C_INSTRUCTIONS 892 893#define DECODE_VRI_A_INSTRUCTIONS(name, opcode_name, opcode_value) \ 894 case opcode_name: \ 895 Format(instr, #name "\t'f1,'i1,'m4"); \ 896 break; 897 S390_VRI_A_OPCODE_LIST(DECODE_VRI_A_INSTRUCTIONS) 898#undef DECODE_VRI_A_INSTRUCTIONS 899 900#define DECODE_VRI_C_INSTRUCTIONS(name, opcode_name, opcode_value) \ 901 case opcode_name: \ 902 Format(instr, #name "\t'f1,'f2,'i1,'m4"); \ 903 break; 904 S390_VRI_C_OPCODE_LIST(DECODE_VRI_C_INSTRUCTIONS) 905#undef DECODE_VRI_C_INSTRUCTIONS 906 907#define DECODE_RIL_A_INSTRUCTIONS(name, opcode_name, opcode_value) \ 908 case opcode_name: \ 909 Format(instr, #name "\t'r1,'i7"); \ 910 break; 911 S390_RIL_A_OPCODE_LIST(DECODE_RIL_A_INSTRUCTIONS) 912#undef DECODE_RIL_A_INSTRUCTIONS 913 914#define DECODE_RIL_B_INSTRUCTIONS(name, opcode_name, opcode_value) \ 915 case opcode_name: \ 916 Format(instr, #name "\t'r1,'ie"); \ 917 break; 918 S390_RIL_B_OPCODE_LIST(DECODE_RIL_B_INSTRUCTIONS) 919#undef DECODE_RIL_B_INSTRUCTIONS 920 921#define DECODE_RIL_C_INSTRUCTIONS(name, opcode_name, opcode_value) \ 922 case opcode_name: \ 923 Format(instr, #name "\t'm1,'ie"); \ 924 break; 925 S390_RIL_C_OPCODE_LIST(DECODE_RIL_C_INSTRUCTIONS) 926#undef DECODE_RIL_C_INSTRUCTIONS 927 928#define DECODE_SIY_INSTRUCTIONS(name, opcode_name, opcode_value) \ 929 case opcode_name: \ 930 Format(instr, #name "\t'd2('r3),'i8"); \ 931 break; 932 S390_SIY_OPCODE_LIST(DECODE_SIY_INSTRUCTIONS) 933#undef DECODE_SIY_INSTRUCTIONS 934 935#define DECODE_RIE_D_INSTRUCTIONS(name, opcode_name, opcode_value) \ 936 case opcode_name: \ 937 Format(instr, #name "\t'r1,'r2,'i1"); \ 938 break; 939 S390_RIE_D_OPCODE_LIST(DECODE_RIE_D_INSTRUCTIONS) 940#undef DECODE_RIE_D_INSTRUCTIONS 941 942#define DECODE_RIE_E_INSTRUCTIONS(name, opcode_name, opcode_value) \ 943 case opcode_name: \ 944 Format(instr, #name "\t'r1,'r2,'i4"); \ 945 break; 946 S390_RIE_E_OPCODE_LIST(DECODE_RIE_E_INSTRUCTIONS) 947#undef DECODE_RIE_E_INSTRUCTIONS 948 949#define DECODE_RIE_F_INSTRUCTIONS(name, opcode_name, opcode_value) \ 950 case opcode_name: \ 951 Format(instr, #name "\t'r1,'r2,'i9,'ia,'ib"); \ 952 break; 953 S390_RIE_F_OPCODE_LIST(DECODE_RIE_F_INSTRUCTIONS) 954#undef DECODE_RIE_F_INSTRUCTIONS 955 956#define DECODE_RSY_A_INSTRUCTIONS(name, opcode_name, opcode_value) \ 957 case opcode_name: \ 958 Format(instr, #name "\t'r1,'r2,'d2('r3)"); \ 959 break; 960 S390_RSY_A_OPCODE_LIST(DECODE_RSY_A_INSTRUCTIONS) 961#undef DECODE_RSY_A_INSTRUCTIONS 962 963#define DECODE_RSY_B_INSTRUCTIONS(name, opcode_name, opcode_value) \ 964 case opcode_name: \ 965 Format(instr, #name "\t'm2,'r1,'d2('r3)"); \ 966 break; 967 S390_RSY_B_OPCODE_LIST(DECODE_RSY_B_INSTRUCTIONS) 968#undef DECODE_RSY_B_INSTRUCTIONS 969 970#define DECODE_RXY_A_INSTRUCTIONS(name, opcode_name, opcode_value) \ 971 case opcode_name: \ 972 Format(instr, #name "\t'r1,'d2('r2d,'r3)"); \ 973 break; 974 S390_RXY_A_OPCODE_LIST(DECODE_RXY_A_INSTRUCTIONS) 975#undef DECODE_RXY_A_INSTRUCTIONS 976 977#define DECODE_RXY_B_INSTRUCTIONS(name, opcode_name, opcode_value) \ 978 case opcode_name: \ 979 Format(instr, #name "\t'm1,'d2('r2d,'r3)"); \ 980 break; 981 S390_RXY_B_OPCODE_LIST(DECODE_RXY_B_INSTRUCTIONS) 982#undef DECODE_RXY_B_INSTRUCTIONS 983 984#define DECODE_RXE_INSTRUCTIONS(name, opcode_name, opcode_value) \ 985 case opcode_name: \ 986 Format(instr, #name "\t'f1,'d1('r2d, 'r3)"); \ 987 break; 988 S390_RXE_OPCODE_LIST(DECODE_RXE_INSTRUCTIONS) 989#undef DECODE_RXE_INSTRUCTIONS 990 991#define DECODE_SIL_INSTRUCTIONS(name, opcode_name, opcode_value) \ 992 case opcode_name: \ 993 Format(instr, #name "\t'd3('r3),'id"); \ 994 break; 995 S390_SIL_OPCODE_LIST(DECODE_SIL_INSTRUCTIONS) 996#undef DECODE_SIL_INSTRUCTIONS 997 998#define DECODE_SS_A_INSTRUCTIONS(name, opcode_name, opcode_value) \ 999 case opcode_name: \ 1000 Format(instr, #name "\t'd3('i8,'r3),'d4('r7)"); \ 1001 break; 1002 S390_SS_A_OPCODE_LIST(DECODE_SS_A_INSTRUCTIONS) 1003#undef DECODE_SS_A_INSTRUCTIONS 1004 1005 default: 1006 return false; 1007 } 1008 return true; 1009} 1010 1011// Disassemble the instruction at *instr_ptr into the output buffer. 1012int Decoder::InstructionDecode(byte* instr_ptr) { 1013 Instruction* instr = Instruction::At(instr_ptr); 1014 int instrLength = instr->InstructionLength(); 1015 1016 // Print the Instruction bits. 1017 if (instrLength == 2) { 1018 out_buffer_pos_ += 1019 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%04x ", 1020 instr->InstructionBits<TwoByteInstr>()); 1021 } else if (instrLength == 4) { 1022 out_buffer_pos_ += 1023 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%08x ", 1024 instr->InstructionBits<FourByteInstr>()); 1025 } else { 1026 out_buffer_pos_ += 1027 base::SNPrintF(out_buffer_ + out_buffer_pos_, "%012" PRIx64 " ", 1028 instr->InstructionBits<SixByteInstr>()); 1029 } 1030 1031 bool decoded = DecodeSpecial(instr); 1032 if (!decoded) decoded = DecodeGeneric(instr); 1033 if (!decoded) Unknown(instr); 1034 return instrLength; 1035} 1036 1037} // namespace internal 1038} // namespace v8 1039 1040//------------------------------------------------------------------------------ 1041 1042namespace disasm { 1043 1044const char* NameConverter::NameOfAddress(byte* addr) const { 1045 v8::base::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr)); 1046 return tmp_buffer_.begin(); 1047} 1048 1049const char* NameConverter::NameOfConstant(byte* addr) const { 1050 return NameOfAddress(addr); 1051} 1052 1053const char* NameConverter::NameOfCPURegister(int reg) const { 1054 return RegisterName(i::Register::from_code(reg)); 1055} 1056 1057const char* NameConverter::NameOfByteCPURegister(int reg) const { 1058 UNREACHABLE(); // S390 does not have the concept of a byte register 1059} 1060 1061const char* NameConverter::NameOfXMMRegister(int reg) const { 1062 // S390 does not have XMM register 1063 // TODO(joransiu): Consider update this for Vector Regs 1064 UNREACHABLE(); 1065} 1066 1067const char* NameConverter::NameInCode(byte* addr) const { 1068 // The default name converter is called for unknown code. So we will not try 1069 // to access any memory. 1070 return ""; 1071} 1072 1073//------------------------------------------------------------------------------ 1074 1075int Disassembler::InstructionDecode(v8::base::Vector<char> buffer, 1076 byte* instruction) { 1077 v8::internal::Decoder d(converter_, buffer); 1078 return d.InstructionDecode(instruction); 1079} 1080 1081// The S390 assembler does not currently use constant pools. 1082int Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; } 1083 1084void Disassembler::Disassemble(FILE* f, byte* begin, byte* end, 1085 UnimplementedOpcodeAction unimplemented_action) { 1086 NameConverter converter; 1087 Disassembler d(converter, unimplemented_action); 1088 for (byte* pc = begin; pc < end;) { 1089 v8::base::EmbeddedVector<char, 128> buffer; 1090 buffer[0] = '\0'; 1091 byte* prev_pc = pc; 1092 pc += d.InstructionDecode(buffer, pc); 1093 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc), 1094 *reinterpret_cast<int32_t*>(prev_pc), buffer.begin()); 1095 } 1096} 1097 1098} // namespace disasm 1099 1100#endif // V8_TARGET_ARCH_S390 1101