13233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
45c838251403b0be9a882540f1922577abba4c872ager@chromium.org
55c838251403b0be9a882540f1922577abba4c872ager@chromium.org// A Disassembler object is used to disassemble a block of code instruction by
65c838251403b0be9a882540f1922577abba4c872ager@chromium.org// instruction. The default implementation of the NameConverter object can be
75c838251403b0be9a882540f1922577abba4c872ager@chromium.org// overriden to modify register names or to do symbol lookup on addresses.
85c838251403b0be9a882540f1922577abba4c872ager@chromium.org//
95c838251403b0be9a882540f1922577abba4c872ager@chromium.org// The example below will disassemble a block of code and print it to stdout.
105c838251403b0be9a882540f1922577abba4c872ager@chromium.org//
115c838251403b0be9a882540f1922577abba4c872ager@chromium.org//   NameConverter converter;
125c838251403b0be9a882540f1922577abba4c872ager@chromium.org//   Disassembler d(converter);
1383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org//   for (byte* pc = begin; pc < end;) {
147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//     v8::internal::EmbeddedVector<char, 256> buffer;
157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//     byte* prev_pc = pc;
167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//     pc += d.InstructionDecode(buffer, pc);
175c838251403b0be9a882540f1922577abba4c872ager@chromium.org//     printf("%p    %08x      %s\n",
185c838251403b0be9a882540f1922577abba4c872ager@chromium.org//            prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
195c838251403b0be9a882540f1922577abba4c872ager@chromium.org//   }
205c838251403b0be9a882540f1922577abba4c872ager@chromium.org//
215c838251403b0be9a882540f1922577abba4c872ager@chromium.org// The Disassembler class also has a convenience method to disassemble a block
225c838251403b0be9a882540f1922577abba4c872ager@chromium.org// of code into a FILE*, meaning that the above functionality could also be
235c838251403b0be9a882540f1922577abba4c872ager@chromium.org// achieved by just calling Disassembler::Disassemble(stdout, begin, end);
245c838251403b0be9a882540f1922577abba4c872ager@chromium.org
255c838251403b0be9a882540f1922577abba4c872ager@chromium.org
265c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include <assert.h>
275c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include <stdarg.h>
284b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include <stdio.h>
295c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include <string.h>
305c838251403b0be9a882540f1922577abba4c872ager@chromium.org
31196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
325c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS
349dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
355de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org#include "src/base/platform/platform.h"
36196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/disasm.h"
37196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/macro-assembler.h"
384b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/mips/constants-mips.h"
395c838251403b0be9a882540f1922577abba4c872ager@chromium.org
407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgnamespace v8 {
417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgnamespace internal {
425c838251403b0be9a882540f1922577abba4c872ager@chromium.org
435c838251403b0be9a882540f1922577abba4c872ager@chromium.org//------------------------------------------------------------------------------
445c838251403b0be9a882540f1922577abba4c872ager@chromium.org
455c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Decoder decodes and disassembles instructions into an output buffer.
465c838251403b0be9a882540f1922577abba4c872ager@chromium.org// It uses the converter to convert register names and call destinations into
475c838251403b0be9a882540f1922577abba4c872ager@chromium.org// more informative description.
485c838251403b0be9a882540f1922577abba4c872ager@chromium.orgclass Decoder {
495c838251403b0be9a882540f1922577abba4c872ager@chromium.org public:
505c838251403b0be9a882540f1922577abba4c872ager@chromium.org  Decoder(const disasm::NameConverter& converter,
515c838251403b0be9a882540f1922577abba4c872ager@chromium.org          v8::internal::Vector<char> out_buffer)
525c838251403b0be9a882540f1922577abba4c872ager@chromium.org    : converter_(converter),
535c838251403b0be9a882540f1922577abba4c872ager@chromium.org      out_buffer_(out_buffer),
545c838251403b0be9a882540f1922577abba4c872ager@chromium.org      out_buffer_pos_(0) {
555c838251403b0be9a882540f1922577abba4c872ager@chromium.org    out_buffer_[out_buffer_pos_] = '\0';
565c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
575c838251403b0be9a882540f1922577abba4c872ager@chromium.org
585c838251403b0be9a882540f1922577abba4c872ager@chromium.org  ~Decoder() {}
595c838251403b0be9a882540f1922577abba4c872ager@chromium.org
605c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Writes one disassembled instruction into 'buffer' (0-terminated).
615c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Returns the length of the disassembled machine instruction in bytes.
6283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  int InstructionDecode(byte* instruction);
635c838251403b0be9a882540f1922577abba4c872ager@chromium.org
645c838251403b0be9a882540f1922577abba4c872ager@chromium.org private:
655c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Bottleneck functions to print into the out_buffer.
665c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintChar(const char ch);
675c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void Print(const char* str);
685c838251403b0be9a882540f1922577abba4c872ager@chromium.org
695c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Printing of common values.
705c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintRegister(int reg);
717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void PrintFPURegister(int freg);
725c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintRs(Instruction* instr);
735c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintRt(Instruction* instr);
745c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintRd(Instruction* instr);
755c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintFs(Instruction* instr);
765c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintFt(Instruction* instr);
775c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintFd(Instruction* instr);
785c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintSa(Instruction* instr);
797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void PrintSd(Instruction* instr);
8083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void PrintSs1(Instruction* instr);
8183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void PrintSs2(Instruction* instr);
827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void PrintBc(Instruction* instr);
837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void PrintCc(Instruction* instr);
845c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintFunction(Instruction* instr);
855c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintSecondaryField(Instruction* instr);
865c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintUImm16(Instruction* instr);
875c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintSImm16(Instruction* instr);
885c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintXImm16(Instruction* instr);
895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  void PrintXImm21(Instruction* instr);
9034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  void PrintXImm26(Instruction* instr);
915c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintCode(Instruction* instr);   // For break and trap instructions.
925c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Printing of instruction name.
935c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PrintInstructionName(Instruction* instr);
945c838251403b0be9a882540f1922577abba4c872ager@chromium.org
955c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Handle formatting of instructions and their options.
965c838251403b0be9a882540f1922577abba4c872ager@chromium.org  int FormatRegister(Instruction* instr, const char* option);
977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int FormatFPURegister(Instruction* instr, const char* option);
985c838251403b0be9a882540f1922577abba4c872ager@chromium.org  int FormatOption(Instruction* instr, const char* option);
995c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void Format(Instruction* instr, const char* format);
1005c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void Unknown(Instruction* instr);
1015c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1025c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Each of these functions decodes one particular instruction type.
1035c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void DecodeTypeRegister(Instruction* instr);
1045c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void DecodeTypeImmediate(Instruction* instr);
1055c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void DecodeTypeJump(Instruction* instr);
1065c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1075c838251403b0be9a882540f1922577abba4c872ager@chromium.org  const disasm::NameConverter& converter_;
1085c838251403b0be9a882540f1922577abba4c872ager@chromium.org  v8::internal::Vector<char> out_buffer_;
1095c838251403b0be9a882540f1922577abba4c872ager@chromium.org  int out_buffer_pos_;
1105c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1115c838251403b0be9a882540f1922577abba4c872ager@chromium.org  DISALLOW_COPY_AND_ASSIGN(Decoder);
1125c838251403b0be9a882540f1922577abba4c872ager@chromium.org};
1135c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1145c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1155c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Support for assertions in the Decoder formatting functions.
1165c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define STRING_STARTS_WITH(string, compare_string) \
1175c838251403b0be9a882540f1922577abba4c872ager@chromium.org  (strncmp(string, compare_string, strlen(compare_string)) == 0)
1185c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1195c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1205c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Append the ch to the output buffer.
1215c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintChar(const char ch) {
1225c838251403b0be9a882540f1922577abba4c872ager@chromium.org  out_buffer_[out_buffer_pos_++] = ch;
1235c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1245c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1255c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1265c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Append the str to the output buffer.
1275c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::Print(const char* str) {
1285c838251403b0be9a882540f1922577abba4c872ager@chromium.org  char cur = *str++;
1295c838251403b0be9a882540f1922577abba4c872ager@chromium.org  while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
1305c838251403b0be9a882540f1922577abba4c872ager@chromium.org    PrintChar(cur);
1315c838251403b0be9a882540f1922577abba4c872ager@chromium.org    cur = *str++;
1325c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
1335c838251403b0be9a882540f1922577abba4c872ager@chromium.org  out_buffer_[out_buffer_pos_] = 0;
1345c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1355c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1365c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1375c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Print the register name according to the active name converter.
1385c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintRegister(int reg) {
1395c838251403b0be9a882540f1922577abba4c872ager@chromium.org  Print(converter_.NameOfCPURegister(reg));
1405c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1415c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1425c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1435c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintRs(Instruction* instr) {
1447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int reg = instr->RsValue();
1455c838251403b0be9a882540f1922577abba4c872ager@chromium.org  PrintRegister(reg);
1465c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1475c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1485c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1495c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintRt(Instruction* instr) {
1507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int reg = instr->RtValue();
1515c838251403b0be9a882540f1922577abba4c872ager@chromium.org  PrintRegister(reg);
1525c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1535c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1545c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1555c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintRd(Instruction* instr) {
1567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int reg = instr->RdValue();
1575c838251403b0be9a882540f1922577abba4c872ager@chromium.org  PrintRegister(reg);
1585c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1595c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1605c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Print the FPUregister name according to the active name converter.
1627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Decoder::PrintFPURegister(int freg) {
1637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Print(converter_.NameOfXMMRegister(freg));
1645c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1655c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1665c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1675c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintFs(Instruction* instr) {
1687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int freg = instr->RsValue();
1697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  PrintFPURegister(freg);
1705c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1715c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1725c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1735c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintFt(Instruction* instr) {
1747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int freg = instr->RtValue();
1757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  PrintFPURegister(freg);
1765c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1775c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1785c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1795c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintFd(Instruction* instr) {
1807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int freg = instr->RdValue();
1817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  PrintFPURegister(freg);
1825c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1835c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1845c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1855c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Print the integer value of the sa field.
1865c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintSa(Instruction* instr) {
1877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int sa = instr->SaValue();
18870ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa);
1897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
1907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
19283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org// Print the integer value of the rd field, when it is not used as reg.
1937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Decoder::PrintSd(Instruction* instr) {
1947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int sd = instr->RdValue();
19570ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sd);
1967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
1977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
19983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org// Print the integer value of the rd field, when used as 'ext' size.
20083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid Decoder::PrintSs1(Instruction* instr) {
20183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  int ss = instr->RdValue();
20270ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss + 1);
20383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
20483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
20583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
20683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org// Print the integer value of the rd field, when used as 'ins' size.
20783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid Decoder::PrintSs2(Instruction* instr) {
20883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  int ss = instr->RdValue();
20983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  int pos = instr->SaValue();
21083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  out_buffer_pos_ +=
21170ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org      SNPrintF(out_buffer_ + out_buffer_pos_, "%d", ss - pos + 1);
21283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org}
21383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
21483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
2157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Print the integer value of the cc field for the bc1t/f instructions.
2167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Decoder::PrintBc(Instruction* instr) {
2177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int cc = instr->FBccValue();
21870ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", cc);
2197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
2207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Print the integer value of the cc field for the FP compare instructions.
2237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Decoder::PrintCc(Instruction* instr) {
2247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int cc = instr->FCccValue();
22570ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "cc(%d)", cc);
2265c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
2275c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2285c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2295c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Print 16-bit unsigned immediate value.
2305c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintUImm16(Instruction* instr) {
2317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int32_t imm = instr->Imm16Value();
23270ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm);
2335c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
2345c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2355c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2365c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Print 16-bit signed immediate value.
2375c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintSImm16(Instruction* instr) {
23883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  int32_t imm = ((instr->Imm16Value()) << 16) >> 16;
23970ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
2405c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
2415c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2425c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2435c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Print 16-bit hexa immediate value.
2445c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintXImm16(Instruction* instr) {
2457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int32_t imm = instr->Imm16Value();
24670ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
2475c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
2485c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2495c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2505e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org// Print 21-bit immediate value.
2515e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid Decoder::PrintXImm21(Instruction* instr) {
2525e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  uint32_t imm = instr->Imm21Value();
2535e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
2545e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
2555e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
2565e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
2575c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Print 26-bit immediate value.
25834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgvoid Decoder::PrintXImm26(Instruction* instr) {
25934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  uint32_t imm = instr->Imm26Value() << kImmFieldShift;
26070ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
2615c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
2625c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2635c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2645c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Print 26-bit immediate value.
2655c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintCode(Instruction* instr) {
2665c838251403b0be9a882540f1922577abba4c872ager@chromium.org  if (instr->OpcodeFieldRaw() != SPECIAL)
2675c838251403b0be9a882540f1922577abba4c872ager@chromium.org    return;  // Not a break or trap instruction.
2685c838251403b0be9a882540f1922577abba4c872ager@chromium.org  switch (instr->FunctionFieldRaw()) {
2695c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case BREAK: {
2705c838251403b0be9a882540f1922577abba4c872ager@chromium.org      int32_t code = instr->Bits(25, 6);
27170ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org      out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
27270ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org                                  "0x%05x (%d)", code, code);
2735c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
2745c838251403b0be9a882540f1922577abba4c872ager@chromium.org                }
2755c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case TGE:
2765c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case TGEU:
2775c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case TLT:
2785c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case TLTU:
2795c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case TEQ:
2805c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case TNE: {
2815c838251403b0be9a882540f1922577abba4c872ager@chromium.org      int32_t code = instr->Bits(15, 6);
2825c838251403b0be9a882540f1922577abba4c872ager@chromium.org      out_buffer_pos_ +=
28370ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org          SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code);
2845c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
2855c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
2865c838251403b0be9a882540f1922577abba4c872ager@chromium.org    default:  // Not a break or trap instruction.
2875c838251403b0be9a882540f1922577abba4c872ager@chromium.org    break;
2883c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  }
2895c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
2905c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2915c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2925c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Printing of instruction name.
2935c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::PrintInstructionName(Instruction* instr) {
2945c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
2955c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2965c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2975c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Handle all register based formatting in this function to reduce the
2985c838251403b0be9a882540f1922577abba4c872ager@chromium.org// complexity of FormatOption.
2995c838251403b0be9a882540f1922577abba4c872ager@chromium.orgint Decoder::FormatRegister(Instruction* instr, const char* format) {
300e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(format[0] == 'r');
30183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (format[1] == 's') {  // 'rs: Rs register.
3027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    int reg = instr->RsValue();
3035c838251403b0be9a882540f1922577abba4c872ager@chromium.org    PrintRegister(reg);
3045c838251403b0be9a882540f1922577abba4c872ager@chromium.org    return 2;
30583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else if (format[1] == 't') {  // 'rt: rt register.
3067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    int reg = instr->RtValue();
3075c838251403b0be9a882540f1922577abba4c872ager@chromium.org    PrintRegister(reg);
3085c838251403b0be9a882540f1922577abba4c872ager@chromium.org    return 2;
30983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else if (format[1] == 'd') {  // 'rd: rd register.
3107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    int reg = instr->RdValue();
3115c838251403b0be9a882540f1922577abba4c872ager@chromium.org    PrintRegister(reg);
3125c838251403b0be9a882540f1922577abba4c872ager@chromium.org    return 2;
3135c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
3145c838251403b0be9a882540f1922577abba4c872ager@chromium.org  UNREACHABLE();
3155c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return -1;
3165c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
3175c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3185c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Handle all FPUregister based formatting in this function to reduce the
3205c838251403b0be9a882540f1922577abba4c872ager@chromium.org// complexity of FormatOption.
3217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgint Decoder::FormatFPURegister(Instruction* instr, const char* format) {
322e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(format[0] == 'f');
32383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  if (format[1] == 's') {  // 'fs: fs register.
3247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    int reg = instr->FsValue();
3257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    PrintFPURegister(reg);
3265c838251403b0be9a882540f1922577abba4c872ager@chromium.org    return 2;
32783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else if (format[1] == 't') {  // 'ft: ft register.
3287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    int reg = instr->FtValue();
3297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    PrintFPURegister(reg);
3305c838251403b0be9a882540f1922577abba4c872ager@chromium.org    return 2;
33183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  } else if (format[1] == 'd') {  // 'fd: fd register.
3327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    int reg = instr->FdValue();
3337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    PrintFPURegister(reg);
3345c838251403b0be9a882540f1922577abba4c872ager@chromium.org    return 2;
33559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  } else if (format[1] == 'r') {  // 'fr: fr register.
33659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    int reg = instr->FrValue();
33759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    PrintFPURegister(reg);
33859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return 2;
3395c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
3405c838251403b0be9a882540f1922577abba4c872ager@chromium.org  UNREACHABLE();
3415c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return -1;
3425c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
3435c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3445c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3455c838251403b0be9a882540f1922577abba4c872ager@chromium.org// FormatOption takes a formatting string and interprets it based on
3465c838251403b0be9a882540f1922577abba4c872ager@chromium.org// the current instructions. The format string points to the first
3475c838251403b0be9a882540f1922577abba4c872ager@chromium.org// character of the option string (the option escape has already been
3485c838251403b0be9a882540f1922577abba4c872ager@chromium.org// consumed by the caller.)  FormatOption returns the number of
3495c838251403b0be9a882540f1922577abba4c872ager@chromium.org// characters that were consumed from the formatting string.
3505c838251403b0be9a882540f1922577abba4c872ager@chromium.orgint Decoder::FormatOption(Instruction* instr, const char* format) {
3515c838251403b0be9a882540f1922577abba4c872ager@chromium.org  switch (format[0]) {
35283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    case 'c': {   // 'code for break or trap instructions.
353e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(STRING_STARTS_WITH(format, "code"));
3545c838251403b0be9a882540f1922577abba4c872ager@chromium.org      PrintCode(instr);
3555c838251403b0be9a882540f1922577abba4c872ager@chromium.org      return 4;
3565c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
35783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    case 'i': {   // 'imm16u or 'imm26.
3585c838251403b0be9a882540f1922577abba4c872ager@chromium.org      if (format[3] == '1') {
359e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(STRING_STARTS_WITH(format, "imm16"));
3605c838251403b0be9a882540f1922577abba4c872ager@chromium.org        if (format[5] == 's') {
361e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(STRING_STARTS_WITH(format, "imm16s"));
3625c838251403b0be9a882540f1922577abba4c872ager@chromium.org          PrintSImm16(instr);
3635c838251403b0be9a882540f1922577abba4c872ager@chromium.org        } else if (format[5] == 'u') {
364e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(STRING_STARTS_WITH(format, "imm16u"));
3655c838251403b0be9a882540f1922577abba4c872ager@chromium.org          PrintSImm16(instr);
3665c838251403b0be9a882540f1922577abba4c872ager@chromium.org        } else {
367e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(STRING_STARTS_WITH(format, "imm16x"));
3685c838251403b0be9a882540f1922577abba4c872ager@chromium.org          PrintXImm16(instr);
3695c838251403b0be9a882540f1922577abba4c872ager@chromium.org        }
3705c838251403b0be9a882540f1922577abba4c872ager@chromium.org        return 6;
3715e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else if (format[3] == '2' && format[4] == '1') {
3725e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        DCHECK(STRING_STARTS_WITH(format, "imm21x"));
3735e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        PrintXImm21(instr);
3745e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        return 6;
3755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else if (format[3] == '2' && format[4] == '6') {
376e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(STRING_STARTS_WITH(format, "imm26x"));
37734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org        PrintXImm26(instr);
37834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org        return 6;
3795c838251403b0be9a882540f1922577abba4c872ager@chromium.org      }
3805c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
38183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    case 'r': {   // 'r: registers.
3825c838251403b0be9a882540f1922577abba4c872ager@chromium.org      return FormatRegister(instr, format);
3835c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
38483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    case 'f': {   // 'f: FPUregisters.
3857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      return FormatFPURegister(instr, format);
3865c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
38783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    case 's': {   // 'sa.
3887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      switch (format[1]) {
3897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        case 'a': {
390e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(STRING_STARTS_WITH(format, "sa"));
3917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          PrintSa(instr);
3927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          return 2;
3937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        }
3947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        case 'd': {
395e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          DCHECK(STRING_STARTS_WITH(format, "sd"));
3967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          PrintSd(instr);
3977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          return 2;
3987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        }
39983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        case 's': {
40083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          if (format[2] == '1') {
401e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org              DCHECK(STRING_STARTS_WITH(format, "ss1"));  /* ext size */
40283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              PrintSs1(instr);
40383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              return 3;
40483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          } else {
405e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org              DCHECK(STRING_STARTS_WITH(format, "ss2"));  /* ins size */
40683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              PrintSs2(instr);
40783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              return 3;
40883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          }
40983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org        }
4107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      }
4117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    }
4127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    case 'b': {   // 'bc - Special for bc1 cc field.
413e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(STRING_STARTS_WITH(format, "bc"));
4147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      PrintBc(instr);
4157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      return 2;
4167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    }
4177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    case 'C': {   // 'Cc - Special for c.xx.d cc field.
418e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(STRING_STARTS_WITH(format, "Cc"));
4197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      PrintCc(instr);
4205c838251403b0be9a882540f1922577abba4c872ager@chromium.org      return 2;
4215c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
4223c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  }
4235c838251403b0be9a882540f1922577abba4c872ager@chromium.org  UNREACHABLE();
4245c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return -1;
4255c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
4265c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4275c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4285c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Format takes a formatting string for a whole instruction and prints it into
4295c838251403b0be9a882540f1922577abba4c872ager@chromium.org// the output buffer. All escaped options are handed to FormatOption to be
4305c838251403b0be9a882540f1922577abba4c872ager@chromium.org// parsed further.
4315c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::Format(Instruction* instr, const char* format) {
4325c838251403b0be9a882540f1922577abba4c872ager@chromium.org  char cur = *format++;
4335c838251403b0be9a882540f1922577abba4c872ager@chromium.org  while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
4345c838251403b0be9a882540f1922577abba4c872ager@chromium.org    if (cur == '\'') {  // Single quote is used as the formatting escape.
4355c838251403b0be9a882540f1922577abba4c872ager@chromium.org      format += FormatOption(instr, format);
4365c838251403b0be9a882540f1922577abba4c872ager@chromium.org    } else {
4375c838251403b0be9a882540f1922577abba4c872ager@chromium.org      out_buffer_[out_buffer_pos_++] = cur;
4385c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
4395c838251403b0be9a882540f1922577abba4c872ager@chromium.org    cur = *format++;
4405c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
4415c838251403b0be9a882540f1922577abba4c872ager@chromium.org  out_buffer_[out_buffer_pos_]  = '\0';
4425c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
4435c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4445c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4455c838251403b0be9a882540f1922577abba4c872ager@chromium.org// For currently unimplemented decodings the disassembler calls Unknown(instr)
4465c838251403b0be9a882540f1922577abba4c872ager@chromium.org// which will just print "unknown" of the instruction bits.
4475c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::Unknown(Instruction* instr) {
4485c838251403b0be9a882540f1922577abba4c872ager@chromium.org  Format(instr, "unknown");
4495c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
4505c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4515c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4525c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::DecodeTypeRegister(Instruction* instr) {
4535c838251403b0be9a882540f1922577abba4c872ager@chromium.org  switch (instr->OpcodeFieldRaw()) {
45483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    case COP1:    // Coprocessor instructions.
4555c838251403b0be9a882540f1922577abba4c872ager@chromium.org      switch (instr->RsFieldRaw()) {
4567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        case BC1:   // bc1 handled in DecodeTypeImmediate.
4575c838251403b0be9a882540f1922577abba4c872ager@chromium.org          UNREACHABLE();
4585c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
4595c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case MFC1:
46083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "mfc1    'rt, 'fs");
4615c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
4625c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case MFHC1:
46383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "mfhc1   'rt, 'fs");
4645c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
4655c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case MTC1:
46683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "mtc1    'rt, 'fs");
4677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          break;
4687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        // These are called "fs" too, although they are not FPU registers.
4697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        case CTC1:
47083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "ctc1    'rt, 'fs");
4717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          break;
4727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        case CFC1:
47383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "cfc1    'rt, 'fs");
4745c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
4755c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case MTHC1:
47683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "mthc1   'rt, 'fs");
4775c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
4785c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case D:
4797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          switch (instr->FunctionFieldRaw()) {
4807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case ADD_D:
4817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "add.d   'fd, 'fs, 'ft");
4827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
4837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case SUB_D:
4847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "sub.d   'fd, 'fs, 'ft");
4857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
4867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case MUL_D:
4877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "mul.d   'fd, 'fs, 'ft");
4887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
4897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case DIV_D:
4907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "div.d   'fd, 'fs, 'ft");
4917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
4927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case ABS_D:
4937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "abs.d   'fd, 'fs");
4947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
4957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case MOV_D:
4967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "mov.d   'fd, 'fs");
4977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
4987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case NEG_D:
4997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "neg.d   'fd, 'fs");
5007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case SQRT_D:
50283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Format(instr, "sqrt.d  'fd, 'fs");
5037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case CVT_W_D:
5057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "cvt.w.d 'fd, 'fs");
5067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CVT_L_D:
5085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cvt.l.d 'fd, 'fs");
5097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case TRUNC_W_D:
5117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "trunc.w.d 'fd, 'fs");
5127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case TRUNC_L_D:
5145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "trunc.l.d 'fd, 'fs");
5157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case ROUND_W_D:
5177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "round.w.d 'fd, 'fs");
5187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case FLOOR_W_D:
5207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "floor.w.d 'fd, 'fs");
5217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case CEIL_W_D:
5237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "ceil.w.d 'fd, 'fs");
5247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case CVT_S_D:
5267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "cvt.s.d 'fd, 'fs");
5277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case C_F_D:
5297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "c.f.d   'fs, 'ft, 'Cc");
5307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case C_UN_D:
5327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "c.un.d  'fs, 'ft, 'Cc");
5337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case C_EQ_D:
5357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "c.eq.d  'fs, 'ft, 'Cc");
5367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case C_UEQ_D:
5387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "c.ueq.d 'fs, 'ft, 'Cc");
5397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case C_OLT_D:
5417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "c.olt.d 'fs, 'ft, 'Cc");
5427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case C_ULT_D:
5447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "c.ult.d 'fs, 'ft, 'Cc");
5457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case C_OLE_D:
5477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "c.ole.d 'fs, 'ft, 'Cc");
5487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case C_ULE_D:
5507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "c.ule.d 'fs, 'ft, 'Cc");
5517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            default:
5537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "unknown.cop1.d");
5547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          }
5567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          break;
5577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        case S:
5585c838251403b0be9a882540f1922577abba4c872ager@chromium.org          UNIMPLEMENTED_MIPS();
5595c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
5605c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case W:
5615c838251403b0be9a882540f1922577abba4c872ager@chromium.org          switch (instr->FunctionFieldRaw()) {
5627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            case CVT_S_W:   // Convert word to float (single).
5637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "cvt.s.w 'fd, 'fs");
5645c838251403b0be9a882540f1922577abba4c872ager@chromium.org              break;
5655c838251403b0be9a882540f1922577abba4c872ager@chromium.org            case CVT_D_W:   // Convert word to double.
5667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Format(instr, "cvt.d.w 'fd, 'fs");
5675c838251403b0be9a882540f1922577abba4c872ager@chromium.org              break;
5685c838251403b0be9a882540f1922577abba4c872ager@chromium.org            default:
5695c838251403b0be9a882540f1922577abba4c872ager@chromium.org              UNREACHABLE();
5707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          }
5715c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
5725c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case L:
5737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          switch (instr->FunctionFieldRaw()) {
5745e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CVT_D_L:
5755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cvt.d.l 'fd, 'fs");
5767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
5775e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CVT_S_L:
5785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cvt.s.l 'fd, 'fs");
5795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
5805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_UN:
5815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.un.d  'fd,  'fs, 'ft");
5825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
5835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_EQ:
5845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.eq.d  'fd,  'fs, 'ft");
5855e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
5865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_UEQ:
5875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.ueq.d  'fd,  'fs, 'ft");
5885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
5895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_LT:
5905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.lt.d  'fd,  'fs, 'ft");
5915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
5925e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_ULT:
5935e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.ult.d  'fd,  'fs, 'ft");
5945e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
5955e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_LE:
5965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.le.d  'fd,  'fs, 'ft");
5975e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
5985e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_ULE:
5995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.ule.d  'fd,  'fs, 'ft");
6005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
6015e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_OR:
6025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.or.d  'fd,  'fs, 'ft");
6035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
6045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_UNE:
6055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.une.d  'fd,  'fs, 'ft");
6065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
6075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_NE:
6085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.ne.d  'fd,  'fs, 'ft");
6097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              break;
6107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            default:
6117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              UNREACHABLE();
6127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          }
6137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          break;
6145c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case PS:
6155c838251403b0be9a882540f1922577abba4c872ager@chromium.org          UNIMPLEMENTED_MIPS();
6165c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
6175c838251403b0be9a882540f1922577abba4c872ager@chromium.org        default:
6185c838251403b0be9a882540f1922577abba4c872ager@chromium.org          UNREACHABLE();
6197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      }
6205c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
62159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    case COP1X:
62259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      switch (instr->FunctionFieldRaw()) {
62359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        case MADD_D:
62459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org          Format(instr, "madd.d  'fd, 'fr, 'fs, 'ft");
62559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org          break;
62659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        default:
62759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org          UNREACHABLE();
6283c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      }
62959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      break;
6305c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case SPECIAL:
6315c838251403b0be9a882540f1922577abba4c872ager@chromium.org      switch (instr->FunctionFieldRaw()) {
6325c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case JR:
63383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "jr      'rs");
6345c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
6355c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case JALR:
63683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "jalr    'rs");
6375c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
6385c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case SLL:
6395c838251403b0be9a882540f1922577abba4c872ager@chromium.org          if ( 0x0 == static_cast<int>(instr->InstructionBits()))
6405c838251403b0be9a882540f1922577abba4c872ager@chromium.org            Format(instr, "nop");
6415c838251403b0be9a882540f1922577abba4c872ager@chromium.org          else
64283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org            Format(instr, "sll     'rd, 'rt, 'sa");
6435c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
6445c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case SRL:
6457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          if (instr->RsValue() == 0) {
64683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org            Format(instr, "srl     'rd, 'rt, 'sa");
6477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          } else {
6485e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            if (IsMipsArchVariant(kMips32r2)) {
64983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Format(instr, "rotr    'rd, 'rt, 'sa");
6507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            } else {
6517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Unknown(instr);
6527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            }
6537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          }
6545c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
6555c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case SRA:
65683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "sra     'rd, 'rt, 'sa");
6575c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
6585c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case SLLV:
65983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "sllv    'rd, 'rt, 'rs");
6605c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
6615c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case SRLV:
6627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          if (instr->SaValue() == 0) {
66383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org            Format(instr, "srlv    'rd, 'rt, 'rs");
6647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          } else {
6655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            if (IsMipsArchVariant(kMips32r2)) {
66683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Format(instr, "rotrv   'rd, 'rt, 'rs");
6677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            } else {
6687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org              Unknown(instr);
6697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            }
6707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          }
6715c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
6725c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case SRAV:
67383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "srav    'rd, 'rt, 'rs");
6745c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
6755c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case MFHI:
6765e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (instr->Bits(25, 16) == 0) {
6775e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            Format(instr, "mfhi    'rd");
6785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          } else {
6795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            if ((instr->FunctionFieldRaw() == CLZ_R6)
6805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                && (instr->FdValue() == 1)) {
6815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "clz     'rd, 'rs");
6825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            } else if ((instr->FunctionFieldRaw() == CLO_R6)
6835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                && (instr->FdValue() == 1)) {
6845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "clo     'rd, 'rs");
6855e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            }
6865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
6875c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
6885c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case MFLO:
68983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "mflo    'rd");
6905c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
6915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case MULT:  // @Mips32r6 == MUL_MUH.
6925e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (!IsMipsArchVariant(kMips32r6)) {
6935e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            Format(instr, "mult    'rs, 'rt");
6945e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          } else {
6955e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            if (instr->SaValue() == MUL_OP) {
6965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "mul    'rd, 'rs, 'rt");
6975e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            } else {
6985e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "muh    'rd, 'rs, 'rt");
6995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            }
7005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
7015c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case MULTU:  // @Mips32r6 == MUL_MUH_U.
7035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (!IsMipsArchVariant(kMips32r6)) {
7045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            Format(instr, "multu   'rs, 'rt");
7055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          } else {
7065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            if (instr->SaValue() == MUL_OP) {
7075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "mulu   'rd, 'rs, 'rt");
7085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            } else {
7095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "muhu   'rd, 'rs, 'rt");
7105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            }
7115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
7125c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case DIV:  // @Mips32r6 == DIV_MOD.
7145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (!IsMipsArchVariant(kMips32r6)) {
7155e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            Format(instr, "div     'rs, 'rt");
7165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          } else {
7175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            if (instr->SaValue() == DIV_OP) {
7185e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "div    'rd, 'rs, 'rt");
7195e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            } else {
7205e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "mod    'rd, 'rs, 'rt");
7215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            }
7225e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
7235c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7245e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case DIVU:  // @Mips32r6 == DIV_MOD_U.
7255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (!IsMipsArchVariant(kMips32r6)) {
7265e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            Format(instr, "divu    'rs, 'rt");
7275e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          } else {
7285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            if (instr->SaValue() == DIV_OP) {
7295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "divu   'rd, 'rs, 'rt");
7305e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            } else {
7315e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "modu   'rd, 'rs, 'rt");
7325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            }
7335e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
7345c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7355c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case ADD:
73683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "add     'rd, 'rs, 'rt");
7375c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7385c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case ADDU:
73983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "addu    'rd, 'rs, 'rt");
7405c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7415c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case SUB:
74283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "sub     'rd, 'rs, 'rt");
7435c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7445c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case SUBU:
74583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "subu    'rd, 'rs, 'rt");
7465c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7475c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case AND:
74883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "and     'rd, 'rs, 'rt");
7495c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7505c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case OR:
7517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          if (0 == instr->RsValue()) {
75283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org            Format(instr, "mov     'rd, 'rt");
7537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          } else if (0 == instr->RtValue()) {
75483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org            Format(instr, "mov     'rd, 'rs");
7555c838251403b0be9a882540f1922577abba4c872ager@chromium.org          } else {
75683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org            Format(instr, "or      'rd, 'rs, 'rt");
7575c838251403b0be9a882540f1922577abba4c872ager@chromium.org          }
7585c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7595c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case XOR:
76083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "xor     'rd, 'rs, 'rt");
7615c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7625c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case NOR:
76383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "nor     'rd, 'rs, 'rt");
7645c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7655c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case SLT:
76683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "slt     'rd, 'rs, 'rt");
7675c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7685c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case SLTU:
76983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "sltu    'rd, 'rs, 'rt");
7705c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7715c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case BREAK:
7725c838251403b0be9a882540f1922577abba4c872ager@chromium.org          Format(instr, "break, code: 'code");
7735c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7745c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case TGE:
77583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "tge     'rs, 'rt, code: 'code");
7765c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7775c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case TGEU:
77883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "tgeu    'rs, 'rt, code: 'code");
7795c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7805c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case TLT:
78183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "tlt     'rs, 'rt, code: 'code");
7825c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7835c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case TLTU:
78483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "tltu    'rs, 'rt, code: 'code");
7855c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7865c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case TEQ:
78783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "teq     'rs, 'rt, code: 'code");
7885c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7895c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case TNE:
79083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "tne     'rs, 'rt, code: 'code");
7915c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
7927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        case MOVZ:
79383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "movz    'rd, 'rs, 'rt");
7947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          break;
7957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        case MOVN:
79683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "movn    'rd, 'rs, 'rt");
7977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          break;
7987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        case MOVCI:
7997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          if (instr->Bit(16)) {
80083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org            Format(instr, "movt    'rd, 'rs, 'bc");
8017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          } else {
80283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org            Format(instr, "movf    'rd, 'rs, 'bc");
8037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          }
8047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          break;
8055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case SELEQZ_S:
8065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          Format(instr, "seleqz    'rd, 'rs, 'rt");
8075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          break;
8085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case SELNEZ_S:
8095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          Format(instr, "selnez    'rd, 'rs, 'rt");
8105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          break;
8115c838251403b0be9a882540f1922577abba4c872ager@chromium.org        default:
8125c838251403b0be9a882540f1922577abba4c872ager@chromium.org          UNREACHABLE();
8137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      }
8145c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
8155c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case SPECIAL2:
8165c838251403b0be9a882540f1922577abba4c872ager@chromium.org      switch (instr->FunctionFieldRaw()) {
8175c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case MUL:
81883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "mul     'rd, 'rs, 'rt");
8197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          break;
8207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        case CLZ:
8215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (!IsMipsArchVariant(kMips32r6)) {
8225e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            Format(instr, "clz     'rd, 'rs");
8235e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
8245c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
8255c838251403b0be9a882540f1922577abba4c872ager@chromium.org        default:
8265c838251403b0be9a882540f1922577abba4c872ager@chromium.org          UNREACHABLE();
8277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      }
8287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      break;
8297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    case SPECIAL3:
8307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      switch (instr->FunctionFieldRaw()) {
8317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        case INS: {
8325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (IsMipsArchVariant(kMips32r2)) {
83383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org            Format(instr, "ins     'rt, 'rs, 'sa, 'ss2");
8347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          } else {
8357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            Unknown(instr);
8367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          }
8377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          break;
8387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        }
8397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        case EXT: {
8405e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          if (IsMipsArchVariant(kMips32r2)) {
84183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org            Format(instr, "ext     'rt, 'rs, 'sa, 'ss1");
8427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          } else {
8437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            Unknown(instr);
8447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          }
8457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          break;
8467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        }
8477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        default:
8487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          UNREACHABLE();
8497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      }
8505c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
8515c838251403b0be9a882540f1922577abba4c872ager@chromium.org    default:
8525c838251403b0be9a882540f1922577abba4c872ager@chromium.org      UNREACHABLE();
8537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
8545c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
8555c838251403b0be9a882540f1922577abba4c872ager@chromium.org
8565c838251403b0be9a882540f1922577abba4c872ager@chromium.org
8575c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::DecodeTypeImmediate(Instruction* instr) {
8585c838251403b0be9a882540f1922577abba4c872ager@chromium.org  switch (instr->OpcodeFieldRaw()) {
8597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    case COP1:
8607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      switch (instr->RsFieldRaw()) {
8617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        case BC1:
8627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          if (instr->FBtrueValue()) {
8637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            Format(instr, "bc1t    'bc, 'imm16u");
8647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          } else {
8657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            Format(instr, "bc1f    'bc, 'imm16u");
8667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          }
8677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          break;
8685e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case BC1EQZ:
8695e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          Format(instr, "bc1eqz    'ft, 'imm16u");
8705e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          break;
8715e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case BC1NEZ:
8725e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          Format(instr, "bc1nez    'ft, 'imm16u");
8735e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          break;
8745e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case W:  // CMP.S instruction.
8755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          switch (instr->FunctionValue()) {
8765e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_AF:
8775e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.af.S    'ft, 'fs, 'fd");
8785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
8795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_UN:
8805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.un.S    'ft, 'fs, 'fd");
8815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
8825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_EQ:
8835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.eq.S    'ft, 'fs, 'fd");
8845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
8855e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_UEQ:
8865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.ueq.S   'ft, 'fs, 'fd");
8875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
8885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_LT:
8895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.lt.S    'ft, 'fs, 'fd");
8905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
8915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_ULT:
8925e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.ult.S   'ft, 'fs, 'fd");
8935e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
8945e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_LE:
8955e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.le.S    'ft, 'fs, 'fd");
8965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
8975e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_ULE:
8985e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.ule.S   'ft, 'fs, 'fd");
8995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_OR:
9015e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.or.S    'ft, 'fs, 'fd");
9025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_UNE:
9045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.une.S   'ft, 'fs, 'fd");
9055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_NE:
9075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.ne.S    'ft, 'fs, 'fd");
9085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            default:
9105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              UNREACHABLE();
9115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
9125e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          break;
9135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case L:  // CMP.D instruction.
9145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          switch (instr->FunctionValue()) {
9155e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_AF:
9165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.af.D    'ft, 'fs, 'fd");
9175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9185e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_UN:
9195e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.un.D    'ft, 'fs, 'fd");
9205e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_EQ:
9225e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.eq.D    'ft, 'fs, 'fd");
9235e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9245e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_UEQ:
9255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.ueq.D   'ft, 'fs, 'fd");
9265e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9275e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_LT:
9285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.lt.D    'ft, 'fs, 'fd");
9295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9305e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_ULT:
9315e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.ult.D   'ft, 'fs, 'fd");
9325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9335e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_LE:
9345e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.le.D    'ft, 'fs, 'fd");
9355e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9365e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_ULE:
9375e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.ule.D   'ft, 'fs, 'fd");
9385e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9395e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_OR:
9405e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.or.D    'ft, 'fs, 'fd");
9415e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9425e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_UNE:
9435e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.une.D   'ft, 'fs, 'fd");
9445e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9455e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case CMP_NE:
9465e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "cmp.ne.D    'ft, 'fs, 'fd");
9475e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9485e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            default:
9495e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              UNREACHABLE();
9505e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
9515e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          break;
9525e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case S:
9535e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          switch (instr->FunctionValue()) {
9545e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case SEL:
9555e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "sel.S    'ft, 'fs, 'fd");
9565e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9575e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case SELEQZ_C:
9585e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "seleqz.S 'ft, 'fs, 'fd");
9595e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9605e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case SELNEZ_C:
9615e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "selnez.S 'ft, 'fs, 'fd");
9625e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case MIN:
9645e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "min.S    'ft, 'fs, 'fd");
9655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case MINA:
9675e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "mina.S   'ft, 'fs, 'fd");
9685e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9695e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case MAX:
9705e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "max.S    'ft, 'fs, 'fd");
9715e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9725e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case MAXA:
9735e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "maxa.S   'ft, 'fs, 'fd");
9745e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            default:
9765e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              UNREACHABLE();
9775e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
9785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          break;
9795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case D:
9805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          switch (instr->FunctionValue()) {
9815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case SEL:
9825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "sel.D    'ft, 'fs, 'fd");
9835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case SELEQZ_C:
9855e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "seleqz.D 'ft, 'fs, 'fd");
9865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case SELNEZ_C:
9885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "selnez.D 'ft, 'fs, 'fd");
9895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case MIN:
9915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "min.D    'ft, 'fs, 'fd");
9925e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9935e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case MINA:
9945e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "mina.D   'ft, 'fs, 'fd");
9955e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case MAX:
9975e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "max.D    'ft, 'fs, 'fd");
9985e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
9995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            case MAXA:
10005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              Format(instr, "maxa.D   'ft, 'fs, 'fd");
10015e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              break;
10025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            default:
10035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org              UNREACHABLE();
10045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          }
10055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          break;
10067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        default:
10077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org          UNREACHABLE();
10083c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org      }
10095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
10107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      break;  // Case COP1.
10115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    // ------------- REGIMM class.
10125c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case REGIMM:
10135c838251403b0be9a882540f1922577abba4c872ager@chromium.org      switch (instr->RtFieldRaw()) {
10145c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case BLTZ:
101583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "bltz    'rs, 'imm16u");
10165c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
10175c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case BLTZAL:
101883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "bltzal  'rs, 'imm16u");
10195c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
10205c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case BGEZ:
102183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "bgez    'rs, 'imm16u");
10225c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
10235c838251403b0be9a882540f1922577abba4c872ager@chromium.org        case BGEZAL:
102483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org          Format(instr, "bgezal  'rs, 'imm16u");
10255c838251403b0be9a882540f1922577abba4c872ager@chromium.org          break;
10265e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        case BGEZALL:
10275e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          Format(instr, "bgezall 'rs, 'imm16u");
10285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          break;
10295c838251403b0be9a882540f1922577abba4c872ager@chromium.org        default:
10305c838251403b0be9a882540f1922577abba4c872ager@chromium.org          UNREACHABLE();
10317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      }
10327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    break;  // Case REGIMM.
10335c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // ------------- Branch instructions.
10345c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case BEQ:
103583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "beq     'rs, 'rt, 'imm16u");
10365c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
10375c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case BNE:
103883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "bne     'rs, 'rt, 'imm16u");
10395c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
10405c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case BLEZ:
10415e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if ((instr->RtFieldRaw() == 0)
10425e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RsFieldRaw() != 0)) {
10435e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "blez    'rs, 'imm16u");
10445e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else if ((instr->RtFieldRaw() != instr->RsFieldRaw())
10455e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) {
10465e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "bgeuc    'rs, 'rt, 'imm16u");
10475e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else if ((instr->RtFieldRaw() == instr->RsFieldRaw())
10485e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RtFieldRaw() != 0)) {
10495e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "bgezalc  'rs, 'imm16u");
10505e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else if ((instr->RsFieldRaw() == 0)
10515e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RtFieldRaw() != 0)) {
10525e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "blezalc  'rs, 'imm16u");
10535e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else {
10545e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        UNREACHABLE();
10555e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
10565c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
10575c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case BGTZ:
10585e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if ((instr->RtFieldRaw() == 0)
10595e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RsFieldRaw() != 0)) {
10605e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "bgtz    'rs, 'imm16u");
10615e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else if ((instr->RtFieldRaw() != instr->RsFieldRaw())
10625e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) {
10635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "bltuc   'rs, 'rt, 'imm16u");
10645e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else if ((instr->RtFieldRaw() == instr->RsFieldRaw())
10655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RtFieldRaw() != 0)) {
10665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "bltzalc 'rt, 'imm16u");
10675e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else if ((instr->RsFieldRaw() == 0)
10685e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RtFieldRaw() != 0)) {
10695e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "bgtzalc 'rt, 'imm16u");
10705e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else {
10715e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        UNREACHABLE();
10725e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
10735e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      break;
10745e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case BLEZL:
10755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if ((instr->RtFieldRaw() == instr->RsFieldRaw())
10765e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RtFieldRaw() != 0)) {
10775e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "bgezc    'rt, 'imm16u");
10785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else if ((instr->RtFieldRaw() != instr->RsFieldRaw())
10795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) {
10805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "bgec     'rs, 'rt, 'imm16u");
10815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else if ((instr->RsFieldRaw() == 0)
10825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RtFieldRaw() != 0)) {
10835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "blezc    'rt, 'imm16u");
10845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else {
10855e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        UNREACHABLE();
10865e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
10875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      break;
10885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case BGTZL:
10895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if ((instr->RtFieldRaw() == instr->RsFieldRaw())
10905e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RtFieldRaw() != 0)) {
10915e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "bltzc    'rt, 'imm16u");
10925e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else if ((instr->RtFieldRaw() != instr->RsFieldRaw())
10935e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) {
10945e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "bltc     'rs, 'rt, 'imm16u");
10955e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else if ((instr->RsFieldRaw() == 0)
10965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          && (instr->RtFieldRaw() != 0)) {
10975e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "bgtzc    'rt, 'imm16u");
10985e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else {
10995e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        UNREACHABLE();
11005e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
11015e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      break;
11025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case BEQZC:
11035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if (instr->RsFieldRaw() != 0) {
11045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "beqzc   'rs, 'imm21x");
11055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
11065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      break;
11075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case BNEZC:
11085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if (instr->RsFieldRaw() != 0) {
11095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "bnezc   'rs, 'imm21x");
11105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
11115c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
11125c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // ------------- Arithmetic instructions.
11135c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case ADDI:
11145e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if (!IsMipsArchVariant(kMips32r6)) {
11155e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "addi    'rt, 'rs, 'imm16s");
11165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else {
11175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        // Check if BOVC or BEQC instruction.
11185e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        if (instr->RsFieldRaw() >= instr->RtFieldRaw()) {
11195e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          Format(instr, "bovc  'rs, 'rt, 'imm16s");
11205e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        } else if (instr->RsFieldRaw() < instr->RtFieldRaw()) {
11215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          Format(instr, "beqc  'rs, 'rt, 'imm16s");
11225e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        } else {
11235e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          UNREACHABLE();
11245e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        }
11255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
11265e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      break;
11275e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case DADDI:
11285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if (IsMipsArchVariant(kMips32r6)) {
11295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        // Check if BNVC or BNEC instruction.
11305e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        if (instr->RsFieldRaw() >= instr->RtFieldRaw()) {
11315e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          Format(instr, "bnvc  'rs, 'rt, 'imm16s");
11325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        } else if (instr->RsFieldRaw() < instr->RtFieldRaw()) {
11335e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          Format(instr, "bnec  'rs, 'rt, 'imm16s");
11345e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        } else {
11355e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          UNREACHABLE();
11365e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        }
11375e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
11385c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
11395c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case ADDIU:
114083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "addiu   'rt, 'rs, 'imm16s");
11415c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
11425c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case SLTI:
114383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "slti    'rt, 'rs, 'imm16s");
11445c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
11455c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case SLTIU:
114683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "sltiu   'rt, 'rs, 'imm16u");
11475c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
11485c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case ANDI:
114983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "andi    'rt, 'rs, 'imm16x");
11505c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
11515c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case ORI:
115283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "ori     'rt, 'rs, 'imm16x");
11535c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
11545c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case XORI:
115583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "xori    'rt, 'rs, 'imm16x");
11565c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
11575c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case LUI:
11585e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      if (!IsMipsArchVariant(kMips32r6)) {
11595e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        Format(instr, "lui     'rt, 'imm16x");
11605e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      } else {
11615e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        if (instr->RsValue() != 0) {
11625e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          Format(instr, "aui     'rt, 'imm16x");
11635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        } else {
11645e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org          Format(instr, "lui     'rt, 'imm16x");
11655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        }
11665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      }
11675c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
11685c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // ------------- Memory instructions.
11695c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case LB:
117083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "lb      'rt, 'imm16s('rs)");
11715c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
11727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    case LH:
117383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "lh      'rt, 'imm16s('rs)");
11747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      break;
11757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    case LWL:
117683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "lwl     'rt, 'imm16s('rs)");
11777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      break;
11785c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case LW:
117983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "lw      'rt, 'imm16s('rs)");
11805c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
11815c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case LBU:
118283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "lbu     'rt, 'imm16s('rs)");
11835c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
11847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    case LHU:
118583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "lhu     'rt, 'imm16s('rs)");
11867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      break;
11877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    case LWR:
118883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "lwr     'rt, 'imm16s('rs)");
11897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      break;
1190afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    case PREF:
1191afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      Format(instr, "pref    'rt, 'imm16s('rs)");
1192afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      break;
11935c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case SB:
119483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "sb      'rt, 'imm16s('rs)");
11955c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
11967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    case SH:
119783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "sh      'rt, 'imm16s('rs)");
11987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      break;
11997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    case SWL:
120083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "swl     'rt, 'imm16s('rs)");
12017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      break;
12025c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case SW:
120383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "sw      'rt, 'imm16s('rs)");
12045c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
12057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    case SWR:
120683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "swr     'rt, 'imm16s('rs)");
12077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      break;
12085c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case LWC1:
120983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "lwc1    'ft, 'imm16s('rs)");
12105c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
12115c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case LDC1:
121283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "ldc1    'ft, 'imm16s('rs)");
12135c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
12145c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case SWC1:
121583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "swc1    'ft, 'imm16s('rs)");
12165c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
12175c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case SDC1:
121883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Format(instr, "sdc1    'ft, 'imm16s('rs)");
12195c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
12205c838251403b0be9a882540f1922577abba4c872ager@chromium.org    default:
12215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      printf("a 0x%x \n", instr->OpcodeFieldRaw());
12225c838251403b0be9a882540f1922577abba4c872ager@chromium.org      UNREACHABLE();
12235c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
12243c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  }
12255c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
12265c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12275c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12285c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Decoder::DecodeTypeJump(Instruction* instr) {
12295c838251403b0be9a882540f1922577abba4c872ager@chromium.org  switch (instr->OpcodeFieldRaw()) {
12305c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case J:
123134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      Format(instr, "j       'imm26x");
12325c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
12335c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case JAL:
123434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      Format(instr, "jal     'imm26x");
12355c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
12365c838251403b0be9a882540f1922577abba4c872ager@chromium.org    default:
12375c838251403b0be9a882540f1922577abba4c872ager@chromium.org      UNREACHABLE();
12385c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
12395c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
12405c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12415c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12425c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Disassemble the instruction at *instr_ptr into the output buffer.
124383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgint Decoder::InstructionDecode(byte* instr_ptr) {
12445c838251403b0be9a882540f1922577abba4c872ager@chromium.org  Instruction* instr = Instruction::At(instr_ptr);
12455c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Print raw instruction bytes.
124670ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
124770ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org                                   "%08x       ",
124870ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org                                   instr->InstructionBits());
12495c838251403b0be9a882540f1922577abba4c872ager@chromium.org  switch (instr->InstructionType()) {
12505c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case Instruction::kRegisterType: {
12515c838251403b0be9a882540f1922577abba4c872ager@chromium.org      DecodeTypeRegister(instr);
12525c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
12535c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
12545c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case Instruction::kImmediateType: {
12555c838251403b0be9a882540f1922577abba4c872ager@chromium.org      DecodeTypeImmediate(instr);
12565c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
12575c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
12585c838251403b0be9a882540f1922577abba4c872ager@chromium.org    case Instruction::kJumpType: {
12595c838251403b0be9a882540f1922577abba4c872ager@chromium.org      DecodeTypeJump(instr);
12605c838251403b0be9a882540f1922577abba4c872ager@chromium.org      break;
12615c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
12625c838251403b0be9a882540f1922577abba4c872ager@chromium.org    default: {
126334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org      Format(instr, "UNSUPPORTED");
12645c838251403b0be9a882540f1922577abba4c872ager@chromium.org      UNSUPPORTED_MIPS();
12655c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
12665c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
12677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  return Instruction::kInstrSize;
12685c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
12695c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12705c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} }  // namespace v8::internal
12725c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12735c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12745c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12755c838251403b0be9a882540f1922577abba4c872ager@chromium.org//------------------------------------------------------------------------------
12765c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12775c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace disasm {
12785c838251403b0be9a882540f1922577abba4c872ager@chromium.org
127983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgconst char* NameConverter::NameOfAddress(byte* addr) const {
128070ec1a2160dd946b9578d04d97d631a6d4ab4f8cbmeurer@chromium.org  v8::internal::SNPrintF(tmp_buffer_, "%p", addr);
1281ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return tmp_buffer_.start();
12825c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
12835c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12845c838251403b0be9a882540f1922577abba4c872ager@chromium.org
128583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgconst char* NameConverter::NameOfConstant(byte* addr) const {
12865c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return NameOfAddress(addr);
12875c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
12885c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12895c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12905c838251403b0be9a882540f1922577abba4c872ager@chromium.orgconst char* NameConverter::NameOfCPURegister(int reg) const {
12917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  return v8::internal::Registers::Name(reg);
12925c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
12935c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12945c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12955c838251403b0be9a882540f1922577abba4c872ager@chromium.orgconst char* NameConverter::NameOfXMMRegister(int reg) const {
12967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  return v8::internal::FPURegisters::Name(reg);
12975c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
12985c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12995c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13005c838251403b0be9a882540f1922577abba4c872ager@chromium.orgconst char* NameConverter::NameOfByteCPURegister(int reg) const {
130183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  UNREACHABLE();  // MIPS does not have the concept of a byte register.
13025c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return "nobytereg";
13035c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
13045c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13055c838251403b0be9a882540f1922577abba4c872ager@chromium.org
130683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgconst char* NameConverter::NameInCode(byte* addr) const {
13075c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // The default name converter is called for unknown code. So we will not try
13085c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // to access any memory.
13095c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return "";
13105c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
13115c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13125c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13135c838251403b0be9a882540f1922577abba4c872ager@chromium.org//------------------------------------------------------------------------------
13145c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13155c838251403b0be9a882540f1922577abba4c872ager@chromium.orgDisassembler::Disassembler(const NameConverter& converter)
13165c838251403b0be9a882540f1922577abba4c872ager@chromium.org    : converter_(converter) {}
13175c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13185c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13195c838251403b0be9a882540f1922577abba4c872ager@chromium.orgDisassembler::~Disassembler() {}
13205c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13215c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13225c838251403b0be9a882540f1922577abba4c872ager@chromium.orgint Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
132383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    byte* instruction) {
13247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  v8::internal::Decoder d(converter_, buffer);
13255c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return d.InstructionDecode(instruction);
13265c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
13275c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13285c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// The MIPS assembler does not currently use constant pools.
133083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgint Disassembler::ConstantPoolSizeAt(byte* instruction) {
13315c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return -1;
13325c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
13335c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13345c838251403b0be9a882540f1922577abba4c872ager@chromium.org
133583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
13365c838251403b0be9a882540f1922577abba4c872ager@chromium.org  NameConverter converter;
13375c838251403b0be9a882540f1922577abba4c872ager@chromium.org  Disassembler d(converter);
133883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  for (byte* pc = begin; pc < end;) {
13395c838251403b0be9a882540f1922577abba4c872ager@chromium.org    v8::internal::EmbeddedVector<char, 128> buffer;
13405c838251403b0be9a882540f1922577abba4c872ager@chromium.org    buffer[0] = '\0';
134183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    byte* prev_pc = pc;
13425c838251403b0be9a882540f1922577abba4c872ager@chromium.org    pc += d.InstructionDecode(buffer, pc);
1343e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    v8::internal::PrintF(f, "%p    %08x      %s\n",
1344e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
13455c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
13465c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
13475c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
13495c838251403b0be9a882540f1922577abba4c872ager@chromium.org#undef UNSUPPORTED
13505c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13515c838251403b0be9a882540f1922577abba4c872ager@chromium.org}  // namespace disasm
13525c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13539dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif  // V8_TARGET_ARCH_MIPS
1354