mirror of
https://github.com/DaedalusX64/daedalus.git
synced 2025-04-02 10:21:48 -04:00
1166 lines
47 KiB
C++
1166 lines
47 KiB
C++
/*
|
|
Copyright (C) 2006 StrmnNrmn
|
|
|
|
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; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
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 for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
#include "Base/Types.h"
|
|
|
|
#include "DynaRec/StaticAnalysis.h"
|
|
|
|
#include "Core/R4300OpCode.h"
|
|
#include "Core/CPU.h"
|
|
#include "Core/ROM.h"
|
|
|
|
using namespace StaticAnalysis;
|
|
|
|
namespace
|
|
{
|
|
|
|
void RegFPRRead( u32 r [[maybe_unused]] ) {}
|
|
void RegFPRWrite( u32 r [[maybe_unused]]) {}
|
|
|
|
using StaticAnalysisFunction = void (*const) ( OpCode op_code, RegisterUsage & recorder );
|
|
|
|
|
|
|
|
// Forward declarations
|
|
void StaticAnalysis_Special( OpCode op_code, RegisterUsage & recorder );
|
|
void StaticAnalysis_RegImm( OpCode op_code, RegisterUsage & recorder );
|
|
void StaticAnalysis_CoPro0( OpCode op_code, RegisterUsage & recorder );
|
|
void StaticAnalysis_CoPro1( OpCode op_code, RegisterUsage & recorder );
|
|
void StaticAnalysis_Cop0_TLB( OpCode op_code, RegisterUsage & recorder );
|
|
void StaticAnalysis_Cop1_BCInstr( OpCode op_code, RegisterUsage & recorder );
|
|
void StaticAnalysis_Cop1_SInstr( OpCode op_code, RegisterUsage & recorder );
|
|
void StaticAnalysis_Cop1_DInstr( OpCode op_code, RegisterUsage & recorder );
|
|
|
|
void StaticAnalysis_Unk( OpCode op_code [[maybe_unused]], RegisterUsage & recorder[[maybe_unused]] )
|
|
{
|
|
}
|
|
|
|
// These are the only unimplemented R4300 instructions now:
|
|
void StaticAnalysis_LL( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]]) {}
|
|
void StaticAnalysis_LLD( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
|
|
void StaticAnalysis_SC( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
void StaticAnalysis_SCD( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
|
|
void StaticAnalysis_LDC2( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
void StaticAnalysis_SDC2( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
|
|
void StaticAnalysis_RegImm_TGEI( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
void StaticAnalysis_RegImm_TGEIU( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
void StaticAnalysis_RegImm_TLTI( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]]) {}
|
|
void StaticAnalysis_RegImm_TLTIU( OpCode op_code [[maybe_unused]] , RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
void StaticAnalysis_RegImm_TEQI( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
void StaticAnalysis_RegImm_TNEI( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
|
|
void StaticAnalysis_RegImm_BLTZALL( OpCode op_code [[maybe_unused]] , RegisterUsage & recorder [[maybe_unused]]) {}
|
|
void StaticAnalysis_RegImm_BGEZALL( OpCode op_code [[maybe_unused]] , RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
|
|
void StaticAnalysis_Special_TGE( OpCode op_code [[maybe_unused]] , RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
void StaticAnalysis_Special_TGEU( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
void StaticAnalysis_Special_TLT( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
void StaticAnalysis_Special_TLTU( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
void StaticAnalysis_Special_TEQ( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
void StaticAnalysis_Special_TNE( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) {}
|
|
|
|
|
|
void StaticAnalysis_J( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) // Jump
|
|
{
|
|
// No registers used
|
|
recorder.BranchOP( BT_J );
|
|
}
|
|
|
|
void StaticAnalysis_JAL( OpCode op_code [[maybe_unused]], RegisterUsage & recorder ) // Jump And Link
|
|
{
|
|
recorder.BranchOP( BT_JAL );
|
|
recorder.Record( RegDstUse( N64Reg_RA ) );
|
|
}
|
|
|
|
void StaticAnalysis_BEQ( OpCode op_code, RegisterUsage & recorder ) // Branch on Equal
|
|
{
|
|
recorder.BranchOP( BT_BEQ );
|
|
recorder.Record( RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_BNE( OpCode op_code, RegisterUsage & recorder ) // Branch on Not Equal
|
|
{
|
|
recorder.BranchOP( BT_BNE );
|
|
recorder.Record( RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_BLEZ( OpCode op_code, RegisterUsage & recorder ) // Branch on Less than of Equal to Zero
|
|
{
|
|
recorder.BranchOP( BT_BLEZ );
|
|
recorder.Record( RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_BGTZ( OpCode op_code, RegisterUsage & recorder ) // Branch on Greater than Zero
|
|
{
|
|
recorder.BranchOP( BT_BGTZ );
|
|
recorder.Record( RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_DADDI( OpCode op_code, RegisterUsage & recorder ) // Doubleword ADD Immediate
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rt ), RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_DADDIU( OpCode op_code, RegisterUsage & recorder ) // Doubleword ADD Immediate Unsigned
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rt ), RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_ADDI( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rt ), RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_ADDIU( OpCode op_code, RegisterUsage & recorder ) // Add Immediate Unsigned
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rt ), RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_SLTI( OpCode op_code, RegisterUsage & recorder ) // Set on Less Than Immediate
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rt ), RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_SLTIU( OpCode op_code, RegisterUsage & recorder ) // Set on Less Than Immediate Unsigned
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rt ), RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_ANDI( OpCode op_code, RegisterUsage & recorder ) // AND Immediate
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rt ), RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_ORI( OpCode op_code, RegisterUsage & recorder ) // OR Immediate
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rt ), RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_XORI( OpCode op_code, RegisterUsage & recorder ) // XOR Immediate
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rt ), RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_LUI( OpCode op_code, RegisterUsage & recorder ) // Load Upper Immediate
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rt ), RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_BEQL( OpCode op_code, RegisterUsage & recorder ) // Branch on Equal Likely
|
|
{
|
|
recorder.BranchOP( BT_BEQL );
|
|
recorder.Record( RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_BNEL( OpCode op_code, RegisterUsage & recorder ) // Branch on Not Equal Likely
|
|
{
|
|
recorder.BranchOP( BT_BNEL );
|
|
recorder.Record( RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_BLEZL( OpCode op_code, RegisterUsage & recorder ) // Branch on Less than or Equal to Zero Likely
|
|
{
|
|
recorder.BranchOP( BT_BLEZL );
|
|
recorder.Record( RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_BGTZL( OpCode op_code, RegisterUsage & recorder ) // Branch on Greater than Zero Likely
|
|
{
|
|
recorder.BranchOP( BT_BGTZL );
|
|
recorder.Record( RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_LB( OpCode op_code, RegisterUsage & recorder ) // Load Byte
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegDstUse( op_code.rt ) );
|
|
//Should be safe to skip adding "op_code.offset" to check for inrage in RDRAM //Corn
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 + op_code.offset );
|
|
}
|
|
|
|
void StaticAnalysis_LBU( OpCode op_code, RegisterUsage & recorder ) // Load Byte Unsigned -- Zero extend byte...
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegDstUse( op_code.rt ) );
|
|
//Should be safe to skip adding "op_code.offset" to check for inrage in RDRAM //Corn
|
|
if( !g_ROM.DISABLE_LBU_OPT ) recorder.Access( gCPUState.CPU[op_code.base]._u32_0 ); //PD and Banjo dont like this
|
|
}
|
|
|
|
void StaticAnalysis_LH( OpCode op_code, RegisterUsage & recorder ) // Load Halfword
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegDstUse( op_code.rt ) );
|
|
//Should be safe to skip adding "op_code.offset" to check for inrage in RDRAM //Corn
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_LHU( OpCode op_code, RegisterUsage & recorder ) // Load Halfword Unsigned -- Zero extend word
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegDstUse( op_code.rt ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_LWL( OpCode op_code, RegisterUsage & recorder ) // Load Word Left
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegDstUse( op_code.rt ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_LDL( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegDstUse( op_code.rt ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_LWR( OpCode op_code, RegisterUsage & recorder ) // Load Word Right
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegDstUse( op_code.rt ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_LDR( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegDstUse( op_code.rt ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_LW( OpCode op_code, RegisterUsage & recorder ) // Load Word
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegDstUse( op_code.rt ) );
|
|
|
|
// Causes P Mario to BSOD in intro, doesn't happen anymore //Salvy
|
|
//Should be safe to skip adding "op_code.offset" to check for inrage in RDRAM //Corn
|
|
if( g_ROM.GameHacks != PMARIO ) recorder.Access( gCPUState.CPU[op_code.base]._u32_0 ); // Breaks Paper Mario
|
|
}
|
|
|
|
void StaticAnalysis_LWU( OpCode op_code, RegisterUsage & recorder ) // Load Word Unsigned
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegDstUse( op_code.rt ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_LD( OpCode op_code, RegisterUsage & recorder ) // Load Doubleword
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegDstUse( op_code.rt ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_SW( OpCode op_code, RegisterUsage & recorder ) // Store Word
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegSrcUse( op_code.rt ) );
|
|
//Should be safe to skip adding "op_code.offset" to check for inrage in RDRAM //Corn
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_SH( OpCode op_code, RegisterUsage & recorder ) // Store Halfword
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegSrcUse( op_code.rt ) );
|
|
|
|
// Causes Zelda MM to BSOD when you enter clock town
|
|
if( g_ROM.GameHacks != ZELDA_MM ) recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_SB( OpCode op_code, RegisterUsage & recorder ) // Store Byte
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegSrcUse( op_code.rt ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_SWL( OpCode op_code, RegisterUsage & recorder ) // Store Word Left
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegSrcUse( op_code.rt ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_SWR( OpCode op_code, RegisterUsage & recorder ) // Store Word Right
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegSrcUse( op_code.rt ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_SD( OpCode op_code, RegisterUsage & recorder ) // Store Doubleword
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegSrcUse( op_code.rt ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_SDL( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegSrcUse( op_code.rt ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_SDR( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ), RegSrcUse( op_code.rt ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_CACHE( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegBaseUse( op_code.base ) );
|
|
}
|
|
|
|
void StaticAnalysis_LWC1( OpCode op_code, RegisterUsage & recorder ) // Load Word to Copro 1 (FPU)
|
|
{
|
|
RegFPRWrite( op_code.ft );
|
|
recorder.Record( RegBaseUse( op_code.base ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_LDC1( OpCode op_code, RegisterUsage & recorder ) // Load Doubleword to Copro 1 (FPU)
|
|
{
|
|
RegFPRWrite( op_code.ft );
|
|
recorder.Record( RegBaseUse( op_code.base ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_SWC1( OpCode op_code, RegisterUsage & recorder ) // Store Word From Copro 1
|
|
{
|
|
RegFPRRead( op_code.ft );
|
|
recorder.Record( RegBaseUse( op_code.base ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_SDC1( OpCode op_code, RegisterUsage & recorder ) // Store Doubleword From Copro 1
|
|
{
|
|
RegFPRRead( op_code.ft );
|
|
recorder.Record( RegBaseUse( op_code.base ) );
|
|
recorder.Access( gCPUState.CPU[op_code.base]._u32_0 );
|
|
}
|
|
|
|
void StaticAnalysis_Special_Unk( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
// Just ignore
|
|
}
|
|
|
|
void StaticAnalysis_Special_SLL( OpCode op_code, RegisterUsage & recorder ) // Shift word Left Logical
|
|
{
|
|
if (op_code._u32 == 0)
|
|
return;
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_SRL( OpCode op_code, RegisterUsage & recorder ) // Shift word Right Logical
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_SRA( OpCode op_code, RegisterUsage & recorder ) // Shift word Right Arithmetic
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_SLLV( OpCode op_code, RegisterUsage & recorder ) // Shift word Left Logical Variable
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_SRLV( OpCode op_code, RegisterUsage & recorder ) // Shift word Right Logical Variable
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_SRAV( OpCode op_code, RegisterUsage & recorder ) // Shift word Right Arithmetic Variable
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_JR( OpCode op_code, RegisterUsage & recorder ) // Jump Register
|
|
{
|
|
recorder.BranchOP( BT_JR );
|
|
recorder.Record( RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_JALR( OpCode op_code, RegisterUsage & recorder ) // Jump and Link register
|
|
{
|
|
recorder.BranchOP( BT_JALR );
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_SYSCALL( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
}
|
|
|
|
void StaticAnalysis_Special_BREAK( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) // BREAK
|
|
{
|
|
}
|
|
|
|
void StaticAnalysis_Special_SYNC( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
}
|
|
|
|
void StaticAnalysis_Special_MFHI( OpCode op_code, RegisterUsage & recorder ) // Move From MultHI
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_MTHI( OpCode op_code, RegisterUsage & recorder ) // Move To MultHI
|
|
{
|
|
recorder.Record( RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_MFLO( OpCode op_code, RegisterUsage & recorder ) // Move From MultLO
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_MTLO( OpCode op_code, RegisterUsage & recorder ) // Move To MultLO
|
|
{
|
|
recorder.Record( RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DSLLV( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DSRLV( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DSRAV( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_MULT( OpCode op_code, RegisterUsage & recorder ) // MULTiply Signed
|
|
{
|
|
recorder.Record( RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_MULTU( OpCode op_code, RegisterUsage & recorder ) // MULTiply Unsigned
|
|
{
|
|
recorder.Record( RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DIV( OpCode op_code, RegisterUsage & recorder ) //DIVide
|
|
{
|
|
recorder.Record( RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DIVU( OpCode op_code, RegisterUsage & recorder ) // DIVide Unsigned
|
|
{
|
|
recorder.Record( RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DMULT( OpCode op_code, RegisterUsage & recorder ) // Double Multiply
|
|
{
|
|
recorder.Record( RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DMULTU( OpCode op_code, RegisterUsage & recorder ) // Double Multiply Unsigned
|
|
{
|
|
recorder.Record( RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DDIV( OpCode op_code, RegisterUsage & recorder ) // Double Divide
|
|
{
|
|
recorder.Record( RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DDIVU( OpCode op_code, RegisterUsage & recorder ) // Double Divide Unsigned
|
|
{
|
|
recorder.Record( RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_ADD( OpCode op_code, RegisterUsage & recorder ) // ADD signed - may throw exception
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_ADDU( OpCode op_code, RegisterUsage & recorder ) // ADD Unsigned - doesn't throw exception
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_SUB( OpCode op_code, RegisterUsage & recorder ) // SUB Signed - may throw exception
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_SUBU( OpCode op_code, RegisterUsage & recorder ) // SUB Unsigned - doesn't throw exception
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_AND( OpCode op_code, RegisterUsage & recorder ) // logical AND
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_OR( OpCode op_code, RegisterUsage & recorder ) // logical OR
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_XOR( OpCode op_code, RegisterUsage & recorder ) // logical XOR
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_NOR( OpCode op_code, RegisterUsage & recorder ) // logical Not OR
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_SLT( OpCode op_code, RegisterUsage & recorder ) // Set on Less Than
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_SLTU( OpCode op_code, RegisterUsage & recorder ) // Set on Less Than Unsigned
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DADD( OpCode op_code, RegisterUsage & recorder )//CYRUS64
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DADDU( OpCode op_code, RegisterUsage & recorder )//CYRUS64
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DSUB( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DSUBU( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rs ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DSLL( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DSRL( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DSRA( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DSLL32( OpCode op_code, RegisterUsage & recorder ) // Double Shift Left Logical 32
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DSRL32( OpCode op_code, RegisterUsage & recorder ) // Double Shift Right Logical 32
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Special_DSRA32( OpCode op_code, RegisterUsage & recorder ) // Double Shift Right Arithmetic 32
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rd ), RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_RegImm_BLTZ( OpCode op_code, RegisterUsage & recorder ) // Branch on Less than Zero
|
|
{
|
|
recorder.BranchOP( BT_BLTZ );
|
|
recorder.Record( RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_RegImm_BLTZL( OpCode op_code, RegisterUsage & recorder ) // Branch on Less than Zero Likely
|
|
{
|
|
recorder.BranchOP( BT_BLTZL );
|
|
recorder.Record( RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_RegImm_BLTZAL( OpCode op_code, RegisterUsage & recorder ) // Branch on Less than Zero And Link
|
|
{
|
|
recorder.BranchOP( BT_BLTZAL );
|
|
recorder.Record( RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_RegImm_BGEZ( OpCode op_code, RegisterUsage & recorder ) // Branch on Greater than or Equal to Zero
|
|
{
|
|
recorder.BranchOP( BT_BGEZ );
|
|
recorder.Record( RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_RegImm_BGEZL( OpCode op_code, RegisterUsage & recorder ) // Branch on Greater than or Equal to Zero Likely
|
|
{
|
|
recorder.BranchOP( BT_BGEZL );
|
|
recorder.Record( RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_RegImm_BGEZAL( OpCode op_code, RegisterUsage & recorder ) // Branch on Greater than or Equal to Zero And Link
|
|
{
|
|
recorder.BranchOP( BT_BGEZAL );
|
|
recorder.Record( RegSrcUse( op_code.rs ) );
|
|
}
|
|
|
|
void StaticAnalysis_Cop0_MFC0( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rt ) );
|
|
}
|
|
|
|
// Move Word To CopReg
|
|
void StaticAnalysis_Cop0_MTC0( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
recorder.Record( RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_TLB_TLBR( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) // TLB Read
|
|
{
|
|
}
|
|
|
|
void StaticAnalysis_TLB_TLBWI( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) // TLB Write Index
|
|
{
|
|
}
|
|
|
|
void StaticAnalysis_TLB_TLBWR( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
}
|
|
|
|
void StaticAnalysis_TLB_TLBP( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]]) // TLB Probe
|
|
{
|
|
}
|
|
|
|
void StaticAnalysis_TLB_ERET( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
recorder.BranchOP( BT_ERET );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_MTC1( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
RegFPRWrite( op_code.fs );
|
|
recorder.Record( RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_DMTC1( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
RegFPRWrite( op_code.fs );
|
|
recorder.Record( RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_MFC1( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
RegFPRRead( op_code.fs );
|
|
recorder.Record( RegDstUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_DMFC1( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
RegFPRRead( op_code.fs );
|
|
recorder.Record( RegDstUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_CFC1( OpCode op_code, RegisterUsage & recorder ) // move Control word From Copro 1
|
|
{
|
|
recorder.Record( RegDstUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_CTC1( OpCode op_code, RegisterUsage & recorder ) // move Control word To Copro 1
|
|
{
|
|
recorder.Record( RegSrcUse( op_code.rt ) );
|
|
}
|
|
|
|
void StaticAnalysis_BC1_BC1F( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) // Branch on FPU False
|
|
{
|
|
recorder.BranchOP( BT_BC1F );
|
|
}
|
|
|
|
void StaticAnalysis_BC1_BC1T( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) // Branch on FPU True
|
|
{
|
|
recorder.BranchOP( BT_BC1T );
|
|
}
|
|
|
|
void StaticAnalysis_BC1_BC1FL( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) // Branch on FPU False Likely
|
|
{
|
|
recorder.BranchOP( BT_BC1FL );
|
|
}
|
|
|
|
void StaticAnalysis_BC1_BC1TL( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]] ) // Branch on FPU True Likely
|
|
{
|
|
recorder.BranchOP( BT_BC1TL );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_W_CVT_S( OpCode op_code [[maybe_unused]], RegisterUsage & recorder [[maybe_unused]])
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_W_CVT_D( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_WInstr( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
switch ( op_code.cop1_funct )
|
|
{
|
|
case Cop1OpFunc_CVT_S:
|
|
StaticAnalysis_Cop1_W_CVT_S( op_code, recorder );
|
|
return;
|
|
case Cop1OpFunc_CVT_D:
|
|
StaticAnalysis_Cop1_W_CVT_D( op_code, recorder );
|
|
return;
|
|
}
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_L_CVT_S( OpCode op_code, RegisterUsage & recorder [[maybe_unused]])
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_L_CVT_D( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_LInstr( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
switch ( op_code.cop1_funct )
|
|
{
|
|
case Cop1OpFunc_CVT_S:
|
|
StaticAnalysis_Cop1_L_CVT_S( op_code, recorder );
|
|
return;
|
|
case Cop1OpFunc_CVT_D:
|
|
StaticAnalysis_Cop1_L_CVT_D( op_code, recorder );
|
|
return;
|
|
}
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_ADD( OpCode op_code, RegisterUsage & recorder [[maybe_unused]])
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
RegFPRRead( op_code.ft );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_SUB( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
RegFPRRead( op_code.ft );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_MUL( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
RegFPRRead( op_code.ft );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_DIV( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
RegFPRRead( op_code.ft );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_SQRT( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_NEG( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_MOV( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_ABS( OpCode op_code, RegisterUsage & recorder [[maybe_unused]])
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_TRUNC_W( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_TRUNC_L( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_ROUND_W( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_ROUND_L( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_CEIL_W( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_CEIL_L( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_FLOOR_W( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_FLOOR_L( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_CVT_L( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_CVT_W( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_S_CVT_D( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
// FIXME: this is not referenced anywhere
|
|
//void StaticAnalysis_Cop1_S_EQ( OpCode op_code, RegisterUsage & recorder ) // Compare for Equality
|
|
//{
|
|
// RegFPRRead( op_code.fs );
|
|
// RegFPRRead( op_code.ft );
|
|
//}
|
|
|
|
// FIXME: this is not referenced anywhere
|
|
//void StaticAnalysis_Cop1_S_LT( OpCode op_code, RegisterUsage & recorder ) // Compare for Equality
|
|
//{
|
|
// RegFPRRead( op_code.fs );
|
|
// RegFPRRead( op_code.ft );
|
|
//}
|
|
|
|
void StaticAnalysis_Cop1_Compare_S( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRRead( op_code.fs );
|
|
RegFPRRead( op_code.ft );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_ADD( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
RegFPRRead( op_code.ft );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_SUB( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
RegFPRRead( op_code.ft );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_MUL( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
RegFPRRead( op_code.ft );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_DIV( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
RegFPRRead( op_code.ft );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_ABS( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_SQRT( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_NEG( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_MOV( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_TRUNC_W( OpCode op_code, RegisterUsage & recorder [[maybe_unused]])
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_TRUNC_L( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_ROUND_W( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_ROUND_L( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_CEIL_W( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_CEIL_L( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_FLOOR_W( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_FLOOR_L( OpCode op_code, RegisterUsage & recorder [[maybe_unused]])
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_CVT_S( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_CVT_W( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_D_CVT_L( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRWrite( op_code.fd );
|
|
RegFPRRead( op_code.fs );
|
|
}
|
|
|
|
void StaticAnalysis_Cop1_Compare_D( OpCode op_code, RegisterUsage & recorder [[maybe_unused]] )
|
|
{
|
|
RegFPRRead( op_code.fs );
|
|
RegFPRRead( op_code.ft );
|
|
}
|
|
|
|
// Opcode Jump Table
|
|
const StaticAnalysisFunction gStaticAnalysisInstruction[64] =
|
|
{
|
|
StaticAnalysis_Special, StaticAnalysis_RegImm, StaticAnalysis_J, StaticAnalysis_JAL, StaticAnalysis_BEQ, StaticAnalysis_BNE, StaticAnalysis_BLEZ, StaticAnalysis_BGTZ,
|
|
StaticAnalysis_ADDI, StaticAnalysis_ADDIU, StaticAnalysis_SLTI, StaticAnalysis_SLTIU, StaticAnalysis_ANDI, StaticAnalysis_ORI, StaticAnalysis_XORI, StaticAnalysis_LUI,
|
|
StaticAnalysis_CoPro0, StaticAnalysis_CoPro1, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_BEQL, StaticAnalysis_BNEL, StaticAnalysis_BLEZL, StaticAnalysis_BGTZL,
|
|
StaticAnalysis_DADDI, StaticAnalysis_DADDIU, StaticAnalysis_LDL, StaticAnalysis_LDR, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_LB, StaticAnalysis_LH, StaticAnalysis_LWL, StaticAnalysis_LW, StaticAnalysis_LBU, StaticAnalysis_LHU, StaticAnalysis_LWR, StaticAnalysis_LWU,
|
|
StaticAnalysis_SB, StaticAnalysis_SH, StaticAnalysis_SWL, StaticAnalysis_SW, StaticAnalysis_SDL, StaticAnalysis_SDR, StaticAnalysis_SWR, StaticAnalysis_CACHE,
|
|
StaticAnalysis_LL, StaticAnalysis_LWC1, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_LLD, StaticAnalysis_LDC1, StaticAnalysis_LDC2, StaticAnalysis_LD,
|
|
StaticAnalysis_SC, StaticAnalysis_SWC1, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_SCD, StaticAnalysis_SDC1, StaticAnalysis_SDC2, StaticAnalysis_SD
|
|
};
|
|
|
|
// SpecialOpCode Jump Table
|
|
const StaticAnalysisFunction gStaticAnalysisSpecialInstruction[64] =
|
|
{
|
|
StaticAnalysis_Special_SLL, StaticAnalysis_Special_Unk, StaticAnalysis_Special_SRL, StaticAnalysis_Special_SRA, StaticAnalysis_Special_SLLV, StaticAnalysis_Special_Unk, StaticAnalysis_Special_SRLV, StaticAnalysis_Special_SRAV,
|
|
StaticAnalysis_Special_JR, StaticAnalysis_Special_JALR, StaticAnalysis_Special_Unk, StaticAnalysis_Special_Unk, StaticAnalysis_Special_SYSCALL, StaticAnalysis_Special_BREAK, StaticAnalysis_Special_Unk, StaticAnalysis_Special_SYNC,
|
|
StaticAnalysis_Special_MFHI, StaticAnalysis_Special_MTHI, StaticAnalysis_Special_MFLO, StaticAnalysis_Special_MTLO, StaticAnalysis_Special_DSLLV, StaticAnalysis_Special_Unk, StaticAnalysis_Special_DSRLV, StaticAnalysis_Special_DSRAV,
|
|
StaticAnalysis_Special_MULT, StaticAnalysis_Special_MULTU, StaticAnalysis_Special_DIV, StaticAnalysis_Special_DIVU, StaticAnalysis_Special_DMULT, StaticAnalysis_Special_DMULTU, StaticAnalysis_Special_DDIV, StaticAnalysis_Special_DDIVU,
|
|
StaticAnalysis_Special_ADD, StaticAnalysis_Special_ADDU, StaticAnalysis_Special_SUB, StaticAnalysis_Special_SUBU, StaticAnalysis_Special_AND, StaticAnalysis_Special_OR, StaticAnalysis_Special_XOR, StaticAnalysis_Special_NOR,
|
|
StaticAnalysis_Special_Unk, StaticAnalysis_Special_Unk, StaticAnalysis_Special_SLT, StaticAnalysis_Special_SLTU, StaticAnalysis_Special_DADD, StaticAnalysis_Special_DADDU, StaticAnalysis_Special_DSUB, StaticAnalysis_Special_DSUBU,
|
|
StaticAnalysis_Special_TGE, StaticAnalysis_Special_TGEU, StaticAnalysis_Special_TLT, StaticAnalysis_Special_TLTU, StaticAnalysis_Special_TEQ, StaticAnalysis_Special_Unk, StaticAnalysis_Special_TNE, StaticAnalysis_Special_Unk,
|
|
StaticAnalysis_Special_DSLL, StaticAnalysis_Special_Unk, StaticAnalysis_Special_DSRL, StaticAnalysis_Special_DSRA, StaticAnalysis_Special_DSLL32, StaticAnalysis_Special_Unk, StaticAnalysis_Special_DSRL32, StaticAnalysis_Special_DSRA32
|
|
};
|
|
|
|
void StaticAnalysis_Special( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
gStaticAnalysisSpecialInstruction[ op_code.spec_op ]( op_code, recorder );
|
|
}
|
|
|
|
const StaticAnalysisFunction gStaticAnalysisRegImmInstruction[32] =
|
|
{
|
|
StaticAnalysis_RegImm_BLTZ, StaticAnalysis_RegImm_BGEZ, StaticAnalysis_RegImm_BLTZL, StaticAnalysis_RegImm_BGEZL, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_RegImm_TGEI, StaticAnalysis_RegImm_TGEIU, StaticAnalysis_RegImm_TLTI, StaticAnalysis_RegImm_TLTIU, StaticAnalysis_RegImm_TEQI, StaticAnalysis_Unk, StaticAnalysis_RegImm_TNEI, StaticAnalysis_Unk,
|
|
StaticAnalysis_RegImm_BLTZAL, StaticAnalysis_RegImm_BGEZAL, StaticAnalysis_RegImm_BLTZALL, StaticAnalysis_RegImm_BGEZALL, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk
|
|
};
|
|
|
|
void StaticAnalysis_RegImm( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
gStaticAnalysisRegImmInstruction[ op_code.regimm_op ]( op_code, recorder );
|
|
}
|
|
|
|
// COP0 Jump Table
|
|
const StaticAnalysisFunction gStaticAnalysisCop0Instruction[32] =
|
|
{
|
|
StaticAnalysis_Cop0_MFC0, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Cop0_MTC0, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Cop0_TLB, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
};
|
|
|
|
void StaticAnalysis_CoPro0( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
gStaticAnalysisCop0Instruction[ op_code.cop0_op ]( op_code, recorder );
|
|
}
|
|
|
|
// TLBOpCode Jump Table
|
|
const StaticAnalysisFunction gStaticAnalysisTLBInstruction[64] =
|
|
{
|
|
StaticAnalysis_Unk, StaticAnalysis_TLB_TLBR, StaticAnalysis_TLB_TLBWI, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_TLB_TLBWR, StaticAnalysis_Unk,
|
|
StaticAnalysis_TLB_TLBP, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_TLB_ERET, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
};
|
|
|
|
void StaticAnalysis_Cop0_TLB( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
gStaticAnalysisTLBInstruction[ op_code.cop0tlb_funct ]( op_code, recorder );
|
|
}
|
|
|
|
// COP1 Jump Table
|
|
const StaticAnalysisFunction gStaticAnalysisCop1Instruction[32] =
|
|
{
|
|
StaticAnalysis_Cop1_MFC1, StaticAnalysis_Cop1_DMFC1, StaticAnalysis_Cop1_CFC1, StaticAnalysis_Unk, StaticAnalysis_Cop1_MTC1, StaticAnalysis_Cop1_DMTC1, StaticAnalysis_Cop1_CTC1, StaticAnalysis_Unk,
|
|
StaticAnalysis_Cop1_BCInstr, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Cop1_SInstr, StaticAnalysis_Cop1_DInstr, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Cop1_WInstr, StaticAnalysis_Cop1_LInstr, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk
|
|
};
|
|
|
|
void StaticAnalysis_CoPro1( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
gStaticAnalysisCop1Instruction[ op_code.cop1_op ]( op_code, recorder );
|
|
}
|
|
|
|
const StaticAnalysisFunction gStaticAnalysisCop1BC1Instruction[4] =
|
|
{
|
|
StaticAnalysis_BC1_BC1F, StaticAnalysis_BC1_BC1T, StaticAnalysis_BC1_BC1FL, StaticAnalysis_BC1_BC1TL
|
|
};
|
|
|
|
void StaticAnalysis_Cop1_BCInstr( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
gStaticAnalysisCop1BC1Instruction[ op_code.cop1_bc ]( op_code, recorder );
|
|
}
|
|
|
|
// Single Jump Table
|
|
const StaticAnalysisFunction gStaticAnalysisCop1SInstruction[64] =
|
|
{
|
|
StaticAnalysis_Cop1_S_ADD, StaticAnalysis_Cop1_S_SUB, StaticAnalysis_Cop1_S_MUL, StaticAnalysis_Cop1_S_DIV, StaticAnalysis_Cop1_S_SQRT, StaticAnalysis_Cop1_S_ABS, StaticAnalysis_Cop1_S_MOV, StaticAnalysis_Cop1_S_NEG,
|
|
StaticAnalysis_Cop1_S_ROUND_L, StaticAnalysis_Cop1_S_TRUNC_L, StaticAnalysis_Cop1_S_CEIL_L, StaticAnalysis_Cop1_S_FLOOR_L, StaticAnalysis_Cop1_S_ROUND_W, StaticAnalysis_Cop1_S_TRUNC_W, StaticAnalysis_Cop1_S_CEIL_W, StaticAnalysis_Cop1_S_FLOOR_W,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Cop1_S_CVT_D, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Cop1_S_CVT_W, StaticAnalysis_Cop1_S_CVT_L, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S,
|
|
StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S, StaticAnalysis_Cop1_Compare_S,
|
|
};
|
|
|
|
void StaticAnalysis_Cop1_SInstr( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
gStaticAnalysisCop1SInstruction[ op_code.cop1_funct ]( op_code, recorder );
|
|
}
|
|
|
|
// Double Jump Table
|
|
const StaticAnalysisFunction gStaticAnalysisCop1DInstruction[64] =
|
|
{
|
|
StaticAnalysis_Cop1_D_ADD, StaticAnalysis_Cop1_D_SUB, StaticAnalysis_Cop1_D_MUL, StaticAnalysis_Cop1_D_DIV, StaticAnalysis_Cop1_D_SQRT, StaticAnalysis_Cop1_D_ABS, StaticAnalysis_Cop1_D_MOV, StaticAnalysis_Cop1_D_NEG,
|
|
StaticAnalysis_Cop1_D_ROUND_L, StaticAnalysis_Cop1_D_TRUNC_L, StaticAnalysis_Cop1_D_CEIL_L, StaticAnalysis_Cop1_D_FLOOR_L, StaticAnalysis_Cop1_D_ROUND_W, StaticAnalysis_Cop1_D_TRUNC_W, StaticAnalysis_Cop1_D_CEIL_W, StaticAnalysis_Cop1_D_FLOOR_W,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Cop1_D_CVT_S, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Cop1_D_CVT_W, StaticAnalysis_Cop1_D_CVT_L, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk, StaticAnalysis_Unk,
|
|
StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D,
|
|
StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D, StaticAnalysis_Cop1_Compare_D,
|
|
};
|
|
|
|
void StaticAnalysis_Cop1_DInstr( OpCode op_code, RegisterUsage & recorder )
|
|
{
|
|
gStaticAnalysisCop1DInstruction[ op_code.cop1_funct ]( op_code, recorder );
|
|
}
|
|
|
|
}
|
|
|
|
namespace StaticAnalysis
|
|
{
|
|
|
|
void Analyse( OpCode op_code, RegisterUsage & reg_usage )
|
|
{
|
|
reg_usage.BranchOP( BT_NOT_BRANCH );
|
|
gStaticAnalysisInstruction[ op_code.op ]( op_code, reg_usage );
|
|
}
|
|
|
|
}
|