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/s390/constants-s390.h"
36
37 namespace v8 {
38 namespace internal {
39
40 const auto GetRegConfig = RegisterConfiguration::Crankshaft;
41
42 //------------------------------------------------------------------------------
43
44 // Decoder decodes and disassembles instructions into an output buffer.
45 // It uses the converter to convert register names and call destinations into
46 // more informative description.
47 class Decoder {
48 public:
Decoder(const disasm::NameConverter & converter,Vector<char> out_buffer)49 Decoder(const disasm::NameConverter& converter, Vector<char> out_buffer)
50 : converter_(converter), out_buffer_(out_buffer), out_buffer_pos_(0) {
51 out_buffer_[out_buffer_pos_] = '\0';
52 }
53
~Decoder()54 ~Decoder() {}
55
56 // Writes one disassembled instruction into 'buffer' (0-terminated).
57 // Returns the length of the disassembled machine instruction in bytes.
58 int InstructionDecode(byte* instruction);
59
60 private:
61 // Bottleneck functions to print into the out_buffer.
62 void PrintChar(const char ch);
63 void Print(const char* str);
64
65 // Printing of common values.
66 void PrintRegister(int reg);
67 void PrintDRegister(int reg);
68 void PrintSoftwareInterrupt(SoftwareInterruptCodes svc);
69
70 // Handle formatting of instructions and their options.
71 int FormatRegister(Instruction* instr, const char* option);
72 int FormatFloatingRegister(Instruction* instr, const char* option);
73 int FormatMask(Instruction* instr, const char* option);
74 int FormatDisplacement(Instruction* instr, const char* option);
75 int FormatImmediate(Instruction* instr, const char* option);
76 int FormatOption(Instruction* instr, const char* option);
77 void Format(Instruction* instr, const char* format);
78 void Unknown(Instruction* instr);
79 void UnknownFormat(Instruction* instr, const char* opcname);
80
81 bool DecodeTwoByte(Instruction* instr);
82 bool DecodeFourByte(Instruction* instr);
83 bool DecodeSixByte(Instruction* instr);
84
85 const disasm::NameConverter& converter_;
86 Vector<char> out_buffer_;
87 int out_buffer_pos_;
88
89 DISALLOW_COPY_AND_ASSIGN(Decoder);
90 };
91
92 // Support for assertions in the Decoder formatting functions.
93 #define STRING_STARTS_WITH(string, compare_string) \
94 (strncmp(string, compare_string, strlen(compare_string)) == 0)
95
96 // Append the ch to the output buffer.
PrintChar(const char ch)97 void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; }
98
99 // Append the str to the output buffer.
Print(const char * str)100 void Decoder::Print(const char* str) {
101 char cur = *str++;
102 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
103 PrintChar(cur);
104 cur = *str++;
105 }
106 out_buffer_[out_buffer_pos_] = 0;
107 }
108
109 // Print the register name according to the active name converter.
PrintRegister(int reg)110 void Decoder::PrintRegister(int reg) {
111 Print(converter_.NameOfCPURegister(reg));
112 }
113
114 // Print the double FP register name according to the active name converter.
PrintDRegister(int reg)115 void Decoder::PrintDRegister(int reg) {
116 Print(GetRegConfig()->GetDoubleRegisterName(reg));
117 }
118
119 // Print SoftwareInterrupt codes. Factoring this out reduces the complexity of
120 // the FormatOption method.
PrintSoftwareInterrupt(SoftwareInterruptCodes svc)121 void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) {
122 switch (svc) {
123 case kCallRtRedirected:
124 Print("call rt redirected");
125 return;
126 case kBreakpoint:
127 Print("breakpoint");
128 return;
129 default:
130 if (svc >= kStopCode) {
131 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d - 0x%x",
132 svc & kStopCodeMask, svc & kStopCodeMask);
133 } else {
134 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", svc);
135 }
136 return;
137 }
138 }
139
140 // Handle all register based formatting in this function to reduce the
141 // complexity of FormatOption.
FormatRegister(Instruction * instr,const char * format)142 int Decoder::FormatRegister(Instruction* instr, const char* format) {
143 DCHECK(format[0] == 'r');
144
145 if (format[1] == '1') { // 'r1: register resides in bit 8-11
146 RRInstruction* rrinstr = reinterpret_cast<RRInstruction*>(instr);
147 int reg = rrinstr->R1Value();
148 PrintRegister(reg);
149 return 2;
150 } else if (format[1] == '2') { // 'r2: register resides in bit 12-15
151 RRInstruction* rrinstr = reinterpret_cast<RRInstruction*>(instr);
152 int reg = rrinstr->R2Value();
153 // indicating it is a r0 for displacement, in which case the offset
154 // should be 0.
155 if (format[2] == 'd') {
156 if (reg == 0) return 4;
157 PrintRegister(reg);
158 return 3;
159 } else {
160 PrintRegister(reg);
161 return 2;
162 }
163 } else if (format[1] == '3') { // 'r3: register resides in bit 16-19
164 RSInstruction* rsinstr = reinterpret_cast<RSInstruction*>(instr);
165 int reg = rsinstr->B2Value();
166 PrintRegister(reg);
167 return 2;
168 } else if (format[1] == '4') { // 'r4: register resides in bit 20-23
169 RSInstruction* rsinstr = reinterpret_cast<RSInstruction*>(instr);
170 int reg = rsinstr->B2Value();
171 PrintRegister(reg);
172 return 2;
173 } else if (format[1] == '5') { // 'r5: register resides in bit 24-28
174 RREInstruction* rreinstr = reinterpret_cast<RREInstruction*>(instr);
175 int reg = rreinstr->R1Value();
176 PrintRegister(reg);
177 return 2;
178 } else if (format[1] == '6') { // 'r6: register resides in bit 29-32
179 RREInstruction* rreinstr = reinterpret_cast<RREInstruction*>(instr);
180 int reg = rreinstr->R2Value();
181 PrintRegister(reg);
182 return 2;
183 } else if (format[1] == '7') { // 'r6: register resides in bit 32-35
184 SSInstruction* ssinstr = reinterpret_cast<SSInstruction*>(instr);
185 int reg = ssinstr->B2Value();
186 PrintRegister(reg);
187 return 2;
188 }
189
190 UNREACHABLE();
191 return -1;
192 }
193
FormatFloatingRegister(Instruction * instr,const char * format)194 int Decoder::FormatFloatingRegister(Instruction* instr, const char* format) {
195 DCHECK(format[0] == 'f');
196
197 // reuse 1, 5 and 6 because it is coresponding
198 if (format[1] == '1') { // 'r1: register resides in bit 8-11
199 RRInstruction* rrinstr = reinterpret_cast<RRInstruction*>(instr);
200 int reg = rrinstr->R1Value();
201 PrintDRegister(reg);
202 return 2;
203 } else if (format[1] == '2') { // 'f2: register resides in bit 12-15
204 RRInstruction* rrinstr = reinterpret_cast<RRInstruction*>(instr);
205 int reg = rrinstr->R2Value();
206 PrintDRegister(reg);
207 return 2;
208 } else if (format[1] == '3') { // 'f3: register resides in bit 16-19
209 RRDInstruction* rrdinstr = reinterpret_cast<RRDInstruction*>(instr);
210 int reg = rrdinstr->R1Value();
211 PrintDRegister(reg);
212 return 2;
213 } else if (format[1] == '5') { // 'f5: register resides in bit 24-28
214 RREInstruction* rreinstr = reinterpret_cast<RREInstruction*>(instr);
215 int reg = rreinstr->R1Value();
216 PrintDRegister(reg);
217 return 2;
218 } else if (format[1] == '6') { // 'f6: register resides in bit 29-32
219 RREInstruction* rreinstr = reinterpret_cast<RREInstruction*>(instr);
220 int reg = rreinstr->R2Value();
221 PrintDRegister(reg);
222 return 2;
223 }
224 UNREACHABLE();
225 return -1;
226 }
227
228 // FormatOption takes a formatting string and interprets it based on
229 // the current instructions. The format string points to the first
230 // character of the option string (the option escape has already been
231 // consumed by the caller.) FormatOption returns the number of
232 // characters that were consumed from the formatting string.
FormatOption(Instruction * instr,const char * format)233 int Decoder::FormatOption(Instruction* instr, const char* format) {
234 switch (format[0]) {
235 case 'o': {
236 if (instr->Bit(10) == 1) {
237 Print("o");
238 }
239 return 1;
240 }
241 case '.': {
242 if (instr->Bit(0) == 1) {
243 Print(".");
244 } else {
245 Print(" "); // ensure consistent spacing
246 }
247 return 1;
248 }
249 case 'r': {
250 return FormatRegister(instr, format);
251 }
252 case 'f': {
253 return FormatFloatingRegister(instr, format);
254 }
255 case 'i': { // int16
256 return FormatImmediate(instr, format);
257 }
258 case 'u': { // uint16
259 int32_t value = instr->Bits(15, 0);
260 out_buffer_pos_ += 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_ += 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_ += SNPrintF(
289 out_buffer_ + out_buffer_pos_, "%+d -> %s", off,
290 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off));
291 return 8;
292 }
293 case 'm': {
294 return FormatMask(instr, format);
295 }
296 }
297 case 'd': { // ds value for offset
298 return FormatDisplacement(instr, format);
299 }
300 default: {
301 UNREACHABLE();
302 break;
303 }
304 }
305
306 UNREACHABLE();
307 return -1;
308 }
309
FormatMask(Instruction * instr,const char * format)310 int Decoder::FormatMask(Instruction* instr, const char* format) {
311 DCHECK(format[0] == 'm');
312 int32_t value = 0;
313 if ((format[1] == '1')) { // prints the mask format in bits 8-12
314 value = reinterpret_cast<RRInstruction*>(instr)->R1Value();
315 out_buffer_pos_ += 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_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value);
320 return 2;
321 } else if (format[1] == '3') { // mask format in bits 20-23
322 value = reinterpret_cast<RRFInstruction*>(instr)->M4Value();
323 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", value);
324 return 2;
325 }
326
327 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
328 return 2;
329 }
330
FormatDisplacement(Instruction * instr,const char * format)331 int Decoder::FormatDisplacement(Instruction* instr, const char* format) {
332 DCHECK(format[0] == 'd');
333
334 if (format[1] == '1') { // displacement in 20-31
335 RSInstruction* rsinstr = reinterpret_cast<RSInstruction*>(instr);
336 uint16_t value = rsinstr->D2Value();
337 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
338
339 return 2;
340 } else if (format[1] == '2') { // displacement in 20-39
341 RXYInstruction* rxyinstr = reinterpret_cast<RXYInstruction*>(instr);
342 int32_t value = rxyinstr->D2Value();
343 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
344 return 2;
345 } else if (format[1] == '4') { // SS displacement 2 36-47
346 SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr);
347 uint16_t value = ssInstr->D2Value();
348 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
349 return 2;
350 } else if (format[1] == '3') { // SS displacement 1 20 - 32
351 SSInstruction* ssInstr = reinterpret_cast<SSInstruction*>(instr);
352 uint16_t value = ssInstr->D1Value();
353 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
354 return 2;
355 } else { // s390 specific
356 int32_t value = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3);
357 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
358 return 1;
359 }
360 }
361
FormatImmediate(Instruction * instr,const char * format)362 int Decoder::FormatImmediate(Instruction* instr, const char* format) {
363 DCHECK(format[0] == 'i');
364
365 if (format[1] == '1') { // immediate in 16-31
366 RIInstruction* riinstr = reinterpret_cast<RIInstruction*>(instr);
367 int16_t value = riinstr->I2Value();
368 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
369 return 2;
370 } else if (format[1] == '2') { // immediate in 16-48
371 RILInstruction* rilinstr = reinterpret_cast<RILInstruction*>(instr);
372 int32_t value = rilinstr->I2Value();
373 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
374 return 2;
375 } else if (format[1] == '3') { // immediate in I format
376 IInstruction* iinstr = reinterpret_cast<IInstruction*>(instr);
377 int8_t value = iinstr->IValue();
378 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
379 return 2;
380 } else if (format[1] == '4') { // immediate in 16-31, but outputs as offset
381 RIInstruction* riinstr = reinterpret_cast<RIInstruction*>(instr);
382 int16_t value = riinstr->I2Value() * 2;
383 if (value >= 0)
384 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "*+");
385 else
386 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "*");
387
388 out_buffer_pos_ += SNPrintF(
389 out_buffer_ + out_buffer_pos_, "%d -> %s", value,
390 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + value));
391 return 2;
392 } else if (format[1] == '5') { // immediate in 16-31, but outputs as offset
393 RILInstruction* rilinstr = reinterpret_cast<RILInstruction*>(instr);
394 int32_t value = rilinstr->I2Value() * 2;
395 if (value >= 0)
396 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "*+");
397 else
398 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "*");
399
400 out_buffer_pos_ += SNPrintF(
401 out_buffer_ + out_buffer_pos_, "%d -> %s", value,
402 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + value));
403 return 2;
404 } else if (format[1] == '6') { // unsigned immediate in 16-31
405 RIInstruction* riinstr = reinterpret_cast<RIInstruction*>(instr);
406 uint16_t value = riinstr->I2UnsignedValue();
407 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
408 return 2;
409 } else if (format[1] == '7') { // unsigned immediate in 16-47
410 RILInstruction* rilinstr = reinterpret_cast<RILInstruction*>(instr);
411 uint32_t value = rilinstr->I2UnsignedValue();
412 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
413 return 2;
414 } else if (format[1] == '8') { // unsigned immediate in 8-15
415 SSInstruction* ssinstr = reinterpret_cast<SSInstruction*>(instr);
416 uint8_t value = ssinstr->Length();
417 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
418 return 2;
419 } else if (format[1] == '9') { // unsigned immediate in 16-23
420 RIEInstruction* rie_instr = reinterpret_cast<RIEInstruction*>(instr);
421 uint8_t value = rie_instr->I3Value();
422 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
423 return 2;
424 } else if (format[1] == 'a') { // unsigned immediate in 24-31
425 RIEInstruction* rie_instr = reinterpret_cast<RIEInstruction*>(instr);
426 uint8_t value = rie_instr->I4Value();
427 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
428 return 2;
429 } else if (format[1] == 'b') { // unsigned immediate in 32-39
430 RIEInstruction* rie_instr = reinterpret_cast<RIEInstruction*>(instr);
431 uint8_t value = rie_instr->I5Value();
432 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
433 return 2;
434 } else if (format[1] == 'c') { // signed immediate in 8-15
435 SSInstruction* ssinstr = reinterpret_cast<SSInstruction*>(instr);
436 int8_t value = ssinstr->Length();
437 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
438 return 2;
439 } else if (format[1] == 'd') { // signed immediate in 32-47
440 SILInstruction* silinstr = reinterpret_cast<SILInstruction*>(instr);
441 int16_t value = silinstr->I2Value();
442 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
443 return 2;
444 } else if (format[1] == 'e') { // immediate in 16-47, but outputs as offset
445 RILInstruction* rilinstr = reinterpret_cast<RILInstruction*>(instr);
446 int32_t value = rilinstr->I2Value() * 2;
447 if (value >= 0)
448 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "*+");
449 else
450 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "*");
451
452 out_buffer_pos_ += SNPrintF(
453 out_buffer_ + out_buffer_pos_, "%d -> %s", value,
454 converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + value));
455 return 2;
456 }
457
458 UNREACHABLE();
459 return -1;
460 }
461
462 // Format takes a formatting string for a whole instruction and prints it into
463 // the output buffer. All escaped options are handed to FormatOption to be
464 // parsed further.
Format(Instruction * instr,const char * format)465 void Decoder::Format(Instruction* instr, const char* format) {
466 char cur = *format++;
467 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
468 if (cur == '\'') { // Single quote is used as the formatting escape.
469 format += FormatOption(instr, format);
470 } else {
471 out_buffer_[out_buffer_pos_++] = cur;
472 }
473 cur = *format++;
474 }
475 out_buffer_[out_buffer_pos_] = '\0';
476 }
477
478 // The disassembler may end up decoding data inlined in the code. We do not want
479 // it to crash if the data does not ressemble any known instruction.
480 #define VERIFY(condition) \
481 if (!(condition)) { \
482 Unknown(instr); \
483 return; \
484 }
485
486 // For currently unimplemented decodings the disassembler calls Unknown(instr)
487 // which will just print "unknown" of the instruction bits.
Unknown(Instruction * instr)488 void Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); }
489
490 // For currently unimplemented decodings the disassembler calls
491 // UnknownFormat(instr) which will just print opcode name of the
492 // instruction bits.
UnknownFormat(Instruction * instr,const char * name)493 void Decoder::UnknownFormat(Instruction* instr, const char* name) {
494 char buffer[100];
495 snprintf(buffer, sizeof(buffer), "%s (unknown-format)", name);
496 Format(instr, buffer);
497 }
498
499 // Disassembles Two Byte S390 Instructions
500 // @return true if successfully decoded
DecodeTwoByte(Instruction * instr)501 bool Decoder::DecodeTwoByte(Instruction* instr) {
502 // Print the Instruction bits.
503 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%04x ",
504 instr->InstructionBits<TwoByteInstr>());
505
506 Opcode opcode = instr->S390OpcodeValue();
507 switch (opcode) {
508 case AR:
509 Format(instr, "ar\t'r1,'r2");
510 break;
511 case SR:
512 Format(instr, "sr\t'r1,'r2");
513 break;
514 case MR:
515 Format(instr, "mr\t'r1,'r2");
516 break;
517 case DR:
518 Format(instr, "dr\t'r1,'r2");
519 break;
520 case OR:
521 Format(instr, "or\t'r1,'r2");
522 break;
523 case NR:
524 Format(instr, "nr\t'r1,'r2");
525 break;
526 case XR:
527 Format(instr, "xr\t'r1,'r2");
528 break;
529 case LR:
530 Format(instr, "lr\t'r1,'r2");
531 break;
532 case CR:
533 Format(instr, "cr\t'r1,'r2");
534 break;
535 case CLR:
536 Format(instr, "clr\t'r1,'r2");
537 break;
538 case BCR:
539 Format(instr, "bcr\t'm1,'r2");
540 break;
541 case LTR:
542 Format(instr, "ltr\t'r1,'r2");
543 break;
544 case ALR:
545 Format(instr, "alr\t'r1,'r2");
546 break;
547 case SLR:
548 Format(instr, "slr\t'r1,'r2");
549 break;
550 case LNR:
551 Format(instr, "lnr\t'r1,'r2");
552 break;
553 case LCR:
554 Format(instr, "lcr\t'r1,'r2");
555 break;
556 case BASR:
557 Format(instr, "basr\t'r1,'r2");
558 break;
559 case LDR:
560 Format(instr, "ldr\t'f1,'f2");
561 break;
562 case BKPT:
563 Format(instr, "bkpt");
564 break;
565 default:
566 return false;
567 }
568 return true;
569 }
570
571 // Disassembles Four Byte S390 Instructions
572 // @return true if successfully decoded
DecodeFourByte(Instruction * instr)573 bool Decoder::DecodeFourByte(Instruction* instr) {
574 // Print the Instruction bits.
575 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%08x ",
576 instr->InstructionBits<FourByteInstr>());
577
578 Opcode opcode = instr->S390OpcodeValue();
579 switch (opcode) {
580 case AHI:
581 Format(instr, "ahi\t'r1,'i1");
582 break;
583 case AGHI:
584 Format(instr, "aghi\t'r1,'i1");
585 break;
586 case LHI:
587 Format(instr, "lhi\t'r1,'i1");
588 break;
589 case LGHI:
590 Format(instr, "lghi\t'r1,'i1");
591 break;
592 case MHI:
593 Format(instr, "mhi\t'r1,'i1");
594 break;
595 case MGHI:
596 Format(instr, "mghi\t'r1,'i1");
597 break;
598 case CHI:
599 Format(instr, "chi\t'r1,'i1");
600 break;
601 case CGHI:
602 Format(instr, "cghi\t'r1,'i1");
603 break;
604 case BRAS:
605 Format(instr, "bras\t'r1,'i1");
606 break;
607 case BRC:
608 Format(instr, "brc\t'm1,'i4");
609 break;
610 case BRCT:
611 Format(instr, "brct\t'r1,'i4");
612 break;
613 case BRCTG:
614 Format(instr, "brctg\t'r1,'i4");
615 break;
616 case IIHH:
617 Format(instr, "iihh\t'r1,'i1");
618 break;
619 case IIHL:
620 Format(instr, "iihl\t'r1,'i1");
621 break;
622 case IILH:
623 Format(instr, "iilh\t'r1,'i1");
624 break;
625 case IILL:
626 Format(instr, "iill\t'r1,'i1");
627 break;
628 case OILL:
629 Format(instr, "oill\t'r1,'i1");
630 break;
631 case TMLL:
632 Format(instr, "tmll\t'r1,'i1");
633 break;
634 case STM:
635 Format(instr, "stm\t'r1,'r2,'d1('r3)");
636 break;
637 case LM:
638 Format(instr, "lm\t'r1,'r2,'d1('r3)");
639 break;
640 case SLL:
641 Format(instr, "sll\t'r1,'d1('r3)");
642 break;
643 case SRL:
644 Format(instr, "srl\t'r1,'d1('r3)");
645 break;
646 case SLA:
647 Format(instr, "sla\t'r1,'d1('r3)");
648 break;
649 case SRA:
650 Format(instr, "sra\t'r1,'d1('r3)");
651 break;
652 case SLDL:
653 Format(instr, "sldl\t'r1,'d1('r3)");
654 break;
655 case AGR:
656 Format(instr, "agr\t'r5,'r6");
657 break;
658 case AGFR:
659 Format(instr, "agfr\t'r5,'r6");
660 break;
661 case ARK:
662 Format(instr, "ark\t'r5,'r6,'r3");
663 break;
664 case AGRK:
665 Format(instr, "agrk\t'r5,'r6,'r3");
666 break;
667 case SGR:
668 Format(instr, "sgr\t'r5,'r6");
669 break;
670 case SGFR:
671 Format(instr, "sgfr\t'r5,'r6");
672 break;
673 case SRK:
674 Format(instr, "srk\t'r5,'r6,'r3");
675 break;
676 case SGRK:
677 Format(instr, "sgrk\t'r5,'r6,'r3");
678 break;
679 case NGR:
680 Format(instr, "ngr\t'r5,'r6");
681 break;
682 case NRK:
683 Format(instr, "nrk\t'r5,'r6,'r3");
684 break;
685 case NGRK:
686 Format(instr, "ngrk\t'r5,'r6,'r3");
687 break;
688 case NILL:
689 Format(instr, "nill\t'r1,'i1");
690 break;
691 case NILH:
692 Format(instr, "nilh\t'r1,'i1");
693 break;
694 case OGR:
695 Format(instr, "ogr\t'r5,'r6");
696 break;
697 case ORK:
698 Format(instr, "ork\t'r5,'r6,'r3");
699 break;
700 case OGRK:
701 Format(instr, "ogrk\t'r5,'r6,'r3");
702 break;
703 case XGR:
704 Format(instr, "xgr\t'r5,'r6");
705 break;
706 case XRK:
707 Format(instr, "xrk\t'r5,'r6,'r3");
708 break;
709 case XGRK:
710 Format(instr, "xgrk\t'r5,'r6,'r3");
711 break;
712 case CGR:
713 Format(instr, "cgr\t'r5,'r6");
714 break;
715 case CLGR:
716 Format(instr, "clgr\t'r5,'r6");
717 break;
718 case LLGFR:
719 Format(instr, "llgfr\t'r5,'r6");
720 break;
721 case LBR:
722 Format(instr, "lbr\t'r5,'r6");
723 break;
724 case LEDBR:
725 Format(instr, "ledbr\t'f5,'f6");
726 break;
727 case LDEBR:
728 Format(instr, "ldebr\t'f5,'f6");
729 break;
730 case LTGR:
731 Format(instr, "ltgr\t'r5,'r6");
732 break;
733 case LTDBR:
734 Format(instr, "ltdbr\t'f5,'f6");
735 break;
736 case LTEBR:
737 Format(instr, "ltebr\t'f5,'f6");
738 break;
739 case LRVR:
740 Format(instr, "lrvr\t'r5,'r6");
741 break;
742 case LRVGR:
743 Format(instr, "lrvgr\t'r5,'r6");
744 break;
745 case LGR:
746 Format(instr, "lgr\t'r5,'r6");
747 break;
748 case LGDR:
749 Format(instr, "lgdr\t'r5,'f6");
750 break;
751 case LGFR:
752 Format(instr, "lgfr\t'r5,'r6");
753 break;
754 case LTGFR:
755 Format(instr, "ltgfr\t'r5,'r6");
756 break;
757 case LCGR:
758 Format(instr, "lcgr\t'r5,'r6");
759 break;
760 case MSR:
761 Format(instr, "msr\t'r5,'r6");
762 break;
763 case LGBR:
764 Format(instr, "lgbr\t'r5,'r6");
765 break;
766 case LGHR:
767 Format(instr, "lghr\t'r5,'r6");
768 break;
769 case MSGR:
770 Format(instr, "msgr\t'r5,'r6");
771 break;
772 case DSGR:
773 Format(instr, "dsgr\t'r5,'r6");
774 break;
775 case LZDR:
776 Format(instr, "lzdr\t'f5");
777 break;
778 case MLR:
779 Format(instr, "mlr\t'r5,'r6");
780 break;
781 case MLGR:
782 Format(instr, "mlgr\t'r5,'r6");
783 break;
784 case ALCR:
785 Format(instr, "alcr\t'r5,'r6");
786 break;
787 case ALGR:
788 Format(instr, "algr\t'r5,'r6");
789 break;
790 case ALRK:
791 Format(instr, "alrk\t'r5,'r6,'r3");
792 break;
793 case ALGRK:
794 Format(instr, "algrk\t'r5,'r6,'r3");
795 break;
796 case SLGR:
797 Format(instr, "slgr\t'r5,'r6");
798 break;
799 case SLBR:
800 Format(instr, "slbr\t'r5,'r6");
801 break;
802 case DLR:
803 Format(instr, "dlr\t'r5,'r6");
804 break;
805 case DLGR:
806 Format(instr, "dlgr\t'r5,'r6");
807 break;
808 case SLRK:
809 Format(instr, "slrk\t'r5,'r6,'r3");
810 break;
811 case SLGRK:
812 Format(instr, "slgrk\t'r5,'r6,'r3");
813 break;
814 case LHR:
815 Format(instr, "lhr\t'r5,'r6");
816 break;
817 case LLHR:
818 Format(instr, "llhr\t'r5,'r6");
819 break;
820 case LLGHR:
821 Format(instr, "llghr\t'r5,'r6");
822 break;
823 case LOCR:
824 Format(instr, "locr\t'm1,'r5,'r6");
825 break;
826 case LOCGR:
827 Format(instr, "locgr\t'm1,'r5,'r6");
828 break;
829 case LNGR:
830 Format(instr, "lngr\t'r5,'r6");
831 break;
832 case A:
833 Format(instr, "a\t'r1,'d1('r2d,'r3)");
834 break;
835 case S:
836 Format(instr, "s\t'r1,'d1('r2d,'r3)");
837 break;
838 case M:
839 Format(instr, "m\t'r1,'d1('r2d,'r3)");
840 break;
841 case D:
842 Format(instr, "d\t'r1,'d1('r2d,'r3)");
843 break;
844 case O:
845 Format(instr, "o\t'r1,'d1('r2d,'r3)");
846 break;
847 case N:
848 Format(instr, "n\t'r1,'d1('r2d,'r3)");
849 break;
850 case L:
851 Format(instr, "l\t'r1,'d1('r2d,'r3)");
852 break;
853 case C:
854 Format(instr, "c\t'r1,'d1('r2d,'r3)");
855 break;
856 case AH:
857 Format(instr, "ah\t'r1,'d1('r2d,'r3)");
858 break;
859 case SH:
860 Format(instr, "sh\t'r1,'d1('r2d,'r3)");
861 break;
862 case MH:
863 Format(instr, "mh\t'r1,'d1('r2d,'r3)");
864 break;
865 case AL:
866 Format(instr, "al\t'r1,'d1('r2d,'r3)");
867 break;
868 case SL:
869 Format(instr, "sl\t'r1,'d1('r2d,'r3)");
870 break;
871 case LA:
872 Format(instr, "la\t'r1,'d1('r2d,'r3)");
873 break;
874 case CH:
875 Format(instr, "ch\t'r1,'d1('r2d,'r3)");
876 break;
877 case CL:
878 Format(instr, "cl\t'r1,'d1('r2d,'r3)");
879 break;
880 case CLI:
881 Format(instr, "cli\t'd1('r3),'i8");
882 break;
883 case TM:
884 Format(instr, "tm\t'd1('r3),'i8");
885 break;
886 case BC:
887 Format(instr, "bc\t'm1,'d1('r2d,'r3)");
888 break;
889 case BCT:
890 Format(instr, "bct\t'r1,'d1('r2d,'r3)");
891 break;
892 case ST:
893 Format(instr, "st\t'r1,'d1('r2d,'r3)");
894 break;
895 case STC:
896 Format(instr, "stc\t'r1,'d1('r2d,'r3)");
897 break;
898 case IC_z:
899 Format(instr, "ic\t'r1,'d1('r2d,'r3)");
900 break;
901 case LD:
902 Format(instr, "ld\t'f1,'d1('r2d,'r3)");
903 break;
904 case LE:
905 Format(instr, "le\t'f1,'d1('r2d,'r3)");
906 break;
907 case LDGR:
908 Format(instr, "ldgr\t'f5,'r6");
909 break;
910 case MS:
911 Format(instr, "ms\t'r1,'d1('r2d,'r3)");
912 break;
913 case STE:
914 Format(instr, "ste\t'f1,'d1('r2d,'r3)");
915 break;
916 case STD:
917 Format(instr, "std\t'f1,'d1('r2d,'r3)");
918 break;
919 case CFDBR:
920 Format(instr, "cfdbr\t'r5,'m2,'f6");
921 break;
922 case CDFBR:
923 Format(instr, "cdfbr\t'f5,'m2,'r6");
924 break;
925 case CFEBR:
926 Format(instr, "cfebr\t'r5,'m2,'f6");
927 break;
928 case CEFBR:
929 Format(instr, "cefbr\t'f5,'m2,'r6");
930 break;
931 case CELFBR:
932 Format(instr, "celfbr\t'f5,'m2,'r6");
933 break;
934 case CGEBR:
935 Format(instr, "cgebr\t'r5,'m2,'f6");
936 break;
937 case CGDBR:
938 Format(instr, "cgdbr\t'r5,'m2,'f6");
939 break;
940 case CEGBR:
941 Format(instr, "cegbr\t'f5,'m2,'r6");
942 break;
943 case CDGBR:
944 Format(instr, "cdgbr\t'f5,'m2,'r6");
945 break;
946 case CDLFBR:
947 Format(instr, "cdlfbr\t'f5,'m2,'r6");
948 break;
949 case CDLGBR:
950 Format(instr, "cdlgbr\t'f5,'m2,'r6");
951 break;
952 case CELGBR:
953 Format(instr, "celgbr\t'f5,'m2,'r6");
954 break;
955 case CLFDBR:
956 Format(instr, "clfdbr\t'r5,'m2,'f6");
957 break;
958 case CLFEBR:
959 Format(instr, "clfebr\t'r5,'m2,'f6");
960 break;
961 case CLGEBR:
962 Format(instr, "clgebr\t'r5,'m2,'f6");
963 break;
964 case CLGDBR:
965 Format(instr, "clgdbr\t'r5,'m2,'f6");
966 break;
967 case AEBR:
968 Format(instr, "aebr\t'f5,'f6");
969 break;
970 case SEBR:
971 Format(instr, "sebr\t'f5,'f6");
972 break;
973 case MEEBR:
974 Format(instr, "meebr\t'f5,'f6");
975 break;
976 case DEBR:
977 Format(instr, "debr\t'f5,'f6");
978 break;
979 case ADBR:
980 Format(instr, "adbr\t'f5,'f6");
981 break;
982 case SDBR:
983 Format(instr, "sdbr\t'f5,'f6");
984 break;
985 case MDBR:
986 Format(instr, "mdbr\t'f5,'f6");
987 break;
988 case DDBR:
989 Format(instr, "ddbr\t'f5,'f6");
990 break;
991 case CDBR:
992 Format(instr, "cdbr\t'f5,'f6");
993 break;
994 case CEBR:
995 Format(instr, "cebr\t'f5,'f6");
996 break;
997 case SQDBR:
998 Format(instr, "sqdbr\t'f5,'f6");
999 break;
1000 case SQEBR:
1001 Format(instr, "sqebr\t'f5,'f6");
1002 break;
1003 case LCDBR:
1004 Format(instr, "lcdbr\t'f5,'f6");
1005 break;
1006 case LCEBR:
1007 Format(instr, "lcebr\t'f5,'f6");
1008 break;
1009 case STH:
1010 Format(instr, "sth\t'r1,'d1('r2d,'r3)");
1011 break;
1012 case SRDA:
1013 Format(instr, "srda\t'r1,'d1('r3)");
1014 break;
1015 case SRDL:
1016 Format(instr, "srdl\t'r1,'d1('r3)");
1017 break;
1018 case MADBR:
1019 Format(instr, "madbr\t'f3,'f5,'f6");
1020 break;
1021 case MSDBR:
1022 Format(instr, "msdbr\t'f3,'f5,'f6");
1023 break;
1024 case FLOGR:
1025 Format(instr, "flogr\t'r5,'r6");
1026 break;
1027 case FIEBRA:
1028 Format(instr, "fiebra\t'f5,'m2,'f6,'m3");
1029 break;
1030 case FIDBRA:
1031 Format(instr, "fidbra\t'f5,'m2,'f6,'m3");
1032 break;
1033 // TRAP4 is used in calling to native function. it will not be generated
1034 // in native code.
1035 case TRAP4: {
1036 Format(instr, "trap4");
1037 break;
1038 }
1039 default:
1040 return false;
1041 }
1042 return true;
1043 }
1044
1045 // Disassembles Six Byte S390 Instructions
1046 // @return true if successfully decoded
DecodeSixByte(Instruction * instr)1047 bool Decoder::DecodeSixByte(Instruction* instr) {
1048 // Print the Instruction bits.
1049 out_buffer_pos_ +=
1050 SNPrintF(out_buffer_ + out_buffer_pos_, "%012" PRIx64 " ",
1051 instr->InstructionBits<SixByteInstr>());
1052
1053 Opcode opcode = instr->S390OpcodeValue();
1054 switch (opcode) {
1055 case LLILF:
1056 Format(instr, "llilf\t'r1,'i7");
1057 break;
1058 case LLIHF:
1059 Format(instr, "llihf\t'r1,'i7");
1060 break;
1061 case AFI:
1062 Format(instr, "afi\t'r1,'i7");
1063 break;
1064 case ASI:
1065 Format(instr, "asi\t'd2('r3),'ic");
1066 break;
1067 case AGSI:
1068 Format(instr, "agsi\t'd2('r3),'ic");
1069 break;
1070 case ALFI:
1071 Format(instr, "alfi\t'r1,'i7");
1072 break;
1073 case AHIK:
1074 Format(instr, "ahik\t'r1,'r2,'i1");
1075 break;
1076 case AGHIK:
1077 Format(instr, "aghik\t'r1,'r2,'i1");
1078 break;
1079 case CLGFI:
1080 Format(instr, "clgfi\t'r1,'i7");
1081 break;
1082 case CLFI:
1083 Format(instr, "clfi\t'r1,'i7");
1084 break;
1085 case CFI:
1086 Format(instr, "cfi\t'r1,'i2");
1087 break;
1088 case CGFI:
1089 Format(instr, "cgfi\t'r1,'i2");
1090 break;
1091 case BRASL:
1092 Format(instr, "brasl\t'r1,'ie");
1093 break;
1094 case BRCL:
1095 Format(instr, "brcl\t'm1,'i5");
1096 break;
1097 case IIHF:
1098 Format(instr, "iihf\t'r1,'i7");
1099 break;
1100 case LGFI:
1101 Format(instr, "lgfi\t'r1,'i7");
1102 break;
1103 case IILF:
1104 Format(instr, "iilf\t'r1,'i7");
1105 break;
1106 case XIHF:
1107 Format(instr, "xihf\t'r1,'i7");
1108 break;
1109 case XILF:
1110 Format(instr, "xilf\t'r1,'i7");
1111 break;
1112 case SLLK:
1113 Format(instr, "sllk\t'r1,'r2,'d2('r3)");
1114 break;
1115 case SLLG:
1116 Format(instr, "sllg\t'r1,'r2,'d2('r3)");
1117 break;
1118 case RLL:
1119 Format(instr, "rll\t'r1,'r2,'d2('r3)");
1120 break;
1121 case RLLG:
1122 Format(instr, "rllg\t'r1,'r2,'d2('r3)");
1123 break;
1124 case SRLK:
1125 Format(instr, "srlk\t'r1,'r2,'d2('r3)");
1126 break;
1127 case SRLG:
1128 Format(instr, "srlg\t'r1,'r2,'d2('r3)");
1129 break;
1130 case SLAK:
1131 Format(instr, "slak\t'r1,'r2,'d2('r3)");
1132 break;
1133 case SLAG:
1134 Format(instr, "slag\t'r1,'r2,'d2('r3)");
1135 break;
1136 case SRAK:
1137 Format(instr, "srak\t'r1,'r2,'d2('r3)");
1138 break;
1139 case SRAG:
1140 Format(instr, "srag\t'r1,'r2,'d2('r3)");
1141 break;
1142 case RISBG:
1143 Format(instr, "risbg\t'r1,'r2,'i9,'ia,'ib");
1144 break;
1145 case RISBGN:
1146 Format(instr, "risbgn\t'r1,'r2,'i9,'ia,'ib");
1147 break;
1148 case LOCG:
1149 Format(instr, "locg\t'm2,'r1,'d2('r3)");
1150 break;
1151 case LOC:
1152 Format(instr, "loc\t'm2,'r1,'d2('r3)");
1153 break;
1154 case LMY:
1155 Format(instr, "lmy\t'r1,'r2,'d2('r3)");
1156 break;
1157 case LMG:
1158 Format(instr, "lmg\t'r1,'r2,'d2('r3)");
1159 break;
1160 case STMY:
1161 Format(instr, "stmy\t'r1,'r2,'d2('r3)");
1162 break;
1163 case STMG:
1164 Format(instr, "stmg\t'r1,'r2,'d2('r3)");
1165 break;
1166 case LT:
1167 Format(instr, "lt\t'r1,'d2('r2d,'r3)");
1168 break;
1169 case LTG:
1170 Format(instr, "ltg\t'r1,'d2('r2d,'r3)");
1171 break;
1172 case ML:
1173 Format(instr, "ml\t'r1,'d2('r2d,'r3)");
1174 break;
1175 case AY:
1176 Format(instr, "ay\t'r1,'d2('r2d,'r3)");
1177 break;
1178 case SY:
1179 Format(instr, "sy\t'r1,'d2('r2d,'r3)");
1180 break;
1181 case NY:
1182 Format(instr, "ny\t'r1,'d2('r2d,'r3)");
1183 break;
1184 case OY:
1185 Format(instr, "oy\t'r1,'d2('r2d,'r3)");
1186 break;
1187 case XY:
1188 Format(instr, "xy\t'r1,'d2('r2d,'r3)");
1189 break;
1190 case CY:
1191 Format(instr, "cy\t'r1,'d2('r2d,'r3)");
1192 break;
1193 case AHY:
1194 Format(instr, "ahy\t'r1,'d2('r2d,'r3)");
1195 break;
1196 case SHY:
1197 Format(instr, "shy\t'r1,'d2('r2d,'r3)");
1198 break;
1199 case LGH:
1200 Format(instr, "lgh\t'r1,'d2('r2d,'r3)");
1201 break;
1202 case AG:
1203 Format(instr, "ag\t'r1,'d2('r2d,'r3)");
1204 break;
1205 case AGF:
1206 Format(instr, "agf\t'r1,'d2('r2d,'r3)");
1207 break;
1208 case SG:
1209 Format(instr, "sg\t'r1,'d2('r2d,'r3)");
1210 break;
1211 case NG:
1212 Format(instr, "ng\t'r1,'d2('r2d,'r3)");
1213 break;
1214 case OG:
1215 Format(instr, "og\t'r1,'d2('r2d,'r3)");
1216 break;
1217 case XG:
1218 Format(instr, "xg\t'r1,'d2('r2d,'r3)");
1219 break;
1220 case CG:
1221 Format(instr, "cg\t'r1,'d2('r2d,'r3)");
1222 break;
1223 case LB:
1224 Format(instr, "lb\t'r1,'d2('r2d,'r3)");
1225 break;
1226 case LRVH:
1227 Format(instr, "lrvh\t'r1,'d2('r2d,'r3)");
1228 break;
1229 case LRV:
1230 Format(instr, "lrv\t'r1,'d2('r2d,'r3)");
1231 break;
1232 case LRVG:
1233 Format(instr, "lrvg\t'r1,'d2('r2d,'r3)");
1234 break;
1235 case LG:
1236 Format(instr, "lg\t'r1,'d2('r2d,'r3)");
1237 break;
1238 case LGF:
1239 Format(instr, "lgf\t'r1,'d2('r2d,'r3)");
1240 break;
1241 case LLGF:
1242 Format(instr, "llgf\t'r1,'d2('r2d,'r3)");
1243 break;
1244 case LY:
1245 Format(instr, "ly\t'r1,'d2('r2d,'r3)");
1246 break;
1247 case ALY:
1248 Format(instr, "aly\t'r1,'d2('r2d,'r3)");
1249 break;
1250 case ALG:
1251 Format(instr, "alg\t'r1,'d2('r2d,'r3)");
1252 break;
1253 case SLG:
1254 Format(instr, "slg\t'r1,'d2('r2d,'r3)");
1255 break;
1256 case SGF:
1257 Format(instr, "sgf\t'r1,'d2('r2d,'r3)");
1258 break;
1259 case SLY:
1260 Format(instr, "sly\t'r1,'d2('r2d,'r3)");
1261 break;
1262 case LLH:
1263 Format(instr, "llh\t'r1,'d2('r2d,'r3)");
1264 break;
1265 case LLGH:
1266 Format(instr, "llgh\t'r1,'d2('r2d,'r3)");
1267 break;
1268 case LLC:
1269 Format(instr, "llc\t'r1,'d2('r2d,'r3)");
1270 break;
1271 case LLGC:
1272 Format(instr, "llgc\t'r1,'d2('r2d,'r3)");
1273 break;
1274 case LDEB:
1275 Format(instr, "ldeb\t'f1,'d2('r2d,'r3)");
1276 break;
1277 case LAY:
1278 Format(instr, "lay\t'r1,'d2('r2d,'r3)");
1279 break;
1280 case LARL:
1281 Format(instr, "larl\t'r1,'i5");
1282 break;
1283 case LGB:
1284 Format(instr, "lgb\t'r1,'d2('r2d,'r3)");
1285 break;
1286 case CHY:
1287 Format(instr, "chy\t'r1,'d2('r2d,'r3)");
1288 break;
1289 case CLY:
1290 Format(instr, "cly\t'r1,'d2('r2d,'r3)");
1291 break;
1292 case CLIY:
1293 Format(instr, "cliy\t'd2('r3),'i8");
1294 break;
1295 case TMY:
1296 Format(instr, "tmy\t'd2('r3),'i8");
1297 break;
1298 case CLG:
1299 Format(instr, "clg\t'r1,'d2('r2d,'r3)");
1300 break;
1301 case BCTG:
1302 Format(instr, "bctg\t'r1,'d2('r2d,'r3)");
1303 break;
1304 case STY:
1305 Format(instr, "sty\t'r1,'d2('r2d,'r3)");
1306 break;
1307 case STRVH:
1308 Format(instr, "strvh\t'r1,'d2('r2d,'r3)");
1309 break;
1310 case STRV:
1311 Format(instr, "strv\t'r1,'d2('r2d,'r3)");
1312 break;
1313 case STRVG:
1314 Format(instr, "strvg\t'r1,'d2('r2d,'r3)");
1315 break;
1316 case STG:
1317 Format(instr, "stg\t'r1,'d2('r2d,'r3)");
1318 break;
1319 case ICY:
1320 Format(instr, "icy\t'r1,'d2('r2d,'r3)");
1321 break;
1322 case MVC:
1323 Format(instr, "mvc\t'd3('i8,'r3),'d4('r7)");
1324 break;
1325 case MVHI:
1326 Format(instr, "mvhi\t'd3('r3),'id");
1327 break;
1328 case MVGHI:
1329 Format(instr, "mvghi\t'd3('r3),'id");
1330 break;
1331 case ALGFI:
1332 Format(instr, "algfi\t'r1,'i7");
1333 break;
1334 case SLGFI:
1335 Format(instr, "slgfi\t'r1,'i7");
1336 break;
1337 case SLFI:
1338 Format(instr, "slfi\t'r1,'i7");
1339 break;
1340 case NIHF:
1341 Format(instr, "nihf\t'r1,'i7");
1342 break;
1343 case NILF:
1344 Format(instr, "nilf\t'r1,'i7");
1345 break;
1346 case OIHF:
1347 Format(instr, "oihf\t'r1,'i7");
1348 break;
1349 case OILF:
1350 Format(instr, "oilf\t'r1,'i7");
1351 break;
1352 case MSFI:
1353 Format(instr, "msfi\t'r1,'i7");
1354 break;
1355 case MSGFI:
1356 Format(instr, "msgfi\t'r1,'i7");
1357 break;
1358 case LDY:
1359 Format(instr, "ldy\t'f1,'d2('r2d,'r3)");
1360 break;
1361 case LEY:
1362 Format(instr, "ley\t'f1,'d2('r2d,'r3)");
1363 break;
1364 case MSG:
1365 Format(instr, "msg\t'r1,'d2('r2d,'r3)");
1366 break;
1367 case MSY:
1368 Format(instr, "msy\t'r1,'d2('r2d,'r3)");
1369 break;
1370 case STEY:
1371 Format(instr, "stey\t'f1,'d2('r2d,'r3)");
1372 break;
1373 case STDY:
1374 Format(instr, "stdy\t'f1,'d2('r2d,'r3)");
1375 break;
1376 case ADB:
1377 Format(instr, "adb\t'r1,'d1('r2d, 'r3)");
1378 break;
1379 case SDB:
1380 Format(instr, "sdb\t'r1,'d1('r2d, 'r3)");
1381 break;
1382 case MDB:
1383 Format(instr, "mdb\t'r1,'d1('r2d, 'r3)");
1384 break;
1385 case DDB:
1386 Format(instr, "ddb\t'r1,'d1('r2d, 'r3)");
1387 break;
1388 case SQDB:
1389 Format(instr, "sqdb\t'r1,'d1('r2d, 'r3)");
1390 break;
1391 default:
1392 return false;
1393 }
1394 return true;
1395 }
1396
1397 #undef VERIFIY
1398
1399 // Disassemble the instruction at *instr_ptr into the output buffer.
InstructionDecode(byte * instr_ptr)1400 int Decoder::InstructionDecode(byte* instr_ptr) {
1401 Instruction* instr = Instruction::At(instr_ptr);
1402 int instrLength = instr->InstructionLength();
1403
1404 if (2 == instrLength)
1405 DecodeTwoByte(instr);
1406 else if (4 == instrLength)
1407 DecodeFourByte(instr);
1408 else
1409 DecodeSixByte(instr);
1410
1411 return instrLength;
1412 }
1413
1414 } // namespace internal
1415 } // namespace v8
1416
1417 //------------------------------------------------------------------------------
1418
1419 namespace disasm {
1420
NameOfAddress(byte * addr) const1421 const char* NameConverter::NameOfAddress(byte* addr) const {
1422 v8::internal::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr));
1423 return tmp_buffer_.start();
1424 }
1425
NameOfConstant(byte * addr) const1426 const char* NameConverter::NameOfConstant(byte* addr) const {
1427 return NameOfAddress(addr);
1428 }
1429
NameOfCPURegister(int reg) const1430 const char* NameConverter::NameOfCPURegister(int reg) const {
1431 return v8::internal::GetRegConfig()->GetGeneralRegisterName(reg);
1432 }
1433
NameOfByteCPURegister(int reg) const1434 const char* NameConverter::NameOfByteCPURegister(int reg) const {
1435 UNREACHABLE(); // S390 does not have the concept of a byte register
1436 return "nobytereg";
1437 }
1438
NameOfXMMRegister(int reg) const1439 const char* NameConverter::NameOfXMMRegister(int reg) const {
1440 // S390 does not have XMM register
1441 // TODO(joransiu): Consider update this for Vector Regs
1442 UNREACHABLE();
1443 return "noxmmreg";
1444 }
1445
NameInCode(byte * addr) const1446 const char* NameConverter::NameInCode(byte* addr) const {
1447 // The default name converter is called for unknown code. So we will not try
1448 // to access any memory.
1449 return "";
1450 }
1451
1452 //------------------------------------------------------------------------------
1453
Disassembler(const NameConverter & converter)1454 Disassembler::Disassembler(const NameConverter& converter)
1455 : converter_(converter) {}
1456
~Disassembler()1457 Disassembler::~Disassembler() {}
1458
InstructionDecode(v8::internal::Vector<char> buffer,byte * instruction)1459 int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
1460 byte* instruction) {
1461 v8::internal::Decoder d(converter_, buffer);
1462 return d.InstructionDecode(instruction);
1463 }
1464
1465 // The S390 assembler does not currently use constant pools.
ConstantPoolSizeAt(byte * instruction)1466 int Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; }
1467
Disassemble(FILE * f,byte * begin,byte * end)1468 void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
1469 NameConverter converter;
1470 Disassembler d(converter);
1471 for (byte* pc = begin; pc < end;) {
1472 v8::internal::EmbeddedVector<char, 128> buffer;
1473 buffer[0] = '\0';
1474 byte* prev_pc = pc;
1475 pc += d.InstructionDecode(buffer, pc);
1476 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc),
1477 *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
1478 }
1479 }
1480
1481 } // namespace disasm
1482
1483 #endif // V8_TARGET_ARCH_S390
1484