CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Core/MIPS/MIPSTables.cpp
Views: 1401
// Copyright (c) 2012- PPSSPP Project.12// This program is free software: you can redistribute it and/or modify3// it under the terms of the GNU General Public License as published by4// the Free Software Foundation, version 2.0 or later versions.56// This program is distributed in the hope that it will be useful,7// but WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9// GNU General Public License 2.0 for more details.1011// A copy of the GPL 2.0 should have been included with the program.12// If not, see http://www.gnu.org/licenses/1314// Official git repository and contact information can be found at15// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.1617#include "Common/StringUtils.h"1819#include "Core/Core.h"20#include "Core/System.h"21#include "Core/MemMap.h"22#include "Core/MIPS/MIPS.h"23#include "Core/MIPS/MIPSDis.h"24#include "Core/MIPS/MIPSDisVFPU.h"25#include "Core/MIPS/MIPSInt.h"26#include "Core/MIPS/MIPSIntVFPU.h"27#include "Core/MIPS/MIPSCodeUtils.h"28#include "Core/MIPS/MIPSTables.h"29#include "Core/CoreTiming.h"30#include "Core/Reporting.h"31#include "Core/Debugger/Breakpoints.h"3233#include "JitCommon/JitCommon.h"3435enum MipsEncoding {36Imme,37Spec,38Spe2,39Spe3,40RegI,41Cop0,42Cop0CO,43Cop1,44Cop1BC,45Cop1S,46Cop1W,47Cop2,48Cop2BC2,49Cop2Rese,50VFPU0,51VFPU1,52VFPU3,53VFPU4Jump,54VFPU7,55VFPU4,56VFPU5,57VFPU6,58VFPUMatrix1,59VFPU9,60ALLEGREX0,61Emu,62Rese,63NumEncodings,6465Instruc = -1,66Inval = -2,67};6869struct MIPSInstruction {70MipsEncoding altEncoding;71const char *name;72MIPSComp::MIPSCompileFunc compile;73MIPSDisFunc disasm;74MIPSInterpretFunc interpret;75//MIPSInstructionInfo information;76MIPSInfo flags;77};7879#define INVALID {Inval}80#define INVALID_X_8 INVALID,INVALID,INVALID,INVALID,INVALID,INVALID,INVALID,INVALID8182#define ENCODING(a) {a}83#define INSTR(name, comp, dis, inter, flags) {Instruc, name, comp, dis, inter, MIPSInfo(flags)}8485#define JITFUNC(f) (&MIPSFrontendInterface::f)8687using namespace MIPSDis;88using namespace MIPSInt;89using namespace MIPSComp;9091// %s/&Jit::\(.\{-}\),/JITFUNC(\1),/g9293// regregreg instructions94static const MIPSInstruction tableImmediate[64] = // xxxxxx ..... ..... ................95{96//097ENCODING(Spec),98ENCODING(RegI),99INSTR("j", JITFUNC(Comp_Jump), Dis_JumpType, Int_JumpType, IS_JUMP|IN_IMM26|DELAYSLOT),100INSTR("jal", JITFUNC(Comp_Jump), Dis_JumpType, Int_JumpType, IS_JUMP|IN_IMM26|OUT_RA|DELAYSLOT),101INSTR("beq", JITFUNC(Comp_RelBranch), Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|IN_RT|DELAYSLOT|CONDTYPE_EQ),102INSTR("bne", JITFUNC(Comp_RelBranch), Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|IN_RT|DELAYSLOT|CONDTYPE_NE),103INSTR("blez", JITFUNC(Comp_RelBranch), Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|CONDTYPE_LEZ),104INSTR("bgtz", JITFUNC(Comp_RelBranch), Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|CONDTYPE_GTZ),105//8106INSTR("addi", JITFUNC(Comp_IType), Dis_addi, Int_IType, IN_RS|IN_IMM16|OUT_RT),107INSTR("addiu", JITFUNC(Comp_IType), Dis_addi, Int_IType, IN_RS|IN_IMM16|OUT_RT),108INSTR("slti", JITFUNC(Comp_IType), Dis_IType, Int_IType, IN_RS|IN_IMM16|OUT_RT),109INSTR("sltiu", JITFUNC(Comp_IType), Dis_IType, Int_IType, IN_RS|IN_IMM16|OUT_RT),110INSTR("andi", JITFUNC(Comp_IType), Dis_IType, Int_IType, IN_RS|IN_IMM16|OUT_RT),111INSTR("ori", JITFUNC(Comp_IType), Dis_ori, Int_IType, IN_RS|IN_IMM16|OUT_RT),112INSTR("xori", JITFUNC(Comp_IType), Dis_IType, Int_IType, IN_RS|IN_IMM16|OUT_RT),113INSTR("lui", JITFUNC(Comp_IType), Dis_IType1, Int_IType, IN_IMM16|OUT_RT),114//16115ENCODING(Cop0), //cop0116ENCODING(Cop1), //cop1117ENCODING(Cop2), //cop2118INVALID, //copU119120INSTR("beql", JITFUNC(Comp_RelBranch), Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|IN_RT|DELAYSLOT|LIKELY|CONDTYPE_EQ), //L = likely121INSTR("bnel", JITFUNC(Comp_RelBranch), Dis_RelBranch2, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|IN_RT|DELAYSLOT|LIKELY|CONDTYPE_NE),122INSTR("blezl", JITFUNC(Comp_RelBranch), Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_LEZ),123INSTR("bgtzl", JITFUNC(Comp_RelBranch), Dis_RelBranch, Int_RelBranch, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_GTZ),124//24125ENCODING(VFPU0),126ENCODING(VFPU1),127ENCODING(Emu),128ENCODING(VFPU3),129ENCODING(Spe2), //special2130INVALID,131INVALID,132ENCODING(Spe3), //special3133//32134INSTR("lb", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_BYTE),135INSTR("lh", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_HWORD),136INSTR("lwl", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|IN_RT|OUT_RT|MEMTYPE_WORD),137INSTR("lw", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_WORD),138INSTR("lbu", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_BYTE),139INSTR("lhu", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|MEMTYPE_HWORD),140INSTR("lwr", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_MEM|IN_IMM16|IN_RS_ADDR|IN_RT|OUT_RT|MEMTYPE_WORD),141INVALID,142//40143INSTR("sb", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_BYTE),144INSTR("sh", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_HWORD),145INSTR("swl", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD),146INSTR("sw", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD),147INVALID,148INVALID,149INSTR("swr", JITFUNC(Comp_ITypeMem), Dis_ITypeMem, Int_ITypeMem, IN_IMM16|IN_RS_ADDR|IN_RT|OUT_MEM|MEMTYPE_WORD),150INSTR("cache", JITFUNC(Comp_Cache), Dis_Cache, Int_Cache, IN_MEM|IN_IMM16|IN_RS_ADDR),151//48152INSTR("ll", JITFUNC(Comp_StoreSync), Dis_ITypeMem, Int_StoreSync, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_RT|OUT_OTHER|MEMTYPE_WORD),153INSTR("lwc1", JITFUNC(Comp_FPULS), Dis_FPULS, Int_FPULS, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_FT|MEMTYPE_FLOAT|IS_FPU),154INSTR("lv.s", JITFUNC(Comp_SV), Dis_SV, Int_SV, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_OTHER|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_FLOAT),155INVALID,156ENCODING(VFPU4Jump),157INSTR("lv", JITFUNC(Comp_SVQ), Dis_SVLRQ, Int_SVQ, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_OTHER|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_VQUAD),158INSTR("lv.q", JITFUNC(Comp_SVQ), Dis_SVQ, Int_SVQ, IN_MEM|IN_IMM16|IN_RS_ADDR|OUT_OTHER|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_VQUAD), //copU159ENCODING(VFPU5),160//56161INSTR("sc", JITFUNC(Comp_StoreSync), Dis_ITypeMem, Int_StoreSync, IN_IMM16|IN_RS_ADDR|IN_OTHER|IN_RT|OUT_RT|OUT_MEM|MEMTYPE_WORD),162INSTR("swc1", JITFUNC(Comp_FPULS), Dis_FPULS, Int_FPULS, IN_IMM16|IN_RS_ADDR|IN_FT|OUT_MEM|MEMTYPE_FLOAT|IS_FPU), //copU163INSTR("sv.s", JITFUNC(Comp_SV), Dis_SV, Int_SV, IN_IMM16|IN_RS_ADDR|IN_OTHER|OUT_MEM|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_FLOAT),164INVALID,165//60166ENCODING(VFPU6),167INSTR("sv", JITFUNC(Comp_SVQ), Dis_SVLRQ, Int_SVQ, IN_IMM16|IN_RS_ADDR|IN_OTHER|OUT_MEM|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_VQUAD), //copU168INSTR("sv.q", JITFUNC(Comp_SVQ), Dis_SVQ, Int_SVQ, IN_IMM16|IN_RS_ADDR|IN_OTHER|OUT_MEM|IS_VFPU|VFPU_NO_PREFIX|MEMTYPE_VQUAD),169// Some call this VFPU7 (vflush/vnop/vsync), but it's not super important.170INSTR("vflush", JITFUNC(Comp_DoNothing), Dis_Vflush, Int_Vflush, IS_VFPU|VFPU_NO_PREFIX),171};172173static const MIPSInstruction tableSpecial[64] = // 000000 ..... ..... ..... ..... xxxxxx174{175INSTR("sll", JITFUNC(Comp_ShiftType), Dis_ShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_SA),176INVALID, // copu177178INSTR("srl", JITFUNC(Comp_ShiftType), Dis_ShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_SA),179INSTR("sra", JITFUNC(Comp_ShiftType), Dis_ShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_SA),180INSTR("sllv", JITFUNC(Comp_ShiftType), Dis_VarShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_RS_SHIFT),181INVALID,182INSTR("srlv", JITFUNC(Comp_ShiftType), Dis_VarShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_RS_SHIFT),183INSTR("srav", JITFUNC(Comp_ShiftType), Dis_VarShiftType, Int_ShiftType, OUT_RD|IN_RT|IN_RS_SHIFT),184185//8186INSTR("jr", JITFUNC(Comp_JumpReg), Dis_JumpRegType, Int_JumpRegType, IS_JUMP|IN_RS|DELAYSLOT),187INSTR("jalr", JITFUNC(Comp_JumpReg), Dis_JumpRegType, Int_JumpRegType, IS_JUMP|IN_RS|OUT_RD|DELAYSLOT),188INSTR("movz", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT|IS_CONDMOVE|CONDTYPE_EQ),189INSTR("movn", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, OUT_RD|IN_RS|IN_RT|IS_CONDMOVE|CONDTYPE_NE),190INSTR("syscall", JITFUNC(Comp_Syscall), Dis_Syscall, Int_Syscall, IN_MEM|IN_OTHER|OUT_MEM|OUT_OTHER|IS_SYSCALL),191INSTR("break", JITFUNC(Comp_Break), Dis_Generic, Int_Break, 0),192INVALID,193INSTR("sync", JITFUNC(Comp_DoNothing), Dis_Generic, Int_Sync, 0),194195//16196INSTR("mfhi", JITFUNC(Comp_MulDivType), Dis_FromHiloTransfer, Int_MulDivType, OUT_RD|IN_HI),197INSTR("mthi", JITFUNC(Comp_MulDivType), Dis_ToHiloTransfer, Int_MulDivType, IN_RS|OUT_HI),198INSTR("mflo", JITFUNC(Comp_MulDivType), Dis_FromHiloTransfer, Int_MulDivType, OUT_RD|IN_LO),199INSTR("mtlo", JITFUNC(Comp_MulDivType), Dis_ToHiloTransfer, Int_MulDivType, IN_RS|OUT_LO),200INVALID,201INVALID,202INSTR("clz", JITFUNC(Comp_RType2), Dis_RType2, Int_RType2, OUT_RD|IN_RS),203INSTR("clo", JITFUNC(Comp_RType2), Dis_RType2, Int_RType2, OUT_RD|IN_RS),204205//24206INSTR("mult", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_HI|OUT_LO),207INSTR("multu", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_HI|OUT_LO),208INSTR("div", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_HI|OUT_LO),209INSTR("divu", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_HI|OUT_LO),210INSTR("madd", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|IN_HI|IN_LO|OUT_HI|OUT_LO),211INSTR("maddu", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|IN_HI|IN_LO|OUT_HI|OUT_LO),212INVALID,213INVALID,214215//32216INSTR("add", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),217INSTR("addu", JITFUNC(Comp_RType3), Dis_addu, Int_RType3, IN_RS|IN_RT|OUT_RD),218INSTR("sub", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),219INSTR("subu", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),220INSTR("and", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),221INSTR("or", JITFUNC(Comp_RType3), Dis_addu, Int_RType3, IN_RS|IN_RT|OUT_RD),222INSTR("xor", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),223INSTR("nor", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),224225//40226INVALID,227INVALID,228INSTR("slt", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),229INSTR("sltu", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),230INSTR("max", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),231INSTR("min", JITFUNC(Comp_RType3), Dis_RType3, Int_RType3, IN_RS|IN_RT|OUT_RD),232INSTR("msub", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|IN_HI|IN_LO|OUT_HI|OUT_LO),233INSTR("msubu", JITFUNC(Comp_MulDivType), Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|IN_HI|IN_LO|OUT_HI|OUT_LO),234235//48236INSTR("tge", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),237INSTR("tgeu", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),238INSTR("tlt", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),239INSTR("tltu", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),240INSTR("teq", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),241INVALID,242INSTR("tne", JITFUNC(Comp_Generic), Dis_RType3, 0, 0),243INVALID,244245//56246INVALID_X_8,247};248249// Theoretically should not hit these.250static const MIPSInstruction tableSpecial2[64] = // 011100 ..... ..... ..... ..... xxxxxx251{252INSTR("halt", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),253INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,254//8255INVALID_X_8,256INVALID_X_8,257INVALID_X_8,258//32259INVALID, INVALID, INVALID, INVALID,260INSTR("mfic", JITFUNC(Comp_Generic), Dis_Generic, Int_Special2, OUT_OTHER),261INVALID,262INSTR("mtic", JITFUNC(Comp_Generic), Dis_Generic, Int_Special2, OUT_OTHER),263INVALID,264//40265INVALID_X_8,266INVALID_X_8,267INVALID_X_8,268};269270static const MIPSInstruction tableSpecial3[64] = // 011111 ..... ..... ..... ..... xxxxxx271{272INSTR("ext", JITFUNC(Comp_Special3), Dis_Special3, Int_Special3, IN_RS|OUT_RT),273INVALID,274INVALID,275INVALID,276INSTR("ins", JITFUNC(Comp_Special3), Dis_Special3, Int_Special3, IN_RS|IN_RT|OUT_RT),277INVALID,278INVALID,279INVALID,280//8281INVALID_X_8,282//16283INVALID_X_8,284//24285// TODO: Is this right? Or should it only be 32? Comment above (24) was mistakenly 32 before.286ENCODING(ALLEGREX0),287INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,288//32289ENCODING(ALLEGREX0),290INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,291//40292INVALID_X_8,293INVALID_X_8,294//56295INVALID, INVALID, INVALID,296INSTR("rdhwr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),297INVALID, INVALID, INVALID, INVALID,298};299300static const MIPSInstruction tableRegImm[32] = // 000001 ..... xxxxx ................301{302INSTR("bltz", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|CONDTYPE_LTZ),303INSTR("bgez", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|CONDTYPE_GEZ),304INSTR("bltzl", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_LTZ),305INSTR("bgezl", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|DELAYSLOT|LIKELY|CONDTYPE_GEZ),306INVALID,307INVALID,308INVALID,309INVALID,310//8311INSTR("tgei", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),312INSTR("tgeiu", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),313INSTR("tlti", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),314INSTR("tltiu", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),315INSTR("teqi", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),316INVALID,317INSTR("tnei", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),318INVALID,319//16320INSTR("bltzal", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|OUT_RA|DELAYSLOT|CONDTYPE_LTZ),321INSTR("bgezal", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|OUT_RA|DELAYSLOT|CONDTYPE_GEZ),322INSTR("bltzall", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|OUT_RA|DELAYSLOT|LIKELY|CONDTYPE_LTZ), //L = likely323INSTR("bgezall", JITFUNC(Comp_RelBranchRI), Dis_RelBranch, Int_RelBranchRI, IS_CONDBRANCH|IN_IMM16|IN_RS|OUT_RA|DELAYSLOT|LIKELY|CONDTYPE_GEZ),324INVALID,325INVALID,326INVALID,327INVALID,328//24329INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,330INSTR("synci", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),331};332333static const MIPSInstruction tableCop2[32] = // 010010 xxxxx ..... ................334{335INSTR("mfc2", JITFUNC(Comp_Generic), Dis_Generic, 0, OUT_RT),336INVALID,337INSTR("cfc2", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),338INSTR("mfv", JITFUNC(Comp_Mftv), Dis_Mftv, Int_Mftv, IN_OTHER|IN_VFPU_CC|OUT_RT|IS_VFPU),339INSTR("mtc2", JITFUNC(Comp_Generic), Dis_Generic, 0, IN_RT),340INVALID,341INSTR("ctc2", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),342INSTR("mtv", JITFUNC(Comp_Mftv), Dis_Mftv, Int_Mftv, IN_RT|OUT_VFPU_CC|OUT_OTHER|IS_VFPU|OUT_VFPU_PREFIX),343//8344ENCODING(Cop2BC2),345INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),346INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),347INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),348INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),349INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),350INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),351INSTR("??", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),352//16353INVALID_X_8,354INVALID_X_8,355};356357static const MIPSInstruction tableCop2BC2[4] = // 010010 01000 ...xx ................358{359INSTR("bvf", JITFUNC(Comp_VBranch), Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|IS_VFPU),360INSTR("bvt", JITFUNC(Comp_VBranch), Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|IS_VFPU),361INSTR("bvfl", JITFUNC(Comp_VBranch), Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|LIKELY|IS_VFPU),362INSTR("bvtl", JITFUNC(Comp_VBranch), Dis_VBranch, Int_VBranch, IS_CONDBRANCH|IN_IMM16|IN_VFPU_CC|DELAYSLOT|LIKELY|IS_VFPU),363};364365static const MIPSInstruction tableCop0[32] = // 010000 xxxxx ..... ................366{367INSTR("mfc0", JITFUNC(Comp_Generic), Dis_Generic, 0, OUT_RT), // unused368INVALID,369INVALID,370INVALID,371INSTR("mtc0", JITFUNC(Comp_Generic), Dis_Generic, 0, IN_RT), // unused372INVALID,373INVALID,374INVALID,375//8376INVALID,377INVALID,378INSTR("rdpgpr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),379INSTR("mfmc0", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),380381INVALID,382INVALID,383INSTR("wrpgpr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),384INVALID,385//16386ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO),387ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO), ENCODING(Cop0CO),388};389390// we won't encounter these since we only do user mode emulation391static const MIPSInstruction tableCop0CO[64] = // 010000 1.... ..... ..... ..... xxxxxx392{393INVALID,394INSTR("tlbr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),395INSTR("tlbwi", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),396INVALID,397INVALID,398INVALID,399INSTR("tlbwr", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),400INVALID,401//8402INSTR("tlbp", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),403INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,404INVALID_X_8,405//24406INSTR("eret", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),407INSTR("iack", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),408INVALID, INVALID, INVALID, INVALID, INVALID,409INSTR("deret", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),410//32411INSTR("wait", JITFUNC(Comp_Generic), Dis_Generic, 0, 0),412INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,413//40414INVALID_X_8,415INVALID_X_8,416INVALID_X_8,417};418419static const MIPSInstruction tableCop1[32] = // 010001 xxxxx ..... ..... ...........420{421INSTR("mfc1", JITFUNC(Comp_mxc1), Dis_mxc1, Int_mxc1, IN_FS|OUT_RT|IS_FPU),422INVALID,423INSTR("cfc1", JITFUNC(Comp_mxc1), Dis_mxc1, Int_mxc1, IN_OTHER|IN_FPUFLAG|OUT_RT|IS_FPU),424INVALID,425INSTR("mtc1", JITFUNC(Comp_mxc1), Dis_mxc1, Int_mxc1, IN_RT|OUT_FS|IS_FPU),426INVALID,427INSTR("ctc1", JITFUNC(Comp_mxc1), Dis_mxc1, Int_mxc1, IN_RT|OUT_FPUFLAG|OUT_OTHER|IS_FPU),428INVALID,429//8430ENCODING(Cop1BC), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID,431//16432ENCODING(Cop1S), INVALID, INVALID, INVALID,433ENCODING(Cop1W), INVALID, INVALID, INVALID,434//24435INVALID_X_8,436};437438static const MIPSInstruction tableCop1BC[32] = // 010001 01000 xxxxx ................439{440INSTR("bc1f", JITFUNC(Comp_FPUBranch), Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_IMM16|IN_FPUFLAG|DELAYSLOT|CONDTYPE_FPUFALSE|IS_FPU),441INSTR("bc1t", JITFUNC(Comp_FPUBranch), Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_IMM16|IN_FPUFLAG|DELAYSLOT|CONDTYPE_FPUTRUE|IS_FPU),442INSTR("bc1fl", JITFUNC(Comp_FPUBranch), Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_IMM16|IN_FPUFLAG|DELAYSLOT|LIKELY|CONDTYPE_FPUFALSE|IS_FPU),443INSTR("bc1tl", JITFUNC(Comp_FPUBranch), Dis_FPUBranch, Int_FPUBranch, IS_CONDBRANCH|IN_IMM16|IN_FPUFLAG|DELAYSLOT|LIKELY|CONDTYPE_FPUTRUE|IS_FPU),444INVALID, INVALID, INVALID, INVALID,445//8446INVALID_X_8,447INVALID_X_8,448INVALID_X_8,449};450451static const MIPSInstruction tableCop1S[64] = // 010001 10000 ..... ..... ..... xxxxxx452{453INSTR("add.s", JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, OUT_FD|IN_FS|IN_FT|IS_FPU),454INSTR("sub.s", JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, OUT_FD|IN_FS|IN_FT|IS_FPU),455INSTR("mul.s", JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, OUT_FD|IN_FS|IN_FT|IS_FPU),456INSTR("div.s", JITFUNC(Comp_FPU3op), Dis_FPU3op, Int_FPU3op, MIPSInfo(OUT_FD|IN_FS|IN_FT|IS_FPU, 29)),457INSTR("sqrt.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),458INSTR("abs.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),459INSTR("mov.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),460INSTR("neg.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),461//8462INVALID, INVALID, INVALID, INVALID,463INSTR("round.w.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),464INSTR("trunc.w.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),465INSTR("ceil.w.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),466INSTR("floor.w.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),467//16468INVALID_X_8,469//24470INVALID_X_8,471//32472INVALID, INVALID, INVALID, INVALID,473//36474INSTR("cvt.w.s", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),475INVALID,476INSTR("dis.int", JITFUNC(Comp_Generic), Dis_Generic, Int_Interrupt, 0),477INVALID,478//40479INVALID_X_8,480//48 - 010001 10000 ..... ..... ..... 11xxxx481INSTR("c.f", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG|IS_FPU),482INSTR("c.un", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),483INSTR("c.eq", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),484INSTR("c.ueq", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),485INSTR("c.olt", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),486INSTR("c.ult", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),487INSTR("c.ole", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),488INSTR("c.ule", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),489INSTR("c.sf", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG|IS_FPU),490INSTR("c.ngle",JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),491INSTR("c.seq", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),492INSTR("c.ngl", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),493INSTR("c.lt", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),494INSTR("c.nge", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),495INSTR("c.le", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),496INSTR("c.ngt", JITFUNC(Comp_FPUComp), Dis_FPUComp, Int_FPUComp, IN_FS|IN_FT|OUT_FPUFLAG|IS_FPU),497};498499static const MIPSInstruction tableCop1W[64] = // 010001 10100 ..... ..... ..... xxxxxx500{501INVALID_X_8,502//8503INVALID_X_8,504//16505INVALID_X_8,506//24507INVALID_X_8,508//32509INSTR("cvt.s.w", JITFUNC(Comp_FPU2op), Dis_FPU2op, Int_FPU2op, OUT_FD|IN_FS|IS_FPU),510INVALID, INVALID, INVALID,511//36512INVALID,513INVALID,514INVALID,515INVALID,516//40517INVALID_X_8,518//48519INVALID_X_8,520INVALID_X_8,521};522523static const MIPSInstruction tableVFPU0[8] = // 011000 xxx ....... . ....... . .......524{525INSTR("vadd", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, MIPSInfo(IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX, 2)),526INSTR("vsub", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, MIPSInfo(IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX, 2)),527// TODO: Disasm is wrong.528INSTR("vsbn", JITFUNC(Comp_Generic), Dis_VectorSet3, Int_Vsbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),529INVALID, INVALID, INVALID, INVALID,530531INSTR("vdiv", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),532};533534static const MIPSInstruction tableVFPU1[8] = // 011001 xxx ....... . ....... . .......535{536INSTR("vmul", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_VecDo3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),537INSTR("vdot", JITFUNC(Comp_VDot), Dis_VectorDot, Int_VDot, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),538INSTR("vscl", JITFUNC(Comp_VScl), Dis_VScl, Int_VScl, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),539INVALID,540INSTR("vhdp", JITFUNC(Comp_VHdp), Dis_VectorDot, Int_VHdp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),541INSTR("vcrs", JITFUNC(Comp_VCrs), Dis_Vcrs, Int_Vcrs, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),542INSTR("vdet", JITFUNC(Comp_VDet), Dis_VectorDot, Int_Vdet, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),543INVALID,544};545546static const MIPSInstruction tableVFPU3[8] = // 011011 xxx ....... . ....... . .......547{548INSTR("vcmp", JITFUNC(Comp_Vcmp), Dis_Vcmp, Int_Vcmp, IN_OTHER|OUT_VFPU_CC|IS_VFPU|OUT_EAT_PREFIX),549INVALID,550INSTR("vmin", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_Vminmax, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),551INSTR("vmax", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_Vminmax, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),552INVALID,553INSTR("vscmp", JITFUNC(Comp_Generic), Dis_VectorSet3, Int_Vscmp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),554INSTR("vsge", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_Vsge, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),555INSTR("vslt", JITFUNC(Comp_VecDo3), Dis_VectorSet3, Int_Vslt, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),556};557558static const MIPSInstruction tableVFPU4Jump[32] = // 110100 xxxxx ..... . ....... . .......559{560ENCODING(VFPU4),561ENCODING(VFPU7),562ENCODING(VFPU9),563INSTR("vcst", JITFUNC(Comp_Vcst), Dis_Vcst, Int_Vcst, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),564INVALID, INVALID, INVALID, INVALID,565566//8567INVALID_X_8,568569//16570INSTR("vf2in", JITFUNC(Comp_Vf2i), Dis_Vf2i, Int_Vf2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),571INSTR("vf2iz", JITFUNC(Comp_Vf2i), Dis_Vf2i, Int_Vf2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),572INSTR("vf2iu", JITFUNC(Comp_Vf2i), Dis_Vf2i, Int_Vf2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),573INSTR("vf2id", JITFUNC(Comp_Vf2i), Dis_Vf2i, Int_Vf2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),574//20575INSTR("vi2f", JITFUNC(Comp_Vi2f), Dis_Vf2i, Int_Vi2f, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),576INSTR("vcmov", JITFUNC(Comp_Vcmov), Dis_Vcmov, Int_Vcmov, IN_OTHER|IN_VFPU_CC|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),577INVALID,578INVALID,579//24 - 110100 11 ........ . ....... . .......580INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),581INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),582INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),583INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),584INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),585INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),586INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),587INSTR("vwbn", JITFUNC(Comp_Generic), Dis_Vwbn, Int_Vwbn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),588};589590static const MIPSInstruction tableVFPU7[32] = // 110100 00001 xxxxx . ....... . .......591{592INSTR("vrnds", JITFUNC(Comp_Generic), Dis_Vrnds, Int_Vrnds, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),593INSTR("vrndi", JITFUNC(Comp_Generic), Dis_VrndX, Int_VrndX, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),594INSTR("vrndf1", JITFUNC(Comp_Generic), Dis_VrndX, Int_VrndX, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),595INSTR("vrndf2", JITFUNC(Comp_Generic), Dis_VrndX, Int_VrndX, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),596597INVALID, INVALID, INVALID, INVALID,598//8599INVALID, INVALID, INVALID, INVALID,600INVALID, INVALID, INVALID, INVALID,601//16602INVALID,603INVALID,604INSTR("vf2h", JITFUNC(Comp_Generic), Dis_Vf2h, Int_Vf2h, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),605INSTR("vh2f", JITFUNC(Comp_Vh2f), Dis_Vh2f, Int_Vh2f, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),606607INVALID,608INVALID,609INSTR("vsbz", JITFUNC(Comp_Generic), Dis_Generic, Int_Vsbz, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),610INSTR("vlgb", JITFUNC(Comp_Generic), Dis_Generic, Int_Vlgb, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),611//24612INSTR("vuc2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), // Seen in BraveStory, initialization 110100 00001110000 000 0001 0000 0000613INSTR("vc2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),614INSTR("vus2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),615INSTR("vs2i", JITFUNC(Comp_Vx2i), Dis_Vs2i, Int_Vx2i, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),616617INSTR("vi2uc", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),618INSTR("vi2c", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),619INSTR("vi2us", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),620INSTR("vi2s", JITFUNC(Comp_Vi2x), Dis_Vi2x, Int_Vi2x, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),621};622623// 110100 00000 10100 0000000000000000624// 110100 00000 10111 0000000000000000625static const MIPSInstruction tableVFPU4[32] = // 110100 00000 xxxxx . ....... . .......626{627INSTR("vmov", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),628INSTR("vabs", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),629INSTR("vneg", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),630INSTR("vidt", JITFUNC(Comp_VIdt), Dis_VectorSet1, Int_Vidt, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),631INSTR("vsat0", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),632INSTR("vsat1", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),633INSTR("vzero", JITFUNC(Comp_VVectorInit), Dis_VectorSet1, Int_VVectorInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),634INSTR("vone", JITFUNC(Comp_VVectorInit), Dis_VectorSet1, Int_VVectorInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),635//8636INVALID_X_8,637//16638INSTR("vrcp", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),639INSTR("vrsq", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),640INSTR("vsin", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),641INSTR("vcos", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),642INSTR("vexp2", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),643INSTR("vlog2", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),644INSTR("vsqrt", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),645INSTR("vasin", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),646//24647INSTR("vnrcp", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),648INVALID,649INSTR("vnsin", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),650INVALID,651INSTR("vrexp2", JITFUNC(Comp_VV2Op), Dis_VectorSet2, Int_VV2Op, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),652INVALID, INVALID, INVALID,653};654655static const MIPSInstruction tableVFPU5[8] = // 110111 xxx ....... ................656{657INSTR("vpfxs", JITFUNC(Comp_VPFX), Dis_VPFXST, Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),658INSTR("vpfxs", JITFUNC(Comp_VPFX), Dis_VPFXST, Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),659INSTR("vpfxt", JITFUNC(Comp_VPFX), Dis_VPFXST, Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),660INSTR("vpfxt", JITFUNC(Comp_VPFX), Dis_VPFXST, Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),661INSTR("vpfxd", JITFUNC(Comp_VPFX), Dis_VPFXD, Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),662INSTR("vpfxd", JITFUNC(Comp_VPFX), Dis_VPFXD, Int_VPFX, IN_IMM16|OUT_OTHER|IS_VFPU),663INSTR("viim.s", JITFUNC(Comp_Viim), Dis_Viim, Int_Viim, IN_IMM16|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),664INSTR("vfim.s", JITFUNC(Comp_Vfim), Dis_Viim, Int_Viim, IN_IMM16|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),665};666667static const MIPSInstruction tableVFPU6[32] = // 111100 xxxxx ..... . ....... . .......668{669//0670INSTR("vmmul", JITFUNC(Comp_Vmmul), Dis_MatrixMult, Int_Vmmul, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),671INSTR("vmmul", JITFUNC(Comp_Vmmul), Dis_MatrixMult, Int_Vmmul, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),672INSTR("vmmul", JITFUNC(Comp_Vmmul), Dis_MatrixMult, Int_Vmmul, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),673INSTR("vmmul", JITFUNC(Comp_Vmmul), Dis_MatrixMult, Int_Vmmul, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),674675INSTR("v(h)tfm2", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),676INSTR("v(h)tfm2", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),677INSTR("v(h)tfm2", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),678INSTR("v(h)tfm2", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),679//8680INSTR("v(h)tfm3", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),681INSTR("v(h)tfm3", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),682INSTR("v(h)tfm3", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),683INSTR("v(h)tfm3", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),684685INSTR("v(h)tfm4", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),686INSTR("v(h)tfm4", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),687INSTR("v(h)tfm4", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),688INSTR("v(h)tfm4", JITFUNC(Comp_Vtfm), Dis_Vtfm, Int_Vtfm, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),689//16690INSTR("vmscl", JITFUNC(Comp_Vmscl), Dis_Vmscl, Int_Vmscl, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),691INSTR("vmscl", JITFUNC(Comp_Vmscl), Dis_Vmscl, Int_Vmscl, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),692INSTR("vmscl", JITFUNC(Comp_Vmscl), Dis_Vmscl, Int_Vmscl, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),693INSTR("vmscl", JITFUNC(Comp_Vmscl), Dis_Vmscl, Int_Vmscl, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),694695INSTR("vcrsp.t/vqmul.q", JITFUNC(Comp_VCrossQuat), Dis_CrossQuat, Int_CrossQuat, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),696INSTR("vcrsp.t/vqmul.q", JITFUNC(Comp_VCrossQuat), Dis_CrossQuat, Int_CrossQuat, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),697INSTR("vcrsp.t/vqmul.q", JITFUNC(Comp_VCrossQuat), Dis_CrossQuat, Int_CrossQuat, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),698INSTR("vcrsp.t/vqmul.q", JITFUNC(Comp_VCrossQuat), Dis_CrossQuat, Int_CrossQuat, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),699//24700INVALID,701INVALID,702INVALID,703INVALID,704//28705ENCODING(VFPUMatrix1),706INSTR("vrot", JITFUNC(Comp_VRot), Dis_VRot, Int_Vrot, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),707INVALID,708INVALID,709};710711// TODO: Should this only be when bit 20 is 0?712static const MIPSInstruction tableVFPUMatrixSet1[16] = // 111100 11100 .xxxx . ....... . ....... (rm x is 16)713{714INSTR("vmmov", JITFUNC(Comp_Vmmov), Dis_MatrixSet2, Int_Vmmov, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),715INVALID,716INVALID,717INSTR("vmidt", JITFUNC(Comp_VMatrixInit), Dis_MatrixSet1, Int_VMatrixInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),718719INVALID,720INVALID,721INSTR("vmzero", JITFUNC(Comp_VMatrixInit), Dis_MatrixSet1, Int_VMatrixInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),722INSTR("vmone", JITFUNC(Comp_VMatrixInit), Dis_MatrixSet1, Int_VMatrixInit, OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),723724INVALID_X_8,725};726727static const MIPSInstruction tableVFPU9[32] = // 110100 00010 xxxxx . ....... . .......728{729INSTR("vsrt1", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt1, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),730INSTR("vsrt2", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt2, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),731INSTR("vbfy1", JITFUNC(Comp_Vbfy), Dis_Vbfy, Int_Vbfy, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),732INSTR("vbfy2", JITFUNC(Comp_Vbfy), Dis_Vbfy, Int_Vbfy, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),733//4734INSTR("vocp", JITFUNC(Comp_Vocp), Dis_Vbfy, Int_Vocp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX), // one's complement735INSTR("vsocp", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsocp, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),736INSTR("vfad", JITFUNC(Comp_Vhoriz), Dis_Vfad, Int_Vfad, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),737INSTR("vavg", JITFUNC(Comp_Vhoriz), Dis_Vfad, Int_Vavg, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),738//8739INSTR("vsrt3", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt3, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),740INSTR("vsrt4", JITFUNC(Comp_Generic), Dis_Vbfy, Int_Vsrt4, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),741INSTR("vsgn", JITFUNC(Comp_Vsgn), Dis_Vbfy, Int_Vsgn, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),742INVALID,743//12744INVALID,745INVALID,746INVALID,747INVALID,748749//16750INSTR("vmfvc", JITFUNC(Comp_Vmfvc), Dis_Vmfvc, Int_Vmfvc, IN_OTHER|IN_VFPU_CC|OUT_OTHER|IS_VFPU),751INSTR("vmtvc", JITFUNC(Comp_Vmtvc), Dis_Vmtvc, Int_Vmtvc, IN_OTHER|OUT_VFPU_CC|OUT_OTHER|IS_VFPU|OUT_VFPU_PREFIX),752INVALID,753INVALID,754755//20756INVALID, INVALID, INVALID, INVALID,757//24758INVALID,759INSTR("vt4444", JITFUNC(Comp_ColorConv), Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),760INSTR("vt5551", JITFUNC(Comp_ColorConv), Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),761INSTR("vt5650", JITFUNC(Comp_ColorConv), Dis_ColorConv, Int_ColorConv, IN_OTHER|OUT_OTHER|IS_VFPU|OUT_EAT_PREFIX),762763//28764INVALID, INVALID, INVALID, INVALID,765};766767static const MIPSInstruction tableALLEGREX0[32] = // 011111 ..... ..... ..... xxxxx 100000 - or ending with 011000?768{769INVALID,770INVALID,771INSTR("wsbh", JITFUNC(Comp_Allegrex2), Dis_Allegrex2, Int_Allegrex2, IN_RT|OUT_RD),772INSTR("wsbw", JITFUNC(Comp_Allegrex2), Dis_Allegrex2, Int_Allegrex2, IN_RT|OUT_RD),773INVALID, INVALID, INVALID, INVALID,774//8775INVALID_X_8,776//16777INSTR("seb", JITFUNC(Comp_Allegrex), Dis_Allegrex,Int_Allegrex, IN_RT|OUT_RD),778INVALID,779INVALID,780INVALID,781//20782INSTR("bitrev", JITFUNC(Comp_Allegrex), Dis_Allegrex,Int_Allegrex, IN_RT|OUT_RD),783INVALID,784INVALID,785INVALID,786//24787INSTR("seh", JITFUNC(Comp_Allegrex), Dis_Allegrex,Int_Allegrex, IN_RT|OUT_RD),788INVALID,789INVALID,790INVALID,791//28792INVALID,793INVALID,794INVALID,795INVALID,796};797798static const MIPSInstruction tableEMU[4] = {799INSTR("RUNBLOCK", JITFUNC(Comp_RunBlock), Dis_Emuhack, Int_Emuhack, 0xFFFFFFFF),800INSTR("RetKrnl", 0, Dis_Emuhack, Int_Emuhack, 0),801INSTR("CallRepl", JITFUNC(Comp_ReplacementFunc), Dis_Emuhack, Int_Emuhack, 0),802INVALID,803};804805struct EncodingBitsInfo {806EncodingBitsInfo(u8 shift_, u8 maskBits_) : shift(shift_) {807mask = (1 << maskBits_) - 1;808}809u8 shift;810u32 mask;811};812813static const EncodingBitsInfo encodingBits[NumEncodings] = {814EncodingBitsInfo(26, 6), //IMME815EncodingBitsInfo(0, 6), //Special816EncodingBitsInfo(0, 6), //special2817EncodingBitsInfo(0, 6), //special3818EncodingBitsInfo(16, 5), //RegImm819EncodingBitsInfo(21, 5), //Cop0820EncodingBitsInfo(0, 6), //Cop0CO821EncodingBitsInfo(21, 5), //Cop1822EncodingBitsInfo(16, 5), //Cop1BC823EncodingBitsInfo(0, 6), //Cop1S824EncodingBitsInfo(0, 6), //Cop1W825EncodingBitsInfo(21, 5), //Cop2826EncodingBitsInfo(16, 2), //Cop2BC2827EncodingBitsInfo(0, 0), //Cop2Rese828EncodingBitsInfo(23, 3), //VFPU0829EncodingBitsInfo(23, 3), //VFPU1830EncodingBitsInfo(23, 3), //VFPU3831EncodingBitsInfo(21, 5), //VFPU4Jump832EncodingBitsInfo(16, 5), //VFPU7833EncodingBitsInfo(16, 5), //VFPU4834EncodingBitsInfo(23, 3), //VFPU5835EncodingBitsInfo(21, 5), //VFPU6836EncodingBitsInfo(16, 4), //VFPUMatrix1837EncodingBitsInfo(16, 5), //VFPU9838EncodingBitsInfo(6, 5), //ALLEGREX0839EncodingBitsInfo(24, 2), //EMUHACK840EncodingBitsInfo(0, 0), //Rese841};842843static const MIPSInstruction *mipsTables[NumEncodings] = {844tableImmediate,845tableSpecial,846tableSpecial2,847tableSpecial3,848tableRegImm,849tableCop0,850tableCop0CO,851tableCop1,852tableCop1BC,853tableCop1S,854tableCop1W,855tableCop2,856tableCop2BC2,8570,858tableVFPU0, //vfpu0859tableVFPU1, //vfpu1860tableVFPU3, //vfpu3861tableVFPU4Jump,862tableVFPU7, //vfpu4 110100 00001863tableVFPU4, //vfpu4 110100 00000864tableVFPU5, //vfpu5 110111865tableVFPU6, //vfpu6 111100866tableVFPUMatrixSet1,867tableVFPU9,868tableALLEGREX0,869tableEMU,8700,871};872873//arm encoding table874//const MIPSInstruction mipsinstructions[] =875//{876//{Comp_Unimpl,Dis_Unimpl, Info_NN, 0, 0x601, 0x1FE,0}, //could be used for drec hook :) bits 5-24 plus 0-3 are available, 19 bits are more than enough877// DATA PROCESSING INSTRUCTIONS878// S879// {Comp_AND, Dis_AND, Info_DP, 0, DATAP(0, 0), 0x20F, {0}},880//};881882// TODO : generate smart dispatcher functions from above tables883// instead of this slow method.884const MIPSInstruction *MIPSGetInstruction(MIPSOpcode op) {885MipsEncoding encoding = Imme;886const MIPSInstruction *instr = &tableImmediate[op.encoding >> 26];887while (instr->altEncoding != Instruc) {888if (instr->altEncoding == Inval) {889//ERROR_LOG(Log::CPU, "Invalid instruction %08x in table %i, entry %i", op, (int)encoding, subop);890return 0; //invalid instruction891}892encoding = instr->altEncoding;893894const MIPSInstruction *table = mipsTables[encoding];895const u32 subop = (op.encoding >> encodingBits[encoding].shift) & encodingBits[encoding].mask;896instr = &table[subop];897}898//alright, we have a valid MIPS instruction!899return instr;900}901902void MIPSCompileOp(MIPSOpcode op, MIPSComp::MIPSFrontendInterface *jit) {903if (op == 0)904return;905const MIPSInstruction *instr = MIPSGetInstruction(op);906const MIPSInfo info = MIPSGetInfo(op);907if (instr) {908if (instr->compile) {909(jit->*(instr->compile))(op);910} else {911ERROR_LOG_REPORT(Log::CPU,"MIPSCompileOp %08x failed",op.encoding);912}913if (info & OUT_EAT_PREFIX)914jit->EatPrefix();915} else {916ERROR_LOG_REPORT(Log::CPU, "MIPSCompileOp: Invalid instruction %08x", op.encoding);917}918}919920void MIPSDisAsm(MIPSOpcode op, u32 pc, char *out, size_t outSize, bool tabsToSpaces) {921if (op == 0) {922truncate_cpy(out, outSize, "nop");923} else {924const MIPSInstruction *instr = MIPSGetInstruction(op);925if (instr && instr->disasm) {926instr->disasm(op, pc, out, outSize);927if (tabsToSpaces) {928while (*out) {929if (*out == '\t')930*out = ' ';931out++;932}933}934} else {935truncate_cpy(out, outSize, "no instruction :(");936}937}938}939940static inline void Interpret(const MIPSInstruction *instr, MIPSOpcode op) {941if (instr && instr->interpret) {942instr->interpret(op);943} else {944ERROR_LOG_REPORT(Log::CPU, "Unknown instruction %08x at %08x", op.encoding, currentMIPS->pc);945// Try to disassemble it946char disasm[256];947MIPSDisAsm(op, currentMIPS->pc, disasm, sizeof(disasm));948_dbg_assert_msg_(0, "%s", disasm);949currentMIPS->pc += 4;950}951}952953inline int GetInstructionCycleEstimate(const MIPSInstruction *instr) {954if (instr)955return instr->flags.cycles;956return 1;957}958959void MIPSInterpret(MIPSOpcode op) {960const MIPSInstruction *instr = MIPSGetInstruction(op);961Interpret(instr, op);962}963964#define _RS ((op>>21) & 0x1F)965#define _RT ((op>>16) & 0x1F)966#define _RD ((op>>11) & 0x1F)967#define R(i) (curMips->r[i])968969static inline void RunUntilFast() {970MIPSState *curMips = currentMIPS;971// NEVER stop in a delay slot!972while (curMips->downcount >= 0 && coreState == CORE_RUNNING) {973do {974// Replacements and similar are processed here, intentionally.975MIPSOpcode op = MIPSOpcode(Memory::Read_U32(curMips->pc));976977bool wasInDelaySlot = curMips->inDelaySlot;978const MIPSInstruction *instr = MIPSGetInstruction(op);979Interpret(instr, op);980curMips->downcount -= GetInstructionCycleEstimate(instr);981982// The reason we have to check this is the delay slot hack in Int_Syscall.983if (curMips->inDelaySlot && wasInDelaySlot) {984curMips->pc = curMips->nextPC;985curMips->inDelaySlot = false;986}987} while (curMips->inDelaySlot);988}989}990991static void RunUntilWithChecks(u64 globalTicks) {992MIPSState *curMips = currentMIPS;993// NEVER stop in a delay slot!994bool hasBPs = CBreakPoints::HasBreakPoints();995bool hasMCs = CBreakPoints::HasMemChecks();996while (curMips->downcount >= 0 && coreState == CORE_RUNNING) {997do {998// Replacements and similar are processed here, intentionally.999MIPSOpcode op = MIPSOpcode(Memory::Read_U32(curMips->pc));1000const MIPSInstruction *instr = MIPSGetInstruction(op);10011002// Check for breakpoint1003if (hasBPs && CBreakPoints::IsAddressBreakPoint(curMips->pc) && CBreakPoints::CheckSkipFirst() != curMips->pc) {1004auto cond = CBreakPoints::GetBreakPointCondition(currentMIPS->pc);1005if (!cond || cond->Evaluate()) {1006Core_EnableStepping(true, "cpu.breakpoint", curMips->pc);1007if (CBreakPoints::IsTempBreakPoint(curMips->pc))1008CBreakPoints::RemoveBreakPoint(curMips->pc);1009break;1010}1011}1012if (hasMCs && (instr->flags & (IN_MEM | OUT_MEM)) != 0 && CBreakPoints::CheckSkipFirst() != curMips->pc && instr->interpret != &Int_Syscall) {1013// This is common for all IN_MEM/OUT_MEM funcs.1014int offset = (instr->flags & IS_VFPU) != 0 ? SignExtend16ToS32(op & 0xFFFC) : SignExtend16ToS32(op);1015u32 addr = (R(_RS) + offset) & 0xFFFFFFFC;1016int sz = MIPSGetMemoryAccessSize(op);10171018if ((instr->flags & IN_MEM) != 0)1019CBreakPoints::ExecMemCheck(addr, false, sz, curMips->pc, "interpret");1020if ((instr->flags & OUT_MEM) != 0)1021CBreakPoints::ExecMemCheck(addr, true, sz, curMips->pc, "interpret");10221023// If it tripped, bail without running.1024if (coreState == CORE_STEPPING)1025break;1026}10271028bool wasInDelaySlot = curMips->inDelaySlot;1029Interpret(instr, op);1030curMips->downcount -= GetInstructionCycleEstimate(instr);10311032// The reason we have to check this is the delay slot hack in Int_Syscall.1033if (curMips->inDelaySlot && wasInDelaySlot) {1034curMips->pc = curMips->nextPC;1035curMips->inDelaySlot = false;1036}1037} while (curMips->inDelaySlot);10381039if (CoreTiming::GetTicks() > globalTicks)1040return;1041}1042}10431044int MIPSInterpret_RunUntil(u64 globalTicks) {1045MIPSState *curMips = currentMIPS;1046while (coreState == CORE_RUNNING) {1047CoreTiming::Advance();10481049uint64_t ticksLeft = globalTicks - CoreTiming::GetTicks();1050if (CBreakPoints::HasBreakPoints() || CBreakPoints::HasMemChecks() || ticksLeft <= curMips->downcount)1051RunUntilWithChecks(globalTicks);1052else1053RunUntilFast();10541055if (CoreTiming::GetTicks() > globalTicks) {1056// DEBUG_LOG(Log::CPU, "Hit the max ticks, bailing 1 : %llu, %llu", globalTicks, CoreTiming::GetTicks());1057return 1;1058}1059}10601061return 1;1062}10631064const char *MIPSGetName(MIPSOpcode op)1065{1066static const char * const noname = "unk";1067const MIPSInstruction *instr = MIPSGetInstruction(op);1068if (!instr)1069return noname;1070else1071return instr->name;1072}10731074MIPSInfo MIPSGetInfo(MIPSOpcode op)1075{1076// int crunch = CRUNCH_MIPS_OP(op);1077const MIPSInstruction *instr = MIPSGetInstruction(op);1078if (instr)1079return instr->flags;1080else1081return MIPSInfo(BAD_INSTRUCTION);1082}10831084MIPSInterpretFunc MIPSGetInterpretFunc(MIPSOpcode op)1085{1086const MIPSInstruction *instr = MIPSGetInstruction(op);1087if (instr->interpret)1088return instr->interpret;1089else1090return 0;1091}10921093// TODO: Do something that makes sense here.1094int MIPSGetInstructionCycleEstimate(MIPSOpcode op)1095{1096const MIPSInstruction *instr = MIPSGetInstruction(op);1097return GetInstructionCycleEstimate(instr);1098}10991100int MIPSGetMemoryAccessSize(MIPSOpcode op) {1101MIPSInfo info = MIPSGetInfo(op);1102if ((info & (IN_MEM | OUT_MEM)) == 0) {1103return 0;1104}11051106switch (info & MEMTYPE_MASK) {1107case MEMTYPE_BYTE:1108return 1;1109case MEMTYPE_HWORD:1110return 2;1111case MEMTYPE_WORD:1112case MEMTYPE_FLOAT:1113return 4;1114case MEMTYPE_VQUAD:1115return 16;1116}11171118return 0;1119}11201121std::string MIPSDisasmAt(u32 compilerPC) {1122char temp[512];1123MIPSDisAsm(Memory::Read_Instruction(compilerPC), 0, temp, sizeof(temp));1124return temp;1125}112611271128