v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
disasm-ppc.cc
Go to the documentation of this file.
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 (uint8_t* pc = begin; pc < end;) {
14// v8::base::EmbeddedVector<char, 256> buffer;
15// uint8_t* 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_PPC64
31
33#include "src/base/strings.h"
34#include "src/base/vector.h"
39
40namespace v8 {
41namespace internal {
42
43//------------------------------------------------------------------------------
44
45// Decoder decodes and disassembles instructions into an output buffer.
46// It uses the converter to convert register names and call destinations into
47// more informative description.
48class Decoder {
49 public:
50 Decoder(const disasm::NameConverter& converter, base::Vector<char> out_buffer)
51 : converter_(converter), out_buffer_(out_buffer), out_buffer_pos_(0) {
53 }
54
55 ~Decoder() {}
56
57 Decoder(const Decoder&) = delete;
58 Decoder& operator=(const Decoder&) = delete;
59
60 // Writes one disassembled instruction into 'buffer' (0-terminated).
61 // Returns the length of the disassembled machine instruction in bytes.
62 int InstructionDecode(uint8_t* instruction);
63
64 // Prefixed instructions.
65 enum PrefixType { not_prefixed, is_prefixed };
66 // static is used to retain values even with new instances.
67 static PrefixType PrefixStatus;
68 static uint64_t PrefixValue;
69 uint64_t GetPrefixValue();
70 void SetAsPrefixed(uint64_t v);
71 void ResetPrefix();
72 bool IsPrefixed();
73
74 private:
75 // Bottleneck functions to print into the out_buffer.
76 void PrintChar(const char ch);
77 void Print(const char* str);
78
79 // Printing of common values.
80 void PrintRegister(int reg);
81 void PrintDRegister(int reg);
82 void PrintVectorRegister(int reg);
83 int FormatFPRegister(Instruction* instr, const char* format);
84 int FormatVectorRegister(Instruction* instr, const char* format);
85 void PrintSoftwareInterrupt(SoftwareInterruptCodes svc);
86 const char* NameOfVectorRegister(int reg) const;
87
88 // Handle formatting of instructions and their options.
89 int FormatRegister(Instruction* instr, const char* option);
90 int FormatOption(Instruction* instr, const char* option);
91 void Format(Instruction* instr, const char* format);
92 void Unknown(Instruction* instr);
93 void UnknownFormat(Instruction* instr, const char* opcname);
94
95 void DecodeExtP(Instruction* instr);
96 void DecodeExt0(Instruction* instr);
97 void DecodeExt1(Instruction* instr);
98 void DecodeExt2(Instruction* instr);
99 void DecodeExt3(Instruction* instr);
100 void DecodeExt4(Instruction* instr);
101 void DecodeExt5(Instruction* instr);
102 void DecodeExt6(Instruction* instr);
103
105 base::Vector<char> out_buffer_;
106 int out_buffer_pos_;
107};
108
109// Define Prefix functions and values.
110// static
111Decoder::PrefixType Decoder::PrefixStatus = not_prefixed;
112uint64_t Decoder::PrefixValue = 0;
113
114uint64_t Decoder::GetPrefixValue() { return PrefixValue; }
115
116void Decoder::SetAsPrefixed(uint64_t v) {
117 PrefixStatus = is_prefixed;
118 PrefixValue = v;
119}
120
121void Decoder::ResetPrefix() {
122 PrefixStatus = not_prefixed;
123 PrefixValue = 0;
124}
125
126bool Decoder::IsPrefixed() { return PrefixStatus == is_prefixed; }
127
128// Support for assertions in the Decoder formatting functions.
129#define STRING_STARTS_WITH(string, compare_string) \
130 (strncmp(string, compare_string, strlen(compare_string)) == 0)
131
132// Append the ch to the output buffer.
133void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; }
134
135// Append the str to the output buffer.
136void Decoder::Print(const char* str) {
137 char cur = *str++;
138 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
139 PrintChar(cur);
140 cur = *str++;
141 }
143}
144
145// Print the register name according to the active name converter.
146void Decoder::PrintRegister(int reg) {
147 Print(converter_.NameOfCPURegister(reg));
148}
149
150// Print the double FP register name according to the active name converter.
151void Decoder::PrintDRegister(int reg) {
152 Print(RegisterName(DoubleRegister::from_code(reg)));
153}
154
155// Print the Simd128 register name according to the active name converter.
156void Decoder::PrintVectorRegister(int reg) {
157 Print(RegisterName(Simd128Register::from_code(reg)));
158}
159
160// Print SoftwareInterrupt codes. Factoring this out reduces the complexity of
161// the FormatOption method.
162void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) {
163 switch (svc) {
165 Print("call rt redirected");
166 return;
167 case kBreakpoint:
168 Print("breakpoint");
169 return;
170 default:
171 if (svc >= kStopCode) {
174 svc & kStopCodeMask, svc & kStopCodeMask);
175 } else {
178 }
179 return;
180 }
181}
182
183// Handle all register based formatting in this function to reduce the
184// complexity of FormatOption.
185int Decoder::FormatRegister(Instruction* instr, const char* format) {
186 DCHECK_EQ(format[0], 'r');
187
188 if ((format[1] == 't') || (format[1] == 's')) { // 'rt & 'rs register
189 int reg = instr->RTValue();
191 return 2;
192 } else if (format[1] == 'a') { // 'ra: RA register
193 int reg = instr->RAValue();
195 return 2;
196 } else if (format[1] == 'b') { // 'rb: RB register
197 int reg = instr->RBValue();
199 return 2;
200 }
201
202 UNREACHABLE();
203}
204
205// Handle all FP register based formatting in this function to reduce the
206// complexity of FormatOption.
207int Decoder::FormatFPRegister(Instruction* instr, const char* format) {
208 DCHECK(format[0] == 'D' || format[0] == 'X');
209
210 int retval = 2;
211 int reg = -1;
212 if (format[1] == 't' || format[1] == 's') {
213 reg = instr->RTValue();
214 } else if (format[1] == 'a') {
215 reg = instr->RAValue();
216 } else if (format[1] == 'b') {
217 reg = instr->RBValue();
218 } else if (format[1] == 'c') {
219 reg = instr->RCValue();
220 } else {
221 UNREACHABLE();
222 }
223
224 PrintDRegister(reg);
225
226 return retval;
227}
228
229int Decoder::FormatVectorRegister(Instruction* instr, const char* format) {
230 int retval = 2;
231 int reg = -1;
232 if (format[1] == 't' || format[1] == 's') {
233 reg = instr->RTValue();
234 } else if (format[1] == 'a') {
235 reg = instr->RAValue();
236 } else if (format[1] == 'b') {
237 reg = instr->RBValue();
238 } else if (format[1] == 'c') {
239 reg = instr->RCValue();
240 } else {
241 UNREACHABLE();
242 }
243
244 PrintVectorRegister(reg);
245
246 return retval;
247}
248
249// FormatOption takes a formatting string and interprets it based on
250// the current instructions. The format string points to the first
251// character of the option string (the option escape has already been
252// consumed by the caller.) FormatOption returns the number of
253// characters that were consumed from the formatting string.
254int Decoder::FormatOption(Instruction* instr, const char* format) {
255 switch (format[0]) {
256 case 'o': {
257 if (instr->Bit(10) == 1) {
258 Print("o");
259 }
260 return 1;
261 }
262 case '.': {
263 if (instr->Bit(0) == 1) {
264 Print(".");
265 } else {
266 Print(" "); // ensure consistent spacing
267 }
268 return 1;
269 }
270 case 'r': {
271 return FormatRegister(instr, format);
272 }
273 case 'D': {
274 return FormatFPRegister(instr, format);
275 }
276 case 'X': {
277 // Check the TX/SX value, if set then it's a Vector register.
278 if (instr->Bit(0) == 1) {
279 return FormatVectorRegister(instr, format);
280 }
281 // Double (VSX) register.
282 return FormatFPRegister(instr, format);
283 }
284 case 'V': {
285 return FormatVectorRegister(instr, format);
286 }
287 case 'i': { // int16
288 int64_t value;
289 uint32_t imm_value = instr->Bits(15, 0);
290 if (IsPrefixed()) {
291 uint64_t prefix_value = GetPrefixValue();
292 value = SIGN_EXT_IMM34((prefix_value << 16) | imm_value);
293 } else {
294 value = (static_cast<int64_t>(imm_value) << 48) >> 48;
295 }
298 return 5;
299 }
300 case 'I': { // IMM8
301 int8_t value = instr->Bits(18, 11);
304 return 4;
305 }
306 case 'u': { // uint16
307 int32_t value = instr->Bits(15, 0);
310 return 6;
311 }
312 case 'F': { // FXM
313 uint8_t value = instr->Bits(19, 12);
316 return 3;
317 }
318 case 'S': { // SIM
319 int32_t value = static_cast<int32_t>(SIGN_EXT_IMM5(instr->Bits(20, 16)));
322 return 3;
323 }
324 case 'U': { // UIM
325 uint8_t value = instr->Bits(19, 16);
328 return 3;
329 }
330 case 'l': {
331 // Link (LK) Bit 0
332 if (instr->Bit(0) == 1) {
333 Print("l");
334 }
335 return 1;
336 }
337 case 'a': {
338 // Absolute Address Bit 1
339 if (instr->Bit(1) == 1) {
340 Print("a");
341 }
342 return 1;
343 }
344 case 'c': { // 'cr: condition register of branch instruction
345 int code = instr->Bits(20, 18);
346 if (code != 7) {
349 }
350 return 2;
351 }
352 case 't': { // 'target: target of branch instructions
353 // target26 or target16
354 DCHECK(STRING_STARTS_WITH(format, "target"));
355 if ((format[6] == '2') && (format[7] == '6')) {
356 int off = ((instr->Bits(25, 2)) << 8) >> 6;
358 out_buffer_ + out_buffer_pos_, "%+d -> %s", off,
359 converter_.NameOfAddress(reinterpret_cast<uint8_t*>(instr) + off));
360 return 8;
361 } else if ((format[6] == '1') && (format[7] == '6')) {
362 int off = ((instr->Bits(15, 2)) << 18) >> 16;
364 out_buffer_ + out_buffer_pos_, "%+d -> %s", off,
365 converter_.NameOfAddress(reinterpret_cast<uint8_t*>(instr) + off));
366 return 8;
367 }
368 break;
369 case 's': {
370 DCHECK_EQ(format[1], 'h');
371 int32_t value = 0;
372 int32_t opcode = instr->OpcodeValue() << 26;
373 int32_t sh = instr->Bits(15, 11);
374 if (opcode == EXT5 ||
375 (opcode == EXT2 && instr->Bits(10, 2) << 2 == SRADIX)) {
376 // SH Bits 1 and 15-11 (split field)
377 value = (sh | (instr->Bit(1) << 5));
378 } else {
379 // SH Bits 15-11
380 value = (sh << 26) >> 26;
381 }
384 return 2;
385 }
386 case 'm': {
387 int32_t value = 0;
388 if (format[1] == 'e') {
389 if (instr->OpcodeValue() << 26 != EXT5) {
390 // ME Bits 10-6
391 value = (instr->Bits(10, 6) << 26) >> 26;
392 } else {
393 // ME Bits 5 and 10-6 (split field)
394 value = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
395 }
396 } else if (format[1] == 'b') {
397 if (instr->OpcodeValue() << 26 != EXT5) {
398 // MB Bits 5-1
399 value = (instr->Bits(5, 1) << 26) >> 26;
400 } else {
401 // MB Bits 5 and 10-6 (split field)
402 value = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
403 }
404 } else {
405 UNREACHABLE(); // bad format
406 }
409 return 2;
410 }
411 }
412 case 'd': { // ds value for offset
413 int32_t value = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3);
416 return 1;
417 }
418 default: {
419 UNREACHABLE();
420 }
421 }
422
423 UNREACHABLE();
424}
425
426// Format takes a formatting string for a whole instruction and prints it into
427// the output buffer. All escaped options are handed to FormatOption to be
428// parsed further.
429void Decoder::Format(Instruction* instr, const char* format) {
430 char cur = *format++;
431 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
432 if (cur == '\'') { // Single quote is used as the formatting escape.
433 format += FormatOption(instr, format);
434 } else {
436 }
437 cur = *format++;
438 }
440}
441
442// The disassembler may end up decoding data inlined in the code. We do not want
443// it to crash if the data does not resemble any known instruction.
444#define VERIFY(condition) \
445 if (!(condition)) { \
446 Unknown(instr); \
447 return; \
448 }
449
450// For currently unimplemented decodings the disassembler calls Unknown(instr)
451// which will just print "unknown" of the instruction bits.
452void Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); }
453
454// For currently unimplemented decodings the disassembler calls
455// UnknownFormat(instr) which will just print opcode name of the
456// instruction bits.
457void Decoder::UnknownFormat(Instruction* instr, const char* name) {
458 char buffer[100];
459 snprintf(buffer, sizeof(buffer), "%s (unknown-format)", name);
460 Format(instr, buffer);
461}
462
463void Decoder::DecodeExtP(Instruction* instr) {
464 switch (EXTP | (instr->BitField(25, 25))) {
465 case PLOAD_STORE_8LS:
466 case PLOAD_STORE_MLS: {
467 // TODO(miladfarca): Decode the R bit.
468 DCHECK_NE(instr->Bit(20), 1);
469 // Read prefix.
470 SetAsPrefixed(instr->Bits(17, 0));
471 // Read suffix (next instruction).
472 Instruction* next_instr = reinterpret_cast<Instruction*>(
473 reinterpret_cast<intptr_t>(instr) + kInstrSize);
474 switch (next_instr->OpcodeBase()) {
475 // Prefixed ADDI.
476 case (ADDI): {
477 if (next_instr->RAValue() == 0) {
478 // This is load immediate prefixed.
479 Format(instr, "pli");
480 Format(next_instr, " 'rt, ");
481 } else {
482 Format(instr, "paddi");
483 Format(next_instr, " 'rt, 'ra, ");
484 }
485 Format(next_instr, "'int34");
486 break;
487 }
488 // Prefixed LBZ.
489 case LBZ: {
490 Format(next_instr, "plbz 'rt, 'int34('ra)");
491 break;
492 }
493 // Prefixed LHZ.
494 case LHZ: {
495 Format(next_instr, "plhz 'rt, 'int34('ra)");
496 break;
497 }
498 // Prefixed LHA.
499 case LHA: {
500 Format(next_instr, "plha 'rt, 'int34('ra)");
501 break;
502 }
503 // Prefixed LWZ.
504 case LWZ: {
505 Format(next_instr, "plwz 'rt, 'int34('ra)");
506 break;
507 }
508 // Prefixed LWA.
509 case PPLWA: {
510 Format(next_instr, "plwa 'rt, 'int34('ra)");
511 break;
512 }
513 // Prefixed LD.
514 case PPLD: {
515 Format(next_instr, "pld 'rt, 'int34('ra)");
516 break;
517 }
518 // Prefixed LFS.
519 case LFS: {
520 Format(next_instr, "plfs 'Dt, 'int34('ra)");
521 break;
522 }
523 // Prefixed LFD.
524 case LFD: {
525 Format(next_instr, "plfd 'Dt, 'int34('ra)");
526 break;
527 }
528 // Prefixed STB.
529 case STB: {
530 Format(next_instr, "pstb 'rs, 'int34('ra)");
531 break;
532 }
533 // Prefixed STH.
534 case STH: {
535 Format(next_instr, "psth 'rs, 'int34('ra)");
536 break;
537 }
538 // Prefixed STW.
539 case STW: {
540 Format(next_instr, "pstw 'rs, 'int34('ra)");
541 break;
542 }
543 // Prefixed STD.
544 case PPSTD: {
545 Format(next_instr, "pstd 'rs, 'int34('ra)");
546 break;
547 }
548 // Prefixed STFS.
549 case STFS: {
550 Format(next_instr, "pstfs 'Dt, 'int34('ra)");
551 break;
552 }
553 // Prefixed STFD.
554 case STFD: {
555 Format(next_instr, "pstfd 'Dt, 'int34('ra)");
556 break;
557 }
558 default: {
559 Unknown(instr);
560 }
561 }
562 break;
563 }
564 default: {
565 Unknown(instr);
566 }
567 }
568}
569
570void Decoder::DecodeExt0(Instruction* instr) {
571 // Some encodings have integers hard coded in the middle, handle those first.
572 switch (EXT0 | (instr->BitField(20, 16)) | (instr->BitField(10, 0))) {
573#define DECODE_VX_D_FORM__INSTRUCTIONS(name, opcode_name, opcode_value) \
574 case opcode_name: { \
575 Format(instr, #name " 'Vt, 'Vb"); \
576 return; \
577 }
578 PPC_VX_OPCODE_D_FORM_LIST(DECODE_VX_D_FORM__INSTRUCTIONS)
579#undef DECODE_VX_D_FORM__INSTRUCTIONS
580#define DECODE_VX_F_FORM__INSTRUCTIONS(name, opcode_name, opcode_value) \
581 case opcode_name: { \
582 Format(instr, #name " 'rt, 'Vb"); \
583 return; \
584 }
585 PPC_VX_OPCODE_F_FORM_LIST(DECODE_VX_F_FORM__INSTRUCTIONS)
586#undef DECODE_VX_F_FORM__INSTRUCTIONS
587 }
588 // Some encodings are 5-0 bits, handle those first
589 switch (EXT0 | (instr->BitField(5, 0))) {
590#define DECODE_VA_A_FORM__INSTRUCTIONS(name, opcode_name, opcode_value) \
591 case opcode_name: { \
592 Format(instr, #name " 'Vt, 'Va, 'Vb, 'Vc"); \
593 return; \
594 }
595 PPC_VA_OPCODE_A_FORM_LIST(DECODE_VA_A_FORM__INSTRUCTIONS)
596#undef DECODE_VA_A_FORM__INSTRUCTIONS
597 }
598 switch (EXT0 | (instr->BitField(9, 0))) {
599// TODO(miladfarca): Fix RC indicator.
600#define DECODE_VC_FORM__INSTRUCTIONS(name, opcode_name, opcode_value) \
601 case opcode_name: { \
602 Format(instr, #name " 'Vt, 'Va, 'Vb"); \
603 return; \
604 }
605 PPC_VC_OPCODE_LIST(DECODE_VC_FORM__INSTRUCTIONS)
606#undef DECODE_VC_FORM__INSTRUCTIONS
607 }
608 switch (EXT0 | (instr->BitField(10, 0))) {
609#define DECODE_VX_A_FORM__INSTRUCTIONS(name, opcode_name, opcode_value) \
610 case opcode_name: { \
611 Format(instr, #name " 'Vt, 'Vb, 'UIM"); \
612 return; \
613 }
614 PPC_VX_OPCODE_A_FORM_LIST(DECODE_VX_A_FORM__INSTRUCTIONS)
615#undef DECODE_VX_A_FORM__INSTRUCTIONS
616#define DECODE_VX_B_FORM__INSTRUCTIONS(name, opcode_name, opcode_value) \
617 case opcode_name: { \
618 Format(instr, #name " 'Vt, 'Va, 'Vb"); \
619 return; \
620 }
621 PPC_VX_OPCODE_B_FORM_LIST(DECODE_VX_B_FORM__INSTRUCTIONS)
622#undef DECODE_VX_B_FORM__INSTRUCTIONS
623#define DECODE_VX_C_FORM__INSTRUCTIONS(name, opcode_name, opcode_value) \
624 case opcode_name: { \
625 Format(instr, #name " 'Vt, 'Vb"); \
626 return; \
627 }
628 PPC_VX_OPCODE_C_FORM_LIST(DECODE_VX_C_FORM__INSTRUCTIONS)
629#undef DECODE_VX_C_FORM__INSTRUCTIONS
630#define DECODE_VX_E_FORM__INSTRUCTIONS(name, opcode_name, opcode_value) \
631 case opcode_name: { \
632 Format(instr, #name " 'Vt, 'SIM"); \
633 return; \
634 }
635 PPC_VX_OPCODE_E_FORM_LIST(DECODE_VX_E_FORM__INSTRUCTIONS)
636#undef DECODE_VX_E_FORM__INSTRUCTIONS
637#define DECODE_VX_G_FORM__INSTRUCTIONS(name, opcode_name, opcode_value) \
638 case opcode_name: { \
639 Format(instr, #name " 'Vt, 'rb, 'UIM"); \
640 return; \
641 }
642 PPC_VX_OPCODE_G_FORM_LIST(DECODE_VX_G_FORM__INSTRUCTIONS)
643#undef DECODE_VX_G_FORM__INSTRUCTIONS
644 }
645}
646
647void Decoder::DecodeExt1(Instruction* instr) {
648 switch (EXT1 | (instr->BitField(10, 1))) {
649 case MCRF: {
650 UnknownFormat(instr, "mcrf"); // not used by V8
651 break;
652 }
653 case BCLRX: {
654 int bo = instr->BitField(25, 21);
655 int bi = instr->Bits(20, 16);
656 CRBit cond = static_cast<CRBit>(bi & (CRWIDTH - 1));
657 switch (bo) {
658 case DCBNZF: {
659 UnknownFormat(instr, "bclrx-dcbnzf");
660 break;
661 }
662 case DCBEZF: {
663 UnknownFormat(instr, "bclrx-dcbezf");
664 break;
665 }
666 case BF: {
667 switch (cond) {
668 case CR_EQ:
669 Format(instr, "bnelr'l'cr");
670 break;
671 case CR_GT:
672 Format(instr, "blelr'l'cr");
673 break;
674 case CR_LT:
675 Format(instr, "bgelr'l'cr");
676 break;
677 case CR_SO:
678 Format(instr, "bnsolr'l'cr");
679 break;
680 }
681 break;
682 }
683 case DCBNZT: {
684 UnknownFormat(instr, "bclrx-dcbbzt");
685 break;
686 }
687 case DCBEZT: {
688 UnknownFormat(instr, "bclrx-dcbnezt");
689 break;
690 }
691 case BT: {
692 switch (cond) {
693 case CR_EQ:
694 Format(instr, "beqlr'l'cr");
695 break;
696 case CR_GT:
697 Format(instr, "bgtlr'l'cr");
698 break;
699 case CR_LT:
700 Format(instr, "bltlr'l'cr");
701 break;
702 case CR_SO:
703 Format(instr, "bsolr'l'cr");
704 break;
705 }
706 break;
707 }
708 case DCBNZ: {
709 UnknownFormat(instr, "bclrx-dcbnz");
710 break;
711 }
712 case DCBEZ: {
713 UnknownFormat(instr, "bclrx-dcbez"); // not used by V8
714 break;
715 }
716 case BA: {
717 Format(instr, "blr'l");
718 break;
719 }
720 }
721 break;
722 }
723 case BCCTRX: {
724 switch (instr->BitField(25, 21)) {
725 case DCBNZF: {
726 UnknownFormat(instr, "bcctrx-dcbnzf");
727 break;
728 }
729 case DCBEZF: {
730 UnknownFormat(instr, "bcctrx-dcbezf");
731 break;
732 }
733 case BF: {
734 UnknownFormat(instr, "bcctrx-bf");
735 break;
736 }
737 case DCBNZT: {
738 UnknownFormat(instr, "bcctrx-dcbnzt");
739 break;
740 }
741 case DCBEZT: {
742 UnknownFormat(instr, "bcctrx-dcbezf");
743 break;
744 }
745 case BT: {
746 UnknownFormat(instr, "bcctrx-bt");
747 break;
748 }
749 case DCBNZ: {
750 UnknownFormat(instr, "bcctrx-dcbnz");
751 break;
752 }
753 case DCBEZ: {
754 UnknownFormat(instr, "bcctrx-dcbez");
755 break;
756 }
757 case BA: {
758 if (instr->Bit(0) == 1) {
759 Format(instr, "bctrl");
760 } else {
761 Format(instr, "bctr");
762 }
763 break;
764 }
765 default: {
766 UNREACHABLE();
767 }
768 }
769 break;
770 }
771 case CRNOR: {
772 Format(instr, "crnor (stuff)");
773 break;
774 }
775 case RFI: {
776 Format(instr, "rfi (stuff)");
777 break;
778 }
779 case CRANDC: {
780 Format(instr, "crandc (stuff)");
781 break;
782 }
783 case ISYNC: {
784 Format(instr, "isync (stuff)");
785 break;
786 }
787 case CRXOR: {
788 Format(instr, "crxor (stuff)");
789 break;
790 }
791 case CRNAND: {
792 UnknownFormat(instr, "crnand");
793 break;
794 }
795 case CRAND: {
796 UnknownFormat(instr, "crand");
797 break;
798 }
799 case CREQV: {
800 UnknownFormat(instr, "creqv");
801 break;
802 }
803 case CRORC: {
804 UnknownFormat(instr, "crorc");
805 break;
806 }
807 case CROR: {
808 UnknownFormat(instr, "cror");
809 break;
810 }
811 default: {
812 Unknown(instr); // not used by V8
813 }
814 }
815}
816
817void Decoder::DecodeExt2(Instruction* instr) {
818 // Some encodings are 10-1 bits, handle those first
819 switch (EXT2 | (instr->BitField(10, 1))) {
820 case LVX: {
821 Format(instr, "lvx 'Vt, 'ra, 'rb");
822 return;
823 }
824 case STVX: {
825 Format(instr, "stvx 'Vs, 'ra, 'rb");
826 return;
827 }
828 case LXVD: {
829 Format(instr, "lxvd 'Xt, 'ra, 'rb");
830 return;
831 }
832 case LXVX: {
833 Format(instr, "lxvx 'Xt, 'ra, 'rb");
834 return;
835 }
836 case LXSDX: {
837 Format(instr, "lxsdx 'Xt, 'ra, 'rb");
838 return;
839 }
840 case LXSIBZX: {
841 Format(instr, "lxsibzx 'Xt, 'ra, 'rb");
842 return;
843 }
844 case LXSIHZX: {
845 Format(instr, "lxsihzx 'Xt, 'ra, 'rb");
846 return;
847 }
848 case LXSIWZX: {
849 Format(instr, "lxsiwzx 'Xt, 'ra, 'rb");
850 return;
851 }
852 case STXVD: {
853 Format(instr, "stxvd 'Xs, 'ra, 'rb");
854 return;
855 }
856 case STXVX: {
857 Format(instr, "stxvx 'Xs, 'ra, 'rb");
858 return;
859 }
860 case STXSDX: {
861 Format(instr, "stxsdx 'Xs, 'ra, 'rb");
862 return;
863 }
864 case STXSIBX: {
865 Format(instr, "stxsibx 'Xs, 'ra, 'rb");
866 return;
867 }
868 case STXSIHX: {
869 Format(instr, "stxsihx 'Xs, 'ra, 'rb");
870 return;
871 }
872 case STXSIWX: {
873 Format(instr, "stxsiwx 'Xs, 'ra, 'rb");
874 return;
875 }
876 case SRWX: {
877 Format(instr, "srw'. 'ra, 'rs, 'rb");
878 return;
879 }
880 case SRDX: {
881 Format(instr, "srd'. 'ra, 'rs, 'rb");
882 return;
883 }
884 case SRAW: {
885 Format(instr, "sraw'. 'ra, 'rs, 'rb");
886 return;
887 }
888 case SRAD: {
889 Format(instr, "srad'. 'ra, 'rs, 'rb");
890 return;
891 }
892 case SYNC: {
893 Format(instr, "sync");
894 return;
895 }
896 case MODSW: {
897 Format(instr, "modsw 'rt, 'ra, 'rb");
898 return;
899 }
900 case MODUW: {
901 Format(instr, "moduw 'rt, 'ra, 'rb");
902 return;
903 }
904 case MODSD: {
905 Format(instr, "modsd 'rt, 'ra, 'rb");
906 return;
907 }
908 case MODUD: {
909 Format(instr, "modud 'rt, 'ra, 'rb");
910 return;
911 }
912 case SRAWIX: {
913 Format(instr, "srawi'. 'ra,'rs,'sh");
914 return;
915 }
916 case EXTSH: {
917 Format(instr, "extsh'. 'ra, 'rs");
918 return;
919 }
920 case EXTSW: {
921 Format(instr, "extsw'. 'ra, 'rs");
922 return;
923 }
924 case EXTSB: {
925 Format(instr, "extsb'. 'ra, 'rs");
926 return;
927 }
928 case LFSX: {
929 Format(instr, "lfsx 'Dt, 'ra, 'rb");
930 return;
931 }
932 case LFSUX: {
933 Format(instr, "lfsux 'Dt, 'ra, 'rb");
934 return;
935 }
936 case LFDX: {
937 Format(instr, "lfdx 'Dt, 'ra, 'rb");
938 return;
939 }
940 case LFDUX: {
941 Format(instr, "lfdux 'Dt, 'ra, 'rb");
942 return;
943 }
944 case STFSX: {
945 Format(instr, "stfsx 'rs, 'ra, 'rb");
946 return;
947 }
948 case STFSUX: {
949 Format(instr, "stfsux 'rs, 'ra, 'rb");
950 return;
951 }
952 case STFDX: {
953 Format(instr, "stfdx 'rs, 'ra, 'rb");
954 return;
955 }
956 case STFDUX: {
957 Format(instr, "stfdux 'rs, 'ra, 'rb");
958 return;
959 }
960 case POPCNTW: {
961 Format(instr, "popcntw 'ra, 'rs");
962 return;
963 }
964 case POPCNTD: {
965 Format(instr, "popcntd 'ra, 'rs");
966 return;
967 }
968 }
969
970 switch (EXT2 | (instr->BitField(10, 2))) {
971 case SRADIX: {
972 Format(instr, "sradi'. 'ra,'rs,'sh");
973 return;
974 }
975 }
976
977 switch (EXT2 | (instr->BitField(10, 0))) {
978 case STBCX: {
979 Format(instr, "stbcx 'rs, 'ra, 'rb");
980 return;
981 }
982 case STHCX: {
983 Format(instr, "sthcx 'rs, 'ra, 'rb");
984 return;
985 }
986 case STWCX: {
987 Format(instr, "stwcx 'rs, 'ra, 'rb");
988 return;
989 }
990 case STDCX: {
991 Format(instr, "stdcx 'rs, 'ra, 'rb");
992 return;
993 }
994 }
995
996 // ?? are all of these xo_form?
997 switch (EXT2 | (instr->BitField(10, 1))) {
998 case CMP: {
999 if (instr->Bit(21)) {
1000 Format(instr, "cmp 'ra, 'rb");
1001 } else {
1002 Format(instr, "cmpw 'ra, 'rb");
1003 }
1004 return;
1005 }
1006 case SLWX: {
1007 Format(instr, "slw'. 'ra, 'rs, 'rb");
1008 return;
1009 }
1010 case SLDX: {
1011 Format(instr, "sld'. 'ra, 'rs, 'rb");
1012 return;
1013 }
1014 case SUBFCX: {
1015 Format(instr, "subfc'. 'rt, 'ra, 'rb");
1016 return;
1017 }
1018 case SUBFEX: {
1019 Format(instr, "subfe'. 'rt, 'ra, 'rb");
1020 return;
1021 }
1022 case ADDCX: {
1023 Format(instr, "addc'. 'rt, 'ra, 'rb");
1024 return;
1025 }
1026 case ADDEX: {
1027 Format(instr, "adde'. 'rt, 'ra, 'rb");
1028 return;
1029 }
1030 case CNTLZWX: {
1031 Format(instr, "cntlzw'. 'ra, 'rs");
1032 return;
1033 }
1034 case CNTLZDX: {
1035 Format(instr, "cntlzd'. 'ra, 'rs");
1036 return;
1037 }
1038 case CNTTZWX: {
1039 Format(instr, "cnttzw'. 'ra, 'rs");
1040 return;
1041 }
1042 case CNTTZDX: {
1043 Format(instr, "cnttzd'. 'ra, 'rs");
1044 return;
1045 }
1046 case BRH: {
1047 Format(instr, "brh 'ra, 'rs");
1048 return;
1049 }
1050 case BRW: {
1051 Format(instr, "brw 'ra, 'rs");
1052 return;
1053 }
1054 case BRD: {
1055 Format(instr, "brd 'ra, 'rs");
1056 return;
1057 }
1058 case ANDX: {
1059 Format(instr, "and'. 'ra, 'rs, 'rb");
1060 return;
1061 }
1062 case ANDCX: {
1063 Format(instr, "andc'. 'ra, 'rs, 'rb");
1064 return;
1065 }
1066 case CMPL: {
1067 if (instr->Bit(21)) {
1068 Format(instr, "cmpl 'ra, 'rb");
1069 } else {
1070 Format(instr, "cmplw 'ra, 'rb");
1071 }
1072 return;
1073 }
1074 case NEGX: {
1075 Format(instr, "neg'. 'rt, 'ra");
1076 return;
1077 }
1078 case NORX: {
1079 Format(instr, "nor'. 'rt, 'ra, 'rb");
1080 return;
1081 }
1082 case SUBFX: {
1083 Format(instr, "subf'. 'rt, 'ra, 'rb");
1084 return;
1085 }
1086 case MULHWX: {
1087 Format(instr, "mulhw'o'. 'rt, 'ra, 'rb");
1088 return;
1089 }
1090 case ADDZEX: {
1091 Format(instr, "addze'. 'rt, 'ra");
1092 return;
1093 }
1094 case MULLW: {
1095 Format(instr, "mullw'o'. 'rt, 'ra, 'rb");
1096 return;
1097 }
1098 case MULLD: {
1099 Format(instr, "mulld'o'. 'rt, 'ra, 'rb");
1100 return;
1101 }
1102 case DIVW: {
1103 Format(instr, "divw'o'. 'rt, 'ra, 'rb");
1104 return;
1105 }
1106 case DIVWU: {
1107 Format(instr, "divwu'o'. 'rt, 'ra, 'rb");
1108 return;
1109 }
1110 case DIVD: {
1111 Format(instr, "divd'o'. 'rt, 'ra, 'rb");
1112 return;
1113 }
1114 case ADDX: {
1115 Format(instr, "add'o 'rt, 'ra, 'rb");
1116 return;
1117 }
1118 case XORX: {
1119 Format(instr, "xor'. 'ra, 'rs, 'rb");
1120 return;
1121 }
1122 case ORX: {
1123 if (instr->RTValue() == instr->RBValue()) {
1124 Format(instr, "mr 'ra, 'rb");
1125 } else {
1126 Format(instr, "or 'ra, 'rs, 'rb");
1127 }
1128 return;
1129 }
1130 case MFSPR: {
1131 int spr = instr->Bits(20, 11);
1132 if (256 == spr) {
1133 Format(instr, "mflr 'rt");
1134 } else {
1135 Format(instr, "mfspr 'rt ??");
1136 }
1137 return;
1138 }
1139 case MTSPR: {
1140 int spr = instr->Bits(20, 11);
1141 if (256 == spr) {
1142 Format(instr, "mtlr 'rt");
1143 } else if (288 == spr) {
1144 Format(instr, "mtctr 'rt");
1145 } else {
1146 Format(instr, "mtspr 'rt ??");
1147 }
1148 return;
1149 }
1150 case MFCR: {
1151 Format(instr, "mfcr 'rt");
1152 return;
1153 }
1154 case STWX: {
1155 Format(instr, "stwx 'rs, 'ra, 'rb");
1156 return;
1157 }
1158 case STWUX: {
1159 Format(instr, "stwux 'rs, 'ra, 'rb");
1160 return;
1161 }
1162 case STBX: {
1163 Format(instr, "stbx 'rs, 'ra, 'rb");
1164 return;
1165 }
1166 case STBUX: {
1167 Format(instr, "stbux 'rs, 'ra, 'rb");
1168 return;
1169 }
1170 case STHX: {
1171 Format(instr, "sthx 'rs, 'ra, 'rb");
1172 return;
1173 }
1174 case STHUX: {
1175 Format(instr, "sthux 'rs, 'ra, 'rb");
1176 return;
1177 }
1178 case LWZX: {
1179 Format(instr, "lwzx 'rt, 'ra, 'rb");
1180 return;
1181 }
1182 case LWZUX: {
1183 Format(instr, "lwzux 'rt, 'ra, 'rb");
1184 return;
1185 }
1186 case LWAX: {
1187 Format(instr, "lwax 'rt, 'ra, 'rb");
1188 return;
1189 }
1190 case LBZX: {
1191 Format(instr, "lbzx 'rt, 'ra, 'rb");
1192 return;
1193 }
1194 case LBZUX: {
1195 Format(instr, "lbzux 'rt, 'ra, 'rb");
1196 return;
1197 }
1198 case LHZX: {
1199 Format(instr, "lhzx 'rt, 'ra, 'rb");
1200 return;
1201 }
1202 case LHZUX: {
1203 Format(instr, "lhzux 'rt, 'ra, 'rb");
1204 return;
1205 }
1206 case LHAX: {
1207 Format(instr, "lhax 'rt, 'ra, 'rb");
1208 return;
1209 }
1210 case LBARX: {
1211 Format(instr, "lbarx 'rt, 'ra, 'rb");
1212 return;
1213 }
1214 case LHARX: {
1215 Format(instr, "lharx 'rt, 'ra, 'rb");
1216 return;
1217 }
1218 case LWARX: {
1219 Format(instr, "lwarx 'rt, 'ra, 'rb");
1220 return;
1221 }
1222 case LDX: {
1223 Format(instr, "ldx 'rt, 'ra, 'rb");
1224 return;
1225 }
1226 case LDUX: {
1227 Format(instr, "ldux 'rt, 'ra, 'rb");
1228 return;
1229 }
1230 case LDARX: {
1231 Format(instr, "ldarx 'rt, 'ra, 'rb");
1232 return;
1233 }
1234 case STDX: {
1235 Format(instr, "stdx 'rt, 'ra, 'rb");
1236 return;
1237 }
1238 case STDUX: {
1239 Format(instr, "stdux 'rt, 'ra, 'rb");
1240 return;
1241 }
1242 case MFVSRD: {
1243 Format(instr, "mfvsrd 'ra, 'Xs");
1244 return;
1245 }
1246 case MFVSRWZ: {
1247 Format(instr, "mffprwz 'ra, 'Dt");
1248 return;
1249 }
1250 case MTVSRD: {
1251 Format(instr, "mtvsrd 'Xt, 'ra");
1252 return;
1253 }
1254 case MTVSRWA: {
1255 Format(instr, "mtfprwa 'Dt, 'ra");
1256 return;
1257 }
1258 case MTVSRWZ: {
1259 Format(instr, "mtfprwz 'Dt, 'ra");
1260 return;
1261 }
1262 case MTVSRDD: {
1263 Format(instr, "mtvsrdd 'Xt, 'ra, 'rb");
1264 return;
1265 }
1266 case LDBRX: {
1267 Format(instr, "ldbrx 'rt, 'ra, 'rb");
1268 return;
1269 }
1270 case LHBRX: {
1271 Format(instr, "lhbrx 'rt, 'ra, 'rb");
1272 return;
1273 }
1274 case LWBRX: {
1275 Format(instr, "lwbrx 'rt, 'ra, 'rb");
1276 return;
1277 }
1278 case STDBRX: {
1279 Format(instr, "stdbrx 'rs, 'ra, 'rb");
1280 return;
1281 }
1282 case STWBRX: {
1283 Format(instr, "stwbrx 'rs, 'ra, 'rb");
1284 return;
1285 }
1286 case STHBRX: {
1287 Format(instr, "sthbrx 'rs, 'ra, 'rb");
1288 return;
1289 }
1290 case MTCRF: {
1291 Format(instr, "mtcrf 'FXM, 'rs");
1292 return;
1293 }
1294 }
1295
1296 switch (EXT2 | (instr->BitField(5, 1))) {
1297 case ISEL: {
1298 Format(instr, "isel 'rt, 'ra, 'rb");
1299 return;
1300 }
1301 default: {
1302 Unknown(instr); // not used by V8
1303 }
1304 }
1305}
1306
1307void Decoder::DecodeExt3(Instruction* instr) {
1308 switch (EXT3 | (instr->BitField(10, 1))) {
1309 case FCFID: {
1310 Format(instr, "fcfid'. 'Dt, 'Db");
1311 break;
1312 }
1313 case FCFIDS: {
1314 Format(instr, "fcfids'. 'Dt, 'Db");
1315 break;
1316 }
1317 case FCFIDU: {
1318 Format(instr, "fcfidu'. 'Dt, 'Db");
1319 break;
1320 }
1321 case FCFIDUS: {
1322 Format(instr, "fcfidus'.'Dt, 'Db");
1323 break;
1324 }
1325 default: {
1326 Unknown(instr); // not used by V8
1327 }
1328 }
1329}
1330
1331void Decoder::DecodeExt4(Instruction* instr) {
1332 switch (EXT4 | (instr->BitField(5, 1))) {
1333 case FDIV: {
1334 Format(instr, "fdiv'. 'Dt, 'Da, 'Db");
1335 return;
1336 }
1337 case FSUB: {
1338 Format(instr, "fsub'. 'Dt, 'Da, 'Db");
1339 return;
1340 }
1341 case FADD: {
1342 Format(instr, "fadd'. 'Dt, 'Da, 'Db");
1343 return;
1344 }
1345 case FSQRT: {
1346 Format(instr, "fsqrt'. 'Dt, 'Db");
1347 return;
1348 }
1349 case FSEL: {
1350 Format(instr, "fsel'. 'Dt, 'Da, 'Dc, 'Db");
1351 return;
1352 }
1353 case FMUL: {
1354 Format(instr, "fmul'. 'Dt, 'Da, 'Dc");
1355 return;
1356 }
1357 case FMSUB: {
1358 Format(instr, "fmsub'. 'Dt, 'Da, 'Dc, 'Db");
1359 return;
1360 }
1361 case FMADD: {
1362 Format(instr, "fmadd'. 'Dt, 'Da, 'Dc, 'Db");
1363 return;
1364 }
1365 }
1366
1367 switch (EXT4 | (instr->BitField(10, 1))) {
1368 case FCMPU: {
1369 Format(instr, "fcmpu 'Da, 'Db");
1370 break;
1371 }
1372 case FRSP: {
1373 Format(instr, "frsp'. 'Dt, 'Db");
1374 break;
1375 }
1376 case FCFID: {
1377 Format(instr, "fcfid'. 'Dt, 'Db");
1378 break;
1379 }
1380 case FCFIDU: {
1381 Format(instr, "fcfidu'. 'Dt, 'Db");
1382 break;
1383 }
1384 case FCTID: {
1385 Format(instr, "fctid 'Dt, 'Db");
1386 break;
1387 }
1388 case FCTIDZ: {
1389 Format(instr, "fctidz 'Dt, 'Db");
1390 break;
1391 }
1392 case FCTIDU: {
1393 Format(instr, "fctidu 'Dt, 'Db");
1394 break;
1395 }
1396 case FCTIDUZ: {
1397 Format(instr, "fctiduz 'Dt, 'Db");
1398 break;
1399 }
1400 case FCTIW: {
1401 Format(instr, "fctiw'. 'Dt, 'Db");
1402 break;
1403 }
1404 case FCTIWZ: {
1405 Format(instr, "fctiwz'. 'Dt, 'Db");
1406 break;
1407 }
1408 case FCTIWUZ: {
1409 Format(instr, "fctiwuz 'Dt, 'Db");
1410 break;
1411 }
1412 case FMR: {
1413 Format(instr, "fmr'. 'Dt, 'Db");
1414 break;
1415 }
1416 case MTFSFI: {
1417 Format(instr, "mtfsfi'. ?,?");
1418 break;
1419 }
1420 case MFFS: {
1421 Format(instr, "mffs'. 'Dt");
1422 break;
1423 }
1424 case MTFSF: {
1425 Format(instr, "mtfsf'. 'Db ?,?,?");
1426 break;
1427 }
1428 case FABS: {
1429 Format(instr, "fabs'. 'Dt, 'Db");
1430 break;
1431 }
1432 case FRIN: {
1433 Format(instr, "frin. 'Dt, 'Db");
1434 break;
1435 }
1436 case FRIZ: {
1437 Format(instr, "friz. 'Dt, 'Db");
1438 break;
1439 }
1440 case FRIP: {
1441 Format(instr, "frip. 'Dt, 'Db");
1442 break;
1443 }
1444 case FRIM: {
1445 Format(instr, "frim. 'Dt, 'Db");
1446 break;
1447 }
1448 case FNEG: {
1449 Format(instr, "fneg'. 'Dt, 'Db");
1450 break;
1451 }
1452 case FCPSGN: {
1453 Format(instr, "fcpsgn'. 'Dt, 'Da, 'Db");
1454 break;
1455 }
1456 case MCRFS: {
1457 Format(instr, "mcrfs ?,?");
1458 break;
1459 }
1460 case MTFSB0: {
1461 Format(instr, "mtfsb0'. ?");
1462 break;
1463 }
1464 case MTFSB1: {
1465 Format(instr, "mtfsb1'. ?");
1466 break;
1467 }
1468 default: {
1469 Unknown(instr); // not used by V8
1470 }
1471 }
1472}
1473
1474void Decoder::DecodeExt5(Instruction* instr) {
1475 switch (EXT5 | (instr->BitField(4, 2))) {
1476 case RLDICL: {
1477 Format(instr, "rldicl'. 'ra, 'rs, 'sh, 'mb");
1478 return;
1479 }
1480 case RLDICR: {
1481 Format(instr, "rldicr'. 'ra, 'rs, 'sh, 'me");
1482 return;
1483 }
1484 case RLDIC: {
1485 Format(instr, "rldic'. 'ra, 'rs, 'sh, 'mb");
1486 return;
1487 }
1488 case RLDIMI: {
1489 Format(instr, "rldimi'. 'ra, 'rs, 'sh, 'mb");
1490 return;
1491 }
1492 }
1493 switch (EXT5 | (instr->BitField(4, 1))) {
1494 case RLDCL: {
1495 Format(instr, "rldcl'. 'ra, 'rs, 'sb, 'mb");
1496 return;
1497 }
1498 }
1499 Unknown(instr); // not used by V8
1500}
1501
1502void Decoder::DecodeExt6(Instruction* instr) {
1503 switch (EXT6 | (instr->BitField(10, 1))) {
1504 case XXSPLTIB: {
1505 Format(instr, "xxspltib 'Xt, 'IMM8");
1506 return;
1507 }
1508 }
1509 switch (EXT6 | (instr->BitField(10, 3))) {
1510#define DECODE_XX3_VECTOR_B_FORM_INSTRUCTIONS(name, opcode_name, opcode_value) \
1511 case opcode_name: { \
1512 Format(instr, #name " 'Xt, 'Xa, 'Xb"); \
1513 return; \
1514 }
1515 PPC_XX3_OPCODE_VECTOR_B_FORM_LIST(DECODE_XX3_VECTOR_B_FORM_INSTRUCTIONS)
1516#undef DECODE_XX3_VECTOR_B_FORM_INSTRUCTIONS
1517#define DECODE_XX3_SCALAR_INSTRUCTIONS(name, opcode_name, opcode_value) \
1518 case opcode_name: { \
1519 Format(instr, #name " 'Dt, 'Da, 'Db"); \
1520 return; \
1521 }
1522 PPC_XX3_OPCODE_SCALAR_LIST(DECODE_XX3_SCALAR_INSTRUCTIONS)
1523#undef DECODE_XX3_SCALAR_INSTRUCTIONS
1524 }
1525 // Some encodings have integers hard coded in the middle, handle those first.
1526 switch (EXT6 | (instr->BitField(20, 16)) | (instr->BitField(10, 2))) {
1527#define DECODE_XX2_B_INSTRUCTIONS(name, opcode_name, opcode_value) \
1528 case opcode_name: { \
1529 Format(instr, #name " 'Xt, 'Xb"); \
1530 return; \
1531 }
1532 PPC_XX2_OPCODE_B_FORM_LIST(DECODE_XX2_B_INSTRUCTIONS)
1533#undef DECODE_XX2_B_INSTRUCTIONS
1534 }
1535 switch (EXT6 | (instr->BitField(10, 2))) {
1536#define DECODE_XX2_VECTOR_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
1537 case opcode_name: { \
1538 Format(instr, #name " 'Xt, 'Xb"); \
1539 return; \
1540 }
1541 PPC_XX2_OPCODE_VECTOR_A_FORM_LIST(DECODE_XX2_VECTOR_A_INSTRUCTIONS)
1542#undef DECODE_XX2_VECTOR_A_INSTRUCTIONS
1543#define DECODE_XX2_SCALAR_A_INSTRUCTIONS(name, opcode_name, opcode_value) \
1544 case opcode_name: { \
1545 Format(instr, #name " 'Dt, 'Db"); \
1546 return; \
1547 }
1548 PPC_XX2_OPCODE_SCALAR_A_FORM_LIST(DECODE_XX2_SCALAR_A_INSTRUCTIONS)
1549#undef DECODE_XX2_SCALAR_A_INSTRUCTIONS
1550 }
1551 Unknown(instr); // not used by V8
1552}
1553
1554#undef VERIFY
1555
1556// Disassemble the instruction at *instr_ptr into the output buffer.
1557int Decoder::InstructionDecode(uint8_t* instr_ptr) {
1558 Instruction* instr = Instruction::At(instr_ptr);
1559
1560 uint32_t opcode = instr->OpcodeValue() << 26;
1561 // Print raw instruction bytes.
1562 if (opcode != EXTP) {
1564 "%08x ", instr->InstructionBits());
1565 } else {
1566 // Prefixed instructions have a 4-byte prefix and a 4-byte suffix. Print
1567 // both on the same line.
1568 Instruction* next_instr = reinterpret_cast<Instruction*>(
1569 reinterpret_cast<intptr_t>(instr) + kInstrSize);
1572 instr->InstructionBits(), next_instr->InstructionBits());
1573 }
1574
1575 if (ABI_USES_FUNCTION_DESCRIPTORS && instr->InstructionBits() == 0) {
1576 // The first field will be identified as a jump table entry. We
1577 // emit the rest of the structure as zero, so just skip past them.
1578 Format(instr, "constant");
1579 return kInstrSize;
1580 }
1581
1582 switch (opcode) {
1583 case TWI: {
1584 PrintSoftwareInterrupt(instr->SvcValue());
1585 break;
1586 }
1587 case MULLI: {
1588 UnknownFormat(instr, "mulli");
1589 break;
1590 }
1591 case SUBFIC: {
1592 Format(instr, "subfic 'rt, 'ra, 'int16");
1593 break;
1594 }
1595 case CMPLI: {
1596 if (instr->Bit(21)) {
1597 Format(instr, "cmpli 'ra, 'uint16");
1598 } else {
1599 Format(instr, "cmplwi 'ra, 'uint16");
1600 }
1601 break;
1602 }
1603 case CMPI: {
1604 if (instr->Bit(21)) {
1605 Format(instr, "cmpi 'ra, 'int16");
1606 } else {
1607 Format(instr, "cmpwi 'ra, 'int16");
1608 }
1609 break;
1610 }
1611 case ADDIC: {
1612 Format(instr, "addic 'rt, 'ra, 'int16");
1613 break;
1614 }
1615 case ADDICx: {
1616 UnknownFormat(instr, "addicx");
1617 break;
1618 }
1619 case ADDI: {
1620 if (instr->RAValue() == 0) {
1621 // this is load immediate
1622 Format(instr, "li 'rt, 'int16");
1623 } else {
1624 Format(instr, "addi 'rt, 'ra, 'int16");
1625 }
1626 break;
1627 }
1628 case ADDIS: {
1629 if (instr->RAValue() == 0) {
1630 Format(instr, "lis 'rt, 'int16");
1631 } else {
1632 Format(instr, "addis 'rt, 'ra, 'int16");
1633 }
1634 break;
1635 }
1636 case BCX: {
1637 int bo = instr->Bits(25, 21) << 21;
1638 int bi = instr->Bits(20, 16);
1639 CRBit cond = static_cast<CRBit>(bi & (CRWIDTH - 1));
1640 switch (bo) {
1641 case BT: { // Branch if condition true
1642 switch (cond) {
1643 case CR_EQ:
1644 Format(instr, "beq'l'a'cr 'target16");
1645 break;
1646 case CR_GT:
1647 Format(instr, "bgt'l'a'cr 'target16");
1648 break;
1649 case CR_LT:
1650 Format(instr, "blt'l'a'cr 'target16");
1651 break;
1652 case CR_SO:
1653 Format(instr, "bso'l'a'cr 'target16");
1654 break;
1655 }
1656 break;
1657 }
1658 case BF: { // Branch if condition false
1659 switch (cond) {
1660 case CR_EQ:
1661 Format(instr, "bne'l'a'cr 'target16");
1662 break;
1663 case CR_GT:
1664 Format(instr, "ble'l'a'cr 'target16");
1665 break;
1666 case CR_LT:
1667 Format(instr, "bge'l'a'cr 'target16");
1668 break;
1669 case CR_SO:
1670 Format(instr, "bnso'l'a'cr 'target16");
1671 break;
1672 }
1673 break;
1674 }
1675 case DCBNZ: { // Decrement CTR; branch if CTR != 0
1676 Format(instr, "bdnz'l'a 'target16");
1677 break;
1678 }
1679 default:
1680 Format(instr, "bc'l'a'cr 'target16");
1681 break;
1682 }
1683 break;
1684 }
1685 case SC: {
1686 UnknownFormat(instr, "sc");
1687 break;
1688 }
1689 case BX: {
1690 Format(instr, "b'l'a 'target26");
1691 break;
1692 }
1693 case EXTP: {
1694 DecodeExtP(instr);
1695 break;
1696 }
1697 case EXT0: {
1698 DecodeExt0(instr);
1699 break;
1700 }
1701 case EXT1: {
1702 DecodeExt1(instr);
1703 break;
1704 }
1705 case RLWIMIX: {
1706 Format(instr, "rlwimi'. 'ra, 'rs, 'sh, 'me, 'mb");
1707 break;
1708 }
1709 case RLWINMX: {
1710 Format(instr, "rlwinm'. 'ra, 'rs, 'sh, 'me, 'mb");
1711 break;
1712 }
1713 case RLWNMX: {
1714 Format(instr, "rlwnm'. 'ra, 'rs, 'rb, 'me, 'mb");
1715 break;
1716 }
1717 case ORI: {
1718 Format(instr, "ori 'ra, 'rs, 'uint16");
1719 break;
1720 }
1721 case ORIS: {
1722 Format(instr, "oris 'ra, 'rs, 'uint16");
1723 break;
1724 }
1725 case XORI: {
1726 Format(instr, "xori 'ra, 'rs, 'uint16");
1727 break;
1728 }
1729 case XORIS: {
1730 Format(instr, "xoris 'ra, 'rs, 'uint16");
1731 break;
1732 }
1733 case ANDIx: {
1734 Format(instr, "andi. 'ra, 'rs, 'uint16");
1735 break;
1736 }
1737 case ANDISx: {
1738 Format(instr, "andis. 'ra, 'rs, 'uint16");
1739 break;
1740 }
1741 case EXT2: {
1742 DecodeExt2(instr);
1743 break;
1744 }
1745 case LWZ: {
1746 Format(instr, "lwz 'rt, 'int16('ra)");
1747 break;
1748 }
1749 case LWZU: {
1750 Format(instr, "lwzu 'rt, 'int16('ra)");
1751 break;
1752 }
1753 case LBZ: {
1754 Format(instr, "lbz 'rt, 'int16('ra)");
1755 break;
1756 }
1757 case LBZU: {
1758 Format(instr, "lbzu 'rt, 'int16('ra)");
1759 break;
1760 }
1761 case STW: {
1762 Format(instr, "stw 'rs, 'int16('ra)");
1763 break;
1764 }
1765 case STWU: {
1766 Format(instr, "stwu 'rs, 'int16('ra)");
1767 break;
1768 }
1769 case STB: {
1770 Format(instr, "stb 'rs, 'int16('ra)");
1771 break;
1772 }
1773 case STBU: {
1774 Format(instr, "stbu 'rs, 'int16('ra)");
1775 break;
1776 }
1777 case LHZ: {
1778 Format(instr, "lhz 'rt, 'int16('ra)");
1779 break;
1780 }
1781 case LHZU: {
1782 Format(instr, "lhzu 'rt, 'int16('ra)");
1783 break;
1784 }
1785 case LHA: {
1786 Format(instr, "lha 'rt, 'int16('ra)");
1787 break;
1788 }
1789 case LHAU: {
1790 Format(instr, "lhau 'rt, 'int16('ra)");
1791 break;
1792 }
1793 case STH: {
1794 Format(instr, "sth 'rs, 'int16('ra)");
1795 break;
1796 }
1797 case STHU: {
1798 Format(instr, "sthu 'rs, 'int16('ra)");
1799 break;
1800 }
1801 case LMW: {
1802 UnknownFormat(instr, "lmw");
1803 break;
1804 }
1805 case STMW: {
1806 UnknownFormat(instr, "stmw");
1807 break;
1808 }
1809 case LFS: {
1810 Format(instr, "lfs 'Dt, 'int16('ra)");
1811 break;
1812 }
1813 case LFSU: {
1814 Format(instr, "lfsu 'Dt, 'int16('ra)");
1815 break;
1816 }
1817 case LFD: {
1818 Format(instr, "lfd 'Dt, 'int16('ra)");
1819 break;
1820 }
1821 case LFDU: {
1822 Format(instr, "lfdu 'Dt, 'int16('ra)");
1823 break;
1824 }
1825 case STFS: {
1826 Format(instr, "stfs 'Dt, 'int16('ra)");
1827 break;
1828 }
1829 case STFSU: {
1830 Format(instr, "stfsu 'Dt, 'int16('ra)");
1831 break;
1832 }
1833 case STFD: {
1834 Format(instr, "stfd 'Dt, 'int16('ra)");
1835 break;
1836 }
1837 case STFDU: {
1838 Format(instr, "stfdu 'Dt, 'int16('ra)");
1839 break;
1840 }
1841 case EXT3: {
1842 DecodeExt3(instr);
1843 break;
1844 }
1845 case EXT4: {
1846 DecodeExt4(instr);
1847 break;
1848 }
1849 case EXT5: {
1850 DecodeExt5(instr);
1851 break;
1852 }
1853 case EXT6: {
1854 DecodeExt6(instr);
1855 break;
1856 }
1857 case LD: {
1858 switch (instr->Bits(1, 0)) {
1859 case 0:
1860 Format(instr, "ld 'rt, 'd('ra)");
1861 break;
1862 case 1:
1863 Format(instr, "ldu 'rt, 'd('ra)");
1864 break;
1865 case 2:
1866 Format(instr, "lwa 'rt, 'd('ra)");
1867 break;
1868 }
1869 break;
1870 }
1871 case STD: { // could be STD or STDU
1872 if (instr->Bit(0) == 0) {
1873 Format(instr, "std 'rs, 'd('ra)");
1874 } else {
1875 Format(instr, "stdu 'rs, 'd('ra)");
1876 }
1877 break;
1878 }
1879 default: {
1880 Unknown(instr);
1881 break;
1882 }
1883 }
1884
1885 if (IsPrefixed()) {
1886 // The next instruction (suffix) should have already been decoded as part of
1887 // prefix decoding.
1888 ResetPrefix();
1889 return 2 * kInstrSize;
1890 }
1891
1892 return kInstrSize;
1893}
1894} // namespace internal
1895} // namespace v8
1896
1897//------------------------------------------------------------------------------
1898
1899namespace disasm {
1900
1901const char* NameConverter::NameOfAddress(uint8_t* addr) const {
1902 v8::base::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr));
1903 return tmp_buffer_.begin();
1904}
1905
1906const char* NameConverter::NameOfConstant(uint8_t* addr) const {
1907 return NameOfAddress(addr);
1908}
1909
1910const char* NameConverter::NameOfCPURegister(int reg) const {
1911 return RegisterName(i::Register::from_code(reg));
1912}
1913
1914const char* NameConverter::NameOfByteCPURegister(int reg) const {
1915 UNREACHABLE(); // PPC does not have the concept of a byte register
1916}
1917
1918const char* NameConverter::NameOfXMMRegister(int reg) const {
1919 UNREACHABLE(); // PPC does not have any XMM registers
1920}
1921
1922const char* NameConverter::NameInCode(uint8_t* addr) const {
1923 // The default name converter is called for unknown code. So we will not try
1924 // to access any memory.
1925 return "";
1926}
1927
1928//------------------------------------------------------------------------------
1929
1931 uint8_t* instruction) {
1933 return d.InstructionDecode(instruction);
1934}
1935
1936// The PPC assembler does not currently use constant pools.
1937int Disassembler::ConstantPoolSizeAt(uint8_t* instruction) { return -1; }
1938
1939void Disassembler::Disassemble(FILE* f, uint8_t* begin, uint8_t* end,
1940 UnimplementedOpcodeAction unimplemented_action) {
1941 NameConverter converter;
1942 Disassembler d(converter, unimplemented_action);
1943 for (uint8_t* pc = begin; pc < end;) {
1945 buffer[0] = '\0';
1946 uint8_t* prev_pc = pc;
1947 pc += d.InstructionDecode(buffer, pc);
1948 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc),
1949 *reinterpret_cast<int32_t*>(prev_pc), buffer.begin());
1950 }
1951}
1952
1953#undef STRING_STARTS_WITH
1954
1955} // namespace disasm
1956
1957#endif // V8_TARGET_ARCH_PPC64
static V8_EXPORT_PRIVATE void Disassemble(FILE *f, uint8_t *begin, uint8_t *end, UnimplementedOpcodeAction unimplemented_action=kAbortOnUnimplementedOpcode)
V8_EXPORT_PRIVATE int InstructionDecode(v8::base::Vector< char > buffer, uint8_t *instruction)
int ConstantPoolSizeAt(uint8_t *instruction)
Disassembler(const NameConverter &converter, UnimplementedOpcodeAction unimplemented_opcode_action=kAbortOnUnimplementedOpcode)
Definition disasm.h:44
const NameConverter & converter_
Definition disasm.h:71
virtual const char * NameOfAddress(uint8_t *addr) const
virtual const char * NameOfXMMRegister(int reg) const
virtual const char * NameInCode(uint8_t *addr) const
virtual const char * NameOfConstant(uint8_t *addr) const
v8::base::EmbeddedVector< char, 128 > tmp_buffer_
Definition disasm.h:32
virtual const char * NameOfByteCPURegister(int reg) const
virtual const char * NameOfCPURegister(int reg) const
int length() const
Definition vector.h:64
constexpr T * begin() const
Definition vector.h:96
void Format(Instruction *instr, const char *format)
int InstructionDecode(uint8_t *instruction)
void Unknown(Instruction *instr)
const disasm::NameConverter & converter_
void PrintRegister(int reg)
void PrintChar(const char ch)
v8::base::Vector< char > out_buffer_
int FormatOption(Instruction *instr, const char *option)
int FormatRegister(Instruction *instr, const char *option)
void Print(const char *str)
Decoder & operator=(const Decoder &)=delete
static Instruction * At(Address pc)
static constexpr DwVfpRegister from_code(int8_t code)
#define PPC_VX_OPCODE_A_FORM_LIST(V)
#define PPC_VX_OPCODE_G_FORM_LIST(V)
#define PPC_VA_OPCODE_A_FORM_LIST(V)
#define PPC_VX_OPCODE_C_FORM_LIST(V)
#define SIGN_EXT_IMM5(imm)
#define PPC_VX_OPCODE_B_FORM_LIST(V)
#define PPC_VX_OPCODE_D_FORM_LIST(V)
#define CRWIDTH
#define PPC_XX3_OPCODE_SCALAR_LIST(V)
#define SIGN_EXT_IMM16(imm)
#define PPC_XX2_OPCODE_VECTOR_A_FORM_LIST(V)
#define SIGN_EXT_IMM34(imm)
#define PPC_XX3_OPCODE_VECTOR_B_FORM_LIST(V)
#define PPC_VX_OPCODE_E_FORM_LIST(V)
#define PPC_VC_OPCODE_LIST(V)
#define PPC_VX_OPCODE_F_FORM_LIST(V)
#define PPC_XX2_OPCODE_B_FORM_LIST(V)
#define PPC_XX2_OPCODE_SCALAR_A_FORM_LIST(V)
#define ABI_USES_FUNCTION_DESCRIPTORS
int end
#define STRING_STARTS_WITH(string, compare_string)
Instruction * instr
LiftoffRegister reg
int int32_t
Definition unicode.cc:40
int SNPrintF(Vector< char > str, const char *format,...)
Definition strings.cc:20
constexpr Opcode ADDI
constexpr BarrierOption LD
constexpr SoftwareInterruptCodes kStopCode
void PrintF(const char *format,...)
Definition utils.cc:39
constexpr FPDataProcessing2SourceOp FSUB
constexpr FPDataProcessing1SourceOp FABS
constexpr SoftwareInterruptCodes kBreakpoint
constexpr SoftwareInterruptCodes kCallRtRedirected
constexpr FPDataProcessing2SourceOp FDIV
constexpr FPDataProcessing2SourceOp FADD
constexpr Opcode SC
constexpr FPDataProcessing1SourceOp FNEG
return value
Definition map-inl.h:893
constexpr uint8_t kInstrSize
constexpr Opcode CMP
constexpr MiscInstructionsBits74 BX
constexpr FPDataProcessing2SourceOp FMUL
constexpr FPDataProcessing1SourceOp FSQRT
constexpr uint32_t kStopCodeMask
#define UNREACHABLE()
Definition logging.h:67
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485