// Copyright (c) 2012- PPSSPP Project.

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License 2.0 for more details.

// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/

// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.

// AUTO-GENERATED by `PPSSPPHeadless --generate-interpreter-dispatch` from the
// tables in MIPSTables.cpp - do not hand-edit, regenerate instead.

#include "Core/MIPS/MIPS.h"
#include "Core/MIPS/Interpreter.h"
#include "Core/MIPS/InterpreterVFPU.h"

// Returns the cycle count consumed, or -1 if op isn't a recognized instruction -
// callers must fall back to MIPSInterpret() themselves in that case.
int ExecInstruction(MIPSState *mips, MIPSOpcode op) {
    switch ((op.encoding >> 26) & 0x3f) {
    case 0:
    {
        switch ((op.encoding >> 0) & 0x3f) {
        // sll, srl, sra, sllv, srlv, srav
        case 0:
        case 2:
        case 3:
        case 4:
        case 6:
        case 7:
            MIPSInt::Int_ShiftType(mips, op);
            return 1;
        // jr, jalr
        case 8:
        case 9:
            MIPSInt::Int_JumpRegType(mips, op);
            return 1;
        // movz, movn, add, addu, sub, subu, and, or, xor, nor, slt, sltu, max, min
        case 10:
        case 11:
        case 32:
        case 33:
        case 34:
        case 35:
        case 36:
        case 37:
        case 38:
        case 39:
        case 42:
        case 43:
        case 44:
        case 45:
            MIPSInt::Int_RType3(mips, op);
            return 1;
        // syscall
        case 12:
            MIPSInt::Int_Syscall(mips, op);
            return 1;
        // break
        case 13:
            MIPSInt::Int_Break(mips, op);
            return 1;
        // sync
        case 15:
            MIPSInt::Int_Sync(mips, op);
            return 1;
        // mfhi, mthi, mflo, mtlo, mult, multu, div, divu, madd, maddu, msub, msubu
        case 16:
        case 17:
        case 18:
        case 19:
        case 24:
        case 25:
        case 26:
        case 27:
        case 28:
        case 29:
        case 46:
        case 47:
            MIPSInt::Int_MulDivType(mips, op);
            return 1;
        // clz, clo
        case 22:
        case 23:
            MIPSInt::Int_RType2(mips, op);
            return 1;
        default:
            return -1;
        }
    }
    case 1:
    {
        switch ((op.encoding >> 16) & 0x1f) {
        // bltz, bgez, bltzl, bgezl, bltzal, bgezal, bltzall, bgezall
        case 0:
        case 1:
        case 2:
        case 3:
        case 16:
        case 17:
        case 18:
        case 19:
            MIPSInt::Int_RelBranchRI(mips, op);
            return 1;
        default:
            return -1;
        }
    }
    // j, jal
    case 2:
    case 3:
        MIPSInt::Int_JumpType(mips, op);
        return 1;
    // beq, bne, blez, bgtz, beql, bnel, blezl, bgtzl
    case 4:
    case 5:
    case 6:
    case 7:
    case 20:
    case 21:
    case 22:
    case 23:
        MIPSInt::Int_RelBranch(mips, op);
        return 1;
    // addi, addiu, slti, sltiu, andi, ori, xori, lui
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 14:
    case 15:
        MIPSInt::Int_IType(mips, op);
        return 1;
    case 16:
    {
        switch ((op.encoding >> 21) & 0x1f) {
        // mfc0, mtc0, rdpgpr, mfmc0, wrpgpr
        case 0:
        case 4:
        case 10:
        case 11:
        case 14:
            MIPSInt::Int_Cop0(mips, op);
            return 1;
        case 16:
        case 17:
        case 18:
        case 19:
        case 20:
        case 21:
        case 22:
        case 23:
        case 24:
        case 25:
        case 26:
        case 27:
        case 28:
        case 29:
        case 30:
        case 31:
        {
            return -1;
        }
        default:
            return -1;
        }
    }
    case 17:
    {
        switch ((op.encoding >> 21) & 0x1f) {
        // mfc1, cfc1, mtc1, ctc1
        case 0:
        case 2:
        case 4:
        case 6:
            MIPSInt::Int_mxc1(mips, op);
            return 1;
        case 8:
        {
            switch ((op.encoding >> 16) & 0x1f) {
            // bc1f, bc1t, bc1fl, bc1tl
            case 0:
            case 1:
            case 2:
            case 3:
                MIPSInt::Int_FPUBranch(mips, op);
                return 1;
            default:
                return -1;
            }
        }
        case 16:
        {
            switch ((op.encoding >> 0) & 0x3f) {
            // add.s, sub.s, mul.s
            case 0:
            case 1:
            case 2:
                MIPSInt::Int_FPU3op(mips, op);
                return 1;
            // div.s
            case 3:
                MIPSInt::Int_FPU3op(mips, op);
                return 29;
            // sqrt.s, abs.s, mov.s, neg.s, round.w.s, trunc.w.s, ceil.w.s, floor.w.s, cvt.w.s
            case 4:
            case 5:
            case 6:
            case 7:
            case 12:
            case 13:
            case 14:
            case 15:
            case 36:
                MIPSInt::Int_FPU2op(mips, op);
                return 1;
            // dis.int
            case 38:
                MIPSInt::Int_Interrupt(mips, op);
                return 1;
            // c.f.s, c.un.s, c.eq.s, c.ueq.s, c.olt.s, c.ult.s, c.ole.s, c.ule.s, c.sf.s, c.ngle.s, c.seq.s, c.ngl.s, c.lt.s, c.nge.s, c.le.s, c.ngt.s
            case 48:
            case 49:
            case 50:
            case 51:
            case 52:
            case 53:
            case 54:
            case 55:
            case 56:
            case 57:
            case 58:
            case 59:
            case 60:
            case 61:
            case 62:
            case 63:
                MIPSInt::Int_FPUComp(mips, op);
                return 1;
            default:
                return -1;
            }
        }
        case 20:
        {
            switch ((op.encoding >> 0) & 0x3f) {
            // cvt.s.w
            case 32:
                MIPSInt::Int_FPU2op(mips, op);
                return 1;
            default:
                return -1;
            }
        }
        default:
            return -1;
        }
    }
    case 18:
    {
        switch ((op.encoding >> 21) & 0x1f) {
        // mfv, mtv
        case 3:
        case 7:
            MIPSInt::Int_Mftv(mips, op);
            return 2;
        case 8:
        {
            switch ((op.encoding >> 16) & 0x3) {
            // bvf, bvt, bvfl, bvtl
            case 0:
            case 1:
            case 2:
            case 3:
                MIPSInt::Int_VBranch(mips, op);
                return 2;
            default:
                return -1;
            }
        }
        default:
            return -1;
        }
    }
    case 24:
    {
        switch ((op.encoding >> 23) & 0x7) {
        // vadd, vsub, vdiv
        case 0:
        case 1:
        case 7:
            MIPSInt::Int_VecDo3(mips, op);
            return 2;
        // vsbn
        case 2:
            MIPSInt::Int_Vsbn(mips, op);
            return 2;
        default:
            return -1;
        }
    }
    case 25:
    {
        switch ((op.encoding >> 23) & 0x7) {
        // vmul
        case 0:
            MIPSInt::Int_VecDo3(mips, op);
            return 2;
        // vdot
        case 1:
            MIPSInt::Int_VDot(mips, op);
            return 2;
        // vscl
        case 2:
            MIPSInt::Int_VScl(mips, op);
            return 2;
        // vhdp
        case 4:
            MIPSInt::Int_VHdp(mips, op);
            return 2;
        // vcrs
        case 5:
            MIPSInt::Int_Vcrs(mips, op);
            return 2;
        // vdet
        case 6:
            MIPSInt::Int_Vdet(mips, op);
            return 2;
        default:
            return -1;
        }
    }
    case 26:
    {
        switch ((op.encoding >> 24) & 0x3) {
        // RUNBLOCK
        case 0:
            MIPSInt::Int_Emuhack(mips, op);
            return 2;
        // RetKrnl, CallRepl
        case 1:
        case 2:
            MIPSInt::Int_Emuhack(mips, op);
            return 1;
        default:
            return -1;
        }
    }
    case 27:
    {
        switch ((op.encoding >> 23) & 0x7) {
        // vcmp
        case 0:
            MIPSInt::Int_Vcmp(mips, op);
            return 2;
        // vmin, vmax
        case 2:
        case 3:
            MIPSInt::Int_Vminmax(mips, op);
            return 2;
        // vscmp
        case 5:
            MIPSInt::Int_Vscmp(mips, op);
            return 2;
        // vsge
        case 6:
            MIPSInt::Int_Vsge(mips, op);
            return 2;
        // vslt
        case 7:
            MIPSInt::Int_Vslt(mips, op);
            return 2;
        default:
            return -1;
        }
    }
    case 28:
    {
        switch ((op.encoding >> 0) & 0x3f) {
        // mfic, mtic
        case 36:
        case 38:
            MIPSInt::Int_Special2(mips, op);
            return 1;
        default:
            return -1;
        }
    }
    case 31:
    {
        switch ((op.encoding >> 0) & 0x3f) {
        // ext, ins
        case 0:
        case 4:
            MIPSInt::Int_Special3(mips, op);
            return 1;
        case 24:
        case 32:
        {
            switch ((op.encoding >> 6) & 0x1f) {
            // wsbh, wsbw
            case 2:
            case 3:
                MIPSInt::Int_Allegrex2(mips, op);
                return 1;
            // seb, bitrev, seh
            case 16:
            case 20:
            case 24:
                MIPSInt::Int_Allegrex(mips, op);
                return 1;
            default:
                return -1;
            }
        }
        default:
            return -1;
        }
    }
    // lb, lh, lwl, lw, lbu, lhu, lwr, sb, sh, swl, sw, swr
    case 32:
    case 33:
    case 34:
    case 35:
    case 36:
    case 37:
    case 38:
    case 40:
    case 41:
    case 42:
    case 43:
    case 46:
        MIPSInt::Int_ITypeMem(mips, op);
        return 1;
    // cache
    case 47:
        MIPSInt::Int_Cache(mips, op);
        return 1;
    // ll, sc
    case 48:
    case 56:
        MIPSInt::Int_StoreSync(mips, op);
        return 1;
    // lwc1, swc1
    case 49:
    case 57:
        MIPSInt::Int_FPULS(mips, op);
        return 1;
    // lv.s, sv.s
    case 50:
    case 58:
        MIPSInt::Int_SV(mips, op);
        return 2;
    case 52:
    {
        switch ((op.encoding >> 21) & 0x1f) {
        case 0:
        {
            switch ((op.encoding >> 16) & 0x1f) {
            // vmov, vabs, vneg, vsat0, vsat1, vrcp, vrsq, vsin, vcos, vexp2, vlog2, vsqrt, vasin, vnrcp, vnsin, vrexp2
            case 0:
            case 1:
            case 2:
            case 4:
            case 5:
            case 16:
            case 17:
            case 18:
            case 19:
            case 20:
            case 21:
            case 22:
            case 23:
            case 24:
            case 26:
            case 28:
                MIPSInt::Int_VV2Op(mips, op);
                return 2;
            // vidt
            case 3:
                MIPSInt::Int_Vidt(mips, op);
                return 2;
            // vzero, vone
            case 6:
            case 7:
                MIPSInt::Int_VVectorInit(mips, op);
                return 2;
            default:
                return -1;
            }
        }
        case 1:
        {
            switch ((op.encoding >> 16) & 0x1f) {
            // vrnds
            case 0:
                MIPSInt::Int_Vrnds(mips, op);
                return 2;
            // vrndi, vrndf1, vrndf2
            case 1:
            case 2:
            case 3:
                MIPSInt::Int_VrndX(mips, op);
                return 2;
            // vf2h
            case 18:
                MIPSInt::Int_Vf2h(mips, op);
                return 2;
            // vh2f
            case 19:
                MIPSInt::Int_Vh2f(mips, op);
                return 2;
            // vsbz
            case 22:
                MIPSInt::Int_Vsbz(mips, op);
                return 2;
            // vlgb
            case 23:
                MIPSInt::Int_Vlgb(mips, op);
                return 2;
            // vuc2ifs, vc2i, vus2i, vs2i
            case 24:
            case 25:
            case 26:
            case 27:
                MIPSInt::Int_Vx2i(mips, op);
                return 2;
            // vi2uc, vi2c, vi2us, vi2s
            case 28:
            case 29:
            case 30:
            case 31:
                MIPSInt::Int_Vi2x(mips, op);
                return 2;
            default:
                return -1;
            }
        }
        case 2:
        {
            switch ((op.encoding >> 16) & 0x1f) {
            // vsrt1
            case 0:
                MIPSInt::Int_Vsrt1(mips, op);
                return 2;
            // vsrt2
            case 1:
                MIPSInt::Int_Vsrt2(mips, op);
                return 2;
            // vbfy1, vbfy2
            case 2:
            case 3:
                MIPSInt::Int_Vbfy(mips, op);
                return 2;
            // vocp
            case 4:
                MIPSInt::Int_Vocp(mips, op);
                return 2;
            // vsocp
            case 5:
                MIPSInt::Int_Vsocp(mips, op);
                return 2;
            // vfad
            case 6:
                MIPSInt::Int_Vfad(mips, op);
                return 2;
            // vavg
            case 7:
                MIPSInt::Int_Vavg(mips, op);
                return 2;
            // vsrt3
            case 8:
                MIPSInt::Int_Vsrt3(mips, op);
                return 2;
            // vsrt4
            case 9:
                MIPSInt::Int_Vsrt4(mips, op);
                return 2;
            // vsgn
            case 10:
                MIPSInt::Int_Vsgn(mips, op);
                return 2;
            // vmfvc
            case 16:
                MIPSInt::Int_Vmfvc(mips, op);
                return 2;
            // vmtvc
            case 17:
                MIPSInt::Int_Vmtvc(mips, op);
                return 2;
            // vt4444, vt5551, vt5650
            case 25:
            case 26:
            case 27:
                MIPSInt::Int_ColorConv(mips, op);
                return 2;
            default:
                return -1;
            }
        }
        // vcst
        case 3:
            MIPSInt::Int_Vcst(mips, op);
            return 2;
        // vf2in, vf2iz, vf2iu, vf2id
        case 16:
        case 17:
        case 18:
        case 19:
            MIPSInt::Int_Vf2i(mips, op);
            return 2;
        // vi2f
        case 20:
            MIPSInt::Int_Vi2f(mips, op);
            return 2;
        // vcmov
        case 21:
            MIPSInt::Int_Vcmov(mips, op);
            return 2;
        // vwbn, vwbn, vwbn, vwbn, vwbn, vwbn, vwbn, vwbn
        case 24:
        case 25:
        case 26:
        case 27:
        case 28:
        case 29:
        case 30:
        case 31:
            MIPSInt::Int_Vwbn(mips, op);
            return 2;
        default:
            return -1;
        }
    }
    // lv, lv.q, sv, sv.q
    case 53:
    case 54:
    case 61:
    case 62:
        MIPSInt::Int_SVQ(mips, op);
        return 2;
    case 55:
    {
        switch ((op.encoding >> 23) & 0x7) {
        // vpfxs, vpfxs, vpfxt, vpfxt, vpfxd, vpfxd
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
            MIPSInt::Int_VPFX(mips, op);
            return 2;
        // viim.s, vfim.s
        case 6:
        case 7:
            MIPSInt::Int_Viim(mips, op);
            return 2;
        default:
            return -1;
        }
    }
    case 60:
    {
        switch ((op.encoding >> 21) & 0x1f) {
        // vmmul, vmmul, vmmul, vmmul
        case 0:
        case 1:
        case 2:
        case 3:
            MIPSInt::Int_Vmmul(mips, op);
            return 2;
        // v(h)tfm2, v(h)tfm2, v(h)tfm2, v(h)tfm2, v(h)tfm3, v(h)tfm3, v(h)tfm3, v(h)tfm3, v(h)tfm4, v(h)tfm4, v(h)tfm4, v(h)tfm4
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
        case 14:
        case 15:
            MIPSInt::Int_Vtfm(mips, op);
            return 2;
        // vmscl, vmscl, vmscl, vmscl
        case 16:
        case 17:
        case 18:
        case 19:
            MIPSInt::Int_Vmscl(mips, op);
            return 2;
        // vcrsp.t/vqmul.q, vcrsp.t/vqmul.q, vcrsp.t/vqmul.q, vcrsp.t/vqmul.q
        case 20:
        case 21:
        case 22:
        case 23:
            MIPSInt::Int_CrossQuat(mips, op);
            return 2;
        case 28:
        {
            switch ((op.encoding >> 16) & 0xf) {
            // vmmov
            case 0:
                MIPSInt::Int_Vmmov(mips, op);
                return 2;
            // vmidt, vmzero, vmone
            case 3:
            case 6:
            case 7:
                MIPSInt::Int_VMatrixInit(mips, op);
                return 2;
            default:
                return -1;
            }
        }
        // vrot
        case 29:
            MIPSInt::Int_Vrot(mips, op);
            return 2;
        default:
            return -1;
        }
    }
    // vflush
    case 63:
        MIPSInt::Int_Vflush(mips, op);
        return 2;
    default:
        return -1;
    }
}
