• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
40 namespace v8 {
41 namespace 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.
48 class Decoder {
49  public:
Decoder(const disasm::NameConverter & converter,base::Vector<char> out_buffer)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 
~Decoder()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.
PrintChar(const char ch)98 void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; }
99 
100 // Append the str to the output buffer.
Print(const char * str)101 void 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.
PrintRegister(int reg)111 void Decoder::PrintRegister(int reg) {
112   Print(converter_.NameOfCPURegister(reg));
113 }
114 
115 // Print the double FP register name according to the active name converter.
PrintDRegister(int reg)116 void 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.
PrintSoftwareInterrupt(SoftwareInterruptCodes svc)122 void 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.
FormatRegister(Instruction * instr,const char * format)145 int 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 
FormatFloatingRegister(Instruction * instr,const char * format)189 int 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.
FormatOption(Instruction * instr,const char * format)232 int 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 
FormatMask(Instruction * instr,const char * format)309 int 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 
FormatDisplacement(Instruction * instr,const char * format)347 int 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 
FormatImmediate(Instruction * instr,const char * format)383 int 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.
Format(Instruction * instr,const char * format)496 void 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.
Unknown(Instruction * instr)519 void 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.
UnknownFormat(Instruction * instr,const char * name)524 void 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
DecodeSpecial(Instruction * instr)535 bool 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
DecodeGeneric(Instruction * instr)726 bool 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.
InstructionDecode(byte * instr_ptr)1012 int 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 
1042 namespace disasm {
1043 
NameOfAddress(byte * addr) const1044 const char* NameConverter::NameOfAddress(byte* addr) const {
1045   v8::base::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr));
1046   return tmp_buffer_.begin();
1047 }
1048 
NameOfConstant(byte * addr) const1049 const char* NameConverter::NameOfConstant(byte* addr) const {
1050   return NameOfAddress(addr);
1051 }
1052 
NameOfCPURegister(int reg) const1053 const char* NameConverter::NameOfCPURegister(int reg) const {
1054   return RegisterName(i::Register::from_code(reg));
1055 }
1056 
NameOfByteCPURegister(int reg) const1057 const char* NameConverter::NameOfByteCPURegister(int reg) const {
1058   UNREACHABLE();  // S390 does not have the concept of a byte register
1059 }
1060 
NameOfXMMRegister(int reg) const1061 const 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 
NameInCode(byte * addr) const1067 const 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 
InstructionDecode(v8::base::Vector<char> buffer,byte * instruction)1075 int 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.
ConstantPoolSizeAt(byte * instruction)1082 int Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; }
1083 
Disassemble(FILE * f,byte * begin,byte * end,UnimplementedOpcodeAction unimplemented_action)1084 void 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