2012-12-19 09:30:18 +00:00
/****************************************************************************
* *
* Project 64 - A Nintendo 64 emulator . *
* http : //www.pj64-emu.com/ *
* Copyright ( C ) 2012 Project64 . All rights reserved . *
* *
* License : *
* GNU / GPLv2 http : //www.gnu.org/licenses/gpl-2.0.html *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-05-25 09:15:19 +00:00
# include "stdafx.h"
2010-05-30 01:54:42 +00:00
CCodeSection * CRecompilerOps : : m_Section = NULL ;
2015-04-28 22:19:02 +00:00
CRegInfo CRecompilerOps : : m_RegWorkingSet ;
2010-05-30 01:54:42 +00:00
STEP_TYPE CRecompilerOps : : m_NextInstruction ;
DWORD CRecompilerOps : : m_CompilePC ;
OPCODE CRecompilerOps : : m_Opcode ;
2010-06-04 06:25:07 +00:00
DWORD CRecompilerOps : : m_BranchCompare = 0 ;
2010-05-30 01:54:42 +00:00
2012-10-25 08:38:58 +00:00
void CRecompilerOps : : CompileReadTLBMiss ( DWORD VirtualAddress , x86Reg LookUpReg )
{
2012-11-17 10:50:11 +00:00
MoveConstToVariable ( VirtualAddress , g_TLBLoadAddress , " TLBLoadAddress " ) ;
2012-10-25 08:38:58 +00:00
TestX86RegToX86Reg ( LookUpReg , LookUpReg ) ;
2015-05-02 22:14:19 +00:00
m_Section - > CompileExit ( m_CompilePC , m_CompilePC , m_RegWorkingSet , CExitInfo : : TLBReadMiss , false , JeLabel32 ) ;
2012-10-25 08:38:58 +00:00
}
2012-09-29 07:58:16 +00:00
void CRecompilerOps : : CompileReadTLBMiss ( x86Reg AddressReg , x86Reg LookUpReg )
2010-05-30 01:54:42 +00:00
{
2012-11-17 10:50:11 +00:00
MoveX86regToVariable ( AddressReg , g_TLBLoadAddress , " TLBLoadAddress " ) ;
2010-05-25 09:15:19 +00:00
TestX86RegToX86Reg ( LookUpReg , LookUpReg ) ;
2015-05-02 22:14:19 +00:00
m_Section - > CompileExit ( m_CompilePC , m_CompilePC , m_RegWorkingSet , CExitInfo : : TLBReadMiss , false , JeLabel32 ) ;
2010-05-25 09:15:19 +00:00
}
2012-09-29 07:58:16 +00:00
void CRecompilerOps : : CompileWriteTLBMiss ( x86Reg AddressReg , x86Reg LookUpReg )
2010-05-25 09:15:19 +00:00
{
2012-11-17 10:50:11 +00:00
MoveX86regToVariable ( AddressReg , & g_TLBStoreAddress , " g_TLBStoreAddress " ) ;
2010-05-25 09:15:19 +00:00
TestX86RegToX86Reg ( LookUpReg , LookUpReg ) ;
2015-05-02 22:14:19 +00:00
m_Section - > CompileExit ( m_CompilePC , m_CompilePC , m_RegWorkingSet , CExitInfo : : TLBWriteMiss , false , JeLabel32 ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
2012-10-22 10:36:57 +00:00
bool DelaySlotEffectsCompare ( DWORD PC , DWORD Reg1 , DWORD Reg2 ) ;
2010-05-30 01:54:42 +00:00
2010-05-25 09:15:19 +00:00
/************************** Branch functions ************************/
2015-05-02 22:14:19 +00:00
void CRecompilerOps : : Compile_Branch ( CRecompilerOps : : BranchFunction CompareFunc , BRANCH_TYPE BranchType , bool Link )
2010-05-25 09:15:19 +00:00
{
static CRegInfo RegBeforeDelay ;
2012-10-22 10:36:57 +00:00
static bool EffectDelaySlot ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
if ( m_NextInstruction = = NORMAL ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2012-10-22 08:02:53 +00:00
if ( m_CompilePC + ( ( short ) m_Opcode . offset < < 2 ) + 4 = = m_CompilePC + 8 )
2015-05-02 22:14:19 +00:00
return ;
2012-10-22 08:02:53 +00:00
2012-09-25 05:58:06 +00:00
if ( ( m_CompilePC & 0xFFC ) ! = 0xFFC )
{
2010-05-25 09:15:19 +00:00
switch ( BranchType ) {
2010-05-30 01:54:42 +00:00
case BranchTypeRs : EffectDelaySlot = DelaySlotEffectsCompare ( m_CompilePC , m_Opcode . rs , 0 ) ; break ;
case BranchTypeRsRt : EffectDelaySlot = DelaySlotEffectsCompare ( m_CompilePC , m_Opcode . rs , m_Opcode . rt ) ; break ;
2010-05-25 09:15:19 +00:00
case BranchTypeCop1 :
{
OPCODE Command ;
2012-11-17 01:18:00 +00:00
if ( ! g_MMU - > LW_VAddr ( m_CompilePC + 4 , Command . Hex ) ) {
2012-11-17 00:58:31 +00:00
g_Notify - > DisplayError ( GS ( MSG_FAIL_LOAD_WORD ) ) ;
2010-05-25 09:15:19 +00:00
ExitThread ( 0 ) ;
}
2015-05-02 22:14:19 +00:00
EffectDelaySlot = false ;
2010-05-25 09:15:19 +00:00
if ( Command . op = = R4300i_CP1 ) {
2015-05-02 22:14:19 +00:00
if ( Command . fmt = = R4300i_COP1_S & & ( Command . funct & 0x30 ) = = 0x30 )
EffectDelaySlot = true ;
if ( Command . fmt = = R4300i_COP1_D & & ( Command . funct & 0x30 ) = = 0x30 )
EffectDelaySlot = true ;
2010-05-25 09:15:19 +00:00
}
}
break ;
default :
2015-03-04 09:36:08 +00:00
if ( bHaveDebugger ( ) ) { g_Notify - > DisplayError ( L " Unknown branch type " ) ; }
2010-05-25 09:15:19 +00:00
}
} else {
2012-09-25 05:58:06 +00:00
EffectDelaySlot = true ;
2010-05-25 09:15:19 +00:00
}
2010-10-23 18:53:01 +00:00
m_Section - > m_Jump . JumpPC = m_CompilePC ;
m_Section - > m_Jump . TargetPC = m_CompilePC + ( ( short ) m_Opcode . offset < < 2 ) + 4 ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_JumpSection ! = NULL ) {
2010-05-31 00:21:08 +00:00
m_Section - > m_Jump . BranchLabel . Format ( " Section_%d " , m_Section - > m_JumpSection - > m_SectionID ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
m_Section - > m_Jump . BranchLabel . Format ( " Exit_%X_jump_%X " , m_Section - > m_EnterPC , m_Section - > m_Jump . TargetPC ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = NULL ;
m_Section - > m_Jump . LinkLocation2 = NULL ;
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . DoneDelaySlot = false ;
2010-10-23 18:53:01 +00:00
m_Section - > m_Cont . JumpPC = m_CompilePC ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . TargetPC = m_CompilePC + 8 ;
2010-05-31 00:21:08 +00:00
if ( m_Section - > m_ContinueSection ! = NULL ) {
m_Section - > m_Cont . BranchLabel . Format ( " Section_%d " , m_Section - > m_ContinueSection - > m_SectionID ) ;
} else {
m_Section - > m_Cont . BranchLabel . Format ( " Exit_%X_continue_%X " , m_Section - > m_EnterPC , m_Section - > m_Cont . TargetPC ) ;
}
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = NULL ;
m_Section - > m_Cont . LinkLocation2 = NULL ;
2015-05-02 22:14:19 +00:00
m_Section - > m_Cont . DoneDelaySlot = false ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Jump . TargetPC < m_Section - > m_Cont . TargetPC ) {
2015-05-02 22:14:19 +00:00
m_Section - > m_Cont . FallThrough = false ;
m_Section - > m_Jump . FallThrough = true ;
2010-05-30 01:54:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Cont . FallThrough = true ;
m_Section - > m_Jump . FallThrough = false ;
2010-05-25 09:15:19 +00:00
}
2010-10-23 18:53:01 +00:00
2010-05-25 09:15:19 +00:00
if ( Link ) {
2015-05-02 22:14:19 +00:00
UnMap_GPR ( 31 , false ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( 31 , m_CompilePC + 8 ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( 31 , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
}
if ( EffectDelaySlot ) {
2012-09-25 05:58:06 +00:00
if ( ( m_CompilePC & 0xFFC ) ! = 0xFFC )
{
m_Section - > m_Cont . BranchLabel = m_Section - > m_ContinueSection ! = NULL ? " Continue " : " ExitBlock " ;
m_Section - > m_Jump . BranchLabel = m_Section - > m_JumpSection ! = NULL ? " Jump " : " ExitBlock " ;
} else {
m_Section - > m_Cont . BranchLabel = " Continue " ;
m_Section - > m_Jump . BranchLabel = " Jump " ;
}
2010-10-23 18:53:01 +00:00
if ( m_Section - > m_Jump . TargetPC ! = m_Section - > m_Cont . TargetPC )
{
CompareFunc ( ) ;
}
2010-05-30 01:54:42 +00:00
if ( ! m_Section - > m_Jump . FallThrough & & ! m_Section - > m_Cont . FallThrough ) {
if ( m_Section - > m_Jump . LinkLocation ! = NULL ) {
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
2010-06-04 06:25:07 +00:00
CPU_Message ( " %s: " , m_Section - > m_Jump . BranchLabel . c_str ( ) ) ;
2010-05-30 01:54:42 +00:00
SetJump32 ( ( DWORD * ) m_Section - > m_Jump . LinkLocation , ( DWORD * ) m_RecompPos ) ;
m_Section - > m_Jump . LinkLocation = NULL ;
if ( m_Section - > m_Jump . LinkLocation2 ! = NULL ) {
SetJump32 ( ( DWORD * ) m_Section - > m_Jump . LinkLocation2 , ( DWORD * ) m_RecompPos ) ;
m_Section - > m_Jump . LinkLocation2 = NULL ;
2010-05-25 09:15:19 +00:00
}
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
2010-05-30 01:54:42 +00:00
} else if ( m_Section - > m_Cont . LinkLocation ! = NULL ) {
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
2010-06-04 06:25:07 +00:00
CPU_Message ( " %s: " , m_Section - > m_Cont . BranchLabel . c_str ( ) ) ;
2010-05-30 01:54:42 +00:00
SetJump32 ( ( DWORD * ) m_Section - > m_Cont . LinkLocation , ( DWORD * ) m_RecompPos ) ;
m_Section - > m_Cont . LinkLocation = NULL ;
if ( m_Section - > m_Cont . LinkLocation2 ! = NULL ) {
SetJump32 ( ( DWORD * ) m_Section - > m_Cont . LinkLocation2 , ( DWORD * ) m_RecompPos ) ;
m_Section - > m_Cont . LinkLocation2 = NULL ;
2010-05-25 09:15:19 +00:00
}
2015-05-02 22:14:19 +00:00
m_Section - > m_Cont . FallThrough = true ;
2010-05-25 09:15:19 +00:00
}
}
2012-09-25 05:58:06 +00:00
if ( ( m_CompilePC & 0xFFC ) = = 0xFFC )
{
BYTE * DelayLinkLocation = NULL ;
if ( m_Section - > m_Jump . FallThrough )
{
if ( m_Section - > m_Jump . LinkLocation ! = NULL | | m_Section - > m_Jump . LinkLocation2 ! = NULL )
{
2015-03-11 19:50:30 +00:00
g_Notify - > BreakPoint ( __FILEW__ , __LINE__ ) ;
2012-09-25 05:58:06 +00:00
}
MoveConstToVariable ( m_Section - > m_Jump . TargetPC , & R4300iOp : : m_JumpToLocation , " R4300iOp::m_JumpToLocation " ) ;
}
else if ( m_Section - > m_Cont . FallThrough )
{
if ( m_Section - > m_Cont . LinkLocation ! = NULL | | m_Section - > m_Cont . LinkLocation2 ! = NULL )
{
2015-03-11 19:50:30 +00:00
g_Notify - > BreakPoint ( __FILEW__ , __LINE__ ) ;
2012-09-25 05:58:06 +00:00
}
MoveConstToVariable ( m_Section - > m_Cont . TargetPC , & R4300iOp : : m_JumpToLocation , " R4300iOp::m_JumpToLocation " ) ;
}
if ( m_Section - > m_Jump . LinkLocation ! = NULL | | m_Section - > m_Jump . LinkLocation2 ! = NULL )
{
JmpLabel8 ( " DoDelaySlot " , 0 ) ;
2015-03-11 19:50:30 +00:00
if ( DelayLinkLocation ! = NULL ) { g_Notify - > BreakPoint ( __FILEW__ , __LINE__ ) ; }
2012-09-25 05:58:06 +00:00
DelayLinkLocation = ( BYTE * ) ( m_RecompPos - 1 ) ;
CPU_Message ( " " ) ;
CPU_Message ( " %s: " , m_Section - > m_Jump . BranchLabel . c_str ( ) ) ;
SetJump32 ( m_Section - > m_Jump . LinkLocation , ( DWORD * ) m_RecompPos ) ;
m_Section - > m_Jump . LinkLocation = NULL ;
if ( m_Section - > m_Jump . LinkLocation2 ! = NULL ) {
SetJump32 ( m_Section - > m_Jump . LinkLocation2 , ( DWORD * ) m_RecompPos ) ;
m_Section - > m_Jump . LinkLocation2 = NULL ;
}
MoveConstToVariable ( m_Section - > m_Jump . TargetPC , & R4300iOp : : m_JumpToLocation , " R4300iOp::m_JumpToLocation " ) ;
}
if ( m_Section - > m_Cont . LinkLocation ! = NULL | | m_Section - > m_Cont . LinkLocation2 ! = NULL )
{
2012-09-26 01:31:17 +00:00
JmpLabel8 ( " DoDelaySlot " , 0 ) ;
2015-03-11 19:50:30 +00:00
if ( DelayLinkLocation ! = NULL ) { g_Notify - > BreakPoint ( __FILEW__ , __LINE__ ) ; }
2012-09-26 01:31:17 +00:00
DelayLinkLocation = ( BYTE * ) ( m_RecompPos - 1 ) ;
CPU_Message ( " " ) ;
CPU_Message ( " %s: " , m_Section - > m_Cont . BranchLabel . c_str ( ) ) ;
SetJump32 ( m_Section - > m_Cont . LinkLocation , ( DWORD * ) m_RecompPos ) ;
m_Section - > m_Cont . LinkLocation = NULL ;
if ( m_Section - > m_Cont . LinkLocation2 ! = NULL ) {
SetJump32 ( m_Section - > m_Cont . LinkLocation2 , ( DWORD * ) m_RecompPos ) ;
m_Section - > m_Cont . LinkLocation2 = NULL ;
}
MoveConstToVariable ( m_Section - > m_Cont . TargetPC , & R4300iOp : : m_JumpToLocation , " R4300iOp::m_JumpToLocation " ) ;
2012-09-25 05:58:06 +00:00
}
if ( DelayLinkLocation )
{
CPU_Message ( " " ) ;
CPU_Message ( " DoDelaySlot: " ) ;
SetJump8 ( DelayLinkLocation , m_RecompPos ) ;
}
2012-09-26 00:38:29 +00:00
OverflowDelaySlot ( false ) ;
2012-09-25 05:58:06 +00:00
return ;
}
2010-06-04 06:25:07 +00:00
ResetX86Protection ( ) ;
2012-10-14 01:05:52 +00:00
RegBeforeDelay = m_RegWorkingSet ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
m_NextInstruction = DO_DELAY_SLOT ;
} else if ( m_NextInstruction = = DELAY_SLOT_DONE ) {
2010-05-25 09:15:19 +00:00
if ( EffectDelaySlot ) {
2010-05-30 01:54:42 +00:00
CJumpInfo * FallInfo = m_Section - > m_Jump . FallThrough ? & m_Section - > m_Jump : & m_Section - > m_Cont ;
CJumpInfo * JumpInfo = m_Section - > m_Jump . FallThrough ? & m_Section - > m_Cont : & m_Section - > m_Jump ;
2010-05-25 09:15:19 +00:00
if ( FallInfo - > FallThrough & & ! FallInfo - > DoneDelaySlot ) {
2010-06-04 06:25:07 +00:00
ResetX86Protection ( ) ;
2010-05-30 01:54:42 +00:00
FallInfo - > RegSet = m_RegWorkingSet ;
if ( FallInfo = = & m_Section - > m_Jump ) {
if ( m_Section - > m_JumpSection ! = NULL ) {
2010-05-31 00:21:08 +00:00
m_Section - > m_Jump . BranchLabel . Format ( " Section_%d " , m_Section - > m_JumpSection - > m_SectionID ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
m_Section - > m_Jump . BranchLabel = " ExitBlock " ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( FallInfo - > TargetPC < = m_CompilePC )
2010-05-25 09:15:19 +00:00
{
2010-06-14 21:14:58 +00:00
UpdateCounters ( m_Section - > m_Jump . RegSet , true , true ) ;
2010-10-29 03:20:25 +00:00
CPU_Message ( " CompileSystemCheck 12 " ) ;
CompileSystemCheck ( FallInfo - > TargetPC , m_Section - > m_Jump . RegSet ) ;
2010-06-04 06:25:07 +00:00
ResetX86Protection ( ) ;
2013-01-15 19:00:57 +00:00
FallInfo - > ExitReason = CExitInfo : : Normal_NoSysCheck ;
FallInfo - > JumpPC = ( DWORD ) - 1 ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_ContinueSection ! = NULL ) {
2010-05-31 00:21:08 +00:00
m_Section - > m_Cont . BranchLabel . Format ( " Section_%d " , m_Section - > m_ContinueSection - > m_SectionID ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
m_Section - > m_Cont . BranchLabel = " ExitBlock " ;
2010-05-25 09:15:19 +00:00
}
}
2015-05-02 22:14:19 +00:00
FallInfo - > DoneDelaySlot = true ;
2010-05-25 09:15:19 +00:00
if ( ! JumpInfo - > DoneDelaySlot ) {
2015-05-02 22:14:19 +00:00
FallInfo - > FallThrough = false ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( FallInfo - > BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
FallInfo - > LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
if ( JumpInfo - > LinkLocation ! = NULL ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %s: " , JumpInfo - > BranchLabel . c_str ( ) ) ;
2010-05-30 01:54:42 +00:00
SetJump32 ( ( DWORD * ) JumpInfo - > LinkLocation , ( DWORD * ) m_RecompPos ) ;
2010-05-25 09:15:19 +00:00
JumpInfo - > LinkLocation = NULL ;
if ( JumpInfo - > LinkLocation2 ! = NULL ) {
2010-05-30 01:54:42 +00:00
SetJump32 ( ( DWORD * ) JumpInfo - > LinkLocation2 , ( DWORD * ) m_RecompPos ) ;
2010-05-25 09:15:19 +00:00
JumpInfo - > LinkLocation2 = NULL ;
}
2015-05-02 22:14:19 +00:00
JumpInfo - > FallThrough = true ;
2010-05-30 01:54:42 +00:00
m_NextInstruction = DO_DELAY_SLOT ;
2010-06-14 21:14:58 +00:00
m_RegWorkingSet = RegBeforeDelay ;
2010-05-25 09:15:19 +00:00
return ;
}
}
}
} else {
2010-10-23 18:53:01 +00:00
if ( m_Section - > m_Jump . TargetPC ! = m_Section - > m_Cont . TargetPC )
{
CompareFunc ( ) ;
ResetX86Protection ( ) ;
m_Section - > m_Cont . RegSet = m_RegWorkingSet ;
m_Section - > m_Jump . RegSet = m_RegWorkingSet ;
} else {
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Cont . FallThrough = true ;
m_Section - > m_Cont . RegSet = m_RegWorkingSet ;
if ( m_Section - > m_ContinueSection = = NULL & & m_Section - > m_JumpSection ! = NULL )
{
m_Section - > m_ContinueSection = m_Section - > m_JumpSection ;
m_Section - > m_JumpSection = NULL ;
}
if ( m_Section - > m_ContinueSection ! = NULL ) {
m_Section - > m_Cont . BranchLabel . Format ( " Section_%d " , m_Section - > m_ContinueSection - > m_SectionID ) ;
} else {
m_Section - > m_Cont . BranchLabel = " ExitBlock " ;
}
}
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
m_Section - > GenerateSectionLinkage ( ) ;
m_NextInstruction = END_BLOCK ;
2010-05-25 09:15:19 +00:00
} else {
2013-03-22 05:47:20 +00:00
if ( bHaveDebugger ( ) )
{
2015-03-04 09:36:08 +00:00
g_Notify - > DisplayError ( L " WTF \n \n Branch \n NextInstruction = %X " , m_NextInstruction ) ;
2013-03-22 05:47:20 +00:00
}
2010-05-25 09:15:19 +00:00
}
}
2015-05-02 22:14:19 +00:00
void CRecompilerOps : : Compile_BranchLikely ( BranchFunction CompareFunc , bool Link )
2010-05-30 01:54:42 +00:00
{
2015-05-02 22:14:19 +00:00
if ( m_NextInstruction = = NORMAL ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2012-11-29 11:23:35 +00:00
if ( ! g_System - > bLinkBlocks ( ) | | ( m_CompilePC & 0xFFC ) = = 0xFFC )
2012-10-14 01:05:52 +00:00
{
2012-10-22 08:02:53 +00:00
m_Section - > m_Jump . JumpPC = m_CompilePC ;
2012-10-14 01:05:52 +00:00
m_Section - > m_Jump . TargetPC = m_CompilePC + ( ( short ) m_Opcode . offset < < 2 ) + 4 ;
2012-10-22 08:02:53 +00:00
m_Section - > m_Cont . JumpPC = m_CompilePC ;
m_Section - > m_Cont . TargetPC = m_CompilePC + 8 ;
2015-05-02 22:14:19 +00:00
}
else
{
2012-10-22 08:02:53 +00:00
if ( m_Section - > m_Jump . JumpPC ! = m_CompilePC )
2015-03-11 19:50:30 +00:00
g_Notify - > BreakPoint ( __FILEW__ , __LINE__ ) ;
2015-05-02 22:14:19 +00:00
2012-10-22 08:02:53 +00:00
if ( m_Section - > m_Cont . JumpPC ! = m_CompilePC )
2015-03-11 19:50:30 +00:00
g_Notify - > BreakPoint ( __FILEW__ , __LINE__ ) ;
2015-05-02 22:14:19 +00:00
2012-10-22 08:02:53 +00:00
if ( m_Section - > m_Cont . TargetPC ! = m_CompilePC + 8 )
2015-03-11 19:50:30 +00:00
g_Notify - > BreakPoint ( __FILEW__ , __LINE__ ) ;
2010-05-25 09:15:19 +00:00
}
2015-05-02 22:14:19 +00:00
if ( m_Section - > m_JumpSection ! = NULL )
2012-10-22 08:02:53 +00:00
m_Section - > m_Jump . BranchLabel . Format ( " Section_%d " , ( ( CCodeSection * ) m_Section - > m_JumpSection ) - > m_SectionID ) ;
2015-05-02 22:14:19 +00:00
else
2012-10-22 08:02:53 +00:00
m_Section - > m_Jump . BranchLabel = " ExitBlock " ;
2015-05-02 22:14:19 +00:00
if ( m_Section - > m_ContinueSection ! = NULL )
2012-10-22 08:02:53 +00:00
m_Section - > m_Cont . BranchLabel . Format ( " Section_%d " , ( ( CCodeSection * ) m_Section - > m_ContinueSection ) - > m_SectionID ) ;
2015-05-02 22:14:19 +00:00
else
2012-10-22 08:02:53 +00:00
m_Section - > m_Cont . BranchLabel = " ExitBlock " ;
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = NULL ;
m_Section - > m_Jump . LinkLocation2 = NULL ;
2015-05-02 22:14:19 +00:00
m_Section - > m_Cont . FallThrough = false ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = NULL ;
m_Section - > m_Cont . LinkLocation2 = NULL ;
2015-05-02 22:14:19 +00:00
2012-10-14 01:05:52 +00:00
if ( Link )
{
2015-05-02 22:14:19 +00:00
UnMap_GPR ( 31 , false ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( 31 , m_CompilePC + 8 ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( 31 , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
}
2015-05-02 22:14:19 +00:00
2010-06-04 06:25:07 +00:00
CompareFunc ( ) ;
ResetX86Protection ( ) ;
2012-10-22 08:02:53 +00:00
m_Section - > m_Cont . RegSet = m_RegWorkingSet ;
if ( ( m_CompilePC & 0xFFC ) = = 0xFFC )
{
2012-12-22 08:45:52 +00:00
if ( m_Section - > m_Cont . FallThrough )
{
if ( m_Section - > m_Jump . LinkLocation ! = NULL )
2015-05-02 22:14:19 +00:00
g_Notify - > BreakPoint ( __FILEW__ , __LINE__ ) ;
2012-12-22 08:45:52 +00:00
}
2012-10-22 08:02:53 +00:00
2012-12-22 08:45:52 +00:00
if ( m_Section - > m_Jump . LinkLocation ! = NULL | | m_Section - > m_Jump . FallThrough )
{
if ( m_Section - > m_Jump . LinkLocation ! = NULL ) {
SetJump32 ( m_Section - > m_Jump . LinkLocation , ( DWORD * ) m_RecompPos ) ;
m_Section - > m_Jump . LinkLocation = NULL ;
if ( m_Section - > m_Jump . LinkLocation2 ! = NULL ) {
SetJump32 ( m_Section - > m_Jump . LinkLocation2 , ( DWORD * ) m_RecompPos ) ;
m_Section - > m_Jump . LinkLocation2 = NULL ;
}
2012-10-22 08:02:53 +00:00
}
2012-12-22 08:45:52 +00:00
MoveConstToVariable ( m_Section - > m_Jump . TargetPC , & R4300iOp : : m_JumpToLocation , " R4300iOp::m_JumpToLocation " ) ;
OverflowDelaySlot ( false ) ;
CPU_Message ( " " ) ;
CPU_Message ( " %s: " , m_Section - > m_Cont . BranchLabel . c_str ( ) ) ;
} else if ( ! m_Section - > m_Cont . FallThrough ) {
2015-03-11 19:50:30 +00:00
g_Notify - > BreakPoint ( __FILEW__ , __LINE__ ) ;
2012-10-22 08:02:53 +00:00
}
2012-12-22 08:45:52 +00:00
2012-10-22 08:02:53 +00:00
if ( m_Section - > m_Cont . LinkLocation ! = NULL ) {
SetJump32 ( m_Section - > m_Cont . LinkLocation , ( DWORD * ) m_RecompPos ) ;
m_Section - > m_Cont . LinkLocation = NULL ;
if ( m_Section - > m_Cont . LinkLocation2 ! = NULL ) {
SetJump32 ( m_Section - > m_Cont . LinkLocation2 , ( DWORD * ) m_RecompPos ) ;
m_Section - > m_Cont . LinkLocation2 = NULL ;
}
}
2015-05-02 22:14:19 +00:00
m_Section - > CompileExit ( m_CompilePC , m_CompilePC + 8 , m_Section - > m_Cont . RegSet , CExitInfo : : Normal , true , NULL ) ;
2012-10-22 08:02:53 +00:00
return ;
} else {
m_NextInstruction = DO_DELAY_SLOT ;
}
2012-11-29 11:23:35 +00:00
if ( g_System - > bLinkBlocks ( ) )
2012-10-14 01:05:52 +00:00
{
m_Section - > m_Jump . RegSet = m_RegWorkingSet ;
2010-06-04 06:25:07 +00:00
m_Section - > GenerateSectionLinkage ( ) ;
2010-05-30 01:54:42 +00:00
m_NextInstruction = END_BLOCK ;
2010-05-25 09:15:19 +00:00
} else {
2012-10-14 01:05:52 +00:00
if ( m_Section - > m_Cont . FallThrough )
{
if ( m_Section - > m_Jump . LinkLocation ! = NULL )
{
2015-03-11 19:50:30 +00:00
g_Notify - > BreakPoint ( __FILEW__ , __LINE__ ) ;
2010-05-25 09:15:19 +00:00
}
2012-10-14 01:05:52 +00:00
m_Section - > GenerateSectionLinkage ( ) ;
m_NextInstruction = END_BLOCK ;
2010-05-25 09:15:19 +00:00
}
}
2010-05-30 01:54:42 +00:00
} else if ( m_NextInstruction = = DELAY_SLOT_DONE ) {
2010-06-04 06:25:07 +00:00
ResetX86Protection ( ) ;
2012-10-14 01:05:52 +00:00
m_Section - > m_Jump . RegSet = m_RegWorkingSet ;
2010-06-04 06:25:07 +00:00
m_Section - > GenerateSectionLinkage ( ) ;
2010-05-30 01:54:42 +00:00
m_NextInstruction = END_BLOCK ;
2013-03-22 05:47:20 +00:00
} else if ( bHaveDebugger ( ) ) {
2015-03-04 09:36:08 +00:00
g_Notify - > DisplayError ( L " WTF \n \n BranchLikely \n NextInstruction = %X " , m_NextInstruction ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : BNE_Compare ( )
2010-05-30 01:54:42 +00:00
{
2010-10-23 18:53:01 +00:00
BYTE * Jump = NULL ;
2010-05-25 09:15:19 +00:00
2010-09-22 21:43:42 +00:00
if ( IsKnown ( m_Opcode . rs ) & & IsKnown ( m_Opcode . rt ) ) {
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) & & IsConst ( m_Opcode . rt ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) | | Is64Bit ( m_Opcode . rt ) ) {
2010-05-30 01:54:42 +00:00
CRecompilerOps : : UnknownOpcode ( ) ;
2012-11-06 08:19:22 +00:00
} else if ( GetMipsRegLo ( m_Opcode . rs ) ! = GetMipsRegLo ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
m_Section - > m_Cont . FallThrough = false ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Cont . FallThrough = true ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rs ) & & IsMapped ( m_Opcode . rt ) ) {
2013-01-28 08:37:59 +00:00
ProtectGPR ( m_Opcode . rs ) ;
ProtectGPR ( m_Opcode . rt ) ;
if ( Is64Bit ( m_Opcode . rs ) | | Is64Bit ( m_Opcode . rt ) )
{
2010-05-25 09:15:19 +00:00
CompX86RegToX86Reg (
2015-05-02 22:14:19 +00:00
Is32Bit ( m_Opcode . rs ) ? Map_TempReg ( x86_Any , m_Opcode . rs , true ) : GetMipsRegMapHi ( m_Opcode . rs ) ,
Is32Bit ( m_Opcode . rt ) ? Map_TempReg ( x86_Any , m_Opcode . rt , true ) : GetMipsRegMapHi ( m_Opcode . rt )
2010-05-25 09:15:19 +00:00
) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Jump . FallThrough ) {
2010-05-25 09:15:19 +00:00
JneLabel8 ( " continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-03 01:18:08 +00:00
CompX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rs ) , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " continue: " ) ;
2010-05-30 01:54:42 +00:00
SetJump8 ( Jump , m_RecompPos ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-03 01:18:08 +00:00
CompX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rs ) , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
}
} else {
2010-05-30 01:54:42 +00:00
DWORD ConstReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
DWORD MappedReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( ConstReg ) | | Is64Bit ( MappedReg ) ) {
2010-09-22 21:43:42 +00:00
if ( Is32Bit ( ConstReg ) | | Is32Bit ( MappedReg ) ) {
2010-05-30 01:54:42 +00:00
ProtectGPR ( MappedReg ) ;
2010-09-22 21:43:42 +00:00
if ( Is32Bit ( MappedReg ) ) {
2015-05-02 22:14:19 +00:00
CompConstToX86reg ( Map_TempReg ( x86_Any , MappedReg , true ) , GetMipsRegHi ( ConstReg ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-06 08:19:22 +00:00
CompConstToX86reg ( GetMipsRegMapHi ( MappedReg ) , GetMipsRegLo_S ( ConstReg ) > > 31 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapHi ( MappedReg ) , GetMipsRegHi ( ConstReg ) ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Jump . FallThrough ) {
2010-05-25 09:15:19 +00:00
JneLabel8 ( " continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-06 08:19:22 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( MappedReg ) , GetMipsRegLo ( ConstReg ) ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " continue: " ) ;
2010-05-30 01:54:42 +00:00
SetJump8 ( Jump , m_RecompPos ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-06 08:19:22 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( MappedReg ) , GetMipsRegLo ( ConstReg ) ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
}
}
2010-09-22 21:43:42 +00:00
} else if ( IsKnown ( m_Opcode . rs ) | | IsKnown ( m_Opcode . rt ) ) {
DWORD KnownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
DWORD UnknownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2012-11-29 11:23:35 +00:00
if ( ! g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
if ( IsConst ( KnownReg ) ) {
if ( Is64Bit ( KnownReg ) ) {
2012-11-03 01:18:08 +00:00
CompConstToVariable ( GetMipsRegHi ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
} else if ( IsSigned ( KnownReg ) ) {
2012-11-06 08:19:22 +00:00
CompConstToVariable ( ( GetMipsRegLo_S ( KnownReg ) > > 31 ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
} else {
CompConstToVariable ( 0 , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
}
2010-05-25 09:15:19 +00:00
} else {
2010-10-23 18:53:01 +00:00
if ( Is64Bit ( KnownReg ) ) {
2012-11-03 01:18:08 +00:00
CompX86regToVariable ( GetMipsRegMapHi ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
} else if ( IsSigned ( KnownReg ) ) {
ProtectGPR ( KnownReg ) ;
2015-05-02 22:14:19 +00:00
CompX86regToVariable ( Map_TempReg ( x86_Any , KnownReg , true ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
} else {
CompConstToVariable ( 0 , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
}
2010-05-25 09:15:19 +00:00
}
2010-10-23 18:53:01 +00:00
if ( m_Section - > m_Jump . FallThrough ) {
JneLabel8 ( " continue " , 0 ) ;
Jump = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
} else {
2010-10-23 18:53:01 +00:00
JneLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
}
2010-05-30 01:54:42 +00:00
if ( IsConst ( KnownReg ) ) {
2012-11-06 08:19:22 +00:00
CompConstToVariable ( GetMipsRegLo ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
CompX86regToVariable ( GetMipsRegMapLo ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else {
m_Section - > m_Jump . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
2010-05-30 01:54:42 +00:00
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-10-23 18:53:01 +00:00
if ( Jump )
{
CPU_Message ( " " ) ;
CPU_Message ( " continue: " ) ;
SetJump8 ( Jump , m_RecompPos ) ;
}
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else {
m_Section - > m_Jump . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
2010-05-25 09:15:19 +00:00
}
} else {
2010-10-23 18:53:01 +00:00
x86Reg Reg = x86_Any ;
2010-05-25 09:15:19 +00:00
2012-11-29 11:23:35 +00:00
if ( ! g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
2015-05-02 22:14:19 +00:00
Reg = Map_TempReg ( x86_Any , m_Opcode . rt , true ) ;
2010-10-23 18:53:01 +00:00
CompX86regToVariable ( Reg , & _GPR [ m_Opcode . rs ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rs ] ) ;
if ( m_Section - > m_Jump . FallThrough ) {
JneLabel8 ( " continue " , 0 ) ;
Jump = m_RecompPos - 1 ;
} else {
JneLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
2010-05-25 09:15:19 +00:00
}
2015-05-02 22:14:19 +00:00
Reg = Map_TempReg ( Reg , m_Opcode . rt , false ) ;
2010-05-30 01:54:42 +00:00
CompX86regToVariable ( Reg , & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] ) ;
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else {
m_Section - > m_Jump . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
2010-05-30 01:54:42 +00:00
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-10-23 18:53:01 +00:00
if ( Jump )
{
CPU_Message ( " " ) ;
CPU_Message ( " continue: " ) ;
SetJump8 ( Jump , m_RecompPos ) ;
}
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else {
m_Section - > m_Jump . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
2010-05-25 09:15:19 +00:00
}
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : BEQ_Compare ( ) {
2010-10-23 18:53:01 +00:00
BYTE * Jump = NULL ;
2010-05-25 09:15:19 +00:00
2010-09-22 21:43:42 +00:00
if ( IsKnown ( m_Opcode . rs ) & & IsKnown ( m_Opcode . rt ) ) {
2010-10-23 18:53:01 +00:00
if ( IsConst ( m_Opcode . rs ) & & IsConst ( m_Opcode . rt ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) | | Is64Bit ( m_Opcode . rt ) ) {
2010-05-30 01:54:42 +00:00
CRecompilerOps : : UnknownOpcode ( ) ;
2012-11-06 08:19:22 +00:00
} else if ( GetMipsRegLo ( m_Opcode . rs ) = = GetMipsRegLo ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
m_Section - > m_Cont . FallThrough = false ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Cont . FallThrough = true ;
2010-05-25 09:15:19 +00:00
}
2012-10-23 08:06:13 +00:00
}
else if ( IsMapped ( m_Opcode . rs ) & & IsMapped ( m_Opcode . rt ) )
{
2012-11-29 11:23:35 +00:00
if ( ( Is64Bit ( m_Opcode . rs ) | | Is64Bit ( m_Opcode . rt ) ) & & ! g_System - > b32BitCore ( ) )
2012-10-23 08:06:13 +00:00
{
2010-05-30 01:54:42 +00:00
ProtectGPR ( m_Opcode . rs ) ;
ProtectGPR ( m_Opcode . rt ) ;
2010-05-25 09:15:19 +00:00
CompX86RegToX86Reg (
2015-05-02 22:14:19 +00:00
Is32Bit ( m_Opcode . rs ) ? Map_TempReg ( x86_Any , m_Opcode . rs , true ) : GetMipsRegMapHi ( m_Opcode . rs ) ,
Is32Bit ( m_Opcode . rt ) ? Map_TempReg ( x86_Any , m_Opcode . rt , true ) : GetMipsRegMapHi ( m_Opcode . rt )
2010-05-25 09:15:19 +00:00
) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-25 09:15:19 +00:00
JneLabel8 ( " continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-03 01:18:08 +00:00
CompX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rs ) , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " continue: " ) ;
2010-05-30 01:54:42 +00:00
SetJump8 ( Jump , m_RecompPos ) ;
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-03 01:18:08 +00:00
CompX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rs ) , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
}
} else {
2010-05-30 01:54:42 +00:00
DWORD ConstReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
DWORD MappedReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( ConstReg ) | | Is64Bit ( MappedReg ) ) {
2010-09-22 21:43:42 +00:00
if ( Is32Bit ( ConstReg ) | | Is32Bit ( MappedReg ) ) {
if ( Is32Bit ( MappedReg ) ) {
2010-05-30 01:54:42 +00:00
ProtectGPR ( MappedReg ) ;
2015-05-02 22:14:19 +00:00
CompConstToX86reg ( Map_TempReg ( x86_Any , MappedReg , true ) , GetMipsRegHi ( ConstReg ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-06 08:19:22 +00:00
CompConstToX86reg ( GetMipsRegMapHi ( MappedReg ) , GetMipsRegLo_S ( ConstReg ) > > 31 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapHi ( MappedReg ) , GetMipsRegHi ( ConstReg ) ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-25 09:15:19 +00:00
JneLabel8 ( " continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-06 08:19:22 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( MappedReg ) , GetMipsRegLo ( ConstReg ) ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " continue: " ) ;
2010-05-30 01:54:42 +00:00
SetJump8 ( Jump , m_RecompPos ) ;
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-06 08:19:22 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( MappedReg ) , GetMipsRegLo ( ConstReg ) ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
}
}
2010-09-22 21:43:42 +00:00
} else if ( IsKnown ( m_Opcode . rs ) | | IsKnown ( m_Opcode . rt ) ) {
DWORD KnownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
DWORD UnknownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2012-11-29 11:23:35 +00:00
if ( ! g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
if ( IsConst ( KnownReg ) ) {
if ( Is64Bit ( KnownReg ) ) {
2012-11-03 01:18:08 +00:00
CompConstToVariable ( GetMipsRegHi ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
} else if ( IsSigned ( KnownReg ) ) {
2012-11-06 08:19:22 +00:00
CompConstToVariable ( GetMipsRegLo_S ( KnownReg ) > > 31 , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
} else {
CompConstToVariable ( 0 , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
}
2010-05-25 09:15:19 +00:00
} else {
2010-10-23 18:53:01 +00:00
ProtectGPR ( KnownReg ) ;
if ( Is64Bit ( KnownReg ) ) {
2012-11-03 01:18:08 +00:00
CompX86regToVariable ( GetMipsRegMapHi ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
} else if ( IsSigned ( KnownReg ) ) {
2015-05-02 22:14:19 +00:00
CompX86regToVariable ( Map_TempReg ( x86_Any , KnownReg , true ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
} else {
CompConstToVariable ( 0 , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
}
2010-05-25 09:15:19 +00:00
}
2010-10-23 18:53:01 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
JneLabel8 ( " continue " , 0 ) ;
Jump = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
} else {
2010-10-23 18:53:01 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
}
2010-05-30 01:54:42 +00:00
if ( IsConst ( KnownReg ) ) {
2012-11-06 08:19:22 +00:00
CompConstToVariable ( GetMipsRegLo ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
CompX86regToVariable ( GetMipsRegMapLo ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-10-23 18:53:01 +00:00
if ( Jump )
{
CPU_Message ( " " ) ;
CPU_Message ( " continue: " ) ;
SetJump8 ( Jump , m_RecompPos ) ;
}
2010-05-30 01:54:42 +00:00
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else {
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-10-23 18:53:01 +00:00
x86Reg Reg = x86_Any ;
2012-11-29 11:23:35 +00:00
if ( ! g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
2015-05-02 22:14:19 +00:00
Reg = Map_TempReg ( x86_Any , m_Opcode . rs , true ) ;
2010-10-23 18:53:01 +00:00
CompX86regToVariable ( Reg , & _GPR [ m_Opcode . rt ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rt ] ) ;
if ( m_Section - > m_Cont . FallThrough ) {
JneLabel8 ( " continue " , 0 ) ;
Jump = m_RecompPos - 1 ;
} else {
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
2010-05-25 09:15:19 +00:00
}
2015-05-02 22:14:19 +00:00
CompX86regToVariable ( Map_TempReg ( Reg , m_Opcode . rs , false ) , & _GPR [ m_Opcode . rt ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rt ] ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-10-23 18:53:01 +00:00
if ( Jump )
{
CPU_Message ( " " ) ;
CPU_Message ( " continue: " ) ;
SetJump8 ( Jump , m_RecompPos ) ;
}
2010-05-30 01:54:42 +00:00
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else {
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else {
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : BGTZ_Compare ( ) {
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) ) {
2012-11-06 08:19:22 +00:00
if ( GetMipsReg_S ( m_Opcode . rs ) > 0 ) {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
m_Section - > m_Cont . FallThrough = false ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Cont . FallThrough = true ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rs ) > 0 ) {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
m_Section - > m_Cont . FallThrough = false ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Cont . FallThrough = true ;
2010-05-25 09:15:19 +00:00
}
}
2010-09-22 21:43:42 +00:00
} else if ( IsMapped ( m_Opcode . rs ) & & Is32Bit ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( m_Opcode . rs ) , 0 ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JleLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JgLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JleLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-29 11:23:35 +00:00
} else if ( IsUnknown ( m_Opcode . rs ) & & g_System - > b32BitCore ( ) ) {
2010-10-23 18:53:01 +00:00
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] ) ;
if ( m_Section - > m_Jump . FallThrough ) {
JleLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Cont . FallThrough ) {
JgLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else {
JleLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
2010-05-25 09:15:19 +00:00
} else {
2012-10-06 04:09:17 +00:00
BYTE * Jump = NULL ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsMapped ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapHi ( m_Opcode . rs ) , 0 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-30 01:54:42 +00:00
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rs ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rs ] ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
JgLabel8 ( " continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump = m_RecompPos - 1 ;
} else if ( m_Section - > m_Cont . FallThrough ) {
2010-05-25 09:15:19 +00:00
JlLabel8 ( " continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump = m_RecompPos - 1 ;
2010-05-31 00:21:08 +00:00
JgLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JgLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( IsMapped ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( m_Opcode . rs ) , 0 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-30 01:54:42 +00:00
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " continue: " ) ;
2010-10-23 18:53:01 +00:00
SetJump8 ( Jump , m_RecompPos ) ;
2010-05-30 01:54:42 +00:00
} else if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " continue: " ) ;
2010-10-23 18:53:01 +00:00
SetJump8 ( Jump , m_RecompPos ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : BLEZ_Compare ( ) {
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) ) {
2012-11-06 08:19:22 +00:00
if ( GetMipsReg_S ( m_Opcode . rs ) < = 0 ) {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
m_Section - > m_Cont . FallThrough = false ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Cont . FallThrough = true ;
2010-05-25 09:15:19 +00:00
}
2010-09-22 21:43:42 +00:00
} else if ( IsSigned ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rs ) < = 0 ) {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
m_Section - > m_Cont . FallThrough = false ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Cont . FallThrough = true ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-06 08:19:22 +00:00
if ( GetMipsRegLo ( m_Opcode . rs ) = = 0 ) {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
m_Section - > m_Cont . FallThrough = false ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Cont . FallThrough = true ;
2010-05-25 09:15:19 +00:00
}
}
2010-10-23 18:53:01 +00:00
} else if ( IsMapped ( m_Opcode . rs ) ) {
if ( Is32Bit ( m_Opcode . rs ) )
{
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( m_Opcode . rs ) , 0 ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JgLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JleLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JgLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-10-06 04:09:17 +00:00
BYTE * Jump = NULL ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsMapped ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapHi ( m_Opcode . rs ) , 0 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-30 01:54:42 +00:00
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rs ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rs ] ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JgLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
JlLabel8 ( " Continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump = m_RecompPos - 1 ;
} else if ( m_Section - > m_Cont . FallThrough ) {
2010-05-25 09:15:19 +00:00
JgLabel8 ( " Continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump = m_RecompPos - 1 ;
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JgLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( IsMapped ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( m_Opcode . rs ) , 0 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-30 01:54:42 +00:00
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " continue: " ) ;
2010-10-23 18:53:01 +00:00
SetJump8 ( Jump , m_RecompPos ) ;
2010-05-30 01:54:42 +00:00
} else if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " continue: " ) ;
2010-10-23 18:53:01 +00:00
SetJump8 ( Jump , m_RecompPos ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
JmpLabel32 ( " BranchToJump " , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
}
2010-10-23 18:53:01 +00:00
} else {
BYTE * Jump = NULL ;
2012-11-29 11:23:35 +00:00
if ( ! g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rs ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rs ] ) ;
if ( m_Section - > m_Jump . FallThrough ) {
JgLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
JlLabel8 ( " Continue " , 0 ) ;
Jump = m_RecompPos - 1 ;
} else if ( m_Section - > m_Cont . FallThrough ) {
JgLabel8 ( " Continue " , 0 ) ;
Jump = m_RecompPos - 1 ;
JlLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else {
JgLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
JlLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] ) ;
if ( m_Section - > m_Jump . FallThrough ) {
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else {
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
if ( Jump )
{
CPU_Message ( " continue: " ) ;
SetJump8 ( Jump , m_RecompPos ) ;
}
} else if ( m_Section - > m_Cont . FallThrough ) {
JeLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Jump . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
if ( Jump )
{
CPU_Message ( " continue: " ) ;
SetJump8 ( Jump , m_RecompPos ) ;
}
} else {
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Cont . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
JmpLabel32 ( " BranchToJump " , 0 ) ;
m_Section - > m_Jump . LinkLocation2 = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
} else {
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] ) ;
if ( m_Section - > m_Jump . FallThrough ) {
JgLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Cont . FallThrough ) {
JleLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else {
JgLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
}
}
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : BLTZ_Compare ( ) {
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) ) {
2012-11-06 08:19:22 +00:00
if ( GetMipsReg_S ( m_Opcode . rs ) < 0 ) {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
m_Section - > m_Cont . FallThrough = false ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Cont . FallThrough = true ;
2010-05-25 09:15:19 +00:00
}
2010-09-22 21:43:42 +00:00
} else if ( IsSigned ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rs ) < 0 ) {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
m_Section - > m_Cont . FallThrough = false ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Cont . FallThrough = true ;
2010-05-25 09:15:19 +00:00
}
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Cont . FallThrough = true ;
2010-05-30 01:54:42 +00:00
}
} else if ( IsMapped ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapHi ( m_Opcode . rs ) , 0 ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JgeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JgeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
2010-09-22 21:43:42 +00:00
} else if ( IsSigned ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( m_Opcode . rs ) , 0 ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JgeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JgeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Cont . FallThrough = true ;
2010-05-25 09:15:19 +00:00
}
2010-09-22 21:43:42 +00:00
} else if ( IsUnknown ( m_Opcode . rs ) ) {
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] ) ;
} else {
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rs ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rs ] ) ;
}
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JgeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : BGEZ_Compare ( ) {
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) ) {
2015-03-11 19:50:30 +00:00
g_Notify - > BreakPoint ( __FILEW__ , __LINE__ ) ;
2010-05-30 01:54:42 +00:00
CRecompilerOps : : UnknownOpcode ( ) ;
2010-09-22 21:43:42 +00:00
} else if ( IsSigned ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rs ) > = 0 ) {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
m_Section - > m_Cont . FallThrough = false ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Cont . FallThrough = true ;
2010-05-25 09:15:19 +00:00
}
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
m_Section - > m_Cont . FallThrough = false ;
2010-05-30 01:54:42 +00:00
}
} else if ( IsMapped ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapHi ( m_Opcode . rs ) , 0 ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JgeLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
2010-09-22 21:43:42 +00:00
} else if ( IsSigned ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( m_Opcode . rs ) , 0 ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JgeLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
m_Section - > m_Cont . FallThrough = false ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] ) ;
} else {
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rs ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rs ] ) ;
}
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JgeLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else {
2010-05-31 00:21:08 +00:00
JlLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_BCF_Compare ( ) {
2010-05-25 09:15:19 +00:00
TestVariable ( FPCSR_C , & _FPCR [ 31 ] , " _FPCR[31] " ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_BCT_Compare ( ) {
2010-05-25 09:15:19 +00:00
TestVariable ( FPCSR_C , & _FPCR [ 31 ] , " _FPCR[31] " ) ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_Cont . FallThrough ) {
2010-05-31 00:21:08 +00:00
JneLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
} else if ( m_Section - > m_Jump . FallThrough ) {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
JeLabel32 ( m_Section - > m_Cont . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Cont . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-31 00:21:08 +00:00
JmpLabel32 ( m_Section - > m_Jump . BranchLabel . c_str ( ) , 0 ) ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = ( DWORD * ) ( m_RecompPos - 4 ) ;
2010-05-25 09:15:19 +00:00
}
}
2010-05-30 01:54:42 +00:00
2010-05-25 09:15:19 +00:00
/************************* OpCode functions *************************/
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : J ( ) {
2010-05-30 01:54:42 +00:00
if ( m_NextInstruction = = NORMAL ) {
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2012-09-27 22:13:59 +00:00
if ( ( m_CompilePC & 0xFFC ) = = 0xFFC )
{
MoveConstToVariable ( ( m_CompilePC & 0xF0000000 ) + ( m_Opcode . target < < 2 ) , & R4300iOp : : m_JumpToLocation , " R4300iOp::m_JumpToLocation " ) ;
OverflowDelaySlot ( false ) ;
return ;
}
2010-05-25 09:15:19 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > m_Jump . TargetPC = ( m_CompilePC & 0xF0000000 ) + ( m_Opcode . target < < 2 ) ; ;
2010-10-29 03:20:25 +00:00
m_Section - > m_Jump . JumpPC = m_CompilePC ;
2010-05-30 01:54:42 +00:00
if ( m_Section - > m_JumpSection ! = NULL ) {
2010-06-04 06:25:07 +00:00
m_Section - > m_Jump . BranchLabel . Format ( " Section_%d " , ( ( CCodeSection * ) m_Section - > m_JumpSection ) - > m_SectionID ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-06-04 06:25:07 +00:00
m_Section - > m_Jump . BranchLabel = " ExitBlock " ;
2010-05-25 09:15:19 +00:00
}
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
2010-05-30 01:54:42 +00:00
m_Section - > m_Jump . LinkLocation = NULL ;
m_Section - > m_Jump . LinkLocation2 = NULL ;
m_NextInstruction = DO_DELAY_SLOT ;
2015-05-02 22:14:19 +00:00
} else if ( m_NextInstruction = = DELAY_SLOT_DONE ) {
2010-10-23 18:53:01 +00:00
m_Section - > m_Jump . RegSet = m_RegWorkingSet ;
2010-06-04 06:25:07 +00:00
m_Section - > GenerateSectionLinkage ( ) ;
2010-05-30 01:54:42 +00:00
m_NextInstruction = END_BLOCK ;
2013-03-22 05:47:20 +00:00
} else if ( bHaveDebugger ( ) ) {
2015-03-04 09:36:08 +00:00
g_Notify - > DisplayError ( L " WTF \n \n J \n NextInstruction = %X " , m_NextInstruction ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : JAL ( ) {
2013-01-14 06:12:11 +00:00
if ( m_NextInstruction = = NORMAL )
{
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2013-01-11 21:16:35 +00:00
Map_GPR_32bit ( 31 , true , - 1 ) ;
MoveVariableToX86reg ( _PROGRAM_COUNTER , " _PROGRAM_COUNTER " , GetMipsRegMapLo ( 31 ) ) ;
AndConstToX86Reg ( GetMipsRegMapLo ( 31 ) , 0xF0000000 ) ;
AddConstToX86Reg ( GetMipsRegMapLo ( 31 ) , ( m_CompilePC + 8 ) & ~ 0xF0000000 ) ;
2012-09-25 05:58:06 +00:00
if ( ( m_CompilePC & 0xFFC ) = = 0xFFC )
{
MoveConstToVariable ( ( m_CompilePC & 0xF0000000 ) + ( m_Opcode . target < < 2 ) , & R4300iOp : : m_JumpToLocation , " R4300iOp::m_JumpToLocation " ) ;
2012-09-26 00:38:29 +00:00
OverflowDelaySlot ( false ) ;
2012-09-25 05:58:06 +00:00
return ;
}
m_Section - > m_Jump . TargetPC = ( m_CompilePC & 0xF0000000 ) + ( m_Opcode . target < < 2 ) ;
2010-10-23 18:53:01 +00:00
m_Section - > m_Jump . JumpPC = m_CompilePC ;
if ( m_Section - > m_JumpSection ! = NULL ) {
m_Section - > m_Jump . BranchLabel . Format ( " Section_%d " , ( ( CCodeSection * ) m_Section - > m_JumpSection ) - > m_SectionID ) ;
} else {
m_Section - > m_Jump . BranchLabel = " ExitBlock " ;
}
2015-05-02 22:14:19 +00:00
m_Section - > m_Jump . FallThrough = true ;
2010-10-23 18:53:01 +00:00
m_Section - > m_Jump . LinkLocation = NULL ;
m_Section - > m_Jump . LinkLocation2 = NULL ;
2012-09-25 05:58:06 +00:00
m_NextInstruction = DO_DELAY_SLOT ;
2015-05-02 22:14:19 +00:00
} else if ( m_NextInstruction = = DELAY_SLOT_DONE ) {
2010-10-23 18:53:01 +00:00
if ( m_Section - > m_JumpSection )
{
m_Section - > m_Jump . RegSet = m_RegWorkingSet ;
m_Section - > GenerateSectionLinkage ( ) ;
} else {
2013-01-11 21:16:35 +00:00
m_RegWorkingSet . WriteBackRegisters ( ) ;
x86Reg pc_reg = Map_TempReg ( x86_Any , - 1 , false ) ;
MoveVariableToX86reg ( _PROGRAM_COUNTER , " _PROGRAM_COUNTER " , pc_reg ) ;
AndConstToX86Reg ( pc_reg , 0xF0000000 ) ;
AddConstToX86Reg ( pc_reg , ( m_Opcode . target < < 2 ) ) ;
MoveX86regToVariable ( pc_reg , _PROGRAM_COUNTER , " _PROGRAM_COUNTER " ) ;
2010-10-23 18:53:01 +00:00
DWORD TargetPC = ( m_CompilePC & 0xF0000000 ) + ( m_Opcode . target < < 2 ) ;
2013-01-14 06:12:11 +00:00
bool bCheck = TargetPC < = m_CompilePC ;
UpdateCounters ( m_RegWorkingSet , bCheck , true ) ;
2013-01-11 21:16:35 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileExit ( ( DWORD ) - 1 , ( DWORD ) - 1 , m_RegWorkingSet , bCheck ? CExitInfo : : Normal : CExitInfo : : Normal_NoSysCheck , true , NULL ) ;
2010-10-23 18:53:01 +00:00
}
2010-05-30 01:54:42 +00:00
m_NextInstruction = END_BLOCK ;
2010-05-25 09:15:19 +00:00
} else {
2015-03-11 19:50:30 +00:00
g_Notify - > BreakPoint ( __FILEW__ , __LINE__ ) ;
2010-05-25 09:15:19 +00:00
}
return ;
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : ADDI ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( m_Opcode . rt = = 0 ) { return ; }
2010-05-25 09:15:19 +00:00
2012-11-29 11:23:35 +00:00
if ( g_System - > bFastSP ( ) & & m_Opcode . rs = = 29 & & m_Opcode . rt = = 29 ) {
2010-07-23 10:45:35 +00:00
AddConstToX86Reg ( Map_MemoryStack ( x86_Any , true ) , ( short ) m_Opcode . immediate ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rt ) )
UnMap_GPR ( m_Opcode . rt , false ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rt , GetMipsRegLo ( m_Opcode . rs ) + ( short ) m_Opcode . immediate ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rt , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , true , m_Opcode . rs ) ;
2012-11-03 01:18:08 +00:00
AddConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rt ) , ( short ) m_Opcode . immediate ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-29 11:23:35 +00:00
if ( g_System - > bFastSP ( ) & & m_Opcode . rt = = 29 & & m_Opcode . rs ! = 29 ) {
2010-06-04 06:25:07 +00:00
ResetX86Protection ( ) ;
2012-11-17 01:18:00 +00:00
g_MMU - > ResetMemoryStack ( ) ;
2010-07-23 10:45:35 +00:00
}
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : ADDIU ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rt = = 0 | | ( m_Opcode . immediate = = 0 & & m_Opcode . rs = = m_Opcode . rt ) )
return ;
2010-05-25 09:15:19 +00:00
2012-11-29 11:23:35 +00:00
if ( g_System - > bFastSP ( ) )
2010-05-25 09:15:19 +00:00
{
2010-05-30 01:54:42 +00:00
if ( m_Opcode . rs = = 29 & & m_Opcode . rt = = 29 )
2010-05-25 09:15:19 +00:00
{
2015-05-02 22:14:19 +00:00
AddConstToX86Reg ( Map_MemoryStack ( x86_Any , true ) , ( short ) m_Opcode . immediate ) ;
2010-05-25 09:15:19 +00:00
}
}
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rt ) )
UnMap_GPR ( m_Opcode . rt , false ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rt , GetMipsRegLo ( m_Opcode . rs ) + ( short ) m_Opcode . immediate ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rt , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , true , m_Opcode . rs ) ;
2012-11-03 01:18:08 +00:00
AddConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rt ) , ( short ) m_Opcode . immediate ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-29 11:23:35 +00:00
if ( g_System - > bFastSP ( ) & & m_Opcode . rt = = 29 & & m_Opcode . rs ! = 29 ) {
2010-06-04 06:25:07 +00:00
ResetX86Protection ( ) ;
2012-11-17 01:18:00 +00:00
g_MMU - > ResetMemoryStack ( ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SLTIU ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rt = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2012-10-14 01:05:52 +00:00
if ( IsConst ( m_Opcode . rs ) )
{
2012-11-06 08:19:22 +00:00
DWORD Result = Is64Bit ( m_Opcode . rs ) ? GetMipsReg ( m_Opcode . rs ) < ( ( unsigned ) ( ( __int64 ) ( ( short ) m_Opcode . immediate ) ) ) ? 1 : 0 :
GetMipsRegLo ( m_Opcode . rs ) < ( ( unsigned ) ( ( short ) m_Opcode . immediate ) ) ? 1 : 0 ;
2015-05-02 22:14:19 +00:00
UnMap_GPR ( m_Opcode . rt , false ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rt , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rt , Result ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) ) {
2010-05-25 09:15:19 +00:00
BYTE * Jump [ 2 ] ;
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapHi ( m_Opcode . rs ) , ( ( short ) m_Opcode . immediate > > 31 ) ) ;
2010-05-25 09:15:19 +00:00
JeLabel8 ( " Low Compare " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 0 ] = m_RecompPos - 1 ;
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
JmpLabel8 ( " Continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 1 ] = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " Low Compare: " ) ;
2010-10-23 18:53:01 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( m_Opcode . rs ) , ( short ) m_Opcode . immediate ) ;
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " Continue: " ) ;
2010-10-23 18:53:01 +00:00
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , false , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( m_Opcode . rs ) , ( short ) m_Opcode . immediate ) ;
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , false , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-29 11:23:35 +00:00
} else if ( g_System - > b32BitCore ( ) ) {
2010-10-23 18:53:01 +00:00
CompConstToVariable ( ( short ) m_Opcode . immediate , & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] ) ;
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , false , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-10-23 18:53:01 +00:00
BYTE * Jump = NULL ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
CompConstToVariable ( ( ( short ) m_Opcode . immediate > > 31 ) , & _GPR [ m_Opcode . rs ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rs ] ) ;
2010-05-25 09:15:19 +00:00
JneLabel8 ( " CompareSet " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump = m_RecompPos - 1 ;
CompConstToVariable ( ( short ) m_Opcode . immediate , & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] ) ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " CompareSet: " ) ;
2010-10-23 18:53:01 +00:00
SetJump8 ( Jump , m_RecompPos ) ;
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , false , - 1 ) ;
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SLTI ( )
2010-06-04 06:25:07 +00:00
{
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rt = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
2012-10-06 04:09:17 +00:00
DWORD Result = Is64Bit ( m_Opcode . rs ) ?
2012-11-06 08:19:22 +00:00
( ( __int64 ) GetMipsReg ( m_Opcode . rs ) < ( __int64 ) ( ( short ) m_Opcode . immediate ) ? 1 : 0 ) :
2012-11-03 01:18:08 +00:00
( GetMipsRegLo_S ( m_Opcode . rs ) < ( short ) m_Opcode . immediate ? 1 : 0 ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
UnMap_GPR ( m_Opcode . rt , false ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rt , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rt , Result ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) ) {
2010-05-25 09:15:19 +00:00
BYTE * Jump [ 2 ] ;
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapHi ( m_Opcode . rs ) , ( ( short ) m_Opcode . immediate > > 31 ) ) ;
2010-05-25 09:15:19 +00:00
JeLabel8 ( " Low Compare " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 0 ] = m_RecompPos - 1 ;
2010-06-04 06:25:07 +00:00
SetlVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
JmpLabel8 ( " Continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 1 ] = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " Low Compare: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( m_Opcode . rs ) , ( short ) m_Opcode . immediate ) ;
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " Continue: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , false , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
/* CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rs),(short)m_Opcode.immediate);
2010-06-04 06:25:07 +00:00
SetlVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , false , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
*/
2010-05-30 01:54:42 +00:00
ProtectGPR ( m_Opcode . rs ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , false , - 1 ) ;
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( m_Opcode . rs ) , ( short ) m_Opcode . immediate ) ;
2010-05-25 09:15:19 +00:00
2012-11-03 01:18:08 +00:00
if ( GetMipsRegMapLo ( m_Opcode . rt ) > x86_EBX ) {
2010-06-04 06:25:07 +00:00
SetlVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
Setl ( GetMipsRegMapLo ( m_Opcode . rt ) ) ;
AndConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rt ) , 1 ) ;
2010-05-25 09:15:19 +00:00
}
}
2012-11-29 11:23:35 +00:00
} else if ( g_System - > b32BitCore ( ) ) {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , false , - 1 ) ;
2010-10-23 18:53:01 +00:00
CompConstToVariable ( ( short ) m_Opcode . immediate , & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] ) ;
2010-05-25 09:15:19 +00:00
2012-11-03 01:18:08 +00:00
if ( GetMipsRegMapLo ( m_Opcode . rt ) > x86_EBX ) {
2010-10-23 18:53:01 +00:00
SetlVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-10-23 18:53:01 +00:00
} else {
2012-11-03 01:18:08 +00:00
Setl ( GetMipsRegMapLo ( m_Opcode . rt ) ) ;
AndConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rt ) , 1 ) ;
2010-10-23 18:53:01 +00:00
}
} else {
BYTE * Jump [ 2 ] = { NULL , NULL } ;
2010-05-30 01:54:42 +00:00
CompConstToVariable ( ( ( short ) m_Opcode . immediate > > 31 ) , & _GPR [ m_Opcode . rs ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rs ] ) ;
2010-05-25 09:15:19 +00:00
JeLabel8 ( " Low Compare " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 0 ] = m_RecompPos - 1 ;
2010-06-04 06:25:07 +00:00
SetlVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
JmpLabel8 ( " Continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 1 ] = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " Low Compare: " ) ;
2010-10-23 18:53:01 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
2010-05-30 01:54:42 +00:00
CompConstToVariable ( ( short ) m_Opcode . immediate , & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] ) ;
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-10-23 18:53:01 +00:00
if ( Jump [ 1 ] )
{
CPU_Message ( " " ) ;
CPU_Message ( " Continue: " ) ;
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , false , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : ANDI ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rt = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rt ) )
UnMap_GPR ( m_Opcode . rt , false ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rt , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rt , GetMipsRegLo ( m_Opcode . rs ) & m_Opcode . immediate ) ;
2010-05-30 01:54:42 +00:00
} else if ( m_Opcode . immediate ! = 0 ) {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , false , m_Opcode . rs ) ;
2012-11-03 01:18:08 +00:00
AndConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rt ) , m_Opcode . immediate ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , false , 0 ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : ORI ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rt = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2012-11-29 11:23:35 +00:00
if ( g_System - > bFastSP ( ) & & m_Opcode . rs = = 29 & & m_Opcode . rt = = 29 ) {
2010-10-29 03:20:25 +00:00
OrConstToX86Reg ( m_Opcode . immediate , Map_MemoryStack ( x86_Any , true ) ) ;
}
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rt ) )
UnMap_GPR ( m_Opcode . rt , false ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rt , GetMipsRegState ( m_Opcode . rs ) ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegHi ( m_Opcode . rt , GetMipsRegHi ( m_Opcode . rs ) ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rt , GetMipsRegLo ( m_Opcode . rs ) | m_Opcode . immediate ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rs ) ) {
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
Map_GPR_32bit ( m_Opcode . rt , true , m_Opcode . rs ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-10-23 18:53:01 +00:00
if ( Is64Bit ( m_Opcode . rs ) ) {
Map_GPR_64bit ( m_Opcode . rt , m_Opcode . rs ) ;
} else {
Map_GPR_32bit ( m_Opcode . rt , IsSigned ( m_Opcode . rs ) , m_Opcode . rs ) ;
}
2010-05-25 09:15:19 +00:00
}
2012-11-03 01:18:08 +00:00
OrConstToX86Reg ( m_Opcode . immediate , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
Map_GPR_32bit ( m_Opcode . rt , true , m_Opcode . rs ) ;
} else {
Map_GPR_64bit ( m_Opcode . rt , m_Opcode . rs ) ;
}
2012-11-03 01:18:08 +00:00
OrConstToX86Reg ( m_Opcode . immediate , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
}
2010-10-29 03:20:25 +00:00
2012-11-29 11:23:35 +00:00
if ( g_System - > bFastSP ( ) & & m_Opcode . rt = = 29 & & m_Opcode . rs ! = 29 ) {
2010-10-29 03:20:25 +00:00
ResetX86Protection ( ) ;
2012-11-17 01:18:00 +00:00
g_MMU - > ResetMemoryStack ( ) ;
2010-10-29 03:20:25 +00:00
}
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : XORI ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rt = = 0 )
return ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rs ! = m_Opcode . rt )
UnMap_GPR ( m_Opcode . rt , false ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rt , GetMipsRegState ( m_Opcode . rs ) ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegHi ( m_Opcode . rt , GetMipsRegHi ( m_Opcode . rs ) ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rt , GetMipsRegLo ( m_Opcode . rs ) ^ m_Opcode . immediate ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-09-22 21:43:42 +00:00
if ( IsMapped ( m_Opcode . rs ) & & Is32Bit ( m_Opcode . rs ) ) {
Map_GPR_32bit ( m_Opcode . rt , IsSigned ( m_Opcode . rs ) , m_Opcode . rs ) ;
2012-11-29 11:23:35 +00:00
} else if ( g_System - > b32BitCore ( ) ) {
2010-10-23 18:53:01 +00:00
Map_GPR_32bit ( m_Opcode . rt , true , m_Opcode . rs ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rt , m_Opcode . rs ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-03 01:18:08 +00:00
if ( m_Opcode . immediate ! = 0 ) { XorConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rt ) , m_Opcode . immediate ) ; }
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : LUI ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rt = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2012-11-29 11:23:35 +00:00
if ( g_System - > bFastSP ( ) & & m_Opcode . rt = = 29 ) {
2010-10-29 03:20:25 +00:00
x86Reg Reg = Map_MemoryStack ( x86_Any , true , false ) ;
2010-05-25 09:15:19 +00:00
DWORD Address ;
2012-11-17 02:35:36 +00:00
g_TransVaddr - > TranslateVaddr ( ( ( short ) m_Opcode . offset < < 16 ) , Address ) ;
2010-07-23 10:45:35 +00:00
if ( Reg < 0 ) {
2012-11-17 01:18:00 +00:00
MoveConstToVariable ( ( DWORD ) ( Address + g_MMU - > Rdram ( ) ) , & ( g_Recompiler - > MemoryStackPos ( ) ) , " MemoryStack " ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-17 01:18:00 +00:00
MoveConstToX86reg ( ( DWORD ) ( Address + g_MMU - > Rdram ( ) ) , Reg ) ;
2010-05-25 09:15:19 +00:00
}
}
2010-07-23 10:45:35 +00:00
2015-05-02 22:14:19 +00:00
UnMap_GPR ( m_Opcode . rt , false ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rt , ( ( short ) m_Opcode . offset < < 16 ) ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rt , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : DADDIU ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rs ! = 0 )
UnMap_GPR ( m_Opcode . rs , true ) ;
if ( m_Opcode . rs ! = 0 )
UnMap_GPR ( m_Opcode . rt , true ) ;
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2010-06-04 06:25:07 +00:00
MoveConstToVariable ( m_Opcode . Hex , & R4300iOp : : m_Opcode . Hex , " R4300iOp::m_Opcode.Hex " ) ;
2010-05-25 09:15:19 +00:00
Call_Direct ( R4300iOp : : DADDIU , " R4300iOp::DADDIU " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : CACHE ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2012-11-17 01:02:04 +00:00
if ( g_Settings - > LoadDword ( Game_SMM_Cache ) = = 0 )
2010-05-31 00:21:08 +00:00
{
2010-05-25 09:15:19 +00:00
return ;
}
2010-05-31 00:21:08 +00:00
switch ( m_Opcode . rt ) {
case 0 :
case 16 :
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2010-05-31 00:21:08 +00:00
PushImm32 ( " CRecompiler::Remove_Cache " , CRecompiler : : Remove_Cache ) ;
2010-06-14 21:14:58 +00:00
PushImm32 ( " 0x20 " , 0x20 ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . base ) ) {
2012-11-06 08:19:22 +00:00
DWORD Address = GetMipsRegLo ( m_Opcode . base ) + ( short ) m_Opcode . offset ;
2010-05-31 00:21:08 +00:00
PushImm32 ( " Address " , Address ) ;
} else if ( IsMapped ( m_Opcode . base ) ) {
2012-11-03 01:18:08 +00:00
AddConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . base ) , ( short ) m_Opcode . offset ) ;
Push ( GetMipsRegMapLo ( m_Opcode . base ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
MoveVariableToX86reg ( & _GPR [ m_Opcode . base ] . UW [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . base ] , x86_EAX ) ;
AddConstToX86Reg ( x86_EAX , ( short ) m_Opcode . offset ) ;
Push ( x86_EAX ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-17 01:15:55 +00:00
MoveConstToX86reg ( ( DWORD ) g_Recompiler , x86_ECX ) ;
2010-09-22 21:43:42 +00:00
Call_Direct ( AddressOf ( & CRecompiler : : ClearRecompCode_Virt ) , " CRecompiler::ClearRecompCode_Virt " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-25 09:15:19 +00:00
break ;
case 1 :
case 3 :
case 13 :
case 5 :
case 8 :
case 9 :
case 17 :
case 21 :
case 25 :
break ;
default :
2013-03-22 05:47:20 +00:00
if ( bHaveDebugger ( ) )
{
2015-03-04 09:36:08 +00:00
g_Notify - > DisplayError ( L " cache: %d " , m_Opcode . rt ) ;
2013-03-22 05:47:20 +00:00
}
2010-05-31 00:21:08 +00:00
}
2010-05-25 09:15:19 +00:00
}
/********************** R4300i OpCodes: Special **********************/
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_SLL ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-10-23 18:53:01 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , GetMipsRegLo ( m_Opcode . rt ) < < m_Opcode . sa ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2010-05-30 01:54:42 +00:00
if ( m_Opcode . rd ! = m_Opcode . rt & & IsMapped ( m_Opcode . rt ) ) {
switch ( m_Opcode . sa ) {
2010-05-25 09:15:19 +00:00
case 0 :
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2010-05-25 09:15:19 +00:00
break ;
case 1 :
2010-05-30 01:54:42 +00:00
ProtectGPR ( m_Opcode . rt ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
LeaRegReg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rt ) , 0 , Multip_x2 ) ;
2015-05-02 22:14:19 +00:00
break ;
2010-05-25 09:15:19 +00:00
case 2 :
2010-05-30 01:54:42 +00:00
ProtectGPR ( m_Opcode . rt ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
LeaRegReg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rt ) , 0 , Multip_x4 ) ;
2015-05-02 22:14:19 +00:00
break ;
2010-05-25 09:15:19 +00:00
case 3 :
2010-05-30 01:54:42 +00:00
ProtectGPR ( m_Opcode . rt ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
LeaRegReg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rt ) , 0 , Multip_x8 ) ;
2010-05-25 09:15:19 +00:00
break ;
default :
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
ShiftLeftSignImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
ShiftLeftSignImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_SRL ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , GetMipsRegLo ( m_Opcode . rt ) > > m_Opcode . sa ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
ShiftRightUnsignImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_SRA ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , GetMipsRegLo_S ( m_Opcode . rt ) > > m_Opcode . sa ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
ShiftRightSignImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_SLLV ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
2012-11-06 08:19:22 +00:00
DWORD Shift = ( GetMipsRegLo ( m_Opcode . rs ) & 0x1F ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , GetMipsRegLo ( m_Opcode . rt ) < < Shift ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
ShiftLeftSignImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , ( BYTE ) Shift ) ;
2010-05-25 09:15:19 +00:00
}
return ;
}
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_ECX , m_Opcode . rs , false ) ;
AndConstToX86Reg ( x86_ECX , 0x1F ) ;
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
ShiftLeftSign ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_SRLV ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-09-22 21:43:42 +00:00
if ( IsKnown ( m_Opcode . rs ) & & IsConst ( m_Opcode . rs ) ) {
2012-11-06 08:19:22 +00:00
DWORD Shift = ( GetMipsRegLo ( m_Opcode . rs ) & 0x1F ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , GetMipsRegLo ( m_Opcode . rt ) > > Shift ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
ShiftRightUnsignImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , ( BYTE ) Shift ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_ECX , m_Opcode . rs , false ) ;
AndConstToX86Reg ( x86_ECX , 0x1F ) ;
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
ShiftRightUnsign ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_SRAV ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-09-22 21:43:42 +00:00
if ( IsKnown ( m_Opcode . rs ) & & IsConst ( m_Opcode . rs ) ) {
2012-11-06 08:19:22 +00:00
DWORD Shift = ( GetMipsRegLo ( m_Opcode . rs ) & 0x1F ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , GetMipsRegLo_S ( m_Opcode . rt ) > > Shift ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
ShiftRightSignImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , ( BYTE ) Shift ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_ECX , m_Opcode . rs , false ) ;
2010-05-25 09:15:19 +00:00
AndConstToX86Reg ( x86_ECX , 0x1F ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
ShiftRightSign ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_JR ( ) {
2015-05-02 22:14:19 +00:00
if ( m_NextInstruction = = NORMAL )
2012-09-26 00:55:09 +00:00
{
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( ( m_CompilePC & 0xFFC ) = = 0xFFC )
2012-09-25 05:58:06 +00:00
{
if ( IsMapped ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rs ) , & R4300iOp : : m_JumpToLocation , " R4300iOp::m_JumpToLocation " ) ;
2012-09-25 05:58:06 +00:00
m_RegWorkingSet . WriteBackRegisters ( ) ;
} else {
m_RegWorkingSet . WriteBackRegisters ( ) ;
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rs , false ) , & R4300iOp : : m_JumpToLocation , " R4300iOp::m_JumpToLocation " ) ;
2012-09-25 05:58:06 +00:00
}
2012-09-26 00:38:29 +00:00
OverflowDelaySlot ( true ) ;
2012-09-25 05:58:06 +00:00
return ;
}
2012-10-19 06:32:42 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Jump . LinkLocation = NULL ;
m_Section - > m_Jump . LinkLocation2 = NULL ;
2015-05-02 22:14:19 +00:00
m_Section - > m_Cont . FallThrough = false ;
2012-10-19 06:32:42 +00:00
m_Section - > m_Cont . LinkLocation = NULL ;
m_Section - > m_Cont . LinkLocation2 = NULL ;
2010-05-30 01:54:42 +00:00
if ( DelaySlotEffectsCompare ( m_CompilePC , m_Opcode . rs , 0 ) ) {
2015-05-02 22:14:19 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
MoveConstToVariable ( GetMipsRegLo ( m_Opcode . rs ) , _PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
} else if ( IsMapped ( m_Opcode . rs ) ) {
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rs ) , _PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rs , false ) , _PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
2010-05-25 09:15:19 +00:00
}
}
2010-05-30 01:54:42 +00:00
m_NextInstruction = DO_DELAY_SLOT ;
2015-05-02 22:14:19 +00:00
} else if ( m_NextInstruction = = DELAY_SLOT_DONE ) {
2010-05-30 01:54:42 +00:00
if ( DelaySlotEffectsCompare ( m_CompilePC , m_Opcode . rs , 0 ) ) {
2015-05-02 22:14:19 +00:00
m_Section - > CompileExit ( m_CompilePC , ( DWORD ) - 1 , m_RegWorkingSet , CExitInfo : : Normal , true , NULL ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-09-26 04:01:27 +00:00
UpdateCounters ( m_RegWorkingSet , true , true ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
MoveConstToVariable ( GetMipsRegLo ( m_Opcode . rs ) , _PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
2012-10-19 06:32:42 +00:00
} else if ( IsMapped ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rs ) , _PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rs , false ) , _PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
2012-10-19 06:32:42 +00:00
}
2015-05-02 22:14:19 +00:00
m_Section - > CompileExit ( ( DWORD ) - 1 , ( DWORD ) - 1 , m_RegWorkingSet , CExitInfo : : Normal , true , NULL ) ;
2012-10-19 06:32:42 +00:00
if ( m_Section - > m_JumpSection )
{
m_Section - > GenerateSectionLinkage ( ) ;
2010-05-25 09:15:19 +00:00
}
}
2010-05-30 01:54:42 +00:00
m_NextInstruction = END_BLOCK ;
2013-03-22 05:47:20 +00:00
} else if ( bHaveDebugger ( ) ) {
2015-03-04 09:36:08 +00:00
g_Notify - > DisplayError ( L " WTF \n \n Branch \n NextInstruction = %X " , m_NextInstruction ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_JALR ( )
2012-09-26 00:55:09 +00:00
{
2015-05-02 22:14:19 +00:00
if ( m_NextInstruction = = NORMAL )
2012-09-26 00:55:09 +00:00
{
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-02-03 06:36:42 +00:00
if ( DelaySlotEffectsCompare ( m_CompilePC , m_Opcode . rs , 0 ) & & ( m_CompilePC & 0xFFC ) ! = 0xFFC )
2012-09-26 00:55:09 +00:00
{
2015-05-02 22:14:19 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
MoveConstToVariable ( GetMipsRegLo ( m_Opcode . rs ) , _PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
} else if ( IsMapped ( m_Opcode . rs ) ) {
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rs ) , _PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
2015-02-03 06:36:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rs , false ) , _PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
2015-02-03 06:36:42 +00:00
}
2010-05-30 01:54:42 +00:00
}
2015-05-02 22:14:19 +00:00
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , m_CompilePC + 8 ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-09-26 00:55:09 +00:00
if ( ( m_CompilePC & 0xFFC ) = = 0xFFC )
{
2010-06-16 07:31:47 +00:00
if ( IsMapped ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rs ) , & R4300iOp : : m_JumpToLocation , " R4300iOp::m_JumpToLocation " ) ;
2012-09-26 00:55:09 +00:00
m_RegWorkingSet . WriteBackRegisters ( ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-09-26 00:55:09 +00:00
m_RegWorkingSet . WriteBackRegisters ( ) ;
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rs , false ) , & R4300iOp : : m_JumpToLocation , " R4300iOp::m_JumpToLocation " ) ;
2010-05-25 09:15:19 +00:00
}
2012-09-26 00:55:09 +00:00
OverflowDelaySlot ( true ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2013-01-14 06:12:11 +00:00
m_Section - > m_Jump . FallThrough = false ;
m_Section - > m_Jump . LinkLocation = NULL ;
m_Section - > m_Jump . LinkLocation2 = NULL ;
2015-05-02 22:14:19 +00:00
m_Section - > m_Cont . FallThrough = false ;
2013-01-14 06:12:11 +00:00
m_Section - > m_Cont . LinkLocation = NULL ;
m_Section - > m_Cont . LinkLocation2 = NULL ;
2010-05-30 01:54:42 +00:00
m_NextInstruction = DO_DELAY_SLOT ;
} else if ( m_NextInstruction = = DELAY_SLOT_DONE ) {
2015-02-03 06:36:42 +00:00
if ( DelaySlotEffectsCompare ( m_CompilePC , m_Opcode . rs , 0 ) ) {
2015-05-02 22:14:19 +00:00
m_Section - > CompileExit ( m_CompilePC , ( DWORD ) - 1 , m_RegWorkingSet , CExitInfo : : Normal , true , NULL ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-02-03 06:36:42 +00:00
UpdateCounters ( m_RegWorkingSet , true , true ) ;
if ( IsConst ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
MoveConstToVariable ( GetMipsRegLo ( m_Opcode . rs ) , _PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
2015-02-03 06:36:42 +00:00
} else if ( IsMapped ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rs ) , _PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
2015-02-03 06:36:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rs , false ) , _PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
2015-02-03 06:36:42 +00:00
}
2015-05-02 22:14:19 +00:00
m_Section - > CompileExit ( ( DWORD ) - 1 , ( DWORD ) - 1 , m_RegWorkingSet , CExitInfo : : Normal , true , NULL ) ;
2015-02-03 06:36:42 +00:00
if ( m_Section - > m_JumpSection )
{
m_Section - > GenerateSectionLinkage ( ) ;
}
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
m_NextInstruction = END_BLOCK ;
2013-03-22 05:47:20 +00:00
} else if ( bHaveDebugger ( ) ) {
2015-03-04 09:36:08 +00:00
g_Notify - > DisplayError ( L " WTF \n \n Branch \n NextInstruction = %X " , m_NextInstruction ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_SYSCALL ( ) {
2010-06-14 21:14:58 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
m_Section - > CompileExit ( m_CompilePC , ( DWORD ) - 1 , m_RegWorkingSet , CExitInfo : : DoSysCall , true , NULL ) ;
2010-06-14 21:14:58 +00:00
m_NextInstruction = END_BLOCK ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_MFLO ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
if ( m_Opcode . rd = = 0 ) { return ; }
2010-05-25 09:15:19 +00:00
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & _RegLO - > UW [ 0 ] , " _RegLO->UW[0] " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
MoveVariableToX86reg ( & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_MTLO ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2010-09-22 21:43:42 +00:00
if ( IsKnown ( m_Opcode . rs ) & & IsConst ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
MoveConstToVariable ( GetMipsRegHi ( m_Opcode . rs ) , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
2012-11-06 08:19:22 +00:00
} else if ( IsSigned ( m_Opcode . rs ) & & ( ( GetMipsRegLo ( m_Opcode . rs ) & 0x80000000 ) ! = 0 ) ) {
2010-05-25 09:15:19 +00:00
MoveConstToVariable ( 0xFFFFFFFF , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
} else {
MoveConstToVariable ( 0 , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
}
2012-11-06 08:19:22 +00:00
MoveConstToVariable ( GetMipsRegLo ( m_Opcode . rs ) , & _RegLO - > UW [ 0 ] , " _RegLO->UW[0] " ) ;
2010-09-22 21:43:42 +00:00
} else if ( IsKnown ( m_Opcode . rs ) & & IsMapped ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
MoveX86regToVariable ( GetMipsRegMapHi ( m_Opcode . rs ) , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
2010-09-22 21:43:42 +00:00
} else if ( IsSigned ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rs , true ) , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
2010-05-25 09:15:19 +00:00
} else {
MoveConstToVariable ( 0 , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
}
2012-11-03 01:18:08 +00:00
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rs ) , & _RegLO - > UW [ 0 ] , " _RegLO->UW[0] " ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
x86Reg reg = Map_TempReg ( x86_Any , m_Opcode . rs , true ) ;
2010-06-04 06:25:07 +00:00
MoveX86regToVariable ( reg , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( reg , m_Opcode . rs , false ) , & _RegLO - > UW [ 0 ] , " _RegLO->UW[0] " ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_MFHI ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
if ( m_Opcode . rd = = 0 ) { return ; }
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
MoveVariableToX86reg ( & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_MTHI ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-10-23 18:53:01 +00:00
2010-09-22 21:43:42 +00:00
if ( IsKnown ( m_Opcode . rs ) & & IsConst ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
MoveConstToVariable ( GetMipsRegHi ( m_Opcode . rs ) , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
2012-11-06 08:19:22 +00:00
} else if ( IsSigned ( m_Opcode . rs ) & & ( ( GetMipsRegLo ( m_Opcode . rs ) & 0x80000000 ) ! = 0 ) ) {
2010-05-25 09:15:19 +00:00
MoveConstToVariable ( 0xFFFFFFFF , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
} else {
MoveConstToVariable ( 0 , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
}
2012-11-06 08:19:22 +00:00
MoveConstToVariable ( GetMipsRegLo ( m_Opcode . rs ) , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
2010-09-22 21:43:42 +00:00
} else if ( IsKnown ( m_Opcode . rs ) & & IsMapped ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rs ) ) {
2012-11-03 01:18:08 +00:00
MoveX86regToVariable ( GetMipsRegMapHi ( m_Opcode . rs ) , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
2010-09-22 21:43:42 +00:00
} else if ( IsSigned ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rs , true ) , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
2010-05-25 09:15:19 +00:00
} else {
MoveConstToVariable ( 0 , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
}
2012-11-03 01:18:08 +00:00
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rs ) , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
x86Reg reg = Map_TempReg ( x86_Any , m_Opcode . rs , true ) ;
MoveX86regToVariable ( reg , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
MoveX86regToVariable ( Map_TempReg ( reg , m_Opcode . rs , false ) , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DSLLV ( ) {
2010-05-25 09:15:19 +00:00
BYTE * Jump [ 2 ] ;
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2012-10-06 04:09:17 +00:00
if ( IsConst ( m_Opcode . rs ) )
{
2012-11-06 08:19:22 +00:00
//DWORD Shift = (GetMipsRegLo(m_Opcode.rs) & 0x3F);
2010-05-30 01:54:42 +00:00
CRecompilerOps : : UnknownOpcode ( ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_ECX , m_Opcode . rs , false ) ;
2010-05-25 09:15:19 +00:00
AndConstToX86Reg ( x86_ECX , 0x3F ) ;
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rt ) ;
2010-05-25 09:15:19 +00:00
CompConstToX86reg ( x86_ECX , 0x20 ) ;
JaeLabel8 ( " MORE32 " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 0 ] = m_RecompPos - 1 ;
2012-11-03 01:18:08 +00:00
ShiftLeftDouble ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
ShiftLeftSign ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
JmpLabel8 ( " continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 1 ] = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
//MORE32:
CPU_Message ( " " ) ;
CPU_Message ( " MORE32: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
2012-11-03 01:18:08 +00:00
MoveX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
XorX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
AndConstToX86Reg ( x86_ECX , 0x1F ) ;
2012-11-03 01:18:08 +00:00
ShiftLeftSign ( GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
//continue:
CPU_Message ( " " ) ;
CPU_Message ( " continue: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DSRLV ( ) {
2010-05-25 09:15:19 +00:00
BYTE * Jump [ 2 ] ;
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rs ) ) {
2012-11-06 08:19:22 +00:00
DWORD Shift = ( GetMipsRegLo ( m_Opcode . rs ) & 0x3F ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsReg ( m_Opcode . rd , Is64Bit ( m_Opcode . rt ) ? GetMipsReg ( m_Opcode . rt ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rt ) ) ;
m_RegWorkingSet . SetMipsReg ( m_Opcode . rd , GetMipsReg ( m_Opcode . rd ) > > Shift ) ;
if ( ( GetMipsRegHi ( m_Opcode . rd ) = = 0 ) & & ( GetMipsRegLo ( m_Opcode . rd ) & 0x80000000 ) = = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-06 08:19:22 +00:00
} else if ( ( GetMipsRegHi ( m_Opcode . rd ) = = 0xFFFFFFFF ) & & ( GetMipsRegLo ( m_Opcode . rd ) & 0x80000000 ) ! = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_64 ) ;
2010-05-25 09:15:19 +00:00
}
return ;
}
2015-01-23 11:21:34 +00:00
if ( m_Opcode . rd = = m_Opcode . rt )
{
CRecompilerOps : : UnknownOpcode ( ) ;
return ;
}
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_ECX , - 1 , false ) ;
2015-01-23 11:21:34 +00:00
MoveConstToX86reg ( Shift , x86_ECX ) ;
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rt ) ;
if ( ( Shift & 0x20 ) = = 0x20 )
{
MoveX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
XorX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
AndConstToX86Reg ( x86_ECX , 0x1F ) ;
ShiftRightUnsign ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
} else {
ShiftRightDouble ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
ShiftRightUnsign ( GetMipsRegMapHi ( m_Opcode . rd ) ) ;
}
2010-06-12 02:02:06 +00:00
} else {
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_ECX , m_Opcode . rs , false ) ;
2010-06-12 02:02:06 +00:00
AndConstToX86Reg ( x86_ECX , 0x3F ) ;
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rt ) ;
CompConstToX86reg ( x86_ECX , 0x20 ) ;
JaeLabel8 ( " MORE32 " , 0 ) ;
Jump [ 0 ] = m_RecompPos - 1 ;
2012-11-03 01:18:08 +00:00
ShiftRightDouble ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
ShiftRightUnsign ( GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2010-06-12 02:02:06 +00:00
JmpLabel8 ( " continue " , 0 ) ;
Jump [ 1 ] = m_RecompPos - 1 ;
//MORE32:
CPU_Message ( " " ) ;
CPU_Message ( " MORE32: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
2012-11-03 01:18:08 +00:00
MoveX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
XorX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2010-06-12 02:02:06 +00:00
AndConstToX86Reg ( x86_ECX , 0x1F ) ;
2012-11-03 01:18:08 +00:00
ShiftRightUnsign ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
2010-06-12 02:02:06 +00:00
//continue:
CPU_Message ( " " ) ;
CPU_Message ( " continue: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
2010-06-12 02:02:06 +00:00
}
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DSRAV ( )
2012-11-05 10:08:33 +00:00
{
2010-05-25 09:15:19 +00:00
BYTE * Jump [ 2 ] ;
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2012-11-05 10:08:33 +00:00
if ( IsConst ( m_Opcode . rs ) )
{
2012-11-06 08:19:22 +00:00
//DWORD Shift = (GetMipsRegLo(m_Opcode.rs) & 0x3F);
2010-05-30 01:54:42 +00:00
CRecompilerOps : : UnknownOpcode ( ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_ECX , m_Opcode . rs , false ) ;
2010-05-25 09:15:19 +00:00
AndConstToX86Reg ( x86_ECX , 0x3F ) ;
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rt ) ;
2010-05-25 09:15:19 +00:00
CompConstToX86reg ( x86_ECX , 0x20 ) ;
JaeLabel8 ( " MORE32 " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 0 ] = m_RecompPos - 1 ;
2012-11-05 10:08:33 +00:00
ShiftRightDouble ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
ShiftRightSign ( GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
JmpLabel8 ( " continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 1 ] = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
//MORE32:
CPU_Message ( " " ) ;
CPU_Message ( " MORE32: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
MoveX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
ShiftRightSignImmed ( GetMipsRegMapHi ( m_Opcode . rd ) , 0x1F ) ;
2010-05-25 09:15:19 +00:00
AndConstToX86Reg ( x86_ECX , 0x1F ) ;
2012-11-05 10:08:33 +00:00
ShiftRightSign ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
//continue:
CPU_Message ( " " ) ;
CPU_Message ( " continue: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_MULT ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
m_RegWorkingSet . SetX86Protected ( x86_EDX , true ) ;
Map_TempReg ( x86_EAX , m_Opcode . rs , false ) ;
m_RegWorkingSet . SetX86Protected ( x86_EDX , false ) ;
Map_TempReg ( x86_EDX , m_Opcode . rt , false ) ;
2010-05-25 09:15:19 +00:00
imulX86reg ( x86_EDX ) ;
MoveX86regToVariable ( x86_EAX , & _RegLO - > UW [ 0 ] , " _RegLO->UW[0] " ) ;
MoveX86regToVariable ( x86_EDX , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
ShiftRightSignImmed ( x86_EAX , 31 ) ; /* paired */
ShiftRightSignImmed ( x86_EDX , 31 ) ;
MoveX86regToVariable ( x86_EAX , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
MoveX86regToVariable ( x86_EDX , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_MULTU ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
m_RegWorkingSet . SetX86Protected ( x86_EDX , true ) ;
Map_TempReg ( x86_EAX , m_Opcode . rs , false ) ;
m_RegWorkingSet . SetX86Protected ( x86_EDX , false ) ;
Map_TempReg ( x86_EDX , m_Opcode . rt , false ) ;
2010-05-25 09:15:19 +00:00
MulX86reg ( x86_EDX ) ;
MoveX86regToVariable ( x86_EAX , & _RegLO - > UW [ 0 ] , " _RegLO->UW[0] " ) ;
MoveX86regToVariable ( x86_EDX , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
ShiftRightSignImmed ( x86_EAX , 31 ) ; /* paired */
ShiftRightSignImmed ( x86_EDX , 31 ) ;
MoveX86regToVariable ( x86_EAX , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
MoveX86regToVariable ( x86_EDX , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DIV ( )
2012-09-30 13:07:00 +00:00
{
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo ( m_Opcode . rt ) = = 0 ) {
2010-05-25 09:15:19 +00:00
MoveConstToVariable ( 0 , & _RegLO - > UW [ 0 ] , " _RegLO->UW[0] " ) ;
MoveConstToVariable ( 0 , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
MoveConstToVariable ( 0 , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
MoveConstToVariable ( 0 , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
return ;
}
} else {
2010-05-30 01:54:42 +00:00
if ( IsMapped ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( m_Opcode . rt ) , 0 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-30 01:54:42 +00:00
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rt ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rt ] ) ;
2010-05-25 09:15:19 +00:00
}
2015-05-02 22:14:19 +00:00
m_Section - > CompileExit ( m_CompilePC , m_CompilePC , m_RegWorkingSet , CExitInfo : : DivByZero , false , JeLabel32 ) ;
2010-05-25 09:15:19 +00:00
}
/* lo = (SD)rs / (SD)rt;
hi = ( SD ) rs % ( SD ) rt ; */
2015-05-02 22:14:19 +00:00
m_RegWorkingSet . SetX86Protected ( x86_EDX , true ) ;
Map_TempReg ( x86_EAX , m_Opcode . rs , false ) ;
2010-05-25 09:15:19 +00:00
/* edx is the signed portion to eax */
2015-05-02 22:14:19 +00:00
m_RegWorkingSet . SetX86Protected ( x86_EDX , false ) ;
Map_TempReg ( x86_EDX , - 1 , false ) ;
2010-05-25 09:15:19 +00:00
MoveX86RegToX86Reg ( x86_EAX , x86_EDX ) ;
ShiftRightSignImmed ( x86_EDX , 31 ) ;
2010-05-30 01:54:42 +00:00
if ( IsMapped ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
idivX86reg ( GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
idivX86reg ( Map_TempReg ( x86_Any , m_Opcode . rt , false ) ) ;
2010-05-25 09:15:19 +00:00
}
MoveX86regToVariable ( x86_EAX , & _RegLO - > UW [ 0 ] , " _RegLO->UW[0] " ) ;
MoveX86regToVariable ( x86_EDX , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
ShiftRightSignImmed ( x86_EAX , 31 ) ; /* paired */
ShiftRightSignImmed ( x86_EDX , 31 ) ;
MoveX86regToVariable ( x86_EAX , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
MoveX86regToVariable ( x86_EDX , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DIVU ( ) {
2010-05-25 09:15:19 +00:00
BYTE * Jump [ 2 ] ;
2010-06-04 06:25:07 +00:00
x86Reg Reg ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo ( m_Opcode . rt ) = = 0 ) {
2010-05-25 09:15:19 +00:00
MoveConstToVariable ( 0 , & _RegLO - > UW [ 0 ] , " _RegLO->UW[0] " ) ;
MoveConstToVariable ( 0 , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
MoveConstToVariable ( 0 , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
MoveConstToVariable ( 0 , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
return ;
}
Jump [ 1 ] = NULL ;
} else {
2010-05-30 01:54:42 +00:00
if ( IsMapped ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( m_Opcode . rt ) , 0 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-30 01:54:42 +00:00
CompConstToVariable ( 0 , & _GPR [ m_Opcode . rt ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rt ] ) ;
2010-05-25 09:15:19 +00:00
}
JneLabel8 ( " NoExcept " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 0 ] = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
MoveConstToVariable ( 0 , & _RegLO - > UW [ 0 ] , " _RegLO->UW[0] " ) ;
MoveConstToVariable ( 0 , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
MoveConstToVariable ( 0 , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
MoveConstToVariable ( 0 , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
JmpLabel8 ( " EndDivu " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 1 ] = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " NoExcept: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
2010-05-25 09:15:19 +00:00
}
/* lo = (UD)rs / (UD)rt;
hi = ( UD ) rs % ( UD ) rt ; */
2015-05-02 22:14:19 +00:00
m_RegWorkingSet . SetX86Protected ( x86_EAX , true ) ;
Map_TempReg ( x86_EDX , 0 , false ) ;
m_RegWorkingSet . SetX86Protected ( x86_EAX , false ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_EAX , m_Opcode . rs , false ) ;
Reg = Map_TempReg ( x86_Any , m_Opcode . rt , false ) ;
2010-05-25 09:15:19 +00:00
2010-06-04 06:25:07 +00:00
DivX86reg ( Reg ) ;
2010-05-25 09:15:19 +00:00
MoveX86regToVariable ( x86_EAX , & _RegLO - > UW [ 0 ] , " _RegLO->UW[0] " ) ;
MoveX86regToVariable ( x86_EDX , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
/* wouldnt these be zero (???) */
ShiftRightSignImmed ( x86_EAX , 31 ) ; /* paired */
ShiftRightSignImmed ( x86_EDX , 31 ) ;
MoveX86regToVariable ( x86_EAX , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
MoveX86regToVariable ( x86_EDX , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
if ( Jump [ 1 ] ! = NULL ) {
CPU_Message ( " " ) ;
CPU_Message ( " EndDivu: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DMULT ( )
2010-06-22 20:36:28 +00:00
{
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rs ! = 0 )
UnMap_GPR ( m_Opcode . rs , true ) ;
if ( m_Opcode . rs ! = 0 )
UnMap_GPR ( m_Opcode . rt , true ) ;
2010-06-22 20:36:28 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2010-06-04 06:25:07 +00:00
MoveConstToVariable ( m_Opcode . Hex , & R4300iOp : : m_Opcode . Hex , " R4300iOp::m_Opcode.Hex " ) ;
2010-05-25 09:15:19 +00:00
Call_Direct ( R4300iOp : : SPECIAL_DMULT , " R4300iOp::SPECIAL_DMULT " ) ;
2010-06-22 20:36:28 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DMULTU ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
UnMap_GPR ( m_Opcode . rs , true ) ;
UnMap_GPR ( m_Opcode . rt , true ) ;
2010-06-22 20:36:28 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
MoveConstToVariable ( m_Opcode . Hex , & R4300iOp : : m_Opcode . Hex , " R4300iOp::m_Opcode.Hex " ) ;
Call_Direct ( R4300iOp : : SPECIAL_DMULTU , " R4300iOp::SPECIAL_DMULTU " ) ;
AfterCallDirect ( m_RegWorkingSet ) ;
# ifdef toremove
2010-05-30 01:54:42 +00:00
/* _RegLO->UDW = (uint64)_GPR[m_Opcode.rs].UW[0] * (uint64)_GPR[m_Opcode.rt].UW[0]; */
2015-05-02 22:14:19 +00:00
X86Protected ( x86_EDX ) = true ;
Map_TempReg ( x86_EAX , m_Opcode . rs , false ) ;
X86Protected ( x86_EDX ) = false ;
Map_TempReg ( x86_EDX , m_Opcode . rt , false ) ;
2010-05-25 09:15:19 +00:00
MulX86reg ( x86_EDX ) ;
MoveX86regToVariable ( x86_EAX , & _RegLO - > UW [ 0 ] , " _RegLO->UW[0] " ) ;
MoveX86regToVariable ( x86_EDX , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
2010-05-30 01:54:42 +00:00
/* _RegHI->UDW = (uint64)_GPR[m_Opcode.rs].UW[1] * (uint64)_GPR[m_Opcode.rt].UW[1]; */
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_EAX , m_Opcode . rs , true ) ;
Map_TempReg ( x86_EDX , m_Opcode . rt , true ) ;
2010-05-25 09:15:19 +00:00
MulX86reg ( x86_EDX ) ;
MoveX86regToVariable ( x86_EAX , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
MoveX86regToVariable ( x86_EDX , & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " ) ;
2010-05-30 01:54:42 +00:00
/* Tmp[0].UDW = (uint64)_GPR[m_Opcode.rs].UW[1] * (uint64)_GPR[m_Opcode.rt].UW[0]; */
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_EAX , m_Opcode . rs , true ) ;
Map_TempReg ( x86_EDX , m_Opcode . rt , false ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_EBX , - 1 , false ) ;
Map_TempReg ( x86_ECX , - 1 , false ) ;
2010-05-25 09:15:19 +00:00
MulX86reg ( x86_EDX ) ;
MoveX86RegToX86Reg ( x86_EAX , x86_EBX ) ; /* EDX:EAX -> ECX:EBX */
MoveX86RegToX86Reg ( x86_EDX , x86_ECX ) ;
2010-05-30 01:54:42 +00:00
/* Tmp[1].UDW = (uint64)_GPR[m_Opcode.rs].UW[0] * (uint64)_GPR[m_Opcode.rt].UW[1]; */
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_EAX , m_Opcode . rs , false ) ;
Map_TempReg ( x86_EDX , m_Opcode . rt , true ) ;
2010-05-25 09:15:19 +00:00
MulX86reg ( x86_EDX ) ;
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_ESI , - 1 , false ) ;
Map_TempReg ( x86_EDI , - 1 , false ) ;
2010-05-25 09:15:19 +00:00
MoveX86RegToX86Reg ( x86_EAX , x86_ESI ) ; /* EDX:EAX -> EDI:ESI */
MoveX86RegToX86Reg ( x86_EDX , x86_EDI ) ;
/* Tmp[2].UDW = (uint64)_RegLO->UW[1] + (uint64)Tmp[0].UW[0] + (uint64)Tmp[1].UW[0]; */
XorX86RegToX86Reg ( x86_EDX , x86_EDX ) ;
MoveVariableToX86reg ( & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " , x86_EAX ) ;
AddX86RegToX86Reg ( x86_EAX , x86_EBX ) ;
AddConstToX86Reg ( x86_EDX , 0 ) ;
AddX86RegToX86Reg ( x86_EAX , x86_ESI ) ;
AddConstToX86Reg ( x86_EDX , 0 ) ; /* EDX:EAX */
/* _RegLO->UDW += ((uint64)Tmp[0].UW[0] + (uint64)Tmp[1].UW[0]) << 32; */
/* [low+4] += ebx + esi */
AddX86regToVariable ( x86_EBX , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
AddX86regToVariable ( x86_ESI , & _RegLO - > UW [ 1 ] , " _RegLO->UW[1] " ) ;
/* _RegHI->UDW += (uint64)Tmp[0].UW[1] + (uint64)Tmp[1].UW[1] + Tmp[2].UW[1]; */
/* [hi] += ecx + edi + edx */
AddX86regToVariable ( x86_ECX , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
AdcConstToVariable ( & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " , 0 ) ;
AddX86regToVariable ( x86_EDI , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
AdcConstToVariable ( & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " , 0 ) ;
AddX86regToVariable ( x86_EDX , & _RegHI - > UW [ 0 ] , " _RegHI->UW[0] " ) ;
AdcConstToVariable ( & _RegHI - > UW [ 1 ] , " _RegHI->UW[1] " , 0 ) ;
2010-06-22 20:36:28 +00:00
# endif
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DDIV ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
UnMap_GPR ( m_Opcode . rs , true ) ;
UnMap_GPR ( m_Opcode . rt , true ) ;
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2010-06-04 06:25:07 +00:00
MoveConstToVariable ( m_Opcode . Hex , & R4300iOp : : m_Opcode . Hex , " R4300iOp::m_Opcode.Hex " ) ;
2010-05-25 09:15:19 +00:00
Call_Direct ( R4300iOp : : SPECIAL_DDIV , " R4300iOp::SPECIAL_DDIV " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DDIVU ( )
2010-06-04 06:25:07 +00:00
{
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
UnMap_GPR ( m_Opcode . rs , true ) ;
UnMap_GPR ( m_Opcode . rt , true ) ;
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2010-06-04 06:25:07 +00:00
MoveConstToVariable ( m_Opcode . Hex , & R4300iOp : : m_Opcode . Hex , " R4300iOp::m_Opcode.Hex " ) ;
2010-05-25 09:15:19 +00:00
Call_Direct ( R4300iOp : : SPECIAL_DDIVU , " R4300iOp::SPECIAL_DDIVU " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_ADD ( ) {
2010-05-30 01:54:42 +00:00
int source1 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rt : m_Opcode . rs ;
int source2 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( source1 ) & & IsConst ( source2 ) ) {
2012-11-06 08:19:22 +00:00
DWORD temp = GetMipsRegLo ( source1 ) + GetMipsRegLo ( source2 ) ;
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , temp ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , source1 ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( source2 ) ) {
2012-11-06 08:19:22 +00:00
AddConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegLo ( source2 ) ) ;
2010-09-22 21:43:42 +00:00
} else if ( IsKnown ( source2 ) & & IsMapped ( source2 ) ) {
2012-11-03 01:18:08 +00:00
AddX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( source2 ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
AddVariableToX86reg ( GetMipsRegMapLo ( m_Opcode . rd ) , & _GPR [ source2 ] . W [ 0 ] , CRegName : : GPR_Lo [ source2 ] ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-29 11:23:35 +00:00
if ( g_System - > bFastSP ( ) & & m_Opcode . rd = = 29 )
2012-09-27 23:02:01 +00:00
{
2012-11-17 01:18:00 +00:00
g_MMU - > ResetMemoryStack ( ) ;
2012-09-27 23:02:01 +00:00
}
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_ADDU ( ) {
2010-05-30 01:54:42 +00:00
int source1 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rt : m_Opcode . rs ;
int source2 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( source1 ) & & IsConst ( source2 ) ) {
2012-11-06 08:19:22 +00:00
DWORD temp = GetMipsRegLo ( source1 ) + GetMipsRegLo ( source2 ) ;
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , temp ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , source1 ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( source2 ) ) {
2012-11-06 08:19:22 +00:00
AddConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegLo ( source2 ) ) ;
2010-09-22 21:43:42 +00:00
} else if ( IsKnown ( source2 ) & & IsMapped ( source2 ) ) {
2012-11-03 01:18:08 +00:00
AddX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( source2 ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
AddVariableToX86reg ( GetMipsRegMapLo ( m_Opcode . rd ) , & _GPR [ source2 ] . W [ 0 ] , CRegName : : GPR_Lo [ source2 ] ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-29 11:23:35 +00:00
if ( g_System - > bFastSP ( ) & & m_Opcode . rd = = 29 )
2012-09-27 23:02:01 +00:00
{
2012-11-17 01:18:00 +00:00
g_MMU - > ResetMemoryStack ( ) ;
2012-09-27 23:02:01 +00:00
}
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_SUB ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) & & IsConst ( m_Opcode . rs ) ) {
2012-11-06 08:19:22 +00:00
DWORD temp = GetMipsRegLo ( m_Opcode . rs ) - GetMipsRegLo ( m_Opcode . rt ) ;
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , temp ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-30 01:54:42 +00:00
if ( m_Opcode . rd = = m_Opcode . rt ) {
2015-05-02 22:14:19 +00:00
x86Reg Reg = Map_TempReg ( x86_Any , m_Opcode . rt , false ) ;
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rs ) ;
2012-11-03 01:18:08 +00:00
SubX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , Reg ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rs ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-06 08:19:22 +00:00
SubConstFromX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegLo ( m_Opcode . rt ) ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
SubX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
SubVariableFromX86reg ( GetMipsRegMapLo ( m_Opcode . rd ) , & _GPR [ m_Opcode . rt ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rt ] ) ;
2010-05-25 09:15:19 +00:00
}
}
2012-11-29 11:23:35 +00:00
if ( g_System - > bFastSP ( ) & & m_Opcode . rd = = 29 )
2012-09-27 23:02:01 +00:00
{
2012-11-17 01:18:00 +00:00
g_MMU - > ResetMemoryStack ( ) ;
2012-09-27 23:02:01 +00:00
}
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_SUBU ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) & & IsConst ( m_Opcode . rs ) ) {
2012-11-06 08:19:22 +00:00
DWORD temp = GetMipsRegLo ( m_Opcode . rs ) - GetMipsRegLo ( m_Opcode . rt ) ;
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , temp ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-30 01:54:42 +00:00
if ( m_Opcode . rd = = m_Opcode . rt ) {
2015-05-02 22:14:19 +00:00
x86Reg Reg = Map_TempReg ( x86_Any , m_Opcode . rt , false ) ;
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rs ) ;
2012-11-03 01:18:08 +00:00
SubX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , Reg ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rs ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-06 08:19:22 +00:00
SubConstFromX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegLo ( m_Opcode . rt ) ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
SubX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
SubVariableFromX86reg ( GetMipsRegMapLo ( m_Opcode . rd ) , & _GPR [ m_Opcode . rt ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rt ] ) ;
2010-05-25 09:15:19 +00:00
}
}
2012-09-27 22:55:45 +00:00
2012-11-29 11:23:35 +00:00
if ( g_System - > bFastSP ( ) & & m_Opcode . rd = = 29 )
2012-09-27 22:55:45 +00:00
{
2012-11-17 01:18:00 +00:00
g_MMU - > ResetMemoryStack ( ) ;
2012-09-27 22:55:45 +00:00
}
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_AND ( )
2010-06-04 06:25:07 +00:00
{
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-10-23 18:53:01 +00:00
2010-09-22 21:43:42 +00:00
if ( IsKnown ( m_Opcode . rt ) & & IsKnown ( m_Opcode . rs ) ) {
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) & & IsConst ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsReg ( m_Opcode . rd ,
2012-11-06 08:19:22 +00:00
( Is64Bit ( m_Opcode . rt ) ? GetMipsReg ( m_Opcode . rt ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rt ) ) &
( Is64Bit ( m_Opcode . rs ) ? GetMipsReg ( m_Opcode . rs ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rs ) )
2012-10-04 11:01:10 +00:00
) ;
2010-05-25 09:15:19 +00:00
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rd ) < 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = - 1 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-03 01:18:08 +00:00
} else if ( GetMipsRegLo_S ( m_Opcode . rd ) > = 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_64 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsReg ( m_Opcode . rd , GetMipsRegLo ( m_Opcode . rt ) & GetMipsReg ( m_Opcode . rs ) ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) & & IsMapped ( m_Opcode . rs ) ) {
int source1 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rt : m_Opcode . rs ;
int source2 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
ProtectGPR ( source1 ) ;
ProtectGPR ( source2 ) ;
2010-09-22 21:43:42 +00:00
if ( Is32Bit ( source1 ) & & Is32Bit ( source2 ) ) {
2015-05-02 22:14:19 +00:00
bool Sign = ( IsSigned ( m_Opcode . rt ) & & IsSigned ( m_Opcode . rs ) ) ;
Map_GPR_32bit ( m_Opcode . rd , Sign , source1 ) ;
2012-11-03 01:18:08 +00:00
AndX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( source2 ) ) ;
2010-09-22 21:43:42 +00:00
} else if ( Is32Bit ( source1 ) | | Is32Bit ( source2 ) ) {
if ( IsUnsigned ( Is32Bit ( source1 ) ? source1 : source2 ) ) {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , false , source1 ) ;
2012-11-03 01:18:08 +00:00
AndX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( source2 ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , source1 ) ;
2010-09-22 21:43:42 +00:00
if ( Is32Bit ( source2 ) ) {
2015-05-02 22:14:19 +00:00
AndX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , Map_TempReg ( x86_Any , source2 , true ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
AndX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegMapHi ( source2 ) ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-03 01:18:08 +00:00
AndX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( source2 ) ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , source1 ) ;
2012-11-03 01:18:08 +00:00
AndX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegMapHi ( source2 ) ) ;
AndX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( source2 ) ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-05-30 01:54:42 +00:00
int ConstReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
int MappedReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( ConstReg ) ) {
2010-09-22 21:43:42 +00:00
if ( Is32Bit ( MappedReg ) & & IsUnsigned ( MappedReg ) ) {
2012-11-06 08:19:22 +00:00
if ( GetMipsRegLo ( ConstReg ) = = 0 ) {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , false , 0 ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-06 08:19:22 +00:00
DWORD Value = GetMipsRegLo ( ConstReg ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , false , MappedReg ) ;
2012-11-03 01:18:08 +00:00
AndConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , Value ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-06 08:19:22 +00:00
__int64 Value = GetMipsReg ( ConstReg ) ;
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , MappedReg ) ;
2012-11-03 01:18:08 +00:00
AndConstToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , ( DWORD ) ( Value > > 32 ) ) ;
2013-03-26 11:28:49 +00:00
AndConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , ( DWORD ) ( Value & 0xFFFFFFFF ) ) ;
2010-05-25 09:15:19 +00:00
}
2010-06-04 06:25:07 +00:00
} else if ( Is64Bit ( MappedReg ) ) {
2012-11-06 08:19:22 +00:00
DWORD Value = GetMipsRegLo ( ConstReg ) ;
2010-05-25 09:15:19 +00:00
if ( Value ! = 0 ) {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , IsSigned ( ConstReg ) , MappedReg ) ;
2013-03-26 11:28:49 +00:00
AndConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , Value ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , IsSigned ( ConstReg ) , 0 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-06 08:19:22 +00:00
DWORD Value = GetMipsRegLo ( ConstReg ) ;
2012-10-22 10:36:57 +00:00
bool Sign = false ;
2015-05-02 22:14:19 +00:00
if ( IsSigned ( ConstReg ) & & IsSigned ( MappedReg ) )
Sign = true ;
2010-05-25 09:15:19 +00:00
if ( Value ! = 0 ) {
2010-05-30 01:54:42 +00:00
Map_GPR_32bit ( m_Opcode . rd , Sign , MappedReg ) ;
2012-11-03 01:18:08 +00:00
AndConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , Value ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , false , 0 ) ;
2010-05-25 09:15:19 +00:00
}
}
}
2010-09-22 21:43:42 +00:00
} else if ( IsKnown ( m_Opcode . rt ) | | IsKnown ( m_Opcode . rs ) ) {
DWORD KnownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
DWORD UnknownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( KnownReg ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( KnownReg ) ) {
2012-11-06 08:19:22 +00:00
unsigned __int64 Value = GetMipsReg ( KnownReg ) ;
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , UnknownReg ) ;
2012-11-03 01:18:08 +00:00
AndConstToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , ( DWORD ) ( Value > > 32 ) ) ;
2013-03-26 11:28:49 +00:00
AndConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , ( DWORD ) ( Value & 0xFFFFFFFF ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-06 08:19:22 +00:00
DWORD Value = GetMipsRegLo ( KnownReg ) ;
2010-09-22 21:43:42 +00:00
Map_GPR_32bit ( m_Opcode . rd , IsSigned ( KnownReg ) , UnknownReg ) ;
2013-03-26 11:28:49 +00:00
AndConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , Value ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-05-30 01:54:42 +00:00
ProtectGPR ( KnownReg ) ;
if ( KnownReg = = m_Opcode . rd ) {
2013-03-08 20:55:36 +00:00
if ( Is64Bit ( KnownReg ) | | ! g_System - > b32BitCore ( ) ) {
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , KnownReg ) ;
2012-11-03 01:18:08 +00:00
AndVariableToX86Reg ( & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
AndVariableToX86Reg ( & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-09-22 21:43:42 +00:00
Map_GPR_32bit ( m_Opcode . rd , IsSigned ( KnownReg ) , KnownReg ) ;
2012-11-03 01:18:08 +00:00
AndVariableToX86Reg ( & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( KnownReg ) ) {
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , UnknownReg ) ;
2012-11-03 01:18:08 +00:00
AndX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegMapHi ( KnownReg ) ) ;
AndX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( KnownReg ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-09-22 21:43:42 +00:00
Map_GPR_32bit ( m_Opcode . rd , IsSigned ( KnownReg ) , UnknownReg ) ;
2012-11-03 01:18:08 +00:00
AndX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( KnownReg ) ) ;
2010-05-25 09:15:19 +00:00
}
}
}
} else {
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
} else {
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
AndVariableToX86Reg ( & _GPR [ m_Opcode . rs ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rs ] , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2010-10-23 18:53:01 +00:00
}
2012-11-03 01:18:08 +00:00
AndVariableToX86Reg ( & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-30 01:54:42 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_OR ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-09-22 21:43:42 +00:00
if ( IsKnown ( m_Opcode . rt ) & & IsKnown ( m_Opcode . rs ) ) {
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) & & IsConst ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsReg ( m_Opcode . rd ,
2012-11-06 08:19:22 +00:00
( Is64Bit ( m_Opcode . rt ) ? GetMipsReg ( m_Opcode . rt ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rt ) ) |
( Is64Bit ( m_Opcode . rs ) ? GetMipsReg ( m_Opcode . rs ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rs ) )
2012-10-04 11:01:10 +00:00
) ;
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rd ) < 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = - 1 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-03 01:18:08 +00:00
} else if ( GetMipsRegLo_S ( m_Opcode . rd ) > = 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_64 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , GetMipsRegLo ( m_Opcode . rt ) | GetMipsRegLo ( m_Opcode . rs ) ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) & & IsMapped ( m_Opcode . rs ) ) {
int source1 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rt : m_Opcode . rs ;
int source2 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
ProtectGPR ( m_Opcode . rt ) ;
ProtectGPR ( m_Opcode . rs ) ;
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , source1 ) ;
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( source2 ) ) {
2012-11-03 01:18:08 +00:00
OrX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegMapHi ( source2 ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
OrX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , Map_TempReg ( x86_Any , source2 , true ) ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-05-30 01:54:42 +00:00
ProtectGPR ( source2 ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , source1 ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-03 01:18:08 +00:00
OrX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( source2 ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-30 01:54:42 +00:00
DWORD ConstReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
DWORD MappedReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
unsigned __int64 Value ;
2010-05-25 09:15:19 +00:00
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( ConstReg ) ) {
2012-11-06 08:19:22 +00:00
Value = GetMipsReg ( ConstReg ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-06 08:19:22 +00:00
Value = IsSigned ( ConstReg ) ? ( __int64 ) GetMipsRegLo_S ( ConstReg ) : GetMipsRegLo ( ConstReg ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , MappedReg ) ;
2010-05-25 09:15:19 +00:00
if ( ( Value > > 32 ) ! = 0 ) {
2012-11-03 01:18:08 +00:00
OrConstToX86Reg ( ( DWORD ) ( Value > > 32 ) , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
2013-03-26 11:28:49 +00:00
DWORD dwValue = ( DWORD ) ( Value & 0xFFFFFFFF ) ;
if ( dwValue ! = 0 ) {
OrConstToX86Reg ( dwValue , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-06 08:19:22 +00:00
int Value = GetMipsRegLo ( ConstReg ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , MappedReg ) ;
2012-11-03 01:18:08 +00:00
if ( Value ! = 0 ) { OrConstToX86Reg ( Value , GetMipsRegMapLo ( m_Opcode . rd ) ) ; }
2010-05-25 09:15:19 +00:00
}
}
2010-09-22 21:43:42 +00:00
} else if ( IsKnown ( m_Opcode . rt ) | | IsKnown ( m_Opcode . rs ) ) {
int KnownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
int UnknownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2013-03-26 11:28:49 +00:00
if ( IsConst ( KnownReg ) )
{
unsigned __int64 Value = Is64Bit ( KnownReg ) ? GetMipsReg ( KnownReg ) : GetMipsRegLo_S ( KnownReg ) ;
DWORD dwValue = ( DWORD ) ( Value & 0xFFFFFFFF ) ;
2010-10-23 18:53:01 +00:00
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) & & Is32Bit ( KnownReg ) )
2010-10-23 18:53:01 +00:00
{
Map_GPR_32bit ( m_Opcode . rd , true , UnknownReg ) ;
2013-03-26 11:28:49 +00:00
if ( dwValue ! = 0 ) {
OrConstToX86Reg ( dwValue , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-10-23 18:53:01 +00:00
}
} else {
Map_GPR_64bit ( m_Opcode . rd , UnknownReg ) ;
if ( ( Value > > 32 ) ! = 0 ) {
2012-11-03 01:18:08 +00:00
OrConstToX86Reg ( ( DWORD ) ( Value > > 32 ) , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2010-10-23 18:53:01 +00:00
}
2013-03-26 11:28:49 +00:00
if ( dwValue ! = 0 ) {
OrConstToX86Reg ( dwValue , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-10-23 18:53:01 +00:00
}
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
Map_GPR_32bit ( m_Opcode . rd , true , KnownReg ) ;
2012-11-03 01:18:08 +00:00
OrVariableToX86Reg ( & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-10-23 18:53:01 +00:00
} else {
Map_GPR_64bit ( m_Opcode . rd , KnownReg ) ;
2012-11-03 01:18:08 +00:00
OrVariableToX86Reg ( & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
OrVariableToX86Reg ( & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-10-23 18:53:01 +00:00
}
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
OrVariableToX86Reg ( & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-10-23 18:53:01 +00:00
} else {
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
OrVariableToX86Reg ( & _GPR [ m_Opcode . rs ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rs ] , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
OrVariableToX86Reg ( & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-10-23 18:53:01 +00:00
}
2010-05-25 09:15:19 +00:00
}
2012-11-29 11:23:35 +00:00
if ( g_System - > bFastSP ( ) & & m_Opcode . rd = = 29 ) {
2010-06-04 06:25:07 +00:00
ResetX86Protection ( ) ;
2012-11-17 01:18:00 +00:00
g_MMU - > ResetMemoryStack ( ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_XOR ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( m_Opcode . rt = = m_Opcode . rs ) {
2015-05-02 22:14:19 +00:00
UnMap_GPR ( m_Opcode . rd , false ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , 0 ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2010-09-22 21:43:42 +00:00
if ( IsKnown ( m_Opcode . rt ) & & IsKnown ( m_Opcode . rs ) ) {
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) & & IsConst ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
2015-03-04 09:36:08 +00:00
if ( bHaveDebugger ( ) ) { g_Notify - > DisplayError ( L " XOR 1 " ) ; }
2010-05-30 01:54:42 +00:00
CRecompilerOps : : UnknownOpcode ( ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , GetMipsRegLo ( m_Opcode . rt ) ^ GetMipsRegLo ( m_Opcode . rs ) ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) & & IsMapped ( m_Opcode . rs ) ) {
int source1 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rt : m_Opcode . rs ;
int source2 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
ProtectGPR ( source1 ) ;
ProtectGPR ( source2 ) ;
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , source1 ) ;
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( source2 ) ) {
2012-11-03 01:18:08 +00:00
XorX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegMapHi ( source2 ) ) ;
2010-09-22 21:43:42 +00:00
} else if ( IsSigned ( source2 ) ) {
2015-05-02 22:14:19 +00:00
XorX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , Map_TempReg ( x86_Any , source2 , true ) ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-03 01:18:08 +00:00
XorX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( source2 ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-09-22 21:43:42 +00:00
if ( IsSigned ( m_Opcode . rt ) ! = IsSigned ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , source1 ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-09-22 21:43:42 +00:00
Map_GPR_32bit ( m_Opcode . rd , IsSigned ( m_Opcode . rt ) , source1 ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-03 01:18:08 +00:00
XorX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( source2 ) ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-05-30 01:54:42 +00:00
DWORD ConstReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
DWORD MappedReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
2010-05-25 09:15:19 +00:00
DWORD ConstHi , ConstLo ;
2012-11-03 01:18:08 +00:00
ConstHi = Is32Bit ( ConstReg ) ? ( DWORD ) ( GetMipsRegLo_S ( ConstReg ) > > 31 ) : GetMipsRegHi ( ConstReg ) ;
2012-11-06 08:19:22 +00:00
ConstLo = GetMipsRegLo ( ConstReg ) ;
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , MappedReg ) ;
2012-11-03 01:18:08 +00:00
if ( ConstHi ! = 0 ) { XorConstToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , ConstHi ) ; }
if ( ConstLo ! = 0 ) { XorConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , ConstLo ) ; }
2010-05-25 09:15:19 +00:00
} else {
2012-11-06 08:19:22 +00:00
int Value = GetMipsRegLo ( ConstReg ) ;
2010-09-22 21:43:42 +00:00
if ( IsSigned ( m_Opcode . rt ) ! = IsSigned ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , MappedReg ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , IsSigned ( MappedReg ) , MappedReg ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-03 01:18:08 +00:00
if ( Value ! = 0 ) { XorConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , Value ) ; }
2010-05-25 09:15:19 +00:00
}
}
2010-09-22 21:43:42 +00:00
} else if ( IsKnown ( m_Opcode . rt ) | | IsKnown ( m_Opcode . rs ) ) {
int KnownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
int UnknownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( KnownReg ) ) {
2010-06-04 06:25:07 +00:00
unsigned __int64 Value ;
2010-05-25 09:15:19 +00:00
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( KnownReg ) ) {
2012-11-06 08:19:22 +00:00
Value = GetMipsReg ( KnownReg ) ;
2010-10-23 18:53:01 +00:00
Map_GPR_64bit ( m_Opcode . rd , UnknownReg ) ;
if ( ( Value > > 32 ) ! = 0 ) {
2012-11-03 01:18:08 +00:00
XorConstToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , ( DWORD ) ( Value > > 32 ) ) ;
2010-10-23 18:53:01 +00:00
}
2010-05-25 09:15:19 +00:00
} else {
2010-10-23 18:53:01 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , UnknownReg ) ;
2010-09-22 21:43:42 +00:00
if ( IsSigned ( KnownReg ) ) {
2012-11-06 08:19:22 +00:00
Value = ( int ) GetMipsRegLo ( KnownReg ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-06 08:19:22 +00:00
Value = GetMipsRegLo ( KnownReg ) ;
2010-05-25 09:15:19 +00:00
}
}
2013-03-26 11:28:49 +00:00
DWORD dwValue = ( DWORD ) ( Value & 0xFFFFFFFF ) ;
if ( dwValue ! = 0 ) {
XorConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , dwValue ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
Map_GPR_32bit ( m_Opcode . rd , true , KnownReg ) ;
2012-11-03 01:18:08 +00:00
XorVariableToX86reg ( & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-10-23 18:53:01 +00:00
} else {
Map_GPR_64bit ( m_Opcode . rd , KnownReg ) ;
2012-11-03 01:18:08 +00:00
XorVariableToX86reg ( & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
XorVariableToX86reg ( & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-10-23 18:53:01 +00:00
}
2010-05-25 09:15:19 +00:00
}
2012-11-29 11:23:35 +00:00
} else if ( g_System - > b32BitCore ( ) ) {
2010-10-23 18:53:01 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
XorVariableToX86reg ( & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
XorVariableToX86reg ( & _GPR [ m_Opcode . rs ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rs ] , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
XorVariableToX86reg ( & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_NOR ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2010-09-22 21:43:42 +00:00
if ( IsKnown ( m_Opcode . rt ) & & IsKnown ( m_Opcode . rs ) ) {
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) & & IsConst ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsReg ( m_Opcode . rd ,
2012-11-06 08:19:22 +00:00
~ ( ( Is64Bit ( m_Opcode . rt ) ? GetMipsReg ( m_Opcode . rt ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rt ) ) |
( Is64Bit ( m_Opcode . rs ) ? GetMipsReg ( m_Opcode . rs ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rs ) ) )
2012-10-04 11:01:10 +00:00
) ;
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rd ) < 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = - 1 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-03 01:18:08 +00:00
} else if ( GetMipsRegLo_S ( m_Opcode . rd ) > = 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-10-02 23:03:21 +00:00
} else {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_64 ) ;
2012-10-02 23:03:21 +00:00
}
2010-05-25 09:15:19 +00:00
} else {
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , ~ ( GetMipsRegLo ( m_Opcode . rt ) | GetMipsRegLo ( m_Opcode . rs ) ) ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) & & IsMapped ( m_Opcode . rs ) ) {
int source1 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rt : m_Opcode . rs ;
int source2 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rs : m_Opcode . rt ;
2012-10-02 23:03:21 +00:00
ProtectGPR ( m_Opcode . rt ) ;
ProtectGPR ( m_Opcode . rs ) ;
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , source1 ) ;
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( source2 ) ) {
2012-11-03 01:18:08 +00:00
OrX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegMapHi ( source2 ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
OrX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , Map_TempReg ( x86_Any , source2 , true ) ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-05-30 01:54:42 +00:00
ProtectGPR ( source2 ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , source1 ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-03 01:18:08 +00:00
OrX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( source2 ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-30 01:54:42 +00:00
DWORD ConstReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
DWORD MappedReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2012-10-02 23:03:21 +00:00
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
unsigned __int64 Value ;
2010-05-25 09:15:19 +00:00
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( ConstReg ) ) {
2012-11-06 08:19:22 +00:00
Value = GetMipsReg ( ConstReg ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-06 08:19:22 +00:00
Value = IsSigned ( ConstReg ) ? ( __int64 ) GetMipsRegLo_S ( ConstReg ) : GetMipsRegLo ( ConstReg ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , MappedReg ) ;
2010-05-25 09:15:19 +00:00
if ( ( Value > > 32 ) ! = 0 ) {
2012-11-03 01:18:08 +00:00
OrConstToX86Reg ( ( DWORD ) ( Value > > 32 ) , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
2013-03-26 11:28:49 +00:00
DWORD dwValue = ( DWORD ) ( Value & 0xFFFFFFFF ) ;
if ( dwValue ! = 0 ) {
OrConstToX86Reg ( dwValue , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-06 08:19:22 +00:00
int Value = GetMipsRegLo ( ConstReg ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , MappedReg ) ;
2012-11-03 01:18:08 +00:00
if ( Value ! = 0 ) { OrConstToX86Reg ( Value , GetMipsRegMapLo ( m_Opcode . rd ) ) ; }
2010-05-25 09:15:19 +00:00
}
}
2010-09-22 21:43:42 +00:00
} else if ( IsKnown ( m_Opcode . rt ) | | IsKnown ( m_Opcode . rs ) ) {
int KnownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
int UnknownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2012-10-02 23:03:21 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( KnownReg ) ) {
2013-03-26 11:28:49 +00:00
unsigned __int64 Value = Is64Bit ( KnownReg ) ? GetMipsReg ( KnownReg ) : GetMipsRegLo_S ( KnownReg ) ;
DWORD dwValue = ( DWORD ) ( Value & 0xFFFFFFFF ) ;
2012-10-02 23:03:21 +00:00
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) & & Is32Bit ( KnownReg ) )
2010-11-12 05:30:08 +00:00
{
Map_GPR_32bit ( m_Opcode . rd , true , UnknownReg ) ;
2013-03-26 11:28:49 +00:00
if ( dwValue ! = 0 ) {
OrConstToX86Reg ( dwValue , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-11-12 05:30:08 +00:00
}
} else {
Map_GPR_64bit ( m_Opcode . rd , UnknownReg ) ;
if ( ( Value > > 32 ) ! = 0 ) {
2012-11-03 01:18:08 +00:00
OrConstToX86Reg ( ( DWORD ) ( Value > > 32 ) , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2010-11-12 05:30:08 +00:00
}
2013-03-26 11:28:49 +00:00
if ( dwValue ! = 0 ) {
OrConstToX86Reg ( dwValue , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-11-12 05:30:08 +00:00
}
2010-05-25 09:15:19 +00:00
}
} else {
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-11-12 05:30:08 +00:00
{
Map_GPR_32bit ( m_Opcode . rd , true , KnownReg ) ;
2012-11-03 01:18:08 +00:00
OrVariableToX86Reg ( & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-11-12 05:30:08 +00:00
} else {
Map_GPR_64bit ( m_Opcode . rd , KnownReg ) ;
2012-11-03 01:18:08 +00:00
OrVariableToX86Reg ( & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
OrVariableToX86Reg ( & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-11-12 05:30:08 +00:00
}
}
2012-10-02 23:03:21 +00:00
} else {
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-11-12 05:30:08 +00:00
{
2012-10-02 23:03:21 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
OrVariableToX86Reg ( & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2012-10-02 23:03:21 +00:00
} else {
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
OrVariableToX86Reg ( & _GPR [ m_Opcode . rs ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rs ] , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
OrVariableToX86Reg ( & _GPR [ m_Opcode . rs ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rs ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
2012-10-02 23:03:21 +00:00
}
if ( IsMapped ( m_Opcode . rd ) )
{
2012-10-02 23:17:13 +00:00
if ( Is64Bit ( m_Opcode . rd ) )
2012-10-02 23:03:21 +00:00
{
2012-11-03 01:18:08 +00:00
NotX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2012-10-02 23:03:21 +00:00
}
2015-05-02 22:14:19 +00:00
NotX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_SLT ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-09-22 21:43:42 +00:00
if ( IsKnown ( m_Opcode . rt ) & & IsKnown ( m_Opcode . rs ) ) {
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) & & IsConst ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
2015-03-04 09:36:08 +00:00
g_Notify - > DisplayError ( L " 1 " ) ;
2010-05-30 01:54:42 +00:00
CRecompilerOps : : UnknownOpcode ( ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-06 08:19:22 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rs ) < GetMipsRegLo_S ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , 1 ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , 0 ) ;
2010-05-25 09:15:19 +00:00
}
}
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) & & IsMapped ( m_Opcode . rs ) ) {
ProtectGPR ( m_Opcode . rt ) ;
ProtectGPR ( m_Opcode . rs ) ;
2010-10-23 18:53:01 +00:00
if ( ( Is64Bit ( m_Opcode . rt ) & & Is64Bit ( m_Opcode . rs ) ) | |
2012-11-29 11:23:35 +00:00
( ! g_System - > b32BitCore ( ) & & ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) ) )
2010-10-23 18:53:01 +00:00
{
2010-05-25 09:15:19 +00:00
BYTE * Jump [ 2 ] ;
CompX86RegToX86Reg (
2015-05-02 22:14:19 +00:00
Is64Bit ( m_Opcode . rs ) ? GetMipsRegMapHi ( m_Opcode . rs ) : Map_TempReg ( x86_Any , m_Opcode . rs , true ) ,
Is64Bit ( m_Opcode . rt ) ? GetMipsRegMapHi ( m_Opcode . rt ) : Map_TempReg ( x86_Any , m_Opcode . rt , true )
2010-10-23 18:53:01 +00:00
) ;
2010-05-25 09:15:19 +00:00
JeLabel8 ( " Low Compare " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 0 ] = m_RecompPos - 1 ;
2010-06-04 06:25:07 +00:00
SetlVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
JmpLabel8 ( " Continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 1 ] = m_RecompPos - 1 ;
2010-10-23 18:53:01 +00:00
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " Low Compare: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
2012-11-03 01:18:08 +00:00
CompX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rs ) , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " Continue: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
CompX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rs ) , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
2012-11-03 01:18:08 +00:00
if ( GetMipsRegMapLo ( m_Opcode . rd ) > x86_EBX ) {
2010-06-04 06:25:07 +00:00
SetlVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2015-05-02 22:14:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
Setl ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
AndConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , 1 ) ;
2010-05-25 09:15:19 +00:00
}
}
} else {
2010-05-30 01:54:42 +00:00
DWORD ConstReg = IsConst ( m_Opcode . rs ) ? m_Opcode . rs : m_Opcode . rt ;
DWORD MappedReg = IsConst ( m_Opcode . rs ) ? m_Opcode . rt : m_Opcode . rs ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
ProtectGPR ( MappedReg ) ;
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
2010-05-25 09:15:19 +00:00
BYTE * Jump [ 2 ] ;
CompConstToX86reg (
2015-05-02 22:14:19 +00:00
Is64Bit ( MappedReg ) ? GetMipsRegMapHi ( MappedReg ) : Map_TempReg ( x86_Any , MappedReg , true ) ,
Is64Bit ( ConstReg ) ? GetMipsRegHi ( ConstReg ) : ( GetMipsRegLo_S ( ConstReg ) > > 31 )
2010-10-23 18:53:01 +00:00
) ;
2010-05-25 09:15:19 +00:00
JeLabel8 ( " Low Compare " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 0 ] = m_RecompPos - 1 ;
if ( MappedReg = = m_Opcode . rs ) {
2010-06-04 06:25:07 +00:00
SetlVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-06-04 06:25:07 +00:00
SetgVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
}
JmpLabel8 ( " Continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 1 ] = m_RecompPos - 1 ;
2010-10-23 18:53:01 +00:00
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " Low Compare: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
2012-11-06 08:19:22 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( MappedReg ) , GetMipsRegLo ( ConstReg ) ) ;
2010-05-30 01:54:42 +00:00
if ( MappedReg = = m_Opcode . rs ) {
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-06-04 06:25:07 +00:00
SetaVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
}
CPU_Message ( " " ) ;
CPU_Message ( " Continue: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-06 08:19:22 +00:00
DWORD Constant = GetMipsRegLo ( ConstReg ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( MappedReg ) , Constant ) ;
2010-10-23 18:53:01 +00:00
2012-11-03 01:18:08 +00:00
if ( GetMipsRegMapLo ( m_Opcode . rd ) > x86_EBX ) {
2010-05-30 01:54:42 +00:00
if ( MappedReg = = m_Opcode . rs ) {
2010-06-04 06:25:07 +00:00
SetlVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-06-04 06:25:07 +00:00
SetgVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2015-05-02 22:14:19 +00:00
} else {
2010-05-30 01:54:42 +00:00
if ( MappedReg = = m_Opcode . rs ) {
2012-11-03 01:18:08 +00:00
Setl ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
Setg ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-03 01:18:08 +00:00
AndConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , 1 ) ;
2010-05-25 09:15:19 +00:00
}
}
}
2010-09-22 21:43:42 +00:00
} else if ( IsKnown ( m_Opcode . rt ) | | IsKnown ( m_Opcode . rs ) ) {
DWORD KnownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
DWORD UnknownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
BYTE * Jump [ 2 ] ;
2010-10-23 18:53:01 +00:00
2012-11-29 11:23:35 +00:00
if ( ! g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( KnownReg ) ) {
2010-10-23 18:53:01 +00:00
if ( IsConst ( KnownReg ) ) {
2012-11-03 01:18:08 +00:00
CompConstToVariable ( GetMipsRegHi ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
} else {
2012-11-03 01:18:08 +00:00
CompX86regToVariable ( GetMipsRegMapHi ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
}
} else {
if ( IsConst ( KnownReg ) ) {
2012-11-06 08:19:22 +00:00
CompConstToVariable ( ( GetMipsRegLo_S ( KnownReg ) > > 31 ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
} else {
ProtectGPR ( KnownReg ) ;
2015-05-02 22:14:19 +00:00
CompX86regToVariable ( Map_TempReg ( x86_Any , KnownReg , true ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
}
}
JeLabel8 ( " Low Compare " , 0 ) ;
Jump [ 0 ] = m_RecompPos - 1 ;
if ( KnownReg = = ( IsConst ( KnownReg ) ? m_Opcode . rs : m_Opcode . rt ) ) {
SetgVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-10-23 18:53:01 +00:00
SetlVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
}
2010-10-23 18:53:01 +00:00
JmpLabel8 ( " Continue " , 0 ) ;
Jump [ 1 ] = m_RecompPos - 1 ;
CPU_Message ( " " ) ;
CPU_Message ( " Low Compare: " ) ;
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
if ( IsConst ( KnownReg ) ) {
2012-11-06 08:19:22 +00:00
CompConstToVariable ( GetMipsRegLo ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
CompX86regToVariable ( GetMipsRegMapLo ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
}
if ( KnownReg = = ( IsConst ( KnownReg ) ? m_Opcode . rs : m_Opcode . rt ) ) {
SetaVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
} else {
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
}
CPU_Message ( " " ) ;
CPU_Message ( " Continue: " ) ;
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-10-23 18:53:01 +00:00
} else {
if ( IsMapped ( KnownReg ) )
{
2010-05-30 01:54:42 +00:00
ProtectGPR ( KnownReg ) ;
2010-10-23 18:53:01 +00:00
}
bool bConstant = IsConst ( KnownReg ) ;
2012-11-03 01:18:08 +00:00
DWORD Value = IsConst ( KnownReg ) ? GetMipsRegLo ( KnownReg ) : 0 ;
2010-10-23 18:53:01 +00:00
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2010-10-23 18:53:01 +00:00
if ( bConstant ) {
CompConstToVariable ( Value , & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] ) ;
} else {
2012-11-03 01:18:08 +00:00
CompX86regToVariable ( GetMipsRegMapLo ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
}
2012-11-03 01:18:08 +00:00
if ( GetMipsRegMapLo ( m_Opcode . rd ) > x86_EBX ) {
2010-10-23 18:53:01 +00:00
if ( KnownReg = = ( bConstant ? m_Opcode . rs : m_Opcode . rt ) ) {
SetgVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
} else {
SetlVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
}
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2015-05-02 22:14:19 +00:00
} else {
2010-10-23 18:53:01 +00:00
if ( KnownReg = = ( bConstant ? m_Opcode . rs : m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
Setg ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-10-23 18:53:01 +00:00
} else {
2012-11-03 01:18:08 +00:00
Setl ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-10-23 18:53:01 +00:00
}
2012-11-03 01:18:08 +00:00
AndConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , 1 ) ;
2010-10-23 18:53:01 +00:00
}
2010-05-25 09:15:19 +00:00
}
2012-11-29 11:23:35 +00:00
} else if ( g_System - > b32BitCore ( ) ) {
2010-10-23 18:53:01 +00:00
x86Reg Reg = Map_TempReg ( x86_Any , m_Opcode . rs , false ) ;
Map_GPR_32bit ( m_Opcode . rd , false , - 1 ) ;
CompX86regToVariable ( Reg , & _GPR [ m_Opcode . rt ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rt ] ) ;
2012-11-03 01:18:08 +00:00
if ( GetMipsRegMapLo ( m_Opcode . rd ) > x86_EBX ) {
2010-06-04 06:25:07 +00:00
SetlVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2015-05-02 22:14:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
Setl ( GetMipsRegMapLo ( m_Opcode . rd ) ) ;
AndConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , 1 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-10-23 18:53:01 +00:00
BYTE * Jump [ 2 ] = { NULL , NULL } ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
x86Reg Reg = Map_TempReg ( x86_Any , m_Opcode . rs , true ) ;
2010-06-04 06:25:07 +00:00
CompX86regToVariable ( Reg , & _GPR [ m_Opcode . rt ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rt ] ) ;
2010-05-25 09:15:19 +00:00
JeLabel8 ( " Low Compare " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 0 ] = m_RecompPos - 1 ;
2010-06-04 06:25:07 +00:00
SetlVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
JmpLabel8 ( " Continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 1 ] = m_RecompPos - 1 ;
2010-10-23 18:53:01 +00:00
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " Low Compare: " ) ;
2010-10-23 18:53:01 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
2015-05-02 22:14:19 +00:00
CompX86regToVariable ( Map_TempReg ( Reg , m_Opcode . rs , false ) , & _GPR [ m_Opcode . rt ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rt ] ) ;
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-10-23 18:53:01 +00:00
if ( Jump [ 1 ] )
{
CPU_Message ( " " ) ;
CPU_Message ( " Continue: " ) ;
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_SLTU ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-09-22 21:43:42 +00:00
if ( IsKnown ( m_Opcode . rt ) & & IsKnown ( m_Opcode . rs ) ) {
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) & & IsConst ( m_Opcode . rs ) ) {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
2015-03-04 09:36:08 +00:00
g_Notify - > DisplayError ( L " 1 " ) ;
2010-05-30 01:54:42 +00:00
CRecompilerOps : : UnknownOpcode ( ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-06 08:19:22 +00:00
if ( GetMipsRegLo ( m_Opcode . rs ) < GetMipsRegLo ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , 1 ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , 0 ) ;
2010-05-25 09:15:19 +00:00
}
}
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) & & IsMapped ( m_Opcode . rs ) ) {
ProtectGPR ( m_Opcode . rt ) ;
ProtectGPR ( m_Opcode . rs ) ;
2010-10-23 18:53:01 +00:00
if ( ( Is64Bit ( m_Opcode . rt ) & & Is64Bit ( m_Opcode . rs ) ) | |
2012-11-29 11:23:35 +00:00
( ! g_System - > b32BitCore ( ) & & ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) ) )
2010-10-23 18:53:01 +00:00
{
2010-05-25 09:15:19 +00:00
BYTE * Jump [ 2 ] ;
CompX86RegToX86Reg (
2015-05-02 22:14:19 +00:00
Is64Bit ( m_Opcode . rs ) ? GetMipsRegMapHi ( m_Opcode . rs ) : Map_TempReg ( x86_Any , m_Opcode . rs , true ) ,
Is64Bit ( m_Opcode . rt ) ? GetMipsRegMapHi ( m_Opcode . rt ) : Map_TempReg ( x86_Any , m_Opcode . rt , true )
2010-10-23 18:53:01 +00:00
) ;
2010-05-25 09:15:19 +00:00
JeLabel8 ( " Low Compare " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 0 ] = m_RecompPos - 1 ;
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
JmpLabel8 ( " Continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 1 ] = m_RecompPos - 1 ;
2010-10-23 18:53:01 +00:00
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " Low Compare: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
2012-11-03 01:18:08 +00:00
CompX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rs ) , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " Continue: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
CompX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rs ) , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rt ) | | Is64Bit ( m_Opcode . rs ) ) {
DWORD ConstHi , ConstLo , ConstReg , MappedReg ;
x86Reg MappedRegHi , MappedRegLo ;
2010-05-25 09:15:19 +00:00
BYTE * Jump [ 2 ] ;
2010-05-30 01:54:42 +00:00
ConstReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
MappedReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-10-23 18:53:01 +00:00
2012-11-06 08:19:22 +00:00
ConstLo = GetMipsRegLo_S ( ConstReg ) ;
ConstHi = GetMipsRegLo_S ( ConstReg ) > > 31 ;
2012-11-03 01:18:08 +00:00
if ( Is64Bit ( ConstReg ) ) { ConstHi = GetMipsRegHi ( ConstReg ) ; }
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
ProtectGPR ( MappedReg ) ;
2012-11-03 01:18:08 +00:00
MappedRegLo = GetMipsRegMapLo ( MappedReg ) ;
MappedRegHi = GetMipsRegMapHi ( MappedReg ) ;
2010-09-22 21:43:42 +00:00
if ( Is32Bit ( MappedReg ) ) {
2015-05-02 22:14:19 +00:00
MappedRegHi = Map_TempReg ( x86_Any , MappedReg , true ) ;
2010-05-25 09:15:19 +00:00
}
2010-10-23 18:53:01 +00:00
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2010-05-25 09:15:19 +00:00
CompConstToX86reg ( MappedRegHi , ConstHi ) ;
JeLabel8 ( " Low Compare " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 0 ] = m_RecompPos - 1 ;
if ( MappedReg = = m_Opcode . rs ) {
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-06-04 06:25:07 +00:00
SetaVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
}
JmpLabel8 ( " Continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 1 ] = m_RecompPos - 1 ;
2010-10-23 18:53:01 +00:00
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " Low Compare: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
2010-05-25 09:15:19 +00:00
CompConstToX86reg ( MappedRegLo , ConstLo ) ;
2010-05-30 01:54:42 +00:00
if ( MappedReg = = m_Opcode . rs ) {
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-06-04 06:25:07 +00:00
SetaVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
}
CPU_Message ( " " ) ;
CPU_Message ( " Continue: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-06 08:19:22 +00:00
DWORD Const = IsConst ( m_Opcode . rs ) ? GetMipsRegLo ( m_Opcode . rs ) : GetMipsRegLo ( m_Opcode . rt ) ;
2010-05-30 01:54:42 +00:00
DWORD MappedReg = IsConst ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-05-25 09:15:19 +00:00
2012-11-03 01:18:08 +00:00
CompConstToX86reg ( GetMipsRegMapLo ( MappedReg ) , Const ) ;
2010-05-30 01:54:42 +00:00
if ( MappedReg = = m_Opcode . rs ) {
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-06-04 06:25:07 +00:00
SetaVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
}
2010-09-22 21:43:42 +00:00
} else if ( IsKnown ( m_Opcode . rt ) | | IsKnown ( m_Opcode . rs ) ) {
DWORD KnownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rt : m_Opcode . rs ;
DWORD UnknownReg = IsKnown ( m_Opcode . rt ) ? m_Opcode . rs : m_Opcode . rt ;
2010-10-23 18:53:01 +00:00
BYTE * Jump [ 2 ] = { NULL , NULL } ;
ProtectGPR ( KnownReg ) ;
2012-11-29 11:23:35 +00:00
if ( g_System - > b32BitCore ( ) )
2010-10-23 18:53:01 +00:00
{
2012-10-06 04:09:17 +00:00
DWORD TestReg = IsConst ( KnownReg ) ? m_Opcode . rs : m_Opcode . rt ;
2010-10-23 18:53:01 +00:00
if ( IsConst ( KnownReg ) ) {
2012-11-03 01:18:08 +00:00
DWORD Value = GetMipsRegLo ( KnownReg ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2010-10-23 18:53:01 +00:00
CompConstToVariable ( Value , & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
CompX86regToVariable ( GetMipsRegMapLo ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] ) ;
2010-05-25 09:15:19 +00:00
}
2012-10-06 04:09:17 +00:00
if ( KnownReg = = TestReg )
{
2010-10-23 18:53:01 +00:00
SetaVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-10-23 18:53:01 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
}
2010-05-25 09:15:19 +00:00
} else {
2010-10-23 18:53:01 +00:00
if ( IsConst ( KnownReg ) ) {
if ( Is64Bit ( KnownReg ) ) {
2012-11-03 01:18:08 +00:00
CompConstToVariable ( GetMipsRegHi ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
} else {
2012-11-06 08:19:22 +00:00
CompConstToVariable ( ( GetMipsRegLo_S ( KnownReg ) > > 31 ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
}
} else {
if ( Is64Bit ( KnownReg ) ) {
2012-11-03 01:18:08 +00:00
CompX86regToVariable ( GetMipsRegMapHi ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
} else {
ProtectGPR ( KnownReg ) ;
2015-05-02 22:14:19 +00:00
CompX86regToVariable ( Map_TempReg ( x86_Any , KnownReg , true ) , & _GPR [ UnknownReg ] . W [ 1 ] , CRegName : : GPR_Hi [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
}
}
JeLabel8 ( " Low Compare " , 0 ) ;
Jump [ 0 ] = m_RecompPos - 1 ;
if ( KnownReg = = ( IsConst ( KnownReg ) ? m_Opcode . rs : m_Opcode . rt ) ) {
SetaVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
} else {
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
}
JmpLabel8 ( " Continue " , 0 ) ;
Jump [ 1 ] = m_RecompPos - 1 ;
CPU_Message ( " " ) ;
CPU_Message ( " Low Compare: " ) ;
2012-11-05 10:08:33 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
2010-10-23 18:53:01 +00:00
if ( IsConst ( KnownReg ) ) {
2012-11-06 08:19:22 +00:00
CompConstToVariable ( GetMipsRegLo ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
} else {
2012-11-03 01:18:08 +00:00
CompX86regToVariable ( GetMipsRegMapLo ( KnownReg ) , & _GPR [ UnknownReg ] . W [ 0 ] , CRegName : : GPR_Lo [ UnknownReg ] ) ;
2010-10-23 18:53:01 +00:00
}
if ( KnownReg = = ( IsConst ( KnownReg ) ? m_Opcode . rs : m_Opcode . rt ) ) {
SetaVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
} else {
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
}
if ( Jump [ 1 ] )
{
CPU_Message ( " " ) ;
CPU_Message ( " Continue: " ) ;
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
}
2010-05-25 09:15:19 +00:00
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2012-11-29 11:23:35 +00:00
} else if ( g_System - > b32BitCore ( ) ) {
2010-10-23 18:53:01 +00:00
x86Reg Reg = Map_TempReg ( x86_Any , m_Opcode . rs , false ) ;
Map_GPR_32bit ( m_Opcode . rd , false , - 1 ) ;
CompX86regToVariable ( Reg , & _GPR [ m_Opcode . rt ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rt ] ) ;
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-10-23 18:53:01 +00:00
BYTE * Jump [ 2 ] = { NULL , NULL } ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
x86Reg Reg = Map_TempReg ( x86_Any , m_Opcode . rs , true ) ;
2010-06-04 06:25:07 +00:00
CompX86regToVariable ( Reg , & _GPR [ m_Opcode . rt ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rt ] ) ;
2010-05-25 09:15:19 +00:00
JeLabel8 ( " Low Compare " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 0 ] = m_RecompPos - 1 ;
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-05-25 09:15:19 +00:00
JmpLabel8 ( " Continue " , 0 ) ;
2010-05-30 01:54:42 +00:00
Jump [ 1 ] = m_RecompPos - 1 ;
2010-05-25 09:15:19 +00:00
CPU_Message ( " " ) ;
CPU_Message ( " Low Compare: " ) ;
2010-10-23 18:53:01 +00:00
SetJump8 ( Jump [ 0 ] , m_RecompPos ) ;
2015-05-02 22:14:19 +00:00
CompX86regToVariable ( Map_TempReg ( Reg , m_Opcode . rs , false ) , & _GPR [ m_Opcode . rt ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rt ] ) ;
2010-06-04 06:25:07 +00:00
SetbVariable ( & m_BranchCompare , " m_BranchCompare " ) ;
2010-10-23 18:53:01 +00:00
if ( Jump [ 1 ] )
{
CPU_Message ( " " ) ;
CPU_Message ( " Continue: " ) ;
SetJump8 ( Jump [ 1 ] , m_RecompPos ) ;
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & m_BranchCompare , " m_BranchCompare " , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DADD ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) & & IsConst ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsReg ( m_Opcode . rd ,
2012-11-06 08:19:22 +00:00
Is64Bit ( m_Opcode . rs ) ? GetMipsReg ( m_Opcode . rs ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rs ) +
Is64Bit ( m_Opcode . rt ) ? GetMipsReg ( m_Opcode . rt ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rt )
2012-10-04 11:01:10 +00:00
) ;
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rd ) < 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = - 1 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-03 01:18:08 +00:00
} else if ( GetMipsRegLo_S ( m_Opcode . rd ) > = 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_64 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-05-30 01:54:42 +00:00
int source1 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rt : m_Opcode . rs ;
int source2 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rs : m_Opcode . rt ;
2013-03-12 07:40:50 +00:00
if ( IsMapped ( source2 ) ) { ProtectGPR ( source2 ) ; }
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , source1 ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( source2 ) ) {
2012-11-06 08:19:22 +00:00
AddConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegLo ( source2 ) ) ;
2012-11-03 01:18:08 +00:00
AddConstToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegHi ( source2 ) ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( source2 ) ) {
2015-05-02 22:14:19 +00:00
x86Reg HiReg = Is64Bit ( source2 ) ? GetMipsRegMapHi ( source2 ) : Map_TempReg ( x86_Any , source2 , true ) ;
2012-11-03 01:18:08 +00:00
AddX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( source2 ) ) ;
AdcX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , HiReg ) ;
2010-05-30 01:54:42 +00:00
} else {
2012-11-03 01:18:08 +00:00
AddVariableToX86reg ( GetMipsRegMapLo ( m_Opcode . rd ) , & _GPR [ source2 ] . W [ 0 ] , CRegName : : GPR_Lo [ source2 ] ) ;
AdcVariableToX86reg ( GetMipsRegMapHi ( m_Opcode . rd ) , & _GPR [ source2 ] . W [ 1 ] , CRegName : : GPR_Hi [ source2 ] ) ;
2010-05-25 09:15:19 +00:00
}
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DADDU ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) & & IsConst ( m_Opcode . rs ) ) {
2012-11-06 08:19:22 +00:00
__int64 ValRs = Is64Bit ( m_Opcode . rs ) ? GetMipsReg ( m_Opcode . rs ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rs ) ;
__int64 ValRt = Is64Bit ( m_Opcode . rt ) ? GetMipsReg ( m_Opcode . rt ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rt ) ;
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsReg ( m_Opcode . rd , ValRs + ValRt ) ;
2012-11-06 08:19:22 +00:00
if ( ( GetMipsRegHi ( m_Opcode . rd ) = = 0 ) & & ( GetMipsRegLo ( m_Opcode . rd ) & 0x80000000 ) = = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-06 08:19:22 +00:00
} else if ( ( GetMipsRegHi ( m_Opcode . rd ) = = 0xFFFFFFFF ) & & ( GetMipsRegLo ( m_Opcode . rd ) & 0x80000000 ) ! = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_64 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-05-30 01:54:42 +00:00
int source1 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rt : m_Opcode . rs ;
int source2 = m_Opcode . rd = = m_Opcode . rt ? m_Opcode . rs : m_Opcode . rt ;
2013-03-12 07:40:50 +00:00
if ( IsMapped ( source2 ) ) { ProtectGPR ( source2 ) ; }
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , source1 ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( source2 ) ) {
2012-11-06 08:19:22 +00:00
AddConstToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegLo ( source2 ) ) ;
2012-11-03 01:18:08 +00:00
AddConstToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegHi ( source2 ) ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( source2 ) ) {
2015-05-02 22:14:19 +00:00
x86Reg HiReg = Is64Bit ( source2 ) ? GetMipsRegMapHi ( source2 ) : Map_TempReg ( x86_Any , source2 , true ) ;
2012-11-03 01:18:08 +00:00
AddX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( source2 ) ) ;
AdcX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , HiReg ) ;
2010-05-30 01:54:42 +00:00
} else {
2012-11-03 01:18:08 +00:00
AddVariableToX86reg ( GetMipsRegMapLo ( m_Opcode . rd ) , & _GPR [ source2 ] . W [ 0 ] , CRegName : : GPR_Lo [ source2 ] ) ;
AdcVariableToX86reg ( GetMipsRegMapHi ( m_Opcode . rd ) , & _GPR [ source2 ] . W [ 1 ] , CRegName : : GPR_Hi [ source2 ] ) ;
2010-05-25 09:15:19 +00:00
}
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DSUB ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) & & IsConst ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsReg ( m_Opcode . rd ,
2012-11-06 08:19:22 +00:00
Is64Bit ( m_Opcode . rs ) ? GetMipsReg ( m_Opcode . rs ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rs ) -
Is64Bit ( m_Opcode . rt ) ? GetMipsReg ( m_Opcode . rt ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rt )
2012-10-04 11:01:10 +00:00
) ;
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rd ) < 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = - 1 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-03 01:18:08 +00:00
} else if ( GetMipsRegLo_S ( m_Opcode . rd ) > = 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_64 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-05-30 01:54:42 +00:00
if ( m_Opcode . rd = = m_Opcode . rt ) {
2015-05-02 22:14:19 +00:00
x86Reg HiReg = Map_TempReg ( x86_Any , m_Opcode . rt , true ) ;
x86Reg LoReg = Map_TempReg ( x86_Any , m_Opcode . rt , false ) ;
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rs ) ;
2012-11-03 01:18:08 +00:00
SubX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , LoReg ) ;
SbbX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , HiReg ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2013-03-12 07:40:50 +00:00
if ( IsMapped ( m_Opcode . rt ) ) { ProtectGPR ( m_Opcode . rt ) ; }
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rs ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-06 08:19:22 +00:00
SubConstFromX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegLo ( m_Opcode . rt ) ) ;
2012-11-03 01:18:08 +00:00
SbbConstFromX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegHi ( m_Opcode . rt ) ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
x86Reg HiReg = Is64Bit ( m_Opcode . rt ) ? GetMipsRegMapHi ( m_Opcode . rt ) : Map_TempReg ( x86_Any , m_Opcode . rt , true ) ;
2012-11-03 01:18:08 +00:00
SubX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
SbbX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , HiReg ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
SubVariableFromX86reg ( GetMipsRegMapLo ( m_Opcode . rd ) , & _GPR [ m_Opcode . rt ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rt ] ) ;
SbbVariableFromX86reg ( GetMipsRegMapHi ( m_Opcode . rd ) , & _GPR [ m_Opcode . rt ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rt ] ) ;
2010-05-25 09:15:19 +00:00
}
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DSUBU ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) & & IsConst ( m_Opcode . rs ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsReg ( m_Opcode . rd ,
2012-11-06 08:19:22 +00:00
Is64Bit ( m_Opcode . rs ) ? GetMipsReg ( m_Opcode . rs ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rs ) -
Is64Bit ( m_Opcode . rt ) ? GetMipsReg ( m_Opcode . rt ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rt )
2012-10-04 11:01:10 +00:00
) ;
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rd ) < 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = - 1 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-03 01:18:08 +00:00
} else if ( GetMipsRegLo_S ( m_Opcode . rd ) > = 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_64 ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-05-30 01:54:42 +00:00
if ( m_Opcode . rd = = m_Opcode . rt ) {
2015-05-02 22:14:19 +00:00
x86Reg HiReg = Map_TempReg ( x86_Any , m_Opcode . rt , true ) ;
x86Reg LoReg = Map_TempReg ( x86_Any , m_Opcode . rt , false ) ;
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rs ) ;
2012-11-03 01:18:08 +00:00
SubX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , LoReg ) ;
SbbX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , HiReg ) ;
2010-05-25 09:15:19 +00:00
return ;
}
2013-03-12 07:40:50 +00:00
if ( IsMapped ( m_Opcode . rt ) ) { ProtectGPR ( m_Opcode . rt ) ; }
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rs ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-06 08:19:22 +00:00
SubConstFromX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegLo ( m_Opcode . rt ) ) ;
2012-11-03 01:18:08 +00:00
SbbConstFromX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegHi ( m_Opcode . rt ) ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
x86Reg HiReg = Is64Bit ( m_Opcode . rt ) ? GetMipsRegMapHi ( m_Opcode . rt ) : Map_TempReg ( x86_Any , m_Opcode . rt , true ) ;
2012-11-03 01:18:08 +00:00
SubX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
SbbX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rd ) , HiReg ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
SubVariableFromX86reg ( GetMipsRegMapLo ( m_Opcode . rd ) , & _GPR [ m_Opcode . rt ] . W [ 0 ] , CRegName : : GPR_Lo [ m_Opcode . rt ] ) ;
SbbVariableFromX86reg ( GetMipsRegMapHi ( m_Opcode . rd ) , & _GPR [ m_Opcode . rt ] . W [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rt ] ) ;
2010-05-25 09:15:19 +00:00
}
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DSLL ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-11-12 05:30:08 +00:00
2010-06-14 21:14:58 +00:00
if ( IsConst ( m_Opcode . rt ) )
{
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2010-05-25 09:15:19 +00:00
2013-01-28 08:37:59 +00:00
__int64 Value = Is64Bit ( m_Opcode . rt ) ? GetMipsReg_S ( m_Opcode . rt ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rt ) ;
m_RegWorkingSet . SetMipsReg ( m_Opcode . rd , Value < < m_Opcode . sa ) ;
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rd ) < 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = - 1 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-03 01:18:08 +00:00
} else if ( GetMipsRegLo_S ( m_Opcode . rd ) > = 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_64 ) ;
2010-05-25 09:15:19 +00:00
}
return ;
}
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
ShiftLeftDoubleImmed ( GetMipsRegMapHi ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2015-05-02 22:14:19 +00:00
ShiftLeftSignImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DSRL ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-11-12 05:30:08 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2010-05-25 09:15:19 +00:00
2013-01-28 08:37:59 +00:00
__int64 Value = Is64Bit ( m_Opcode . rt ) ? GetMipsReg_S ( m_Opcode . rt ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rt ) ;
m_RegWorkingSet . SetMipsReg ( m_Opcode . rd , Value > > m_Opcode . sa ) ;
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rd ) < 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = - 1 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-03 01:18:08 +00:00
} else if ( GetMipsRegLo_S ( m_Opcode . rd ) > = 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_64 ) ;
2010-05-25 09:15:19 +00:00
}
return ;
}
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
ShiftRightDoubleImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapHi ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
ShiftRightUnsignImmed ( GetMipsRegMapHi ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DSRA ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2011-01-02 10:40:00 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
if ( IsMapped ( m_Opcode . rd ) )
UnMap_GPR ( m_Opcode . rd , false ) ;
2010-05-25 09:15:19 +00:00
2013-01-28 08:37:59 +00:00
__int64 Value = Is64Bit ( m_Opcode . rt ) ? GetMipsReg_S ( m_Opcode . rt ) : ( __int64 ) GetMipsRegLo_S ( m_Opcode . rt ) ;
m_RegWorkingSet . SetMipsReg_S ( m_Opcode . rd , Value > > m_Opcode . sa ) ;
2012-11-03 01:18:08 +00:00
if ( GetMipsRegLo_S ( m_Opcode . rd ) < 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = - 1 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-03 01:18:08 +00:00
} else if ( GetMipsRegLo_S ( m_Opcode . rd ) > = 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_64 ) ;
2010-05-25 09:15:19 +00:00
}
return ;
2015-05-02 22:14:19 +00:00
}
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , m_Opcode . rt ) ;
2012-11-03 01:18:08 +00:00
ShiftRightDoubleImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapHi ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
ShiftRightSignImmed ( GetMipsRegMapHi ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DSLL32 ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rd = = 0 )
return ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rt ! = m_Opcode . rd )
UnMap_GPR ( m_Opcode . rd , false ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegHi ( m_Opcode . rd , GetMipsRegLo ( m_Opcode . rt ) < < m_Opcode . sa ) ;
2012-11-03 01:18:08 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , 0 ) ;
if ( GetMipsRegLo_S ( m_Opcode . rd ) < 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = - 1 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-03 01:18:08 +00:00
} else if ( GetMipsRegLo_S ( m_Opcode . rd ) > = 0 & & GetMipsRegHi_S ( m_Opcode . rd ) = = 0 ) {
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_64 ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
ProtectGPR ( m_Opcode . rt ) ;
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , - 1 ) ;
2010-05-30 01:54:42 +00:00
if ( m_Opcode . rt ! = m_Opcode . rd ) {
2012-11-03 01:18:08 +00:00
MoveX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rt ) , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-03 01:18:08 +00:00
CPU_Message ( " regcache: switch hi (%s) with lo (%s) for %s " , x86_Name ( GetMipsRegMapHi ( m_Opcode . rt ) ) , x86_Name ( GetMipsRegMapLo ( m_Opcode . rt ) ) , CRegName : : GPR [ m_Opcode . rt ] ) ;
x86Reg HiReg = GetMipsRegMapHi ( m_Opcode . rt ) ;
m_RegWorkingSet . SetMipsRegMapHi ( m_Opcode . rt , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegMapLo ( m_Opcode . rt , HiReg ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( ( BYTE ) m_Opcode . sa ! = 0 ) {
2012-11-03 01:18:08 +00:00
ShiftLeftSignImmed ( GetMipsRegMapHi ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-03 01:18:08 +00:00
XorX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
} else {
2010-05-31 00:21:08 +00:00
Map_GPR_64bit ( m_Opcode . rd , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & _GPR [ m_Opcode . rt ] , CRegName : : GPR_Hi [ m_Opcode . rt ] , GetMipsRegMapHi ( m_Opcode . rd ) ) ;
2010-05-30 01:54:42 +00:00
if ( ( BYTE ) m_Opcode . sa ! = 0 ) {
2012-11-03 01:18:08 +00:00
ShiftLeftSignImmed ( GetMipsRegMapHi ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2010-05-30 01:54:42 +00:00
}
2012-11-03 01:18:08 +00:00
XorX86RegToX86Reg ( GetMipsRegMapLo ( m_Opcode . rd ) , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-30 01:54:42 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DSRL32 ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-10-23 18:53:01 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rt ! = m_Opcode . rd )
UnMap_GPR ( m_Opcode . rd , false ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_ZERO ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , ( DWORD ) ( GetMipsReg ( m_Opcode . rt ) > > ( m_Opcode . sa + 32 ) ) ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
ProtectGPR ( m_Opcode . rt ) ;
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rt ) ) {
2010-05-30 01:54:42 +00:00
if ( m_Opcode . rt = = m_Opcode . rd ) {
2012-11-03 01:18:08 +00:00
CPU_Message ( " regcache: switch hi (%s) with lo (%s) for %s " , x86_Name ( GetMipsRegMapHi ( m_Opcode . rt ) ) , x86_Name ( GetMipsRegMapLo ( m_Opcode . rt ) ) , CRegName : : GPR [ m_Opcode . rt ] ) ;
x86Reg HiReg = GetMipsRegMapHi ( m_Opcode . rt ) ;
m_RegWorkingSet . SetMipsRegMapHi ( m_Opcode . rt , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegMapLo ( m_Opcode . rt , HiReg ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , false , - 1 ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , false , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rt ) , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( ( BYTE ) m_Opcode . sa ! = 0 ) {
2012-11-03 01:18:08 +00:00
ShiftRightUnsignImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-05-30 01:54:42 +00:00
CRecompilerOps : : UnknownOpcode ( ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , false , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & _GPR [ m_Opcode . rt ] . UW [ 1 ] , CRegName : : GPR_Hi [ m_Opcode . rt ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-30 01:54:42 +00:00
if ( ( BYTE ) m_Opcode . sa ! = 0 ) {
2012-11-03 01:18:08 +00:00
ShiftRightUnsignImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2010-05-30 01:54:42 +00:00
}
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : SPECIAL_DSRA32 ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-10-23 18:53:01 +00:00
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2015-05-02 22:14:19 +00:00
if ( m_Opcode . rt ! = m_Opcode . rd )
UnMap_GPR ( m_Opcode . rd , false ) ;
2015-02-25 06:41:54 +00:00
m_RegWorkingSet . SetMipsRegState ( m_Opcode . rd , CRegInfo : : STATE_CONST_32_SIGN ) ;
2012-11-06 08:19:22 +00:00
m_RegWorkingSet . SetMipsRegLo ( m_Opcode . rd , ( DWORD ) ( GetMipsReg_S ( m_Opcode . rt ) > > ( m_Opcode . sa + 32 ) ) ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
ProtectGPR ( m_Opcode . rt ) ;
2010-06-04 06:25:07 +00:00
if ( Is64Bit ( m_Opcode . rt ) ) {
2010-05-30 01:54:42 +00:00
if ( m_Opcode . rt = = m_Opcode . rd ) {
2012-11-03 01:18:08 +00:00
CPU_Message ( " regcache: switch hi (%s) with lo (%s) for %s " , x86_Name ( GetMipsRegMapHi ( m_Opcode . rt ) ) , x86_Name ( GetMipsRegMapLo ( m_Opcode . rt ) ) , CRegName : : GPR [ m_Opcode . rt ] ) ;
x86Reg HiReg = GetMipsRegMapHi ( m_Opcode . rt ) ;
m_RegWorkingSet . SetMipsRegMapHi ( m_Opcode . rt , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2012-10-04 11:01:10 +00:00
m_RegWorkingSet . SetMipsRegMapLo ( m_Opcode . rt , HiReg ) ;
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveX86RegToX86Reg ( GetMipsRegMapHi ( m_Opcode . rt ) , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( ( BYTE ) m_Opcode . sa ! = 0 ) {
2012-11-03 01:18:08 +00:00
ShiftRightSignImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2010-05-30 01:54:42 +00:00
CRecompilerOps : : UnknownOpcode ( ) ;
2010-05-25 09:15:19 +00:00
}
} else {
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rd , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & _GPR [ m_Opcode . rt ] . UW [ 1 ] , CRegName : : GPR_Lo [ m_Opcode . rt ] , GetMipsRegMapLo ( m_Opcode . rd ) ) ;
2010-05-30 01:54:42 +00:00
if ( ( BYTE ) m_Opcode . sa ! = 0 ) {
2012-11-03 01:18:08 +00:00
ShiftRightSignImmed ( GetMipsRegMapLo ( m_Opcode . rd ) , ( BYTE ) m_Opcode . sa ) ;
2010-05-25 09:15:19 +00:00
}
}
}
/************************** COP0 functions **************************/
2015-05-02 22:14:19 +00:00
void CRecompilerOps : : COP0_MF ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
switch ( m_Opcode . rd ) {
2010-05-25 09:15:19 +00:00
case 9 : //Count
2015-05-02 22:14:19 +00:00
m_RegWorkingSet . SetBlockCycleCount ( m_RegWorkingSet . GetBlockCycleCount ( ) - g_System - > CountPerOp ( ) ) ;
2010-07-05 11:29:46 +00:00
UpdateCounters ( m_RegWorkingSet , false , true ) ;
2015-05-02 22:14:19 +00:00
m_RegWorkingSet . SetBlockCycleCount ( m_RegWorkingSet . GetBlockCycleCount ( ) + g_System - > CountPerOp ( ) ) ;
2010-07-05 11:29:46 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2015-05-02 22:14:19 +00:00
MoveConstToX86reg ( ( DWORD ) g_SystemTimer , x86_ECX ) ;
2010-09-22 21:43:42 +00:00
Call_Direct ( AddressOf ( & CSystemTimer : : UpdateTimers ) , " CSystemTimer::UpdateTimers " ) ;
2010-07-05 11:29:46 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-25 09:15:19 +00:00
}
2015-05-02 22:14:19 +00:00
Map_GPR_32bit ( m_Opcode . rt , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP0_MT ( ) {
2010-05-30 01:54:42 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2010-05-30 01:54:42 +00:00
BYTE * Jump ;
switch ( m_Opcode . rd ) {
2010-05-25 09:15:19 +00:00
case 0 : //Index
case 2 : //EntryLo0
case 3 : //EntryLo1
case 4 : //Context
case 5 : //PageMask
case 10 : //Entry Hi
case 14 : //EPC
case 16 : //Config
case 18 : //WatchLo
case 19 : //WatchHi
case 28 : //Tag lo
case 29 : //Tag Hi
case 30 : //ErrEPC
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-06 08:19:22 +00:00
MoveConstToVariable ( GetMipsRegLo ( m_Opcode . rt ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rt ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rt , false ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
if ( m_Opcode . rd = = 4 ) //Context
{
AndConstToVariable ( 0xFF800000 , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-25 09:15:19 +00:00
}
break ;
2010-05-30 01:54:42 +00:00
case 11 : //Compare
2012-11-29 11:23:35 +00:00
m_RegWorkingSet . SetBlockCycleCount ( m_RegWorkingSet . GetBlockCycleCount ( ) - g_System - > CountPerOp ( ) ) ;
2012-09-23 22:21:56 +00:00
UpdateCounters ( m_RegWorkingSet , false , true ) ;
2012-11-29 11:23:35 +00:00
m_RegWorkingSet . SetBlockCycleCount ( m_RegWorkingSet . GetBlockCycleCount ( ) + g_System - > CountPerOp ( ) ) ;
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2015-05-02 22:14:19 +00:00
MoveConstToX86reg ( ( DWORD ) g_SystemTimer , x86_ECX ) ;
2010-09-22 21:43:42 +00:00
Call_Direct ( AddressOf ( & CSystemTimer : : UpdateTimers ) , " CSystemTimer::UpdateTimers " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-06 08:19:22 +00:00
MoveConstToVariable ( GetMipsRegLo ( m_Opcode . rt ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rt ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rt , false ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-25 09:15:19 +00:00
}
2012-11-17 02:18:14 +00:00
AndConstToVariable ( ( DWORD ) ~ CAUSE_IP7 , & g_Reg - > FAKE_CAUSE_REGISTER , " FAKE_CAUSE_REGISTER " ) ;
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2015-05-02 22:14:19 +00:00
MoveConstToX86reg ( ( DWORD ) g_SystemTimer , x86_ECX ) ;
2010-09-22 21:43:42 +00:00
Call_Direct ( AddressOf ( & CSystemTimer : : UpdateCompareTimer ) , " CSystemTimer::UpdateCompareTimer " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-25 09:15:19 +00:00
break ;
2010-05-30 01:54:42 +00:00
case 9 : //Count
2012-11-29 11:23:35 +00:00
m_RegWorkingSet . SetBlockCycleCount ( m_RegWorkingSet . GetBlockCycleCount ( ) - g_System - > CountPerOp ( ) ) ;
2010-07-05 11:29:46 +00:00
UpdateCounters ( m_RegWorkingSet , false , true ) ;
2012-11-29 11:23:35 +00:00
m_RegWorkingSet . SetBlockCycleCount ( m_RegWorkingSet . GetBlockCycleCount ( ) + g_System - > CountPerOp ( ) ) ;
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2015-05-02 22:14:19 +00:00
MoveConstToX86reg ( ( DWORD ) g_SystemTimer , x86_ECX ) ;
2010-09-22 21:43:42 +00:00
Call_Direct ( AddressOf ( & CSystemTimer : : UpdateTimers ) , " CSystemTimer::UpdateTimers " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-06 08:19:22 +00:00
MoveConstToVariable ( GetMipsRegLo ( m_Opcode . rt ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rt ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-30 01:54:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rt , false ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2015-05-02 22:14:19 +00:00
MoveConstToX86reg ( ( DWORD ) g_SystemTimer , x86_ECX ) ;
2010-09-22 21:43:42 +00:00
Call_Direct ( AddressOf ( & CSystemTimer : : UpdateCompareTimer ) , " CSystemTimer::UpdateCompareTimer " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-25 09:15:19 +00:00
break ;
2010-05-30 01:54:42 +00:00
case 12 : //Status
{
2015-05-02 22:14:19 +00:00
x86Reg OldStatusReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-05-30 01:54:42 +00:00
MoveVariableToX86reg ( & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] , OldStatusReg ) ;
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-06 08:19:22 +00:00
MoveConstToVariable ( GetMipsRegLo ( m_Opcode . rt ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rt ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-30 01:54:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rt , false ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-30 01:54:42 +00:00
}
XorVariableToX86reg ( & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] , OldStatusReg ) ;
TestConstToX86Reg ( STATUS_FR , OldStatusReg ) ;
JeLabel8 ( " FpuFlagFine " , 0 ) ;
Jump = m_RecompPos - 1 ;
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2012-11-17 02:18:14 +00:00
MoveConstToX86reg ( ( DWORD ) g_Reg , x86_ECX ) ;
2015-05-02 22:14:19 +00:00
Call_Direct ( AddressOf ( & CRegisters : : FixFpuLocations ) , " CRegisters::FixFpuLocations " ) ;
2012-09-30 06:07:08 +00:00
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2015-05-02 22:14:19 +00:00
SetJump8 ( Jump , m_RecompPos ) ;
2010-05-30 01:54:42 +00:00
//TestConstToX86Reg(STATUS_FR,OldStatusReg);
2015-05-02 22:14:19 +00:00
//BreakPoint(__FILEW__,__LINE__); //m_Section->CompileExit(m_CompilePC+4,m_RegWorkingSet,ExitResetRecompCode,false,JneLabel32);
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2012-11-17 02:18:14 +00:00
MoveConstToX86reg ( ( DWORD ) g_Reg , x86_ECX ) ;
2010-09-22 21:43:42 +00:00
Call_Direct ( AddressOf ( & CRegisters : : CheckInterrupts ) , " CRegisters::CheckInterrupts " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-30 01:54:42 +00:00
}
break ;
2010-05-25 09:15:19 +00:00
case 6 : //Wired
2015-05-02 22:14:19 +00:00
m_RegWorkingSet . SetBlockCycleCount ( m_RegWorkingSet . GetBlockCycleCount ( ) - g_System - > CountPerOp ( ) ) ;
2013-02-03 00:51:56 +00:00
UpdateCounters ( m_RegWorkingSet , false , true ) ;
2015-05-02 22:14:19 +00:00
m_RegWorkingSet . SetBlockCycleCount ( m_RegWorkingSet . GetBlockCycleCount ( ) + g_System - > CountPerOp ( ) ) ;
2013-02-03 00:51:56 +00:00
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2015-05-02 22:14:19 +00:00
MoveConstToX86reg ( ( DWORD ) g_SystemTimer , x86_ECX ) ;
2012-09-28 20:13:15 +00:00
Call_Direct ( AddressOf ( & CSystemTimer : : UpdateTimers ) , " CSystemTimer::UpdateTimers " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-06 08:19:22 +00:00
MoveConstToVariable ( GetMipsRegLo ( m_Opcode . rt ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-30 01:54:42 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rt ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-25 09:15:19 +00:00
} else {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rt , false ) , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2010-05-25 09:15:19 +00:00
}
break ;
case 13 : //cause
2010-05-30 01:54:42 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
AndConstToVariable ( 0xFFFFCFF , & _CP0 [ m_Opcode . rd ] , CRegName : : Cop0 [ m_Opcode . rd ] ) ;
2015-03-04 09:36:08 +00:00
if ( ( GetMipsRegLo ( m_Opcode . rt ) & 0x300 ) ! = 0 & & bHaveDebugger ( ) ) { g_Notify - > DisplayError ( L " Set IP0 or IP1 " ) ; }
2010-05-25 09:15:19 +00:00
} else {
2013-03-22 05:47:20 +00:00
UnknownOpcode ( ) ;
return ;
2010-05-25 09:15:19 +00:00
}
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2012-11-17 02:18:14 +00:00
MoveConstToX86reg ( ( DWORD ) g_Reg , x86_ECX ) ;
2010-09-22 21:43:42 +00:00
Call_Direct ( AddressOf ( & CRegisters : : CheckInterrupts ) , " CRegisters::CheckInterrupts " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-25 09:15:19 +00:00
break ;
default :
2013-03-22 05:47:20 +00:00
UnknownOpcode ( ) ;
2010-05-25 09:15:19 +00:00
}
}
/************************** COP0 CO functions ***********************/
2010-05-30 01:54:42 +00:00
void CRecompilerOps : : COP0_CO_TLBR ( void ) {
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2012-11-29 11:23:35 +00:00
if ( ! g_System - > bUseTlb ( ) ) { return ; }
2010-06-16 07:31:47 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2012-11-17 02:16:38 +00:00
MoveConstToX86reg ( ( DWORD ) g_TLB , x86_ECX ) ;
2010-09-22 21:43:42 +00:00
Call_Direct ( AddressOf ( & CTLB : : ReadEntry ) , " CTLB::ReadEntry " ) ;
2010-06-16 07:31:47 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
void CRecompilerOps : : COP0_CO_TLBWI ( void ) {
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2012-11-29 11:23:35 +00:00
if ( ! g_System - > bUseTlb ( ) ) { return ; }
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2015-05-02 22:14:19 +00:00
PushImm32 ( " FALSE " , 0 ) ;
2012-11-17 02:18:14 +00:00
MoveVariableToX86reg ( & g_Reg - > INDEX_REGISTER , " INDEX_REGISTER " , x86_ECX ) ;
2010-05-25 09:15:19 +00:00
AndConstToX86Reg ( x86_ECX , 0x1F ) ;
Push ( x86_ECX ) ;
2012-11-17 02:16:38 +00:00
MoveConstToX86reg ( ( DWORD ) g_TLB , x86_ECX ) ;
2010-09-22 21:43:42 +00:00
Call_Direct ( AddressOf ( & CTLB : : WriteEntry ) , " CTLB::WriteEntry " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
void CRecompilerOps : : COP0_CO_TLBWR ( void ) {
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2012-11-29 11:23:35 +00:00
if ( ! g_System - > bUseTlb ( ) ) { return ; }
2010-05-25 09:15:19 +00:00
2012-11-29 11:23:35 +00:00
m_RegWorkingSet . SetBlockCycleCount ( m_RegWorkingSet . GetBlockCycleCount ( ) - g_System - > CountPerOp ( ) ) ;
2012-09-28 20:13:15 +00:00
UpdateCounters ( m_RegWorkingSet , false , true ) ;
2012-11-29 11:23:35 +00:00
m_RegWorkingSet . SetBlockCycleCount ( m_RegWorkingSet . GetBlockCycleCount ( ) + g_System - > CountPerOp ( ) ) ;
2012-09-28 20:13:15 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2012-11-17 02:31:46 +00:00
MoveConstToX86reg ( ( DWORD ) g_SystemTimer , x86_ECX ) ;
2012-09-28 20:13:15 +00:00
Call_Direct ( AddressOf ( & CSystemTimer : : UpdateTimers ) , " CSystemTimer::UpdateTimers " ) ;
PushImm32 ( " true " , true ) ;
2012-11-17 02:18:14 +00:00
MoveVariableToX86reg ( & g_Reg - > RANDOM_REGISTER , " RANDOM_REGISTER " , x86_ECX ) ;
2010-05-25 09:15:19 +00:00
AndConstToX86Reg ( x86_ECX , 0x1F ) ;
Push ( x86_ECX ) ;
2012-11-17 02:16:38 +00:00
MoveConstToX86reg ( ( DWORD ) g_TLB , x86_ECX ) ;
2012-09-28 20:13:15 +00:00
Call_Direct ( AddressOf ( & CTLB : : WriteEntry ) , " CTLB::WriteEntry " ) ;
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
void CRecompilerOps : : COP0_CO_TLBP ( void ) {
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2012-11-29 11:23:35 +00:00
if ( ! g_System - > bUseTlb ( ) ) { return ; }
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2012-11-17 02:16:38 +00:00
MoveConstToX86reg ( ( DWORD ) g_TLB , x86_ECX ) ;
2010-09-22 21:43:42 +00:00
Call_Direct ( AddressOf ( & CTLB : : Probe ) , " CTLB::TLB_Probe " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-05-25 09:15:19 +00:00
}
2015-04-28 22:19:02 +00:00
void compiler_COP0_CO_ERET ( ) {
2012-11-17 02:18:14 +00:00
if ( ( g_Reg - > STATUS_REGISTER & STATUS_ERL ) ! = 0 ) {
g_Reg - > m_PROGRAM_COUNTER = g_Reg - > ERROREPC_REGISTER ;
g_Reg - > STATUS_REGISTER & = ~ STATUS_ERL ;
2010-05-25 09:15:19 +00:00
} else {
2012-11-17 02:18:14 +00:00
g_Reg - > m_PROGRAM_COUNTER = g_Reg - > EPC_REGISTER ;
g_Reg - > STATUS_REGISTER & = ~ STATUS_EXL ;
2010-05-25 09:15:19 +00:00
}
2012-11-17 02:18:14 +00:00
g_Reg - > m_LLBit = 0 ;
g_Reg - > CheckInterrupts ( ) ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
void CRecompilerOps : : COP0_CO_ERET ( void ) {
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-25 09:15:19 +00:00
2010-06-04 06:25:07 +00:00
m_RegWorkingSet . WriteBackRegisters ( ) ;
2010-05-25 09:15:19 +00:00
Call_Direct ( compiler_COP0_CO_ERET , " compiler_COP0_CO_ERET " ) ;
2010-06-07 02:23:58 +00:00
UpdateCounters ( m_RegWorkingSet , true , true ) ;
2015-05-02 22:14:19 +00:00
m_Section - > CompileExit ( m_CompilePC , ( DWORD ) - 1 , m_RegWorkingSet , CExitInfo : : Normal , true , NULL ) ;
2010-05-30 01:54:42 +00:00
m_NextInstruction = END_BLOCK ;
2010-05-25 09:15:19 +00:00
}
2010-05-30 01:54:42 +00:00
/************************** FPU Options **************************/
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : ChangeDefaultRoundingModel ( ) {
2010-05-30 01:54:42 +00:00
switch ( ( _FPCR [ 31 ] & 3 ) ) {
2010-06-04 06:25:07 +00:00
case 0 : * _RoundingModel = ROUND_NEAR ; break ;
case 1 : * _RoundingModel = ROUND_CHOP ; break ;
case 2 : * _RoundingModel = ROUND_UP ; break ;
case 3 : * _RoundingModel = ROUND_DOWN ; break ;
2010-05-30 01:54:42 +00:00
}
}
/************************** COP1 functions **************************/
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_MF ( ) {
2010-06-04 06:25:07 +00:00
x86Reg TempReg ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
m_Section - > CompileCop1Test ( ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs , true ) ;
Map_GPR_32bit ( m_Opcode . rt , true , - 1 ) ;
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-04 06:25:07 +00:00
char Name [ 100 ] ;
sprintf ( Name , " _FPR_S[%d] " , m_Opcode . fs ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_S [ m_Opcode . fs ] , Name , TempReg ) ;
2015-05-02 22:14:19 +00:00
MoveX86PointerToX86reg ( GetMipsRegMapLo ( m_Opcode . rt ) , TempReg ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_DMF ( ) {
2010-06-04 06:25:07 +00:00
x86Reg TempReg ;
2010-06-12 02:02:06 +00:00
char Name [ 50 ] ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
m_Section - > CompileCop1Test ( ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs , true ) ;
2010-06-04 06:25:07 +00:00
Map_GPR_64bit ( m_Opcode . rt , - 1 ) ;
2015-05-02 22:14:19 +00:00
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-07 02:23:58 +00:00
sprintf ( Name , " _FPR_D[%d] " , m_Opcode . fs ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_D [ m_Opcode . fs ] , Name , TempReg ) ;
2010-05-30 01:54:42 +00:00
AddConstToX86Reg ( TempReg , 4 ) ;
2015-05-02 22:14:19 +00:00
MoveX86PointerToX86reg ( GetMipsRegMapHi ( m_Opcode . rt ) , TempReg ) ;
2010-06-07 02:23:58 +00:00
sprintf ( Name , " _FPR_D[%d] " , m_Opcode . fs ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_D [ m_Opcode . fs ] , Name , TempReg ) ;
2015-05-02 22:14:19 +00:00
MoveX86PointerToX86reg ( GetMipsRegMapLo ( m_Opcode . rt ) , TempReg ) ;
2010-05-30 01:54:42 +00:00
}
2015-05-02 22:14:19 +00:00
void CRecompilerOps : : COP1_CF ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
if ( m_Opcode . fs ! = 31 & & m_Opcode . fs ! = 0 )
{
UnknownOpcode ( ) ;
return ;
}
Map_GPR_32bit ( m_Opcode . rt , true , - 1 ) ;
2012-11-03 01:18:08 +00:00
MoveVariableToX86reg ( & _FPCR [ m_Opcode . fs ] , CRegName : : FPR_Ctrl [ m_Opcode . fs ] , GetMipsRegMapLo ( m_Opcode . rt ) ) ;
2010-05-30 01:54:42 +00:00
}
2015-05-02 22:14:19 +00:00
void CRecompilerOps : : COP1_MT ( ) {
2010-06-04 06:25:07 +00:00
x86Reg TempReg ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
m_Section - > CompileCop1Test ( ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
if ( ( m_Opcode . fs & 1 ) ! = 0 ) {
if ( RegInStack ( m_Opcode . fs - 1 , CRegInfo : : FPU_Double ) | | RegInStack ( m_Opcode . fs - 1 , CRegInfo : : FPU_Qword ) ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs - 1 , true ) ;
2010-05-30 01:54:42 +00:00
}
}
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs , true ) ;
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-04 06:25:07 +00:00
char Name [ 50 ] ;
sprintf ( Name , " _FPR_S[%d] " , m_Opcode . fs ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_S [ m_Opcode . fs ] , Name , TempReg ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-06 08:19:22 +00:00
MoveConstToX86Pointer ( GetMipsRegLo ( m_Opcode . rt ) , TempReg ) ;
2010-06-04 06:25:07 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
MoveX86regToX86Pointer ( GetMipsRegMapLo ( m_Opcode . rt ) , TempReg ) ;
2010-05-30 01:54:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
MoveX86regToX86Pointer ( Map_TempReg ( x86_Any , m_Opcode . rt , false ) , TempReg ) ;
2010-05-30 01:54:42 +00:00
}
}
2015-05-02 22:14:19 +00:00
void CRecompilerOps : : COP1_DMT ( ) {
2010-06-04 06:25:07 +00:00
x86Reg TempReg ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
m_Section - > CompileCop1Test ( ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
if ( ( m_Opcode . fs & 1 ) = = 0 ) {
if ( RegInStack ( m_Opcode . fs + 1 , CRegInfo : : FPU_Float ) | | RegInStack ( m_Opcode . fs + 1 , CRegInfo : : FPU_Dword ) ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs + 1 , true ) ;
2010-05-30 01:54:42 +00:00
}
}
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs , true ) ;
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-12 02:02:06 +00:00
char Name [ 50 ] ;
2010-06-07 02:23:58 +00:00
sprintf ( Name , " _FPR_D[%d] " , m_Opcode . fs ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_D [ m_Opcode . fs ] , Name , TempReg ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-06 08:19:22 +00:00
MoveConstToX86Pointer ( GetMipsRegLo ( m_Opcode . rt ) , TempReg ) ;
2010-05-30 01:54:42 +00:00
AddConstToX86Reg ( TempReg , 4 ) ;
2010-06-12 02:02:06 +00:00
if ( Is64Bit ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
MoveConstToX86Pointer ( GetMipsRegHi ( m_Opcode . rt ) , TempReg ) ;
2010-05-30 01:54:42 +00:00
} else {
2012-11-03 01:18:08 +00:00
MoveConstToX86Pointer ( GetMipsRegLo_S ( m_Opcode . rt ) > > 31 , TempReg ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
MoveX86regToX86Pointer ( GetMipsRegMapLo ( m_Opcode . rt ) , TempReg ) ;
2010-05-30 01:54:42 +00:00
AddConstToX86Reg ( TempReg , 4 ) ;
2010-06-12 02:02:06 +00:00
if ( Is64Bit ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
MoveX86regToX86Pointer ( GetMipsRegMapHi ( m_Opcode . rt ) , TempReg ) ;
2010-05-30 01:54:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
MoveX86regToX86Pointer ( Map_TempReg ( x86_Any , m_Opcode . rt , true ) , TempReg ) ;
2010-05-30 01:54:42 +00:00
}
} else {
2015-05-02 22:14:19 +00:00
x86Reg Reg = Map_TempReg ( x86_Any , m_Opcode . rt , false ) ;
2010-06-04 06:25:07 +00:00
MoveX86regToX86Pointer ( Reg , TempReg ) ;
2010-05-30 01:54:42 +00:00
AddConstToX86Reg ( TempReg , 4 ) ;
2015-05-02 22:14:19 +00:00
MoveX86regToX86Pointer ( Map_TempReg ( Reg , m_Opcode . rt , true ) , TempReg ) ;
2010-05-30 01:54:42 +00:00
}
}
2015-05-02 22:14:19 +00:00
void CRecompilerOps : : COP1_CT ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
m_Section - > CompileCop1Test ( ) ;
2015-05-02 22:14:19 +00:00
if ( m_Opcode . fs ! = 31 ) {
UnknownOpcode ( ) ;
return ;
}
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
if ( IsConst ( m_Opcode . rt ) ) {
2012-11-06 08:19:22 +00:00
MoveConstToVariable ( GetMipsRegLo ( m_Opcode . rt ) , & _FPCR [ m_Opcode . fs ] , CRegName : : FPR_Ctrl [ m_Opcode . fs ] ) ;
2010-06-04 06:25:07 +00:00
} else if ( IsMapped ( m_Opcode . rt ) ) {
2012-11-03 01:18:08 +00:00
MoveX86regToVariable ( GetMipsRegMapLo ( m_Opcode . rt ) , & _FPCR [ m_Opcode . fs ] , CRegName : : FPR_Ctrl [ m_Opcode . fs ] ) ;
2010-05-30 01:54:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
MoveX86regToVariable ( Map_TempReg ( x86_Any , m_Opcode . rt , false ) , & _FPCR [ m_Opcode . fs ] , CRegName : : FPR_Ctrl [ m_Opcode . fs ] ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-14 21:14:58 +00:00
BeforeCallDirect ( m_RegWorkingSet ) ;
2010-05-30 01:54:42 +00:00
Call_Direct ( ChangeDefaultRoundingModel , " ChangeDefaultRoundingModel " ) ;
2010-06-14 21:14:58 +00:00
AfterCallDirect ( m_RegWorkingSet ) ;
2010-07-23 10:45:35 +00:00
m_RegWorkingSet . SetRoundingModel ( CRegInfo : : RoundUnknown ) ;
2010-05-30 01:54:42 +00:00
}
/************************** COP1: S functions ************************/
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_ADD ( ) {
2010-06-04 06:25:07 +00:00
DWORD Reg1 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . ft : m_Opcode . fs ;
DWORD Reg2 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . fs : m_Opcode . ft ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
FixRoundModel ( CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , Reg1 , CRegInfo : : FPU_Float ) ;
if ( RegInStack ( Reg2 , CRegInfo : : FPU_Float ) ) {
fpuAddReg ( StackPosition ( Reg2 ) ) ;
2010-05-30 01:54:42 +00:00
} else {
2010-06-04 06:25:07 +00:00
x86Reg TempReg ;
2015-05-02 22:14:19 +00:00
UnMap_FPR ( Reg2 , true ) ;
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-04 06:25:07 +00:00
char Name [ 50 ] ;
sprintf ( Name , " _FPR_S[%d] " , Reg2 ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_S [ Reg2 ] , Name , TempReg ) ;
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fd , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
fpuAddDwordRegPointer ( TempReg ) ;
}
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fd , true ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_SUB ( ) {
2010-06-04 06:25:07 +00:00
DWORD Reg1 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . ft : m_Opcode . fs ;
DWORD Reg2 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . fs : m_Opcode . ft ;
x86Reg TempReg ;
2015-05-02 22:14:19 +00:00
char Name [ 50 ] ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
FixRoundModel ( CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd = = m_Opcode . ft ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fd , true ) ;
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-04 06:25:07 +00:00
sprintf ( Name , " _FPR_S[%d] " , m_Opcode . ft ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_S [ m_Opcode . ft ] , Name , TempReg ) ;
2010-05-30 01:54:42 +00:00
fpuSubDwordRegPointer ( TempReg ) ;
} else {
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , Reg1 , CRegInfo : : FPU_Float ) ;
if ( RegInStack ( Reg2 , CRegInfo : : FPU_Float ) ) {
fpuSubReg ( StackPosition ( Reg2 ) ) ;
2010-05-30 01:54:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( Reg2 , true ) ;
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fd , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-04 06:25:07 +00:00
sprintf ( Name , " _FPR_S[%d] " , Reg2 ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_S [ Reg2 ] , Name , TempReg ) ;
2015-05-02 22:14:19 +00:00
fpuSubDwordRegPointer ( TempReg ) ;
2010-05-30 01:54:42 +00:00
}
}
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fd , true ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_MUL ( ) {
2010-06-04 06:25:07 +00:00
DWORD Reg1 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . ft : m_Opcode . fs ;
DWORD Reg2 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . fs : m_Opcode . ft ;
x86Reg TempReg ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
FixRoundModel ( CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , Reg1 , CRegInfo : : FPU_Float ) ;
if ( RegInStack ( Reg2 , CRegInfo : : FPU_Float ) ) {
fpuMulReg ( StackPosition ( Reg2 ) ) ;
2010-05-30 01:54:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( Reg2 , true ) ;
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fd , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-04 06:25:07 +00:00
char Name [ 50 ] ;
sprintf ( Name , " _FPR_S[%d] " , Reg2 ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_S [ Reg2 ] , Name , TempReg ) ;
2015-05-02 22:14:19 +00:00
fpuMulDwordRegPointer ( TempReg ) ;
2010-05-30 01:54:42 +00:00
}
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fd , true ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_DIV ( ) {
2010-06-04 06:25:07 +00:00
DWORD Reg1 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . ft : m_Opcode . fs ;
DWORD Reg2 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . fs : m_Opcode . ft ;
x86Reg TempReg ;
char Name [ 50 ] ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
FixRoundModel ( CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd = = m_Opcode . ft ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fd , true ) ;
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-04 06:25:07 +00:00
sprintf ( Name , " _FPR_S[%d] " , m_Opcode . ft ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_S [ m_Opcode . ft ] , Name , TempReg ) ;
2010-05-30 01:54:42 +00:00
fpuDivDwordRegPointer ( TempReg ) ;
} else {
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , Reg1 , CRegInfo : : FPU_Float ) ;
if ( RegInStack ( Reg2 , CRegInfo : : FPU_Float ) ) {
fpuDivReg ( StackPosition ( Reg2 ) ) ;
2010-05-30 01:54:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( Reg2 , true ) ;
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fd , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-04 06:25:07 +00:00
sprintf ( Name , " _FPR_S[%d] " , Reg2 ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_S [ Reg2 ] , Name , TempReg ) ;
2015-05-02 22:14:19 +00:00
fpuDivDwordRegPointer ( TempReg ) ;
2010-05-30 01:54:42 +00:00
}
}
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fd , true ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_ABS ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
FixRoundModel ( CRegInfo : : RoundDefault ) ;
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
fpuAbs ( ) ;
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fd , true ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_NEG ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
FixRoundModel ( CRegInfo : : RoundDefault ) ;
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
fpuNeg ( ) ;
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fd , true ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_SQRT ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
FixRoundModel ( CRegInfo : : RoundDefault ) ;
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
fpuSqrt ( ) ;
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fd , true ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_MOV ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
FixRoundModel ( CRegInfo : : RoundDefault ) ;
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_TRUNC_L ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Float ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Float , CRegInfo : : FPU_Qword , CRegInfo : : RoundTruncate ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_CEIL_L ( ) { //added by Witten
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Float ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Float , CRegInfo : : FPU_Qword , CRegInfo : : RoundUp ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_FLOOR_L ( ) { //added by Witten
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Float ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Float , CRegInfo : : FPU_Qword , CRegInfo : : RoundDown ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_ROUND_W ( )
2010-06-14 21:14:58 +00:00
{
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Float ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Float , CRegInfo : : FPU_Dword , CRegInfo : : RoundNearest ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_TRUNC_W ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Float ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Float , CRegInfo : : FPU_Dword , CRegInfo : : RoundTruncate ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_CEIL_W ( ) { // added by Witten
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Float ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Float , CRegInfo : : FPU_Dword , CRegInfo : : RoundUp ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_FLOOR_W ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Float ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Float , CRegInfo : : FPU_Dword , CRegInfo : : RoundDown ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_CVT_D ( )
2010-06-07 02:23:58 +00:00
{
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Float ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Float , CRegInfo : : FPU_Double , CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_CVT_W ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Float ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Float , CRegInfo : : FPU_Dword , CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_CVT_L ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Float ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Float , CRegInfo : : FPU_Qword , CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_S_CMP ( ) {
2010-06-07 02:23:58 +00:00
DWORD Reg1 = m_Opcode . fs ;
DWORD Reg2 = m_Opcode . ft ;
DWORD cmp = 0 ;
2010-05-30 01:54:42 +00:00
2010-06-07 02:23:58 +00:00
if ( ( m_Opcode . funct & 4 ) = = 0 )
{
Reg1 = RegInStack ( m_Opcode . ft , CRegInfo : : FPU_Float ) ? m_Opcode . ft : m_Opcode . fs ;
Reg2 = RegInStack ( m_Opcode . ft , CRegInfo : : FPU_Float ) ? m_Opcode . fs : m_Opcode . ft ;
}
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-22 20:36:28 +00:00
if ( ( m_Opcode . funct & 7 ) = = 0 ) { CRecompilerOps : : UnknownOpcode ( ) ; }
2010-06-04 06:25:07 +00:00
if ( ( m_Opcode . funct & 2 ) ! = 0 ) { cmp | = 0x4000 ; }
if ( ( m_Opcode . funct & 4 ) ! = 0 ) { cmp | = 0x0100 ; }
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( Reg1 , Reg1 , CRegInfo : : FPU_Float ) ;
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_EAX , 0 , false ) ;
2010-06-04 06:25:07 +00:00
if ( RegInStack ( Reg2 , CRegInfo : : FPU_Float ) ) {
2015-05-02 22:14:19 +00:00
fpuComReg ( StackPosition ( Reg2 ) , false ) ;
2010-05-30 01:54:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( Reg2 , true ) ;
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( Reg1 , Reg1 , CRegInfo : : FPU_Float ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
x86Reg TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-07 02:23:58 +00:00
char Name [ 50 ] ;
2010-06-04 06:25:07 +00:00
sprintf ( Name , " _FPR_S[%d] " , Reg2 ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_S [ Reg2 ] , Name , TempReg ) ;
2015-05-02 22:14:19 +00:00
fpuComDwordRegPointer ( TempReg , false ) ;
2010-05-30 01:54:42 +00:00
}
2012-10-06 04:09:17 +00:00
AndConstToVariable ( ( DWORD ) ~ FPCSR_C , & _FPCR [ 31 ] , " _FPCR[31] " ) ;
2010-05-30 01:54:42 +00:00
fpuStoreStatus ( ) ;
2015-05-02 22:14:19 +00:00
x86Reg Reg = Map_TempReg ( x86_Any8Bit , 0 , false ) ;
TestConstToX86Reg ( cmp , x86_EAX ) ;
2010-06-07 02:23:58 +00:00
Setnz ( Reg ) ;
2010-05-30 01:54:42 +00:00
if ( cmp ! = 0 ) {
2015-05-02 22:14:19 +00:00
TestConstToX86Reg ( cmp , x86_EAX ) ;
2010-06-07 02:23:58 +00:00
Setnz ( Reg ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
if ( ( m_Opcode . funct & 1 ) ! = 0 ) {
2015-05-02 22:14:19 +00:00
x86Reg Reg2 = Map_TempReg ( x86_Any8Bit , 0 , false ) ;
2010-05-30 01:54:42 +00:00
AndConstToX86Reg ( x86_EAX , 0x4300 ) ;
CompConstToX86reg ( x86_EAX , 0x4300 ) ;
2010-06-07 02:23:58 +00:00
Setz ( Reg2 ) ;
2010-05-30 01:54:42 +00:00
2010-06-07 02:23:58 +00:00
OrX86RegToX86Reg ( Reg , Reg2 ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
} else if ( ( m_Opcode . funct & 1 ) ! = 0 ) {
2010-05-30 01:54:42 +00:00
AndConstToX86Reg ( x86_EAX , 0x4300 ) ;
CompConstToX86reg ( x86_EAX , 0x4300 ) ;
2010-06-07 02:23:58 +00:00
Setz ( Reg ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-07 02:23:58 +00:00
ShiftLeftSignImmed ( Reg , 23 ) ;
OrX86RegToVariable ( & _FPCR [ 31 ] , " _FPCR[31] " , Reg ) ;
2010-05-30 01:54:42 +00:00
}
/************************** COP1: D functions ************************/
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_ADD ( ) {
2010-06-04 06:25:07 +00:00
DWORD Reg1 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . ft : m_Opcode . fs ;
DWORD Reg2 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . fs : m_Opcode . ft ;
2010-06-07 02:23:58 +00:00
char Name [ 50 ] ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , Reg1 , CRegInfo : : FPU_Double ) ;
if ( RegInStack ( Reg2 , CRegInfo : : FPU_Double ) ) {
fpuAddReg ( StackPosition ( Reg2 ) ) ;
2010-05-30 01:54:42 +00:00
} else {
2010-06-04 06:25:07 +00:00
x86Reg TempReg ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
UnMap_FPR ( Reg2 , true ) ;
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-07 02:23:58 +00:00
sprintf ( Name , " _FPR_D[%d] " , Reg2 ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_D [ Reg2 ] , Name , TempReg ) ;
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fd , CRegInfo : : FPU_Double ) ;
2015-05-02 22:14:19 +00:00
fpuAddQwordRegPointer ( TempReg ) ;
2010-05-30 01:54:42 +00:00
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_SUB ( ) {
2010-06-04 06:25:07 +00:00
DWORD Reg1 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . ft : m_Opcode . fs ;
DWORD Reg2 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . fs : m_Opcode . ft ;
x86Reg TempReg ;
2010-06-07 02:23:58 +00:00
char Name [ 50 ] ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd = = m_Opcode . ft ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fd , true ) ;
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-07 02:23:58 +00:00
sprintf ( Name , " _FPR_D[%d] " , m_Opcode . ft ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_D [ m_Opcode . ft ] , Name , TempReg ) ;
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
fpuSubQwordRegPointer ( TempReg ) ;
} else {
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , Reg1 , CRegInfo : : FPU_Double ) ;
if ( RegInStack ( Reg2 , CRegInfo : : FPU_Double ) ) {
fpuSubReg ( StackPosition ( Reg2 ) ) ;
2010-05-30 01:54:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( Reg2 , true ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-07 02:23:58 +00:00
sprintf ( Name , " _FPR_D[%d] " , Reg2 ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_D [ Reg2 ] , Name , TempReg ) ;
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fd , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
fpuSubQwordRegPointer ( TempReg ) ;
}
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_MUL ( ) {
2010-06-04 06:25:07 +00:00
DWORD Reg1 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . ft : m_Opcode . fs ;
DWORD Reg2 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . fs : m_Opcode . ft ;
x86Reg TempReg ;
2010-06-07 02:23:58 +00:00
char Name [ 50 ] ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
FixRoundModel ( CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , Reg1 , CRegInfo : : FPU_Double ) ;
if ( RegInStack ( Reg2 , CRegInfo : : FPU_Double ) ) {
fpuMulReg ( StackPosition ( Reg2 ) ) ;
2010-05-30 01:54:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( Reg2 , true ) ;
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fd , CRegInfo : : FPU_Double ) ;
2015-05-02 22:14:19 +00:00
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-07 02:23:58 +00:00
sprintf ( Name , " _FPR_D[%d] " , Reg2 ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_D [ Reg2 ] , Name , TempReg ) ;
2010-05-30 01:54:42 +00:00
fpuMulQwordRegPointer ( TempReg ) ;
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_DIV ( ) {
2010-06-04 06:25:07 +00:00
DWORD Reg1 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . ft : m_Opcode . fs ;
DWORD Reg2 = m_Opcode . ft = = m_Opcode . fd ? m_Opcode . fs : m_Opcode . ft ;
x86Reg TempReg ;
2010-06-07 02:23:58 +00:00
char Name [ 50 ] ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd = = m_Opcode . ft ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fd , true ) ;
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-07 02:23:58 +00:00
sprintf ( Name , " _FPR_D[%d] " , m_Opcode . ft ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_D [ m_Opcode . ft ] , Name , TempReg ) ;
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
fpuDivQwordRegPointer ( TempReg ) ;
} else {
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , Reg1 , CRegInfo : : FPU_Double ) ;
if ( RegInStack ( Reg2 , CRegInfo : : FPU_Double ) ) {
fpuDivReg ( StackPosition ( Reg2 ) ) ;
2010-05-30 01:54:42 +00:00
} else {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( Reg2 , true ) ;
TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-07 02:23:58 +00:00
sprintf ( Name , " _FPR_D[%d] " , Reg2 ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_D [ Reg2 ] , Name , TempReg ) ;
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fd , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
fpuDivQwordRegPointer ( TempReg ) ;
}
}
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_ABS ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
fpuAbs ( ) ;
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_NEG ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
fpuNeg ( ) ;
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_SQRT ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
fpuSqrt ( ) ;
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_MOV ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_TRUNC_L ( ) { //added by Witten
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
if ( RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Double ) | | RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Qword ) ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs , true ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Double ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Double , CRegInfo : : FPU_Qword , CRegInfo : : RoundTruncate ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_CEIL_L ( ) { //added by Witten
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
if ( RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Double ) | | RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Qword ) ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs , true ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Double ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Double , CRegInfo : : FPU_Qword , CRegInfo : : RoundUp ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_FLOOR_L ( ) { //added by Witten
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
if ( RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Double ) | | RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Qword ) ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs , true ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Double ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Double , CRegInfo : : FPU_Qword , CRegInfo : : RoundDown ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_ROUND_W ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
if ( RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Double ) | | RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Qword ) ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs , true ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Double ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Double , CRegInfo : : FPU_Dword , CRegInfo : : RoundNearest ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_TRUNC_W ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-07 02:23:58 +00:00
if ( RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Double ) | | RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Qword ) ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fd , true ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Double ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Double , CRegInfo : : FPU_Dword , CRegInfo : : RoundTruncate ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_CEIL_W ( ) { // added by Witten
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
if ( RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Double ) | | RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Qword ) ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs , true ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Double ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Double , CRegInfo : : FPU_Dword , CRegInfo : : RoundUp ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_FLOOR_W ( ) { //added by Witten
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
if ( RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Double ) | | RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Qword ) ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs , true ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Double ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Double , CRegInfo : : FPU_Dword , CRegInfo : : RoundDown ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_CVT_S ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-07 02:23:58 +00:00
if ( RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Double ) | | RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Qword ) ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fd , true ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Double ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Double , CRegInfo : : FPU_Float , CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_CVT_W ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
if ( RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Double ) | | RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Qword ) ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs , true ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Double ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Double , CRegInfo : : FPU_Dword , CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_CVT_L ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
m_Section - > CompileCop1Test ( ) ;
2010-06-04 06:25:07 +00:00
if ( RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Double ) | | RegInStack ( m_Opcode . fs , CRegInfo : : FPU_Qword ) ) {
2015-05-02 22:14:19 +00:00
UnMap_FPR ( m_Opcode . fs , true ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Double ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Double ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Double , CRegInfo : : FPU_Qword , CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_D_CMP ( ) {
2010-06-07 02:23:58 +00:00
DWORD Reg1 = m_Opcode . fs ;
DWORD Reg2 = m_Opcode . ft ;
DWORD cmp = 0 ;
2010-05-30 01:54:42 +00:00
2010-06-07 02:23:58 +00:00
if ( ( m_Opcode . funct & 4 ) = = 0 )
{
Reg1 = RegInStack ( m_Opcode . ft , CRegInfo : : FPU_Double ) ? m_Opcode . ft : m_Opcode . fs ;
Reg2 = RegInStack ( m_Opcode . ft , CRegInfo : : FPU_Double ) ? m_Opcode . fs : m_Opcode . ft ;
}
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
2013-02-03 10:05:58 +00:00
if ( ( m_Opcode . funct & 7 ) = = 0 ) { CRecompilerOps : : UnknownOpcode ( ) ; }
2010-06-04 06:25:07 +00:00
if ( ( m_Opcode . funct & 2 ) ! = 0 ) { cmp | = 0x4000 ; }
if ( ( m_Opcode . funct & 4 ) ! = 0 ) { cmp | = 0x0100 ; }
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( Reg1 , Reg1 , CRegInfo : : FPU_Double ) ;
2015-05-02 22:14:19 +00:00
Map_TempReg ( x86_EAX , 0 , false ) ;
2010-06-04 06:25:07 +00:00
if ( RegInStack ( Reg2 , CRegInfo : : FPU_Double ) ) {
2015-05-02 22:14:19 +00:00
fpuComReg ( StackPosition ( Reg2 ) , false ) ;
2010-05-30 01:54:42 +00:00
} else {
2010-06-07 02:23:58 +00:00
char Name [ 50 ] ;
2010-05-30 01:54:42 +00:00
2015-05-02 22:14:19 +00:00
UnMap_FPR ( Reg2 , true ) ;
x86Reg TempReg = Map_TempReg ( x86_Any , - 1 , false ) ;
2010-06-07 02:23:58 +00:00
sprintf ( Name , " _FPR_D[%d] " , Reg2 ) ;
MoveVariableToX86reg ( ( BYTE * ) & _FPR_D [ Reg2 ] , Name , TempReg ) ;
2010-06-04 06:25:07 +00:00
Load_FPR_ToTop ( Reg1 , Reg1 , CRegInfo : : FPU_Double ) ;
2015-05-02 22:14:19 +00:00
fpuComQwordRegPointer ( TempReg , false ) ;
2010-05-30 01:54:42 +00:00
}
2012-10-06 04:09:17 +00:00
AndConstToVariable ( ( DWORD ) ~ FPCSR_C , & _FPCR [ 31 ] , " _FPCR[31] " ) ;
2010-05-30 01:54:42 +00:00
fpuStoreStatus ( ) ;
2015-05-02 22:14:19 +00:00
x86Reg Reg = Map_TempReg ( x86_Any8Bit , 0 , false ) ;
TestConstToX86Reg ( cmp , x86_EAX ) ;
2010-06-07 02:23:58 +00:00
Setnz ( Reg ) ;
2010-05-30 01:54:42 +00:00
if ( cmp ! = 0 ) {
2015-05-02 22:14:19 +00:00
TestConstToX86Reg ( cmp , x86_EAX ) ;
2010-06-07 02:23:58 +00:00
Setnz ( Reg ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
if ( ( m_Opcode . funct & 1 ) ! = 0 ) {
2015-05-02 22:14:19 +00:00
x86Reg Reg2 = Map_TempReg ( x86_Any8Bit , 0 , false ) ;
2010-05-30 01:54:42 +00:00
AndConstToX86Reg ( x86_EAX , 0x4300 ) ;
CompConstToX86reg ( x86_EAX , 0x4300 ) ;
2010-06-07 02:23:58 +00:00
Setz ( Reg2 ) ;
2010-05-30 01:54:42 +00:00
2010-06-07 02:23:58 +00:00
OrX86RegToX86Reg ( Reg , Reg2 ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
} else if ( ( m_Opcode . funct & 1 ) ! = 0 ) {
2010-05-30 01:54:42 +00:00
AndConstToX86Reg ( x86_EAX , 0x4300 ) ;
CompConstToX86reg ( x86_EAX , 0x4300 ) ;
2010-06-07 02:23:58 +00:00
Setz ( Reg ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-07 02:23:58 +00:00
ShiftLeftSignImmed ( Reg , 23 ) ;
OrX86RegToVariable ( & _FPCR [ 31 ] , " _FPCR[31] " , Reg ) ;
2010-05-30 01:54:42 +00:00
}
/************************** COP1: W functions ************************/
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_W_CVT_S ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Dword ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Dword ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Dword , CRegInfo : : FPU_Float , CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_W_CVT_D ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Dword ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Dword ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Dword , CRegInfo : : FPU_Double , CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
}
/************************** COP1: L functions ************************/
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_L_CVT_S ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Qword ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Qword ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Qword , CRegInfo : : FPU_Float , CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : COP1_L_CVT_D ( ) {
2010-06-04 06:25:07 +00:00
CPU_Message ( " %X %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_Section - > CompileCop1Test ( ) ;
if ( m_Opcode . fd ! = m_Opcode . fs | | ! RegInStack ( m_Opcode . fd , CRegInfo : : FPU_Qword ) ) {
Load_FPR_ToTop ( m_Opcode . fd , m_Opcode . fs , CRegInfo : : FPU_Qword ) ;
2010-05-30 01:54:42 +00:00
}
2010-06-04 06:25:07 +00:00
ChangeFPURegFormat ( m_Opcode . fd , CRegInfo : : FPU_Qword , CRegInfo : : FPU_Double , CRegInfo : : RoundDefault ) ;
2010-05-30 01:54:42 +00:00
}
/************************** Other functions **************************/
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : UnknownOpcode ( ) {
2010-06-22 20:36:28 +00:00
CPU_Message ( " %X Unhandled Opcode: %s " , m_CompilePC , R4300iOpcodeName ( m_Opcode . Hex , m_CompilePC ) ) ;
2010-05-30 01:54:42 +00:00
2010-06-04 06:25:07 +00:00
m_RegWorkingSet . WriteBackRegisters ( ) ;
2010-06-22 20:36:28 +00:00
UpdateCounters ( m_RegWorkingSet , false , true ) ;
2012-11-17 02:18:14 +00:00
MoveConstToVariable ( m_CompilePC , & g_Reg - > m_PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
2012-11-17 01:12:54 +00:00
if ( g_SyncSystem ) {
2012-11-17 01:09:19 +00:00
MoveConstToX86reg ( ( DWORD ) g_BaseSystem , x86_ECX ) ;
2012-09-30 06:07:08 +00:00
Call_Direct ( AddressOf ( & CN64System : : SyncSystem ) , " CN64System::SyncSystem " ) ;
}
2012-11-29 11:23:35 +00:00
m_RegWorkingSet . SetBlockCycleCount ( m_RegWorkingSet . GetBlockCycleCount ( ) - g_System - > CountPerOp ( ) ) ;
2010-06-22 20:36:28 +00:00
MoveConstToVariable ( m_Opcode . Hex , & R4300iOp : : m_Opcode . Hex , " R4300iOp::m_Opcode.Hex " ) ;
2010-05-30 01:54:42 +00:00
Call_Direct ( R4300iOp : : UnknownOpcode , " R4300iOp::UnknownOpcode " ) ;
Ret ( ) ;
if ( m_NextInstruction = = NORMAL ) { m_NextInstruction = END_BLOCK ; }
}
2010-06-14 21:14:58 +00:00
void CRecompilerOps : : BeforeCallDirect ( CRegInfo & RegSet )
2010-06-07 02:23:58 +00:00
{
2010-06-14 21:14:58 +00:00
RegSet . UnMap_AllFPRs ( ) ;
2010-06-07 02:23:58 +00:00
Pushad ( ) ;
}
2010-06-14 21:14:58 +00:00
void CRecompilerOps : : AfterCallDirect ( CRegInfo & RegSet )
2010-06-07 02:23:58 +00:00
{
Popad ( ) ;
2010-07-23 10:45:35 +00:00
RegSet . SetRoundingModel ( CRegInfo : : RoundUnknown ) ;
2010-06-07 02:23:58 +00:00
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : EnterCodeBlock ( )
2010-05-31 00:21:08 +00:00
{
# ifdef _DEBUG
Push ( x86_ESI ) ;
2010-06-22 20:36:28 +00:00
# else
2012-09-25 22:45:39 +00:00
Push ( x86_EDI ) ;
2010-06-22 20:36:28 +00:00
Push ( x86_ESI ) ;
Push ( x86_EBX ) ;
2010-05-31 00:21:08 +00:00
# endif
}
2015-04-28 22:19:02 +00:00
void CRecompilerOps : : ExitCodeBlock ( )
2010-05-31 00:21:08 +00:00
{
# ifdef _DEBUG
Pop ( x86_ESI ) ;
2010-06-22 20:36:28 +00:00
# else
Pop ( x86_EBX ) ;
Pop ( x86_ESI ) ;
2012-09-25 22:45:39 +00:00
Pop ( x86_EDI ) ;
2010-05-31 00:21:08 +00:00
# endif
Ret ( ) ;
}
2012-09-25 05:58:06 +00:00
void CRecompilerOps : : UpdateSyncCPU ( CRegInfo & RegSet , DWORD Cycles )
{
2012-11-17 01:12:54 +00:00
if ( ! g_SyncSystem )
2012-09-25 05:58:06 +00:00
{
return ;
}
WriteX86Comment ( " Updating Sync CPU " ) ;
BeforeCallDirect ( RegSet ) ;
PushImm32 ( stdstr_f ( " %d " , Cycles ) . c_str ( ) , Cycles ) ;
2012-11-17 01:12:54 +00:00
PushImm32 ( " g_SyncSystem " , ( DWORD ) g_SyncSystem ) ;
2012-11-17 01:07:04 +00:00
MoveConstToX86reg ( ( DWORD ) g_System , x86_ECX ) ;
2012-09-25 05:58:06 +00:00
Call_Direct ( AddressOf ( & CN64System : : UpdateSyncCPU ) , " CN64System::UpdateSyncCPU " ) ;
AfterCallDirect ( RegSet ) ;
}
2010-05-30 01:54:42 +00:00
void CRecompilerOps : : UpdateCounters ( CRegInfo & RegSet , bool CheckTimer , bool ClearValues )
{
if ( RegSet . GetBlockCycleCount ( ) ! = 0 )
{
2012-09-25 05:58:06 +00:00
UpdateSyncCPU ( RegSet , RegSet . GetBlockCycleCount ( ) ) ;
2010-05-30 01:54:42 +00:00
WriteX86Comment ( " Update Counter " ) ;
2012-11-17 03:45:50 +00:00
SubConstFromVariable ( RegSet . GetBlockCycleCount ( ) , g_NextTimer , " g_NextTimer " ) ; // updates compare flag
2010-05-30 01:54:42 +00:00
if ( ClearValues )
{
RegSet . SetBlockCycleCount ( 0 ) ;
}
} else if ( CheckTimer ) {
2012-11-17 03:45:50 +00:00
CompConstToVariable ( 0 , g_NextTimer , " g_NextTimer " ) ;
2010-05-30 01:54:42 +00:00
}
if ( CheckTimer )
{
JnsLabel8 ( " Continue_From_Timer_Test " , 0 ) ;
BYTE * Jump = m_RecompPos - 1 ;
Pushad ( ) ;
2012-11-17 02:31:46 +00:00
MoveConstToX86reg ( ( DWORD ) g_SystemTimer , x86_ECX ) ;
2010-09-22 21:43:42 +00:00
Call_Direct ( AddressOf ( & CSystemTimer : : TimerDone ) , " CSystemTimer::TimerDone " ) ;
2010-05-30 01:54:42 +00:00
Popad ( ) ;
CPU_Message ( " " ) ;
CPU_Message ( " $Continue_From_Timer_Test: " ) ;
2010-10-23 18:53:01 +00:00
SetJump8 ( Jump , m_RecompPos ) ;
2010-05-30 01:54:42 +00:00
}
}
2010-05-25 09:15:19 +00:00
2012-10-14 01:05:52 +00:00
void CRecompilerOps : : CompileSystemCheck ( DWORD TargetPC , const CRegInfo & RegSet )
2010-10-23 18:53:01 +00:00
{
2012-11-17 03:43:02 +00:00
CompConstToVariable ( 0 , ( void * ) & g_SystemEvents - > DoSomething ( ) , " g_SystemEvents->DoSomething() " ) ;
2010-10-23 18:53:01 +00:00
JeLabel32 ( " Continue_From_Interrupt_Test " , 0 ) ;
DWORD * Jump = ( DWORD * ) ( m_RecompPos - 4 ) ;
if ( TargetPC ! = ( DWORD ) - 1 )
{
2012-11-17 02:18:14 +00:00
MoveConstToVariable ( TargetPC , & g_Reg - > m_PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
2010-10-23 18:53:01 +00:00
}
2012-10-14 01:05:52 +00:00
CRegInfo RegSetCopy ( RegSet ) ;
RegSetCopy . WriteBackRegisters ( ) ;
2012-11-17 03:43:02 +00:00
MoveConstToX86reg ( ( DWORD ) g_SystemEvents , x86_ECX ) ;
2010-10-23 18:53:01 +00:00
Call_Direct ( AddressOf ( & CSystemEvents : : ExecuteEvents ) , " CSystemEvents::ExecuteEvents " ) ;
2012-11-17 01:12:54 +00:00
if ( g_SyncSystem ) {
2012-11-17 01:09:19 +00:00
MoveConstToX86reg ( ( DWORD ) g_BaseSystem , x86_ECX ) ;
2012-09-30 06:07:08 +00:00
Call_Direct ( AddressOf ( & CN64System : : SyncSystem ) , " CN64System::SyncSystem " ) ;
}
2010-10-23 18:53:01 +00:00
ExitCodeBlock ( ) ;
CPU_Message ( " " ) ;
CPU_Message ( " $Continue_From_Interrupt_Test: " ) ;
SetJump32 ( Jump , ( DWORD * ) m_RecompPos ) ;
}
2015-05-02 22:14:19 +00:00
void CRecompilerOps : : OverflowDelaySlot ( bool TestTimer )
2012-09-25 05:58:06 +00:00
{
m_RegWorkingSet . WriteBackRegisters ( ) ;
UpdateCounters ( m_RegWorkingSet , false , true ) ;
MoveConstToVariable ( CompilePC ( ) + 4 , _PROGRAM_COUNTER , " PROGRAM_COUNTER " ) ;
2015-05-02 22:14:19 +00:00
if ( g_SyncSystem )
{
2012-11-17 01:09:19 +00:00
MoveConstToX86reg ( ( DWORD ) g_BaseSystem , x86_ECX ) ;
2015-05-02 22:14:19 +00:00
Call_Direct ( AddressOf ( & CN64System : : SyncSystem ) , " CN64System::SyncSystem " ) ;
2012-09-30 06:07:08 +00:00
}
2015-05-02 22:14:19 +00:00
2012-09-25 05:58:06 +00:00
MoveConstToVariable ( JUMP , & R4300iOp : : m_NextInstruction , " R4300iOp::m_NextInstruction " ) ;
2015-05-02 22:14:19 +00:00
2012-09-26 00:38:29 +00:00
if ( TestTimer )
MoveConstToVariable ( TestTimer , & R4300iOp : : m_TestTimer , " R4300iOp::m_TestTimer " ) ;
2015-05-02 22:14:19 +00:00
2012-11-29 11:23:35 +00:00
PushImm32 ( " g_System->CountPerOp() " , g_System - > CountPerOp ( ) ) ;
2012-09-25 05:58:06 +00:00
Call_Direct ( CInterpreterCPU : : ExecuteOps , " CInterpreterCPU::ExecuteOps " ) ;
AddConstToX86Reg ( x86_ESP , 4 ) ;
2015-05-02 22:14:19 +00:00
2012-11-29 11:23:35 +00:00
if ( g_System - > bFastSP ( ) & & g_Recompiler )
2012-09-25 22:07:49 +00:00
{
2015-05-02 22:14:19 +00:00
MoveConstToX86reg ( ( DWORD ) g_Recompiler , x86_ECX ) ;
2012-09-25 22:07:49 +00:00
Call_Direct ( AddressOf ( & CRecompiler : : ResetMemoryStackPos ) , " CRecompiler::ResetMemoryStackPos " ) ;
}
2015-05-02 22:14:19 +00:00
if ( g_SyncSystem )
{
2012-11-29 11:23:35 +00:00
UpdateSyncCPU ( m_RegWorkingSet , g_System - > CountPerOp ( ) ) ;
2012-11-17 01:09:19 +00:00
MoveConstToX86reg ( ( DWORD ) g_BaseSystem , x86_ECX ) ;
2015-05-02 22:14:19 +00:00
Call_Direct ( AddressOf ( & CN64System : : SyncSystem ) , " CN64System::SyncSystem " ) ;
2012-09-25 05:58:06 +00:00
}
2015-05-02 22:14:19 +00:00
2012-09-25 05:58:06 +00:00
ExitCodeBlock ( ) ;
m_NextInstruction = END_BLOCK ;
2015-01-31 19:27:27 +00:00
}