v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
disasm-loong64.cc
Go to the documentation of this file.
1// Copyright 2021 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#include <assert.h>
6#include <stdarg.h>
7#include <stdio.h>
8#include <string.h>
9
10#if V8_TARGET_ARCH_LOONG64
11
13#include "src/base/strings.h"
14#include "src/base/vector.h"
18
19namespace v8 {
20namespace internal {
21
22//------------------------------------------------------------------------------
23
24// Decoder decodes and disassembles instructions into an output buffer.
25// It uses the converter to convert register names and call destinations into
26// more informative description.
27class Decoder {
28 public:
29 Decoder(const disasm::NameConverter& converter,
30 v8::base::Vector<char> out_buffer)
31 : converter_(converter), out_buffer_(out_buffer), out_buffer_pos_(0) {
33 }
34
35 ~Decoder() {}
36
37 Decoder(const Decoder&) = delete;
38 Decoder& operator=(const Decoder&) = delete;
39
40 // Writes one disassembled instruction into 'buffer' (0-terminated).
41 // Returns the length of the disassembled machine instruction in bytes.
42 int InstructionDecode(uint8_t* instruction);
43
44 private:
45 // Bottleneck functions to print into the out_buffer.
46 void PrintChar(const char ch);
47 void Print(const char* str);
48
49 // Printing of common values.
50 void PrintRegister(int reg);
51 void PrintFPURegister(int freg);
52 void PrintFPUStatusRegister(int freg);
53 void PrintRj(Instruction* instr);
54 void PrintRk(Instruction* instr);
55 void PrintRd(Instruction* instr);
56 void PrintFj(Instruction* instr);
57 void PrintFk(Instruction* instr);
58 void PrintFd(Instruction* instr);
59 void PrintFa(Instruction* instr);
60 void PrintSa2(Instruction* instr);
61 void PrintSa3(Instruction* instr);
62 void PrintUi5(Instruction* instr);
63 void PrintUi6(Instruction* instr);
64 void PrintUi12(Instruction* instr);
65 void PrintMsbw(Instruction* instr);
66 void PrintLsbw(Instruction* instr);
67 void PrintMsbd(Instruction* instr);
68 void PrintLsbd(Instruction* instr);
69 // void PrintCond(Instruction* instr);
70 void PrintSi12(Instruction* instr);
71 void PrintSi14(Instruction* instr);
72 void PrintSi16(Instruction* instr);
73 void PrintSi20(Instruction* instr);
74 void PrintXi12(Instruction* instr);
75 void PrintXi20(Instruction* instr);
76 void PrintCj(Instruction* instr);
77 void PrintCd(Instruction* instr);
78 void PrintCa(Instruction* instr);
79 void PrintCode(Instruction* instr);
80 void PrintHint5(Instruction* instr);
81 void PrintHint15(Instruction* instr);
82 void PrintPCOffs16(Instruction* instr);
83 void PrintPCOffs21(Instruction* instr);
84 void PrintPCOffs26(Instruction* instr);
85 void PrintOffs16(Instruction* instr);
86 void PrintOffs21(Instruction* instr);
87 void PrintOffs26(Instruction* instr);
88
89 // Handle formatting of instructions and their options.
90 int FormatRegister(Instruction* instr, const char* option);
91 int FormatFPURegister(Instruction* instr, const char* option);
92 int FormatOption(Instruction* instr, const char* option);
93 void Format(Instruction* instr, const char* format);
94 void Unknown(Instruction* instr);
95 int DecodeBreakInstr(Instruction* instr);
96
97 // Each of these functions decodes one particular instruction type.
98 int InstructionDecode(Instruction* instr);
99 void DecodeTypekOp6(Instruction* instr);
100 void DecodeTypekOp7(Instruction* instr);
101 void DecodeTypekOp8(Instruction* instr);
102 void DecodeTypekOp10(Instruction* instr);
103 void DecodeTypekOp12(Instruction* instr);
104 void DecodeTypekOp14(Instruction* instr);
105 int DecodeTypekOp17(Instruction* instr);
106 void DecodeTypekOp22(Instruction* instr);
107
110 int out_buffer_pos_;
111};
112
113// Support for assertions in the Decoder formatting functions.
114#define STRING_STARTS_WITH(string, compare_string) \
115 (strncmp(string, compare_string, strlen(compare_string)) == 0)
116
117// Append the ch to the output buffer.
118void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; }
119
120// Append the str to the output buffer.
121void Decoder::Print(const char* str) {
122 char cur = *str++;
123 while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
124 PrintChar(cur);
125 cur = *str++;
126 }
128}
129
130// Print the register name according to the active name converter.
131void Decoder::PrintRegister(int reg) {
132 Print(converter_.NameOfCPURegister(reg));
133}
134
135void Decoder::PrintRj(Instruction* instr) {
136 int reg = instr->RjValue();
138}
139
140void Decoder::PrintRk(Instruction* instr) {
141 int reg = instr->RkValue();
143}
144
145void Decoder::PrintRd(Instruction* instr) {
146 int reg = instr->RdValue();
148}
149
150// Print the FPUregister name according to the active name converter.
151void Decoder::PrintFPURegister(int freg) {
152 Print(converter_.NameOfXMMRegister(freg));
153}
154
155void Decoder::PrintFj(Instruction* instr) {
156 int freg = instr->FjValue();
157 PrintFPURegister(freg);
158}
159
160void Decoder::PrintFk(Instruction* instr) {
161 int freg = instr->FkValue();
162 PrintFPURegister(freg);
163}
164
165void Decoder::PrintFd(Instruction* instr) {
166 int freg = instr->FdValue();
167 PrintFPURegister(freg);
168}
169
170void Decoder::PrintFa(Instruction* instr) {
171 int freg = instr->FaValue();
172 PrintFPURegister(freg);
173}
174
175// Print the integer value of the sa field.
176void Decoder::PrintSa2(Instruction* instr) {
177 int sa = instr->Sa2Value();
178 uint32_t opcode = (instr->InstructionBits() >> 18) << 18;
179 if (opcode == ALSL || opcode == ALSL_D) {
180 sa += 1;
181 }
183}
184
185void Decoder::PrintSa3(Instruction* instr) {
186 int sa = instr->Sa3Value();
188}
189
190void Decoder::PrintUi5(Instruction* instr) {
191 int ui = instr->Ui5Value();
193}
194
195void Decoder::PrintUi6(Instruction* instr) {
196 int ui = instr->Ui6Value();
198}
199
200void Decoder::PrintUi12(Instruction* instr) {
201 int ui = instr->Ui12Value();
203}
204
205void Decoder::PrintXi12(Instruction* instr) {
206 int xi = instr->Ui12Value();
208}
209
210void Decoder::PrintXi20(Instruction* instr) {
211 int xi = instr->Si20Value();
213}
214
215void Decoder::PrintMsbd(Instruction* instr) {
216 int msbd = instr->MsbdValue();
218}
219
220void Decoder::PrintLsbd(Instruction* instr) {
221 int lsbd = instr->LsbdValue();
223}
224
225void Decoder::PrintMsbw(Instruction* instr) {
226 int msbw = instr->MsbwValue();
228}
229
230void Decoder::PrintLsbw(Instruction* instr) {
231 int lsbw = instr->LsbwValue();
233}
234
235void Decoder::PrintSi12(Instruction* instr) {
236 int si = ((instr->Si12Value()) << (32 - kSi12Bits)) >> (32 - kSi12Bits);
238 si, instr->Si12Value());
239}
240
241void Decoder::PrintSi14(Instruction* instr) {
242 int si = ((instr->Si14Value()) << (32 - kSi14Bits)) >> (32 - kSi14Bits);
243 si <<= 2;
245 si, instr->Si14Value() << 2);
246}
247
248void Decoder::PrintSi16(Instruction* instr) {
249 int si = ((instr->Si16Value()) << (32 - kSi16Bits)) >> (32 - kSi16Bits);
251 si, instr->Si16Value());
252}
253
254void Decoder::PrintSi20(Instruction* instr) {
255 int si = ((instr->Si20Value()) << (32 - kSi20Bits)) >> (32 - kSi20Bits);
257 si, instr->Si20Value());
258}
259
260void Decoder::PrintCj(Instruction* instr) {
261 int cj = instr->CjValue();
263}
264
265void Decoder::PrintCd(Instruction* instr) {
266 int cd = instr->CdValue();
268}
269
270void Decoder::PrintCa(Instruction* instr) {
271 int ca = instr->CaValue();
273}
274
275void Decoder::PrintCode(Instruction* instr) {
276 int code = instr->CodeValue();
278 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x(%u)", code, code);
279}
280
281void Decoder::PrintHint5(Instruction* instr) {
282 int hint = instr->Hint5Value();
284 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x(%u)", hint, hint);
285}
286
287void Decoder::PrintHint15(Instruction* instr) {
288 int hint = instr->Hint15Value();
290 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x(%u)", hint, hint);
291}
292
293void Decoder::PrintPCOffs16(Instruction* instr) {
294 int n_bits = 2;
295 int offs = instr->Offs16Value();
296 int target = ((offs << n_bits) << (32 - kOffsLowBits - n_bits)) >>
297 (32 - kOffsLowBits - n_bits);
300 converter_.NameOfAddress(reinterpret_cast<uint8_t*>(instr) + target));
301}
302
303void Decoder::PrintPCOffs21(Instruction* instr) {
304 int n_bits = 2;
305 int offs = instr->Offs21Value();
306 int target =
307 ((offs << n_bits) << (32 - kOffsLowBits - kOffs21HighBits - n_bits)) >>
308 (32 - kOffsLowBits - kOffs21HighBits - n_bits);
311 converter_.NameOfAddress(reinterpret_cast<uint8_t*>(instr) + target));
312}
313
314void Decoder::PrintPCOffs26(Instruction* instr) {
315 int n_bits = 2;
316 int offs = instr->Offs26Value();
317 int target =
318 ((offs << n_bits) << (32 - kOffsLowBits - kOffs26HighBits - n_bits)) >>
319 (32 - kOffsLowBits - kOffs26HighBits - n_bits);
322 converter_.NameOfAddress(reinterpret_cast<uint8_t*>(instr) + target));
323}
324
325void Decoder::PrintOffs16(Instruction* instr) {
326 int offs = instr->Offs16Value();
328 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", offs << 2);
329}
330
331void Decoder::PrintOffs21(Instruction* instr) {
332 int offs = instr->Offs21Value();
334 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", offs << 2);
335}
336
337void Decoder::PrintOffs26(Instruction* instr) {
338 int offs = instr->Offs26Value();
340 base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", offs << 2);
341}
342
343// Handle all register based formatting in this function to reduce the
344// complexity of FormatOption.
345int Decoder::FormatRegister(Instruction* instr, const char* format) {
346 DCHECK_EQ(format[0], 'r');
347 if (format[1] == 'j') { // 'rj: Rj register.
348 int reg = instr->RjValue();
350 return 2;
351 } else if (format[1] == 'k') { // 'rk: rk register.
352 int reg = instr->RkValue();
354 return 2;
355 } else if (format[1] == 'd') { // 'rd: rd register.
356 int reg = instr->RdValue();
358 return 2;
359 }
360 UNREACHABLE();
361}
362
363// Handle all FPUregister based formatting in this function to reduce the
364// complexity of FormatOption.
365int Decoder::FormatFPURegister(Instruction* instr, const char* format) {
366 DCHECK_EQ(format[0], 'f');
367 if (format[1] == 'j') { // 'fj: fj register.
368 int reg = instr->FjValue();
370 return 2;
371 } else if (format[1] == 'k') { // 'fk: fk register.
372 int reg = instr->FkValue();
374 return 2;
375 } else if (format[1] == 'd') { // 'fd: fd register.
376 int reg = instr->FdValue();
378 return 2;
379 } else if (format[1] == 'a') { // 'fa: fa register.
380 int reg = instr->FaValue();
382 return 2;
383 }
384 UNREACHABLE();
385}
386
387// FormatOption takes a formatting string and interprets it based on
388// the current instructions. The format string points to the first
389// character of the option string (the option escape has already been
390// consumed by the caller.) FormatOption returns the number of
391// characters that were consumed from the formatting string.
392int Decoder::FormatOption(Instruction* instr, const char* format) {
393 switch (format[0]) {
394 case 'c': {
395 switch (format[1]) {
396 case 'a':
397 DCHECK(STRING_STARTS_WITH(format, "ca"));
398 PrintCa(instr);
399 return 2;
400 case 'd':
401 DCHECK(STRING_STARTS_WITH(format, "cd"));
402 PrintCd(instr);
403 return 2;
404 case 'j':
405 DCHECK(STRING_STARTS_WITH(format, "cj"));
406 PrintCj(instr);
407 return 2;
408 case 'o':
409 DCHECK(STRING_STARTS_WITH(format, "code"));
411 return 4;
412 }
413 }
414 case 'f': {
415 return FormatFPURegister(instr, format);
416 }
417 case 'h': {
418 if (format[4] == '5') {
419 DCHECK(STRING_STARTS_WITH(format, "hint5"));
420 PrintHint5(instr);
421 return 5;
422 } else if (format[4] == '1') {
423 DCHECK(STRING_STARTS_WITH(format, "hint15"));
424 PrintHint15(instr);
425 return 6;
426 }
427 break;
428 }
429 case 'l': {
430 switch (format[3]) {
431 case 'w':
432 DCHECK(STRING_STARTS_WITH(format, "lsbw"));
433 PrintLsbw(instr);
434 return 4;
435 case 'd':
436 DCHECK(STRING_STARTS_WITH(format, "lsbd"));
437 PrintLsbd(instr);
438 return 4;
439 default:
440 return 0;
441 }
442 }
443 case 'm': {
444 if (format[3] == 'w') {
445 DCHECK(STRING_STARTS_WITH(format, "msbw"));
446 PrintMsbw(instr);
447 } else if (format[3] == 'd') {
448 DCHECK(STRING_STARTS_WITH(format, "msbd"));
449 PrintMsbd(instr);
450 }
451 return 4;
452 }
453 case 'o': {
454 if (format[1] == 'f') {
455 if (format[4] == '1') {
456 DCHECK(STRING_STARTS_WITH(format, "offs16"));
457 PrintOffs16(instr);
458 return 6;
459 } else if (format[4] == '2') {
460 if (format[5] == '1') {
461 DCHECK(STRING_STARTS_WITH(format, "offs21"));
462 PrintOffs21(instr);
463 return 6;
464 } else if (format[5] == '6') {
465 DCHECK(STRING_STARTS_WITH(format, "offs26"));
466 PrintOffs26(instr);
467 return 6;
468 }
469 }
470 }
471 break;
472 }
473 case 'p': {
474 if (format[6] == '1') {
475 DCHECK(STRING_STARTS_WITH(format, "pcoffs16"));
476 PrintPCOffs16(instr);
477 return 8;
478 } else if (format[6] == '2') {
479 if (format[7] == '1') {
480 DCHECK(STRING_STARTS_WITH(format, "pcoffs21"));
481 PrintPCOffs21(instr);
482 return 8;
483 } else if (format[7] == '6') {
484 DCHECK(STRING_STARTS_WITH(format, "pcoffs26"));
485 PrintPCOffs26(instr);
486 return 8;
487 }
488 }
489 break;
490 }
491 case 'r': {
492 return FormatRegister(instr, format);
493 }
494 case 's': {
495 switch (format[1]) {
496 case 'a':
497 if (format[2] == '2') {
498 DCHECK(STRING_STARTS_WITH(format, "sa2"));
499 PrintSa2(instr);
500 } else if (format[2] == '3') {
501 DCHECK(STRING_STARTS_WITH(format, "sa3"));
502 PrintSa3(instr);
503 }
504 return 3;
505 case 'i':
506 if (format[2] == '2') {
507 DCHECK(STRING_STARTS_WITH(format, "si20"));
508 PrintSi20(instr);
509 return 4;
510 } else if (format[2] == '1') {
511 switch (format[3]) {
512 case '2':
513 DCHECK(STRING_STARTS_WITH(format, "si12"));
514 PrintSi12(instr);
515 return 4;
516 case '4':
517 DCHECK(STRING_STARTS_WITH(format, "si14"));
518 PrintSi14(instr);
519 return 4;
520 case '6':
521 DCHECK(STRING_STARTS_WITH(format, "si16"));
522 PrintSi16(instr);
523 return 4;
524 default:
525 break;
526 }
527 }
528 break;
529 default:
530 break;
531 }
532 break;
533 }
534 case 'u': {
535 if (format[2] == '5') {
536 DCHECK(STRING_STARTS_WITH(format, "ui5"));
537 PrintUi5(instr);
538 return 3;
539 } else if (format[2] == '6') {
540 DCHECK(STRING_STARTS_WITH(format, "ui6"));
541 PrintUi6(instr);
542 return 3;
543 } else if (format[2] == '1') {
544 DCHECK(STRING_STARTS_WITH(format, "ui12"));
545 PrintUi12(instr);
546 return 4;
547 }
548 break;
549 }
550 case 'x': {
551 if (format[2] == '2') {
552 DCHECK(STRING_STARTS_WITH(format, "xi20"));
553 PrintXi20(instr);
554 return 4;
555 } else if (format[3] == '2') {
556 DCHECK(STRING_STARTS_WITH(format, "xi12"));
557 PrintXi12(instr);
558 return 4;
559 }
560 break;
561 }
562 default:
563 UNREACHABLE();
564 }
565 return 0;
566}
567
568// Format takes a formatting string for a whole instruction and prints it into
569// the output buffer. All escaped options are handed to FormatOption to be
570// parsed further.
571void Decoder::Format(Instruction* instr, const char* format) {
572 char cur = *format++;
573 while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
574 if (cur == '\'') { // Single quote is used as the formatting escape.
575 format += FormatOption(instr, format);
576 } else {
578 }
579 cur = *format++;
580 }
582}
583
584// For currently unimplemented decodings the disassembler calls Unknown(instr)
585// which will just print "unknown" of the instruction bits.
586void Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); }
587
588int Decoder::DecodeBreakInstr(Instruction* instr) {
589 // This is already known to be BREAK instr, just extract the code.
590 /*if (instr->Bits(14, 0) == static_cast<int>(kMaxStopCode)) {
591 // This is stop(msg).
592 Format(instr, "break, code: 'code");
593 out_buffer_pos_ += SNPrintF(
594 out_buffer_ + out_buffer_pos_, "\n%p %08" PRIx64,
595 static_cast<void*>(reinterpret_cast<int32_t*>(instr + kInstrSize)),
596 reinterpret_cast<uint64_t>(
597 *reinterpret_cast<char**>(instr + kInstrSize)));
598 // Size 3: the break_ instr, plus embedded 64-bit char pointer.
599 return 3 * kInstrSize;
600 } else {
601 Format(instr, "break, code: 'code");
602 return kInstrSize;
603 }*/
604 Format(instr, "break code: 'code");
605 return kInstrSize;
606} //===================================================
607
608void Decoder::DecodeTypekOp6(Instruction* instr) {
609 switch (instr->Bits(31, 26) << 26) {
610 case ADDU16I_D:
611 Format(instr, "addu16i.d 'rd, 'rj, 'si16");
612 break;
613 case BEQZ:
614 Format(instr, "beqz 'rj, 'offs21 -> 'pcoffs21");
615 break;
616 case BNEZ:
617 Format(instr, "bnez 'rj, 'offs21 -> 'pcoffs21");
618 break;
619 case BCZ:
620 if (instr->Bit(8))
621 Format(instr, "bcnez fcc'cj, 'offs21 -> 'pcoffs21");
622 else
623 Format(instr, "bceqz fcc'cj, 'offs21 -> 'pcoffs21");
624 break;
625 case JIRL:
626 Format(instr, "jirl 'rd, 'rj, 'offs16");
627 break;
628 case B:
629 Format(instr, "b 'offs26 -> 'pcoffs26");
630 break;
631 case BL:
632 Format(instr, "bl 'offs26 -> 'pcoffs26");
633 break;
634 case BEQ:
635 Format(instr, "beq 'rj, 'rd, 'offs16 -> 'pcoffs16");
636 break;
637 case BNE:
638 Format(instr, "bne 'rj, 'rd, 'offs16 -> 'pcoffs16");
639 break;
640 case BLT:
641 Format(instr, "blt 'rj, 'rd, 'offs16 -> 'pcoffs16");
642 break;
643 case BGE:
644 Format(instr, "bge 'rj, 'rd, 'offs16 -> 'pcoffs16");
645 break;
646 case BLTU:
647 Format(instr, "bltu 'rj, 'rd, 'offs16 -> 'pcoffs16");
648 break;
649 case BGEU:
650 Format(instr, "bgeu 'rj, 'rd, 'offs16 -> 'pcoffs16");
651 break;
652 default:
653 UNREACHABLE();
654 }
655}
656
657void Decoder::DecodeTypekOp7(Instruction* instr) {
658 switch (instr->Bits(31, 25) << 25) {
659 case LU12I_W:
660 Format(instr, "lu12i.w 'rd, 'xi20");
661 break;
662 case LU32I_D:
663 Format(instr, "lu32i.d 'rd, 'xi20");
664 break;
665 case PCADDI:
666 Format(instr, "pcaddi 'rd, 'xi20");
667 break;
668 case PCALAU12I:
669 Format(instr, "pcalau12i 'rd, 'xi20");
670 break;
671 case PCADDU12I:
672 Format(instr, "pcaddu12i 'rd, 'xi20");
673 break;
674 case PCADDU18I:
675 Format(instr, "pcaddu18i 'rd, 'xi20");
676 break;
677 default:
678 UNREACHABLE();
679 }
680}
681
682void Decoder::DecodeTypekOp8(Instruction* instr) {
683 switch (instr->Bits(31, 24) << 24) {
684 case LDPTR_W:
685 Format(instr, "ldptr.w 'rd, 'rj, 'si14");
686 break;
687 case STPTR_W:
688 Format(instr, "stptr.w 'rd, 'rj, 'si14");
689 break;
690 case LDPTR_D:
691 Format(instr, "ldptr.d 'rd, 'rj, 'si14");
692 break;
693 case STPTR_D:
694 Format(instr, "stptr.d 'rd, 'rj, 'si14");
695 break;
696 case LL_W:
697 Format(instr, "ll.w 'rd, 'rj, 'si14");
698 break;
699 case SC_W:
700 Format(instr, "sc.w 'rd, 'rj, 'si14");
701 break;
702 case LL_D:
703 Format(instr, "ll.d 'rd, 'rj, 'si14");
704 break;
705 case SC_D:
706 Format(instr, "sc.d 'rd, 'rj, 'si14");
707 break;
708 default:
709 UNREACHABLE();
710 }
711}
712
713void Decoder::DecodeTypekOp10(Instruction* instr) {
714 switch (instr->Bits(31, 22) << 22) {
715 case BSTR_W: {
716 if (instr->Bit(21) != 0) {
717 if (instr->Bit(15) == 0) {
718 Format(instr, "bstrins.w 'rd, 'rj, 'msbw, 'lsbw");
719 } else {
720 Format(instr, "bstrpick.w 'rd, 'rj, 'msbw, 'lsbw");
721 }
722 }
723 break;
724 }
725 case BSTRINS_D:
726 Format(instr, "bstrins.d 'rd, 'rj, 'msbd, 'lsbd");
727 break;
728 case BSTRPICK_D:
729 Format(instr, "bstrpick.d 'rd, 'rj, 'msbd, 'lsbd");
730 break;
731 case SLTI:
732 Format(instr, "slti 'rd, 'rj, 'si12");
733 break;
734 case SLTUI:
735 Format(instr, "sltui 'rd, 'rj, 'si12");
736 break;
737 case ADDI_W:
738 Format(instr, "addi.w 'rd, 'rj, 'si12");
739 break;
740 case ADDI_D:
741 Format(instr, "addi.d 'rd, 'rj, 'si12");
742 break;
743 case LU52I_D:
744 Format(instr, "lu52i.d 'rd, 'rj, 'xi12");
745 break;
746 case ANDI:
747 Format(instr, "andi 'rd, 'rj, 'xi12");
748 break;
749 case ORI:
750 Format(instr, "ori 'rd, 'rj, 'xi12");
751 break;
752 case XORI:
753 Format(instr, "xori 'rd, 'rj, 'xi12");
754 break;
755 case LD_B:
756 Format(instr, "ld.b 'rd, 'rj, 'si12");
757 break;
758 case LD_H:
759 Format(instr, "ld.h 'rd, 'rj, 'si12");
760 break;
761 case LD_W:
762 Format(instr, "ld.w 'rd, 'rj, 'si12");
763 break;
764 case LD_D:
765 Format(instr, "ld.d 'rd, 'rj, 'si12");
766 break;
767 case ST_B:
768 Format(instr, "st.b 'rd, 'rj, 'si12");
769 break;
770 case ST_H:
771 Format(instr, "st.h 'rd, 'rj, 'si12");
772 break;
773 case ST_W:
774 Format(instr, "st.w 'rd, 'rj, 'si12");
775 break;
776 case ST_D:
777 Format(instr, "st.d 'rd, 'rj, 'si12");
778 break;
779 case LD_BU:
780 Format(instr, "ld.bu 'rd, 'rj, 'si12");
781 break;
782 case LD_HU:
783 Format(instr, "ld.hu 'rd, 'rj, 'si12");
784 break;
785 case LD_WU:
786 Format(instr, "ld.wu 'rd, 'rj, 'si12");
787 break;
788 case FLD_S:
789 Format(instr, "fld.s 'fd, 'rj, 'si12");
790 break;
791 case FST_S:
792 Format(instr, "fst.s 'fd, 'rj, 'si12");
793 break;
794 case FLD_D:
795 Format(instr, "fld.d 'fd, 'rj, 'si12");
796 break;
797 case FST_D:
798 Format(instr, "fst.d 'fd, 'rj, 'si12");
799 break;
800 default:
801 UNREACHABLE();
802 }
803}
804
805void Decoder::DecodeTypekOp12(Instruction* instr) {
806 switch (instr->Bits(31, 20) << 20) {
807 case FMADD_S:
808 Format(instr, "fmadd.s 'fd, 'fj, 'fk, 'fa");
809 break;
810 case FMADD_D:
811 Format(instr, "fmadd.d 'fd, 'fj, 'fk, 'fa");
812 break;
813 case FMSUB_S:
814 Format(instr, "fmsub.s 'fd, 'fj, 'fk, 'fa");
815 break;
816 case FMSUB_D:
817 Format(instr, "fmsub.d 'fd, 'fj, 'fk, 'fa");
818 break;
819 case FNMADD_S:
820 Format(instr, "fnmadd.s 'fd, 'fj, 'fk, 'fa");
821 break;
822 case FNMADD_D:
823 Format(instr, "fnmadd.d 'fd, 'fj, 'fk, 'fa");
824 break;
825 case FNMSUB_S:
826 Format(instr, "fnmsub.s 'fd, 'fj, 'fk, 'fa");
827 break;
828 case FNMSUB_D:
829 Format(instr, "fnmsub.d 'fd, 'fj, 'fk, 'fa");
830 break;
831 case FCMP_COND_S:
832 switch (instr->Bits(19, 15)) {
833 case CAF:
834 Format(instr, "fcmp.caf.s fcc'cd, 'fj, 'fk");
835 break;
836 case SAF:
837 Format(instr, "fcmp.saf.s fcc'cd, 'fj, 'fk");
838 break;
839 case CLT:
840 Format(instr, "fcmp.clt.s fcc'cd, 'fj, 'fk");
841 break;
842 case CEQ:
843 Format(instr, "fcmp.ceq.s fcc'cd, 'fj, 'fk");
844 break;
845 case SEQ:
846 Format(instr, "fcmp.seq.s fcc'cd, 'fj, 'fk");
847 break;
848 case CLE:
849 Format(instr, "fcmp.cle.s fcc'cd, 'fj, 'fk");
850 break;
851 case SLE:
852 Format(instr, "fcmp.sle.s fcc'cd, 'fj, 'fk");
853 break;
854 case CUN:
855 Format(instr, "fcmp.cun.s fcc'cd, 'fj, 'fk");
856 break;
857 case SUN:
858 Format(instr, "fcmp.sun.s fcc'cd, 'fj, 'fk");
859 break;
860 case CULT:
861 Format(instr, "fcmp.cult.s fcc'cd, 'fj, 'fk");
862 break;
863 case SULT:
864 Format(instr, "fcmp.sult.s fcc'cd, 'fj, 'fk");
865 break;
866 case CUEQ:
867 Format(instr, "fcmp.cueq.s fcc'cd, 'fj, 'fk");
868 break;
869 case SUEQ:
870 Format(instr, "fcmp.sueq.s fcc'cd, 'fj, 'fk");
871 break;
872 case CULE:
873 Format(instr, "fcmp.cule.s fcc'cd, 'fj, 'fk");
874 break;
875 case SULE:
876 Format(instr, "fcmp.sule.s fcc'cd, 'fj, 'fk");
877 break;
878 case CNE:
879 Format(instr, "fcmp.cne.s fcc'cd, 'fj, 'fk");
880 break;
881 case SNE:
882 Format(instr, "fcmp.sne.s fcc'cd, 'fj, 'fk");
883 break;
884 case COR:
885 Format(instr, "fcmp.cor.s fcc'cd, 'fj, 'fk");
886 break;
887 case SOR:
888 Format(instr, "fcmp.sor.s fcc'cd, 'fj, 'fk");
889 break;
890 case CUNE:
891 Format(instr, "fcmp.cune.s fcc'cd, 'fj, 'fk");
892 break;
893 case SUNE:
894 Format(instr, "fcmp.sune.s fcc'cd, 'fj, 'fk");
895 break;
896 default:
897 UNREACHABLE();
898 }
899 break;
900 case FCMP_COND_D:
901 switch (instr->Bits(19, 15)) {
902 case CAF:
903 Format(instr, "fcmp.caf.d fcc'cd, 'fj, 'fk");
904 break;
905 case SAF:
906 Format(instr, "fcmp.saf.d fcc'cd, 'fj, 'fk");
907 break;
908 case CLT:
909 Format(instr, "fcmp.clt.d fcc'cd, 'fj, 'fk");
910 break;
911 case CEQ:
912 Format(instr, "fcmp.ceq.d fcc'cd, 'fj, 'fk");
913 break;
914 case SEQ:
915 Format(instr, "fcmp.seq.d fcc'cd, 'fj, 'fk");
916 break;
917 case CLE:
918 Format(instr, "fcmp.cle.d fcc'cd, 'fj, 'fk");
919 break;
920 case SLE:
921 Format(instr, "fcmp.sle.d fcc'cd, 'fj, 'fk");
922 break;
923 case CUN:
924 Format(instr, "fcmp.cun.d fcc'cd, 'fj, 'fk");
925 break;
926 case SUN:
927 Format(instr, "fcmp.sun.d fcc'cd, 'fj, 'fk");
928 break;
929 case CULT:
930 Format(instr, "fcmp.cult.d fcc'cd, 'fj, 'fk");
931 break;
932 case SULT:
933 Format(instr, "fcmp.sult.d fcc'cd, 'fj, 'fk");
934 break;
935 case CUEQ:
936 Format(instr, "fcmp.cueq.d fcc'cd, 'fj, 'fk");
937 break;
938 case SUEQ:
939 Format(instr, "fcmp.sueq.d fcc'cd, 'fj, 'fk");
940 break;
941 case CULE:
942 Format(instr, "fcmp.cule.d fcc'cd, 'fj, 'fk");
943 break;
944 case SULE:
945 Format(instr, "fcmp.sule.d fcc'cd, 'fj, 'fk");
946 break;
947 case CNE:
948 Format(instr, "fcmp.cne.d fcc'cd, 'fj, 'fk");
949 break;
950 case SNE:
951 Format(instr, "fcmp.sne.d fcc'cd, 'fj, 'fk");
952 break;
953 case COR:
954 Format(instr, "fcmp.cor.d fcc'cd, 'fj, 'fk");
955 break;
956 case SOR:
957 Format(instr, "fcmp.sor.d fcc'cd, 'fj, 'fk");
958 break;
959 case CUNE:
960 Format(instr, "fcmp.cune.d fcc'cd, 'fj, 'fk");
961 break;
962 case SUNE:
963 Format(instr, "fcmp.sune.d fcc'cd, 'fj, 'fk");
964 break;
965 default:
966 UNREACHABLE();
967 }
968 break;
969 case FSEL:
970 Format(instr, "fsel 'fd, 'fj, 'fk, fcc'ca");
971 break;
972 default:
973 UNREACHABLE();
974 }
975}
976
977void Decoder::DecodeTypekOp14(Instruction* instr) {
978 switch (instr->Bits(31, 18) << 18) {
979 case ALSL:
980 if (instr->Bit(17))
981 Format(instr, "alsl.wu 'rd, 'rj, 'rk, 'sa2");
982 else
983 Format(instr, "alsl.w 'rd, 'rj, 'rk, 'sa2");
984 break;
985 case BYTEPICK_W:
986 Format(instr, "bytepick.w 'rd, 'rj, 'rk, 'sa2");
987 break;
988 case BYTEPICK_D:
989 Format(instr, "bytepick.d 'rd, 'rj, 'rk, 'sa3");
990 break;
991 case ALSL_D:
992 Format(instr, "alsl.d 'rd, 'rj, 'rk, 'sa2");
993 break;
994 case SLLI:
995 if (instr->Bit(16))
996 Format(instr, "slli.d 'rd, 'rj, 'ui6");
997 else
998 Format(instr, "slli.w 'rd, 'rj, 'ui5");
999 break;
1000 case SRLI:
1001 if (instr->Bit(16))
1002 Format(instr, "srli.d 'rd, 'rj, 'ui6");
1003 else
1004 Format(instr, "srli.w 'rd, 'rj, 'ui5");
1005 break;
1006 case SRAI:
1007 if (instr->Bit(16))
1008 Format(instr, "srai.d 'rd, 'rj, 'ui6");
1009 else
1010 Format(instr, "srai.w 'rd, 'rj, 'ui5");
1011 break;
1012 case ROTRI:
1013 if (instr->Bit(16))
1014 Format(instr, "rotri.d 'rd, 'rj, 'ui6");
1015 else
1016 Format(instr, "rotri.w 'rd, 'rj, 'ui5");
1017 break;
1018 default:
1019 UNREACHABLE();
1020 }
1021}
1022
1023int Decoder::DecodeTypekOp17(Instruction* instr) {
1024 switch (instr->Bits(31, 15) << 15) {
1025 case ADD_W:
1026 Format(instr, "add.w 'rd, 'rj, 'rk");
1027 break;
1028 case ADD_D:
1029 Format(instr, "add.d 'rd, 'rj, 'rk");
1030 break;
1031 case SUB_W:
1032 Format(instr, "sub.w 'rd, 'rj, 'rk");
1033 break;
1034 case SUB_D:
1035 Format(instr, "sub.d 'rd, 'rj, 'rk");
1036 break;
1037 case SLT:
1038 Format(instr, "slt 'rd, 'rj, 'rk");
1039 break;
1040 case SLTU:
1041 Format(instr, "sltu 'rd, 'rj, 'rk");
1042 break;
1043 case MASKEQZ:
1044 Format(instr, "maskeqz 'rd, 'rj, 'rk");
1045 break;
1046 case MASKNEZ:
1047 Format(instr, "masknez 'rd, 'rj, 'rk");
1048 break;
1049 case NOR:
1050 Format(instr, "nor 'rd, 'rj, 'rk");
1051 break;
1052 case AND:
1053 Format(instr, "and 'rd, 'rj, 'rk");
1054 break;
1055 case OR:
1056 Format(instr, "or 'rd, 'rj, 'rk");
1057 break;
1058 case XOR:
1059 Format(instr, "xor 'rd, 'rj, 'rk");
1060 break;
1061 case ORN:
1062 Format(instr, "orn 'rd, 'rj, 'rk");
1063 break;
1064 case ANDN:
1065 Format(instr, "andn 'rd, 'rj, 'rk");
1066 break;
1067 case SLL_W:
1068 Format(instr, "sll.w 'rd, 'rj, 'rk");
1069 break;
1070 case SRL_W:
1071 Format(instr, "srl.w 'rd, 'rj, 'rk");
1072 break;
1073 case SRA_W:
1074 Format(instr, "sra.w 'rd, 'rj, 'rk");
1075 break;
1076 case SLL_D:
1077 Format(instr, "sll.d 'rd, 'rj, 'rk");
1078 break;
1079 case SRL_D:
1080 Format(instr, "srl.d 'rd, 'rj, 'rk");
1081 break;
1082 case SRA_D:
1083 Format(instr, "sra.d 'rd, 'rj, 'rk");
1084 break;
1085 case ROTR_D:
1086 Format(instr, "rotr.d 'rd, 'rj, 'rk");
1087 break;
1088 case ROTR_W:
1089 Format(instr, "rotr.w 'rd, 'rj, 'rk");
1090 break;
1091 case MUL_W:
1092 Format(instr, "mul.w 'rd, 'rj, 'rk");
1093 break;
1094 case MULH_W:
1095 Format(instr, "mulh.w 'rd, 'rj, 'rk");
1096 break;
1097 case MULH_WU:
1098 Format(instr, "mulh.wu 'rd, 'rj, 'rk");
1099 break;
1100 case MUL_D:
1101 Format(instr, "mul.d 'rd, 'rj, 'rk");
1102 break;
1103 case MULH_D:
1104 Format(instr, "mulh.d 'rd, 'rj, 'rk");
1105 break;
1106 case MULH_DU:
1107 Format(instr, "mulh.du 'rd, 'rj, 'rk");
1108 break;
1109 case MULW_D_W:
1110 Format(instr, "mulw.d.w 'rd, 'rj, 'rk");
1111 break;
1112 case MULW_D_WU:
1113 Format(instr, "mulw.d.wu 'rd, 'rj, 'rk");
1114 break;
1115 case DIV_W:
1116 Format(instr, "div.w 'rd, 'rj, 'rk");
1117 break;
1118 case MOD_W:
1119 Format(instr, "mod.w 'rd, 'rj, 'rk");
1120 break;
1121 case DIV_WU:
1122 Format(instr, "div.wu 'rd, 'rj, 'rk");
1123 break;
1124 case MOD_WU:
1125 Format(instr, "mod.wu 'rd, 'rj, 'rk");
1126 break;
1127 case DIV_D:
1128 Format(instr, "div.d 'rd, 'rj, 'rk");
1129 break;
1130 case MOD_D:
1131 Format(instr, "mod.d 'rd, 'rj, 'rk");
1132 break;
1133 case DIV_DU:
1134 Format(instr, "div.du 'rd, 'rj, 'rk");
1135 break;
1136 case MOD_DU:
1137 Format(instr, "mod.du 'rd, 'rj, 'rk");
1138 break;
1139 case BREAK:
1140 return DecodeBreakInstr(instr);
1141 case FADD_S:
1142 Format(instr, "fadd.s 'fd, 'fj, 'fk");
1143 break;
1144 case FADD_D:
1145 Format(instr, "fadd.d 'fd, 'fj, 'fk");
1146 break;
1147 case FSUB_S:
1148 Format(instr, "fsub.s 'fd, 'fj, 'fk");
1149 break;
1150 case FSUB_D:
1151 Format(instr, "fsub.d 'fd, 'fj, 'fk");
1152 break;
1153 case FMUL_S:
1154 Format(instr, "fmul.s 'fd, 'fj, 'fk");
1155 break;
1156 case FMUL_D:
1157 Format(instr, "fmul.d 'fd, 'fj, 'fk");
1158 break;
1159 case FDIV_S:
1160 Format(instr, "fdiv.s 'fd, 'fj, 'fk");
1161 break;
1162 case FDIV_D:
1163 Format(instr, "fdiv.d 'fd, 'fj, 'fk");
1164 break;
1165 case FMAX_S:
1166 Format(instr, "fmax.s 'fd, 'fj, 'fk");
1167 break;
1168 case FMAX_D:
1169 Format(instr, "fmax.d 'fd, 'fj, 'fk");
1170 break;
1171 case FMIN_S:
1172 Format(instr, "fmin.s 'fd, 'fj, 'fk");
1173 break;
1174 case FMIN_D:
1175 Format(instr, "fmin.d 'fd, 'fj, 'fk");
1176 break;
1177 case FMAXA_S:
1178 Format(instr, "fmaxa.s 'fd, 'fj, 'fk");
1179 break;
1180 case FMAXA_D:
1181 Format(instr, "fmaxa.d 'fd, 'fj, 'fk");
1182 break;
1183 case FMINA_S:
1184 Format(instr, "fmina.s 'fd, 'fj, 'fk");
1185 break;
1186 case FMINA_D:
1187 Format(instr, "fmina.d 'fd, 'fj, 'fk");
1188 break;
1189 case LDX_B:
1190 Format(instr, "ldx.b 'rd, 'rj, 'rk");
1191 break;
1192 case LDX_H:
1193 Format(instr, "ldx.h 'rd, 'rj, 'rk");
1194 break;
1195 case LDX_W:
1196 Format(instr, "ldx.w 'rd, 'rj, 'rk");
1197 break;
1198 case LDX_D:
1199 Format(instr, "ldx.d 'rd, 'rj, 'rk");
1200 break;
1201 case STX_B:
1202 Format(instr, "stx.b 'rd, 'rj, 'rk");
1203 break;
1204 case STX_H:
1205 Format(instr, "stx.h 'rd, 'rj, 'rk");
1206 break;
1207 case STX_W:
1208 Format(instr, "stx.w 'rd, 'rj, 'rk");
1209 break;
1210 case STX_D:
1211 Format(instr, "stx.d 'rd, 'rj, 'rk");
1212 break;
1213 case LDX_BU:
1214 Format(instr, "ldx.bu 'rd, 'rj, 'rk");
1215 break;
1216 case LDX_HU:
1217 Format(instr, "ldx.hu 'rd, 'rj, 'rk");
1218 break;
1219 case LDX_WU:
1220 Format(instr, "ldx.wu 'rd, 'rj, 'rk");
1221 break;
1222 case FLDX_S:
1223 Format(instr, "fldx.s 'fd, 'rj, 'rk");
1224 break;
1225 case FLDX_D:
1226 Format(instr, "fldx.d 'fd, 'rj, 'rk");
1227 break;
1228 case FSTX_S:
1229 Format(instr, "fstx.s 'fd, 'rj, 'rk");
1230 break;
1231 case FSTX_D:
1232 Format(instr, "fstx.d 'fd, 'rj, 'rk");
1233 break;
1234 case AMSWAP_W:
1235 Format(instr, "amswap.w 'rd, 'rk, 'rj");
1236 break;
1237 case AMSWAP_D:
1238 Format(instr, "amswap.d 'rd, 'rk, 'rj");
1239 break;
1240 case AMADD_W:
1241 Format(instr, "amadd.w 'rd, 'rk, 'rj");
1242 break;
1243 case AMADD_D:
1244 Format(instr, "amadd.d 'rd, 'rk, 'rj");
1245 break;
1246 case AMAND_W:
1247 Format(instr, "amand.w 'rd, 'rk, 'rj");
1248 break;
1249 case AMAND_D:
1250 Format(instr, "amand.d 'rd, 'rk, 'rj");
1251 break;
1252 case AMOR_W:
1253 Format(instr, "amor.w 'rd, 'rk, 'rj");
1254 break;
1255 case AMOR_D:
1256 Format(instr, "amor.d 'rd, 'rk, 'rj");
1257 break;
1258 case AMXOR_W:
1259 Format(instr, "amxor.w 'rd, 'rk, 'rj");
1260 break;
1261 case AMXOR_D:
1262 Format(instr, "amxor.d 'rd, 'rk, 'rj");
1263 break;
1264 case AMMAX_W:
1265 Format(instr, "ammax.w 'rd, 'rk, 'rj");
1266 break;
1267 case AMMAX_D:
1268 Format(instr, "ammax.d 'rd, 'rk, 'rj");
1269 break;
1270 case AMMIN_W:
1271 Format(instr, "ammin.w 'rd, 'rk, 'rj");
1272 break;
1273 case AMMIN_D:
1274 Format(instr, "ammin.d 'rd, 'rk, 'rj");
1275 break;
1276 case AMMAX_WU:
1277 Format(instr, "ammax.wu 'rd, 'rk, 'rj");
1278 break;
1279 case AMMAX_DU:
1280 Format(instr, "ammax.du 'rd, 'rk, 'rj");
1281 break;
1282 case AMMIN_WU:
1283 Format(instr, "ammin.wu 'rd, 'rk, 'rj");
1284 break;
1285 case AMMIN_DU:
1286 Format(instr, "ammin.du 'rd, 'rk, 'rj");
1287 break;
1288 case AMSWAP_DB_W:
1289 Format(instr, "amswap_db.w 'rd, 'rk, 'rj");
1290 break;
1291 case AMSWAP_DB_D:
1292 Format(instr, "amswap_db.d 'rd, 'rk, 'rj");
1293 break;
1294 case AMADD_DB_W:
1295 Format(instr, "amadd_db.w 'rd, 'rk, 'rj");
1296 break;
1297 case AMADD_DB_D:
1298 Format(instr, "amadd_db.d 'rd, 'rk, 'rj");
1299 break;
1300 case AMAND_DB_W:
1301 Format(instr, "amand_db.w 'rd, 'rk, 'rj");
1302 break;
1303 case AMAND_DB_D:
1304 Format(instr, "amand_db.d 'rd, 'rk, 'rj");
1305 break;
1306 case AMOR_DB_W:
1307 Format(instr, "amor_db.w 'rd, 'rk, 'rj");
1308 break;
1309 case AMOR_DB_D:
1310 Format(instr, "amor_db.d 'rd, 'rk, 'rj");
1311 break;
1312 case AMXOR_DB_W:
1313 Format(instr, "amxor_db.w 'rd, 'rk, 'rj");
1314 break;
1315 case AMXOR_DB_D:
1316 Format(instr, "amxor_db.d 'rd, 'rk, 'rj");
1317 break;
1318 case AMMAX_DB_W:
1319 Format(instr, "ammax_db.w 'rd, 'rk, 'rj");
1320 break;
1321 case AMMAX_DB_D:
1322 Format(instr, "ammax_db.d 'rd, 'rk, 'rj");
1323 break;
1324 case AMMIN_DB_W:
1325 Format(instr, "ammin_db.w 'rd, 'rk, 'rj");
1326 break;
1327 case AMMIN_DB_D:
1328 Format(instr, "ammin_db.d 'rd, 'rk, 'rj");
1329 break;
1330 case AMMAX_DB_WU:
1331 Format(instr, "ammax_db.wu 'rd, 'rk, 'rj");
1332 break;
1333 case AMMAX_DB_DU:
1334 Format(instr, "ammax_db.du 'rd, 'rk, 'rj");
1335 break;
1336 case AMMIN_DB_WU:
1337 Format(instr, "ammin_db.wu 'rd, 'rk, 'rj");
1338 break;
1339 case AMMIN_DB_DU:
1340 Format(instr, "ammin_db.du 'rd, 'rk, 'rj");
1341 break;
1342 case DBAR:
1343 Format(instr, "dbar 'hint15");
1344 break;
1345 case IBAR:
1346 Format(instr, "ibar 'hint15");
1347 break;
1348 case FSCALEB_S:
1349 Format(instr, "fscaleb.s 'fd, 'fj, 'fk");
1350 break;
1351 case FSCALEB_D:
1352 Format(instr, "fscaleb.d 'fd, 'fj, 'fk");
1353 break;
1354 case FCOPYSIGN_S:
1355 Format(instr, "fcopysign.s 'fd, 'fj, 'fk");
1356 break;
1357 case FCOPYSIGN_D:
1358 Format(instr, "fcopysign.d 'fd, 'fj, 'fk");
1359 break;
1360 default:
1361 UNREACHABLE();
1362 }
1363 return kInstrSize;
1364}
1365
1366void Decoder::DecodeTypekOp22(Instruction* instr) {
1367 switch (instr->Bits(31, 10) << 10) {
1368 case CLZ_W:
1369 Format(instr, "clz.w 'rd, 'rj");
1370 break;
1371 case CTZ_W:
1372 Format(instr, "ctz.w 'rd, 'rj");
1373 break;
1374 case CLZ_D:
1375 Format(instr, "clz.d 'rd, 'rj");
1376 break;
1377 case CTZ_D:
1378 Format(instr, "ctz.d 'rd, 'rj");
1379 break;
1380 case REVB_2H:
1381 Format(instr, "revb.2h 'rd, 'rj");
1382 break;
1383 case REVB_4H:
1384 Format(instr, "revb.4h 'rd, 'rj");
1385 break;
1386 case REVB_2W:
1387 Format(instr, "revb.2w 'rd, 'rj");
1388 break;
1389 case REVB_D:
1390 Format(instr, "revb.d 'rd, 'rj");
1391 break;
1392 case REVH_2W:
1393 Format(instr, "revh.2w 'rd, 'rj");
1394 break;
1395 case REVH_D:
1396 Format(instr, "revh.d 'rd, 'rj");
1397 break;
1398 case BITREV_4B:
1399 Format(instr, "bitrev.4b 'rd, 'rj");
1400 break;
1401 case BITREV_8B:
1402 Format(instr, "bitrev.8b 'rd, 'rj");
1403 break;
1404 case BITREV_W:
1405 Format(instr, "bitrev.w 'rd, 'rj");
1406 break;
1407 case BITREV_D:
1408 Format(instr, "bitrev.d 'rd, 'rj");
1409 break;
1410 case EXT_W_B:
1411 Format(instr, "ext.w.b 'rd, 'rj");
1412 break;
1413 case EXT_W_H:
1414 Format(instr, "ext.w.h 'rd, 'rj");
1415 break;
1416 case FABS_S:
1417 Format(instr, "fabs.s 'fd, 'fj");
1418 break;
1419 case FABS_D:
1420 Format(instr, "fabs.d 'fd, 'fj");
1421 break;
1422 case FNEG_S:
1423 Format(instr, "fneg.s 'fd, 'fj");
1424 break;
1425 case FNEG_D:
1426 Format(instr, "fneg.d 'fd, 'fj");
1427 break;
1428 case FSQRT_S:
1429 Format(instr, "fsqrt.s 'fd, 'fj");
1430 break;
1431 case FSQRT_D:
1432 Format(instr, "fsqrt.d 'fd, 'fj");
1433 break;
1434 case FMOV_S:
1435 Format(instr, "fmov.s 'fd, 'fj");
1436 break;
1437 case FMOV_D:
1438 Format(instr, "fmov.d 'fd, 'fj");
1439 break;
1440 case MOVGR2FR_W:
1441 Format(instr, "movgr2fr.w 'fd, 'rj");
1442 break;
1443 case MOVGR2FR_D:
1444 Format(instr, "movgr2fr.d 'fd, 'rj");
1445 break;
1446 case MOVGR2FRH_W:
1447 Format(instr, "movgr2frh.w 'fd, 'rj");
1448 break;
1449 case MOVFR2GR_S:
1450 Format(instr, "movfr2gr.s 'rd, 'fj");
1451 break;
1452 case MOVFR2GR_D:
1453 Format(instr, "movfr2gr.d 'rd, 'fj");
1454 break;
1455 case MOVFRH2GR_S:
1456 Format(instr, "movfrh2gr.s 'rd, 'fj");
1457 break;
1458 case MOVGR2FCSR:
1459 Format(instr, "movgr2fcsr fcsr, 'rj");
1460 break;
1461 case MOVFCSR2GR:
1462 Format(instr, "movfcsr2gr 'rd, fcsr");
1463 break;
1464 case FCVT_S_D:
1465 Format(instr, "fcvt.s.d 'fd, 'fj");
1466 break;
1467 case FCVT_D_S:
1468 Format(instr, "fcvt.d.s 'fd, 'fj");
1469 break;
1470 case FTINTRM_W_S:
1471 Format(instr, "ftintrm.w.s 'fd, 'fj");
1472 break;
1473 case FTINTRM_W_D:
1474 Format(instr, "ftintrm.w.d 'fd, 'fj");
1475 break;
1476 case FTINTRM_L_S:
1477 Format(instr, "ftintrm.l.s 'fd, 'fj");
1478 break;
1479 case FTINTRM_L_D:
1480 Format(instr, "ftintrm.l.d 'fd, 'fj");
1481 break;
1482 case FTINTRP_W_S:
1483 Format(instr, "ftintrp.w.s 'fd, 'fj");
1484 break;
1485 case FTINTRP_W_D:
1486 Format(instr, "ftintrp.w.d 'fd, 'fj");
1487 break;
1488 case FTINTRP_L_S:
1489 Format(instr, "ftintrp.l.s 'fd, 'fj");
1490 break;
1491 case FTINTRP_L_D:
1492 Format(instr, "ftintrp.l.d 'fd, 'fj");
1493 break;
1494 case FTINTRZ_W_S:
1495 Format(instr, "ftintrz.w.s 'fd, 'fj");
1496 break;
1497 case FTINTRZ_W_D:
1498 Format(instr, "ftintrz.w.d 'fd, 'fj");
1499 break;
1500 case FTINTRZ_L_S:
1501 Format(instr, "ftintrz.l.s 'fd, 'fj");
1502 break;
1503 case FTINTRZ_L_D:
1504 Format(instr, "ftintrz.l.d 'fd, 'fj");
1505 break;
1506 case FTINTRNE_W_S:
1507 Format(instr, "ftintrne.w.s 'fd, 'fj");
1508 break;
1509 case FTINTRNE_W_D:
1510 Format(instr, "ftintrne.w.d 'fd, 'fj");
1511 break;
1512 case FTINTRNE_L_S:
1513 Format(instr, "ftintrne.l.s 'fd, 'fj");
1514 break;
1515 case FTINTRNE_L_D:
1516 Format(instr, "ftintrne.l.d 'fd, 'fj");
1517 break;
1518 case FTINT_W_S:
1519 Format(instr, "ftint.w.s 'fd, 'fj");
1520 break;
1521 case FTINT_W_D:
1522 Format(instr, "ftint.w.d 'fd, 'fj");
1523 break;
1524 case FTINT_L_S:
1525 Format(instr, "ftint.l.s 'fd, 'fj");
1526 break;
1527 case FTINT_L_D:
1528 Format(instr, "ftint.l.d 'fd, 'fj");
1529 break;
1530 case FFINT_S_W:
1531 Format(instr, "ffint.s.w 'fd, 'fj");
1532 break;
1533 case FFINT_S_L:
1534 Format(instr, "ffint.s.l 'fd, 'fj");
1535 break;
1536 case FFINT_D_W:
1537 Format(instr, "ffint.d.w 'fd, 'fj");
1538 break;
1539 case FFINT_D_L:
1540 Format(instr, "ffint.d.l 'fd, 'fj");
1541 break;
1542 case FRINT_S:
1543 Format(instr, "frint.s 'fd, 'fj");
1544 break;
1545 case FRINT_D:
1546 Format(instr, "frint.d 'fd, 'fj");
1547 break;
1548 case MOVFR2CF:
1549 Format(instr, "movfr2cf fcc'cd, 'fj");
1550 break;
1551 case MOVCF2FR:
1552 Format(instr, "movcf2fr 'fd, fcc'cj");
1553 break;
1554 case MOVGR2CF:
1555 Format(instr, "movgr2cf fcc'cd, 'rj");
1556 break;
1557 case MOVCF2GR:
1558 Format(instr, "movcf2gr 'rd, fcc'cj");
1559 break;
1560 case FRECIP_S:
1561 Format(instr, "frecip.s 'fd, 'fj");
1562 break;
1563 case FRECIP_D:
1564 Format(instr, "frecip.d 'fd, 'fj");
1565 break;
1566 case FRSQRT_S:
1567 Format(instr, "frsqrt.s 'fd, 'fj");
1568 break;
1569 case FRSQRT_D:
1570 Format(instr, "frsqrt.d 'fd, 'fj");
1571 break;
1572 case FCLASS_S:
1573 Format(instr, "fclass.s 'fd, 'fj");
1574 break;
1575 case FCLASS_D:
1576 Format(instr, "fclass.d 'fd, 'fj");
1577 break;
1578 case FLOGB_S:
1579 Format(instr, "flogb.s 'fd, 'fj");
1580 break;
1581 case FLOGB_D:
1582 Format(instr, "flogb.d 'fd, 'fj");
1583 break;
1584 case CLO_W:
1585 Format(instr, "clo.w 'rd, 'rj");
1586 break;
1587 case CTO_W:
1588 Format(instr, "cto.w 'rd, 'rj");
1589 break;
1590 case CLO_D:
1591 Format(instr, "clo.d 'rd, 'rj");
1592 break;
1593 case CTO_D:
1594 Format(instr, "cto.d 'rd, 'rj");
1595 break;
1596 default:
1597 UNREACHABLE();
1598 }
1599}
1600
1601int Decoder::InstructionDecode(uint8_t* instr_ptr) {
1602 Instruction* instr = Instruction::At(instr_ptr);
1604 "%08x ", instr->InstructionBits());
1605 switch (instr->InstructionType()) {
1606 case Instruction::kOp6Type: {
1607 DecodeTypekOp6(instr);
1608 break;
1609 }
1610 case Instruction::kOp7Type: {
1611 DecodeTypekOp7(instr);
1612 break;
1613 }
1614 case Instruction::kOp8Type: {
1615 DecodeTypekOp8(instr);
1616 break;
1617 }
1619 DecodeTypekOp10(instr);
1620 break;
1621 }
1623 DecodeTypekOp12(instr);
1624 break;
1625 }
1627 DecodeTypekOp14(instr);
1628 break;
1629 }
1631 return DecodeTypekOp17(instr);
1632 }
1634 DecodeTypekOp22(instr);
1635 break;
1636 }
1638 Format(instr, "UNSUPPORTED");
1639 break;
1640 }
1641 default: {
1642 Format(instr, "UNSUPPORTED");
1643 break;
1644 }
1645 }
1646 return kInstrSize;
1647}
1648
1649} // namespace internal
1650} // namespace v8
1651
1652//------------------------------------------------------------------------------
1653
1654namespace disasm {
1655
1656const char* NameConverter::NameOfAddress(uint8_t* addr) const {
1657 v8::base::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr));
1658 return tmp_buffer_.begin();
1659}
1660
1661const char* NameConverter::NameOfConstant(uint8_t* addr) const {
1662 return NameOfAddress(addr);
1663}
1664
1665const char* NameConverter::NameOfCPURegister(int reg) const {
1667}
1668
1669const char* NameConverter::NameOfXMMRegister(int reg) const {
1671}
1672
1673const char* NameConverter::NameOfByteCPURegister(int reg) const {
1674 UNREACHABLE();
1675}
1676
1677const char* NameConverter::NameInCode(uint8_t* addr) const {
1678 // The default name converter is called for unknown code. So we will not try
1679 // to access any memory.
1680 return "";
1681}
1682
1683//------------------------------------------------------------------------------
1684
1686 uint8_t* instruction) {
1688 return d.InstructionDecode(instruction);
1689}
1690
1691int Disassembler::ConstantPoolSizeAt(uint8_t* instruction) { return -1; }
1692
1693void Disassembler::Disassemble(FILE* f, uint8_t* begin, uint8_t* end,
1694 UnimplementedOpcodeAction unimplemented_action) {
1695 NameConverter converter;
1696 Disassembler d(converter, unimplemented_action);
1697 for (uint8_t* pc = begin; pc < end;) {
1699 buffer[0] = '\0';
1700 uint8_t* prev_pc = pc;
1701 pc += d.InstructionDecode(buffer, pc);
1702 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc),
1703 *reinterpret_cast<int32_t*>(prev_pc), buffer.begin());
1704 }
1705}
1706
1707#undef STRING_STARTS_WITH
1708
1709} // namespace disasm
1710
1711#endif // V8_TARGET_ARCH_LOONG64
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)
void PrintFPUStatusRegister(int freg)
void PrintFPURegister(int freg)
int InstructionDecode(uint8_t *instruction)
void Unknown(Instruction *instr)
const disasm::NameConverter & converter_
void PrintRegister(int reg)
void PrintRd(Instruction *instr)
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 const char * Name(int reg)
static Instruction * At(Address pc)
static const char * Name(int reg)
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
void PrintCode(Isolate *isolate, DirectHandle< Code > code, OptimizedCompilationInfo *info)
Definition pipeline.cc:588
constexpr UnconditionalBranchOp BL
constexpr Opcode AND
void PrintF(const char *format,...)
Definition utils.cc:39
constexpr int B
const int kOffs26HighBits
constexpr LogicalOp ORN
const int kOffsLowBits
constexpr uint8_t kInstrSize
const int kOffs21HighBits
#define UNREACHABLE()
Definition logging.h:67
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_EQ(v1, v2)
Definition logging.h:485