11cb0ef41Sopenharmony_ci// Copyright 2012 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci// A Disassembler object is used to disassemble a block of code instruction by 61cb0ef41Sopenharmony_ci// instruction. The default implementation of the NameConverter object can be 71cb0ef41Sopenharmony_ci// overriden to modify register names or to do symbol lookup on addresses. 81cb0ef41Sopenharmony_ci// 91cb0ef41Sopenharmony_ci// The example below will disassemble a block of code and print it to stdout. 101cb0ef41Sopenharmony_ci// 111cb0ef41Sopenharmony_ci// NameConverter converter; 121cb0ef41Sopenharmony_ci// Disassembler d(converter); 131cb0ef41Sopenharmony_ci// for (byte* pc = begin; pc < end;) { 141cb0ef41Sopenharmony_ci// v8::base::EmbeddedVector<char, 256> buffer; 151cb0ef41Sopenharmony_ci// byte* prev_pc = pc; 161cb0ef41Sopenharmony_ci// pc += d.InstructionDecode(buffer, pc); 171cb0ef41Sopenharmony_ci// printf("%p %08x %s\n", 181cb0ef41Sopenharmony_ci// prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer); 191cb0ef41Sopenharmony_ci// } 201cb0ef41Sopenharmony_ci// 211cb0ef41Sopenharmony_ci// The Disassembler class also has a convenience method to disassemble a block 221cb0ef41Sopenharmony_ci// of code into a FILE*, meaning that the above functionality could also be 231cb0ef41Sopenharmony_ci// achieved by just calling Disassembler::Disassemble(stdout, begin, end); 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci#include <assert.h> 261cb0ef41Sopenharmony_ci#include <stdarg.h> 271cb0ef41Sopenharmony_ci#include <stdio.h> 281cb0ef41Sopenharmony_ci#include <string.h> 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci#if V8_TARGET_ARCH_MIPS64 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci#include "src/base/platform/platform.h" 331cb0ef41Sopenharmony_ci#include "src/base/strings.h" 341cb0ef41Sopenharmony_ci#include "src/base/vector.h" 351cb0ef41Sopenharmony_ci#include "src/codegen/macro-assembler.h" 361cb0ef41Sopenharmony_ci#include "src/codegen/mips64/constants-mips64.h" 371cb0ef41Sopenharmony_ci#include "src/diagnostics/disasm.h" 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_cinamespace v8 { 401cb0ef41Sopenharmony_cinamespace internal { 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci//------------------------------------------------------------------------------ 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci// Decoder decodes and disassembles instructions into an output buffer. 451cb0ef41Sopenharmony_ci// It uses the converter to convert register names and call destinations into 461cb0ef41Sopenharmony_ci// more informative description. 471cb0ef41Sopenharmony_ciclass Decoder { 481cb0ef41Sopenharmony_ci public: 491cb0ef41Sopenharmony_ci Decoder(const disasm::NameConverter& converter, 501cb0ef41Sopenharmony_ci v8::base::Vector<char> out_buffer) 511cb0ef41Sopenharmony_ci : converter_(converter), out_buffer_(out_buffer), out_buffer_pos_(0) { 521cb0ef41Sopenharmony_ci out_buffer_[out_buffer_pos_] = '\0'; 531cb0ef41Sopenharmony_ci } 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci ~Decoder() {} 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci Decoder(const Decoder&) = delete; 581cb0ef41Sopenharmony_ci Decoder& operator=(const Decoder&) = delete; 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci // Writes one disassembled instruction into 'buffer' (0-terminated). 611cb0ef41Sopenharmony_ci // Returns the length of the disassembled machine instruction in bytes. 621cb0ef41Sopenharmony_ci int InstructionDecode(byte* instruction); 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci private: 651cb0ef41Sopenharmony_ci // Bottleneck functions to print into the out_buffer. 661cb0ef41Sopenharmony_ci void PrintChar(const char ch); 671cb0ef41Sopenharmony_ci void Print(const char* str); 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci // Printing of common values. 701cb0ef41Sopenharmony_ci void PrintRegister(int reg); 711cb0ef41Sopenharmony_ci void PrintFPURegister(int freg); 721cb0ef41Sopenharmony_ci void PrintMSARegister(int wreg); 731cb0ef41Sopenharmony_ci void PrintFPUStatusRegister(int freg); 741cb0ef41Sopenharmony_ci void PrintMSAControlRegister(int creg); 751cb0ef41Sopenharmony_ci void PrintRs(Instruction* instr); 761cb0ef41Sopenharmony_ci void PrintRt(Instruction* instr); 771cb0ef41Sopenharmony_ci void PrintRd(Instruction* instr); 781cb0ef41Sopenharmony_ci void PrintFs(Instruction* instr); 791cb0ef41Sopenharmony_ci void PrintFt(Instruction* instr); 801cb0ef41Sopenharmony_ci void PrintFd(Instruction* instr); 811cb0ef41Sopenharmony_ci void PrintSa(Instruction* instr); 821cb0ef41Sopenharmony_ci void PrintLsaSa(Instruction* instr); 831cb0ef41Sopenharmony_ci void PrintSd(Instruction* instr); 841cb0ef41Sopenharmony_ci void PrintSs1(Instruction* instr); 851cb0ef41Sopenharmony_ci void PrintSs2(Instruction* instr); 861cb0ef41Sopenharmony_ci void PrintSs3(Instruction* instr); 871cb0ef41Sopenharmony_ci void PrintSs4(Instruction* instr); 881cb0ef41Sopenharmony_ci void PrintSs5(Instruction* instr); 891cb0ef41Sopenharmony_ci void PrintBc(Instruction* instr); 901cb0ef41Sopenharmony_ci void PrintCc(Instruction* instr); 911cb0ef41Sopenharmony_ci void PrintFunction(Instruction* instr); 921cb0ef41Sopenharmony_ci void PrintSecondaryField(Instruction* instr); 931cb0ef41Sopenharmony_ci void PrintUImm9(Instruction* instr); 941cb0ef41Sopenharmony_ci void PrintSImm9(Instruction* instr); 951cb0ef41Sopenharmony_ci void PrintUImm16(Instruction* instr); 961cb0ef41Sopenharmony_ci void PrintSImm16(Instruction* instr); 971cb0ef41Sopenharmony_ci void PrintXImm16(Instruction* instr); 981cb0ef41Sopenharmony_ci void PrintPCImm16(Instruction* instr, int delta_pc, int n_bits); 991cb0ef41Sopenharmony_ci void PrintXImm18(Instruction* instr); 1001cb0ef41Sopenharmony_ci void PrintSImm18(Instruction* instr); 1011cb0ef41Sopenharmony_ci void PrintXImm19(Instruction* instr); 1021cb0ef41Sopenharmony_ci void PrintSImm19(Instruction* instr); 1031cb0ef41Sopenharmony_ci void PrintXImm21(Instruction* instr); 1041cb0ef41Sopenharmony_ci void PrintSImm21(Instruction* instr); 1051cb0ef41Sopenharmony_ci void PrintPCImm21(Instruction* instr, int delta_pc, int n_bits); 1061cb0ef41Sopenharmony_ci void PrintXImm26(Instruction* instr); 1071cb0ef41Sopenharmony_ci void PrintSImm26(Instruction* instr); 1081cb0ef41Sopenharmony_ci void PrintPCImm26(Instruction* instr, int delta_pc, int n_bits); 1091cb0ef41Sopenharmony_ci void PrintPCImm26(Instruction* instr); 1101cb0ef41Sopenharmony_ci void PrintCode(Instruction* instr); // For break and trap instructions. 1111cb0ef41Sopenharmony_ci void PrintFormat(Instruction* instr); // For floating format postfix. 1121cb0ef41Sopenharmony_ci void PrintBp2(Instruction* instr); 1131cb0ef41Sopenharmony_ci void PrintBp3(Instruction* instr); 1141cb0ef41Sopenharmony_ci void PrintMsaDataFormat(Instruction* instr); 1151cb0ef41Sopenharmony_ci void PrintMsaXImm8(Instruction* instr); 1161cb0ef41Sopenharmony_ci void PrintMsaImm8(Instruction* instr); 1171cb0ef41Sopenharmony_ci void PrintMsaImm5(Instruction* instr); 1181cb0ef41Sopenharmony_ci void PrintMsaSImm5(Instruction* instr); 1191cb0ef41Sopenharmony_ci void PrintMsaSImm10(Instruction* instr, bool is_mi10 = false); 1201cb0ef41Sopenharmony_ci void PrintMsaImmBit(Instruction* instr); 1211cb0ef41Sopenharmony_ci void PrintMsaImmElm(Instruction* instr); 1221cb0ef41Sopenharmony_ci void PrintMsaCopy(Instruction* instr); 1231cb0ef41Sopenharmony_ci // Printing of instruction name. 1241cb0ef41Sopenharmony_ci void PrintInstructionName(Instruction* instr); 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_ci // Handle formatting of instructions and their options. 1271cb0ef41Sopenharmony_ci int FormatRegister(Instruction* instr, const char* option); 1281cb0ef41Sopenharmony_ci int FormatFPURegister(Instruction* instr, const char* option); 1291cb0ef41Sopenharmony_ci int FormatMSARegister(Instruction* instr, const char* option); 1301cb0ef41Sopenharmony_ci int FormatOption(Instruction* instr, const char* option); 1311cb0ef41Sopenharmony_ci void Format(Instruction* instr, const char* format); 1321cb0ef41Sopenharmony_ci void Unknown(Instruction* instr); 1331cb0ef41Sopenharmony_ci int DecodeBreakInstr(Instruction* instr); 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci // Each of these functions decodes one particular instruction type. 1361cb0ef41Sopenharmony_ci bool DecodeTypeRegisterRsType(Instruction* instr); 1371cb0ef41Sopenharmony_ci void DecodeTypeRegisterSRsType(Instruction* instr); 1381cb0ef41Sopenharmony_ci void DecodeTypeRegisterDRsType(Instruction* instr); 1391cb0ef41Sopenharmony_ci void DecodeTypeRegisterLRsType(Instruction* instr); 1401cb0ef41Sopenharmony_ci void DecodeTypeRegisterWRsType(Instruction* instr); 1411cb0ef41Sopenharmony_ci void DecodeTypeRegisterSPECIAL(Instruction* instr); 1421cb0ef41Sopenharmony_ci void DecodeTypeRegisterSPECIAL2(Instruction* instr); 1431cb0ef41Sopenharmony_ci void DecodeTypeRegisterSPECIAL3(Instruction* instr); 1441cb0ef41Sopenharmony_ci void DecodeTypeRegisterCOP1(Instruction* instr); 1451cb0ef41Sopenharmony_ci void DecodeTypeRegisterCOP1X(Instruction* instr); 1461cb0ef41Sopenharmony_ci int DecodeTypeRegister(Instruction* instr); 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ci void DecodeTypeImmediateCOP1(Instruction* instr); 1491cb0ef41Sopenharmony_ci void DecodeTypeImmediateREGIMM(Instruction* instr); 1501cb0ef41Sopenharmony_ci void DecodeTypeImmediateSPECIAL3(Instruction* instr); 1511cb0ef41Sopenharmony_ci void DecodeTypeImmediate(Instruction* instr); 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci void DecodeTypeJump(Instruction* instr); 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci void DecodeTypeMsaI8(Instruction* instr); 1561cb0ef41Sopenharmony_ci void DecodeTypeMsaI5(Instruction* instr); 1571cb0ef41Sopenharmony_ci void DecodeTypeMsaI10(Instruction* instr); 1581cb0ef41Sopenharmony_ci void DecodeTypeMsaELM(Instruction* instr); 1591cb0ef41Sopenharmony_ci void DecodeTypeMsaBIT(Instruction* instr); 1601cb0ef41Sopenharmony_ci void DecodeTypeMsaMI10(Instruction* instr); 1611cb0ef41Sopenharmony_ci void DecodeTypeMsa3R(Instruction* instr); 1621cb0ef41Sopenharmony_ci void DecodeTypeMsa3RF(Instruction* instr); 1631cb0ef41Sopenharmony_ci void DecodeTypeMsaVec(Instruction* instr); 1641cb0ef41Sopenharmony_ci void DecodeTypeMsa2R(Instruction* instr); 1651cb0ef41Sopenharmony_ci void DecodeTypeMsa2RF(Instruction* instr); 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci const disasm::NameConverter& converter_; 1681cb0ef41Sopenharmony_ci v8::base::Vector<char> out_buffer_; 1691cb0ef41Sopenharmony_ci int out_buffer_pos_; 1701cb0ef41Sopenharmony_ci}; 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci// Support for assertions in the Decoder formatting functions. 1731cb0ef41Sopenharmony_ci#define STRING_STARTS_WITH(string, compare_string) \ 1741cb0ef41Sopenharmony_ci (strncmp(string, compare_string, strlen(compare_string)) == 0) 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ci// Append the ch to the output buffer. 1771cb0ef41Sopenharmony_civoid Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; } 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci// Append the str to the output buffer. 1801cb0ef41Sopenharmony_civoid Decoder::Print(const char* str) { 1811cb0ef41Sopenharmony_ci char cur = *str++; 1821cb0ef41Sopenharmony_ci while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 1831cb0ef41Sopenharmony_ci PrintChar(cur); 1841cb0ef41Sopenharmony_ci cur = *str++; 1851cb0ef41Sopenharmony_ci } 1861cb0ef41Sopenharmony_ci out_buffer_[out_buffer_pos_] = 0; 1871cb0ef41Sopenharmony_ci} 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ci// Print the register name according to the active name converter. 1901cb0ef41Sopenharmony_civoid Decoder::PrintRegister(int reg) { 1911cb0ef41Sopenharmony_ci Print(converter_.NameOfCPURegister(reg)); 1921cb0ef41Sopenharmony_ci} 1931cb0ef41Sopenharmony_ci 1941cb0ef41Sopenharmony_civoid Decoder::PrintRs(Instruction* instr) { 1951cb0ef41Sopenharmony_ci int reg = instr->RsValue(); 1961cb0ef41Sopenharmony_ci PrintRegister(reg); 1971cb0ef41Sopenharmony_ci} 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_civoid Decoder::PrintRt(Instruction* instr) { 2001cb0ef41Sopenharmony_ci int reg = instr->RtValue(); 2011cb0ef41Sopenharmony_ci PrintRegister(reg); 2021cb0ef41Sopenharmony_ci} 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_civoid Decoder::PrintRd(Instruction* instr) { 2051cb0ef41Sopenharmony_ci int reg = instr->RdValue(); 2061cb0ef41Sopenharmony_ci PrintRegister(reg); 2071cb0ef41Sopenharmony_ci} 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci// Print the FPUregister name according to the active name converter. 2101cb0ef41Sopenharmony_civoid Decoder::PrintFPURegister(int freg) { 2111cb0ef41Sopenharmony_ci Print(converter_.NameOfXMMRegister(freg)); 2121cb0ef41Sopenharmony_ci} 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_civoid Decoder::PrintMSARegister(int wreg) { Print(MSARegisters::Name(wreg)); } 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_civoid Decoder::PrintFPUStatusRegister(int freg) { 2171cb0ef41Sopenharmony_ci switch (freg) { 2181cb0ef41Sopenharmony_ci case kFCSRRegister: 2191cb0ef41Sopenharmony_ci Print("FCSR"); 2201cb0ef41Sopenharmony_ci break; 2211cb0ef41Sopenharmony_ci default: 2221cb0ef41Sopenharmony_ci Print(converter_.NameOfXMMRegister(freg)); 2231cb0ef41Sopenharmony_ci } 2241cb0ef41Sopenharmony_ci} 2251cb0ef41Sopenharmony_ci 2261cb0ef41Sopenharmony_civoid Decoder::PrintMSAControlRegister(int creg) { 2271cb0ef41Sopenharmony_ci switch (creg) { 2281cb0ef41Sopenharmony_ci case kMSAIRRegister: 2291cb0ef41Sopenharmony_ci Print("MSAIR"); 2301cb0ef41Sopenharmony_ci break; 2311cb0ef41Sopenharmony_ci case kMSACSRRegister: 2321cb0ef41Sopenharmony_ci Print("MSACSR"); 2331cb0ef41Sopenharmony_ci break; 2341cb0ef41Sopenharmony_ci default: 2351cb0ef41Sopenharmony_ci Print("no_msacreg"); 2361cb0ef41Sopenharmony_ci } 2371cb0ef41Sopenharmony_ci} 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_civoid Decoder::PrintFs(Instruction* instr) { 2401cb0ef41Sopenharmony_ci int freg = instr->RsValue(); 2411cb0ef41Sopenharmony_ci PrintFPURegister(freg); 2421cb0ef41Sopenharmony_ci} 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_civoid Decoder::PrintFt(Instruction* instr) { 2451cb0ef41Sopenharmony_ci int freg = instr->RtValue(); 2461cb0ef41Sopenharmony_ci PrintFPURegister(freg); 2471cb0ef41Sopenharmony_ci} 2481cb0ef41Sopenharmony_ci 2491cb0ef41Sopenharmony_civoid Decoder::PrintFd(Instruction* instr) { 2501cb0ef41Sopenharmony_ci int freg = instr->RdValue(); 2511cb0ef41Sopenharmony_ci PrintFPURegister(freg); 2521cb0ef41Sopenharmony_ci} 2531cb0ef41Sopenharmony_ci 2541cb0ef41Sopenharmony_ci// Print the integer value of the sa field. 2551cb0ef41Sopenharmony_civoid Decoder::PrintSa(Instruction* instr) { 2561cb0ef41Sopenharmony_ci int sa = instr->SaValue(); 2571cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa); 2581cb0ef41Sopenharmony_ci} 2591cb0ef41Sopenharmony_ci 2601cb0ef41Sopenharmony_ci// Print the integer value of the sa field of a lsa instruction. 2611cb0ef41Sopenharmony_civoid Decoder::PrintLsaSa(Instruction* instr) { 2621cb0ef41Sopenharmony_ci int sa = instr->LsaSaValue() + 1; 2631cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sa); 2641cb0ef41Sopenharmony_ci} 2651cb0ef41Sopenharmony_ci 2661cb0ef41Sopenharmony_ci// Print the integer value of the rd field, when it is not used as reg. 2671cb0ef41Sopenharmony_civoid Decoder::PrintSd(Instruction* instr) { 2681cb0ef41Sopenharmony_ci int sd = instr->RdValue(); 2691cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sd); 2701cb0ef41Sopenharmony_ci} 2711cb0ef41Sopenharmony_ci 2721cb0ef41Sopenharmony_ci// Print the integer value of ext/dext/dextu size from the msbd field. 2731cb0ef41Sopenharmony_civoid Decoder::PrintSs1(Instruction* instr) { 2741cb0ef41Sopenharmony_ci int msbd = instr->RdValue(); 2751cb0ef41Sopenharmony_ci out_buffer_pos_ += 2761cb0ef41Sopenharmony_ci base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", msbd + 1); 2771cb0ef41Sopenharmony_ci} 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_ci// Print the integer value of ins/dins/dinsu size from the msb and lsb fields 2801cb0ef41Sopenharmony_ci// (for dinsu it is msbminus32 and lsbminus32 fields). 2811cb0ef41Sopenharmony_civoid Decoder::PrintSs2(Instruction* instr) { 2821cb0ef41Sopenharmony_ci int msb = instr->RdValue(); 2831cb0ef41Sopenharmony_ci int lsb = instr->SaValue(); 2841cb0ef41Sopenharmony_ci out_buffer_pos_ += 2851cb0ef41Sopenharmony_ci base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", msb - lsb + 1); 2861cb0ef41Sopenharmony_ci} 2871cb0ef41Sopenharmony_ci 2881cb0ef41Sopenharmony_ci// Print the integer value of dextm size from the msbdminus32 field. 2891cb0ef41Sopenharmony_civoid Decoder::PrintSs3(Instruction* instr) { 2901cb0ef41Sopenharmony_ci int msbdminus32 = instr->RdValue(); 2911cb0ef41Sopenharmony_ci out_buffer_pos_ += 2921cb0ef41Sopenharmony_ci base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", msbdminus32 + 32 + 1); 2931cb0ef41Sopenharmony_ci} 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci// Print the integer value of dinsm size from the msbminus32 and lsb fields. 2961cb0ef41Sopenharmony_civoid Decoder::PrintSs4(Instruction* instr) { 2971cb0ef41Sopenharmony_ci int msbminus32 = instr->RdValue(); 2981cb0ef41Sopenharmony_ci int lsb = instr->SaValue(); 2991cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", 3001cb0ef41Sopenharmony_ci msbminus32 + 32 - lsb + 1); 3011cb0ef41Sopenharmony_ci} 3021cb0ef41Sopenharmony_ci 3031cb0ef41Sopenharmony_ci// Print the integer value of dextu/dinsu pos from the lsbminus32 field. 3041cb0ef41Sopenharmony_civoid Decoder::PrintSs5(Instruction* instr) { 3051cb0ef41Sopenharmony_ci int lsbminus32 = instr->SaValue(); 3061cb0ef41Sopenharmony_ci out_buffer_pos_ += 3071cb0ef41Sopenharmony_ci base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", lsbminus32 + 32); 3081cb0ef41Sopenharmony_ci} 3091cb0ef41Sopenharmony_ci 3101cb0ef41Sopenharmony_ci// Print the integer value of the cc field for the bc1t/f instructions. 3111cb0ef41Sopenharmony_civoid Decoder::PrintBc(Instruction* instr) { 3121cb0ef41Sopenharmony_ci int cc = instr->FBccValue(); 3131cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", cc); 3141cb0ef41Sopenharmony_ci} 3151cb0ef41Sopenharmony_ci 3161cb0ef41Sopenharmony_ci// Print the integer value of the cc field for the FP compare instructions. 3171cb0ef41Sopenharmony_civoid Decoder::PrintCc(Instruction* instr) { 3181cb0ef41Sopenharmony_ci int cc = instr->FCccValue(); 3191cb0ef41Sopenharmony_ci out_buffer_pos_ += 3201cb0ef41Sopenharmony_ci base::SNPrintF(out_buffer_ + out_buffer_pos_, "cc(%d)", cc); 3211cb0ef41Sopenharmony_ci} 3221cb0ef41Sopenharmony_ci 3231cb0ef41Sopenharmony_ci// Print 9-bit unsigned immediate value. 3241cb0ef41Sopenharmony_civoid Decoder::PrintUImm9(Instruction* instr) { 3251cb0ef41Sopenharmony_ci int32_t imm = instr->Imm9Value(); 3261cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); 3271cb0ef41Sopenharmony_ci} 3281cb0ef41Sopenharmony_ci 3291cb0ef41Sopenharmony_ci// Print 9-bit signed immediate value. 3301cb0ef41Sopenharmony_civoid Decoder::PrintSImm9(Instruction* instr) { 3311cb0ef41Sopenharmony_ci int32_t imm = ((instr->Imm9Value()) << 23) >> 23; 3321cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); 3331cb0ef41Sopenharmony_ci} 3341cb0ef41Sopenharmony_ci 3351cb0ef41Sopenharmony_ci// Print 16-bit unsigned immediate value. 3361cb0ef41Sopenharmony_civoid Decoder::PrintUImm16(Instruction* instr) { 3371cb0ef41Sopenharmony_ci int32_t imm = instr->Imm16Value(); 3381cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); 3391cb0ef41Sopenharmony_ci} 3401cb0ef41Sopenharmony_ci 3411cb0ef41Sopenharmony_ci// Print 16-bit signed immediate value. 3421cb0ef41Sopenharmony_civoid Decoder::PrintSImm16(Instruction* instr) { 3431cb0ef41Sopenharmony_ci int32_t imm = 3441cb0ef41Sopenharmony_ci ((instr->Imm16Value()) << (32 - kImm16Bits)) >> (32 - kImm16Bits); 3451cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); 3461cb0ef41Sopenharmony_ci} 3471cb0ef41Sopenharmony_ci 3481cb0ef41Sopenharmony_ci// Print 16-bit hexa immediate value. 3491cb0ef41Sopenharmony_civoid Decoder::PrintXImm16(Instruction* instr) { 3501cb0ef41Sopenharmony_ci int32_t imm = instr->Imm16Value(); 3511cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 3521cb0ef41Sopenharmony_ci} 3531cb0ef41Sopenharmony_ci 3541cb0ef41Sopenharmony_ci// Print absoulte address for 16-bit offset or immediate value. 3551cb0ef41Sopenharmony_ci// The absolute address is calculated according following expression: 3561cb0ef41Sopenharmony_ci// PC + delta_pc + (offset << n_bits) 3571cb0ef41Sopenharmony_civoid Decoder::PrintPCImm16(Instruction* instr, int delta_pc, int n_bits) { 3581cb0ef41Sopenharmony_ci int16_t offset = instr->Imm16Value(); 3591cb0ef41Sopenharmony_ci out_buffer_pos_ += 3601cb0ef41Sopenharmony_ci base::SNPrintF(out_buffer_ + out_buffer_pos_, "%s", 3611cb0ef41Sopenharmony_ci converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + 3621cb0ef41Sopenharmony_ci delta_pc + (offset << n_bits))); 3631cb0ef41Sopenharmony_ci} 3641cb0ef41Sopenharmony_ci 3651cb0ef41Sopenharmony_ci// Print 18-bit signed immediate value. 3661cb0ef41Sopenharmony_civoid Decoder::PrintSImm18(Instruction* instr) { 3671cb0ef41Sopenharmony_ci int32_t imm = 3681cb0ef41Sopenharmony_ci ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits); 3691cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); 3701cb0ef41Sopenharmony_ci} 3711cb0ef41Sopenharmony_ci 3721cb0ef41Sopenharmony_ci// Print 18-bit hexa immediate value. 3731cb0ef41Sopenharmony_civoid Decoder::PrintXImm18(Instruction* instr) { 3741cb0ef41Sopenharmony_ci int32_t imm = instr->Imm18Value(); 3751cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 3761cb0ef41Sopenharmony_ci} 3771cb0ef41Sopenharmony_ci 3781cb0ef41Sopenharmony_ci// Print 19-bit hexa immediate value. 3791cb0ef41Sopenharmony_civoid Decoder::PrintXImm19(Instruction* instr) { 3801cb0ef41Sopenharmony_ci int32_t imm = instr->Imm19Value(); 3811cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 3821cb0ef41Sopenharmony_ci} 3831cb0ef41Sopenharmony_ci 3841cb0ef41Sopenharmony_ci// Print 19-bit signed immediate value. 3851cb0ef41Sopenharmony_civoid Decoder::PrintSImm19(Instruction* instr) { 3861cb0ef41Sopenharmony_ci int32_t imm19 = instr->Imm19Value(); 3871cb0ef41Sopenharmony_ci // set sign 3881cb0ef41Sopenharmony_ci imm19 <<= (32 - kImm19Bits); 3891cb0ef41Sopenharmony_ci imm19 >>= (32 - kImm19Bits); 3901cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm19); 3911cb0ef41Sopenharmony_ci} 3921cb0ef41Sopenharmony_ci 3931cb0ef41Sopenharmony_ci// Print 21-bit immediate value. 3941cb0ef41Sopenharmony_civoid Decoder::PrintXImm21(Instruction* instr) { 3951cb0ef41Sopenharmony_ci uint32_t imm = instr->Imm21Value(); 3961cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 3971cb0ef41Sopenharmony_ci} 3981cb0ef41Sopenharmony_ci 3991cb0ef41Sopenharmony_ci// Print 21-bit signed immediate value. 4001cb0ef41Sopenharmony_civoid Decoder::PrintSImm21(Instruction* instr) { 4011cb0ef41Sopenharmony_ci int32_t imm21 = instr->Imm21Value(); 4021cb0ef41Sopenharmony_ci // set sign 4031cb0ef41Sopenharmony_ci imm21 <<= (32 - kImm21Bits); 4041cb0ef41Sopenharmony_ci imm21 >>= (32 - kImm21Bits); 4051cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm21); 4061cb0ef41Sopenharmony_ci} 4071cb0ef41Sopenharmony_ci 4081cb0ef41Sopenharmony_ci// Print absoulte address for 21-bit offset or immediate value. 4091cb0ef41Sopenharmony_ci// The absolute address is calculated according following expression: 4101cb0ef41Sopenharmony_ci// PC + delta_pc + (offset << n_bits) 4111cb0ef41Sopenharmony_civoid Decoder::PrintPCImm21(Instruction* instr, int delta_pc, int n_bits) { 4121cb0ef41Sopenharmony_ci int32_t imm21 = instr->Imm21Value(); 4131cb0ef41Sopenharmony_ci // set sign 4141cb0ef41Sopenharmony_ci imm21 <<= (32 - kImm21Bits); 4151cb0ef41Sopenharmony_ci imm21 >>= (32 - kImm21Bits); 4161cb0ef41Sopenharmony_ci out_buffer_pos_ += 4171cb0ef41Sopenharmony_ci base::SNPrintF(out_buffer_ + out_buffer_pos_, "%s", 4181cb0ef41Sopenharmony_ci converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + 4191cb0ef41Sopenharmony_ci delta_pc + (imm21 << n_bits))); 4201cb0ef41Sopenharmony_ci} 4211cb0ef41Sopenharmony_ci 4221cb0ef41Sopenharmony_ci// Print 26-bit hex immediate value. 4231cb0ef41Sopenharmony_civoid Decoder::PrintXImm26(Instruction* instr) { 4241cb0ef41Sopenharmony_ci uint64_t target = static_cast<uint64_t>(instr->Imm26Value()) 4251cb0ef41Sopenharmony_ci << kImmFieldShift; 4261cb0ef41Sopenharmony_ci target = (reinterpret_cast<uint64_t>(instr) & ~0xFFFFFFF) | target; 4271cb0ef41Sopenharmony_ci out_buffer_pos_ += 4281cb0ef41Sopenharmony_ci base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%" PRIx64, target); 4291cb0ef41Sopenharmony_ci} 4301cb0ef41Sopenharmony_ci 4311cb0ef41Sopenharmony_ci// Print 26-bit signed immediate value. 4321cb0ef41Sopenharmony_civoid Decoder::PrintSImm26(Instruction* instr) { 4331cb0ef41Sopenharmony_ci int32_t imm26 = instr->Imm26Value(); 4341cb0ef41Sopenharmony_ci // set sign 4351cb0ef41Sopenharmony_ci imm26 <<= (32 - kImm26Bits); 4361cb0ef41Sopenharmony_ci imm26 >>= (32 - kImm26Bits); 4371cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm26); 4381cb0ef41Sopenharmony_ci} 4391cb0ef41Sopenharmony_ci 4401cb0ef41Sopenharmony_ci// Print absoulte address for 26-bit offset or immediate value. 4411cb0ef41Sopenharmony_ci// The absolute address is calculated according following expression: 4421cb0ef41Sopenharmony_ci// PC + delta_pc + (offset << n_bits) 4431cb0ef41Sopenharmony_civoid Decoder::PrintPCImm26(Instruction* instr, int delta_pc, int n_bits) { 4441cb0ef41Sopenharmony_ci int32_t imm26 = instr->Imm26Value(); 4451cb0ef41Sopenharmony_ci // set sign 4461cb0ef41Sopenharmony_ci imm26 <<= (32 - kImm26Bits); 4471cb0ef41Sopenharmony_ci imm26 >>= (32 - kImm26Bits); 4481cb0ef41Sopenharmony_ci out_buffer_pos_ += 4491cb0ef41Sopenharmony_ci base::SNPrintF(out_buffer_ + out_buffer_pos_, "%s", 4501cb0ef41Sopenharmony_ci converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + 4511cb0ef41Sopenharmony_ci delta_pc + (imm26 << n_bits))); 4521cb0ef41Sopenharmony_ci} 4531cb0ef41Sopenharmony_ci 4541cb0ef41Sopenharmony_ci// Print absoulte address for 26-bit offset or immediate value. 4551cb0ef41Sopenharmony_ci// The absolute address is calculated according following expression: 4561cb0ef41Sopenharmony_ci// PC[GPRLEN-1 .. 28] || instr_index26 || 00 4571cb0ef41Sopenharmony_civoid Decoder::PrintPCImm26(Instruction* instr) { 4581cb0ef41Sopenharmony_ci int32_t imm26 = instr->Imm26Value(); 4591cb0ef41Sopenharmony_ci uint64_t pc_mask = ~0xFFFFFFF; 4601cb0ef41Sopenharmony_ci uint64_t pc = ((uint64_t)(instr + 1) & pc_mask) | (imm26 << 2); 4611cb0ef41Sopenharmony_ci out_buffer_pos_ += 4621cb0ef41Sopenharmony_ci base::SNPrintF(out_buffer_ + out_buffer_pos_, "%s", 4631cb0ef41Sopenharmony_ci converter_.NameOfAddress((reinterpret_cast<byte*>(pc)))); 4641cb0ef41Sopenharmony_ci} 4651cb0ef41Sopenharmony_ci 4661cb0ef41Sopenharmony_civoid Decoder::PrintBp2(Instruction* instr) { 4671cb0ef41Sopenharmony_ci int bp2 = instr->Bp2Value(); 4681cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp2); 4691cb0ef41Sopenharmony_ci} 4701cb0ef41Sopenharmony_ci 4711cb0ef41Sopenharmony_civoid Decoder::PrintBp3(Instruction* instr) { 4721cb0ef41Sopenharmony_ci int bp3 = instr->Bp3Value(); 4731cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp3); 4741cb0ef41Sopenharmony_ci} 4751cb0ef41Sopenharmony_ci 4761cb0ef41Sopenharmony_ci// Print 26-bit immediate value. 4771cb0ef41Sopenharmony_civoid Decoder::PrintCode(Instruction* instr) { 4781cb0ef41Sopenharmony_ci if (instr->OpcodeFieldRaw() != SPECIAL) 4791cb0ef41Sopenharmony_ci return; // Not a break or trap instruction. 4801cb0ef41Sopenharmony_ci switch (instr->FunctionFieldRaw()) { 4811cb0ef41Sopenharmony_ci case BREAK: { 4821cb0ef41Sopenharmony_ci int32_t code = instr->Bits(25, 6); 4831cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, 4841cb0ef41Sopenharmony_ci "0x%05x (%d)", code, code); 4851cb0ef41Sopenharmony_ci break; 4861cb0ef41Sopenharmony_ci } 4871cb0ef41Sopenharmony_ci case TGE: 4881cb0ef41Sopenharmony_ci case TGEU: 4891cb0ef41Sopenharmony_ci case TLT: 4901cb0ef41Sopenharmony_ci case TLTU: 4911cb0ef41Sopenharmony_ci case TEQ: 4921cb0ef41Sopenharmony_ci case TNE: { 4931cb0ef41Sopenharmony_ci int32_t code = instr->Bits(15, 6); 4941cb0ef41Sopenharmony_ci out_buffer_pos_ += 4951cb0ef41Sopenharmony_ci base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%03x", code); 4961cb0ef41Sopenharmony_ci break; 4971cb0ef41Sopenharmony_ci } 4981cb0ef41Sopenharmony_ci default: // Not a break or trap instruction. 4991cb0ef41Sopenharmony_ci break; 5001cb0ef41Sopenharmony_ci } 5011cb0ef41Sopenharmony_ci} 5021cb0ef41Sopenharmony_ci 5031cb0ef41Sopenharmony_civoid Decoder::PrintMsaXImm8(Instruction* instr) { 5041cb0ef41Sopenharmony_ci int32_t imm = instr->MsaImm8Value(); 5051cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); 5061cb0ef41Sopenharmony_ci} 5071cb0ef41Sopenharmony_ci 5081cb0ef41Sopenharmony_civoid Decoder::PrintMsaImm8(Instruction* instr) { 5091cb0ef41Sopenharmony_ci int32_t imm = instr->MsaImm8Value(); 5101cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); 5111cb0ef41Sopenharmony_ci} 5121cb0ef41Sopenharmony_ci 5131cb0ef41Sopenharmony_civoid Decoder::PrintMsaImm5(Instruction* instr) { 5141cb0ef41Sopenharmony_ci int32_t imm = instr->MsaImm5Value(); 5151cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", imm); 5161cb0ef41Sopenharmony_ci} 5171cb0ef41Sopenharmony_ci 5181cb0ef41Sopenharmony_civoid Decoder::PrintMsaSImm5(Instruction* instr) { 5191cb0ef41Sopenharmony_ci int32_t imm = instr->MsaImm5Value(); 5201cb0ef41Sopenharmony_ci imm <<= (32 - kMsaImm5Bits); 5211cb0ef41Sopenharmony_ci imm >>= (32 - kMsaImm5Bits); 5221cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); 5231cb0ef41Sopenharmony_ci} 5241cb0ef41Sopenharmony_ci 5251cb0ef41Sopenharmony_civoid Decoder::PrintMsaSImm10(Instruction* instr, bool is_mi10) { 5261cb0ef41Sopenharmony_ci int32_t imm = is_mi10 ? instr->MsaImmMI10Value() : instr->MsaImm10Value(); 5271cb0ef41Sopenharmony_ci imm <<= (32 - kMsaImm10Bits); 5281cb0ef41Sopenharmony_ci imm >>= (32 - kMsaImm10Bits); 5291cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm); 5301cb0ef41Sopenharmony_ci} 5311cb0ef41Sopenharmony_ci 5321cb0ef41Sopenharmony_civoid Decoder::PrintMsaImmBit(Instruction* instr) { 5331cb0ef41Sopenharmony_ci int32_t m = instr->MsaBitMValue(); 5341cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", m); 5351cb0ef41Sopenharmony_ci} 5361cb0ef41Sopenharmony_ci 5371cb0ef41Sopenharmony_civoid Decoder::PrintMsaImmElm(Instruction* instr) { 5381cb0ef41Sopenharmony_ci int32_t n = instr->MsaElmNValue(); 5391cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%u", n); 5401cb0ef41Sopenharmony_ci} 5411cb0ef41Sopenharmony_ci 5421cb0ef41Sopenharmony_civoid Decoder::PrintMsaCopy(Instruction* instr) { 5431cb0ef41Sopenharmony_ci int32_t rd = instr->WdValue(); 5441cb0ef41Sopenharmony_ci int32_t ws = instr->WsValue(); 5451cb0ef41Sopenharmony_ci int32_t n = instr->MsaElmNValue(); 5461cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%s, %s[%u]", 5471cb0ef41Sopenharmony_ci converter_.NameOfCPURegister(rd), 5481cb0ef41Sopenharmony_ci MSARegisters::Name(ws), n); 5491cb0ef41Sopenharmony_ci} 5501cb0ef41Sopenharmony_ci 5511cb0ef41Sopenharmony_civoid Decoder::PrintFormat(Instruction* instr) { 5521cb0ef41Sopenharmony_ci char formatLetter = ' '; 5531cb0ef41Sopenharmony_ci switch (instr->RsFieldRaw()) { 5541cb0ef41Sopenharmony_ci case S: 5551cb0ef41Sopenharmony_ci formatLetter = 's'; 5561cb0ef41Sopenharmony_ci break; 5571cb0ef41Sopenharmony_ci case D: 5581cb0ef41Sopenharmony_ci formatLetter = 'd'; 5591cb0ef41Sopenharmony_ci break; 5601cb0ef41Sopenharmony_ci case W: 5611cb0ef41Sopenharmony_ci formatLetter = 'w'; 5621cb0ef41Sopenharmony_ci break; 5631cb0ef41Sopenharmony_ci case L: 5641cb0ef41Sopenharmony_ci formatLetter = 'l'; 5651cb0ef41Sopenharmony_ci break; 5661cb0ef41Sopenharmony_ci default: 5671cb0ef41Sopenharmony_ci UNREACHABLE(); 5681cb0ef41Sopenharmony_ci } 5691cb0ef41Sopenharmony_ci PrintChar(formatLetter); 5701cb0ef41Sopenharmony_ci} 5711cb0ef41Sopenharmony_ci 5721cb0ef41Sopenharmony_civoid Decoder::PrintMsaDataFormat(Instruction* instr) { 5731cb0ef41Sopenharmony_ci DCHECK(instr->IsMSAInstr()); 5741cb0ef41Sopenharmony_ci char df = ' '; 5751cb0ef41Sopenharmony_ci if (instr->IsMSABranchInstr()) { 5761cb0ef41Sopenharmony_ci switch (instr->RsFieldRaw()) { 5771cb0ef41Sopenharmony_ci case BZ_V: 5781cb0ef41Sopenharmony_ci case BNZ_V: 5791cb0ef41Sopenharmony_ci df = 'v'; 5801cb0ef41Sopenharmony_ci break; 5811cb0ef41Sopenharmony_ci case BZ_B: 5821cb0ef41Sopenharmony_ci case BNZ_B: 5831cb0ef41Sopenharmony_ci df = 'b'; 5841cb0ef41Sopenharmony_ci break; 5851cb0ef41Sopenharmony_ci case BZ_H: 5861cb0ef41Sopenharmony_ci case BNZ_H: 5871cb0ef41Sopenharmony_ci df = 'h'; 5881cb0ef41Sopenharmony_ci break; 5891cb0ef41Sopenharmony_ci case BZ_W: 5901cb0ef41Sopenharmony_ci case BNZ_W: 5911cb0ef41Sopenharmony_ci df = 'w'; 5921cb0ef41Sopenharmony_ci break; 5931cb0ef41Sopenharmony_ci case BZ_D: 5941cb0ef41Sopenharmony_ci case BNZ_D: 5951cb0ef41Sopenharmony_ci df = 'd'; 5961cb0ef41Sopenharmony_ci break; 5971cb0ef41Sopenharmony_ci default: 5981cb0ef41Sopenharmony_ci UNREACHABLE(); 5991cb0ef41Sopenharmony_ci } 6001cb0ef41Sopenharmony_ci } else { 6011cb0ef41Sopenharmony_ci char DF[] = {'b', 'h', 'w', 'd'}; 6021cb0ef41Sopenharmony_ci switch (instr->MSAMinorOpcodeField()) { 6031cb0ef41Sopenharmony_ci case kMsaMinorI5: 6041cb0ef41Sopenharmony_ci case kMsaMinorI10: 6051cb0ef41Sopenharmony_ci case kMsaMinor3R: 6061cb0ef41Sopenharmony_ci df = DF[instr->Bits(22, 21)]; 6071cb0ef41Sopenharmony_ci break; 6081cb0ef41Sopenharmony_ci case kMsaMinorMI10: 6091cb0ef41Sopenharmony_ci df = DF[instr->Bits(1, 0)]; 6101cb0ef41Sopenharmony_ci break; 6111cb0ef41Sopenharmony_ci case kMsaMinorBIT: 6121cb0ef41Sopenharmony_ci df = DF[instr->MsaBitDf()]; 6131cb0ef41Sopenharmony_ci break; 6141cb0ef41Sopenharmony_ci case kMsaMinorELM: 6151cb0ef41Sopenharmony_ci df = DF[instr->MsaElmDf()]; 6161cb0ef41Sopenharmony_ci break; 6171cb0ef41Sopenharmony_ci case kMsaMinor3RF: { 6181cb0ef41Sopenharmony_ci uint32_t opcode = instr->InstructionBits() & kMsa3RFMask; 6191cb0ef41Sopenharmony_ci switch (opcode) { 6201cb0ef41Sopenharmony_ci case FEXDO: 6211cb0ef41Sopenharmony_ci case FTQ: 6221cb0ef41Sopenharmony_ci case MUL_Q: 6231cb0ef41Sopenharmony_ci case MADD_Q: 6241cb0ef41Sopenharmony_ci case MSUB_Q: 6251cb0ef41Sopenharmony_ci case MULR_Q: 6261cb0ef41Sopenharmony_ci case MADDR_Q: 6271cb0ef41Sopenharmony_ci case MSUBR_Q: 6281cb0ef41Sopenharmony_ci df = DF[1 + instr->Bit(21)]; 6291cb0ef41Sopenharmony_ci break; 6301cb0ef41Sopenharmony_ci default: 6311cb0ef41Sopenharmony_ci df = DF[2 + instr->Bit(21)]; 6321cb0ef41Sopenharmony_ci break; 6331cb0ef41Sopenharmony_ci } 6341cb0ef41Sopenharmony_ci } break; 6351cb0ef41Sopenharmony_ci case kMsaMinor2R: 6361cb0ef41Sopenharmony_ci df = DF[instr->Bits(17, 16)]; 6371cb0ef41Sopenharmony_ci break; 6381cb0ef41Sopenharmony_ci case kMsaMinor2RF: 6391cb0ef41Sopenharmony_ci df = DF[2 + instr->Bit(16)]; 6401cb0ef41Sopenharmony_ci break; 6411cb0ef41Sopenharmony_ci default: 6421cb0ef41Sopenharmony_ci UNREACHABLE(); 6431cb0ef41Sopenharmony_ci } 6441cb0ef41Sopenharmony_ci } 6451cb0ef41Sopenharmony_ci 6461cb0ef41Sopenharmony_ci PrintChar(df); 6471cb0ef41Sopenharmony_ci} 6481cb0ef41Sopenharmony_ci 6491cb0ef41Sopenharmony_ci// Printing of instruction name. 6501cb0ef41Sopenharmony_civoid Decoder::PrintInstructionName(Instruction* instr) {} 6511cb0ef41Sopenharmony_ci 6521cb0ef41Sopenharmony_ci// Handle all register based formatting in this function to reduce the 6531cb0ef41Sopenharmony_ci// complexity of FormatOption. 6541cb0ef41Sopenharmony_ciint Decoder::FormatRegister(Instruction* instr, const char* format) { 6551cb0ef41Sopenharmony_ci DCHECK_EQ(format[0], 'r'); 6561cb0ef41Sopenharmony_ci if (format[1] == 's') { // 'rs: Rs register. 6571cb0ef41Sopenharmony_ci int reg = instr->RsValue(); 6581cb0ef41Sopenharmony_ci PrintRegister(reg); 6591cb0ef41Sopenharmony_ci return 2; 6601cb0ef41Sopenharmony_ci } else if (format[1] == 't') { // 'rt: rt register. 6611cb0ef41Sopenharmony_ci int reg = instr->RtValue(); 6621cb0ef41Sopenharmony_ci PrintRegister(reg); 6631cb0ef41Sopenharmony_ci return 2; 6641cb0ef41Sopenharmony_ci } else if (format[1] == 'd') { // 'rd: rd register. 6651cb0ef41Sopenharmony_ci int reg = instr->RdValue(); 6661cb0ef41Sopenharmony_ci PrintRegister(reg); 6671cb0ef41Sopenharmony_ci return 2; 6681cb0ef41Sopenharmony_ci } 6691cb0ef41Sopenharmony_ci UNREACHABLE(); 6701cb0ef41Sopenharmony_ci} 6711cb0ef41Sopenharmony_ci 6721cb0ef41Sopenharmony_ci// Handle all FPUregister based formatting in this function to reduce the 6731cb0ef41Sopenharmony_ci// complexity of FormatOption. 6741cb0ef41Sopenharmony_ciint Decoder::FormatFPURegister(Instruction* instr, const char* format) { 6751cb0ef41Sopenharmony_ci DCHECK_EQ(format[0], 'f'); 6761cb0ef41Sopenharmony_ci if ((CTC1 == instr->RsFieldRaw()) || (CFC1 == instr->RsFieldRaw())) { 6771cb0ef41Sopenharmony_ci if (format[1] == 's') { // 'fs: fs register. 6781cb0ef41Sopenharmony_ci int reg = instr->FsValue(); 6791cb0ef41Sopenharmony_ci PrintFPUStatusRegister(reg); 6801cb0ef41Sopenharmony_ci return 2; 6811cb0ef41Sopenharmony_ci } else if (format[1] == 't') { // 'ft: ft register. 6821cb0ef41Sopenharmony_ci int reg = instr->FtValue(); 6831cb0ef41Sopenharmony_ci PrintFPUStatusRegister(reg); 6841cb0ef41Sopenharmony_ci return 2; 6851cb0ef41Sopenharmony_ci } else if (format[1] == 'd') { // 'fd: fd register. 6861cb0ef41Sopenharmony_ci int reg = instr->FdValue(); 6871cb0ef41Sopenharmony_ci PrintFPUStatusRegister(reg); 6881cb0ef41Sopenharmony_ci return 2; 6891cb0ef41Sopenharmony_ci } else if (format[1] == 'r') { // 'fr: fr register. 6901cb0ef41Sopenharmony_ci int reg = instr->FrValue(); 6911cb0ef41Sopenharmony_ci PrintFPUStatusRegister(reg); 6921cb0ef41Sopenharmony_ci return 2; 6931cb0ef41Sopenharmony_ci } 6941cb0ef41Sopenharmony_ci } else { 6951cb0ef41Sopenharmony_ci if (format[1] == 's') { // 'fs: fs register. 6961cb0ef41Sopenharmony_ci int reg = instr->FsValue(); 6971cb0ef41Sopenharmony_ci PrintFPURegister(reg); 6981cb0ef41Sopenharmony_ci return 2; 6991cb0ef41Sopenharmony_ci } else if (format[1] == 't') { // 'ft: ft register. 7001cb0ef41Sopenharmony_ci int reg = instr->FtValue(); 7011cb0ef41Sopenharmony_ci PrintFPURegister(reg); 7021cb0ef41Sopenharmony_ci return 2; 7031cb0ef41Sopenharmony_ci } else if (format[1] == 'd') { // 'fd: fd register. 7041cb0ef41Sopenharmony_ci int reg = instr->FdValue(); 7051cb0ef41Sopenharmony_ci PrintFPURegister(reg); 7061cb0ef41Sopenharmony_ci return 2; 7071cb0ef41Sopenharmony_ci } else if (format[1] == 'r') { // 'fr: fr register. 7081cb0ef41Sopenharmony_ci int reg = instr->FrValue(); 7091cb0ef41Sopenharmony_ci PrintFPURegister(reg); 7101cb0ef41Sopenharmony_ci return 2; 7111cb0ef41Sopenharmony_ci } 7121cb0ef41Sopenharmony_ci } 7131cb0ef41Sopenharmony_ci UNREACHABLE(); 7141cb0ef41Sopenharmony_ci} 7151cb0ef41Sopenharmony_ci 7161cb0ef41Sopenharmony_ci// Handle all MSARegister based formatting in this function to reduce the 7171cb0ef41Sopenharmony_ci// complexity of FormatOption. 7181cb0ef41Sopenharmony_ciint Decoder::FormatMSARegister(Instruction* instr, const char* format) { 7191cb0ef41Sopenharmony_ci DCHECK_EQ(format[0], 'w'); 7201cb0ef41Sopenharmony_ci if (format[1] == 's') { 7211cb0ef41Sopenharmony_ci int reg = instr->WsValue(); 7221cb0ef41Sopenharmony_ci PrintMSARegister(reg); 7231cb0ef41Sopenharmony_ci return 2; 7241cb0ef41Sopenharmony_ci } else if (format[1] == 't') { 7251cb0ef41Sopenharmony_ci int reg = instr->WtValue(); 7261cb0ef41Sopenharmony_ci PrintMSARegister(reg); 7271cb0ef41Sopenharmony_ci return 2; 7281cb0ef41Sopenharmony_ci } else if (format[1] == 'd') { 7291cb0ef41Sopenharmony_ci int reg = instr->WdValue(); 7301cb0ef41Sopenharmony_ci PrintMSARegister(reg); 7311cb0ef41Sopenharmony_ci return 2; 7321cb0ef41Sopenharmony_ci } 7331cb0ef41Sopenharmony_ci 7341cb0ef41Sopenharmony_ci UNREACHABLE(); 7351cb0ef41Sopenharmony_ci} 7361cb0ef41Sopenharmony_ci 7371cb0ef41Sopenharmony_ci// FormatOption takes a formatting string and interprets it based on 7381cb0ef41Sopenharmony_ci// the current instructions. The format string points to the first 7391cb0ef41Sopenharmony_ci// character of the option string (the option escape has already been 7401cb0ef41Sopenharmony_ci// consumed by the caller.) FormatOption returns the number of 7411cb0ef41Sopenharmony_ci// characters that were consumed from the formatting string. 7421cb0ef41Sopenharmony_ciint Decoder::FormatOption(Instruction* instr, const char* format) { 7431cb0ef41Sopenharmony_ci switch (format[0]) { 7441cb0ef41Sopenharmony_ci case 'c': { // 'code for break or trap instructions. 7451cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "code")); 7461cb0ef41Sopenharmony_ci PrintCode(instr); 7471cb0ef41Sopenharmony_ci return 4; 7481cb0ef41Sopenharmony_ci } 7491cb0ef41Sopenharmony_ci case 'i': { // 'imm16u or 'imm26. 7501cb0ef41Sopenharmony_ci if (format[3] == '1') { 7511cb0ef41Sopenharmony_ci if (format[4] == '6') { 7521cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm16")); 7531cb0ef41Sopenharmony_ci switch (format[5]) { 7541cb0ef41Sopenharmony_ci case 's': 7551cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm16s")); 7561cb0ef41Sopenharmony_ci PrintSImm16(instr); 7571cb0ef41Sopenharmony_ci break; 7581cb0ef41Sopenharmony_ci case 'u': 7591cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm16u")); 7601cb0ef41Sopenharmony_ci PrintSImm16(instr); 7611cb0ef41Sopenharmony_ci break; 7621cb0ef41Sopenharmony_ci case 'x': 7631cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm16x")); 7641cb0ef41Sopenharmony_ci PrintXImm16(instr); 7651cb0ef41Sopenharmony_ci break; 7661cb0ef41Sopenharmony_ci case 'p': { // The PC relative address. 7671cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm16p")); 7681cb0ef41Sopenharmony_ci int delta_pc = 0; 7691cb0ef41Sopenharmony_ci int n_bits = 0; 7701cb0ef41Sopenharmony_ci switch (format[6]) { 7711cb0ef41Sopenharmony_ci case '4': { 7721cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm16p4")); 7731cb0ef41Sopenharmony_ci delta_pc = 4; 7741cb0ef41Sopenharmony_ci switch (format[8]) { 7751cb0ef41Sopenharmony_ci case '2': 7761cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm16p4s2")); 7771cb0ef41Sopenharmony_ci n_bits = 2; 7781cb0ef41Sopenharmony_ci PrintPCImm16(instr, delta_pc, n_bits); 7791cb0ef41Sopenharmony_ci return 9; 7801cb0ef41Sopenharmony_ci } 7811cb0ef41Sopenharmony_ci } 7821cb0ef41Sopenharmony_ci } 7831cb0ef41Sopenharmony_ci } 7841cb0ef41Sopenharmony_ci } 7851cb0ef41Sopenharmony_ci return 6; 7861cb0ef41Sopenharmony_ci } else if (format[4] == '8') { 7871cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm18")); 7881cb0ef41Sopenharmony_ci switch (format[5]) { 7891cb0ef41Sopenharmony_ci case 's': 7901cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm18s")); 7911cb0ef41Sopenharmony_ci PrintSImm18(instr); 7921cb0ef41Sopenharmony_ci break; 7931cb0ef41Sopenharmony_ci case 'x': 7941cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm18x")); 7951cb0ef41Sopenharmony_ci PrintXImm18(instr); 7961cb0ef41Sopenharmony_ci break; 7971cb0ef41Sopenharmony_ci } 7981cb0ef41Sopenharmony_ci return 6; 7991cb0ef41Sopenharmony_ci } else if (format[4] == '9') { 8001cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm19")); 8011cb0ef41Sopenharmony_ci switch (format[5]) { 8021cb0ef41Sopenharmony_ci case 's': 8031cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm19s")); 8041cb0ef41Sopenharmony_ci PrintSImm19(instr); 8051cb0ef41Sopenharmony_ci break; 8061cb0ef41Sopenharmony_ci case 'x': 8071cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm19x")); 8081cb0ef41Sopenharmony_ci PrintXImm19(instr); 8091cb0ef41Sopenharmony_ci break; 8101cb0ef41Sopenharmony_ci } 8111cb0ef41Sopenharmony_ci return 6; 8121cb0ef41Sopenharmony_ci } else if (format[4] == '0' && format[5] == 's') { 8131cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm10s")); 8141cb0ef41Sopenharmony_ci if (format[6] == '1') { 8151cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm10s1")); 8161cb0ef41Sopenharmony_ci PrintMsaSImm10(instr, false); 8171cb0ef41Sopenharmony_ci } else if (format[6] == '2') { 8181cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm10s2")); 8191cb0ef41Sopenharmony_ci PrintMsaSImm10(instr, true); 8201cb0ef41Sopenharmony_ci } 8211cb0ef41Sopenharmony_ci return 7; 8221cb0ef41Sopenharmony_ci } 8231cb0ef41Sopenharmony_ci } else if (format[3] == '2' && format[4] == '1') { 8241cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm21")); 8251cb0ef41Sopenharmony_ci switch (format[5]) { 8261cb0ef41Sopenharmony_ci case 's': 8271cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm21s")); 8281cb0ef41Sopenharmony_ci PrintSImm21(instr); 8291cb0ef41Sopenharmony_ci break; 8301cb0ef41Sopenharmony_ci case 'x': 8311cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm21x")); 8321cb0ef41Sopenharmony_ci PrintXImm21(instr); 8331cb0ef41Sopenharmony_ci break; 8341cb0ef41Sopenharmony_ci case 'p': { // The PC relative address. 8351cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm21p")); 8361cb0ef41Sopenharmony_ci int delta_pc = 0; 8371cb0ef41Sopenharmony_ci int n_bits = 0; 8381cb0ef41Sopenharmony_ci switch (format[6]) { 8391cb0ef41Sopenharmony_ci case '4': { 8401cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm21p4")); 8411cb0ef41Sopenharmony_ci delta_pc = 4; 8421cb0ef41Sopenharmony_ci switch (format[8]) { 8431cb0ef41Sopenharmony_ci case '2': 8441cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm21p4s2")); 8451cb0ef41Sopenharmony_ci n_bits = 2; 8461cb0ef41Sopenharmony_ci PrintPCImm21(instr, delta_pc, n_bits); 8471cb0ef41Sopenharmony_ci return 9; 8481cb0ef41Sopenharmony_ci } 8491cb0ef41Sopenharmony_ci } 8501cb0ef41Sopenharmony_ci } 8511cb0ef41Sopenharmony_ci } 8521cb0ef41Sopenharmony_ci } 8531cb0ef41Sopenharmony_ci return 6; 8541cb0ef41Sopenharmony_ci } else if (format[3] == '2' && format[4] == '6') { 8551cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm26")); 8561cb0ef41Sopenharmony_ci switch (format[5]) { 8571cb0ef41Sopenharmony_ci case 's': 8581cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm26s")); 8591cb0ef41Sopenharmony_ci PrintSImm26(instr); 8601cb0ef41Sopenharmony_ci break; 8611cb0ef41Sopenharmony_ci case 'x': 8621cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm26x")); 8631cb0ef41Sopenharmony_ci PrintXImm26(instr); 8641cb0ef41Sopenharmony_ci break; 8651cb0ef41Sopenharmony_ci case 'p': { // The PC relative address. 8661cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm26p")); 8671cb0ef41Sopenharmony_ci int delta_pc = 0; 8681cb0ef41Sopenharmony_ci int n_bits = 0; 8691cb0ef41Sopenharmony_ci switch (format[6]) { 8701cb0ef41Sopenharmony_ci case '4': { 8711cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm26p4")); 8721cb0ef41Sopenharmony_ci delta_pc = 4; 8731cb0ef41Sopenharmony_ci switch (format[8]) { 8741cb0ef41Sopenharmony_ci case '2': 8751cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm26p4s2")); 8761cb0ef41Sopenharmony_ci n_bits = 2; 8771cb0ef41Sopenharmony_ci PrintPCImm26(instr, delta_pc, n_bits); 8781cb0ef41Sopenharmony_ci return 9; 8791cb0ef41Sopenharmony_ci } 8801cb0ef41Sopenharmony_ci } 8811cb0ef41Sopenharmony_ci } 8821cb0ef41Sopenharmony_ci } 8831cb0ef41Sopenharmony_ci case 'j': { // Absolute address for jump instructions. 8841cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm26j")); 8851cb0ef41Sopenharmony_ci PrintPCImm26(instr); 8861cb0ef41Sopenharmony_ci break; 8871cb0ef41Sopenharmony_ci } 8881cb0ef41Sopenharmony_ci } 8891cb0ef41Sopenharmony_ci return 6; 8901cb0ef41Sopenharmony_ci } else if (format[3] == '5') { 8911cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm5")); 8921cb0ef41Sopenharmony_ci if (format[4] == 'u') { 8931cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm5u")); 8941cb0ef41Sopenharmony_ci PrintMsaImm5(instr); 8951cb0ef41Sopenharmony_ci } else if (format[4] == 's') { 8961cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm5s")); 8971cb0ef41Sopenharmony_ci PrintMsaSImm5(instr); 8981cb0ef41Sopenharmony_ci } 8991cb0ef41Sopenharmony_ci return 5; 9001cb0ef41Sopenharmony_ci } else if (format[3] == '8') { 9011cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm8")); 9021cb0ef41Sopenharmony_ci PrintMsaImm8(instr); 9031cb0ef41Sopenharmony_ci return 4; 9041cb0ef41Sopenharmony_ci } else if (format[3] == '9') { 9051cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm9")); 9061cb0ef41Sopenharmony_ci if (format[4] == 'u') { 9071cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm9u")); 9081cb0ef41Sopenharmony_ci PrintUImm9(instr); 9091cb0ef41Sopenharmony_ci } else if (format[4] == 's') { 9101cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imm9s")); 9111cb0ef41Sopenharmony_ci PrintSImm9(instr); 9121cb0ef41Sopenharmony_ci } 9131cb0ef41Sopenharmony_ci return 5; 9141cb0ef41Sopenharmony_ci } else if (format[3] == 'b') { 9151cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "immb")); 9161cb0ef41Sopenharmony_ci PrintMsaImmBit(instr); 9171cb0ef41Sopenharmony_ci return 4; 9181cb0ef41Sopenharmony_ci } else if (format[3] == 'e') { 9191cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "imme")); 9201cb0ef41Sopenharmony_ci PrintMsaImmElm(instr); 9211cb0ef41Sopenharmony_ci return 4; 9221cb0ef41Sopenharmony_ci } 9231cb0ef41Sopenharmony_ci UNREACHABLE(); 9241cb0ef41Sopenharmony_ci } 9251cb0ef41Sopenharmony_ci case 'r': { // 'r: registers. 9261cb0ef41Sopenharmony_ci return FormatRegister(instr, format); 9271cb0ef41Sopenharmony_ci } 9281cb0ef41Sopenharmony_ci case 'f': { // 'f: FPUregisters. 9291cb0ef41Sopenharmony_ci return FormatFPURegister(instr, format); 9301cb0ef41Sopenharmony_ci } 9311cb0ef41Sopenharmony_ci case 'w': { // 'w: MSA Register 9321cb0ef41Sopenharmony_ci return FormatMSARegister(instr, format); 9331cb0ef41Sopenharmony_ci } 9341cb0ef41Sopenharmony_ci case 's': { // 'sa. 9351cb0ef41Sopenharmony_ci switch (format[1]) { 9361cb0ef41Sopenharmony_ci case 'a': 9371cb0ef41Sopenharmony_ci if (format[2] == '2') { 9381cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "sa2")); // 'sa2 9391cb0ef41Sopenharmony_ci PrintLsaSa(instr); 9401cb0ef41Sopenharmony_ci return 3; 9411cb0ef41Sopenharmony_ci } else { 9421cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "sa")); 9431cb0ef41Sopenharmony_ci PrintSa(instr); 9441cb0ef41Sopenharmony_ci return 2; 9451cb0ef41Sopenharmony_ci } 9461cb0ef41Sopenharmony_ci case 'd': { 9471cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "sd")); 9481cb0ef41Sopenharmony_ci PrintSd(instr); 9491cb0ef41Sopenharmony_ci return 2; 9501cb0ef41Sopenharmony_ci } 9511cb0ef41Sopenharmony_ci case 's': { 9521cb0ef41Sopenharmony_ci if (format[2] == '1') { 9531cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "ss1")); // ext, dext, dextu size 9541cb0ef41Sopenharmony_ci PrintSs1(instr); 9551cb0ef41Sopenharmony_ci } else if (format[2] == '2') { 9561cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "ss2")); // ins, dins, dinsu size 9571cb0ef41Sopenharmony_ci PrintSs2(instr); 9581cb0ef41Sopenharmony_ci } else if (format[2] == '3') { 9591cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "ss3")); // dextm size 9601cb0ef41Sopenharmony_ci PrintSs3(instr); 9611cb0ef41Sopenharmony_ci } else if (format[2] == '4') { 9621cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "ss4")); // dinsm size 9631cb0ef41Sopenharmony_ci PrintSs4(instr); 9641cb0ef41Sopenharmony_ci } else { 9651cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "ss5")); // dextu, dinsu pos 9661cb0ef41Sopenharmony_ci PrintSs5(instr); 9671cb0ef41Sopenharmony_ci } 9681cb0ef41Sopenharmony_ci return 3; 9691cb0ef41Sopenharmony_ci } 9701cb0ef41Sopenharmony_ci } 9711cb0ef41Sopenharmony_ci } 9721cb0ef41Sopenharmony_ci case 'b': { 9731cb0ef41Sopenharmony_ci switch (format[1]) { 9741cb0ef41Sopenharmony_ci case 'c': { // 'bc - Special for bc1 cc field. 9751cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "bc")); 9761cb0ef41Sopenharmony_ci PrintBc(instr); 9771cb0ef41Sopenharmony_ci return 2; 9781cb0ef41Sopenharmony_ci } 9791cb0ef41Sopenharmony_ci case 'p': { 9801cb0ef41Sopenharmony_ci switch (format[2]) { 9811cb0ef41Sopenharmony_ci case '2': { // 'bp2 9821cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "bp2")); 9831cb0ef41Sopenharmony_ci PrintBp2(instr); 9841cb0ef41Sopenharmony_ci return 3; 9851cb0ef41Sopenharmony_ci } 9861cb0ef41Sopenharmony_ci case '3': { // 'bp3 9871cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "bp3")); 9881cb0ef41Sopenharmony_ci PrintBp3(instr); 9891cb0ef41Sopenharmony_ci return 3; 9901cb0ef41Sopenharmony_ci } 9911cb0ef41Sopenharmony_ci } 9921cb0ef41Sopenharmony_ci } 9931cb0ef41Sopenharmony_ci } 9941cb0ef41Sopenharmony_ci } 9951cb0ef41Sopenharmony_ci case 'C': { // 'Cc - Special for c.xx.d cc field. 9961cb0ef41Sopenharmony_ci DCHECK(STRING_STARTS_WITH(format, "Cc")); 9971cb0ef41Sopenharmony_ci PrintCc(instr); 9981cb0ef41Sopenharmony_ci return 2; 9991cb0ef41Sopenharmony_ci } 10001cb0ef41Sopenharmony_ci case 't': 10011cb0ef41Sopenharmony_ci if (instr->IsMSAInstr()) { 10021cb0ef41Sopenharmony_ci PrintMsaDataFormat(instr); 10031cb0ef41Sopenharmony_ci } else { 10041cb0ef41Sopenharmony_ci PrintFormat(instr); 10051cb0ef41Sopenharmony_ci } 10061cb0ef41Sopenharmony_ci return 1; 10071cb0ef41Sopenharmony_ci } 10081cb0ef41Sopenharmony_ci UNREACHABLE(); 10091cb0ef41Sopenharmony_ci} 10101cb0ef41Sopenharmony_ci 10111cb0ef41Sopenharmony_ci// Format takes a formatting string for a whole instruction and prints it into 10121cb0ef41Sopenharmony_ci// the output buffer. All escaped options are handed to FormatOption to be 10131cb0ef41Sopenharmony_ci// parsed further. 10141cb0ef41Sopenharmony_civoid Decoder::Format(Instruction* instr, const char* format) { 10151cb0ef41Sopenharmony_ci char cur = *format++; 10161cb0ef41Sopenharmony_ci while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) { 10171cb0ef41Sopenharmony_ci if (cur == '\'') { // Single quote is used as the formatting escape. 10181cb0ef41Sopenharmony_ci format += FormatOption(instr, format); 10191cb0ef41Sopenharmony_ci } else { 10201cb0ef41Sopenharmony_ci out_buffer_[out_buffer_pos_++] = cur; 10211cb0ef41Sopenharmony_ci } 10221cb0ef41Sopenharmony_ci cur = *format++; 10231cb0ef41Sopenharmony_ci } 10241cb0ef41Sopenharmony_ci out_buffer_[out_buffer_pos_] = '\0'; 10251cb0ef41Sopenharmony_ci} 10261cb0ef41Sopenharmony_ci 10271cb0ef41Sopenharmony_ci// For currently unimplemented decodings the disassembler calls Unknown(instr) 10281cb0ef41Sopenharmony_ci// which will just print "unknown" of the instruction bits. 10291cb0ef41Sopenharmony_civoid Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); } 10301cb0ef41Sopenharmony_ci 10311cb0ef41Sopenharmony_ciint Decoder::DecodeBreakInstr(Instruction* instr) { 10321cb0ef41Sopenharmony_ci // This is already known to be BREAK instr, just extract the code. 10331cb0ef41Sopenharmony_ci if (instr->Bits(25, 6) == static_cast<int>(kMaxStopCode)) { 10341cb0ef41Sopenharmony_ci // This is stop(msg). 10351cb0ef41Sopenharmony_ci Format(instr, "break, code: 'code"); 10361cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF( 10371cb0ef41Sopenharmony_ci out_buffer_ + out_buffer_pos_, "\n%p %08" PRIx64, 10381cb0ef41Sopenharmony_ci static_cast<void*>(reinterpret_cast<int32_t*>(instr + kInstrSize)), 10391cb0ef41Sopenharmony_ci reinterpret_cast<uint64_t>( 10401cb0ef41Sopenharmony_ci *reinterpret_cast<char**>(instr + kInstrSize))); 10411cb0ef41Sopenharmony_ci // Size 3: the break_ instr, plus embedded 64-bit char pointer. 10421cb0ef41Sopenharmony_ci return 3 * kInstrSize; 10431cb0ef41Sopenharmony_ci } else { 10441cb0ef41Sopenharmony_ci Format(instr, "break, code: 'code"); 10451cb0ef41Sopenharmony_ci return kInstrSize; 10461cb0ef41Sopenharmony_ci } 10471cb0ef41Sopenharmony_ci} 10481cb0ef41Sopenharmony_ci 10491cb0ef41Sopenharmony_cibool Decoder::DecodeTypeRegisterRsType(Instruction* instr) { 10501cb0ef41Sopenharmony_ci switch (instr->FunctionFieldRaw()) { 10511cb0ef41Sopenharmony_ci case RINT: 10521cb0ef41Sopenharmony_ci Format(instr, "rint.'t 'fd, 'fs"); 10531cb0ef41Sopenharmony_ci break; 10541cb0ef41Sopenharmony_ci case SEL: 10551cb0ef41Sopenharmony_ci Format(instr, "sel.'t 'fd, 'fs, 'ft"); 10561cb0ef41Sopenharmony_ci break; 10571cb0ef41Sopenharmony_ci case SELEQZ_C: 10581cb0ef41Sopenharmony_ci Format(instr, "seleqz.'t 'fd, 'fs, 'ft"); 10591cb0ef41Sopenharmony_ci break; 10601cb0ef41Sopenharmony_ci case SELNEZ_C: 10611cb0ef41Sopenharmony_ci Format(instr, "selnez.'t 'fd, 'fs, 'ft"); 10621cb0ef41Sopenharmony_ci break; 10631cb0ef41Sopenharmony_ci case MOVZ_C: 10641cb0ef41Sopenharmony_ci Format(instr, "movz.'t 'fd, 'fs, 'rt"); 10651cb0ef41Sopenharmony_ci break; 10661cb0ef41Sopenharmony_ci case MOVN_C: 10671cb0ef41Sopenharmony_ci Format(instr, "movn.'t 'fd, 'fs, 'rt"); 10681cb0ef41Sopenharmony_ci break; 10691cb0ef41Sopenharmony_ci case MOVF: 10701cb0ef41Sopenharmony_ci if (instr->Bit(16)) { 10711cb0ef41Sopenharmony_ci Format(instr, "movt.'t 'fd, 'fs, 'Cc"); 10721cb0ef41Sopenharmony_ci } else { 10731cb0ef41Sopenharmony_ci Format(instr, "movf.'t 'fd, 'fs, 'Cc"); 10741cb0ef41Sopenharmony_ci } 10751cb0ef41Sopenharmony_ci break; 10761cb0ef41Sopenharmony_ci case MIN: 10771cb0ef41Sopenharmony_ci Format(instr, "min.'t 'fd, 'fs, 'ft"); 10781cb0ef41Sopenharmony_ci break; 10791cb0ef41Sopenharmony_ci case MAX: 10801cb0ef41Sopenharmony_ci Format(instr, "max.'t 'fd, 'fs, 'ft"); 10811cb0ef41Sopenharmony_ci break; 10821cb0ef41Sopenharmony_ci case MINA: 10831cb0ef41Sopenharmony_ci Format(instr, "mina.'t 'fd, 'fs, 'ft"); 10841cb0ef41Sopenharmony_ci break; 10851cb0ef41Sopenharmony_ci case MAXA: 10861cb0ef41Sopenharmony_ci Format(instr, "maxa.'t 'fd, 'fs, 'ft"); 10871cb0ef41Sopenharmony_ci break; 10881cb0ef41Sopenharmony_ci case ADD_D: 10891cb0ef41Sopenharmony_ci Format(instr, "add.'t 'fd, 'fs, 'ft"); 10901cb0ef41Sopenharmony_ci break; 10911cb0ef41Sopenharmony_ci case SUB_D: 10921cb0ef41Sopenharmony_ci Format(instr, "sub.'t 'fd, 'fs, 'ft"); 10931cb0ef41Sopenharmony_ci break; 10941cb0ef41Sopenharmony_ci case MUL_D: 10951cb0ef41Sopenharmony_ci Format(instr, "mul.'t 'fd, 'fs, 'ft"); 10961cb0ef41Sopenharmony_ci break; 10971cb0ef41Sopenharmony_ci case DIV_D: 10981cb0ef41Sopenharmony_ci Format(instr, "div.'t 'fd, 'fs, 'ft"); 10991cb0ef41Sopenharmony_ci break; 11001cb0ef41Sopenharmony_ci case ABS_D: 11011cb0ef41Sopenharmony_ci Format(instr, "abs.'t 'fd, 'fs"); 11021cb0ef41Sopenharmony_ci break; 11031cb0ef41Sopenharmony_ci case MOV_D: 11041cb0ef41Sopenharmony_ci Format(instr, "mov.'t 'fd, 'fs"); 11051cb0ef41Sopenharmony_ci break; 11061cb0ef41Sopenharmony_ci case NEG_D: 11071cb0ef41Sopenharmony_ci Format(instr, "neg.'t 'fd, 'fs"); 11081cb0ef41Sopenharmony_ci break; 11091cb0ef41Sopenharmony_ci case SQRT_D: 11101cb0ef41Sopenharmony_ci Format(instr, "sqrt.'t 'fd, 'fs"); 11111cb0ef41Sopenharmony_ci break; 11121cb0ef41Sopenharmony_ci case RECIP_D: 11131cb0ef41Sopenharmony_ci Format(instr, "recip.'t 'fd, 'fs"); 11141cb0ef41Sopenharmony_ci break; 11151cb0ef41Sopenharmony_ci case RSQRT_D: 11161cb0ef41Sopenharmony_ci Format(instr, "rsqrt.'t 'fd, 'fs"); 11171cb0ef41Sopenharmony_ci break; 11181cb0ef41Sopenharmony_ci case CVT_W_D: 11191cb0ef41Sopenharmony_ci Format(instr, "cvt.w.'t 'fd, 'fs"); 11201cb0ef41Sopenharmony_ci break; 11211cb0ef41Sopenharmony_ci case CVT_L_D: 11221cb0ef41Sopenharmony_ci Format(instr, "cvt.l.'t 'fd, 'fs"); 11231cb0ef41Sopenharmony_ci break; 11241cb0ef41Sopenharmony_ci case TRUNC_W_D: 11251cb0ef41Sopenharmony_ci Format(instr, "trunc.w.'t 'fd, 'fs"); 11261cb0ef41Sopenharmony_ci break; 11271cb0ef41Sopenharmony_ci case TRUNC_L_D: 11281cb0ef41Sopenharmony_ci Format(instr, "trunc.l.'t 'fd, 'fs"); 11291cb0ef41Sopenharmony_ci break; 11301cb0ef41Sopenharmony_ci case ROUND_W_D: 11311cb0ef41Sopenharmony_ci Format(instr, "round.w.'t 'fd, 'fs"); 11321cb0ef41Sopenharmony_ci break; 11331cb0ef41Sopenharmony_ci case ROUND_L_D: 11341cb0ef41Sopenharmony_ci Format(instr, "round.l.'t 'fd, 'fs"); 11351cb0ef41Sopenharmony_ci break; 11361cb0ef41Sopenharmony_ci case FLOOR_W_D: 11371cb0ef41Sopenharmony_ci Format(instr, "floor.w.'t 'fd, 'fs"); 11381cb0ef41Sopenharmony_ci break; 11391cb0ef41Sopenharmony_ci case FLOOR_L_D: 11401cb0ef41Sopenharmony_ci Format(instr, "floor.l.'t 'fd, 'fs"); 11411cb0ef41Sopenharmony_ci break; 11421cb0ef41Sopenharmony_ci case CEIL_W_D: 11431cb0ef41Sopenharmony_ci Format(instr, "ceil.w.'t 'fd, 'fs"); 11441cb0ef41Sopenharmony_ci break; 11451cb0ef41Sopenharmony_ci case CEIL_L_D: 11461cb0ef41Sopenharmony_ci Format(instr, "ceil.l.'t 'fd, 'fs"); 11471cb0ef41Sopenharmony_ci break; 11481cb0ef41Sopenharmony_ci case CLASS_D: 11491cb0ef41Sopenharmony_ci Format(instr, "class.'t 'fd, 'fs"); 11501cb0ef41Sopenharmony_ci break; 11511cb0ef41Sopenharmony_ci case CVT_S_D: 11521cb0ef41Sopenharmony_ci Format(instr, "cvt.s.'t 'fd, 'fs"); 11531cb0ef41Sopenharmony_ci break; 11541cb0ef41Sopenharmony_ci case C_F_D: 11551cb0ef41Sopenharmony_ci Format(instr, "c.f.'t 'fs, 'ft, 'Cc"); 11561cb0ef41Sopenharmony_ci break; 11571cb0ef41Sopenharmony_ci case C_UN_D: 11581cb0ef41Sopenharmony_ci Format(instr, "c.un.'t 'fs, 'ft, 'Cc"); 11591cb0ef41Sopenharmony_ci break; 11601cb0ef41Sopenharmony_ci case C_EQ_D: 11611cb0ef41Sopenharmony_ci Format(instr, "c.eq.'t 'fs, 'ft, 'Cc"); 11621cb0ef41Sopenharmony_ci break; 11631cb0ef41Sopenharmony_ci case C_UEQ_D: 11641cb0ef41Sopenharmony_ci Format(instr, "c.ueq.'t 'fs, 'ft, 'Cc"); 11651cb0ef41Sopenharmony_ci break; 11661cb0ef41Sopenharmony_ci case C_OLT_D: 11671cb0ef41Sopenharmony_ci Format(instr, "c.olt.'t 'fs, 'ft, 'Cc"); 11681cb0ef41Sopenharmony_ci break; 11691cb0ef41Sopenharmony_ci case C_ULT_D: 11701cb0ef41Sopenharmony_ci Format(instr, "c.ult.'t 'fs, 'ft, 'Cc"); 11711cb0ef41Sopenharmony_ci break; 11721cb0ef41Sopenharmony_ci case C_OLE_D: 11731cb0ef41Sopenharmony_ci Format(instr, "c.ole.'t 'fs, 'ft, 'Cc"); 11741cb0ef41Sopenharmony_ci break; 11751cb0ef41Sopenharmony_ci case C_ULE_D: 11761cb0ef41Sopenharmony_ci Format(instr, "c.ule.'t 'fs, 'ft, 'Cc"); 11771cb0ef41Sopenharmony_ci break; 11781cb0ef41Sopenharmony_ci default: 11791cb0ef41Sopenharmony_ci return false; 11801cb0ef41Sopenharmony_ci } 11811cb0ef41Sopenharmony_ci return true; 11821cb0ef41Sopenharmony_ci} 11831cb0ef41Sopenharmony_ci 11841cb0ef41Sopenharmony_civoid Decoder::DecodeTypeRegisterSRsType(Instruction* instr) { 11851cb0ef41Sopenharmony_ci if (!DecodeTypeRegisterRsType(instr)) { 11861cb0ef41Sopenharmony_ci switch (instr->FunctionFieldRaw()) { 11871cb0ef41Sopenharmony_ci case CVT_D_S: 11881cb0ef41Sopenharmony_ci Format(instr, "cvt.d.'t 'fd, 'fs"); 11891cb0ef41Sopenharmony_ci break; 11901cb0ef41Sopenharmony_ci case MADDF_S: 11911cb0ef41Sopenharmony_ci Format(instr, "maddf.s 'fd, 'fs, 'ft"); 11921cb0ef41Sopenharmony_ci break; 11931cb0ef41Sopenharmony_ci case MSUBF_S: 11941cb0ef41Sopenharmony_ci Format(instr, "msubf.s 'fd, 'fs, 'ft"); 11951cb0ef41Sopenharmony_ci break; 11961cb0ef41Sopenharmony_ci default: 11971cb0ef41Sopenharmony_ci Format(instr, "unknown.cop1.'t"); 11981cb0ef41Sopenharmony_ci break; 11991cb0ef41Sopenharmony_ci } 12001cb0ef41Sopenharmony_ci } 12011cb0ef41Sopenharmony_ci} 12021cb0ef41Sopenharmony_ci 12031cb0ef41Sopenharmony_civoid Decoder::DecodeTypeRegisterDRsType(Instruction* instr) { 12041cb0ef41Sopenharmony_ci if (!DecodeTypeRegisterRsType(instr)) { 12051cb0ef41Sopenharmony_ci switch (instr->FunctionFieldRaw()) { 12061cb0ef41Sopenharmony_ci case MADDF_D: 12071cb0ef41Sopenharmony_ci Format(instr, "maddf.d 'fd, 'fs, 'ft"); 12081cb0ef41Sopenharmony_ci break; 12091cb0ef41Sopenharmony_ci case MSUBF_D: 12101cb0ef41Sopenharmony_ci Format(instr, "msubf.d 'fd, 'fs, 'ft"); 12111cb0ef41Sopenharmony_ci break; 12121cb0ef41Sopenharmony_ci default: 12131cb0ef41Sopenharmony_ci Format(instr, "unknown.cop1.'t"); 12141cb0ef41Sopenharmony_ci break; 12151cb0ef41Sopenharmony_ci } 12161cb0ef41Sopenharmony_ci } 12171cb0ef41Sopenharmony_ci} 12181cb0ef41Sopenharmony_ci 12191cb0ef41Sopenharmony_civoid Decoder::DecodeTypeRegisterLRsType(Instruction* instr) { 12201cb0ef41Sopenharmony_ci switch (instr->FunctionFieldRaw()) { 12211cb0ef41Sopenharmony_ci case CVT_D_L: 12221cb0ef41Sopenharmony_ci Format(instr, "cvt.d.l 'fd, 'fs"); 12231cb0ef41Sopenharmony_ci break; 12241cb0ef41Sopenharmony_ci case CVT_S_L: 12251cb0ef41Sopenharmony_ci Format(instr, "cvt.s.l 'fd, 'fs"); 12261cb0ef41Sopenharmony_ci break; 12271cb0ef41Sopenharmony_ci case CMP_AF: 12281cb0ef41Sopenharmony_ci Format(instr, "cmp.af.d 'fd, 'fs, 'ft"); 12291cb0ef41Sopenharmony_ci break; 12301cb0ef41Sopenharmony_ci case CMP_UN: 12311cb0ef41Sopenharmony_ci Format(instr, "cmp.un.d 'fd, 'fs, 'ft"); 12321cb0ef41Sopenharmony_ci break; 12331cb0ef41Sopenharmony_ci case CMP_EQ: 12341cb0ef41Sopenharmony_ci Format(instr, "cmp.eq.d 'fd, 'fs, 'ft"); 12351cb0ef41Sopenharmony_ci break; 12361cb0ef41Sopenharmony_ci case CMP_UEQ: 12371cb0ef41Sopenharmony_ci Format(instr, "cmp.ueq.d 'fd, 'fs, 'ft"); 12381cb0ef41Sopenharmony_ci break; 12391cb0ef41Sopenharmony_ci case CMP_LT: 12401cb0ef41Sopenharmony_ci Format(instr, "cmp.lt.d 'fd, 'fs, 'ft"); 12411cb0ef41Sopenharmony_ci break; 12421cb0ef41Sopenharmony_ci case CMP_ULT: 12431cb0ef41Sopenharmony_ci Format(instr, "cmp.ult.d 'fd, 'fs, 'ft"); 12441cb0ef41Sopenharmony_ci break; 12451cb0ef41Sopenharmony_ci case CMP_LE: 12461cb0ef41Sopenharmony_ci Format(instr, "cmp.le.d 'fd, 'fs, 'ft"); 12471cb0ef41Sopenharmony_ci break; 12481cb0ef41Sopenharmony_ci case CMP_ULE: 12491cb0ef41Sopenharmony_ci Format(instr, "cmp.ule.d 'fd, 'fs, 'ft"); 12501cb0ef41Sopenharmony_ci break; 12511cb0ef41Sopenharmony_ci case CMP_OR: 12521cb0ef41Sopenharmony_ci Format(instr, "cmp.or.d 'fd, 'fs, 'ft"); 12531cb0ef41Sopenharmony_ci break; 12541cb0ef41Sopenharmony_ci case CMP_UNE: 12551cb0ef41Sopenharmony_ci Format(instr, "cmp.une.d 'fd, 'fs, 'ft"); 12561cb0ef41Sopenharmony_ci break; 12571cb0ef41Sopenharmony_ci case CMP_NE: 12581cb0ef41Sopenharmony_ci Format(instr, "cmp.ne.d 'fd, 'fs, 'ft"); 12591cb0ef41Sopenharmony_ci break; 12601cb0ef41Sopenharmony_ci default: 12611cb0ef41Sopenharmony_ci UNREACHABLE(); 12621cb0ef41Sopenharmony_ci } 12631cb0ef41Sopenharmony_ci} 12641cb0ef41Sopenharmony_ci 12651cb0ef41Sopenharmony_civoid Decoder::DecodeTypeRegisterWRsType(Instruction* instr) { 12661cb0ef41Sopenharmony_ci switch (instr->FunctionValue()) { 12671cb0ef41Sopenharmony_ci case CVT_S_W: // Convert word to float (single). 12681cb0ef41Sopenharmony_ci Format(instr, "cvt.s.w 'fd, 'fs"); 12691cb0ef41Sopenharmony_ci break; 12701cb0ef41Sopenharmony_ci case CVT_D_W: // Convert word to double. 12711cb0ef41Sopenharmony_ci Format(instr, "cvt.d.w 'fd, 'fs"); 12721cb0ef41Sopenharmony_ci break; 12731cb0ef41Sopenharmony_ci case CMP_AF: 12741cb0ef41Sopenharmony_ci Format(instr, "cmp.af.s 'fd, 'fs, 'ft"); 12751cb0ef41Sopenharmony_ci break; 12761cb0ef41Sopenharmony_ci case CMP_UN: 12771cb0ef41Sopenharmony_ci Format(instr, "cmp.un.s 'fd, 'fs, 'ft"); 12781cb0ef41Sopenharmony_ci break; 12791cb0ef41Sopenharmony_ci case CMP_EQ: 12801cb0ef41Sopenharmony_ci Format(instr, "cmp.eq.s 'fd, 'fs, 'ft"); 12811cb0ef41Sopenharmony_ci break; 12821cb0ef41Sopenharmony_ci case CMP_UEQ: 12831cb0ef41Sopenharmony_ci Format(instr, "cmp.ueq.s 'fd, 'fs, 'ft"); 12841cb0ef41Sopenharmony_ci break; 12851cb0ef41Sopenharmony_ci case CMP_LT: 12861cb0ef41Sopenharmony_ci Format(instr, "cmp.lt.s 'fd, 'fs, 'ft"); 12871cb0ef41Sopenharmony_ci break; 12881cb0ef41Sopenharmony_ci case CMP_ULT: 12891cb0ef41Sopenharmony_ci Format(instr, "cmp.ult.s 'fd, 'fs, 'ft"); 12901cb0ef41Sopenharmony_ci break; 12911cb0ef41Sopenharmony_ci case CMP_LE: 12921cb0ef41Sopenharmony_ci Format(instr, "cmp.le.s 'fd, 'fs, 'ft"); 12931cb0ef41Sopenharmony_ci break; 12941cb0ef41Sopenharmony_ci case CMP_ULE: 12951cb0ef41Sopenharmony_ci Format(instr, "cmp.ule.s 'fd, 'fs, 'ft"); 12961cb0ef41Sopenharmony_ci break; 12971cb0ef41Sopenharmony_ci case CMP_OR: 12981cb0ef41Sopenharmony_ci Format(instr, "cmp.or.s 'fd, 'fs, 'ft"); 12991cb0ef41Sopenharmony_ci break; 13001cb0ef41Sopenharmony_ci case CMP_UNE: 13011cb0ef41Sopenharmony_ci Format(instr, "cmp.une.s 'fd, 'fs, 'ft"); 13021cb0ef41Sopenharmony_ci break; 13031cb0ef41Sopenharmony_ci case CMP_NE: 13041cb0ef41Sopenharmony_ci Format(instr, "cmp.ne.s 'fd, 'fs, 'ft"); 13051cb0ef41Sopenharmony_ci break; 13061cb0ef41Sopenharmony_ci default: 13071cb0ef41Sopenharmony_ci UNREACHABLE(); 13081cb0ef41Sopenharmony_ci } 13091cb0ef41Sopenharmony_ci} 13101cb0ef41Sopenharmony_ci 13111cb0ef41Sopenharmony_civoid Decoder::DecodeTypeRegisterCOP1(Instruction* instr) { 13121cb0ef41Sopenharmony_ci switch (instr->RsFieldRaw()) { 13131cb0ef41Sopenharmony_ci case MFC1: 13141cb0ef41Sopenharmony_ci Format(instr, "mfc1 'rt, 'fs"); 13151cb0ef41Sopenharmony_ci break; 13161cb0ef41Sopenharmony_ci case DMFC1: 13171cb0ef41Sopenharmony_ci Format(instr, "dmfc1 'rt, 'fs"); 13181cb0ef41Sopenharmony_ci break; 13191cb0ef41Sopenharmony_ci case MFHC1: 13201cb0ef41Sopenharmony_ci Format(instr, "mfhc1 'rt, 'fs"); 13211cb0ef41Sopenharmony_ci break; 13221cb0ef41Sopenharmony_ci case MTC1: 13231cb0ef41Sopenharmony_ci Format(instr, "mtc1 'rt, 'fs"); 13241cb0ef41Sopenharmony_ci break; 13251cb0ef41Sopenharmony_ci case DMTC1: 13261cb0ef41Sopenharmony_ci Format(instr, "dmtc1 'rt, 'fs"); 13271cb0ef41Sopenharmony_ci break; 13281cb0ef41Sopenharmony_ci // These are called "fs" too, although they are not FPU registers. 13291cb0ef41Sopenharmony_ci case CTC1: 13301cb0ef41Sopenharmony_ci Format(instr, "ctc1 'rt, 'fs"); 13311cb0ef41Sopenharmony_ci break; 13321cb0ef41Sopenharmony_ci case CFC1: 13331cb0ef41Sopenharmony_ci Format(instr, "cfc1 'rt, 'fs"); 13341cb0ef41Sopenharmony_ci break; 13351cb0ef41Sopenharmony_ci case MTHC1: 13361cb0ef41Sopenharmony_ci Format(instr, "mthc1 'rt, 'fs"); 13371cb0ef41Sopenharmony_ci break; 13381cb0ef41Sopenharmony_ci case S: 13391cb0ef41Sopenharmony_ci DecodeTypeRegisterSRsType(instr); 13401cb0ef41Sopenharmony_ci break; 13411cb0ef41Sopenharmony_ci case D: 13421cb0ef41Sopenharmony_ci DecodeTypeRegisterDRsType(instr); 13431cb0ef41Sopenharmony_ci break; 13441cb0ef41Sopenharmony_ci case W: 13451cb0ef41Sopenharmony_ci DecodeTypeRegisterWRsType(instr); 13461cb0ef41Sopenharmony_ci break; 13471cb0ef41Sopenharmony_ci case L: 13481cb0ef41Sopenharmony_ci DecodeTypeRegisterLRsType(instr); 13491cb0ef41Sopenharmony_ci break; 13501cb0ef41Sopenharmony_ci default: 13511cb0ef41Sopenharmony_ci UNREACHABLE(); 13521cb0ef41Sopenharmony_ci } 13531cb0ef41Sopenharmony_ci} 13541cb0ef41Sopenharmony_ci 13551cb0ef41Sopenharmony_civoid Decoder::DecodeTypeRegisterCOP1X(Instruction* instr) { 13561cb0ef41Sopenharmony_ci switch (instr->FunctionFieldRaw()) { 13571cb0ef41Sopenharmony_ci case MADD_S: 13581cb0ef41Sopenharmony_ci Format(instr, "madd.s 'fd, 'fr, 'fs, 'ft"); 13591cb0ef41Sopenharmony_ci break; 13601cb0ef41Sopenharmony_ci case MADD_D: 13611cb0ef41Sopenharmony_ci Format(instr, "madd.d 'fd, 'fr, 'fs, 'ft"); 13621cb0ef41Sopenharmony_ci break; 13631cb0ef41Sopenharmony_ci case MSUB_S: 13641cb0ef41Sopenharmony_ci Format(instr, "msub.s 'fd, 'fr, 'fs, 'ft"); 13651cb0ef41Sopenharmony_ci break; 13661cb0ef41Sopenharmony_ci case MSUB_D: 13671cb0ef41Sopenharmony_ci Format(instr, "msub.d 'fd, 'fr, 'fs, 'ft"); 13681cb0ef41Sopenharmony_ci break; 13691cb0ef41Sopenharmony_ci default: 13701cb0ef41Sopenharmony_ci UNREACHABLE(); 13711cb0ef41Sopenharmony_ci } 13721cb0ef41Sopenharmony_ci} 13731cb0ef41Sopenharmony_ci 13741cb0ef41Sopenharmony_civoid Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) { 13751cb0ef41Sopenharmony_ci switch (instr->FunctionFieldRaw()) { 13761cb0ef41Sopenharmony_ci case JR: 13771cb0ef41Sopenharmony_ci Format(instr, "jr 'rs"); 13781cb0ef41Sopenharmony_ci break; 13791cb0ef41Sopenharmony_ci case JALR: 13801cb0ef41Sopenharmony_ci Format(instr, "jalr 'rs, 'rd"); 13811cb0ef41Sopenharmony_ci break; 13821cb0ef41Sopenharmony_ci case SLL: 13831cb0ef41Sopenharmony_ci if (0x0 == static_cast<int>(instr->InstructionBits())) 13841cb0ef41Sopenharmony_ci Format(instr, "nop"); 13851cb0ef41Sopenharmony_ci else 13861cb0ef41Sopenharmony_ci Format(instr, "sll 'rd, 'rt, 'sa"); 13871cb0ef41Sopenharmony_ci break; 13881cb0ef41Sopenharmony_ci case DSLL: 13891cb0ef41Sopenharmony_ci Format(instr, "dsll 'rd, 'rt, 'sa"); 13901cb0ef41Sopenharmony_ci break; 13911cb0ef41Sopenharmony_ci case D_MUL_MUH: // Equals to DMUL. 13921cb0ef41Sopenharmony_ci if (kArchVariant != kMips64r6) { 13931cb0ef41Sopenharmony_ci Format(instr, "dmult 'rs, 'rt"); 13941cb0ef41Sopenharmony_ci } else { 13951cb0ef41Sopenharmony_ci if (instr->SaValue() == MUL_OP) { 13961cb0ef41Sopenharmony_ci Format(instr, "dmul 'rd, 'rs, 'rt"); 13971cb0ef41Sopenharmony_ci } else { 13981cb0ef41Sopenharmony_ci Format(instr, "dmuh 'rd, 'rs, 'rt"); 13991cb0ef41Sopenharmony_ci } 14001cb0ef41Sopenharmony_ci } 14011cb0ef41Sopenharmony_ci break; 14021cb0ef41Sopenharmony_ci case DSLL32: 14031cb0ef41Sopenharmony_ci Format(instr, "dsll32 'rd, 'rt, 'sa"); 14041cb0ef41Sopenharmony_ci break; 14051cb0ef41Sopenharmony_ci case SRL: 14061cb0ef41Sopenharmony_ci if (instr->RsValue() == 0) { 14071cb0ef41Sopenharmony_ci Format(instr, "srl 'rd, 'rt, 'sa"); 14081cb0ef41Sopenharmony_ci } else { 14091cb0ef41Sopenharmony_ci Format(instr, "rotr 'rd, 'rt, 'sa"); 14101cb0ef41Sopenharmony_ci } 14111cb0ef41Sopenharmony_ci break; 14121cb0ef41Sopenharmony_ci case DSRL: 14131cb0ef41Sopenharmony_ci if (instr->RsValue() == 0) { 14141cb0ef41Sopenharmony_ci Format(instr, "dsrl 'rd, 'rt, 'sa"); 14151cb0ef41Sopenharmony_ci } else { 14161cb0ef41Sopenharmony_ci Format(instr, "drotr 'rd, 'rt, 'sa"); 14171cb0ef41Sopenharmony_ci } 14181cb0ef41Sopenharmony_ci break; 14191cb0ef41Sopenharmony_ci case DSRL32: 14201cb0ef41Sopenharmony_ci if (instr->RsValue() == 0) { 14211cb0ef41Sopenharmony_ci Format(instr, "dsrl32 'rd, 'rt, 'sa"); 14221cb0ef41Sopenharmony_ci } else { 14231cb0ef41Sopenharmony_ci Format(instr, "drotr32 'rd, 'rt, 'sa"); 14241cb0ef41Sopenharmony_ci } 14251cb0ef41Sopenharmony_ci break; 14261cb0ef41Sopenharmony_ci case SRA: 14271cb0ef41Sopenharmony_ci Format(instr, "sra 'rd, 'rt, 'sa"); 14281cb0ef41Sopenharmony_ci break; 14291cb0ef41Sopenharmony_ci case DSRA: 14301cb0ef41Sopenharmony_ci Format(instr, "dsra 'rd, 'rt, 'sa"); 14311cb0ef41Sopenharmony_ci break; 14321cb0ef41Sopenharmony_ci case DSRA32: 14331cb0ef41Sopenharmony_ci Format(instr, "dsra32 'rd, 'rt, 'sa"); 14341cb0ef41Sopenharmony_ci break; 14351cb0ef41Sopenharmony_ci case SLLV: 14361cb0ef41Sopenharmony_ci Format(instr, "sllv 'rd, 'rt, 'rs"); 14371cb0ef41Sopenharmony_ci break; 14381cb0ef41Sopenharmony_ci case DSLLV: 14391cb0ef41Sopenharmony_ci Format(instr, "dsllv 'rd, 'rt, 'rs"); 14401cb0ef41Sopenharmony_ci break; 14411cb0ef41Sopenharmony_ci case SRLV: 14421cb0ef41Sopenharmony_ci if (instr->SaValue() == 0) { 14431cb0ef41Sopenharmony_ci Format(instr, "srlv 'rd, 'rt, 'rs"); 14441cb0ef41Sopenharmony_ci } else { 14451cb0ef41Sopenharmony_ci Format(instr, "rotrv 'rd, 'rt, 'rs"); 14461cb0ef41Sopenharmony_ci } 14471cb0ef41Sopenharmony_ci break; 14481cb0ef41Sopenharmony_ci case DSRLV: 14491cb0ef41Sopenharmony_ci if (instr->SaValue() == 0) { 14501cb0ef41Sopenharmony_ci Format(instr, "dsrlv 'rd, 'rt, 'rs"); 14511cb0ef41Sopenharmony_ci } else { 14521cb0ef41Sopenharmony_ci Format(instr, "drotrv 'rd, 'rt, 'rs"); 14531cb0ef41Sopenharmony_ci } 14541cb0ef41Sopenharmony_ci break; 14551cb0ef41Sopenharmony_ci case SRAV: 14561cb0ef41Sopenharmony_ci Format(instr, "srav 'rd, 'rt, 'rs"); 14571cb0ef41Sopenharmony_ci break; 14581cb0ef41Sopenharmony_ci case DSRAV: 14591cb0ef41Sopenharmony_ci Format(instr, "dsrav 'rd, 'rt, 'rs"); 14601cb0ef41Sopenharmony_ci break; 14611cb0ef41Sopenharmony_ci case LSA: 14621cb0ef41Sopenharmony_ci Format(instr, "lsa 'rd, 'rt, 'rs, 'sa2"); 14631cb0ef41Sopenharmony_ci break; 14641cb0ef41Sopenharmony_ci case DLSA: 14651cb0ef41Sopenharmony_ci Format(instr, "dlsa 'rd, 'rt, 'rs, 'sa2"); 14661cb0ef41Sopenharmony_ci break; 14671cb0ef41Sopenharmony_ci case MFHI: 14681cb0ef41Sopenharmony_ci if (instr->Bits(25, 16) == 0) { 14691cb0ef41Sopenharmony_ci Format(instr, "mfhi 'rd"); 14701cb0ef41Sopenharmony_ci } else { 14711cb0ef41Sopenharmony_ci if ((instr->FunctionFieldRaw() == CLZ_R6) && (instr->FdValue() == 1)) { 14721cb0ef41Sopenharmony_ci Format(instr, "clz 'rd, 'rs"); 14731cb0ef41Sopenharmony_ci } else if ((instr->FunctionFieldRaw() == CLO_R6) && 14741cb0ef41Sopenharmony_ci (instr->FdValue() == 1)) { 14751cb0ef41Sopenharmony_ci Format(instr, "clo 'rd, 'rs"); 14761cb0ef41Sopenharmony_ci } 14771cb0ef41Sopenharmony_ci } 14781cb0ef41Sopenharmony_ci break; 14791cb0ef41Sopenharmony_ci case MFLO: 14801cb0ef41Sopenharmony_ci if (instr->Bits(25, 16) == 0) { 14811cb0ef41Sopenharmony_ci Format(instr, "mflo 'rd"); 14821cb0ef41Sopenharmony_ci } else { 14831cb0ef41Sopenharmony_ci if ((instr->FunctionFieldRaw() == DCLZ_R6) && (instr->FdValue() == 1)) { 14841cb0ef41Sopenharmony_ci Format(instr, "dclz 'rd, 'rs"); 14851cb0ef41Sopenharmony_ci } else if ((instr->FunctionFieldRaw() == DCLO_R6) && 14861cb0ef41Sopenharmony_ci (instr->FdValue() == 1)) { 14871cb0ef41Sopenharmony_ci Format(instr, "dclo 'rd, 'rs"); 14881cb0ef41Sopenharmony_ci } 14891cb0ef41Sopenharmony_ci } 14901cb0ef41Sopenharmony_ci break; 14911cb0ef41Sopenharmony_ci case D_MUL_MUH_U: // Equals to DMULTU. 14921cb0ef41Sopenharmony_ci if (kArchVariant != kMips64r6) { 14931cb0ef41Sopenharmony_ci Format(instr, "dmultu 'rs, 'rt"); 14941cb0ef41Sopenharmony_ci } else { 14951cb0ef41Sopenharmony_ci if (instr->SaValue() == MUL_OP) { 14961cb0ef41Sopenharmony_ci Format(instr, "dmulu 'rd, 'rs, 'rt"); 14971cb0ef41Sopenharmony_ci } else { 14981cb0ef41Sopenharmony_ci Format(instr, "dmuhu 'rd, 'rs, 'rt"); 14991cb0ef41Sopenharmony_ci } 15001cb0ef41Sopenharmony_ci } 15011cb0ef41Sopenharmony_ci break; 15021cb0ef41Sopenharmony_ci case MULT: // @Mips64r6 == MUL_MUH. 15031cb0ef41Sopenharmony_ci if (kArchVariant != kMips64r6) { 15041cb0ef41Sopenharmony_ci Format(instr, "mult 'rs, 'rt"); 15051cb0ef41Sopenharmony_ci } else { 15061cb0ef41Sopenharmony_ci if (instr->SaValue() == MUL_OP) { 15071cb0ef41Sopenharmony_ci Format(instr, "mul 'rd, 'rs, 'rt"); 15081cb0ef41Sopenharmony_ci } else { 15091cb0ef41Sopenharmony_ci Format(instr, "muh 'rd, 'rs, 'rt"); 15101cb0ef41Sopenharmony_ci } 15111cb0ef41Sopenharmony_ci } 15121cb0ef41Sopenharmony_ci break; 15131cb0ef41Sopenharmony_ci case MULTU: // @Mips64r6 == MUL_MUH_U. 15141cb0ef41Sopenharmony_ci if (kArchVariant != kMips64r6) { 15151cb0ef41Sopenharmony_ci Format(instr, "multu 'rs, 'rt"); 15161cb0ef41Sopenharmony_ci } else { 15171cb0ef41Sopenharmony_ci if (instr->SaValue() == MUL_OP) { 15181cb0ef41Sopenharmony_ci Format(instr, "mulu 'rd, 'rs, 'rt"); 15191cb0ef41Sopenharmony_ci } else { 15201cb0ef41Sopenharmony_ci Format(instr, "muhu 'rd, 'rs, 'rt"); 15211cb0ef41Sopenharmony_ci } 15221cb0ef41Sopenharmony_ci } 15231cb0ef41Sopenharmony_ci 15241cb0ef41Sopenharmony_ci break; 15251cb0ef41Sopenharmony_ci case DIV: // @Mips64r6 == DIV_MOD. 15261cb0ef41Sopenharmony_ci if (kArchVariant != kMips64r6) { 15271cb0ef41Sopenharmony_ci Format(instr, "div 'rs, 'rt"); 15281cb0ef41Sopenharmony_ci } else { 15291cb0ef41Sopenharmony_ci if (instr->SaValue() == DIV_OP) { 15301cb0ef41Sopenharmony_ci Format(instr, "div 'rd, 'rs, 'rt"); 15311cb0ef41Sopenharmony_ci } else { 15321cb0ef41Sopenharmony_ci Format(instr, "mod 'rd, 'rs, 'rt"); 15331cb0ef41Sopenharmony_ci } 15341cb0ef41Sopenharmony_ci } 15351cb0ef41Sopenharmony_ci break; 15361cb0ef41Sopenharmony_ci case DDIV: // @Mips64r6 == D_DIV_MOD. 15371cb0ef41Sopenharmony_ci if (kArchVariant != kMips64r6) { 15381cb0ef41Sopenharmony_ci Format(instr, "ddiv 'rs, 'rt"); 15391cb0ef41Sopenharmony_ci } else { 15401cb0ef41Sopenharmony_ci if (instr->SaValue() == DIV_OP) { 15411cb0ef41Sopenharmony_ci Format(instr, "ddiv 'rd, 'rs, 'rt"); 15421cb0ef41Sopenharmony_ci } else { 15431cb0ef41Sopenharmony_ci Format(instr, "dmod 'rd, 'rs, 'rt"); 15441cb0ef41Sopenharmony_ci } 15451cb0ef41Sopenharmony_ci } 15461cb0ef41Sopenharmony_ci break; 15471cb0ef41Sopenharmony_ci case DIVU: // @Mips64r6 == DIV_MOD_U. 15481cb0ef41Sopenharmony_ci if (kArchVariant != kMips64r6) { 15491cb0ef41Sopenharmony_ci Format(instr, "divu 'rs, 'rt"); 15501cb0ef41Sopenharmony_ci } else { 15511cb0ef41Sopenharmony_ci if (instr->SaValue() == DIV_OP) { 15521cb0ef41Sopenharmony_ci Format(instr, "divu 'rd, 'rs, 'rt"); 15531cb0ef41Sopenharmony_ci } else { 15541cb0ef41Sopenharmony_ci Format(instr, "modu 'rd, 'rs, 'rt"); 15551cb0ef41Sopenharmony_ci } 15561cb0ef41Sopenharmony_ci } 15571cb0ef41Sopenharmony_ci break; 15581cb0ef41Sopenharmony_ci case DDIVU: // @Mips64r6 == D_DIV_MOD_U. 15591cb0ef41Sopenharmony_ci if (kArchVariant != kMips64r6) { 15601cb0ef41Sopenharmony_ci Format(instr, "ddivu 'rs, 'rt"); 15611cb0ef41Sopenharmony_ci } else { 15621cb0ef41Sopenharmony_ci if (instr->SaValue() == DIV_OP) { 15631cb0ef41Sopenharmony_ci Format(instr, "ddivu 'rd, 'rs, 'rt"); 15641cb0ef41Sopenharmony_ci } else { 15651cb0ef41Sopenharmony_ci Format(instr, "dmodu 'rd, 'rs, 'rt"); 15661cb0ef41Sopenharmony_ci } 15671cb0ef41Sopenharmony_ci } 15681cb0ef41Sopenharmony_ci break; 15691cb0ef41Sopenharmony_ci case ADD: 15701cb0ef41Sopenharmony_ci Format(instr, "add 'rd, 'rs, 'rt"); 15711cb0ef41Sopenharmony_ci break; 15721cb0ef41Sopenharmony_ci case DADD: 15731cb0ef41Sopenharmony_ci Format(instr, "dadd 'rd, 'rs, 'rt"); 15741cb0ef41Sopenharmony_ci break; 15751cb0ef41Sopenharmony_ci case ADDU: 15761cb0ef41Sopenharmony_ci Format(instr, "addu 'rd, 'rs, 'rt"); 15771cb0ef41Sopenharmony_ci break; 15781cb0ef41Sopenharmony_ci case DADDU: 15791cb0ef41Sopenharmony_ci Format(instr, "daddu 'rd, 'rs, 'rt"); 15801cb0ef41Sopenharmony_ci break; 15811cb0ef41Sopenharmony_ci case SUB: 15821cb0ef41Sopenharmony_ci Format(instr, "sub 'rd, 'rs, 'rt"); 15831cb0ef41Sopenharmony_ci break; 15841cb0ef41Sopenharmony_ci case DSUB: 15851cb0ef41Sopenharmony_ci Format(instr, "dsub 'rd, 'rs, 'rt"); 15861cb0ef41Sopenharmony_ci break; 15871cb0ef41Sopenharmony_ci case SUBU: 15881cb0ef41Sopenharmony_ci Format(instr, "subu 'rd, 'rs, 'rt"); 15891cb0ef41Sopenharmony_ci break; 15901cb0ef41Sopenharmony_ci case DSUBU: 15911cb0ef41Sopenharmony_ci Format(instr, "dsubu 'rd, 'rs, 'rt"); 15921cb0ef41Sopenharmony_ci break; 15931cb0ef41Sopenharmony_ci case AND: 15941cb0ef41Sopenharmony_ci Format(instr, "and 'rd, 'rs, 'rt"); 15951cb0ef41Sopenharmony_ci break; 15961cb0ef41Sopenharmony_ci case OR: 15971cb0ef41Sopenharmony_ci if (0 == instr->RsValue()) { 15981cb0ef41Sopenharmony_ci Format(instr, "mov 'rd, 'rt"); 15991cb0ef41Sopenharmony_ci } else if (0 == instr->RtValue()) { 16001cb0ef41Sopenharmony_ci Format(instr, "mov 'rd, 'rs"); 16011cb0ef41Sopenharmony_ci } else { 16021cb0ef41Sopenharmony_ci Format(instr, "or 'rd, 'rs, 'rt"); 16031cb0ef41Sopenharmony_ci } 16041cb0ef41Sopenharmony_ci break; 16051cb0ef41Sopenharmony_ci case XOR: 16061cb0ef41Sopenharmony_ci Format(instr, "xor 'rd, 'rs, 'rt"); 16071cb0ef41Sopenharmony_ci break; 16081cb0ef41Sopenharmony_ci case NOR: 16091cb0ef41Sopenharmony_ci Format(instr, "nor 'rd, 'rs, 'rt"); 16101cb0ef41Sopenharmony_ci break; 16111cb0ef41Sopenharmony_ci case SLT: 16121cb0ef41Sopenharmony_ci Format(instr, "slt 'rd, 'rs, 'rt"); 16131cb0ef41Sopenharmony_ci break; 16141cb0ef41Sopenharmony_ci case SLTU: 16151cb0ef41Sopenharmony_ci Format(instr, "sltu 'rd, 'rs, 'rt"); 16161cb0ef41Sopenharmony_ci break; 16171cb0ef41Sopenharmony_ci case TGE: 16181cb0ef41Sopenharmony_ci Format(instr, "tge 'rs, 'rt, code: 'code"); 16191cb0ef41Sopenharmony_ci break; 16201cb0ef41Sopenharmony_ci case TGEU: 16211cb0ef41Sopenharmony_ci Format(instr, "tgeu 'rs, 'rt, code: 'code"); 16221cb0ef41Sopenharmony_ci break; 16231cb0ef41Sopenharmony_ci case TLT: 16241cb0ef41Sopenharmony_ci Format(instr, "tlt 'rs, 'rt, code: 'code"); 16251cb0ef41Sopenharmony_ci break; 16261cb0ef41Sopenharmony_ci case TLTU: 16271cb0ef41Sopenharmony_ci Format(instr, "tltu 'rs, 'rt, code: 'code"); 16281cb0ef41Sopenharmony_ci break; 16291cb0ef41Sopenharmony_ci case TEQ: 16301cb0ef41Sopenharmony_ci Format(instr, "teq 'rs, 'rt, code: 'code"); 16311cb0ef41Sopenharmony_ci break; 16321cb0ef41Sopenharmony_ci case TNE: 16331cb0ef41Sopenharmony_ci Format(instr, "tne 'rs, 'rt, code: 'code"); 16341cb0ef41Sopenharmony_ci break; 16351cb0ef41Sopenharmony_ci case SYNC: 16361cb0ef41Sopenharmony_ci Format(instr, "sync"); 16371cb0ef41Sopenharmony_ci break; 16381cb0ef41Sopenharmony_ci case MOVZ: 16391cb0ef41Sopenharmony_ci Format(instr, "movz 'rd, 'rs, 'rt"); 16401cb0ef41Sopenharmony_ci break; 16411cb0ef41Sopenharmony_ci case MOVN: 16421cb0ef41Sopenharmony_ci Format(instr, "movn 'rd, 'rs, 'rt"); 16431cb0ef41Sopenharmony_ci break; 16441cb0ef41Sopenharmony_ci case MOVCI: 16451cb0ef41Sopenharmony_ci if (instr->Bit(16)) { 16461cb0ef41Sopenharmony_ci Format(instr, "movt 'rd, 'rs, 'bc"); 16471cb0ef41Sopenharmony_ci } else { 16481cb0ef41Sopenharmony_ci Format(instr, "movf 'rd, 'rs, 'bc"); 16491cb0ef41Sopenharmony_ci } 16501cb0ef41Sopenharmony_ci break; 16511cb0ef41Sopenharmony_ci case SELEQZ_S: 16521cb0ef41Sopenharmony_ci Format(instr, "seleqz 'rd, 'rs, 'rt"); 16531cb0ef41Sopenharmony_ci break; 16541cb0ef41Sopenharmony_ci case SELNEZ_S: 16551cb0ef41Sopenharmony_ci Format(instr, "selnez 'rd, 'rs, 'rt"); 16561cb0ef41Sopenharmony_ci break; 16571cb0ef41Sopenharmony_ci default: 16581cb0ef41Sopenharmony_ci UNREACHABLE(); 16591cb0ef41Sopenharmony_ci } 16601cb0ef41Sopenharmony_ci} 16611cb0ef41Sopenharmony_ci 16621cb0ef41Sopenharmony_civoid Decoder::DecodeTypeRegisterSPECIAL2(Instruction* instr) { 16631cb0ef41Sopenharmony_ci switch (instr->FunctionFieldRaw()) { 16641cb0ef41Sopenharmony_ci case MUL: 16651cb0ef41Sopenharmony_ci Format(instr, "mul 'rd, 'rs, 'rt"); 16661cb0ef41Sopenharmony_ci break; 16671cb0ef41Sopenharmony_ci case CLZ: 16681cb0ef41Sopenharmony_ci if (kArchVariant != kMips64r6) { 16691cb0ef41Sopenharmony_ci Format(instr, "clz 'rd, 'rs"); 16701cb0ef41Sopenharmony_ci } 16711cb0ef41Sopenharmony_ci break; 16721cb0ef41Sopenharmony_ci case DCLZ: 16731cb0ef41Sopenharmony_ci if (kArchVariant != kMips64r6) { 16741cb0ef41Sopenharmony_ci Format(instr, "dclz 'rd, 'rs"); 16751cb0ef41Sopenharmony_ci } 16761cb0ef41Sopenharmony_ci break; 16771cb0ef41Sopenharmony_ci default: 16781cb0ef41Sopenharmony_ci UNREACHABLE(); 16791cb0ef41Sopenharmony_ci } 16801cb0ef41Sopenharmony_ci} 16811cb0ef41Sopenharmony_ci 16821cb0ef41Sopenharmony_civoid Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) { 16831cb0ef41Sopenharmony_ci switch (instr->FunctionFieldRaw()) { 16841cb0ef41Sopenharmony_ci case EXT: { 16851cb0ef41Sopenharmony_ci Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); 16861cb0ef41Sopenharmony_ci break; 16871cb0ef41Sopenharmony_ci } 16881cb0ef41Sopenharmony_ci case DEXT: { 16891cb0ef41Sopenharmony_ci Format(instr, "dext 'rt, 'rs, 'sa, 'ss1"); 16901cb0ef41Sopenharmony_ci break; 16911cb0ef41Sopenharmony_ci } 16921cb0ef41Sopenharmony_ci case DEXTM: { 16931cb0ef41Sopenharmony_ci Format(instr, "dextm 'rt, 'rs, 'sa, 'ss3"); 16941cb0ef41Sopenharmony_ci break; 16951cb0ef41Sopenharmony_ci } 16961cb0ef41Sopenharmony_ci case DEXTU: { 16971cb0ef41Sopenharmony_ci Format(instr, "dextu 'rt, 'rs, 'ss5, 'ss1"); 16981cb0ef41Sopenharmony_ci break; 16991cb0ef41Sopenharmony_ci } 17001cb0ef41Sopenharmony_ci case INS: { 17011cb0ef41Sopenharmony_ci Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); 17021cb0ef41Sopenharmony_ci break; 17031cb0ef41Sopenharmony_ci } 17041cb0ef41Sopenharmony_ci case DINS: { 17051cb0ef41Sopenharmony_ci Format(instr, "dins 'rt, 'rs, 'sa, 'ss2"); 17061cb0ef41Sopenharmony_ci break; 17071cb0ef41Sopenharmony_ci } 17081cb0ef41Sopenharmony_ci case DINSM: { 17091cb0ef41Sopenharmony_ci Format(instr, "dinsm 'rt, 'rs, 'sa, 'ss4"); 17101cb0ef41Sopenharmony_ci break; 17111cb0ef41Sopenharmony_ci } 17121cb0ef41Sopenharmony_ci case DINSU: { 17131cb0ef41Sopenharmony_ci Format(instr, "dinsu 'rt, 'rs, 'ss5, 'ss2"); 17141cb0ef41Sopenharmony_ci break; 17151cb0ef41Sopenharmony_ci } 17161cb0ef41Sopenharmony_ci case BSHFL: { 17171cb0ef41Sopenharmony_ci int sa = instr->SaFieldRaw() >> kSaShift; 17181cb0ef41Sopenharmony_ci switch (sa) { 17191cb0ef41Sopenharmony_ci case BITSWAP: { 17201cb0ef41Sopenharmony_ci Format(instr, "bitswap 'rd, 'rt"); 17211cb0ef41Sopenharmony_ci break; 17221cb0ef41Sopenharmony_ci } 17231cb0ef41Sopenharmony_ci case SEB: { 17241cb0ef41Sopenharmony_ci Format(instr, "seb 'rd, 'rt"); 17251cb0ef41Sopenharmony_ci break; 17261cb0ef41Sopenharmony_ci } 17271cb0ef41Sopenharmony_ci case SEH: { 17281cb0ef41Sopenharmony_ci Format(instr, "seh 'rd, 'rt"); 17291cb0ef41Sopenharmony_ci break; 17301cb0ef41Sopenharmony_ci } 17311cb0ef41Sopenharmony_ci case WSBH: { 17321cb0ef41Sopenharmony_ci Format(instr, "wsbh 'rd, 'rt"); 17331cb0ef41Sopenharmony_ci break; 17341cb0ef41Sopenharmony_ci } 17351cb0ef41Sopenharmony_ci default: { 17361cb0ef41Sopenharmony_ci sa >>= kBp2Bits; 17371cb0ef41Sopenharmony_ci switch (sa) { 17381cb0ef41Sopenharmony_ci case ALIGN: { 17391cb0ef41Sopenharmony_ci Format(instr, "align 'rd, 'rs, 'rt, 'bp2"); 17401cb0ef41Sopenharmony_ci break; 17411cb0ef41Sopenharmony_ci } 17421cb0ef41Sopenharmony_ci default: 17431cb0ef41Sopenharmony_ci UNREACHABLE(); 17441cb0ef41Sopenharmony_ci } 17451cb0ef41Sopenharmony_ci break; 17461cb0ef41Sopenharmony_ci } 17471cb0ef41Sopenharmony_ci } 17481cb0ef41Sopenharmony_ci break; 17491cb0ef41Sopenharmony_ci } 17501cb0ef41Sopenharmony_ci case DBSHFL: { 17511cb0ef41Sopenharmony_ci int sa = instr->SaFieldRaw() >> kSaShift; 17521cb0ef41Sopenharmony_ci switch (sa) { 17531cb0ef41Sopenharmony_ci case DBITSWAP: { 17541cb0ef41Sopenharmony_ci switch (instr->SaFieldRaw() >> kSaShift) { 17551cb0ef41Sopenharmony_ci case DBITSWAP_SA: 17561cb0ef41Sopenharmony_ci Format(instr, "dbitswap 'rd, 'rt"); 17571cb0ef41Sopenharmony_ci break; 17581cb0ef41Sopenharmony_ci default: 17591cb0ef41Sopenharmony_ci UNREACHABLE(); 17601cb0ef41Sopenharmony_ci } 17611cb0ef41Sopenharmony_ci break; 17621cb0ef41Sopenharmony_ci } 17631cb0ef41Sopenharmony_ci case DSBH: { 17641cb0ef41Sopenharmony_ci Format(instr, "dsbh 'rd, 'rt"); 17651cb0ef41Sopenharmony_ci break; 17661cb0ef41Sopenharmony_ci } 17671cb0ef41Sopenharmony_ci case DSHD: { 17681cb0ef41Sopenharmony_ci Format(instr, "dshd 'rd, 'rt"); 17691cb0ef41Sopenharmony_ci break; 17701cb0ef41Sopenharmony_ci } 17711cb0ef41Sopenharmony_ci default: { 17721cb0ef41Sopenharmony_ci sa >>= kBp3Bits; 17731cb0ef41Sopenharmony_ci switch (sa) { 17741cb0ef41Sopenharmony_ci case DALIGN: { 17751cb0ef41Sopenharmony_ci Format(instr, "dalign 'rd, 'rs, 'rt, 'bp3"); 17761cb0ef41Sopenharmony_ci break; 17771cb0ef41Sopenharmony_ci } 17781cb0ef41Sopenharmony_ci default: 17791cb0ef41Sopenharmony_ci UNREACHABLE(); 17801cb0ef41Sopenharmony_ci } 17811cb0ef41Sopenharmony_ci break; 17821cb0ef41Sopenharmony_ci } 17831cb0ef41Sopenharmony_ci } 17841cb0ef41Sopenharmony_ci break; 17851cb0ef41Sopenharmony_ci } 17861cb0ef41Sopenharmony_ci default: 17871cb0ef41Sopenharmony_ci UNREACHABLE(); 17881cb0ef41Sopenharmony_ci } 17891cb0ef41Sopenharmony_ci} 17901cb0ef41Sopenharmony_ci 17911cb0ef41Sopenharmony_ciint Decoder::DecodeTypeRegister(Instruction* instr) { 17921cb0ef41Sopenharmony_ci switch (instr->OpcodeFieldRaw()) { 17931cb0ef41Sopenharmony_ci case COP1: // Coprocessor instructions. 17941cb0ef41Sopenharmony_ci DecodeTypeRegisterCOP1(instr); 17951cb0ef41Sopenharmony_ci break; 17961cb0ef41Sopenharmony_ci case COP1X: 17971cb0ef41Sopenharmony_ci DecodeTypeRegisterCOP1X(instr); 17981cb0ef41Sopenharmony_ci break; 17991cb0ef41Sopenharmony_ci case SPECIAL: 18001cb0ef41Sopenharmony_ci switch (instr->FunctionFieldRaw()) { 18011cb0ef41Sopenharmony_ci case BREAK: 18021cb0ef41Sopenharmony_ci return DecodeBreakInstr(instr); 18031cb0ef41Sopenharmony_ci default: 18041cb0ef41Sopenharmony_ci DecodeTypeRegisterSPECIAL(instr); 18051cb0ef41Sopenharmony_ci break; 18061cb0ef41Sopenharmony_ci } 18071cb0ef41Sopenharmony_ci break; 18081cb0ef41Sopenharmony_ci case SPECIAL2: 18091cb0ef41Sopenharmony_ci DecodeTypeRegisterSPECIAL2(instr); 18101cb0ef41Sopenharmony_ci break; 18111cb0ef41Sopenharmony_ci case SPECIAL3: 18121cb0ef41Sopenharmony_ci DecodeTypeRegisterSPECIAL3(instr); 18131cb0ef41Sopenharmony_ci break; 18141cb0ef41Sopenharmony_ci case MSA: 18151cb0ef41Sopenharmony_ci switch (instr->MSAMinorOpcodeField()) { 18161cb0ef41Sopenharmony_ci case kMsaMinor3R: 18171cb0ef41Sopenharmony_ci DecodeTypeMsa3R(instr); 18181cb0ef41Sopenharmony_ci break; 18191cb0ef41Sopenharmony_ci case kMsaMinor3RF: 18201cb0ef41Sopenharmony_ci DecodeTypeMsa3RF(instr); 18211cb0ef41Sopenharmony_ci break; 18221cb0ef41Sopenharmony_ci case kMsaMinorVEC: 18231cb0ef41Sopenharmony_ci DecodeTypeMsaVec(instr); 18241cb0ef41Sopenharmony_ci break; 18251cb0ef41Sopenharmony_ci case kMsaMinor2R: 18261cb0ef41Sopenharmony_ci DecodeTypeMsa2R(instr); 18271cb0ef41Sopenharmony_ci break; 18281cb0ef41Sopenharmony_ci case kMsaMinor2RF: 18291cb0ef41Sopenharmony_ci DecodeTypeMsa2RF(instr); 18301cb0ef41Sopenharmony_ci break; 18311cb0ef41Sopenharmony_ci case kMsaMinorELM: 18321cb0ef41Sopenharmony_ci DecodeTypeMsaELM(instr); 18331cb0ef41Sopenharmony_ci break; 18341cb0ef41Sopenharmony_ci default: 18351cb0ef41Sopenharmony_ci UNREACHABLE(); 18361cb0ef41Sopenharmony_ci } 18371cb0ef41Sopenharmony_ci break; 18381cb0ef41Sopenharmony_ci default: 18391cb0ef41Sopenharmony_ci UNREACHABLE(); 18401cb0ef41Sopenharmony_ci } 18411cb0ef41Sopenharmony_ci return kInstrSize; 18421cb0ef41Sopenharmony_ci} 18431cb0ef41Sopenharmony_ci 18441cb0ef41Sopenharmony_civoid Decoder::DecodeTypeImmediateCOP1(Instruction* instr) { 18451cb0ef41Sopenharmony_ci switch (instr->RsFieldRaw()) { 18461cb0ef41Sopenharmony_ci case BC1: 18471cb0ef41Sopenharmony_ci if (instr->FBtrueValue()) { 18481cb0ef41Sopenharmony_ci Format(instr, "bc1t 'bc, 'imm16u -> 'imm16p4s2"); 18491cb0ef41Sopenharmony_ci } else { 18501cb0ef41Sopenharmony_ci Format(instr, "bc1f 'bc, 'imm16u -> 'imm16p4s2"); 18511cb0ef41Sopenharmony_ci } 18521cb0ef41Sopenharmony_ci break; 18531cb0ef41Sopenharmony_ci case BC1EQZ: 18541cb0ef41Sopenharmony_ci Format(instr, "bc1eqz 'ft, 'imm16u -> 'imm16p4s2"); 18551cb0ef41Sopenharmony_ci break; 18561cb0ef41Sopenharmony_ci case BC1NEZ: 18571cb0ef41Sopenharmony_ci Format(instr, "bc1nez 'ft, 'imm16u -> 'imm16p4s2"); 18581cb0ef41Sopenharmony_ci break; 18591cb0ef41Sopenharmony_ci case BZ_V: 18601cb0ef41Sopenharmony_ci case BZ_B: 18611cb0ef41Sopenharmony_ci case BZ_H: 18621cb0ef41Sopenharmony_ci case BZ_W: 18631cb0ef41Sopenharmony_ci case BZ_D: 18641cb0ef41Sopenharmony_ci Format(instr, "bz.'t 'wt, 'imm16s -> 'imm16p4s2"); 18651cb0ef41Sopenharmony_ci break; 18661cb0ef41Sopenharmony_ci case BNZ_V: 18671cb0ef41Sopenharmony_ci case BNZ_B: 18681cb0ef41Sopenharmony_ci case BNZ_H: 18691cb0ef41Sopenharmony_ci case BNZ_W: 18701cb0ef41Sopenharmony_ci case BNZ_D: 18711cb0ef41Sopenharmony_ci Format(instr, "bnz.'t 'wt, 'imm16s -> 'imm16p4s2"); 18721cb0ef41Sopenharmony_ci break; 18731cb0ef41Sopenharmony_ci default: 18741cb0ef41Sopenharmony_ci UNREACHABLE(); 18751cb0ef41Sopenharmony_ci } 18761cb0ef41Sopenharmony_ci} 18771cb0ef41Sopenharmony_ci 18781cb0ef41Sopenharmony_civoid Decoder::DecodeTypeImmediateREGIMM(Instruction* instr) { 18791cb0ef41Sopenharmony_ci switch (instr->RtFieldRaw()) { 18801cb0ef41Sopenharmony_ci case BLTZ: 18811cb0ef41Sopenharmony_ci Format(instr, "bltz 'rs, 'imm16u -> 'imm16p4s2"); 18821cb0ef41Sopenharmony_ci break; 18831cb0ef41Sopenharmony_ci case BLTZAL: 18841cb0ef41Sopenharmony_ci Format(instr, "bltzal 'rs, 'imm16u -> 'imm16p4s2"); 18851cb0ef41Sopenharmony_ci break; 18861cb0ef41Sopenharmony_ci case BGEZ: 18871cb0ef41Sopenharmony_ci Format(instr, "bgez 'rs, 'imm16u -> 'imm16p4s2"); 18881cb0ef41Sopenharmony_ci break; 18891cb0ef41Sopenharmony_ci case BGEZAL: { 18901cb0ef41Sopenharmony_ci if (instr->RsValue() == 0) 18911cb0ef41Sopenharmony_ci Format(instr, "bal 'imm16s -> 'imm16p4s2"); 18921cb0ef41Sopenharmony_ci else 18931cb0ef41Sopenharmony_ci Format(instr, "bgezal 'rs, 'imm16u -> 'imm16p4s2"); 18941cb0ef41Sopenharmony_ci break; 18951cb0ef41Sopenharmony_ci } 18961cb0ef41Sopenharmony_ci case BGEZALL: 18971cb0ef41Sopenharmony_ci Format(instr, "bgezall 'rs, 'imm16u -> 'imm16p4s2"); 18981cb0ef41Sopenharmony_ci break; 18991cb0ef41Sopenharmony_ci case DAHI: 19001cb0ef41Sopenharmony_ci Format(instr, "dahi 'rs, 'imm16x"); 19011cb0ef41Sopenharmony_ci break; 19021cb0ef41Sopenharmony_ci case DATI: 19031cb0ef41Sopenharmony_ci Format(instr, "dati 'rs, 'imm16x"); 19041cb0ef41Sopenharmony_ci break; 19051cb0ef41Sopenharmony_ci default: 19061cb0ef41Sopenharmony_ci UNREACHABLE(); 19071cb0ef41Sopenharmony_ci } 19081cb0ef41Sopenharmony_ci} 19091cb0ef41Sopenharmony_ci 19101cb0ef41Sopenharmony_civoid Decoder::DecodeTypeImmediateSPECIAL3(Instruction* instr) { 19111cb0ef41Sopenharmony_ci switch (instr->FunctionFieldRaw()) { 19121cb0ef41Sopenharmony_ci case LL_R6: { 19131cb0ef41Sopenharmony_ci if (kArchVariant == kMips64r6) { 19141cb0ef41Sopenharmony_ci Format(instr, "ll 'rt, 'imm9s('rs)"); 19151cb0ef41Sopenharmony_ci } else { 19161cb0ef41Sopenharmony_ci Unknown(instr); 19171cb0ef41Sopenharmony_ci } 19181cb0ef41Sopenharmony_ci break; 19191cb0ef41Sopenharmony_ci } 19201cb0ef41Sopenharmony_ci case LLD_R6: { 19211cb0ef41Sopenharmony_ci if (kArchVariant == kMips64r6) { 19221cb0ef41Sopenharmony_ci Format(instr, "lld 'rt, 'imm9s('rs)"); 19231cb0ef41Sopenharmony_ci } else { 19241cb0ef41Sopenharmony_ci Unknown(instr); 19251cb0ef41Sopenharmony_ci } 19261cb0ef41Sopenharmony_ci break; 19271cb0ef41Sopenharmony_ci } 19281cb0ef41Sopenharmony_ci case SC_R6: { 19291cb0ef41Sopenharmony_ci if (kArchVariant == kMips64r6) { 19301cb0ef41Sopenharmony_ci Format(instr, "sc 'rt, 'imm9s('rs)"); 19311cb0ef41Sopenharmony_ci } else { 19321cb0ef41Sopenharmony_ci Unknown(instr); 19331cb0ef41Sopenharmony_ci } 19341cb0ef41Sopenharmony_ci break; 19351cb0ef41Sopenharmony_ci } 19361cb0ef41Sopenharmony_ci case SCD_R6: { 19371cb0ef41Sopenharmony_ci if (kArchVariant == kMips64r6) { 19381cb0ef41Sopenharmony_ci Format(instr, "scd 'rt, 'imm9s('rs)"); 19391cb0ef41Sopenharmony_ci } else { 19401cb0ef41Sopenharmony_ci Unknown(instr); 19411cb0ef41Sopenharmony_ci } 19421cb0ef41Sopenharmony_ci break; 19431cb0ef41Sopenharmony_ci } 19441cb0ef41Sopenharmony_ci default: 19451cb0ef41Sopenharmony_ci UNREACHABLE(); 19461cb0ef41Sopenharmony_ci } 19471cb0ef41Sopenharmony_ci} 19481cb0ef41Sopenharmony_ci 19491cb0ef41Sopenharmony_civoid Decoder::DecodeTypeImmediate(Instruction* instr) { 19501cb0ef41Sopenharmony_ci switch (instr->OpcodeFieldRaw()) { 19511cb0ef41Sopenharmony_ci case COP1: 19521cb0ef41Sopenharmony_ci DecodeTypeImmediateCOP1(instr); 19531cb0ef41Sopenharmony_ci break; // Case COP1. 19541cb0ef41Sopenharmony_ci // ------------- REGIMM class. 19551cb0ef41Sopenharmony_ci case REGIMM: 19561cb0ef41Sopenharmony_ci DecodeTypeImmediateREGIMM(instr); 19571cb0ef41Sopenharmony_ci break; // Case REGIMM. 19581cb0ef41Sopenharmony_ci // ------------- Branch instructions. 19591cb0ef41Sopenharmony_ci case BEQ: 19601cb0ef41Sopenharmony_ci Format(instr, "beq 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 19611cb0ef41Sopenharmony_ci break; 19621cb0ef41Sopenharmony_ci case BC: 19631cb0ef41Sopenharmony_ci Format(instr, "bc 'imm26s -> 'imm26p4s2"); 19641cb0ef41Sopenharmony_ci break; 19651cb0ef41Sopenharmony_ci case BALC: 19661cb0ef41Sopenharmony_ci Format(instr, "balc 'imm26s -> 'imm26p4s2"); 19671cb0ef41Sopenharmony_ci break; 19681cb0ef41Sopenharmony_ci case BNE: 19691cb0ef41Sopenharmony_ci Format(instr, "bne 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 19701cb0ef41Sopenharmony_ci break; 19711cb0ef41Sopenharmony_ci case BLEZ: 19721cb0ef41Sopenharmony_ci if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { 19731cb0ef41Sopenharmony_ci Format(instr, "blez 'rs, 'imm16u -> 'imm16p4s2"); 19741cb0ef41Sopenharmony_ci } else if ((instr->RtValue() != instr->RsValue()) && 19751cb0ef41Sopenharmony_ci (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 19761cb0ef41Sopenharmony_ci Format(instr, "bgeuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 19771cb0ef41Sopenharmony_ci } else if ((instr->RtValue() == instr->RsValue()) && 19781cb0ef41Sopenharmony_ci (instr->RtValue() != 0)) { 19791cb0ef41Sopenharmony_ci Format(instr, "bgezalc 'rs, 'imm16u -> 'imm16p4s2"); 19801cb0ef41Sopenharmony_ci } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 19811cb0ef41Sopenharmony_ci Format(instr, "blezalc 'rt, 'imm16u -> 'imm16p4s2"); 19821cb0ef41Sopenharmony_ci } else { 19831cb0ef41Sopenharmony_ci UNREACHABLE(); 19841cb0ef41Sopenharmony_ci } 19851cb0ef41Sopenharmony_ci break; 19861cb0ef41Sopenharmony_ci case BGTZ: 19871cb0ef41Sopenharmony_ci if ((instr->RtValue() == 0) && (instr->RsValue() != 0)) { 19881cb0ef41Sopenharmony_ci Format(instr, "bgtz 'rs, 'imm16u -> 'imm16p4s2"); 19891cb0ef41Sopenharmony_ci } else if ((instr->RtValue() != instr->RsValue()) && 19901cb0ef41Sopenharmony_ci (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 19911cb0ef41Sopenharmony_ci Format(instr, "bltuc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 19921cb0ef41Sopenharmony_ci } else if ((instr->RtValue() == instr->RsValue()) && 19931cb0ef41Sopenharmony_ci (instr->RtValue() != 0)) { 19941cb0ef41Sopenharmony_ci Format(instr, "bltzalc 'rt, 'imm16u -> 'imm16p4s2"); 19951cb0ef41Sopenharmony_ci } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 19961cb0ef41Sopenharmony_ci Format(instr, "bgtzalc 'rt, 'imm16u -> 'imm16p4s2"); 19971cb0ef41Sopenharmony_ci } else { 19981cb0ef41Sopenharmony_ci UNREACHABLE(); 19991cb0ef41Sopenharmony_ci } 20001cb0ef41Sopenharmony_ci break; 20011cb0ef41Sopenharmony_ci case BLEZL: 20021cb0ef41Sopenharmony_ci if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { 20031cb0ef41Sopenharmony_ci Format(instr, "bgezc 'rt, 'imm16u -> 'imm16p4s2"); 20041cb0ef41Sopenharmony_ci } else if ((instr->RtValue() != instr->RsValue()) && 20051cb0ef41Sopenharmony_ci (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 20061cb0ef41Sopenharmony_ci Format(instr, "bgec 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 20071cb0ef41Sopenharmony_ci } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 20081cb0ef41Sopenharmony_ci Format(instr, "blezc 'rt, 'imm16u -> 'imm16p4s2"); 20091cb0ef41Sopenharmony_ci } else { 20101cb0ef41Sopenharmony_ci UNREACHABLE(); 20111cb0ef41Sopenharmony_ci } 20121cb0ef41Sopenharmony_ci break; 20131cb0ef41Sopenharmony_ci case BGTZL: 20141cb0ef41Sopenharmony_ci if ((instr->RtValue() == instr->RsValue()) && (instr->RtValue() != 0)) { 20151cb0ef41Sopenharmony_ci Format(instr, "bltzc 'rt, 'imm16u -> 'imm16p4s2"); 20161cb0ef41Sopenharmony_ci } else if ((instr->RtValue() != instr->RsValue()) && 20171cb0ef41Sopenharmony_ci (instr->RsValue() != 0) && (instr->RtValue() != 0)) { 20181cb0ef41Sopenharmony_ci Format(instr, "bltc 'rs, 'rt, 'imm16u -> 'imm16p4s2"); 20191cb0ef41Sopenharmony_ci } else if ((instr->RsValue() == 0) && (instr->RtValue() != 0)) { 20201cb0ef41Sopenharmony_ci Format(instr, "bgtzc 'rt, 'imm16u -> 'imm16p4s2"); 20211cb0ef41Sopenharmony_ci } else { 20221cb0ef41Sopenharmony_ci UNREACHABLE(); 20231cb0ef41Sopenharmony_ci } 20241cb0ef41Sopenharmony_ci break; 20251cb0ef41Sopenharmony_ci case POP66: 20261cb0ef41Sopenharmony_ci if (instr->RsValue() == JIC) { 20271cb0ef41Sopenharmony_ci Format(instr, "jic 'rt, 'imm16s"); 20281cb0ef41Sopenharmony_ci } else { 20291cb0ef41Sopenharmony_ci Format(instr, "beqzc 'rs, 'imm21s -> 'imm21p4s2"); 20301cb0ef41Sopenharmony_ci } 20311cb0ef41Sopenharmony_ci break; 20321cb0ef41Sopenharmony_ci case POP76: 20331cb0ef41Sopenharmony_ci if (instr->RsValue() == JIALC) { 20341cb0ef41Sopenharmony_ci Format(instr, "jialc 'rt, 'imm16s"); 20351cb0ef41Sopenharmony_ci } else { 20361cb0ef41Sopenharmony_ci Format(instr, "bnezc 'rs, 'imm21s -> 'imm21p4s2"); 20371cb0ef41Sopenharmony_ci } 20381cb0ef41Sopenharmony_ci break; 20391cb0ef41Sopenharmony_ci // ------------- Arithmetic instructions. 20401cb0ef41Sopenharmony_ci case ADDI: 20411cb0ef41Sopenharmony_ci if (kArchVariant != kMips64r6) { 20421cb0ef41Sopenharmony_ci Format(instr, "addi 'rt, 'rs, 'imm16s"); 20431cb0ef41Sopenharmony_ci } else { 20441cb0ef41Sopenharmony_ci int rs_reg = instr->RsValue(); 20451cb0ef41Sopenharmony_ci int rt_reg = instr->RtValue(); 20461cb0ef41Sopenharmony_ci // Check if BOVC, BEQZALC or BEQC instruction. 20471cb0ef41Sopenharmony_ci if (rs_reg >= rt_reg) { 20481cb0ef41Sopenharmony_ci Format(instr, "bovc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 20491cb0ef41Sopenharmony_ci } else { 20501cb0ef41Sopenharmony_ci DCHECK_GT(rt_reg, 0); 20511cb0ef41Sopenharmony_ci if (rs_reg == 0) { 20521cb0ef41Sopenharmony_ci Format(instr, "beqzalc 'rt, 'imm16s -> 'imm16p4s2"); 20531cb0ef41Sopenharmony_ci } else { 20541cb0ef41Sopenharmony_ci Format(instr, "beqc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 20551cb0ef41Sopenharmony_ci } 20561cb0ef41Sopenharmony_ci } 20571cb0ef41Sopenharmony_ci } 20581cb0ef41Sopenharmony_ci break; 20591cb0ef41Sopenharmony_ci case DADDI: 20601cb0ef41Sopenharmony_ci if (kArchVariant != kMips64r6) { 20611cb0ef41Sopenharmony_ci Format(instr, "daddi 'rt, 'rs, 'imm16s"); 20621cb0ef41Sopenharmony_ci } else { 20631cb0ef41Sopenharmony_ci int rs_reg = instr->RsValue(); 20641cb0ef41Sopenharmony_ci int rt_reg = instr->RtValue(); 20651cb0ef41Sopenharmony_ci // Check if BNVC, BNEZALC or BNEC instruction. 20661cb0ef41Sopenharmony_ci if (rs_reg >= rt_reg) { 20671cb0ef41Sopenharmony_ci Format(instr, "bnvc 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 20681cb0ef41Sopenharmony_ci } else { 20691cb0ef41Sopenharmony_ci DCHECK_GT(rt_reg, 0); 20701cb0ef41Sopenharmony_ci if (rs_reg == 0) { 20711cb0ef41Sopenharmony_ci Format(instr, "bnezalc 'rt, 'imm16s -> 'imm16p4s2"); 20721cb0ef41Sopenharmony_ci } else { 20731cb0ef41Sopenharmony_ci Format(instr, "bnec 'rs, 'rt, 'imm16s -> 'imm16p4s2"); 20741cb0ef41Sopenharmony_ci } 20751cb0ef41Sopenharmony_ci } 20761cb0ef41Sopenharmony_ci } 20771cb0ef41Sopenharmony_ci break; 20781cb0ef41Sopenharmony_ci case ADDIU: 20791cb0ef41Sopenharmony_ci Format(instr, "addiu 'rt, 'rs, 'imm16s"); 20801cb0ef41Sopenharmony_ci break; 20811cb0ef41Sopenharmony_ci case DADDIU: 20821cb0ef41Sopenharmony_ci Format(instr, "daddiu 'rt, 'rs, 'imm16s"); 20831cb0ef41Sopenharmony_ci break; 20841cb0ef41Sopenharmony_ci case SLTI: 20851cb0ef41Sopenharmony_ci Format(instr, "slti 'rt, 'rs, 'imm16s"); 20861cb0ef41Sopenharmony_ci break; 20871cb0ef41Sopenharmony_ci case SLTIU: 20881cb0ef41Sopenharmony_ci Format(instr, "sltiu 'rt, 'rs, 'imm16u"); 20891cb0ef41Sopenharmony_ci break; 20901cb0ef41Sopenharmony_ci case ANDI: 20911cb0ef41Sopenharmony_ci Format(instr, "andi 'rt, 'rs, 'imm16x"); 20921cb0ef41Sopenharmony_ci break; 20931cb0ef41Sopenharmony_ci case ORI: 20941cb0ef41Sopenharmony_ci Format(instr, "ori 'rt, 'rs, 'imm16x"); 20951cb0ef41Sopenharmony_ci break; 20961cb0ef41Sopenharmony_ci case XORI: 20971cb0ef41Sopenharmony_ci Format(instr, "xori 'rt, 'rs, 'imm16x"); 20981cb0ef41Sopenharmony_ci break; 20991cb0ef41Sopenharmony_ci case LUI: 21001cb0ef41Sopenharmony_ci if (kArchVariant != kMips64r6) { 21011cb0ef41Sopenharmony_ci Format(instr, "lui 'rt, 'imm16x"); 21021cb0ef41Sopenharmony_ci } else { 21031cb0ef41Sopenharmony_ci if (instr->RsValue() != 0) { 21041cb0ef41Sopenharmony_ci Format(instr, "aui 'rt, 'rs, 'imm16x"); 21051cb0ef41Sopenharmony_ci } else { 21061cb0ef41Sopenharmony_ci Format(instr, "lui 'rt, 'imm16x"); 21071cb0ef41Sopenharmony_ci } 21081cb0ef41Sopenharmony_ci } 21091cb0ef41Sopenharmony_ci break; 21101cb0ef41Sopenharmony_ci case DAUI: 21111cb0ef41Sopenharmony_ci Format(instr, "daui 'rt, 'rs, 'imm16x"); 21121cb0ef41Sopenharmony_ci break; 21131cb0ef41Sopenharmony_ci // ------------- Memory instructions. 21141cb0ef41Sopenharmony_ci case LB: 21151cb0ef41Sopenharmony_ci Format(instr, "lb 'rt, 'imm16s('rs)"); 21161cb0ef41Sopenharmony_ci break; 21171cb0ef41Sopenharmony_ci case LH: 21181cb0ef41Sopenharmony_ci Format(instr, "lh 'rt, 'imm16s('rs)"); 21191cb0ef41Sopenharmony_ci break; 21201cb0ef41Sopenharmony_ci case LWL: 21211cb0ef41Sopenharmony_ci Format(instr, "lwl 'rt, 'imm16s('rs)"); 21221cb0ef41Sopenharmony_ci break; 21231cb0ef41Sopenharmony_ci case LDL: 21241cb0ef41Sopenharmony_ci Format(instr, "ldl 'rt, 'imm16s('rs)"); 21251cb0ef41Sopenharmony_ci break; 21261cb0ef41Sopenharmony_ci case LW: 21271cb0ef41Sopenharmony_ci Format(instr, "lw 'rt, 'imm16s('rs)"); 21281cb0ef41Sopenharmony_ci break; 21291cb0ef41Sopenharmony_ci case LWU: 21301cb0ef41Sopenharmony_ci Format(instr, "lwu 'rt, 'imm16s('rs)"); 21311cb0ef41Sopenharmony_ci break; 21321cb0ef41Sopenharmony_ci case LD: 21331cb0ef41Sopenharmony_ci Format(instr, "ld 'rt, 'imm16s('rs)"); 21341cb0ef41Sopenharmony_ci break; 21351cb0ef41Sopenharmony_ci case LBU: 21361cb0ef41Sopenharmony_ci Format(instr, "lbu 'rt, 'imm16s('rs)"); 21371cb0ef41Sopenharmony_ci break; 21381cb0ef41Sopenharmony_ci case LHU: 21391cb0ef41Sopenharmony_ci Format(instr, "lhu 'rt, 'imm16s('rs)"); 21401cb0ef41Sopenharmony_ci break; 21411cb0ef41Sopenharmony_ci case LWR: 21421cb0ef41Sopenharmony_ci Format(instr, "lwr 'rt, 'imm16s('rs)"); 21431cb0ef41Sopenharmony_ci break; 21441cb0ef41Sopenharmony_ci case LDR: 21451cb0ef41Sopenharmony_ci Format(instr, "ldr 'rt, 'imm16s('rs)"); 21461cb0ef41Sopenharmony_ci break; 21471cb0ef41Sopenharmony_ci case PREF: 21481cb0ef41Sopenharmony_ci Format(instr, "pref 'rt, 'imm16s('rs)"); 21491cb0ef41Sopenharmony_ci break; 21501cb0ef41Sopenharmony_ci case SB: 21511cb0ef41Sopenharmony_ci Format(instr, "sb 'rt, 'imm16s('rs)"); 21521cb0ef41Sopenharmony_ci break; 21531cb0ef41Sopenharmony_ci case SH: 21541cb0ef41Sopenharmony_ci Format(instr, "sh 'rt, 'imm16s('rs)"); 21551cb0ef41Sopenharmony_ci break; 21561cb0ef41Sopenharmony_ci case SWL: 21571cb0ef41Sopenharmony_ci Format(instr, "swl 'rt, 'imm16s('rs)"); 21581cb0ef41Sopenharmony_ci break; 21591cb0ef41Sopenharmony_ci case SW: 21601cb0ef41Sopenharmony_ci Format(instr, "sw 'rt, 'imm16s('rs)"); 21611cb0ef41Sopenharmony_ci break; 21621cb0ef41Sopenharmony_ci case SD: 21631cb0ef41Sopenharmony_ci Format(instr, "sd 'rt, 'imm16s('rs)"); 21641cb0ef41Sopenharmony_ci break; 21651cb0ef41Sopenharmony_ci case SWR: 21661cb0ef41Sopenharmony_ci Format(instr, "swr 'rt, 'imm16s('rs)"); 21671cb0ef41Sopenharmony_ci break; 21681cb0ef41Sopenharmony_ci case SDR: 21691cb0ef41Sopenharmony_ci Format(instr, "sdr 'rt, 'imm16s('rs)"); 21701cb0ef41Sopenharmony_ci break; 21711cb0ef41Sopenharmony_ci case SDL: 21721cb0ef41Sopenharmony_ci Format(instr, "sdl 'rt, 'imm16s('rs)"); 21731cb0ef41Sopenharmony_ci break; 21741cb0ef41Sopenharmony_ci case LL: 21751cb0ef41Sopenharmony_ci if (kArchVariant == kMips64r6) { 21761cb0ef41Sopenharmony_ci Unknown(instr); 21771cb0ef41Sopenharmony_ci } else { 21781cb0ef41Sopenharmony_ci Format(instr, "ll 'rt, 'imm16s('rs)"); 21791cb0ef41Sopenharmony_ci } 21801cb0ef41Sopenharmony_ci break; 21811cb0ef41Sopenharmony_ci case LLD: 21821cb0ef41Sopenharmony_ci if (kArchVariant == kMips64r6) { 21831cb0ef41Sopenharmony_ci Unknown(instr); 21841cb0ef41Sopenharmony_ci } else { 21851cb0ef41Sopenharmony_ci Format(instr, "lld 'rt, 'imm16s('rs)"); 21861cb0ef41Sopenharmony_ci } 21871cb0ef41Sopenharmony_ci break; 21881cb0ef41Sopenharmony_ci case SC: 21891cb0ef41Sopenharmony_ci if (kArchVariant == kMips64r6) { 21901cb0ef41Sopenharmony_ci Unknown(instr); 21911cb0ef41Sopenharmony_ci } else { 21921cb0ef41Sopenharmony_ci Format(instr, "sc 'rt, 'imm16s('rs)"); 21931cb0ef41Sopenharmony_ci } 21941cb0ef41Sopenharmony_ci break; 21951cb0ef41Sopenharmony_ci case SCD: 21961cb0ef41Sopenharmony_ci if (kArchVariant == kMips64r6) { 21971cb0ef41Sopenharmony_ci Unknown(instr); 21981cb0ef41Sopenharmony_ci } else { 21991cb0ef41Sopenharmony_ci Format(instr, "scd 'rt, 'imm16s('rs)"); 22001cb0ef41Sopenharmony_ci } 22011cb0ef41Sopenharmony_ci break; 22021cb0ef41Sopenharmony_ci case LWC1: 22031cb0ef41Sopenharmony_ci Format(instr, "lwc1 'ft, 'imm16s('rs)"); 22041cb0ef41Sopenharmony_ci break; 22051cb0ef41Sopenharmony_ci case LDC1: 22061cb0ef41Sopenharmony_ci Format(instr, "ldc1 'ft, 'imm16s('rs)"); 22071cb0ef41Sopenharmony_ci break; 22081cb0ef41Sopenharmony_ci case SWC1: 22091cb0ef41Sopenharmony_ci Format(instr, "swc1 'ft, 'imm16s('rs)"); 22101cb0ef41Sopenharmony_ci break; 22111cb0ef41Sopenharmony_ci case SDC1: 22121cb0ef41Sopenharmony_ci Format(instr, "sdc1 'ft, 'imm16s('rs)"); 22131cb0ef41Sopenharmony_ci break; 22141cb0ef41Sopenharmony_ci case PCREL: { 22151cb0ef41Sopenharmony_ci int32_t imm21 = instr->Imm21Value(); 22161cb0ef41Sopenharmony_ci // rt field: 5-bits checking 22171cb0ef41Sopenharmony_ci uint8_t rt = (imm21 >> kImm16Bits); 22181cb0ef41Sopenharmony_ci switch (rt) { 22191cb0ef41Sopenharmony_ci case ALUIPC: 22201cb0ef41Sopenharmony_ci Format(instr, "aluipc 'rs, 'imm16s"); 22211cb0ef41Sopenharmony_ci break; 22221cb0ef41Sopenharmony_ci case AUIPC: 22231cb0ef41Sopenharmony_ci Format(instr, "auipc 'rs, 'imm16s"); 22241cb0ef41Sopenharmony_ci break; 22251cb0ef41Sopenharmony_ci default: { 22261cb0ef41Sopenharmony_ci // rt field: checking of the most significant 3-bits 22271cb0ef41Sopenharmony_ci rt = (imm21 >> kImm18Bits); 22281cb0ef41Sopenharmony_ci switch (rt) { 22291cb0ef41Sopenharmony_ci case LDPC: 22301cb0ef41Sopenharmony_ci Format(instr, "ldpc 'rs, 'imm18s"); 22311cb0ef41Sopenharmony_ci break; 22321cb0ef41Sopenharmony_ci default: { 22331cb0ef41Sopenharmony_ci // rt field: checking of the most significant 2-bits 22341cb0ef41Sopenharmony_ci rt = (imm21 >> kImm19Bits); 22351cb0ef41Sopenharmony_ci switch (rt) { 22361cb0ef41Sopenharmony_ci case LWUPC: 22371cb0ef41Sopenharmony_ci Format(instr, "lwupc 'rs, 'imm19s"); 22381cb0ef41Sopenharmony_ci break; 22391cb0ef41Sopenharmony_ci case LWPC: 22401cb0ef41Sopenharmony_ci Format(instr, "lwpc 'rs, 'imm19s"); 22411cb0ef41Sopenharmony_ci break; 22421cb0ef41Sopenharmony_ci case ADDIUPC: 22431cb0ef41Sopenharmony_ci Format(instr, "addiupc 'rs, 'imm19s"); 22441cb0ef41Sopenharmony_ci break; 22451cb0ef41Sopenharmony_ci default: 22461cb0ef41Sopenharmony_ci UNREACHABLE(); 22471cb0ef41Sopenharmony_ci } 22481cb0ef41Sopenharmony_ci break; 22491cb0ef41Sopenharmony_ci } 22501cb0ef41Sopenharmony_ci } 22511cb0ef41Sopenharmony_ci break; 22521cb0ef41Sopenharmony_ci } 22531cb0ef41Sopenharmony_ci } 22541cb0ef41Sopenharmony_ci break; 22551cb0ef41Sopenharmony_ci } 22561cb0ef41Sopenharmony_ci case SPECIAL3: 22571cb0ef41Sopenharmony_ci DecodeTypeImmediateSPECIAL3(instr); 22581cb0ef41Sopenharmony_ci break; 22591cb0ef41Sopenharmony_ci case MSA: 22601cb0ef41Sopenharmony_ci switch (instr->MSAMinorOpcodeField()) { 22611cb0ef41Sopenharmony_ci case kMsaMinorI8: 22621cb0ef41Sopenharmony_ci DecodeTypeMsaI8(instr); 22631cb0ef41Sopenharmony_ci break; 22641cb0ef41Sopenharmony_ci case kMsaMinorI5: 22651cb0ef41Sopenharmony_ci DecodeTypeMsaI5(instr); 22661cb0ef41Sopenharmony_ci break; 22671cb0ef41Sopenharmony_ci case kMsaMinorI10: 22681cb0ef41Sopenharmony_ci DecodeTypeMsaI10(instr); 22691cb0ef41Sopenharmony_ci break; 22701cb0ef41Sopenharmony_ci case kMsaMinorELM: 22711cb0ef41Sopenharmony_ci DecodeTypeMsaELM(instr); 22721cb0ef41Sopenharmony_ci break; 22731cb0ef41Sopenharmony_ci case kMsaMinorBIT: 22741cb0ef41Sopenharmony_ci DecodeTypeMsaBIT(instr); 22751cb0ef41Sopenharmony_ci break; 22761cb0ef41Sopenharmony_ci case kMsaMinorMI10: 22771cb0ef41Sopenharmony_ci DecodeTypeMsaMI10(instr); 22781cb0ef41Sopenharmony_ci break; 22791cb0ef41Sopenharmony_ci default: 22801cb0ef41Sopenharmony_ci UNREACHABLE(); 22811cb0ef41Sopenharmony_ci } 22821cb0ef41Sopenharmony_ci break; 22831cb0ef41Sopenharmony_ci default: 22841cb0ef41Sopenharmony_ci printf("a 0x%x \n", instr->OpcodeFieldRaw()); 22851cb0ef41Sopenharmony_ci UNREACHABLE(); 22861cb0ef41Sopenharmony_ci } 22871cb0ef41Sopenharmony_ci} 22881cb0ef41Sopenharmony_ci 22891cb0ef41Sopenharmony_civoid Decoder::DecodeTypeJump(Instruction* instr) { 22901cb0ef41Sopenharmony_ci switch (instr->OpcodeFieldRaw()) { 22911cb0ef41Sopenharmony_ci case J: 22921cb0ef41Sopenharmony_ci Format(instr, "j 'imm26x -> 'imm26j"); 22931cb0ef41Sopenharmony_ci break; 22941cb0ef41Sopenharmony_ci case JAL: 22951cb0ef41Sopenharmony_ci Format(instr, "jal 'imm26x -> 'imm26j"); 22961cb0ef41Sopenharmony_ci break; 22971cb0ef41Sopenharmony_ci default: 22981cb0ef41Sopenharmony_ci UNREACHABLE(); 22991cb0ef41Sopenharmony_ci } 23001cb0ef41Sopenharmony_ci} 23011cb0ef41Sopenharmony_ci 23021cb0ef41Sopenharmony_civoid Decoder::DecodeTypeMsaI8(Instruction* instr) { 23031cb0ef41Sopenharmony_ci uint32_t opcode = instr->InstructionBits() & kMsaI8Mask; 23041cb0ef41Sopenharmony_ci 23051cb0ef41Sopenharmony_ci switch (opcode) { 23061cb0ef41Sopenharmony_ci case ANDI_B: 23071cb0ef41Sopenharmony_ci Format(instr, "andi.b 'wd, 'ws, 'imm8"); 23081cb0ef41Sopenharmony_ci break; 23091cb0ef41Sopenharmony_ci case ORI_B: 23101cb0ef41Sopenharmony_ci Format(instr, "ori.b 'wd, 'ws, 'imm8"); 23111cb0ef41Sopenharmony_ci break; 23121cb0ef41Sopenharmony_ci case NORI_B: 23131cb0ef41Sopenharmony_ci Format(instr, "nori.b 'wd, 'ws, 'imm8"); 23141cb0ef41Sopenharmony_ci break; 23151cb0ef41Sopenharmony_ci case XORI_B: 23161cb0ef41Sopenharmony_ci Format(instr, "xori.b 'wd, 'ws, 'imm8"); 23171cb0ef41Sopenharmony_ci break; 23181cb0ef41Sopenharmony_ci case BMNZI_B: 23191cb0ef41Sopenharmony_ci Format(instr, "bmnzi.b 'wd, 'ws, 'imm8"); 23201cb0ef41Sopenharmony_ci break; 23211cb0ef41Sopenharmony_ci case BMZI_B: 23221cb0ef41Sopenharmony_ci Format(instr, "bmzi.b 'wd, 'ws, 'imm8"); 23231cb0ef41Sopenharmony_ci break; 23241cb0ef41Sopenharmony_ci case BSELI_B: 23251cb0ef41Sopenharmony_ci Format(instr, "bseli.b 'wd, 'ws, 'imm8"); 23261cb0ef41Sopenharmony_ci break; 23271cb0ef41Sopenharmony_ci case SHF_B: 23281cb0ef41Sopenharmony_ci Format(instr, "shf.b 'wd, 'ws, 'imm8"); 23291cb0ef41Sopenharmony_ci break; 23301cb0ef41Sopenharmony_ci case SHF_H: 23311cb0ef41Sopenharmony_ci Format(instr, "shf.h 'wd, 'ws, 'imm8"); 23321cb0ef41Sopenharmony_ci break; 23331cb0ef41Sopenharmony_ci case SHF_W: 23341cb0ef41Sopenharmony_ci Format(instr, "shf.w 'wd, 'ws, 'imm8"); 23351cb0ef41Sopenharmony_ci break; 23361cb0ef41Sopenharmony_ci default: 23371cb0ef41Sopenharmony_ci UNREACHABLE(); 23381cb0ef41Sopenharmony_ci } 23391cb0ef41Sopenharmony_ci} 23401cb0ef41Sopenharmony_ci 23411cb0ef41Sopenharmony_civoid Decoder::DecodeTypeMsaI5(Instruction* instr) { 23421cb0ef41Sopenharmony_ci uint32_t opcode = instr->InstructionBits() & kMsaI5Mask; 23431cb0ef41Sopenharmony_ci 23441cb0ef41Sopenharmony_ci switch (opcode) { 23451cb0ef41Sopenharmony_ci case ADDVI: 23461cb0ef41Sopenharmony_ci Format(instr, "addvi.'t 'wd, 'ws, 'imm5u"); 23471cb0ef41Sopenharmony_ci break; 23481cb0ef41Sopenharmony_ci case SUBVI: 23491cb0ef41Sopenharmony_ci Format(instr, "subvi.'t 'wd, 'ws, 'imm5u"); 23501cb0ef41Sopenharmony_ci break; 23511cb0ef41Sopenharmony_ci case MAXI_S: 23521cb0ef41Sopenharmony_ci Format(instr, "maxi_s.'t 'wd, 'ws, 'imm5s"); 23531cb0ef41Sopenharmony_ci break; 23541cb0ef41Sopenharmony_ci case MAXI_U: 23551cb0ef41Sopenharmony_ci Format(instr, "maxi_u.'t 'wd, 'ws, 'imm5u"); 23561cb0ef41Sopenharmony_ci break; 23571cb0ef41Sopenharmony_ci case MINI_S: 23581cb0ef41Sopenharmony_ci Format(instr, "mini_s.'t 'wd, 'ws, 'imm5s"); 23591cb0ef41Sopenharmony_ci break; 23601cb0ef41Sopenharmony_ci case MINI_U: 23611cb0ef41Sopenharmony_ci Format(instr, "mini_u.'t 'wd, 'ws, 'imm5u"); 23621cb0ef41Sopenharmony_ci break; 23631cb0ef41Sopenharmony_ci case CEQI: 23641cb0ef41Sopenharmony_ci Format(instr, "ceqi.'t 'wd, 'ws, 'imm5s"); 23651cb0ef41Sopenharmony_ci break; 23661cb0ef41Sopenharmony_ci case CLTI_S: 23671cb0ef41Sopenharmony_ci Format(instr, "clti_s.'t 'wd, 'ws, 'imm5s"); 23681cb0ef41Sopenharmony_ci break; 23691cb0ef41Sopenharmony_ci case CLTI_U: 23701cb0ef41Sopenharmony_ci Format(instr, "clti_u.'t 'wd, 'ws, 'imm5u"); 23711cb0ef41Sopenharmony_ci break; 23721cb0ef41Sopenharmony_ci case CLEI_S: 23731cb0ef41Sopenharmony_ci Format(instr, "clei_s.'t 'wd, 'ws, 'imm5s"); 23741cb0ef41Sopenharmony_ci break; 23751cb0ef41Sopenharmony_ci case CLEI_U: 23761cb0ef41Sopenharmony_ci Format(instr, "clei_u.'t 'wd, 'ws, 'imm5u"); 23771cb0ef41Sopenharmony_ci break; 23781cb0ef41Sopenharmony_ci default: 23791cb0ef41Sopenharmony_ci UNREACHABLE(); 23801cb0ef41Sopenharmony_ci } 23811cb0ef41Sopenharmony_ci} 23821cb0ef41Sopenharmony_ci 23831cb0ef41Sopenharmony_civoid Decoder::DecodeTypeMsaI10(Instruction* instr) { 23841cb0ef41Sopenharmony_ci uint32_t opcode = instr->InstructionBits() & kMsaI5Mask; 23851cb0ef41Sopenharmony_ci if (opcode == LDI) { 23861cb0ef41Sopenharmony_ci Format(instr, "ldi.'t 'wd, 'imm10s1"); 23871cb0ef41Sopenharmony_ci } else { 23881cb0ef41Sopenharmony_ci UNREACHABLE(); 23891cb0ef41Sopenharmony_ci } 23901cb0ef41Sopenharmony_ci} 23911cb0ef41Sopenharmony_ci 23921cb0ef41Sopenharmony_civoid Decoder::DecodeTypeMsaELM(Instruction* instr) { 23931cb0ef41Sopenharmony_ci uint32_t opcode = instr->InstructionBits() & kMsaELMMask; 23941cb0ef41Sopenharmony_ci switch (opcode) { 23951cb0ef41Sopenharmony_ci case SLDI: 23961cb0ef41Sopenharmony_ci if (instr->Bits(21, 16) == 0x3E) { 23971cb0ef41Sopenharmony_ci Format(instr, "ctcmsa "); 23981cb0ef41Sopenharmony_ci PrintMSAControlRegister(instr->WdValue()); 23991cb0ef41Sopenharmony_ci Print(", "); 24001cb0ef41Sopenharmony_ci PrintRegister(instr->WsValue()); 24011cb0ef41Sopenharmony_ci } else { 24021cb0ef41Sopenharmony_ci Format(instr, "sldi.'t 'wd, 'ws['imme]"); 24031cb0ef41Sopenharmony_ci } 24041cb0ef41Sopenharmony_ci break; 24051cb0ef41Sopenharmony_ci case SPLATI: 24061cb0ef41Sopenharmony_ci if (instr->Bits(21, 16) == 0x3E) { 24071cb0ef41Sopenharmony_ci Format(instr, "cfcmsa "); 24081cb0ef41Sopenharmony_ci PrintRegister(instr->WdValue()); 24091cb0ef41Sopenharmony_ci Print(", "); 24101cb0ef41Sopenharmony_ci PrintMSAControlRegister(instr->WsValue()); 24111cb0ef41Sopenharmony_ci } else { 24121cb0ef41Sopenharmony_ci Format(instr, "splati.'t 'wd, 'ws['imme]"); 24131cb0ef41Sopenharmony_ci } 24141cb0ef41Sopenharmony_ci break; 24151cb0ef41Sopenharmony_ci case COPY_S: 24161cb0ef41Sopenharmony_ci if (instr->Bits(21, 16) == 0x3E) { 24171cb0ef41Sopenharmony_ci Format(instr, "move.v 'wd, 'ws"); 24181cb0ef41Sopenharmony_ci } else { 24191cb0ef41Sopenharmony_ci Format(instr, "copy_s.'t "); 24201cb0ef41Sopenharmony_ci PrintMsaCopy(instr); 24211cb0ef41Sopenharmony_ci } 24221cb0ef41Sopenharmony_ci break; 24231cb0ef41Sopenharmony_ci case COPY_U: 24241cb0ef41Sopenharmony_ci Format(instr, "copy_u.'t "); 24251cb0ef41Sopenharmony_ci PrintMsaCopy(instr); 24261cb0ef41Sopenharmony_ci break; 24271cb0ef41Sopenharmony_ci case INSERT: 24281cb0ef41Sopenharmony_ci Format(instr, "insert.'t 'wd['imme], "); 24291cb0ef41Sopenharmony_ci PrintRegister(instr->WsValue()); 24301cb0ef41Sopenharmony_ci break; 24311cb0ef41Sopenharmony_ci case INSVE: 24321cb0ef41Sopenharmony_ci Format(instr, "insve.'t 'wd['imme], 'ws[0]"); 24331cb0ef41Sopenharmony_ci break; 24341cb0ef41Sopenharmony_ci default: 24351cb0ef41Sopenharmony_ci UNREACHABLE(); 24361cb0ef41Sopenharmony_ci } 24371cb0ef41Sopenharmony_ci} 24381cb0ef41Sopenharmony_ci 24391cb0ef41Sopenharmony_civoid Decoder::DecodeTypeMsaBIT(Instruction* instr) { 24401cb0ef41Sopenharmony_ci uint32_t opcode = instr->InstructionBits() & kMsaBITMask; 24411cb0ef41Sopenharmony_ci 24421cb0ef41Sopenharmony_ci switch (opcode) { 24431cb0ef41Sopenharmony_ci case SLLI: 24441cb0ef41Sopenharmony_ci Format(instr, "slli.'t 'wd, 'ws, 'immb"); 24451cb0ef41Sopenharmony_ci break; 24461cb0ef41Sopenharmony_ci case SRAI: 24471cb0ef41Sopenharmony_ci Format(instr, "srai.'t 'wd, 'ws, 'immb"); 24481cb0ef41Sopenharmony_ci break; 24491cb0ef41Sopenharmony_ci case SRLI: 24501cb0ef41Sopenharmony_ci Format(instr, "srli.'t 'wd, 'ws, 'immb"); 24511cb0ef41Sopenharmony_ci break; 24521cb0ef41Sopenharmony_ci case BCLRI: 24531cb0ef41Sopenharmony_ci Format(instr, "bclri.'t 'wd, 'ws, 'immb"); 24541cb0ef41Sopenharmony_ci break; 24551cb0ef41Sopenharmony_ci case BSETI: 24561cb0ef41Sopenharmony_ci Format(instr, "bseti.'t 'wd, 'ws, 'immb"); 24571cb0ef41Sopenharmony_ci break; 24581cb0ef41Sopenharmony_ci case BNEGI: 24591cb0ef41Sopenharmony_ci Format(instr, "bnegi.'t 'wd, 'ws, 'immb"); 24601cb0ef41Sopenharmony_ci break; 24611cb0ef41Sopenharmony_ci case BINSLI: 24621cb0ef41Sopenharmony_ci Format(instr, "binsli.'t 'wd, 'ws, 'immb"); 24631cb0ef41Sopenharmony_ci break; 24641cb0ef41Sopenharmony_ci case BINSRI: 24651cb0ef41Sopenharmony_ci Format(instr, "binsri.'t 'wd, 'ws, 'immb"); 24661cb0ef41Sopenharmony_ci break; 24671cb0ef41Sopenharmony_ci case SAT_S: 24681cb0ef41Sopenharmony_ci Format(instr, "sat_s.'t 'wd, 'ws, 'immb"); 24691cb0ef41Sopenharmony_ci break; 24701cb0ef41Sopenharmony_ci case SAT_U: 24711cb0ef41Sopenharmony_ci Format(instr, "sat_u.'t 'wd, 'ws, 'immb"); 24721cb0ef41Sopenharmony_ci break; 24731cb0ef41Sopenharmony_ci case SRARI: 24741cb0ef41Sopenharmony_ci Format(instr, "srari.'t 'wd, 'ws, 'immb"); 24751cb0ef41Sopenharmony_ci break; 24761cb0ef41Sopenharmony_ci case SRLRI: 24771cb0ef41Sopenharmony_ci Format(instr, "srlri.'t 'wd, 'ws, 'immb"); 24781cb0ef41Sopenharmony_ci break; 24791cb0ef41Sopenharmony_ci default: 24801cb0ef41Sopenharmony_ci UNREACHABLE(); 24811cb0ef41Sopenharmony_ci } 24821cb0ef41Sopenharmony_ci} 24831cb0ef41Sopenharmony_ci 24841cb0ef41Sopenharmony_civoid Decoder::DecodeTypeMsaMI10(Instruction* instr) { 24851cb0ef41Sopenharmony_ci uint32_t opcode = instr->InstructionBits() & kMsaMI10Mask; 24861cb0ef41Sopenharmony_ci if (opcode == MSA_LD) { 24871cb0ef41Sopenharmony_ci Format(instr, "ld.'t 'wd, 'imm10s2("); 24881cb0ef41Sopenharmony_ci PrintRegister(instr->WsValue()); 24891cb0ef41Sopenharmony_ci Print(")"); 24901cb0ef41Sopenharmony_ci } else if (opcode == MSA_ST) { 24911cb0ef41Sopenharmony_ci Format(instr, "st.'t 'wd, 'imm10s2("); 24921cb0ef41Sopenharmony_ci PrintRegister(instr->WsValue()); 24931cb0ef41Sopenharmony_ci Print(")"); 24941cb0ef41Sopenharmony_ci } else { 24951cb0ef41Sopenharmony_ci UNREACHABLE(); 24961cb0ef41Sopenharmony_ci } 24971cb0ef41Sopenharmony_ci} 24981cb0ef41Sopenharmony_ci 24991cb0ef41Sopenharmony_civoid Decoder::DecodeTypeMsa3R(Instruction* instr) { 25001cb0ef41Sopenharmony_ci uint32_t opcode = instr->InstructionBits() & kMsa3RMask; 25011cb0ef41Sopenharmony_ci switch (opcode) { 25021cb0ef41Sopenharmony_ci case SLL_MSA: 25031cb0ef41Sopenharmony_ci Format(instr, "sll.'t 'wd, 'ws, 'wt"); 25041cb0ef41Sopenharmony_ci break; 25051cb0ef41Sopenharmony_ci case SRA_MSA: 25061cb0ef41Sopenharmony_ci Format(instr, "sra.'t 'wd, 'ws, 'wt"); 25071cb0ef41Sopenharmony_ci break; 25081cb0ef41Sopenharmony_ci case SRL_MSA: 25091cb0ef41Sopenharmony_ci Format(instr, "srl.'t 'wd, 'ws, 'wt"); 25101cb0ef41Sopenharmony_ci break; 25111cb0ef41Sopenharmony_ci case BCLR: 25121cb0ef41Sopenharmony_ci Format(instr, "bclr.'t 'wd, 'ws, 'wt"); 25131cb0ef41Sopenharmony_ci break; 25141cb0ef41Sopenharmony_ci case BSET: 25151cb0ef41Sopenharmony_ci Format(instr, "bset.'t 'wd, 'ws, 'wt"); 25161cb0ef41Sopenharmony_ci break; 25171cb0ef41Sopenharmony_ci case BNEG: 25181cb0ef41Sopenharmony_ci Format(instr, "bneg.'t 'wd, 'ws, 'wt"); 25191cb0ef41Sopenharmony_ci break; 25201cb0ef41Sopenharmony_ci case BINSL: 25211cb0ef41Sopenharmony_ci Format(instr, "binsl.'t 'wd, 'ws, 'wt"); 25221cb0ef41Sopenharmony_ci break; 25231cb0ef41Sopenharmony_ci case BINSR: 25241cb0ef41Sopenharmony_ci Format(instr, "binsr.'t 'wd, 'ws, 'wt"); 25251cb0ef41Sopenharmony_ci break; 25261cb0ef41Sopenharmony_ci case ADDV: 25271cb0ef41Sopenharmony_ci Format(instr, "addv.'t 'wd, 'ws, 'wt"); 25281cb0ef41Sopenharmony_ci break; 25291cb0ef41Sopenharmony_ci case SUBV: 25301cb0ef41Sopenharmony_ci Format(instr, "subv.'t 'wd, 'ws, 'wt"); 25311cb0ef41Sopenharmony_ci break; 25321cb0ef41Sopenharmony_ci case MAX_S: 25331cb0ef41Sopenharmony_ci Format(instr, "max_s.'t 'wd, 'ws, 'wt"); 25341cb0ef41Sopenharmony_ci break; 25351cb0ef41Sopenharmony_ci case MAX_U: 25361cb0ef41Sopenharmony_ci Format(instr, "max_u.'t 'wd, 'ws, 'wt"); 25371cb0ef41Sopenharmony_ci break; 25381cb0ef41Sopenharmony_ci case MIN_S: 25391cb0ef41Sopenharmony_ci Format(instr, "min_s.'t 'wd, 'ws, 'wt"); 25401cb0ef41Sopenharmony_ci break; 25411cb0ef41Sopenharmony_ci case MIN_U: 25421cb0ef41Sopenharmony_ci Format(instr, "min_u.'t 'wd, 'ws, 'wt"); 25431cb0ef41Sopenharmony_ci break; 25441cb0ef41Sopenharmony_ci case MAX_A: 25451cb0ef41Sopenharmony_ci Format(instr, "max_a.'t 'wd, 'ws, 'wt"); 25461cb0ef41Sopenharmony_ci break; 25471cb0ef41Sopenharmony_ci case MIN_A: 25481cb0ef41Sopenharmony_ci Format(instr, "min_a.'t 'wd, 'ws, 'wt"); 25491cb0ef41Sopenharmony_ci break; 25501cb0ef41Sopenharmony_ci case CEQ: 25511cb0ef41Sopenharmony_ci Format(instr, "ceq.'t 'wd, 'ws, 'wt"); 25521cb0ef41Sopenharmony_ci break; 25531cb0ef41Sopenharmony_ci case CLT_S: 25541cb0ef41Sopenharmony_ci Format(instr, "clt_s.'t 'wd, 'ws, 'wt"); 25551cb0ef41Sopenharmony_ci break; 25561cb0ef41Sopenharmony_ci case CLT_U: 25571cb0ef41Sopenharmony_ci Format(instr, "clt_u.'t 'wd, 'ws, 'wt"); 25581cb0ef41Sopenharmony_ci break; 25591cb0ef41Sopenharmony_ci case CLE_S: 25601cb0ef41Sopenharmony_ci Format(instr, "cle_s.'t 'wd, 'ws, 'wt"); 25611cb0ef41Sopenharmony_ci break; 25621cb0ef41Sopenharmony_ci case CLE_U: 25631cb0ef41Sopenharmony_ci Format(instr, "cle_u.'t 'wd, 'ws, 'wt"); 25641cb0ef41Sopenharmony_ci break; 25651cb0ef41Sopenharmony_ci case ADD_A: 25661cb0ef41Sopenharmony_ci Format(instr, "add_a.'t 'wd, 'ws, 'wt"); 25671cb0ef41Sopenharmony_ci break; 25681cb0ef41Sopenharmony_ci case ADDS_A: 25691cb0ef41Sopenharmony_ci Format(instr, "adds_a.'t 'wd, 'ws, 'wt"); 25701cb0ef41Sopenharmony_ci break; 25711cb0ef41Sopenharmony_ci case ADDS_S: 25721cb0ef41Sopenharmony_ci Format(instr, "adds_s.'t 'wd, 'ws, 'wt"); 25731cb0ef41Sopenharmony_ci break; 25741cb0ef41Sopenharmony_ci case ADDS_U: 25751cb0ef41Sopenharmony_ci Format(instr, "adds_u.'t 'wd, 'ws, 'wt"); 25761cb0ef41Sopenharmony_ci break; 25771cb0ef41Sopenharmony_ci case AVE_S: 25781cb0ef41Sopenharmony_ci Format(instr, "ave_s.'t 'wd, 'ws, 'wt"); 25791cb0ef41Sopenharmony_ci break; 25801cb0ef41Sopenharmony_ci case AVE_U: 25811cb0ef41Sopenharmony_ci Format(instr, "ave_u.'t 'wd, 'ws, 'wt"); 25821cb0ef41Sopenharmony_ci break; 25831cb0ef41Sopenharmony_ci case AVER_S: 25841cb0ef41Sopenharmony_ci Format(instr, "aver_s.'t 'wd, 'ws, 'wt"); 25851cb0ef41Sopenharmony_ci break; 25861cb0ef41Sopenharmony_ci case AVER_U: 25871cb0ef41Sopenharmony_ci Format(instr, "aver_u.'t 'wd, 'ws, 'wt"); 25881cb0ef41Sopenharmony_ci break; 25891cb0ef41Sopenharmony_ci case SUBS_S: 25901cb0ef41Sopenharmony_ci Format(instr, "subs_s.'t 'wd, 'ws, 'wt"); 25911cb0ef41Sopenharmony_ci break; 25921cb0ef41Sopenharmony_ci case SUBS_U: 25931cb0ef41Sopenharmony_ci Format(instr, "subs_u.'t 'wd, 'ws, 'wt"); 25941cb0ef41Sopenharmony_ci break; 25951cb0ef41Sopenharmony_ci case SUBSUS_U: 25961cb0ef41Sopenharmony_ci Format(instr, "subsus_u.'t 'wd, 'ws, 'wt"); 25971cb0ef41Sopenharmony_ci break; 25981cb0ef41Sopenharmony_ci case SUBSUU_S: 25991cb0ef41Sopenharmony_ci Format(instr, "subsuu_s.'t 'wd, 'ws, 'wt"); 26001cb0ef41Sopenharmony_ci break; 26011cb0ef41Sopenharmony_ci case ASUB_S: 26021cb0ef41Sopenharmony_ci Format(instr, "asub_s.'t 'wd, 'ws, 'wt"); 26031cb0ef41Sopenharmony_ci break; 26041cb0ef41Sopenharmony_ci case ASUB_U: 26051cb0ef41Sopenharmony_ci Format(instr, "asub_u.'t 'wd, 'ws, 'wt"); 26061cb0ef41Sopenharmony_ci break; 26071cb0ef41Sopenharmony_ci case MULV: 26081cb0ef41Sopenharmony_ci Format(instr, "mulv.'t 'wd, 'ws, 'wt"); 26091cb0ef41Sopenharmony_ci break; 26101cb0ef41Sopenharmony_ci case MADDV: 26111cb0ef41Sopenharmony_ci Format(instr, "maddv.'t 'wd, 'ws, 'wt"); 26121cb0ef41Sopenharmony_ci break; 26131cb0ef41Sopenharmony_ci case MSUBV: 26141cb0ef41Sopenharmony_ci Format(instr, "msubv.'t 'wd, 'ws, 'wt"); 26151cb0ef41Sopenharmony_ci break; 26161cb0ef41Sopenharmony_ci case DIV_S_MSA: 26171cb0ef41Sopenharmony_ci Format(instr, "div_s.'t 'wd, 'ws, 'wt"); 26181cb0ef41Sopenharmony_ci break; 26191cb0ef41Sopenharmony_ci case DIV_U: 26201cb0ef41Sopenharmony_ci Format(instr, "div_u.'t 'wd, 'ws, 'wt"); 26211cb0ef41Sopenharmony_ci break; 26221cb0ef41Sopenharmony_ci case MOD_S: 26231cb0ef41Sopenharmony_ci Format(instr, "mod_s.'t 'wd, 'ws, 'wt"); 26241cb0ef41Sopenharmony_ci break; 26251cb0ef41Sopenharmony_ci case MOD_U: 26261cb0ef41Sopenharmony_ci Format(instr, "mod_u.'t 'wd, 'ws, 'wt"); 26271cb0ef41Sopenharmony_ci break; 26281cb0ef41Sopenharmony_ci case DOTP_S: 26291cb0ef41Sopenharmony_ci Format(instr, "dotp_s.'t 'wd, 'ws, 'wt"); 26301cb0ef41Sopenharmony_ci break; 26311cb0ef41Sopenharmony_ci case DOTP_U: 26321cb0ef41Sopenharmony_ci Format(instr, "dotp_u.'t 'wd, 'ws, 'wt"); 26331cb0ef41Sopenharmony_ci break; 26341cb0ef41Sopenharmony_ci case DPADD_S: 26351cb0ef41Sopenharmony_ci Format(instr, "dpadd_s.'t 'wd, 'ws, 'wt"); 26361cb0ef41Sopenharmony_ci break; 26371cb0ef41Sopenharmony_ci case DPADD_U: 26381cb0ef41Sopenharmony_ci Format(instr, "dpadd_u.'t 'wd, 'ws, 'wt"); 26391cb0ef41Sopenharmony_ci break; 26401cb0ef41Sopenharmony_ci case DPSUB_S: 26411cb0ef41Sopenharmony_ci Format(instr, "dpsub_s.'t 'wd, 'ws, 'wt"); 26421cb0ef41Sopenharmony_ci break; 26431cb0ef41Sopenharmony_ci case DPSUB_U: 26441cb0ef41Sopenharmony_ci Format(instr, "dpsub_u.'t 'wd, 'ws, 'wt"); 26451cb0ef41Sopenharmony_ci break; 26461cb0ef41Sopenharmony_ci case SLD: 26471cb0ef41Sopenharmony_ci Format(instr, "sld.'t 'wd, 'ws['rt]"); 26481cb0ef41Sopenharmony_ci break; 26491cb0ef41Sopenharmony_ci case SPLAT: 26501cb0ef41Sopenharmony_ci Format(instr, "splat.'t 'wd, 'ws['rt]"); 26511cb0ef41Sopenharmony_ci break; 26521cb0ef41Sopenharmony_ci case PCKEV: 26531cb0ef41Sopenharmony_ci Format(instr, "pckev.'t 'wd, 'ws, 'wt"); 26541cb0ef41Sopenharmony_ci break; 26551cb0ef41Sopenharmony_ci case PCKOD: 26561cb0ef41Sopenharmony_ci Format(instr, "pckod.'t 'wd, 'ws, 'wt"); 26571cb0ef41Sopenharmony_ci break; 26581cb0ef41Sopenharmony_ci case ILVL: 26591cb0ef41Sopenharmony_ci Format(instr, "ilvl.'t 'wd, 'ws, 'wt"); 26601cb0ef41Sopenharmony_ci break; 26611cb0ef41Sopenharmony_ci case ILVR: 26621cb0ef41Sopenharmony_ci Format(instr, "ilvr.'t 'wd, 'ws, 'wt"); 26631cb0ef41Sopenharmony_ci break; 26641cb0ef41Sopenharmony_ci case ILVEV: 26651cb0ef41Sopenharmony_ci Format(instr, "ilvev.'t 'wd, 'ws, 'wt"); 26661cb0ef41Sopenharmony_ci break; 26671cb0ef41Sopenharmony_ci case ILVOD: 26681cb0ef41Sopenharmony_ci Format(instr, "ilvod.'t 'wd, 'ws, 'wt"); 26691cb0ef41Sopenharmony_ci break; 26701cb0ef41Sopenharmony_ci case VSHF: 26711cb0ef41Sopenharmony_ci Format(instr, "vshf.'t 'wd, 'ws, 'wt"); 26721cb0ef41Sopenharmony_ci break; 26731cb0ef41Sopenharmony_ci case SRAR: 26741cb0ef41Sopenharmony_ci Format(instr, "srar.'t 'wd, 'ws, 'wt"); 26751cb0ef41Sopenharmony_ci break; 26761cb0ef41Sopenharmony_ci case SRLR: 26771cb0ef41Sopenharmony_ci Format(instr, "srlr.'t 'wd, 'ws, 'wt"); 26781cb0ef41Sopenharmony_ci break; 26791cb0ef41Sopenharmony_ci case HADD_S: 26801cb0ef41Sopenharmony_ci Format(instr, "hadd_s.'t 'wd, 'ws, 'wt"); 26811cb0ef41Sopenharmony_ci break; 26821cb0ef41Sopenharmony_ci case HADD_U: 26831cb0ef41Sopenharmony_ci Format(instr, "hadd_u.'t 'wd, 'ws, 'wt"); 26841cb0ef41Sopenharmony_ci break; 26851cb0ef41Sopenharmony_ci case HSUB_S: 26861cb0ef41Sopenharmony_ci Format(instr, "hsub_s.'t 'wd, 'ws, 'wt"); 26871cb0ef41Sopenharmony_ci break; 26881cb0ef41Sopenharmony_ci case HSUB_U: 26891cb0ef41Sopenharmony_ci Format(instr, "hsub_u.'t 'wd, 'ws, 'wt"); 26901cb0ef41Sopenharmony_ci break; 26911cb0ef41Sopenharmony_ci default: 26921cb0ef41Sopenharmony_ci UNREACHABLE(); 26931cb0ef41Sopenharmony_ci } 26941cb0ef41Sopenharmony_ci} 26951cb0ef41Sopenharmony_ci 26961cb0ef41Sopenharmony_civoid Decoder::DecodeTypeMsa3RF(Instruction* instr) { 26971cb0ef41Sopenharmony_ci uint32_t opcode = instr->InstructionBits() & kMsa3RFMask; 26981cb0ef41Sopenharmony_ci switch (opcode) { 26991cb0ef41Sopenharmony_ci case FCAF: 27001cb0ef41Sopenharmony_ci Format(instr, "fcaf.'t 'wd, 'ws, 'wt"); 27011cb0ef41Sopenharmony_ci break; 27021cb0ef41Sopenharmony_ci case FCUN: 27031cb0ef41Sopenharmony_ci Format(instr, "fcun.'t 'wd, 'ws, 'wt"); 27041cb0ef41Sopenharmony_ci break; 27051cb0ef41Sopenharmony_ci case FCEQ: 27061cb0ef41Sopenharmony_ci Format(instr, "fceq.'t 'wd, 'ws, 'wt"); 27071cb0ef41Sopenharmony_ci break; 27081cb0ef41Sopenharmony_ci case FCUEQ: 27091cb0ef41Sopenharmony_ci Format(instr, "fcueq.'t 'wd, 'ws, 'wt"); 27101cb0ef41Sopenharmony_ci break; 27111cb0ef41Sopenharmony_ci case FCLT: 27121cb0ef41Sopenharmony_ci Format(instr, "fclt.'t 'wd, 'ws, 'wt"); 27131cb0ef41Sopenharmony_ci break; 27141cb0ef41Sopenharmony_ci case FCULT: 27151cb0ef41Sopenharmony_ci Format(instr, "fcult.'t 'wd, 'ws, 'wt"); 27161cb0ef41Sopenharmony_ci break; 27171cb0ef41Sopenharmony_ci case FCLE: 27181cb0ef41Sopenharmony_ci Format(instr, "fcle.'t 'wd, 'ws, 'wt"); 27191cb0ef41Sopenharmony_ci break; 27201cb0ef41Sopenharmony_ci case FCULE: 27211cb0ef41Sopenharmony_ci Format(instr, "fcule.'t 'wd, 'ws, 'wt"); 27221cb0ef41Sopenharmony_ci break; 27231cb0ef41Sopenharmony_ci case FSAF: 27241cb0ef41Sopenharmony_ci Format(instr, "fsaf.'t 'wd, 'ws, 'wt"); 27251cb0ef41Sopenharmony_ci break; 27261cb0ef41Sopenharmony_ci case FSUN: 27271cb0ef41Sopenharmony_ci Format(instr, "fsun.'t 'wd, 'ws, 'wt"); 27281cb0ef41Sopenharmony_ci break; 27291cb0ef41Sopenharmony_ci case FSEQ: 27301cb0ef41Sopenharmony_ci Format(instr, "fseq.'t 'wd, 'ws, 'wt"); 27311cb0ef41Sopenharmony_ci break; 27321cb0ef41Sopenharmony_ci case FSUEQ: 27331cb0ef41Sopenharmony_ci Format(instr, "fsueq.'t 'wd, 'ws, 'wt"); 27341cb0ef41Sopenharmony_ci break; 27351cb0ef41Sopenharmony_ci case FSLT: 27361cb0ef41Sopenharmony_ci Format(instr, "fslt.'t 'wd, 'ws, 'wt"); 27371cb0ef41Sopenharmony_ci break; 27381cb0ef41Sopenharmony_ci case FSULT: 27391cb0ef41Sopenharmony_ci Format(instr, "fsult.'t 'wd, 'ws, 'wt"); 27401cb0ef41Sopenharmony_ci break; 27411cb0ef41Sopenharmony_ci case FSLE: 27421cb0ef41Sopenharmony_ci Format(instr, "fsle.'t 'wd, 'ws, 'wt"); 27431cb0ef41Sopenharmony_ci break; 27441cb0ef41Sopenharmony_ci case FSULE: 27451cb0ef41Sopenharmony_ci Format(instr, "fsule.'t 'wd, 'ws, 'wt"); 27461cb0ef41Sopenharmony_ci break; 27471cb0ef41Sopenharmony_ci case FADD: 27481cb0ef41Sopenharmony_ci Format(instr, "fadd.'t 'wd, 'ws, 'wt"); 27491cb0ef41Sopenharmony_ci break; 27501cb0ef41Sopenharmony_ci case FSUB: 27511cb0ef41Sopenharmony_ci Format(instr, "fsub.'t 'wd, 'ws, 'wt"); 27521cb0ef41Sopenharmony_ci break; 27531cb0ef41Sopenharmony_ci case FMUL: 27541cb0ef41Sopenharmony_ci Format(instr, "fmul.'t 'wd, 'ws, 'wt"); 27551cb0ef41Sopenharmony_ci break; 27561cb0ef41Sopenharmony_ci case FDIV: 27571cb0ef41Sopenharmony_ci Format(instr, "fdiv.'t 'wd, 'ws, 'wt"); 27581cb0ef41Sopenharmony_ci break; 27591cb0ef41Sopenharmony_ci case FMADD: 27601cb0ef41Sopenharmony_ci Format(instr, "fmadd.'t 'wd, 'ws, 'wt"); 27611cb0ef41Sopenharmony_ci break; 27621cb0ef41Sopenharmony_ci case FMSUB: 27631cb0ef41Sopenharmony_ci Format(instr, "fmsub.'t 'wd, 'ws, 'wt"); 27641cb0ef41Sopenharmony_ci break; 27651cb0ef41Sopenharmony_ci case FEXP2: 27661cb0ef41Sopenharmony_ci Format(instr, "fexp2.'t 'wd, 'ws, 'wt"); 27671cb0ef41Sopenharmony_ci break; 27681cb0ef41Sopenharmony_ci case FEXDO: 27691cb0ef41Sopenharmony_ci Format(instr, "fexdo.'t 'wd, 'ws, 'wt"); 27701cb0ef41Sopenharmony_ci break; 27711cb0ef41Sopenharmony_ci case FTQ: 27721cb0ef41Sopenharmony_ci Format(instr, "ftq.'t 'wd, 'ws, 'wt"); 27731cb0ef41Sopenharmony_ci break; 27741cb0ef41Sopenharmony_ci case FMIN: 27751cb0ef41Sopenharmony_ci Format(instr, "fmin.'t 'wd, 'ws, 'wt"); 27761cb0ef41Sopenharmony_ci break; 27771cb0ef41Sopenharmony_ci case FMIN_A: 27781cb0ef41Sopenharmony_ci Format(instr, "fmin_a.'t 'wd, 'ws, 'wt"); 27791cb0ef41Sopenharmony_ci break; 27801cb0ef41Sopenharmony_ci case FMAX: 27811cb0ef41Sopenharmony_ci Format(instr, "fmax.'t 'wd, 'ws, 'wt"); 27821cb0ef41Sopenharmony_ci break; 27831cb0ef41Sopenharmony_ci case FMAX_A: 27841cb0ef41Sopenharmony_ci Format(instr, "fmax_a.'t 'wd, 'ws, 'wt"); 27851cb0ef41Sopenharmony_ci break; 27861cb0ef41Sopenharmony_ci case FCOR: 27871cb0ef41Sopenharmony_ci Format(instr, "fcor.'t 'wd, 'ws, 'wt"); 27881cb0ef41Sopenharmony_ci break; 27891cb0ef41Sopenharmony_ci case FCUNE: 27901cb0ef41Sopenharmony_ci Format(instr, "fcune.'t 'wd, 'ws, 'wt"); 27911cb0ef41Sopenharmony_ci break; 27921cb0ef41Sopenharmony_ci case FCNE: 27931cb0ef41Sopenharmony_ci Format(instr, "fcne.'t 'wd, 'ws, 'wt"); 27941cb0ef41Sopenharmony_ci break; 27951cb0ef41Sopenharmony_ci case MUL_Q: 27961cb0ef41Sopenharmony_ci Format(instr, "mul_q.'t 'wd, 'ws, 'wt"); 27971cb0ef41Sopenharmony_ci break; 27981cb0ef41Sopenharmony_ci case MADD_Q: 27991cb0ef41Sopenharmony_ci Format(instr, "madd_q.'t 'wd, 'ws, 'wt"); 28001cb0ef41Sopenharmony_ci break; 28011cb0ef41Sopenharmony_ci case MSUB_Q: 28021cb0ef41Sopenharmony_ci Format(instr, "msub_q.'t 'wd, 'ws, 'wt"); 28031cb0ef41Sopenharmony_ci break; 28041cb0ef41Sopenharmony_ci case FSOR: 28051cb0ef41Sopenharmony_ci Format(instr, "fsor.'t 'wd, 'ws, 'wt"); 28061cb0ef41Sopenharmony_ci break; 28071cb0ef41Sopenharmony_ci case FSUNE: 28081cb0ef41Sopenharmony_ci Format(instr, "fsune.'t 'wd, 'ws, 'wt"); 28091cb0ef41Sopenharmony_ci break; 28101cb0ef41Sopenharmony_ci case FSNE: 28111cb0ef41Sopenharmony_ci Format(instr, "fsne.'t 'wd, 'ws, 'wt"); 28121cb0ef41Sopenharmony_ci break; 28131cb0ef41Sopenharmony_ci case MULR_Q: 28141cb0ef41Sopenharmony_ci Format(instr, "mulr_q.'t 'wd, 'ws, 'wt"); 28151cb0ef41Sopenharmony_ci break; 28161cb0ef41Sopenharmony_ci case MADDR_Q: 28171cb0ef41Sopenharmony_ci Format(instr, "maddr_q.'t 'wd, 'ws, 'wt"); 28181cb0ef41Sopenharmony_ci break; 28191cb0ef41Sopenharmony_ci case MSUBR_Q: 28201cb0ef41Sopenharmony_ci Format(instr, "msubr_q.'t 'wd, 'ws, 'wt"); 28211cb0ef41Sopenharmony_ci break; 28221cb0ef41Sopenharmony_ci default: 28231cb0ef41Sopenharmony_ci UNREACHABLE(); 28241cb0ef41Sopenharmony_ci } 28251cb0ef41Sopenharmony_ci} 28261cb0ef41Sopenharmony_ci 28271cb0ef41Sopenharmony_civoid Decoder::DecodeTypeMsaVec(Instruction* instr) { 28281cb0ef41Sopenharmony_ci uint32_t opcode = instr->InstructionBits() & kMsaVECMask; 28291cb0ef41Sopenharmony_ci switch (opcode) { 28301cb0ef41Sopenharmony_ci case AND_V: 28311cb0ef41Sopenharmony_ci Format(instr, "and.v 'wd, 'ws, 'wt"); 28321cb0ef41Sopenharmony_ci break; 28331cb0ef41Sopenharmony_ci case OR_V: 28341cb0ef41Sopenharmony_ci Format(instr, "or.v 'wd, 'ws, 'wt"); 28351cb0ef41Sopenharmony_ci break; 28361cb0ef41Sopenharmony_ci case NOR_V: 28371cb0ef41Sopenharmony_ci Format(instr, "nor.v 'wd, 'ws, 'wt"); 28381cb0ef41Sopenharmony_ci break; 28391cb0ef41Sopenharmony_ci case XOR_V: 28401cb0ef41Sopenharmony_ci Format(instr, "xor.v 'wd, 'ws, 'wt"); 28411cb0ef41Sopenharmony_ci break; 28421cb0ef41Sopenharmony_ci case BMNZ_V: 28431cb0ef41Sopenharmony_ci Format(instr, "bmnz.v 'wd, 'ws, 'wt"); 28441cb0ef41Sopenharmony_ci break; 28451cb0ef41Sopenharmony_ci case BMZ_V: 28461cb0ef41Sopenharmony_ci Format(instr, "bmz.v 'wd, 'ws, 'wt"); 28471cb0ef41Sopenharmony_ci break; 28481cb0ef41Sopenharmony_ci case BSEL_V: 28491cb0ef41Sopenharmony_ci Format(instr, "bsel.v 'wd, 'ws, 'wt"); 28501cb0ef41Sopenharmony_ci break; 28511cb0ef41Sopenharmony_ci default: 28521cb0ef41Sopenharmony_ci UNREACHABLE(); 28531cb0ef41Sopenharmony_ci } 28541cb0ef41Sopenharmony_ci} 28551cb0ef41Sopenharmony_ci 28561cb0ef41Sopenharmony_civoid Decoder::DecodeTypeMsa2R(Instruction* instr) { 28571cb0ef41Sopenharmony_ci uint32_t opcode = instr->InstructionBits() & kMsa2RMask; 28581cb0ef41Sopenharmony_ci switch (opcode) { 28591cb0ef41Sopenharmony_ci case FILL: { 28601cb0ef41Sopenharmony_ci Format(instr, "fill.'t 'wd, "); 28611cb0ef41Sopenharmony_ci PrintRegister(instr->WsValue()); // rs value is in ws field 28621cb0ef41Sopenharmony_ci } break; 28631cb0ef41Sopenharmony_ci case PCNT: 28641cb0ef41Sopenharmony_ci Format(instr, "pcnt.'t 'wd, 'ws"); 28651cb0ef41Sopenharmony_ci break; 28661cb0ef41Sopenharmony_ci case NLOC: 28671cb0ef41Sopenharmony_ci Format(instr, "nloc.'t 'wd, 'ws"); 28681cb0ef41Sopenharmony_ci break; 28691cb0ef41Sopenharmony_ci case NLZC: 28701cb0ef41Sopenharmony_ci Format(instr, "nlzc.'t 'wd, 'ws"); 28711cb0ef41Sopenharmony_ci break; 28721cb0ef41Sopenharmony_ci default: 28731cb0ef41Sopenharmony_ci UNREACHABLE(); 28741cb0ef41Sopenharmony_ci } 28751cb0ef41Sopenharmony_ci} 28761cb0ef41Sopenharmony_ci 28771cb0ef41Sopenharmony_civoid Decoder::DecodeTypeMsa2RF(Instruction* instr) { 28781cb0ef41Sopenharmony_ci uint32_t opcode = instr->InstructionBits() & kMsa2RFMask; 28791cb0ef41Sopenharmony_ci switch (opcode) { 28801cb0ef41Sopenharmony_ci case FCLASS: 28811cb0ef41Sopenharmony_ci Format(instr, "fclass.'t 'wd, 'ws"); 28821cb0ef41Sopenharmony_ci break; 28831cb0ef41Sopenharmony_ci case FTRUNC_S: 28841cb0ef41Sopenharmony_ci Format(instr, "ftrunc_s.'t 'wd, 'ws"); 28851cb0ef41Sopenharmony_ci break; 28861cb0ef41Sopenharmony_ci case FTRUNC_U: 28871cb0ef41Sopenharmony_ci Format(instr, "ftrunc_u.'t 'wd, 'ws"); 28881cb0ef41Sopenharmony_ci break; 28891cb0ef41Sopenharmony_ci case FSQRT: 28901cb0ef41Sopenharmony_ci Format(instr, "fsqrt.'t 'wd, 'ws"); 28911cb0ef41Sopenharmony_ci break; 28921cb0ef41Sopenharmony_ci case FRSQRT: 28931cb0ef41Sopenharmony_ci Format(instr, "frsqrt.'t 'wd, 'ws"); 28941cb0ef41Sopenharmony_ci break; 28951cb0ef41Sopenharmony_ci case FRCP: 28961cb0ef41Sopenharmony_ci Format(instr, "frcp.'t 'wd, 'ws"); 28971cb0ef41Sopenharmony_ci break; 28981cb0ef41Sopenharmony_ci case FRINT: 28991cb0ef41Sopenharmony_ci Format(instr, "frint.'t 'wd, 'ws"); 29001cb0ef41Sopenharmony_ci break; 29011cb0ef41Sopenharmony_ci case FLOG2: 29021cb0ef41Sopenharmony_ci Format(instr, "flog2.'t 'wd, 'ws"); 29031cb0ef41Sopenharmony_ci break; 29041cb0ef41Sopenharmony_ci case FEXUPL: 29051cb0ef41Sopenharmony_ci Format(instr, "fexupl.'t 'wd, 'ws"); 29061cb0ef41Sopenharmony_ci break; 29071cb0ef41Sopenharmony_ci case FEXUPR: 29081cb0ef41Sopenharmony_ci Format(instr, "fexupr.'t 'wd, 'ws"); 29091cb0ef41Sopenharmony_ci break; 29101cb0ef41Sopenharmony_ci case FFQL: 29111cb0ef41Sopenharmony_ci Format(instr, "ffql.'t 'wd, 'ws"); 29121cb0ef41Sopenharmony_ci break; 29131cb0ef41Sopenharmony_ci case FFQR: 29141cb0ef41Sopenharmony_ci Format(instr, "ffqr.'t 'wd, 'ws"); 29151cb0ef41Sopenharmony_ci break; 29161cb0ef41Sopenharmony_ci case FTINT_S: 29171cb0ef41Sopenharmony_ci Format(instr, "ftint_s.'t 'wd, 'ws"); 29181cb0ef41Sopenharmony_ci break; 29191cb0ef41Sopenharmony_ci case FTINT_U: 29201cb0ef41Sopenharmony_ci Format(instr, "ftint_u.'t 'wd, 'ws"); 29211cb0ef41Sopenharmony_ci break; 29221cb0ef41Sopenharmony_ci case FFINT_S: 29231cb0ef41Sopenharmony_ci Format(instr, "ffint_s.'t 'wd, 'ws"); 29241cb0ef41Sopenharmony_ci break; 29251cb0ef41Sopenharmony_ci case FFINT_U: 29261cb0ef41Sopenharmony_ci Format(instr, "ffint_u.'t 'wd, 'ws"); 29271cb0ef41Sopenharmony_ci break; 29281cb0ef41Sopenharmony_ci default: 29291cb0ef41Sopenharmony_ci UNREACHABLE(); 29301cb0ef41Sopenharmony_ci } 29311cb0ef41Sopenharmony_ci} 29321cb0ef41Sopenharmony_ci 29331cb0ef41Sopenharmony_ci// Disassemble the instruction at *instr_ptr into the output buffer. 29341cb0ef41Sopenharmony_ci// All instructions are one word long, except for the simulator 29351cb0ef41Sopenharmony_ci// pseudo-instruction stop(msg). For that one special case, we return 29361cb0ef41Sopenharmony_ci// size larger than one kInstrSize. 29371cb0ef41Sopenharmony_ciint Decoder::InstructionDecode(byte* instr_ptr) { 29381cb0ef41Sopenharmony_ci Instruction* instr = Instruction::At(instr_ptr); 29391cb0ef41Sopenharmony_ci // Print raw instruction bytes. 29401cb0ef41Sopenharmony_ci out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, 29411cb0ef41Sopenharmony_ci "%08x ", instr->InstructionBits()); 29421cb0ef41Sopenharmony_ci switch (instr->InstructionType()) { 29431cb0ef41Sopenharmony_ci case Instruction::kRegisterType: { 29441cb0ef41Sopenharmony_ci return DecodeTypeRegister(instr); 29451cb0ef41Sopenharmony_ci } 29461cb0ef41Sopenharmony_ci case Instruction::kImmediateType: { 29471cb0ef41Sopenharmony_ci DecodeTypeImmediate(instr); 29481cb0ef41Sopenharmony_ci break; 29491cb0ef41Sopenharmony_ci } 29501cb0ef41Sopenharmony_ci case Instruction::kJumpType: { 29511cb0ef41Sopenharmony_ci DecodeTypeJump(instr); 29521cb0ef41Sopenharmony_ci break; 29531cb0ef41Sopenharmony_ci } 29541cb0ef41Sopenharmony_ci default: { 29551cb0ef41Sopenharmony_ci Format(instr, "UNSUPPORTED"); 29561cb0ef41Sopenharmony_ci UNSUPPORTED_MIPS(); 29571cb0ef41Sopenharmony_ci } 29581cb0ef41Sopenharmony_ci } 29591cb0ef41Sopenharmony_ci return kInstrSize; 29601cb0ef41Sopenharmony_ci} 29611cb0ef41Sopenharmony_ci 29621cb0ef41Sopenharmony_ci} // namespace internal 29631cb0ef41Sopenharmony_ci} // namespace v8 29641cb0ef41Sopenharmony_ci 29651cb0ef41Sopenharmony_ci//------------------------------------------------------------------------------ 29661cb0ef41Sopenharmony_ci 29671cb0ef41Sopenharmony_cinamespace disasm { 29681cb0ef41Sopenharmony_ci 29691cb0ef41Sopenharmony_ciconst char* NameConverter::NameOfAddress(byte* addr) const { 29701cb0ef41Sopenharmony_ci v8::base::SNPrintF(tmp_buffer_, "%p", static_cast<void*>(addr)); 29711cb0ef41Sopenharmony_ci return tmp_buffer_.begin(); 29721cb0ef41Sopenharmony_ci} 29731cb0ef41Sopenharmony_ci 29741cb0ef41Sopenharmony_ciconst char* NameConverter::NameOfConstant(byte* addr) const { 29751cb0ef41Sopenharmony_ci return NameOfAddress(addr); 29761cb0ef41Sopenharmony_ci} 29771cb0ef41Sopenharmony_ci 29781cb0ef41Sopenharmony_ciconst char* NameConverter::NameOfCPURegister(int reg) const { 29791cb0ef41Sopenharmony_ci return v8::internal::Registers::Name(reg); 29801cb0ef41Sopenharmony_ci} 29811cb0ef41Sopenharmony_ci 29821cb0ef41Sopenharmony_ciconst char* NameConverter::NameOfXMMRegister(int reg) const { 29831cb0ef41Sopenharmony_ci return v8::internal::FPURegisters::Name(reg); 29841cb0ef41Sopenharmony_ci} 29851cb0ef41Sopenharmony_ci 29861cb0ef41Sopenharmony_ciconst char* NameConverter::NameOfByteCPURegister(int reg) const { 29871cb0ef41Sopenharmony_ci UNREACHABLE(); // MIPS does not have the concept of a byte register. 29881cb0ef41Sopenharmony_ci} 29891cb0ef41Sopenharmony_ci 29901cb0ef41Sopenharmony_ciconst char* NameConverter::NameInCode(byte* addr) const { 29911cb0ef41Sopenharmony_ci // The default name converter is called for unknown code. So we will not try 29921cb0ef41Sopenharmony_ci // to access any memory. 29931cb0ef41Sopenharmony_ci return ""; 29941cb0ef41Sopenharmony_ci} 29951cb0ef41Sopenharmony_ci 29961cb0ef41Sopenharmony_ci//------------------------------------------------------------------------------ 29971cb0ef41Sopenharmony_ci 29981cb0ef41Sopenharmony_ciint Disassembler::InstructionDecode(v8::base::Vector<char> buffer, 29991cb0ef41Sopenharmony_ci byte* instruction) { 30001cb0ef41Sopenharmony_ci v8::internal::Decoder d(converter_, buffer); 30011cb0ef41Sopenharmony_ci return d.InstructionDecode(instruction); 30021cb0ef41Sopenharmony_ci} 30031cb0ef41Sopenharmony_ci 30041cb0ef41Sopenharmony_ci// The MIPS assembler does not currently use constant pools. 30051cb0ef41Sopenharmony_ciint Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; } 30061cb0ef41Sopenharmony_ci 30071cb0ef41Sopenharmony_civoid Disassembler::Disassemble(FILE* f, byte* begin, byte* end, 30081cb0ef41Sopenharmony_ci UnimplementedOpcodeAction unimplemented_action) { 30091cb0ef41Sopenharmony_ci NameConverter converter; 30101cb0ef41Sopenharmony_ci Disassembler d(converter, unimplemented_action); 30111cb0ef41Sopenharmony_ci for (byte* pc = begin; pc < end;) { 30121cb0ef41Sopenharmony_ci v8::base::EmbeddedVector<char, 128> buffer; 30131cb0ef41Sopenharmony_ci buffer[0] = '\0'; 30141cb0ef41Sopenharmony_ci byte* prev_pc = pc; 30151cb0ef41Sopenharmony_ci pc += d.InstructionDecode(buffer, pc); 30161cb0ef41Sopenharmony_ci v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc), 30171cb0ef41Sopenharmony_ci *reinterpret_cast<int32_t*>(prev_pc), buffer.begin()); 30181cb0ef41Sopenharmony_ci } 30191cb0ef41Sopenharmony_ci} 30201cb0ef41Sopenharmony_ci 30211cb0ef41Sopenharmony_ci#undef STRING_STARTS_WITH 30221cb0ef41Sopenharmony_ci 30231cb0ef41Sopenharmony_ci} // namespace disasm 30241cb0ef41Sopenharmony_ci 30251cb0ef41Sopenharmony_ci#endif // V8_TARGET_ARCH_MIPS64 3026