13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
43100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
53100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// A Disassembler object is used to disassemble a block of code instruction by
63100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// instruction. The default implementation of the NameConverter object can be
73100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// overriden to modify register names or to do symbol lookup on addresses.
83100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//
93100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// The example below will disassemble a block of code and print it to stdout.
103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//
113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//   NameConverter converter;
123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//   Disassembler d(converter);
13257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch//   for (byte* pc = begin; pc < end;) {
1444f0eee88ff00398ff7f715fab053374d808c90dSteve Block//     v8::internal::EmbeddedVector<char, 256> buffer;
1544f0eee88ff00398ff7f715fab053374d808c90dSteve Block//     byte* prev_pc = pc;
1644f0eee88ff00398ff7f715fab053374d808c90dSteve Block//     pc += d.InstructionDecode(buffer, pc);
173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//     printf("%p    %08x      %s\n",
183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//            prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//   }
203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//
213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// The Disassembler class also has a convenience method to disassemble a block
223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// of code into a FILE*, meaning that the above functionality could also be
233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// achieved by just calling Disassembler::Disassemble(stdout, begin, end);
243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include <assert.h>
263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include <stdarg.h>
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <stdio.h>
283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#include <string.h>
293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_MIPS
31f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h"
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/disasm.h"
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/macro-assembler.h"
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/mips/constants-mips.h"
363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3744f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace v8 {
3844f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace internal {
393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//------------------------------------------------------------------------------
413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Decoder decodes and disassembles instructions into an output buffer.
433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// It uses the converter to convert register names and call destinations into
443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// more informative description.
453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuclass Decoder {
463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu public:
473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Decoder(const disasm::NameConverter& converter,
483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          v8::internal::Vector<char> out_buffer)
493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    : converter_(converter),
503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      out_buffer_(out_buffer),
513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      out_buffer_pos_(0) {
523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    out_buffer_[out_buffer_pos_] = '\0';
533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  ~Decoder() {}
563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Writes one disassembled instruction into 'buffer' (0-terminated).
583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Returns the length of the disassembled machine instruction in bytes.
59257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int InstructionDecode(byte* instruction);
603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu private:
623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Bottleneck functions to print into the out_buffer.
633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintChar(const char ch);
643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void Print(const char* str);
653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Printing of common values.
673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintRegister(int reg);
6844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void PrintFPURegister(int freg);
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintFPUStatusRegister(int freg);
703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintRs(Instruction* instr);
713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintRt(Instruction* instr);
723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintRd(Instruction* instr);
733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintFs(Instruction* instr);
743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintFt(Instruction* instr);
753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintFd(Instruction* instr);
763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintSa(Instruction* instr);
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintLsaSa(Instruction* instr);
7844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void PrintSd(Instruction* instr);
79257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void PrintSs1(Instruction* instr);
80257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void PrintSs2(Instruction* instr);
8144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void PrintBc(Instruction* instr);
8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void PrintCc(Instruction* instr);
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintBp2(Instruction* instr);
843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintFunction(Instruction* instr);
853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintSecondaryField(Instruction* instr);
863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintUImm16(Instruction* instr);
873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintSImm16(Instruction* instr);
883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintXImm16(Instruction* instr);
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits);
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintXImm18(Instruction* instr);
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintSImm18(Instruction* instr);
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintXImm19(Instruction* instr);
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintSImm19(Instruction* instr);
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void PrintXImm21(Instruction* instr);
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintSImm21(Instruction* instr);
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits);
97589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  void PrintXImm26(Instruction* instr);
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintSImm26(Instruction* instr);
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits);
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintPCImm26(Instruction* instr);
1013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintCode(Instruction* instr);   // For break and trap instructions.
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void PrintFormat(Instruction* instr);  // For floating format postfix.
1033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Printing of instruction name.
1043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void PrintInstructionName(Instruction* instr);
1053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Handle formatting of instructions and their options.
1073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  int FormatRegister(Instruction* instr, const char* option);
10844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int FormatFPURegister(Instruction* instr, const char* option);
1093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  int FormatOption(Instruction* instr, const char* option);
1103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void Format(Instruction* instr, const char* format);
1113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void Unknown(Instruction* instr);
1123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Each of these functions decodes one particular instruction type.
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool DecodeTypeRegisterRsType(Instruction* instr);
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DecodeTypeRegisterSRsType(Instruction* instr);
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DecodeTypeRegisterDRsType(Instruction* instr);
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DecodeTypeRegisterLRsType(Instruction* instr);
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DecodeTypeRegisterWRsType(Instruction* instr);
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DecodeTypeRegisterSPECIAL(Instruction* instr);
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DecodeTypeRegisterSPECIAL2(Instruction* instr);
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void DecodeTypeRegisterSPECIAL3(Instruction* instr);
1233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void DecodeTypeRegister(Instruction* instr);
1243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void DecodeTypeImmediate(Instruction* instr);
1253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void DecodeTypeJump(Instruction* instr);
1263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  const disasm::NameConverter& converter_;
1283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  v8::internal::Vector<char> out_buffer_;
1293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  int out_buffer_pos_;
1303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  DISALLOW_COPY_AND_ASSIGN(Decoder);
1323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu};
1333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Support for assertions in the Decoder formatting functions.
1363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#define STRING_STARTS_WITH(string, compare_string) \
1373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  (strncmp(string, compare_string, strlen(compare_string)) == 0)
1383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Append the ch to the output buffer.
1413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintChar(const char ch) {
1423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  out_buffer_[out_buffer_pos_++] = ch;
1433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Append the str to the output buffer.
1473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::Print(const char* str) {
1483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  char cur = *str++;
1493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
1503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    PrintChar(cur);
1513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    cur = *str++;
1523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
1533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  out_buffer_[out_buffer_pos_] = 0;
1543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Print the register name according to the active name converter.
1583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintRegister(int reg) {
1593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Print(converter_.NameOfCPURegister(reg));
1603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintRs(Instruction* instr) {
16444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int reg = instr->RsValue();
1653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  PrintRegister(reg);
1663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintRt(Instruction* instr) {
17044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int reg = instr->RtValue();
1713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  PrintRegister(reg);
1723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintRd(Instruction* instr) {
17644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int reg = instr->RdValue();
1773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  PrintRegister(reg);
1783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
18144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Print the FPUregister name according to the active name converter.
18244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Decoder::PrintFPURegister(int freg) {
18344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Print(converter_.NameOfXMMRegister(freg));
1843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
1853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintFPUStatusRegister(int freg) {
188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (freg) {
189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kFCSRRegister:
190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Print("FCSR");
191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Print(converter_.NameOfXMMRegister(freg));
194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintFs(Instruction* instr) {
19944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int freg = instr->RsValue();
20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PrintFPURegister(freg);
2013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
2023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintFt(Instruction* instr) {
20544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int freg = instr->RtValue();
20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PrintFPURegister(freg);
2073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
2083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintFd(Instruction* instr) {
21144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int freg = instr->RdValue();
21244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PrintFPURegister(freg);
2133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
2143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Print the integer value of the sa field.
2173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintSa(Instruction* instr) {
21844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int sa = instr->SaValue();
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa);
22044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
22144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
22244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Print the integer value of the sa field of a lsa instruction.
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintLsaSa(Instruction* instr) {
225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int sa = instr->LsaSaValue() + 1;
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa);
227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
230257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Print the integer value of the rd field, when it is not used as reg.
23144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Decoder::PrintSd(Instruction* instr) {
23244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int sd = instr->RdValue();
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sd);
23444f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
23544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
23644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
237257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Print the integer value of the rd field, when used as 'ext' size.
238257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Decoder::PrintSs1(Instruction* instr) {
239257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int ss = instr->RdValue();
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss + 1);
241257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
242257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
243257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
244257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Print the integer value of the rd field, when used as 'ins' size.
245257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Decoder::PrintSs2(Instruction* instr) {
246257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int ss = instr->RdValue();
247257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int pos = instr->SaValue();
248257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  out_buffer_pos_ +=
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss - pos + 1);
250257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
252257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
25344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Print the integer value of the cc field for the bc1t/f instructions.
25444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Decoder::PrintBc(Instruction* instr) {
25544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int cc = instr->FBccValue();
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", cc);
25744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
25844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
25944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
26044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Print the integer value of the cc field for the FP compare instructions.
26144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Decoder::PrintCc(Instruction* instr) {
26244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int cc = instr->FCccValue();
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "cc(%d)", cc);
2643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
2653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintBp2(Instruction* instr) {
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int bp2 = instr->Bp2Value();
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp2);
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Print 16-bit unsigned immediate value.
2743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintUImm16(Instruction* instr) {
27544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int32_t imm = instr->Imm16Value();
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm);
2773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
2783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Print 16-bit signed immediate value.
2813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintSImm16(Instruction* instr) {
282257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int32_t imm = ((instr->Imm16Value()) << 16) >> 16;
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
2843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
2853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
2873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Print 16-bit hexa immediate value.
2883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintXImm16(Instruction* instr) {
28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int32_t imm = instr->Imm16Value();
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Print absoulte address for 16-bit offset or immediate value.
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The absolute address is calculated according following expression:
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//      PC + delta_pc + (offset << n_bits)
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintPCImm16(Instruction* instr, int delta_pc, int n_bits) {
298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int16_t offset = instr->Imm16Value();
299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  out_buffer_pos_ +=
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SNPrintF(out_buffer_ + out_buffer_pos_, "%s",
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter_.NameOfAddress(reinterpret_cast<byte*>(instr) +
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        delta_pc + (offset << n_bits)));
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Print 18-bit signed immediate value.
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintSImm18(Instruction* instr) {
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t imm =
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits);
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Print 18-bit hexa immediate value.
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintXImm18(Instruction* instr) {
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t imm = instr->Imm18Value();
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Print 19-bit hexa immediate value.
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintXImm19(Instruction* instr) {
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t imm = instr->Imm19Value();
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Print 19-bit signed immediate value.
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintSImm19(Instruction* instr) {
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t imm19 = instr->Imm19Value();
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // set sign
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  imm19 <<= (32 - kImm19Bits);
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  imm19 >>= (32 - kImm19Bits);
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm19);
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Print 21-bit immediate value.
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Decoder::PrintXImm21(Instruction* instr) {
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint32_t imm = instr->Imm21Value();
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
3423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
3433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Print 21-bit signed immediate value.
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintSImm21(Instruction* instr) {
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t imm21 = instr->Imm21Value();
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // set sign
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  imm21 <<= (32 - kImm21Bits);
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  imm21 >>= (32 - kImm21Bits);
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm21);
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Print absoulte address for 21-bit offset or immediate value.
356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The absolute address is calculated according following expression:
357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//      PC + delta_pc + (offset << n_bits)
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) {
359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t imm21 = instr->Imm21Value();
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // set sign
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  imm21 <<= (32 - kImm21Bits);
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  imm21 >>= (32 - kImm21Bits);
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  out_buffer_pos_ +=
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SNPrintF(out_buffer_ + out_buffer_pos_, "%s",
365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter_.NameOfAddress(reinterpret_cast<byte*>(instr) +
366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        delta_pc + (imm21 << n_bits)));
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Print 26-bit hex immediate value.
371589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid Decoder::PrintXImm26(Instruction* instr) {
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t target = static_cast<uint32_t>(instr->Imm26Value())
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    << kImmFieldShift;
374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  target = (reinterpret_cast<uint32_t>(instr) & ~0xfffffff) | target;
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", target);
376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Print 26-bit signed immediate value.
380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintSImm26(Instruction* instr) {
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t imm26 = instr->Imm26Value();
382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // set sign
383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  imm26 <<= (32 - kImm26Bits);
384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  imm26 >>= (32 - kImm26Bits);
385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm26);
386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Print absoulte address for 26-bit offset or immediate value.
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The absolute address is calculated according following expression:
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//      PC + delta_pc + (offset << n_bits)
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintPCImm26(Instruction* instr, int delta_pc, int n_bits) {
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t imm26 = instr->Imm26Value();
394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // set sign
395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  imm26 <<= (32 - kImm26Bits);
396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  imm26 >>= (32 - kImm26Bits);
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  out_buffer_pos_ +=
398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SNPrintF(out_buffer_ + out_buffer_pos_, "%s",
399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter_.NameOfAddress(reinterpret_cast<byte*>(instr) +
400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        delta_pc + (imm26 << n_bits)));
401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Print absoulte address for 26-bit offset or immediate value.
405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// The absolute address is calculated according following expression:
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//      PC[GPRLEN-1 .. 28] || instr_index26 || 00
407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintPCImm26(Instruction* instr) {
408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t imm26 = instr->Imm26Value();
409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t pc_mask = ~0xfffffff;
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t pc = ((uint32_t)(instr + 1) & pc_mask) | (imm26 << 2);
411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  out_buffer_pos_ +=
412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SNPrintF(out_buffer_ + out_buffer_pos_, "%s",
413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               converter_.NameOfAddress((reinterpret_cast<byte*>(pc))));
4143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
4153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
4163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
4173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Print 26-bit immediate value.
4183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintCode(Instruction* instr) {
4193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  if (instr->OpcodeFieldRaw() != SPECIAL)
4203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    return;  // Not a break or trap instruction.
4213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  switch (instr->FunctionFieldRaw()) {
4223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case BREAK: {
4233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      int32_t code = instr->Bits(25, 6);
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  "0x%05x (%d)", code, code);
4263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
4273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                }
4283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case TGE:
4293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case TGEU:
4303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case TLT:
4313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case TLTU:
4323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case TEQ:
4333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case TNE: {
4343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      int32_t code = instr->Bits(15, 6);
4353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      out_buffer_pos_ +=
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code);
4373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
4383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
4393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    default:  // Not a break or trap instruction.
4403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    break;
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
4433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
4443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::PrintFormat(Instruction* instr) {
446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  char formatLetter = ' ';
447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (instr->RsFieldRaw()) {
448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case S:
449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      formatLetter = 's';
450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case D:
452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      formatLetter = 'd';
453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case W:
455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      formatLetter = 'w';
456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case L:
458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      formatLetter = 'l';
459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintChar(formatLetter);
465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Printing of instruction name.
4693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::PrintInstructionName(Instruction* instr) {
4703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
4713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
4723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
4733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Handle all register based formatting in this function to reduce the
4743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// complexity of FormatOption.
4753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuint Decoder::FormatRegister(Instruction* instr, const char* format) {
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(format[0] == 'r');
477257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (format[1] == 's') {  // 'rs: Rs register.
47844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int reg = instr->RsValue();
4793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    PrintRegister(reg);
4803100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    return 2;
481257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else if (format[1] == 't') {  // 'rt: rt register.
48244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int reg = instr->RtValue();
4833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    PrintRegister(reg);
4843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    return 2;
485257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else if (format[1] == 'd') {  // 'rd: rd register.
48644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    int reg = instr->RdValue();
4873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    PrintRegister(reg);
4883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    return 2;
4893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
4903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  UNREACHABLE();
4913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return -1;
4923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
4933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
4943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
49544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Handle all FPUregister based formatting in this function to reduce the
4963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// complexity of FormatOption.
49744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint Decoder::FormatFPURegister(Instruction* instr, const char* format) {
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(format[0] == 'f');
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if ((CTC1 == instr->RsFieldRaw()) || (CFC1 == instr->RsFieldRaw())) {
500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (format[1] == 's') {  // 'fs: fs register.
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int reg = instr->FsValue();
502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintFPUStatusRegister(reg);
503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 2;
504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (format[1] == 't') {  // 'ft: ft register.
505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int reg = instr->FtValue();
506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintFPUStatusRegister(reg);
507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 2;
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (format[1] == 'd') {  // 'fd: fd register.
509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int reg = instr->FdValue();
510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintFPUStatusRegister(reg);
511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 2;
512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (format[1] == 'r') {  // 'fr: fr register.
513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int reg = instr->FrValue();
514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintFPUStatusRegister(reg);
515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 2;
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (format[1] == 's') {  // 'fs: fs register.
519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int reg = instr->FsValue();
520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintFPURegister(reg);
521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 2;
522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (format[1] == 't') {  // 'ft: ft register.
523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int reg = instr->FtValue();
524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintFPURegister(reg);
525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 2;
526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (format[1] == 'd') {  // 'fd: fd register.
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int reg = instr->FdValue();
528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintFPURegister(reg);
529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 2;
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (format[1] == 'r') {  // 'fr: fr register.
531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int reg = instr->FrValue();
532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintFPURegister(reg);
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 2;
534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
5353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
5363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  UNREACHABLE();
5373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return -1;
5383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
5393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
5403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
5413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// FormatOption takes a formatting string and interprets it based on
5423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// the current instructions. The format string points to the first
5433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// character of the option string (the option escape has already been
5443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// consumed by the caller.)  FormatOption returns the number of
5453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// characters that were consumed from the formatting string.
5463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuint Decoder::FormatOption(Instruction* instr, const char* format) {
5473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  switch (format[0]) {
548257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    case 'c': {   // 'code for break or trap instructions.
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(STRING_STARTS_WITH(format, "code"));
5503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      PrintCode(instr);
5513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      return 4;
5523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
553257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    case 'i': {   // 'imm16u or 'imm26.
5543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      if (format[3] == '1') {
555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (format[4] == '6') {
556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DCHECK(STRING_STARTS_WITH(format, "imm16"));
557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          switch (format[5]) {
558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            case 's':
559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              DCHECK(STRING_STARTS_WITH(format, "imm16s"));
560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              PrintSImm16(instr);
561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              break;
562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            case 'u':
563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              DCHECK(STRING_STARTS_WITH(format, "imm16u"));
564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              PrintSImm16(instr);
565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              break;
566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            case 'x':
567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              DCHECK(STRING_STARTS_WITH(format, "imm16x"));
568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              PrintXImm16(instr);
569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              break;
570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            case 'p': {  // The PC relative address.
571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              DCHECK(STRING_STARTS_WITH(format, "imm16p"));
572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              int delta_pc = 0;
573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              int n_bits = 0;
574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              switch (format[6]) {
575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                case '4': {
576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  DCHECK(STRING_STARTS_WITH(format, "imm16p4"));
577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  delta_pc = 4;
578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  switch (format[8]) {
579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    case '2':
580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      DCHECK(STRING_STARTS_WITH(format, "imm16p4s2"));
581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      n_bits = 2;
582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      PrintPCImm16(instr, delta_pc, n_bits);
583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      return 9;
584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  }
585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                }
586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              }
587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return 6;
590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else if (format[4] == '8') {
591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DCHECK(STRING_STARTS_WITH(format, "imm18"));
592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          switch (format[5]) {
593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            case 's':
594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              DCHECK(STRING_STARTS_WITH(format, "imm18s"));
595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              PrintSImm18(instr);
596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              break;
597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            case 'x':
598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              DCHECK(STRING_STARTS_WITH(format, "imm18x"));
599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              PrintXImm18(instr);
600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              break;
601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return 6;
603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else if (format[4] == '9') {
604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DCHECK(STRING_STARTS_WITH(format, "imm19"));
605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          switch (format[5]) {
606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            case 's':
607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              DCHECK(STRING_STARTS_WITH(format, "imm19s"));
608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              PrintSImm19(instr);
609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              break;
610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            case 'x':
611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              DCHECK(STRING_STARTS_WITH(format, "imm19x"));
612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              PrintXImm19(instr);
613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              break;
614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return 6;
6163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu        }
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (format[3] == '2' && format[4] == '1') {
618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(STRING_STARTS_WITH(format, "imm21"));
619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        switch (format[5]) {
620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          case 's':
621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            DCHECK(STRING_STARTS_WITH(format, "imm21s"));
622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            PrintSImm21(instr);
623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            break;
624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          case 'x':
625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            DCHECK(STRING_STARTS_WITH(format, "imm21x"));
626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            PrintXImm21(instr);
627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            break;
628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          case 'p': {  // The PC relative address.
629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            DCHECK(STRING_STARTS_WITH(format, "imm21p"));
630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            int delta_pc = 0;
631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            int n_bits = 0;
632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            switch (format[6]) {
633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              case '4': {
634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                DCHECK(STRING_STARTS_WITH(format, "imm21p4"));
635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                delta_pc = 4;
636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                switch (format[8]) {
637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  case '2':
638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    DCHECK(STRING_STARTS_WITH(format, "imm21p4s2"));
639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    n_bits = 2;
640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    PrintPCImm21(instr, delta_pc, n_bits);
641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    return 9;
642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                }
643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              }
644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return 6;
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (format[3] == '2' && format[4] == '6') {
649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(STRING_STARTS_WITH(format, "imm26"));
650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        switch (format[5]) {
651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          case 's':
652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            DCHECK(STRING_STARTS_WITH(format, "imm26s"));
653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            PrintSImm26(instr);
654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            break;
655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          case 'x':
656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            DCHECK(STRING_STARTS_WITH(format, "imm26x"));
657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            PrintXImm26(instr);
658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            break;
659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          case 'p': {  // The PC relative address.
660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            DCHECK(STRING_STARTS_WITH(format, "imm26p"));
661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            int delta_pc = 0;
662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            int n_bits = 0;
663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            switch (format[6]) {
664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              case '4': {
665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                DCHECK(STRING_STARTS_WITH(format, "imm26p4"));
666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                delta_pc = 4;
667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                switch (format[8]) {
668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  case '2':
669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    DCHECK(STRING_STARTS_WITH(format, "imm26p4s2"));
670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    n_bits = 2;
671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    PrintPCImm26(instr, delta_pc, n_bits);
672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    return 9;
673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                }
674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              }
675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          case 'j': {  // Absolute address for jump instructions.
678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            DCHECK(STRING_STARTS_WITH(format, "imm26j"));
679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            PrintPCImm26(instr);
680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            break;
681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
683589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        return 6;
6843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      }
6853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
686257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    case 'r': {   // 'r: registers.
6873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      return FormatRegister(instr, format);
6883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
689257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    case 'f': {   // 'f: FPUregisters.
69044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return FormatFPURegister(instr, format);
6913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
692257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    case 's': {   // 'sa.
69344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      switch (format[1]) {
694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case 'a':
695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (format[2] == '2') {
696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            DCHECK(STRING_STARTS_WITH(format, "sa2"));  // 'sa2
697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            PrintLsaSa(instr);
698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            return 3;
699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else {
700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            DCHECK(STRING_STARTS_WITH(format, "sa"));
701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            PrintSa(instr);
702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            return 2;
703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
70544f0eee88ff00398ff7f715fab053374d808c90dSteve Block        case 'd': {
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          DCHECK(STRING_STARTS_WITH(format, "sd"));
70744f0eee88ff00398ff7f715fab053374d808c90dSteve Block          PrintSd(instr);
70844f0eee88ff00398ff7f715fab053374d808c90dSteve Block          return 2;
70944f0eee88ff00398ff7f715fab053374d808c90dSteve Block        }
710257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        case 's': {
711257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          if (format[2] == '1') {
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              DCHECK(STRING_STARTS_WITH(format, "ss1"));  /* ext size */
713257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              PrintSs1(instr);
714257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              return 3;
715257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          } else {
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              DCHECK(STRING_STARTS_WITH(format, "ss2"));  /* ins size */
717257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              PrintSs2(instr);
718257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              return 3;
719257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          }
720257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        }
72144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      }
72244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case 'b': {
724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      switch (format[1]) {
725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case 'c': {  // 'bc - Special for bc1 cc field.
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DCHECK(STRING_STARTS_WITH(format, "bc"));
727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          PrintBc(instr);
728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return 2;
729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case 'p': {
731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          switch (format[2]) {
732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            case '2': {  // 'bp2
733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              DCHECK(STRING_STARTS_WITH(format, "bp2"));
734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              PrintBp2(instr);
735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              return 3;
736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
74044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
74144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case 'C': {   // 'Cc - Special for c.xx.d cc field.
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(STRING_STARTS_WITH(format, "Cc"));
74344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      PrintCc(instr);
7443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      return 2;
7453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case 't':
747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintFormat(instr);
748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 1;
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
7503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  UNREACHABLE();
7513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return -1;
7523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
7533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
7543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
7553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Format takes a formatting string for a whole instruction and prints it into
7563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// the output buffer. All escaped options are handed to FormatOption to be
7573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// parsed further.
7583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::Format(Instruction* instr, const char* format) {
7593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  char cur = *format++;
7603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
7613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    if (cur == '\'') {  // Single quote is used as the formatting escape.
7623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      format += FormatOption(instr, format);
7633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    } else {
7643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      out_buffer_[out_buffer_pos_++] = cur;
7653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
7663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    cur = *format++;
7673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
7683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  out_buffer_[out_buffer_pos_]  = '\0';
7693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
7703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
7713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
7723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// For currently unimplemented decodings the disassembler calls Unknown(instr)
7733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// which will just print "unknown" of the instruction bits.
7743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::Unknown(Instruction* instr) {
7753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Format(instr, "unknown");
7763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
7773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
7783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool Decoder::DecodeTypeRegisterRsType(Instruction* instr) {
780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (instr->FunctionFieldRaw()) {
781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case RINT:
782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "rint.'t    'fd, 'fs");
7833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MIN:
785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "min.'t    'fd, 'fs, 'ft");
786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MAX:
788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "max.'t    'fd, 'fs, 'ft");
789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MINA:
791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "mina.'t   'fd, 'fs, 'ft");
792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MAXA:
794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "maxa.'t   'fd, 'fs, 'ft");
795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SEL:
797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "sel.'t      'fd, 'fs, 'ft");
798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SELEQZ_C:
800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "seleqz.'t    'fd, 'fs, 'ft");
801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SELNEZ_C:
803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "selnez.'t    'fd, 'fs, 'ft");
804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MOVZ_C:
806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "movz.'t    'fd, 'fs, 'rt");
807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MOVN_C:
809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "movn.'t    'fd, 'fs, 'rt");
810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MOVF:
812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->Bit(16)) {
813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "movt.'t    'fd, 'fs, 'Cc");
814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "movf.'t    'fd, 'fs, 'Cc");
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case ADD_D:
819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "add.'t   'fd, 'fs, 'ft");
820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SUB_D:
822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "sub.'t   'fd, 'fs, 'ft");
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MUL_D:
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "mul.'t   'fd, 'fs, 'ft");
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case DIV_D:
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "div.'t   'fd, 'fs, 'ft");
829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case ABS_D:
831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "abs.'t   'fd, 'fs");
832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MOV_D:
834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "mov.'t   'fd, 'fs");
835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case NEG_D:
837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "neg.'t   'fd, 'fs");
838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SQRT_D:
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "sqrt.'t  'fd, 'fs");
841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case RECIP_D:
843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "recip.'t  'fd, 'fs");
844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case RSQRT_D:
846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "rsqrt.'t  'fd, 'fs");
847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CVT_W_D:
849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cvt.w.'t 'fd, 'fs");
850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CVT_L_D:
852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cvt.l.'t 'fd, 'fs");
853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TRUNC_W_D:
855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "trunc.w.'t 'fd, 'fs");
856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TRUNC_L_D:
858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "trunc.l.'t 'fd, 'fs");
859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case ROUND_W_D:
861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "round.w.'t 'fd, 'fs");
862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case ROUND_L_D:
864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "round.l.'t 'fd, 'fs");
865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FLOOR_W_D:
867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "floor.w.'t 'fd, 'fs");
868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case FLOOR_L_D:
870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "floor.l.'t 'fd, 'fs");
871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CEIL_W_D:
873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "ceil.w.'t 'fd, 'fs");
874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CLASS_D:
876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "class.'t 'fd, 'fs");
877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CEIL_L_D:
879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "ceil.l.'t 'fd, 'fs");
880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CVT_S_D:
882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cvt.s.'t 'fd, 'fs");
883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case C_F_D:
885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "c.f.'t   'fs, 'ft, 'Cc");
886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case C_UN_D:
888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "c.un.'t  'fs, 'ft, 'Cc");
889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case C_EQ_D:
891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "c.eq.'t  'fs, 'ft, 'Cc");
892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case C_UEQ_D:
894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "c.ueq.'t 'fs, 'ft, 'Cc");
895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case C_OLT_D:
897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "c.olt.'t 'fs, 'ft, 'Cc");
898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case C_ULT_D:
900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "c.ult.'t 'fs, 'ft, 'Cc");
901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case C_OLE_D:
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "c.ole.'t 'fs, 'ft, 'Cc");
904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case C_ULE_D:
906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "c.ule.'t 'fs, 'ft, 'Cc");
907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return true;
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::DecodeTypeRegisterSRsType(Instruction* instr) {
916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!DecodeTypeRegisterRsType(instr)) {
917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (instr->FunctionFieldRaw()) {
918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case CVT_D_S:
919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "cvt.d.'t 'fd, 'fs");
920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      default:
922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "unknown.cop1.'t");
923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::DecodeTypeRegisterDRsType(Instruction* instr) {
930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!DecodeTypeRegisterRsType(instr)) {
931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Format(instr, "unknown.cop1.'t");
932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::DecodeTypeRegisterLRsType(Instruction* instr) {
937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (instr->FunctionFieldRaw()) {
938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CVT_D_L:
939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cvt.d.l 'fd, 'fs");
940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CVT_S_L:
942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cvt.s.l 'fd, 'fs");
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_AF:
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.af.d  'fd,  'fs, 'ft");
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_UN:
948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.un.d  'fd,  'fs, 'ft");
949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_EQ:
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.eq.d  'fd,  'fs, 'ft");
952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_UEQ:
954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.ueq.d  'fd,  'fs, 'ft");
955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_LT:
957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.lt.d  'fd,  'fs, 'ft");
958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_ULT:
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.ult.d  'fd,  'fs, 'ft");
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_LE:
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.le.d  'fd,  'fs, 'ft");
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_ULE:
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.ule.d  'fd,  'fs, 'ft");
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_OR:
969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.or.d  'fd,  'fs, 'ft");
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_UNE:
972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.une.d  'fd,  'fs, 'ft");
973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_NE:
975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.ne.d  'fd,  'fs, 'ft");
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::DecodeTypeRegisterWRsType(Instruction* instr) {
984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (instr->FunctionValue()) {
985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CVT_S_W:  // Convert word to float (single).
986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cvt.s.w 'fd, 'fs");
987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CVT_D_W:  // Convert word to double.
989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cvt.d.w 'fd, 'fs");
990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_AF:
992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.af.s    'fd, 'fs, 'ft");
993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_UN:
995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.un.s    'fd, 'fs, 'ft");
996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_EQ:
998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.eq.s    'fd, 'fs, 'ft");
999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_UEQ:
1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.ueq.s   'fd, 'fs, 'ft");
1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_LT:
1004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.lt.s    'fd, 'fs, 'ft");
1005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_ULT:
1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.ult.s   'fd, 'fs, 'ft");
1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_LE:
1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.le.s    'fd, 'fs, 'ft");
1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_ULE:
1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.ule.s   'fd, 'fs, 'ft");
1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_OR:
1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.or.s    'fd, 'fs, 'ft");
1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_UNE:
1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.une.s   'fd, 'fs, 'ft");
1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CMP_NE:
1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "cmp.ne.s    'fd, 'fs, 'ft");
1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) {
1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (instr->FunctionFieldRaw()) {
1032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case JR:
1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "jr      'rs");
1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case JALR:
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "jalr    'rs, 'rd");
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SLL:
1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (0x0 == static_cast<int>(instr->InstructionBits()))
1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "nop");
1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      else
1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "sll     'rd, 'rt, 'sa");
1043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SRL:
1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->RsValue() == 0) {
1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "srl     'rd, 'rt, 'sa");
1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (IsMipsArchVariant(kMips32r2)) {
1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "rotr    'rd, 'rt, 'sa");
1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Unknown(instr);
1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SRA:
1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "sra     'rd, 'rt, 'sa");
1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SLLV:
1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "sllv    'rd, 'rt, 'rs");
1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SRLV:
1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->SaValue() == 0) {
1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "srlv    'rd, 'rt, 'rs");
1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (IsMipsArchVariant(kMips32r2)) {
1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "rotrv   'rd, 'rt, 'rs");
1067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
1068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Unknown(instr);
1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SRAV:
1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "srav    'rd, 'rt, 'rs");
1074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case LSA:
1076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "lsa     'rd, 'rt, 'rs, 'sa2");
1077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MFHI:
1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->Bits(25, 16) == 0) {
1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "mfhi    'rd");
1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if ((instr->FunctionFieldRaw() == CLZ_R6) && (instr->FdValue() == 1)) {
1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "clz     'rd, 'rs");
1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else if ((instr->FunctionFieldRaw() == CLO_R6) &&
1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   (instr->FdValue() == 1)) {
1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "clo     'rd, 'rs");
1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MFLO:
1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "mflo    'rd");
1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MULT:  // @Mips32r6 == MUL_MUH.
1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!IsMipsArchVariant(kMips32r6)) {
1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "mult    'rs, 'rt");
1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (instr->SaValue() == MUL_OP) {
1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "mul    'rd, 'rs, 'rt");
1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "muh    'rd, 'rs, 'rt");
1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MULTU:  // @Mips32r6 == MUL_MUH_U.
1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!IsMipsArchVariant(kMips32r6)) {
1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "multu   'rs, 'rt");
1107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (instr->SaValue() == MUL_OP) {
1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "mulu   'rd, 'rs, 'rt");
1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "muhu   'rd, 'rs, 'rt");
1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case DIV:  // @Mips32r6 == DIV_MOD.
1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!IsMipsArchVariant(kMips32r6)) {
1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "div     'rs, 'rt");
1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (instr->SaValue() == DIV_OP) {
1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "div    'rd, 'rs, 'rt");
1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "mod    'rd, 'rs, 'rt");
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case DIVU:  // @Mips32r6 == DIV_MOD_U.
1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!IsMipsArchVariant(kMips32r6)) {
1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "divu    'rs, 'rt");
1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (instr->SaValue() == DIV_OP) {
1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "divu   'rd, 'rs, 'rt");
1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "modu   'rd, 'rs, 'rt");
1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case ADD:
1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "add     'rd, 'rs, 'rt");
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case ADDU:
1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "addu    'rd, 'rs, 'rt");
1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SUB:
1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "sub     'rd, 'rs, 'rt");
1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SUBU:
1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "subu    'rd, 'rs, 'rt");
1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case AND:
1150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "and     'rd, 'rs, 'rt");
1151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case OR:
1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (0 == instr->RsValue()) {
1154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "mov     'rd, 'rt");
1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if (0 == instr->RtValue()) {
1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "mov     'rd, 'rs");
1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "or      'rd, 'rs, 'rt");
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case XOR:
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "xor     'rd, 'rs, 'rt");
1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case NOR:
1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "nor     'rd, 'rs, 'rt");
1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SLT:
1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "slt     'rd, 'rs, 'rt");
1169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SLTU:
1171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "sltu    'rd, 'rs, 'rt");
1172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BREAK:
1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "break, code: 'code");
1175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TGE:
1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "tge     'rs, 'rt, code: 'code");
1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TGEU:
1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "tgeu    'rs, 'rt, code: 'code");
1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TLT:
1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "tlt     'rs, 'rt, code: 'code");
1184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TLTU:
1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "tltu    'rs, 'rt, code: 'code");
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TEQ:
1189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "teq     'rs, 'rt, code: 'code");
1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case TNE:
1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "tne     'rs, 'rt, code: 'code");
1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MOVZ:
1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "movz    'rd, 'rs, 'rt");
1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MOVN:
1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "movn    'rd, 'rs, 'rt");
1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MOVCI:
1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->Bit(16)) {
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "movt    'rd, 'rs, 'bc");
1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "movf    'rd, 'rs, 'bc");
1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SELEQZ_S:
1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "seleqz    'rd, 'rs, 'rt");
1209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SELNEZ_S:
1211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "selnez    'rd, 'rs, 'rt");
1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
1215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::DecodeTypeRegisterSPECIAL2(Instruction* instr) {
1220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (instr->FunctionFieldRaw()) {
1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MUL:
1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "mul     'rd, 'rs, 'rt");
1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case CLZ:
1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!IsMipsArchVariant(kMips32r6)) {
1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "clz     'rd, 'rs");
1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) {
1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (instr->FunctionFieldRaw()) {
1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case INS: {
1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "ins     'rt, 'rs, 'sa, 'ss2");
1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Unknown(instr);
1242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case EXT: {
1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "ext     'rt, 'rs, 'sa, 'ss1");
1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Unknown(instr);
1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BSHFL: {
1254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int sa = instr->SaFieldRaw() >> kSaShift;
1255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      switch (sa) {
1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case BITSWAP: {
1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (IsMipsArchVariant(kMips32r6)) {
1258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Format(instr, "bitswap 'rd, 'rt");
12593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          } else {
1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Unknown(instr);
12613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          }
12623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
1263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case SEB:
1265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case SEH:
1266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case WSBH:
1267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UNREACHABLE();
12683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        default: {
1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          sa >>= kBp2Bits;
1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          switch (sa) {
1272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            case ALIGN: {
1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              if (IsMipsArchVariant(kMips32r6)) {
1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                Format(instr, "align  'rd, 'rs, 'rt, 'bp2");
1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              } else {
1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                Unknown(instr);
1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              }
1278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              break;
1279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            default:
1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              UNREACHABLE();
1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              break;
1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid Decoder::DecodeTypeRegister(Instruction* instr) {
1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (instr->OpcodeFieldRaw()) {
1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case COP1:    // Coprocessor instructions.
1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      switch (instr->RsFieldRaw()) {
1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case BC1:   // bc1 handled in DecodeTypeImmediate.
1299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UNREACHABLE();
13003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MFC1:
1302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "mfc1    'rt, 'fs");
13033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MFHC1:
1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "mfhc1   'rt, 'fs");
13063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MTC1:
1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "mtc1    'rt, 'fs");
13093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
1310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // These are called "fs" too, although they are not FPU registers.
1311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case CTC1:
1312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "ctc1    'rt, 'fs");
13133100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
1314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case CFC1:
1315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "cfc1    'rt, 'fs");
13163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
1317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MTHC1:
1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "mthc1   'rt, 'fs");
13193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case S:
1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DecodeTypeRegisterSRsType(instr);
132244f0eee88ff00398ff7f715fab053374d808c90dSteve Block          break;
1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case D:
1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DecodeTypeRegisterDRsType(instr);
132544f0eee88ff00398ff7f715fab053374d808c90dSteve Block          break;
1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case L:
1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DecodeTypeRegisterLRsType(instr);
132844f0eee88ff00398ff7f715fab053374d808c90dSteve Block          break;
1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case W:
1330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DecodeTypeRegisterWRsType(instr);
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          break;
1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case PS:
1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UNIMPLEMENTED_MIPS();
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          break;
13353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu        default:
13363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          UNREACHABLE();
133744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      }
13383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
1339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case COP1X:
13403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      switch (instr->FunctionFieldRaw()) {
1341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case MADD_D:
1342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "madd.d  'fd, 'fr, 'fs, 'ft");
13433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
13443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu        default:
13453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          UNREACHABLE();
134644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      }
134744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      break;
1348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SPECIAL:
1349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DecodeTypeRegisterSPECIAL(instr);
1350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case SPECIAL2:
1352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DecodeTypeRegisterSPECIAL2(instr);
1353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
135444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case SPECIAL3:
1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DecodeTypeRegisterSPECIAL3(instr);
13563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
13573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    default:
13583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      UNREACHABLE();
135944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
13603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
13613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
13623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
13633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::DecodeTypeImmediate(Instruction* instr) {
13643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  switch (instr->OpcodeFieldRaw()) {
136544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case COP1:
136644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      switch (instr->RsFieldRaw()) {
136744f0eee88ff00398ff7f715fab053374d808c90dSteve Block        case BC1:
136844f0eee88ff00398ff7f715fab053374d808c90dSteve Block          if (instr->FBtrueValue()) {
1369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Format(instr, "bc1t    'bc, 'imm16u -> 'imm16p4s2");
137044f0eee88ff00398ff7f715fab053374d808c90dSteve Block          } else {
1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Format(instr, "bc1f    'bc, 'imm16u -> 'imm16p4s2");
137244f0eee88ff00398ff7f715fab053374d808c90dSteve Block          }
137344f0eee88ff00398ff7f715fab053374d808c90dSteve Block          break;
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case BC1EQZ:
1375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "bc1eqz    'ft, 'imm16u -> 'imm16p4s2");
1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          break;
1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case BC1NEZ:
1378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "bc1nez    'ft, 'imm16u -> 'imm16p4s2");
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          break;
138044f0eee88ff00398ff7f715fab053374d808c90dSteve Block        default:
138144f0eee88ff00398ff7f715fab053374d808c90dSteve Block          UNREACHABLE();
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
138444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      break;  // Case COP1.
1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // ------------- REGIMM class.
13863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case REGIMM:
13873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      switch (instr->RtFieldRaw()) {
13883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu        case BLTZ:
1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "bltz    'rs, 'imm16u -> 'imm16p4s2");
13903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
13913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu        case BLTZAL:
1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "bltzal  'rs, 'imm16u -> 'imm16p4s2");
13933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
13943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu        case BGEZ:
1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "bgez    'rs, 'imm16u -> 'imm16p4s2");
13963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case BGEZAL: {
1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (instr->RsValue() == 0)
1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Format(instr, "bal     'imm16s -> 'imm16p4s2");
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          else
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Format(instr, "bgezal  'rs, 'imm16u -> 'imm16p4s2");
14023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          break;
1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        case BGEZALL:
1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "bgezall 'rs, 'imm16u -> 'imm16p4s2");
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          break;
14073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu        default:
14083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu          UNREACHABLE();
140944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      }
141044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    break;  // Case REGIMM.
14113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    // ------------- Branch instructions.
14123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case BEQ:
1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "beq     'rs, 'rt, 'imm16u -> 'imm16p4s2");
1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BC:
1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "bc      'imm26s -> 'imm26p4s2");
1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case BALC:
1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "balc    'imm26s -> 'imm26p4s2");
14203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
14213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case BNE:
1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "bne     'rs, 'rt, 'imm16u -> 'imm16p4s2");
14233100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
14243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case BLEZ:
1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) {
1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "blez    'rs, 'imm16u -> 'imm16p4s2");
1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if ((instr->RtValue() != instr->RsValue()) &&
1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "bgeuc   'rs, 'rt, 'imm16u -> 'imm16p4s2");
1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if ((instr->RtValue() == instr->RsValue()) &&
1431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 (instr->RtValue() != 0)) {
1432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2");
1433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
1434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2");
1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UNREACHABLE();
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
14383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
14393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case BGTZ:
1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) {
1441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "bgtz    'rs, 'imm16u -> 'imm16p4s2");
1442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if ((instr->RtValue() != instr->RsValue()) &&
1443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "bltuc   'rs, 'rt, 'imm16u -> 'imm16p4s2");
1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if ((instr->RtValue() == instr->RsValue()) &&
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 (instr->RtValue() != 0)) {
1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "bltzalc 'rt, 'imm16u -> 'imm16p4s2");
1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
1449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "bgtzalc 'rt, 'imm16u -> 'imm16p4s2");
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UNREACHABLE();
1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case BLEZL:
1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) {
1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "bgezc    'rt, 'imm16u -> 'imm16p4s2");
1457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if ((instr->RtValue() != instr->RsValue()) &&
1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "bgec     'rs, 'rt, 'imm16u -> 'imm16p4s2");
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "blezc    'rt, 'imm16u -> 'imm16p4s2");
1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UNREACHABLE();
1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case BGTZL:
1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) {
1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "bltzc    'rt, 'imm16u -> 'imm16p4s2");
1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if ((instr->RtValue() != instr->RsValue()) &&
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 (instr->RsValue() != 0) && (instr->RtValue() != 0)) {
1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "bltc    'rs, 'rt, 'imm16u -> 'imm16p4s2");
1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) {
1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "bgtzc    'rt, 'imm16u -> 'imm16p4s2");
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UNREACHABLE();
1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case POP66:
1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->RsValue() == JIC) {
1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "jic     'rt, 'imm16s");
1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "beqzc   'rs, 'imm21s -> 'imm21p4s2");
1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case POP76:
1486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->RsValue() == JIALC) {
1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "jialc   'rt, 'imm16s");
1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Format(instr, "bnezc   'rs, 'imm21s -> 'imm21p4s2");
1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
14913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
14923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    // ------------- Arithmetic instructions.
14933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case ADDI:
1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!IsMipsArchVariant(kMips32r6)) {
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Format(instr, "addi    'rt, 'rs, 'imm16s");
1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int rs_reg = instr->RsValue();
1498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int rt_reg = instr->RtValue();
1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Check if BOVC, BEQZALC or BEQC instruction.
1500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (rs_reg >= rt_reg) {
1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "bovc  'rs, 'rt, 'imm16s -> 'imm16p4s2");
1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (rs_reg == 0) {
1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Format(instr, "beqzalc 'rt, 'imm16s -> 'imm16p4s2");
1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else {
1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Format(instr, "beqc    'rs, 'rt, 'imm16s -> 'imm16p4s2");
1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case DADDI:
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (IsMipsArchVariant(kMips32r6)) {
1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int rs_reg = instr->RsValue();
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int rt_reg = instr->RtValue();
1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Check if BNVC, BNEZALC or BNEC instruction.
1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (rs_reg >= rt_reg) {
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "bnvc  'rs, 'rt, 'imm16s -> 'imm16p4s2");
1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (rs_reg == 0) {
1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Format(instr, "bnezalc 'rt, 'imm16s -> 'imm16p4s2");
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else {
1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Format(instr, "bnec  'rs, 'rt, 'imm16s -> 'imm16p4s2");
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
15263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
15273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case ADDIU:
1528257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "addiu   'rt, 'rs, 'imm16s");
15293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
15303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case SLTI:
1531257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "slti    'rt, 'rs, 'imm16s");
15323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
15333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case SLTIU:
1534257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "sltiu   'rt, 'rs, 'imm16u");
15353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
15363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case ANDI:
1537257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "andi    'rt, 'rs, 'imm16x");
15383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
15393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case ORI:
1540257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "ori     'rt, 'rs, 'imm16x");
15413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
15423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case XORI:
1543257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "xori    'rt, 'rs, 'imm16x");
15443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
15453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case LUI:
1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!IsMipsArchVariant(kMips32r6)) {
1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Format(instr, "lui     'rt, 'imm16x");
1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (instr->RsValue() != 0) {
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "aui     'rt, 'rs, 'imm16x");
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Format(instr, "lui     'rt, 'imm16x");
1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
15553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
15563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    // ------------- Memory instructions.
15573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case LB:
1558257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "lb      'rt, 'imm16s('rs)");
15593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
156044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case LH:
1561257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "lh      'rt, 'imm16s('rs)");
156244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      break;
156344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case LWL:
1564257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "lwl     'rt, 'imm16s('rs)");
156544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      break;
15663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case LW:
1567257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "lw      'rt, 'imm16s('rs)");
15683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
15693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case LBU:
1570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "lbu     'rt, 'imm16s('rs)");
15713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
157244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case LHU:
1573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "lhu     'rt, 'imm16s('rs)");
157444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      break;
157544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case LWR:
1576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "lwr     'rt, 'imm16s('rs)");
157744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      break;
1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case PREF:
1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Format(instr, "pref    'rt, 'imm16s('rs)");
1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
15813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case SB:
1582257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "sb      'rt, 'imm16s('rs)");
15833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
158444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case SH:
1585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "sh      'rt, 'imm16s('rs)");
158644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      break;
158744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case SWL:
1588257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "swl     'rt, 'imm16s('rs)");
158944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      break;
15903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case SW:
1591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "sw      'rt, 'imm16s('rs)");
15923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
159344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    case SWR:
1594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "swr     'rt, 'imm16s('rs)");
159544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      break;
15963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case LWC1:
1597257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "lwc1    'ft, 'imm16s('rs)");
15983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
15993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case LDC1:
1600257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "ldc1    'ft, 'imm16s('rs)");
16013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
16023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case SWC1:
1603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "swc1    'ft, 'imm16s('rs)");
16043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
16053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case SDC1:
1606257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Format(instr, "sdc1    'ft, 'imm16s('rs)");
16073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case PCREL: {
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int32_t imm21 = instr->Imm21Value();
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // rt field: 5-bits checking
1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint8_t rt = (imm21 >> kImm16Bits);
1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      switch (rt) {
1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case ALUIPC:
1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "aluipc  'rs, 'imm16s");
1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case AUIPC:
1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Format(instr, "auipc   'rs, 'imm16s");
1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        default: {
1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // rt field: checking of the most significant 2-bits
1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          rt = (imm21 >> kImm19Bits);
1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          switch (rt) {
1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            case LWPC:
1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              Format(instr, "lwpc    'rs, 'imm19s");
1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              break;
1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            case ADDIUPC:
1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              Format(instr, "addiupc 'rs, 'imm19s");
1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              break;
1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            default:
1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              UNREACHABLE();
1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              break;
1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
16373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    default:
1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      printf("a 0x%x \n", instr->OpcodeFieldRaw());
16393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      UNREACHABLE();
16403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
16423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
16433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
16443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
16453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid Decoder::DecodeTypeJump(Instruction* instr) {
16463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  switch (instr->OpcodeFieldRaw()) {
16473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case J:
1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "j       'imm26x -> 'imm26j");
16493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
16503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case JAL:
1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Format(instr, "jal     'imm26x -> 'imm26j");
16523100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
16533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    default:
16543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      UNREACHABLE();
16553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
16563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
16573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
16583100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
16593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Disassemble the instruction at *instr_ptr into the output buffer.
1660257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochint Decoder::InstructionDecode(byte* instr_ptr) {
16613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Instruction* instr = Instruction::At(instr_ptr);
16623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Print raw instruction bytes.
1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   "%08x       ",
1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   instr->InstructionBits());
1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (instr->InstructionType(Instruction::EXTRA)) {
16673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case Instruction::kRegisterType: {
16683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      DecodeTypeRegister(instr);
16693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
16703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
16713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case Instruction::kImmediateType: {
16723100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      DecodeTypeImmediate(instr);
16733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
16743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
16753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    case Instruction::kJumpType: {
16763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      DecodeTypeJump(instr);
16773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      break;
16783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
16793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    default: {
1680589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Format(instr, "UNSUPPORTED");
16813100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      UNSUPPORTED_MIPS();
16823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
16833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
168444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return Instruction::kInstrSize;
16853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
16863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
16873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
1689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
16903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
16913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
16923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//------------------------------------------------------------------------------
16933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
16943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescunamespace disasm {
16953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1696257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochconst char* NameConverter::NameOfAddress(byte* addr) const {
1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::internal::SNPrintF(tmp_buffer_, "%p", addr);
169844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return tmp_buffer_.start();
16993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
17003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1702257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochconst char* NameConverter::NameOfConstant(byte* addr) const {
17033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return NameOfAddress(addr);
17043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
17053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuconst char* NameConverter::NameOfCPURegister(int reg) const {
170844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return v8::internal::Registers::Name(reg);
17093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
17103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuconst char* NameConverter::NameOfXMMRegister(int reg) const {
171344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return v8::internal::FPURegisters::Name(reg);
17143100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
17153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17163100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17173100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuconst char* NameConverter::NameOfByteCPURegister(int reg) const {
1718257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  UNREACHABLE();  // MIPS does not have the concept of a byte register.
17193100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return "nobytereg";
17203100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
17213100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17223100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1723257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochconst char* NameConverter::NameInCode(byte* addr) const {
17243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // The default name converter is called for unknown code. So we will not try
17253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // to access any memory.
17263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return "";
17273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
17283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//------------------------------------------------------------------------------
17313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuDisassembler::Disassembler(const NameConverter& converter)
17333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    : converter_(converter) {}
17343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuDisassembler::~Disassembler() {}
17373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuint Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
1740257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    byte* instruction) {
174144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::internal::Decoder d(converter_, buffer);
17423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return d.InstructionDecode(instruction);
17433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
17443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
174644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// The MIPS assembler does not currently use constant pools.
1747257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochint Disassembler::ConstantPoolSizeAt(byte* instruction) {
17483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return -1;
17493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
17503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17513100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1752257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
17533100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  NameConverter converter;
17543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Disassembler d(converter);
1755257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  for (byte* pc = begin; pc < end;) {
17563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    v8::internal::EmbeddedVector<char, 128> buffer;
17573100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    buffer[0] = '\0';
1758257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    byte* prev_pc = pc;
17593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    pc += d.InstructionDecode(buffer, pc);
1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::internal::PrintF(f, "%p    %08x      %s\n",
1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
17623100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
17633100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
17643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
176544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
17663100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu#undef UNSUPPORTED
17673100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
17683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}  // namespace disasm
17693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
1770f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif  // V8_TARGET_ARCH_MIPS
1771