Files
ARMSX2/pcsx2/R5900OpcodeTables.cpp
T

758 lines
32 KiB
C++
Raw Permalink Normal View History

// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
2024-07-30 13:42:36 +02:00
// SPDX-License-Identifier: GPL-3.0+
2009-09-08 12:08:10 +00:00
//all tables for R5900 are define here..
#include "R5900OpcodeTables.h"
#include "R5900.h"
2024-03-21 19:55:59 +10:00
// TODO(Stenzek): Move headers to common code.
#include "x86/iR5900AritImm.h"
#include "x86/iR5900Arit.h"
#include "x86/iR5900MultDiv.h"
#include "x86/iR5900Shift.h"
#include "x86/iR5900Branch.h"
#include "x86/iR5900Jump.h"
#include "x86/iR5900LoadStore.h"
#include "x86/iR5900Move.h"
#include "x86/iMMI.h"
#include "x86/iCOP0.h"
#include "x86/iFPU.h"
namespace R5900
{
namespace Opcodes
{
// Generates an entry for the given opcode name.
// Assumes the default function naming schemes for interpreter and recompiler functions.
2026-06-20 20:27:55 -07:00
#if defined(_M_X86) || defined(ARCH_ARM64) // ARM64 EE recompiler is supported
2014-08-16 20:33:45 +02:00
# define MakeOpcode( name, cycles, flags ) \
static const OPCODE name = { \
#name, \
cycles, \
2014-08-16 20:33:45 +02:00
flags, \
NULL, \
::R5900::Interpreter::OpcodeImpl::name, \
::R5900::Dynarec::OpcodeImpl::rec##name, \
::R5900::OpcodeDisasm::name \
}
2014-08-16 20:33:45 +02:00
# define MakeOpcodeM( name, cycles, flags ) \
static const OPCODE name = { \
#name, \
cycles, \
2014-08-16 20:33:45 +02:00
flags, \
NULL, \
::R5900::Interpreter::OpcodeImpl::MMI::name, \
::R5900::Dynarec::OpcodeImpl::MMI::rec##name, \
::R5900::OpcodeDisasm::name \
}
2014-08-16 20:33:45 +02:00
# define MakeOpcode0( name, cycles, flags ) \
static const OPCODE name = { \
#name, \
cycles, \
2014-08-16 20:33:45 +02:00
flags, \
NULL, \
::R5900::Interpreter::OpcodeImpl::COP0::name, \
::R5900::Dynarec::OpcodeImpl::COP0::rec##name, \
::R5900::OpcodeDisasm::name \
}
2014-08-16 20:33:45 +02:00
# define MakeOpcode1( name, cycles, flags ) \
static const OPCODE name = { \
#name, \
cycles, \
2014-08-16 20:33:45 +02:00
flags, \
NULL, \
::R5900::Interpreter::OpcodeImpl::COP1::name, \
::R5900::Dynarec::OpcodeImpl::COP1::rec##name, \
::R5900::OpcodeDisasm::name \
}
2024-03-21 19:55:59 +10:00
#else
# define MakeOpcode( name, cycles, flags ) \
static const OPCODE name = { \
#name, \
cycles, \
flags, \
NULL, \
::R5900::Interpreter::OpcodeImpl::name, \
nullptr, \
::R5900::OpcodeDisasm::name \
}
# define MakeOpcodeM( name, cycles, flags ) \
static const OPCODE name = { \
#name, \
cycles, \
flags, \
NULL, \
::R5900::Interpreter::OpcodeImpl::MMI::name, \
nullptr, \
::R5900::OpcodeDisasm::name \
}
# define MakeOpcode0( name, cycles, flags ) \
static const OPCODE name = { \
#name, \
cycles, \
flags, \
NULL, \
::R5900::Interpreter::OpcodeImpl::COP0::name, \
nullptr, \
::R5900::OpcodeDisasm::name \
}
# define MakeOpcode1( name, cycles, flags ) \
static const OPCODE name = { \
#name, \
cycles, \
flags, \
NULL, \
::R5900::Interpreter::OpcodeImpl::COP1::name, \
nullptr, \
::R5900::OpcodeDisasm::name \
}
#endif
# define MakeOpcodeClass( name ) \
static const OPCODE name = { \
#name, \
0, \
2014-08-16 20:33:45 +02:00
0, \
R5900::Opcodes::Class_##name, \
NULL, \
NULL, \
NULL \
}
// We're working on new hopefully better cycle ratios, but they're still a WIP.
// And yes this whole thing is an ugly hack. I'll clean it up once we have
// a better idea how exactly the cycle ratios will work best.
namespace Cycles
{
static const int Default = 9;
static const int Branch = 11;
static const int CopDefault = 7;
static const int Mult = 2*8;
static const int Div = 14*8;
static const int MMI_Mult = 3*8;
static const int MMI_Div = 22*8;
static const int MMI_Default = 14;
static const int FPU_Mult = 4*8;
2009-09-03 15:02:38 +00:00
static const int Store = 14;
static const int Load = 14;
}
using namespace Cycles;
2014-08-16 20:33:45 +02:00
MakeOpcode( Unknown, Default, 0 );
MakeOpcode( MMI_Unknown, Default, 0 );
MakeOpcode( COP0_Unknown, Default, 0 );
MakeOpcode( COP1_Unknown, Default, 0 );
// Class Subset Opcodes
// (not really opcodes, but rather entire subsets of other opcode classes)
MakeOpcodeClass( SPECIAL );
MakeOpcodeClass( REGIMM );
//MakeOpcodeClass( COP2 );
MakeOpcodeClass( MMI );
MakeOpcodeClass( MMI0 );
MakeOpcodeClass( MMI2 );
MakeOpcodeClass( MMI1 );
MakeOpcodeClass( MMI3 );
MakeOpcodeClass( COP0 );
MakeOpcodeClass( COP1 );
// Misc Junk
2014-08-16 20:33:45 +02:00
MakeOpcode( COP2, Default, 0 );
2014-08-16 20:33:45 +02:00
MakeOpcode( CACHE, Default, 0 );
MakeOpcode( PREF, Default, 0 );
MakeOpcode( SYSCALL, Default, IS_BRANCH|BRANCHTYPE_SYSCALL );
2014-08-16 20:33:45 +02:00
MakeOpcode( BREAK, Default, 0 );
MakeOpcode( SYNC, Default, 0 );
// Branch/Jump Opcodes
MakeOpcode( J , Default, IS_BRANCH|BRANCHTYPE_JUMP );
MakeOpcode( JAL, Default, IS_BRANCH|BRANCHTYPE_JUMP|IS_LINKED );
MakeOpcode( JR, Default, IS_BRANCH|BRANCHTYPE_REGISTER );
MakeOpcode( JALR, Default, IS_BRANCH|BRANCHTYPE_REGISTER|IS_LINKED );
MakeOpcode( BEQ, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_EQ );
MakeOpcode( BNE, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_NE );
MakeOpcode( BLEZ, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_LEZ );
MakeOpcode( BGTZ, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_GTZ );
MakeOpcode( BEQL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_EQ|IS_LIKELY );
MakeOpcode( BNEL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_NE|IS_LIKELY );
MakeOpcode( BLEZL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_LEZ|IS_LIKELY );
MakeOpcode( BGTZL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_GTZ|IS_LIKELY );
MakeOpcode( BLTZ, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_LTZ );
MakeOpcode( BGEZ, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_GEZ );
MakeOpcode( BLTZL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_LTZ|IS_LIKELY );
MakeOpcode( BGEZL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_GEZ|IS_LIKELY );
MakeOpcode( BLTZAL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_LTZ|IS_LINKED );
MakeOpcode( BGEZAL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_GEZ|IS_LINKED );
MakeOpcode( BLTZALL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_LTZ|IS_LINKED|IS_LIKELY );
MakeOpcode( BGEZALL, Branch, IS_BRANCH|BRANCHTYPE_BRANCH|CONDTYPE_GEZ|IS_LINKED|IS_LIKELY );
2014-08-16 20:33:45 +02:00
MakeOpcode( TGEI, Branch, 0 );
MakeOpcode( TGEIU, Branch, 0 );
MakeOpcode( TLTI, Branch, 0 );
MakeOpcode( TLTIU, Branch, 0 );
MakeOpcode( TEQI, Branch, 0 );
MakeOpcode( TNEI, Branch, 0 );
MakeOpcode( TGE, Branch, 0 );
MakeOpcode( TGEU, Branch, 0 );
MakeOpcode( TLT, Branch, 0 );
MakeOpcode( TLTU, Branch, 0 );
MakeOpcode( TEQ, Branch, 0 );
MakeOpcode( TNE, Branch, 0 );
// Arithmetic
2014-08-16 20:33:45 +02:00
MakeOpcode( MULT, Mult, 0 );
MakeOpcode( MULTU, Mult, 0 );
MakeOpcode( MULT1, Mult, 0 );
MakeOpcode( MULTU1, Mult, 0 );
MakeOpcode( MADD, Mult, 0 );
MakeOpcode( MADDU, Mult, 0 );
MakeOpcode( MADD1, Mult, 0 );
MakeOpcode( MADDU1, Mult, 0 );
MakeOpcode( DIV, Div, 0 );
MakeOpcode( DIVU, Div, 0 );
MakeOpcode( DIV1, Div, 0 );
MakeOpcode( DIVU1, Div, 0 );
MakeOpcode( ADDI, Default, IS_ALU|ALUTYPE_ADDI );
MakeOpcode( ADDIU, Default, IS_ALU|ALUTYPE_ADDI );
MakeOpcode( DADDI, Default, IS_ALU|ALUTYPE_ADDI|IS_64BIT );
MakeOpcode( DADDIU, Default, IS_ALU|ALUTYPE_ADDI|IS_64BIT );
MakeOpcode( DADD, Default, IS_ALU|ALUTYPE_ADD|IS_64BIT );
MakeOpcode( DADDU, Default, IS_ALU|ALUTYPE_ADD|IS_64BIT );
MakeOpcode( DSUB, Default, IS_ALU|ALUTYPE_SUB|IS_64BIT );
MakeOpcode( DSUBU, Default, IS_ALU|ALUTYPE_SUB|IS_64BIT );
MakeOpcode( ADD, Default, IS_ALU|ALUTYPE_ADD );
MakeOpcode( ADDU, Default, IS_ALU|ALUTYPE_ADD );
MakeOpcode( SUB, Default, IS_ALU|ALUTYPE_SUB );
MakeOpcode( SUBU, Default, IS_ALU|ALUTYPE_SUB );
2014-08-16 20:33:45 +02:00
MakeOpcode( ANDI, Default, 0 );
MakeOpcode( ORI, Default, 0 );
MakeOpcode( XORI, Default, 0 );
MakeOpcode( AND, Default, 0 );
MakeOpcode( OR, Default, 0 );
MakeOpcode( XOR, Default, 0 );
MakeOpcode( NOR, Default, 0 );
MakeOpcode( SLTI, Default, 0 );
MakeOpcode( SLTIU, Default, 0 );
MakeOpcode( SLT, Default, 0 );
MakeOpcode( SLTU, Default, 0 );
MakeOpcode( LUI, Default, 0 );
MakeOpcode( SLL, Default, 0 );
MakeOpcode( SRL, Default, 0 );
MakeOpcode( SRA, Default, 0 );
MakeOpcode( SLLV, Default, 0 );
MakeOpcode( SRLV, Default, 0 );
MakeOpcode( SRAV, Default, 0 );
MakeOpcode( MOVZ, Default, IS_ALU|ALUTYPE_CONDMOVE|CONDTYPE_EQ );
MakeOpcode( MOVN, Default, IS_ALU|ALUTYPE_CONDMOVE|CONDTYPE_NE );
2014-08-16 20:33:45 +02:00
MakeOpcode( DSLLV, Default, 0 );
MakeOpcode( DSRLV, Default, 0 );
MakeOpcode( DSRAV, Default, 0 );
MakeOpcode( DSLL, Default, 0 );
MakeOpcode( DSRL, Default, 0 );
MakeOpcode( DSRA, Default, 0 );
MakeOpcode( DSLL32, Default, 0 );
MakeOpcode( DSRL32, Default, 0 );
MakeOpcode( DSRA32, Default, 0 );
2014-08-16 20:33:45 +02:00
MakeOpcode( MFHI, Default, 0 );
MakeOpcode( MTHI, Default, 0 );
MakeOpcode( MFLO, Default, 0 );
MakeOpcode( MTLO, Default, 0 );
MakeOpcode( MFSA, Default, 0 );
MakeOpcode( MTSA, Default, 0 );
MakeOpcode( MTSAB, Default, 0 );
MakeOpcode( MTSAH, Default, 0 );
MakeOpcode( MFHI1, Default, 0 );
MakeOpcode( MTHI1, Default, 0 );
MakeOpcode( MFLO1, Default, 0 );
MakeOpcode( MTLO1, Default, 0 );
// Loads!
MakeOpcode( LDL, Load, IS_MEMORY|IS_LOAD|MEMTYPE_DWORD|IS_LEFT );
MakeOpcode( LDR, Load, IS_MEMORY|IS_LOAD|MEMTYPE_DWORD|IS_RIGHT );
MakeOpcode( LQ, Load, IS_MEMORY|IS_LOAD|MEMTYPE_QWORD );
MakeOpcode( LB, Load, IS_MEMORY|IS_LOAD|MEMTYPE_BYTE );
MakeOpcode( LH, Load, IS_MEMORY|IS_LOAD|MEMTYPE_HALF );
MakeOpcode( LWL, Load, IS_MEMORY|IS_LOAD|MEMTYPE_WORD|IS_LEFT );
MakeOpcode( LW, Load, IS_MEMORY|IS_LOAD|MEMTYPE_WORD );
MakeOpcode( LBU, Load, IS_MEMORY|IS_LOAD|MEMTYPE_BYTE );
MakeOpcode( LHU, Load, IS_MEMORY|IS_LOAD|MEMTYPE_HALF );
MakeOpcode( LWR, Load, IS_MEMORY|IS_LOAD|MEMTYPE_WORD|IS_RIGHT );
MakeOpcode( LWU, Load, IS_MEMORY|IS_LOAD|MEMTYPE_WORD );
MakeOpcode( LWC1, Load, IS_MEMORY|IS_LOAD|MEMTYPE_WORD );
MakeOpcode( LQC2, Load, IS_MEMORY|IS_LOAD|MEMTYPE_QWORD );
MakeOpcode( LD, Load, IS_MEMORY|IS_LOAD|MEMTYPE_DWORD );
// Stores!
MakeOpcode( SQ, Store, IS_MEMORY|IS_STORE|MEMTYPE_QWORD );
MakeOpcode( SB, Store, IS_MEMORY|IS_STORE|MEMTYPE_BYTE );
MakeOpcode( SH, Store, IS_MEMORY|IS_STORE|MEMTYPE_HALF );
MakeOpcode( SWL, Store, IS_MEMORY|IS_STORE|MEMTYPE_WORD|IS_LEFT );
MakeOpcode( SW, Store, IS_MEMORY|IS_STORE|MEMTYPE_WORD );
MakeOpcode( SDL, Store, IS_MEMORY|IS_STORE|MEMTYPE_DWORD|IS_LEFT );
MakeOpcode( SDR, Store, IS_MEMORY|IS_STORE|MEMTYPE_DWORD|IS_RIGHT );
MakeOpcode( SWR, Store, IS_MEMORY|IS_STORE|MEMTYPE_WORD|IS_RIGHT );
MakeOpcode( SWC1, Store, IS_MEMORY|IS_STORE|MEMTYPE_WORD );
MakeOpcode( SQC2, Store, IS_MEMORY|IS_STORE|MEMTYPE_QWORD );
MakeOpcode( SD, Store, IS_MEMORY|IS_STORE|MEMTYPE_DWORD );
// Multimedia Instructions!
2014-08-16 20:33:45 +02:00
MakeOpcodeM( PLZCW, MMI_Default, 0 );
MakeOpcodeM( PMFHL, MMI_Default, 0 );
MakeOpcodeM( PMTHL, MMI_Default, 0 );
MakeOpcodeM( PSLLH, MMI_Default, 0 );
MakeOpcodeM( PSRLH, MMI_Default, 0 );
MakeOpcodeM( PSRAH, MMI_Default, 0 );
MakeOpcodeM( PSLLW, MMI_Default, 0 );
MakeOpcodeM( PSRLW, MMI_Default, 0 );
MakeOpcodeM( PSRAW, MMI_Default, 0 );
2014-08-16 20:33:45 +02:00
MakeOpcodeM( PADDW, MMI_Default, 0 );
MakeOpcodeM( PADDH, MMI_Default, 0 );
MakeOpcodeM( PADDB, MMI_Default, 0 );
MakeOpcodeM( PADDSW, MMI_Default, 0 );
MakeOpcodeM( PADDSH, MMI_Default, 0 );
MakeOpcodeM( PADDSB, MMI_Default, 0 );
MakeOpcodeM( PADDUW, MMI_Default, 0 );
MakeOpcodeM( PADDUH, MMI_Default, 0 );
MakeOpcodeM( PADDUB, MMI_Default, 0 );
MakeOpcodeM( PSUBW, MMI_Default, 0 );
MakeOpcodeM( PSUBH, MMI_Default, 0 );
MakeOpcodeM( PSUBB, MMI_Default, 0 );
MakeOpcodeM( PSUBSW, MMI_Default, 0 );
MakeOpcodeM( PSUBSH, MMI_Default, 0 );
MakeOpcodeM( PSUBSB, MMI_Default, 0 );
MakeOpcodeM( PSUBUW, MMI_Default, 0 );
MakeOpcodeM( PSUBUH, MMI_Default, 0 );
MakeOpcodeM( PSUBUB, MMI_Default, 0 );
2014-08-16 20:33:45 +02:00
MakeOpcodeM( PCGTW, MMI_Default, 0 );
MakeOpcodeM( PMAXW, MMI_Default, 0 );
MakeOpcodeM( PMAXH, MMI_Default, 0 );
MakeOpcodeM( PCGTH, MMI_Default, 0 );
MakeOpcodeM( PCGTB, MMI_Default, 0 );
MakeOpcodeM( PEXTLW, MMI_Default, 0 );
MakeOpcodeM( PEXTLH, MMI_Default, 0 );
MakeOpcodeM( PEXTLB, MMI_Default, 0 );
MakeOpcodeM( PEXT5, MMI_Default, 0 );
MakeOpcodeM( PPACW, MMI_Default, 0 );
MakeOpcodeM( PPACH, MMI_Default, 0 );
MakeOpcodeM( PPACB, MMI_Default, 0 );
MakeOpcodeM( PPAC5, MMI_Default, 0 );
2014-08-16 20:33:45 +02:00
MakeOpcodeM( PABSW, MMI_Default, 0 );
MakeOpcodeM( PABSH, MMI_Default, 0 );
MakeOpcodeM( PCEQW, MMI_Default, 0 );
MakeOpcodeM( PMINW, MMI_Default, 0 );
MakeOpcodeM( PMINH, MMI_Default, 0 );
MakeOpcodeM( PADSBH, MMI_Default, 0 );
MakeOpcodeM( PCEQH, MMI_Default, 0 );
MakeOpcodeM( PCEQB, MMI_Default, 0 );
MakeOpcodeM( PEXTUW, MMI_Default, 0 );
MakeOpcodeM( PEXTUH, MMI_Default, 0 );
MakeOpcodeM( PEXTUB, MMI_Default, 0 );
MakeOpcodeM( PSLLVW, MMI_Default, 0 );
MakeOpcodeM( PSRLVW, MMI_Default, 0 );
2014-08-16 20:33:45 +02:00
MakeOpcodeM( QFSRV, MMI_Default, 0 );
2014-08-16 20:33:45 +02:00
MakeOpcodeM( PMADDH, MMI_Mult, 0 );
MakeOpcodeM( PHMADH, MMI_Mult, 0 );
MakeOpcodeM( PMSUBH, MMI_Mult, 0 );
MakeOpcodeM( PHMSBH, MMI_Mult, 0 );
MakeOpcodeM( PMULTH, MMI_Mult, 0 );
MakeOpcodeM( PMADDW, MMI_Mult, 0 );
MakeOpcodeM( PMSUBW, MMI_Mult, 0 );
MakeOpcodeM( PMFHI, MMI_Mult, 0 );
MakeOpcodeM( PMFLO, MMI_Mult, 0 );
MakeOpcodeM( PMULTW, MMI_Mult, 0 );
MakeOpcodeM( PMADDUW, MMI_Mult, 0 );
MakeOpcodeM( PMULTUW, MMI_Mult, 0 );
MakeOpcodeM( PDIVUW, MMI_Div, 0 );
MakeOpcodeM( PDIVW, MMI_Div, 0 );
MakeOpcodeM( PDIVBW, MMI_Div, 0 );
2014-08-16 20:33:45 +02:00
MakeOpcodeM( PINTH, MMI_Default, 0 );
MakeOpcodeM( PCPYLD, MMI_Default, 0 );
MakeOpcodeM( PAND, MMI_Default, 0 );
MakeOpcodeM( PXOR, MMI_Default, 0 );
MakeOpcodeM( PEXEH, MMI_Default, 0 );
MakeOpcodeM( PREVH, MMI_Default, 0 );
MakeOpcodeM( PEXEW, MMI_Default, 0 );
MakeOpcodeM( PROT3W, MMI_Default, 0 );
2014-08-16 20:33:45 +02:00
MakeOpcodeM( PSRAVW, MMI_Default, 0 );
MakeOpcodeM( PMTHI, MMI_Default, 0 );
MakeOpcodeM( PMTLO, MMI_Default, 0 );
MakeOpcodeM( PINTEH, MMI_Default, 0 );
MakeOpcodeM( PCPYUD, MMI_Default, 0 );
MakeOpcodeM( POR, MMI_Default, 0 );
MakeOpcodeM( PNOR, MMI_Default, 0 );
MakeOpcodeM( PEXCH, MMI_Default, 0 );
MakeOpcodeM( PCPYH, MMI_Default, 0 );
MakeOpcodeM( PEXCW, MMI_Default, 0 );
//////////////////////////////////////////////////////////
// COP0 Instructions
MakeOpcodeClass( COP0_C0 );
MakeOpcodeClass( COP0_BC0 );
2014-08-16 20:33:45 +02:00
MakeOpcode0( MFC0, CopDefault, 0 );
MakeOpcode0( MTC0, CopDefault, 0 );
MakeOpcode0(BC0F, Branch, IS_BRANCH | BRANCHTYPE_BC0 | CONDTYPE_EQ);
MakeOpcode0(BC0T, Branch, IS_BRANCH | BRANCHTYPE_BC0 | CONDTYPE_NE);
MakeOpcode0(BC0FL, Branch, IS_BRANCH | BRANCHTYPE_BC0 | CONDTYPE_EQ | IS_LIKELY);
MakeOpcode0(BC0TL, Branch, IS_BRANCH | BRANCHTYPE_BC0 | CONDTYPE_NE | IS_LIKELY);
2014-08-16 20:33:45 +02:00
MakeOpcode0( TLBR, CopDefault, 0 );
MakeOpcode0( TLBWI, CopDefault, 0 );
MakeOpcode0( TLBWR, CopDefault, 0 );
MakeOpcode0( TLBP, CopDefault, 0 );
MakeOpcode0( ERET, CopDefault, IS_BRANCH|BRANCHTYPE_ERET );
2014-08-16 20:33:45 +02:00
MakeOpcode0( EI, CopDefault, 0 );
MakeOpcode0( DI, CopDefault, 0 );
//////////////////////////////////////////////////////////
// COP1 Instructions!
MakeOpcodeClass( COP1_BC1 );
MakeOpcodeClass( COP1_S );
MakeOpcodeClass( COP1_W ); // contains CVT_S instruction *only*
2014-08-16 20:33:45 +02:00
MakeOpcode1( MFC1, CopDefault, 0 );
MakeOpcode1( CFC1, CopDefault, 0 );
MakeOpcode1( MTC1, CopDefault, 0 );
MakeOpcode1( CTC1, CopDefault, 0 );
MakeOpcode1( BC1F, Branch, IS_BRANCH|BRANCHTYPE_BC1|CONDTYPE_EQ );
MakeOpcode1( BC1T, Branch, IS_BRANCH|BRANCHTYPE_BC1|CONDTYPE_NE );
MakeOpcode1( BC1FL, Branch, IS_BRANCH|BRANCHTYPE_BC1|CONDTYPE_EQ|IS_LIKELY );
MakeOpcode1( BC1TL, Branch, IS_BRANCH|BRANCHTYPE_BC1|CONDTYPE_NE|IS_LIKELY );
2014-08-16 20:33:45 +02:00
MakeOpcode1( ADD_S, CopDefault, 0 );
MakeOpcode1( ADDA_S, CopDefault, 0 );
MakeOpcode1( SUB_S, CopDefault, 0 );
MakeOpcode1( SUBA_S, CopDefault, 0 );
2014-08-16 20:33:45 +02:00
MakeOpcode1( ABS_S, CopDefault, 0 );
MakeOpcode1( MOV_S, CopDefault, 0 );
MakeOpcode1( NEG_S, CopDefault, 0 );
MakeOpcode1( MAX_S, CopDefault, 0 );
MakeOpcode1( MIN_S, CopDefault, 0 );
// The FPU's real timings, measured on silicon rather than inferred.
// Method: COP0 Count around loops of k copies of one instruction, k in
// {1,2,4,8}, so the loop overhead falls out as the intercept and the
// per-instruction cost is the slope. Taken on an SCPH-90000 (FCR0
// 0x2E40) over four runs; three produce byte-identical tables.
//
// MUL.S latency 4, issue interval 1 (pipelined)
// DIV.S 7, and latency == issue interval
// SQRT.S 7, identical to DIV.S
// RSQRT.S 13
//
// DIV.S and SQRT.S are ONE shared, non-pipelined unit. Equal latency
// alone would not say that -- what does is the mix: interleaved
// div.s/sqrt.s costs the SUM (14 per pair), while div.s/add.s and
// div.s/mul.s cost the divide ALONE (7 per pair), because the FMAC runs
// concurrently and hides inside the divide entirely. RSQRT.S at
// 7 + 7 - 1 is two passes through that unit, which agrees with its value
// identity (rsqrt == sqrt then divide, see FPU.cpp's RSQRT_S). The
// latency is identical on every operand class tried -- exact and
// non-terminating quotients, denormals, zero, divide by zero, overflow
// to the EE maximum -- so there is no early termination anywhere.
//
// The three entries below say 6, 6 and 8. They are LEFT AS THEY ARE
// deliberately: this is a compatibility-sensitive timing table, not a
// correctness one, and nothing has measured what moving it does to
// games. The numbers above are recorded here so that the next person to
// wonder does not have to take the console run again. (FPU_Mult's 4
// does match the measured multiply latency.)
2014-08-16 20:33:45 +02:00
MakeOpcode1( MUL_S, FPU_Mult, 0 );
MakeOpcode1( DIV_S, 6*8, 0 );
MakeOpcode1( SQRT_S, 6*8, 0 );
MakeOpcode1( RSQRT_S, 8*8, 0 );
MakeOpcode1( MULA_S, FPU_Mult, 0 );
MakeOpcode1( MADD_S, FPU_Mult, 0 );
MakeOpcode1( MSUB_S, FPU_Mult, 0 );
MakeOpcode1( MADDA_S, FPU_Mult, 0 );
MakeOpcode1( MSUBA_S, FPU_Mult, 0 );
2014-08-16 20:33:45 +02:00
MakeOpcode1( C_F, CopDefault, 0 );
MakeOpcode1( C_EQ, CopDefault, 0 );
MakeOpcode1( C_LT, CopDefault, 0 );
MakeOpcode1( C_LE, CopDefault, 0 );
2014-08-16 20:33:45 +02:00
MakeOpcode1( CVT_S, CopDefault, 0 );
MakeOpcode1( CVT_W, CopDefault, 0 );
}
namespace OpcodeTables
{
using namespace Opcodes;
const OPCODE tbl_Standard[64] =
{
SPECIAL, REGIMM, J, JAL, BEQ, BNE, BLEZ, BGTZ,
ADDI, ADDIU, SLTI, SLTIU, ANDI, ORI, XORI, LUI,
COP0, COP1, COP2, Unknown, BEQL, BNEL, BLEZL, BGTZL,
DADDI, DADDIU, LDL, LDR, MMI, Unknown, LQ, SQ,
LB, LH, LWL, LW, LBU, LHU, LWR, LWU,
SB, SH, SWL, SW, SDL, SDR, SWR, CACHE,
Unknown, LWC1, Unknown, PREF, Unknown, Unknown, LQC2, LD,
Unknown, SWC1, Unknown, Unknown, Unknown, Unknown, SQC2, SD
};
static const OPCODE tbl_Special[64] =
{
SLL, Unknown, SRL, SRA, SLLV, Unknown, SRLV, SRAV,
JR, JALR, MOVZ, MOVN, SYSCALL, BREAK, Unknown, SYNC,
MFHI, MTHI, MFLO, MTLO, DSLLV, Unknown, DSRLV, DSRAV,
MULT, MULTU, DIV, DIVU, Unknown, Unknown, Unknown, Unknown,
ADD, ADDU, SUB, SUBU, AND, OR, XOR, NOR,
MFSA, MTSA, SLT, SLTU, DADD, DADDU, DSUB, DSUBU,
TGE, TGEU, TLT, TLTU, TEQ, Unknown, TNE, Unknown,
DSLL, Unknown, DSRL, DSRA, DSLL32, Unknown, DSRL32, DSRA32
};
static const OPCODE tbl_RegImm[32] = {
BLTZ, BGEZ, BLTZL, BGEZL, Unknown, Unknown, Unknown, Unknown,
TGEI, TGEIU, TLTI, TLTIU, TEQI, Unknown, TNEI, Unknown,
BLTZAL, BGEZAL, BLTZALL, BGEZALL, Unknown, Unknown, Unknown, Unknown,
MTSAB, MTSAH , Unknown, Unknown, Unknown, Unknown, Unknown, Unknown,
};
static const OPCODE tbl_MMI[64] =
{
MADD, MADDU, MMI_Unknown, MMI_Unknown, PLZCW, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MMI0, MMI2, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MFHI1, MTHI1, MFLO1, MTLO1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MULT1, MULTU1, DIV1, DIVU1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MADD1, MADDU1, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MMI1, MMI3, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMFHL, PMTHL, MMI_Unknown, MMI_Unknown, PSLLH, MMI_Unknown, PSRLH, PSRAH,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown, PSLLW, MMI_Unknown, PSRLW, PSRAW,
};
static const OPCODE tbl_MMI0[32] =
{
PADDW, PSUBW, PCGTW, PMAXW,
PADDH, PSUBH, PCGTH, PMAXH,
PADDB, PSUBB, PCGTB, MMI_Unknown,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PADDSW, PSUBSW, PEXTLW, PPACW,
PADDSH, PSUBSH, PEXTLH, PPACH,
PADDSB, PSUBSB, PEXTLB, PPACB,
MMI_Unknown, MMI_Unknown, PEXT5, PPAC5,
};
static const OPCODE tbl_MMI1[32] =
{
MMI_Unknown, PABSW, PCEQW, PMINW,
PADSBH, PABSH, PCEQH, PMINH,
MMI_Unknown, MMI_Unknown, PCEQB, MMI_Unknown,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PADDUW, PSUBUW, PEXTUW, MMI_Unknown,
PADDUH, PSUBUH, PEXTUH, MMI_Unknown,
PADDUB, PSUBUB, PEXTUB, QFSRV,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
};
static const OPCODE tbl_MMI2[32] =
{
PMADDW, MMI_Unknown, PSLLVW, PSRLVW,
PMSUBW, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMFHI, PMFLO, PINTH, MMI_Unknown,
PMULTW, PDIVW, PCPYLD, MMI_Unknown,
PMADDH, PHMADH, PAND, PXOR,
PMSUBH, PHMSBH, MMI_Unknown, MMI_Unknown,
MMI_Unknown, MMI_Unknown, PEXEH, PREVH,
PMULTH, PDIVBW, PEXEW, PROT3W,
};
static const OPCODE tbl_MMI3[32] =
{
PMADDUW, MMI_Unknown, MMI_Unknown, PSRAVW,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
PMTHI, PMTLO, PINTEH, MMI_Unknown,
PMULTUW, PDIVUW, PCPYUD, MMI_Unknown,
MMI_Unknown, MMI_Unknown, POR, PNOR,
MMI_Unknown, MMI_Unknown, MMI_Unknown, MMI_Unknown,
MMI_Unknown, MMI_Unknown, PEXCH, PCPYH,
MMI_Unknown, MMI_Unknown, PEXCW, MMI_Unknown,
};
static const OPCODE tbl_COP0[32] =
{
MFC0, COP0_Unknown, COP0_Unknown, COP0_Unknown, MTC0, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_BC0, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_C0, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
};
static const OPCODE tbl_COP0_BC0[32] =
{
BC0F, BC0T, BC0FL, BC0TL, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
};
static const OPCODE tbl_COP0_C0[64] =
{
COP0_Unknown, TLBR, TLBWI, COP0_Unknown, COP0_Unknown, COP0_Unknown, TLBWR, COP0_Unknown,
TLBP, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
ERET, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown,
EI, DI, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown, COP0_Unknown
};
static const OPCODE tbl_COP1[32] =
{
MFC1, COP1_Unknown, CFC1, COP1_Unknown, MTC1, COP1_Unknown, CTC1, COP1_Unknown,
COP1_BC1, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown,
COP1_S, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_W, COP1_Unknown, COP1_Unknown, COP1_Unknown,
COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown,
};
static const OPCODE tbl_COP1_BC1[32] =
{
BC1F, BC1T, BC1FL, BC1TL, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown,
COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown,
COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown,
COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown, COP1_Unknown,
};
static const OPCODE tbl_COP1_S[64] =
{
ADD_S, SUB_S, MUL_S, DIV_S, SQRT_S, ABS_S, MOV_S, NEG_S,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,RSQRT_S, COP1_Unknown,
ADDA_S, SUBA_S, MULA_S, COP1_Unknown,MADD_S, MSUB_S, MADDA_S, MSUBA_S,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,CVT_W, COP1_Unknown,COP1_Unknown,COP1_Unknown,
MAX_S, MIN_S, COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
C_F, COP1_Unknown,C_EQ, COP1_Unknown,C_LT, COP1_Unknown,C_LE, COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
};
static const OPCODE tbl_COP1_W[64] =
{
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
CVT_S, COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,COP1_Unknown,
};
} // end namespace R5900::OpcodeTables
namespace Opcodes
{
using namespace OpcodeTables;
2014-02-21 14:29:13 +00:00
const OPCODE& Class_SPECIAL(u32 op) { return tbl_Special[op & 0x3F]; }
const OPCODE& Class_REGIMM(u32 op) { return tbl_RegImm[(op >> 16) & 0x1F]; }
2014-02-21 14:29:13 +00:00
const OPCODE& Class_MMI(u32 op) { return tbl_MMI[op & 0x3F]; }
const OPCODE& Class_MMI0(u32 op) { return tbl_MMI0[(op >> 6) & 0x1F]; }
const OPCODE& Class_MMI1(u32 op) { return tbl_MMI1[(op >> 6) & 0x1F]; }
const OPCODE& Class_MMI2(u32 op) { return tbl_MMI2[(op >> 6) & 0x1F]; }
const OPCODE& Class_MMI3(u32 op) { return tbl_MMI3[(op >> 6) & 0x1F]; }
2014-02-21 14:29:13 +00:00
const OPCODE& Class_COP0(u32 op) { return tbl_COP0[(op >> 21) & 0x1F]; }
const OPCODE& Class_COP0_BC0(u32 op) { return tbl_COP0_BC0[(op >> 16) & 0x03]; }
2014-02-21 14:29:13 +00:00
const OPCODE& Class_COP0_C0(u32 op) { return tbl_COP0_C0[op & 0x3F]; }
2014-02-21 14:29:13 +00:00
const OPCODE& Class_COP1(u32 op) { return tbl_COP1[(op >> 21) & 0x1F]; }
const OPCODE& Class_COP1_BC1(u32 op) { return tbl_COP1_BC1[(op >> 16) & 0x1F]; }
const OPCODE& Class_COP1_S(u32 op) { return tbl_COP1_S[op & 0x3F]; }
const OPCODE& Class_COP1_W(u32 op) { return tbl_COP1_W[op & 0x3F]; }
// These are for future use when the COP2 tables are completed.
//const OPCODE& Class_COP2() { return tbl_COP2[_Rs_]; }
//const OPCODE& Class_COP2_BC2() { return tbl_COP2_BC2[_Rt_]; }
//const OPCODE& Class_COP2_SPECIAL() { return tbl_COP2_SPECIAL[_Funct_]; }
//const OPCODE& Class_COP2_SPECIAL2() { return tbl_COP2_SPECIAL2[(cpuRegs.code & 0x3) | ((cpuRegs.code >> 4) & 0x7c)]; }
}
} // end namespace R5900
void (*Int_COP2PrintTable[32])() = {
COP2_Unknown, QMFC2, CFC2, COP2_Unknown, COP2_Unknown, QMTC2, CTC2, COP2_Unknown,
COP2_BC2, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown,
COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL,
COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL, COP2_SPECIAL,
};
void (*Int_COP2BC2PrintTable[32])() = {
BC2F, BC2T, BC2FL, BC2TL, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown,
COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown,
COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown,
COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown, COP2_Unknown,
};
void (*Int_COP2SPECIAL1PrintTable[64])() =
{
VADDx, VADDy, VADDz, VADDw, VSUBx, VSUBy, VSUBz, VSUBw,
VMADDx, VMADDy, VMADDz, VMADDw, VMSUBx, VMSUBy, VMSUBz, VMSUBw,
VMAXx, VMAXy, VMAXz, VMAXw, VMINIx, VMINIy, VMINIz, VMINIw,
VMULx, VMULy, VMULz, VMULw, VMULq, VMAXi, VMULi, VMINIi,
VADDq, VMADDq, VADDi, VMADDi, VSUBq, VMSUBq, VSUBi, VMSUBi,
VADD, VMADD, VMUL, VMAX, VSUB, VMSUB, VOPMSUB, VMINI,
VIADD, VISUB, VIADDI, COP2_Unknown,VIAND, VIOR, COP2_Unknown, COP2_Unknown,
VCALLMS, VCALLMSR, COP2_Unknown,COP2_Unknown,COP2_SPECIAL2,COP2_SPECIAL2,COP2_SPECIAL2,COP2_SPECIAL2,
};
void (*Int_COP2SPECIAL2PrintTable[128])() =
{
VADDAx ,VADDAy ,VADDAz ,VADDAw ,VSUBAx ,VSUBAy ,VSUBAz ,VSUBAw,
VMADDAx ,VMADDAy ,VMADDAz ,VMADDAw ,VMSUBAx ,VMSUBAy ,VMSUBAz ,VMSUBAw,
VITOF0 ,VITOF4 ,VITOF12 ,VITOF15 ,VFTOI0 ,VFTOI4 ,VFTOI12 ,VFTOI15,
VMULAx ,VMULAy ,VMULAz ,VMULAw ,VMULAq ,VABS ,VMULAi ,VCLIPw,
VADDAq ,VMADDAq ,VADDAi ,VMADDAi ,VSUBAq ,VMSUBAq ,VSUBAi ,VMSUBAi,
VADDA ,VMADDA ,VMULA ,COP2_Unknown,VSUBA ,VMSUBA ,VOPMULA ,VNOP,
VMOVE ,VMR32 ,COP2_Unknown,COP2_Unknown,VLQI ,VSQI ,VLQD ,VSQD,
VDIV ,VSQRT ,VRSQRT ,VWAITQ ,VMTIR ,VMFIR ,VILWR ,VISWR,
VRNEXT ,VRGET ,VRINIT ,VRXOR ,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,COP2_Unknown,
};