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