/* * Project 64 - A Nintendo 64 emulator. * * (c) Copyright 2001 zilmar (zilmar@emulation64.com) and * Jabo (jabo@emulation64.com). * * pj64 homepage: www.pj64.net * * Permission to use, copy, modify and distribute Project64 in both binary and * source form, for non-commercial purposes, is hereby granted without fee, * providing that this license information and copyright notice appear with * all copies and any derived work. * * This software is provided 'as-is', without any express or implied * warranty. In no event shall the authors be held liable for any damages * arising from the use of this software. * * Project64 is freeware for PERSONAL USE only. Commercial users should * seek permission of the copyright holders first. Commercial use includes * charging money for Project64 or software derived from Project64. * * The copyright holders request that bug fixes and improvements to the code * should be forwarded to them so if they want them. * */ #include #include #include "c core.h" #include "main.h" #include "cpu.h" #include "x86.h" #include "debugger.h" #include "Recompiler Ops.h" DWORD BranchCompare = 0; void CompileReadTLBMiss (CBlockSection * Section, int AddressReg, int LookUpReg ) { MoveX86regToVariable(AddressReg,&TLBLoadAddress,"TLBLoadAddress"); TestX86RegToX86Reg(LookUpReg,LookUpReg); g_N64System->GetRecompiler()->CompileExit (Section,Section->CompilePC, Section->CompilePC,Section->RegWorking,CExitInfo::TLBReadMiss,FALSE,JeLabel32); } void CompileWriteTLBMiss (CBlockSection * Section, int AddressReg, int LookUpReg ) { MoveX86regToVariable(AddressReg,&TLBStoreAddress,"TLBStoreAddress"); TestX86RegToX86Reg(LookUpReg,LookUpReg); g_N64System->GetRecompiler()->CompileExit (Section,Section->CompilePC, Section->CompilePC,Section->RegWorking,CExitInfo::TLBReadMiss,FALSE,JeLabel32); } /************************** Branch functions ************************/ void Compile_R4300i_Branch (CBlockSection * Section, void (*CompareFunc)(CBlockSection * Section), BRANCH_TYPE BranchType, BOOL Link) { static int EffectDelaySlot, DoneJumpDelay, DoneContinueDelay; static char ContLabel[100], JumpLabel[100]; static CRegInfo RegBeforeDelay; if ( NextInstruction == NORMAL ) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if ((Section->CompilePC & 0xFFC) != 0xFFC) { switch (BranchType) { case BranchTypeRs: EffectDelaySlot = DelaySlotEffectsCompare(Section->CompilePC,Opcode.rs,0); break; case BranchTypeRsRt: EffectDelaySlot = DelaySlotEffectsCompare(Section->CompilePC,Opcode.rs,Opcode.rt); break; case BranchTypeCop1: { OPCODE Command; if (!r4300i_LW_VAddr(Section->CompilePC + 4, &Command.Hex)) { DisplayError(GS(MSG_FAIL_LOAD_WORD)); ExitThread(0); } EffectDelaySlot = FALSE; if (Command.op == R4300i_CP1) { if (Command.fmt == R4300i_COP1_S && (Command.funct & 0x30) == 0x30 ) { EffectDelaySlot = TRUE; } if (Command.fmt == R4300i_COP1_D && (Command.funct & 0x30) == 0x30 ) { EffectDelaySlot = TRUE; } } } break; #ifndef EXTERNAL_RELEASE default: DisplayError("Unknown branch type"); #endif } } else { EffectDelaySlot = TRUE; } if (Section->ContinueSection != NULL) { sprintf(ContLabel,"Section_%d",((CBlockSection *)Section->ContinueSection)->SectionID); } else { strcpy(ContLabel,"Cont.LinkLocationinue"); } if (Section->JumpSection != NULL) { sprintf(JumpLabel,"Section_%d",((CBlockSection *)Section->JumpSection)->SectionID); } else { strcpy(JumpLabel,"Jump.LinkLocation"); } Section->Jump.TargetPC = Section->CompilePC + ((short)Opcode.offset << 2) + 4; Section->Jump.BranchLabel = JumpLabel; Section->Jump.LinkLocation = NULL; Section->Jump.LinkLocation2 = NULL; Section->Jump.DoneDelaySlot = FALSE; Section->Cont.TargetPC = Section->CompilePC + 8; Section->Cont.BranchLabel = ContLabel; Section->Cont.LinkLocation = NULL; Section->Cont.LinkLocation2 = NULL; Section->Cont.DoneDelaySlot = FALSE; if (Section->Jump.TargetPC < Section->Cont.TargetPC) { Section->Cont.FallThrough = FALSE; Section->Jump.FallThrough = TRUE; } else { Section->Cont.FallThrough = TRUE; Section->Jump.FallThrough = FALSE; } if (Link) { UnMap_GPR(Section, 31, FALSE); Section->MipsRegLo(31) = Section->CompilePC + 8; Section->MipsRegState(31) = CRegInfo::STATE_CONST_32; } if (EffectDelaySlot) { if (Section->ContinueSection != NULL) { sprintf(ContLabel,"Continue",((CBlockSection *)Section->ContinueSection)->SectionID); } else { strcpy(ContLabel,"ExitBlock"); } if (Section->JumpSection != NULL) { sprintf(JumpLabel,"Jump",((CBlockSection *)Section->JumpSection)->SectionID); } else { strcpy(JumpLabel,"ExitBlock"); } CompareFunc(Section); if ((Section->CompilePC & 0xFFC) == 0xFFC) { g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; return; } if (!Section->Jump.FallThrough && !Section->Cont.FallThrough) { if (Section->Jump.LinkLocation != NULL) { CPU_Message(""); CPU_Message(" %s:",Section->Jump.BranchLabel); SetJump32((DWORD *)Section->Jump.LinkLocation,(DWORD *)RecompPos); Section->Jump.LinkLocation = NULL; if (Section->Jump.LinkLocation2 != NULL) { SetJump32((DWORD *)Section->Jump.LinkLocation2,(DWORD *)RecompPos); Section->Jump.LinkLocation2 = NULL; } Section->Jump.FallThrough = TRUE; } else if (Section->Cont.LinkLocation != NULL){ CPU_Message(""); CPU_Message(" %s:",Section->Cont.BranchLabel); SetJump32((DWORD *)Section->Cont.LinkLocation,(DWORD *)RecompPos); Section->Cont.LinkLocation = NULL; if (Section->Cont.LinkLocation2 != NULL) { SetJump32((DWORD *)Section->Cont.LinkLocation2,(DWORD *)RecompPos); Section->Cont.LinkLocation2 = NULL; } Section->Cont.FallThrough = TRUE; } } Section->ResetX86Protection(); memcpy(&RegBeforeDelay,&Section->RegWorking,sizeof(CRegInfo)); } NextInstruction = DO_DELAY_SLOT; } else if (NextInstruction == DELAY_SLOT_DONE ) { if (EffectDelaySlot) { CJumpInfo * FallInfo = Section->Jump.FallThrough?&Section->Jump:&Section->Cont; CJumpInfo * JumpInfo = Section->Jump.FallThrough?&Section->Cont:&Section->Jump; if (FallInfo->FallThrough && !FallInfo->DoneDelaySlot) { Section->ResetX86Protection(); FallInfo->RegSet = Section->RegWorking; if (FallInfo == &Section->Jump) { if (Section->JumpSection != NULL) { sprintf(JumpLabel,"Section_%d",((CBlockSection *)Section->JumpSection)->SectionID); } else { strcpy(JumpLabel,"ExitBlock"); } if (FallInfo->TargetPC <= Section->CompilePC) { g_N64System->GetRecompiler()->UpdateCounters(&(FallInfo->RegSet.BlockCycleCount()),&(FallInfo->RegSet.BlockRandomModifier()),true); g_N64System->GetRecompiler()->CompileSystemCheck(FallInfo->TargetPC,FallInfo->RegSet); Section->ResetX86Protection(); } } else { if (Section->ContinueSection != NULL) { sprintf(ContLabel,"Section_%d",((CBlockSection *)Section->ContinueSection)->SectionID); } else { strcpy(ContLabel,"ExitBlock"); } } FallInfo->DoneDelaySlot = TRUE; if (!JumpInfo->DoneDelaySlot) { FallInfo->FallThrough = FALSE; JmpLabel32(FallInfo->BranchLabel,0); FallInfo->LinkLocation = RecompPos - 4; if (JumpInfo->LinkLocation != NULL) { CPU_Message(" %s:",JumpInfo->BranchLabel); SetJump32((DWORD *)JumpInfo->LinkLocation,(DWORD *)RecompPos); JumpInfo->LinkLocation = NULL; if (JumpInfo->LinkLocation2 != NULL) { SetJump32((DWORD *)JumpInfo->LinkLocation2,(DWORD *)RecompPos); JumpInfo->LinkLocation2 = NULL; } JumpInfo->FallThrough = TRUE; NextInstruction = DO_DELAY_SLOT; memcpy(&Section->RegWorking,&RegBeforeDelay,sizeof(CRegInfo)); return; } } } } else { CompareFunc(Section); Section->ResetX86Protection(); memcpy(&Section->Cont.RegSet,&Section->RegWorking,sizeof(CRegInfo)); memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); } g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { #ifndef EXTERNAL_RELEASE DisplayError("WTF\n\nBranch\nNextInstruction = %X", NextInstruction); #endif } } void Compile_R4300i_BranchLikely (CBlockSection * Section, void (*CompareFunc)(CBlockSection * Section), BOOL Link) { static char ContLabel[100], JumpLabel[100]; if ( NextInstruction == NORMAL ) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->ContinueSection != NULL) { sprintf(ContLabel,"Section_%d",((CBlockSection *)Section->ContinueSection)->SectionID); } else { strcpy(ContLabel,"ExitBlock"); } if (Section->JumpSection != NULL) { sprintf(JumpLabel,"Section_%d",((CBlockSection *)Section->JumpSection)->SectionID); } else { strcpy(JumpLabel,"ExitBlock"); } Section->Jump.TargetPC = Section->CompilePC + ((short)Opcode.offset << 2) + 4; Section->Jump.BranchLabel = JumpLabel; Section->Jump.FallThrough = TRUE; Section->Jump.LinkLocation = NULL; Section->Jump.LinkLocation2 = NULL; Section->Cont.TargetPC = Section->CompilePC + 8; Section->Cont.BranchLabel = ContLabel; Section->Cont.FallThrough = FALSE; Section->Cont.LinkLocation = NULL; Section->Cont.LinkLocation2 = NULL; if (Link) { UnMap_GPR(Section, 31, FALSE); Section->MipsRegLo(31) = Section->CompilePC + 8; Section->MipsRegState(31) = CRegInfo::STATE_CONST_32; } CompareFunc(Section); Section->ResetX86Protection(); memcpy(&Section->Cont.RegSet,&Section->RegWorking,sizeof(CRegInfo)); if (UseLinking && Section->Jump.TargetPC == Section->Cont.TargetPC) { if (Section->Cont.FallThrough) { BreakPoint(__FILE__,__LINE__); } if (!Section->Jump.FallThrough) { BreakPoint(__FILE__,__LINE__); } Section->JumpSection->Cont.TargetPC = Section->Jump.TargetPC; Section->JumpSection->DelaySlotSection = true; Section->Jump.TargetPC = Section->CompilePC + 4; Section->Jump.RegSet = Section->RegWorking; g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { if (Section->Cont.FallThrough) { if (Section->Jump.LinkLocation != NULL) { #ifndef EXTERNAL_RELEASE DisplayError("WTF .. problem with Compile_R4300i_BranchLikely"); #endif } g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { if ((Section->CompilePC & 0xFFC) == 0xFFC) { Section->Jump.FallThrough = FALSE; if (Section->Jump.LinkLocation != NULL) { SetJump32(Section->Jump.LinkLocation,RecompPos); Section->Jump.LinkLocation = NULL; if (Section->Jump.LinkLocation2 != NULL) { SetJump32(Section->Jump.LinkLocation2,RecompPos); Section->Jump.LinkLocation2 = NULL; } } JmpLabel32("DoDelaySlot",0); Section->Jump.LinkLocation = RecompPos - 4; CPU_Message(" "); CPU_Message(" %s:",Section->Cont.BranchLabel); if (Section->Cont.LinkLocation != NULL) { SetJump32(Section->Cont.LinkLocation,RecompPos); Section->Cont.LinkLocation = NULL; if (Section->Cont.LinkLocation2 != NULL) { SetJump32(Section->Cont.LinkLocation2,RecompPos); Section->Cont.LinkLocation2 = NULL; } } g_N64System->GetRecompiler()->CompileExit (Section,Section->CompilePC, Section->CompilePC + 8,Section->RegWorking,CExitInfo::Normal,TRUE,NULL); CPU_Message(" "); CPU_Message(" DoDelaySlot"); g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { NextInstruction = DO_DELAY_SLOT; } } } } else if (NextInstruction == DELAY_SLOT_DONE ) { Section->ResetX86Protection(); memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { #ifndef EXTERNAL_RELEASE DisplayError("WTF\n\nBranchLikely\nNextInstruction = %X", NextInstruction); #endif } } void BNE_Compare (CBlockSection * Section) { BYTE *Jump; if (Section->IsKnown(Opcode.rs) && Section->IsKnown(Opcode.rt)) { if (Section->IsConst(Opcode.rs) && Section->IsConst(Opcode.rt)) { if (Section->Is64Bit(Opcode.rs) || Section->Is64Bit(Opcode.rt)) { Compile_R4300i_UnknownOpcode(Section); } else if (Section->MipsRegLo(Opcode.rs) != Section->MipsRegLo(Opcode.rt)) { Section->Jump.FallThrough = TRUE; Section->Cont.FallThrough = FALSE; } else { Section->Jump.FallThrough = FALSE; Section->Cont.FallThrough = TRUE; } } else if (Section->IsMapped(Opcode.rs) && Section->IsMapped(Opcode.rt)) { if (Section->Is64Bit(Opcode.rs) || Section->Is64Bit(Opcode.rt)) { ProtectGPR(Section,Opcode.rs); ProtectGPR(Section,Opcode.rt); CompX86RegToX86Reg( Section->Is32Bit(Opcode.rs)?Map_TempReg(Section,x86_Any,Opcode.rs,TRUE):Section->MipsRegHi(Opcode.rs), Section->Is32Bit(Opcode.rt)?Map_TempReg(Section,x86_Any,Opcode.rt,TRUE):Section->MipsRegHi(Opcode.rt) ); if (Section->Jump.FallThrough) { JneLabel8("continue",0); Jump = RecompPos - 1; } else { JneLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } CompX86RegToX86Reg(Section->MipsRegLo(Opcode.rs),Section->MipsRegLo(Opcode.rt)); if (Section->Cont.FallThrough) { JneLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation2 = RecompPos - 4; } else if (Section->Jump.FallThrough) { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; CPU_Message(" "); CPU_Message(" continue:"); SetJump8(Jump,RecompPos); } else { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation2 = RecompPos - 4; } } else { CompX86RegToX86Reg(Section->MipsRegLo(Opcode.rs),Section->MipsRegLo(Opcode.rt)); if (Section->Cont.FallThrough) { JneLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation = RecompPos - 4; } else if (Section->Jump.FallThrough) { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } } else { DWORD ConstReg = Section->IsConst(Opcode.rt)?Opcode.rt:Opcode.rs; DWORD MappedReg = Section->IsConst(Opcode.rt)?Opcode.rs:Opcode.rt; if (Section->Is64Bit(ConstReg) || Section->Is64Bit(MappedReg)) { if (Section->Is32Bit(ConstReg) || Section->Is32Bit(MappedReg)) { ProtectGPR(Section,MappedReg); if (Section->Is32Bit(MappedReg)) { CompConstToX86reg(Map_TempReg(Section,x86_Any,MappedReg,TRUE),Section->MipsRegHi(ConstReg)); } else { CompConstToX86reg(Section->MipsRegHi(MappedReg),(int)Section->MipsRegLo(ConstReg) >> 31); } } else { CompConstToX86reg(Section->MipsRegHi(MappedReg),Section->MipsRegHi(ConstReg)); } if (Section->Jump.FallThrough) { JneLabel8("continue",0); Jump = RecompPos - 1; } else { JneLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } if (Section->MipsRegLo(ConstReg) == 0) { OrX86RegToX86Reg(Section->MipsRegLo(MappedReg),Section->MipsRegLo(MappedReg)); } else { CompConstToX86reg(Section->MipsRegLo(MappedReg),Section->MipsRegLo(ConstReg)); } if (Section->Cont.FallThrough) { JneLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation2 = RecompPos - 4; } else if (Section->Jump.FallThrough) { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; CPU_Message(" "); CPU_Message(" continue:"); SetJump8(Jump,RecompPos); } else { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation2 = RecompPos - 4; } } else { if (Section->MipsRegLo(ConstReg) == 0) { OrX86RegToX86Reg(Section->MipsRegLo(MappedReg),Section->MipsRegLo(MappedReg)); } else { CompConstToX86reg(Section->MipsRegLo(MappedReg),Section->MipsRegLo(ConstReg)); } if (Section->Cont.FallThrough) { JneLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation = RecompPos - 4; } else if (Section->Jump.FallThrough) { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } } } else if (Section->IsKnown(Opcode.rs) || Section->IsKnown(Opcode.rt)) { DWORD KnownReg = Section->IsKnown(Opcode.rt)?Opcode.rt:Opcode.rs; DWORD UnknownReg = Section->IsKnown(Opcode.rt)?Opcode.rs:Opcode.rt; if (Section->IsConst(KnownReg)) { if (Section->Is64Bit(KnownReg)) { CompConstToVariable(Section->MipsRegHi(KnownReg),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } else if (Section->IsSigned(KnownReg)) { CompConstToVariable(((int)Section->MipsRegLo(KnownReg) >> 31),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } else { CompConstToVariable(0,&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } } else { if (Section->Is64Bit(KnownReg)) { CompX86regToVariable(Section->MipsRegHi(KnownReg),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } else if (Section->IsSigned(KnownReg)) { ProtectGPR(Section,KnownReg); CompX86regToVariable(Map_TempReg(Section,x86_Any,KnownReg,TRUE),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } else { CompConstToVariable(0,&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } } if (Section->Jump.FallThrough) { JneLabel8("continue",0); Jump = RecompPos - 1; } else { JneLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } if (Section->IsConst(KnownReg)) { CompConstToVariable(Section->MipsRegLo(KnownReg),&GPR[UnknownReg].W[0],GPR_NameLo[UnknownReg]); } else { CompX86regToVariable(Section->MipsRegLo(KnownReg),&GPR[UnknownReg].W[0],GPR_NameLo[UnknownReg]); } if (Section->Cont.FallThrough) { JneLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation2 = RecompPos - 4; } else if (Section->Jump.FallThrough) { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; CPU_Message(" "); CPU_Message(" continue:"); SetJump8(Jump,RecompPos); } else { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation2 = RecompPos - 4; } } else { int x86Reg; x86Reg = Map_TempReg(Section,x86_Any,Opcode.rt,TRUE); CompX86regToVariable(x86Reg,&GPR[Opcode.rs].W[1],GPR_NameHi[Opcode.rs]); if (Section->Jump.FallThrough) { JneLabel8("continue",0); Jump = RecompPos - 1; } else { JneLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } x86Reg = Map_TempReg(Section,x86Reg,Opcode.rt,FALSE); CompX86regToVariable(x86Reg,&GPR[Opcode.rs].W[0],GPR_NameLo[Opcode.rs]); if (Section->Cont.FallThrough) { JneLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation2 = RecompPos - 4; } else if (Section->Jump.FallThrough) { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; CPU_Message(" "); CPU_Message(" continue:"); SetJump8(Jump,RecompPos); } else { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation2 = RecompPos - 4; } } } void BEQ_Compare (CBlockSection * Section) { BYTE *Jump; if (Section->IsKnown(Opcode.rs) && Section->IsKnown(Opcode.rt)) { if (Section->IsConst(Opcode.rs) && Section->IsConst(Opcode.rt)) { if (Section->Is64Bit(Opcode.rs) || Section->Is64Bit(Opcode.rt)) { Compile_R4300i_UnknownOpcode(Section); } else if (Section->MipsRegLo(Opcode.rs) == Section->MipsRegLo(Opcode.rt)) { Section->Jump.FallThrough = TRUE; Section->Cont.FallThrough = FALSE; } else { Section->Jump.FallThrough = FALSE; Section->Cont.FallThrough = TRUE; } } else if (Section->IsMapped(Opcode.rs) && Section->IsMapped(Opcode.rt)) { if (Section->Is64Bit(Opcode.rs) || Section->Is64Bit(Opcode.rt)) { ProtectGPR(Section,Opcode.rs); ProtectGPR(Section,Opcode.rt); CompX86RegToX86Reg( Section->Is32Bit(Opcode.rs)?Map_TempReg(Section,x86_Any,Opcode.rs,TRUE):Section->MipsRegHi(Opcode.rs), Section->Is32Bit(Opcode.rt)?Map_TempReg(Section,x86_Any,Opcode.rt,TRUE):Section->MipsRegHi(Opcode.rt) ); if (Section->Cont.FallThrough) { JneLabel8("continue",0); Jump = RecompPos - 1; } else { JneLabel32(Section->Cont.BranchLabel,0); Section->Cont.LinkLocation = RecompPos - 4; } CompX86RegToX86Reg(Section->MipsRegLo(Opcode.rs),Section->MipsRegLo(Opcode.rt)); if (Section->Cont.FallThrough) { JeLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation = RecompPos - 4; CPU_Message(" "); CPU_Message(" continue:"); SetJump8(Jump,RecompPos); } else if (Section->Jump.FallThrough) { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation2 = RecompPos - 4; } else { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation2 = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } else { CompX86RegToX86Reg(Section->MipsRegLo(Opcode.rs),Section->MipsRegLo(Opcode.rt)); if (Section->Cont.FallThrough) { JeLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation = RecompPos - 4; } else if (Section->Jump.FallThrough) { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } } else { DWORD ConstReg = Section->IsConst(Opcode.rt)?Opcode.rt:Opcode.rs; DWORD MappedReg = Section->IsConst(Opcode.rt)?Opcode.rs:Opcode.rt; if (Section->Is64Bit(ConstReg) || Section->Is64Bit(MappedReg)) { if (Section->Is32Bit(ConstReg) || Section->Is32Bit(MappedReg)) { if (Section->Is32Bit(MappedReg)) { ProtectGPR(Section,MappedReg); CompConstToX86reg(Map_TempReg(Section,x86_Any,MappedReg,TRUE),Section->MipsRegHi(ConstReg)); } else { CompConstToX86reg(Section->MipsRegHi(MappedReg),(int)Section->MipsRegLo(ConstReg) >> 31); } } else { CompConstToX86reg(Section->MipsRegHi(MappedReg),Section->MipsRegHi(ConstReg)); } if (Section->Cont.FallThrough) { JneLabel8("continue",0); Jump = RecompPos - 1; } else { JneLabel32(Section->Cont.BranchLabel,0); Section->Cont.LinkLocation = RecompPos - 4; } if (Section->MipsRegLo(ConstReg) == 0) { OrX86RegToX86Reg(Section->MipsRegLo(MappedReg),Section->MipsRegLo(MappedReg)); } else { CompConstToX86reg(Section->MipsRegLo(MappedReg),Section->MipsRegLo(ConstReg)); } if (Section->Cont.FallThrough) { JeLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation = RecompPos - 4; CPU_Message(" "); CPU_Message(" continue:"); SetJump8(Jump,RecompPos); } else if (Section->Jump.FallThrough) { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation2 = RecompPos - 4; } else { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation2 = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } else { if (Section->MipsRegLo(ConstReg) == 0) { OrX86RegToX86Reg(Section->MipsRegLo(MappedReg),Section->MipsRegLo(MappedReg)); } else { CompConstToX86reg(Section->MipsRegLo(MappedReg),Section->MipsRegLo(ConstReg)); } if (Section->Cont.FallThrough) { JeLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation = RecompPos - 4; } else if (Section->Jump.FallThrough) { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } } } else if (Section->IsKnown(Opcode.rs) || Section->IsKnown(Opcode.rt)) { DWORD KnownReg = Section->IsKnown(Opcode.rt)?Opcode.rt:Opcode.rs; DWORD UnknownReg = Section->IsKnown(Opcode.rt)?Opcode.rs:Opcode.rt; if (Section->IsConst(KnownReg)) { if (Section->Is64Bit(KnownReg)) { CompConstToVariable(Section->MipsRegHi(KnownReg),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } else if (Section->IsSigned(KnownReg)) { CompConstToVariable((int)Section->MipsRegLo(KnownReg) >> 31,&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } else { CompConstToVariable(0,&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } } else { ProtectGPR(Section,KnownReg); if (Section->Is64Bit(KnownReg)) { CompX86regToVariable(Section->MipsRegHi(KnownReg),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } else if (Section->IsSigned(KnownReg)) { CompX86regToVariable(Map_TempReg(Section,x86_Any,KnownReg,TRUE),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } else { CompConstToVariable(0,&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } } if (Section->Cont.FallThrough) { JneLabel8("continue",0); Jump = RecompPos - 1; } else { JneLabel32(Section->Cont.BranchLabel,0); Section->Cont.LinkLocation = RecompPos - 4; } if (Section->IsConst(KnownReg)) { CompConstToVariable(Section->MipsRegLo(KnownReg),&GPR[UnknownReg].W[0],GPR_NameLo[UnknownReg]); } else { CompX86regToVariable(Section->MipsRegLo(KnownReg),&GPR[UnknownReg].W[0],GPR_NameLo[UnknownReg]); } if (Section->Cont.FallThrough) { JeLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation = RecompPos - 4; CPU_Message(" "); CPU_Message(" continue:"); SetJump8(Jump,RecompPos); } else if (Section->Jump.FallThrough) { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation2 = RecompPos - 4; } else { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation2 = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } else { int x86Reg = Map_TempReg(Section,x86_Any,Opcode.rs,TRUE); CompX86regToVariable(x86Reg,&GPR[Opcode.rt].W[1],GPR_NameHi[Opcode.rt]); if (Section->Cont.FallThrough) { JneLabel8("continue",0); Jump = RecompPos - 1; } else { JneLabel32(Section->Cont.BranchLabel,0); Section->Cont.LinkLocation = RecompPos - 4; } CompX86regToVariable(Map_TempReg(Section,x86Reg,Opcode.rs,FALSE),&GPR[Opcode.rt].W[0],GPR_NameLo[Opcode.rt]); if (Section->Cont.FallThrough) { JeLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation = RecompPos - 4; CPU_Message(" "); CPU_Message(" continue:"); SetJump8(Jump,RecompPos); } else if (Section->Jump.FallThrough) { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation2 = RecompPos - 4; } else { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation2 = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } } void BGTZ_Compare (CBlockSection * Section) { if (Section->IsConst(Opcode.rs)) { if (Section->Is64Bit(Opcode.rs)) { if (Section->MipsReg_S(Opcode.rs) > 0) { Section->Jump.FallThrough = TRUE; Section->Cont.FallThrough = FALSE; } else { Section->Jump.FallThrough = FALSE; Section->Cont.FallThrough = TRUE; } } else { if (Section->MipsRegLo_S(Opcode.rs) > 0) { Section->Jump.FallThrough = TRUE; Section->Cont.FallThrough = FALSE; } else { Section->Jump.FallThrough = FALSE; Section->Cont.FallThrough = TRUE; } } } else if (Section->IsMapped(Opcode.rs) && Section->Is32Bit(Opcode.rs)) { CompConstToX86reg(Section->MipsRegLo(Opcode.rs),0); if (Section->Jump.FallThrough) { JleLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else if (Section->Cont.FallThrough) { JgLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } else { JleLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } else { BYTE *Jump; if (Section->IsMapped(Opcode.rs)) { CompConstToX86reg(Section->MipsRegHi(Opcode.rs),0); } else { CompConstToVariable(0,&GPR[Opcode.rs].W[1],GPR_NameHi[Opcode.rs]); } if (Section->Jump.FallThrough) { JlLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JgLabel8("continue",0); Jump = RecompPos - 1; } else if (Section->Cont.FallThrough) { JlLabel8("continue",0); Jump = RecompPos - 1; JgLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } else { JlLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JgLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } if (Section->IsMapped(Opcode.rs)) { CompConstToX86reg(Section->MipsRegLo(Opcode.rs),0); } else { CompConstToVariable(0,&GPR[Opcode.rs].W[0],GPR_NameLo[Opcode.rs]); } if (Section->Jump.FallThrough) { JeLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation2 = RecompPos - 4; CPU_Message(" continue:"); *((BYTE *)(Jump))=(BYTE)(RecompPos - Jump - 1); } else if (Section->Cont.FallThrough) { JneLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; CPU_Message(" continue:"); *((BYTE *)(Jump))=(BYTE)(RecompPos - Jump - 1); } else { JneLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; JmpLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation2 = RecompPos - 4; } } } void BLEZ_Compare (CBlockSection * Section) { if (Section->IsConst(Opcode.rs)) { if (Section->Is64Bit(Opcode.rs)) { if (Section->MipsReg_S(Opcode.rs) <= 0) { Section->Jump.FallThrough = TRUE; Section->Cont.FallThrough = FALSE; } else { Section->Jump.FallThrough = FALSE; Section->Cont.FallThrough = TRUE; } } else if (Section->IsSigned(Opcode.rs)) { if (Section->MipsRegLo_S(Opcode.rs) <= 0) { Section->Jump.FallThrough = TRUE; Section->Cont.FallThrough = FALSE; } else { Section->Jump.FallThrough = FALSE; Section->Cont.FallThrough = TRUE; } } else { if (Section->MipsRegLo(Opcode.rs) == 0) { Section->Jump.FallThrough = TRUE; Section->Cont.FallThrough = FALSE; } else { Section->Jump.FallThrough = FALSE; Section->Cont.FallThrough = TRUE; } } } else { if (Section->IsMapped(Opcode.rs) && Section->Is32Bit(Opcode.rs)) { CompConstToX86reg(Section->MipsRegLo(Opcode.rs),0); if (Section->Jump.FallThrough) { JgLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else if (Section->Cont.FallThrough) { JleLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } else { JgLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } else { BYTE *Jump; if (Section->IsMapped(Opcode.rs)) { CompConstToX86reg(Section->MipsRegHi(Opcode.rs),0); } else { CompConstToVariable(0,&GPR[Opcode.rs].W[1],GPR_NameHi[Opcode.rs]); } if (Section->Jump.FallThrough) { JgLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JlLabel8("Continue",0); Jump = RecompPos - 1; } else if (Section->Cont.FallThrough) { JgLabel8("Continue",0); Jump = RecompPos - 1; JlLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } else { JgLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JlLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } if (Section->IsMapped(Opcode.rs)) { CompConstToX86reg(Section->MipsRegLo(Opcode.rs),0); } else { CompConstToVariable(0,&GPR[Opcode.rs].W[0],GPR_NameLo[Opcode.rs]); } if (Section->Jump.FallThrough) { JneLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation2 = RecompPos - 4; CPU_Message(" continue:"); *((BYTE *)(Jump))=(BYTE)(RecompPos - Jump - 1); } else if (Section->Cont.FallThrough) { JeLabel32 (Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation2 = RecompPos - 4; CPU_Message(" continue:"); *((BYTE *)(Jump))=(BYTE)(RecompPos - Jump - 1); } else { JneLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation2 = RecompPos - 4; JmpLabel32("BranchToJump",0); Section->Jump.LinkLocation2 = RecompPos - 4; } } } } void BLTZ_Compare (CBlockSection * Section) { if (Section->IsConst(Opcode.rs)) { if (Section->Is64Bit(Opcode.rs)) { if (Section->MipsReg_S(Opcode.rs) < 0) { Section->Jump.FallThrough = TRUE; Section->Cont.FallThrough = FALSE; } else { Section->Jump.FallThrough = FALSE; Section->Cont.FallThrough = TRUE; } } else if (Section->IsSigned(Opcode.rs)) { if (Section->MipsRegLo_S(Opcode.rs) < 0) { Section->Jump.FallThrough = TRUE; Section->Cont.FallThrough = FALSE; } else { Section->Jump.FallThrough = FALSE; Section->Cont.FallThrough = TRUE; } } else { Section->Jump.FallThrough = FALSE; Section->Cont.FallThrough = TRUE; } } else if (Section->IsMapped(Opcode.rs)) { if (Section->Is64Bit(Opcode.rs)) { CompConstToX86reg(Section->MipsRegHi(Opcode.rs),0); if (Section->Jump.FallThrough) { JgeLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else if (Section->Cont.FallThrough) { JlLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } else { JgeLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } else if (Section->IsSigned(Opcode.rs)) { CompConstToX86reg(Section->MipsRegLo(Opcode.rs),0); if (Section->Jump.FallThrough) { JgeLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else if (Section->Cont.FallThrough) { JlLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } else { JgeLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } else { Section->Jump.FallThrough = FALSE; Section->Cont.FallThrough = TRUE; } } else if (Section->IsUnknown(Opcode.rs)) { CompConstToVariable(0,&GPR[Opcode.rs].W[1],GPR_NameHi[Opcode.rs]); if (Section->Jump.FallThrough) { JgeLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else if (Section->Cont.FallThrough) { JlLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } else { JlLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; JmpLabel32 (Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } } } void BGEZ_Compare (CBlockSection * Section) { if (Section->IsConst(Opcode.rs)) { if (Section->Is64Bit(Opcode.rs)) { #ifndef EXTERNAL_RELEASE DisplayError("BGEZ 1"); #endif Compile_R4300i_UnknownOpcode(Section); } else if (Section->IsSigned(Opcode.rs)) { if (Section->MipsRegLo_S(Opcode.rs) >= 0) { Section->Jump.FallThrough = TRUE; Section->Cont.FallThrough = FALSE; } else { Section->Jump.FallThrough = FALSE; Section->Cont.FallThrough = TRUE; } } else { Section->Jump.FallThrough = TRUE; Section->Cont.FallThrough = FALSE; } } else if (Section->IsMapped(Opcode.rs)) { if (Section->Is64Bit(Opcode.rs)) { CompConstToX86reg(Section->MipsRegHi(Opcode.rs),0); if (Section->Cont.FallThrough) { JgeLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation = RecompPos - 4; } else if (Section->Jump.FallThrough) { JlLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else { JlLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } else if (Section->IsSigned(Opcode.rs)) { CompConstToX86reg(Section->MipsRegLo(Opcode.rs),0); if (Section->Cont.FallThrough) { JgeLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation = RecompPos - 4; } else if (Section->Jump.FallThrough) { JlLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else { JlLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } else { Section->Jump.FallThrough = TRUE; Section->Cont.FallThrough = FALSE; } } else { CompConstToVariable(0,&GPR[Opcode.rs].W[1],GPR_NameHi[Opcode.rs]); if (Section->Cont.FallThrough) { JgeLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation = RecompPos - 4; } else if (Section->Jump.FallThrough) { JlLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else { JlLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } } void COP1_BCF_Compare (CBlockSection * Section) { TestVariable(FPCSR_C,&FPCR[31],"FPCR[31]"); if (Section->Cont.FallThrough) { JeLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation = RecompPos - 4; } else if (Section->Jump.FallThrough) { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else { JneLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } void COP1_BCT_Compare (CBlockSection * Section) { TestVariable(FPCSR_C,&FPCR[31],"FPCR[31]"); if (Section->Cont.FallThrough) { JneLabel32 ( Section->Jump.BranchLabel, 0 ); Section->Jump.LinkLocation = RecompPos - 4; } else if (Section->Jump.FallThrough) { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; } else { JeLabel32 ( Section->Cont.BranchLabel, 0 ); Section->Cont.LinkLocation = RecompPos - 4; JmpLabel32(Section->Jump.BranchLabel,0); Section->Jump.LinkLocation = RecompPos - 4; } } /************************* OpCode functions *************************/ void Compile_R4300i_J (CBlockSection * Section) { static char JumpLabel[100]; if ( NextInstruction == NORMAL ) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->JumpSection != NULL) { sprintf(JumpLabel,"Section_%d",((CBlockSection *)Section->JumpSection)->SectionID); } else { strcpy(JumpLabel,"ExitBlock"); } Section->Jump.TargetPC = (Section->CompilePC & 0xF0000000) + (Opcode.target << 2);; Section->Jump.BranchLabel = JumpLabel; Section->Jump.FallThrough = TRUE; Section->Jump.LinkLocation = NULL; Section->Jump.LinkLocation2 = NULL; NextInstruction = DO_DELAY_SLOT; if ((Section->CompilePC & 0xFFC) == 0xFFC) { memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } } else if (NextInstruction == DELAY_SLOT_DONE ) { memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { #ifndef EXTERNAL_RELEASE DisplayError("WTF\n\nJal\nNextInstruction = %X", NextInstruction); #endif } } void Compile_R4300i_JAL (CBlockSection * Section) { static char JumpLabel[100]; if ( NextInstruction == NORMAL ) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); UnMap_GPR(Section, 31, FALSE); Section->MipsRegLo(31) = Section->CompilePC + 8; Section->MipsRegState(31) = CRegInfo::STATE_CONST_32; if ((Section->CompilePC & 0xFFC) == 0xFFC) { MoveConstToVariable((Section->CompilePC & 0xF0000000) + (Opcode.target << 2),&JumpToLocation,"JumpToLocation"); MoveConstToVariable(Section->CompilePC + 4,&PROGRAM_COUNTER,"PROGRAM_COUNTER"); g_N64System->GetRecompiler()->UpdateCounters(&Section->BlockCycleCount(),&Section->BlockRandomModifier(),FALSE); WriteBackRegisters(Section); if (CPU_Type == CPU_SyncCores) { Call_Direct(SyncToPC, "SyncToPC"); } MoveConstToVariable(DELAY_SLOT,&NextInstruction,"NextInstruction"); Ret(); NextInstruction = END_BLOCK; return; } NextInstruction = DO_DELAY_SLOT; } else if (NextInstruction == DELAY_SLOT_DONE ) { DWORD TargetPC = (Section->CompilePC & 0xF0000000) + (Opcode.target << 2); g_N64System->GetRecompiler()->CompileExit (Section,Section->CompilePC,TargetPC,Section->RegWorking,CExitInfo::Normal,TRUE,NULL); NextInstruction = END_BLOCK; } else { #ifndef EXTERNAL_RELEASE DisplayError("WTF\n\nBranch\nNextInstruction = %X", NextInstruction); #endif } return; if ( NextInstruction == NORMAL ) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); UnMap_GPR(Section, 31, FALSE); Section->MipsRegLo(31) = Section->CompilePC + 8; Section->MipsRegState(31) = CRegInfo::STATE_CONST_32; NextInstruction = DO_DELAY_SLOT; if (Section->JumpSection != NULL) { sprintf(JumpLabel,"Section_%d",((CBlockSection *)Section->JumpSection)->SectionID); } else { strcpy(JumpLabel,"ExitBlock"); } Section->Jump.TargetPC = (Section->CompilePC & 0xF0000000) + (Opcode.target << 2); Section->Jump.BranchLabel = JumpLabel; Section->Jump.FallThrough = TRUE; Section->Jump.LinkLocation = NULL; Section->Jump.LinkLocation2 = NULL; if ((Section->CompilePC & 0xFFC) == 0xFFC) { memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } } else if (NextInstruction == DELAY_SLOT_DONE ) { memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; } else { #ifndef EXTERNAL_RELEASE DisplayError("WTF\n\nJal\nNextInstruction = %X", NextInstruction); #endif } } void Compile_R4300i_ADDI (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) { return; } if (SPHack && Opcode.rs == 29 && Opcode.rt == 29) { AddConstToX86Reg(Map_MemoryStack(Section, x86_Any, true),(short)Opcode.immediate); } if (Section->IsConst(Opcode.rs)) { if (Section->IsMapped(Opcode.rt)) { UnMap_GPR(Section,Opcode.rt, FALSE); } Section->MipsRegLo(Opcode.rt) = Section->MipsRegLo(Opcode.rs) + (short)Opcode.immediate; Section->MipsRegState(Opcode.rt) = CRegInfo::STATE_CONST_32; } else { Map_GPR_32bit(Section,Opcode.rt,TRUE,Opcode.rs); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(Section->MipsRegLo(Opcode.rt)); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(Section->MipsRegLo(Opcode.rt)); } else { AddConstToX86Reg(Section->MipsRegLo(Opcode.rt),(short)Opcode.immediate); } } if (SPHack && Opcode.rt == 29 && Opcode.rs != 29) { Section->ResetX86Protection(); ResetMemoryStack(Section); } } void Compile_R4300i_ADDIU (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) { return; } if (SPHack) { if (Opcode.rs == 29 && Opcode.rt == 29) { AddConstToX86Reg(Map_MemoryStack(Section, x86_Any, TRUE),(short)Opcode.immediate); } } if (Section->IsConst(Opcode.rs)) { if (Section->IsMapped(Opcode.rt)) { UnMap_GPR(Section,Opcode.rt, FALSE); } Section->MipsRegLo(Opcode.rt) = Section->MipsRegLo(Opcode.rs) + (short)Opcode.immediate; Section->MipsRegState(Opcode.rt) = CRegInfo::STATE_CONST_32; } else { Map_GPR_32bit(Section,Opcode.rt,TRUE,Opcode.rs); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(Section->MipsRegLo(Opcode.rt)); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(Section->MipsRegLo(Opcode.rt)); } else { AddConstToX86Reg(Section->MipsRegLo(Opcode.rt),(short)Opcode.immediate); } } if (SPHack && Opcode.rt == 29 && Opcode.rs != 29) { Section->ResetX86Protection(); ResetMemoryStack(Section); } } void Compile_R4300i_SLTIU (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) { return; } if (Section->IsConst(Opcode.rs)) { DWORD Result; if (Section->Is64Bit(Opcode.rs)) { _int64 Immediate = (_int64)((short)Opcode.immediate); Result = Section->MipsReg(Opcode.rs) < ((unsigned)(Immediate))?1:0; } else if (Section->Is32Bit(Opcode.rs)) { Result = Section->MipsRegLo(Opcode.rs) < ((unsigned)((short)Opcode.immediate))?1:0; } UnMap_GPR(Section,Opcode.rt, FALSE); Section->MipsRegState(Opcode.rt) = CRegInfo::STATE_CONST_32; Section->MipsRegLo(Opcode.rt) = Result; } else if (Section->IsMapped(Opcode.rs)) { if (Section->Is64Bit(Opcode.rs)) { BYTE * Jump[2]; CompConstToX86reg(Section->MipsRegHi(Opcode.rs),((short)Opcode.immediate >> 31)); JeLabel8("Low Compare",0); Jump[0] = RecompPos - 1; SetbVariable(&BranchCompare,"BranchCompare"); JmpLabel8("Continue",0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" Low Compare:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); CompConstToX86reg(Section->MipsRegLo(Opcode.rs),(short)Opcode.immediate); SetbVariable(&BranchCompare,"BranchCompare"); CPU_Message(""); CPU_Message(" Continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); Map_GPR_32bit(Section,Opcode.rt,FALSE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rt)); } else { CompConstToX86reg(Section->MipsRegLo(Opcode.rs),(short)Opcode.immediate); SetbVariable(&BranchCompare,"BranchCompare"); Map_GPR_32bit(Section,Opcode.rt,FALSE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rt)); } } else { BYTE * Jump; CompConstToVariable(((short)Opcode.immediate >> 31),&GPR[Opcode.rs].W[1],GPR_NameHi[Opcode.rs]); JneLabel8("CompareSet",0); Jump = RecompPos - 1; CompConstToVariable((short)Opcode.immediate,&GPR[Opcode.rs].W[0],GPR_NameLo[Opcode.rs]); CPU_Message(""); CPU_Message(" CompareSet:"); *((BYTE *)(Jump))=(BYTE)(RecompPos - Jump - 1); SetbVariable(&BranchCompare,"BranchCompare"); Map_GPR_32bit(Section,Opcode.rt,FALSE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rt)); /*SetbVariable(&BranchCompare,"BranchCompare"); JmpLabel8("Continue",0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" Low Compare:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); CompConstToVariable((short)Opcode.immediate,&GPR[Opcode.rs].W[0],GPR_NameLo[Opcode.rs]); SetbVariable(&BranchCompare,"BranchCompare"); CPU_Message(""); CPU_Message(" Continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); Map_GPR_32bit(Section,Opcode.rt,FALSE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rt));*/ } } void Compile_R4300i_SLTI (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) { return; } if (Section->IsConst(Opcode.rs)) { DWORD Result; if (Section->Is64Bit(Opcode.rs)) { _int64 Immediate = (_int64)((short)Opcode.immediate); Result = (_int64)Section->MipsReg(Opcode.rs) < Immediate?1:0; } else if (Section->Is32Bit(Opcode.rs)) { Result = Section->MipsRegLo_S(Opcode.rs) < (short)Opcode.immediate?1:0; } UnMap_GPR(Section,Opcode.rt, FALSE); Section->MipsRegState(Opcode.rt) = CRegInfo::STATE_CONST_32; Section->MipsRegLo(Opcode.rt) = Result; } else if (Section->IsMapped(Opcode.rs)) { if (Section->Is64Bit(Opcode.rs)) { BYTE * Jump[2]; CompConstToX86reg(Section->MipsRegHi(Opcode.rs),((short)Opcode.immediate >> 31)); JeLabel8("Low Compare",0); Jump[0] = RecompPos - 1; SetlVariable(&BranchCompare,"BranchCompare"); JmpLabel8("Continue",0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" Low Compare:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); CompConstToX86reg(Section->MipsRegLo(Opcode.rs),(short)Opcode.immediate); SetbVariable(&BranchCompare,"BranchCompare"); CPU_Message(""); CPU_Message(" Continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); Map_GPR_32bit(Section,Opcode.rt,FALSE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rt)); } else { /* CompConstToX86reg(Section->MipsRegLo(Opcode.rs),(short)Opcode.immediate); SetlVariable(&BranchCompare,"BranchCompare"); Map_GPR_32bit(Section,Opcode.rt,FALSE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rt)); */ ProtectGPR(Section, Opcode.rs); Map_GPR_32bit(Section,Opcode.rt,FALSE, -1); CompConstToX86reg(Section->MipsRegLo(Opcode.rs),(short)Opcode.immediate); if (Section->MipsRegLo(Opcode.rt) > x86_EDX) { SetlVariable(&BranchCompare,"BranchCompare"); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rt)); } else { Setl(Section->MipsRegLo(Opcode.rt)); AndConstToX86Reg(Section->MipsRegLo(Opcode.rt), 1); } } } else { BYTE * Jump[2]; CompConstToVariable(((short)Opcode.immediate >> 31),&GPR[Opcode.rs].W[1],GPR_NameHi[Opcode.rs]); JeLabel8("Low Compare",0); Jump[0] = RecompPos - 1; SetlVariable(&BranchCompare,"BranchCompare"); JmpLabel8("Continue",0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" Low Compare:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); CompConstToVariable((short)Opcode.immediate,&GPR[Opcode.rs].W[0],GPR_NameLo[Opcode.rs]); SetbVariable(&BranchCompare,"BranchCompare"); CPU_Message(""); CPU_Message(" Continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); Map_GPR_32bit(Section,Opcode.rt,FALSE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rt)); } } void Compile_R4300i_ANDI (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) { return;} if (Section->IsConst(Opcode.rs)) { if (Section->IsMapped(Opcode.rt)) { UnMap_GPR(Section,Opcode.rt, FALSE); } Section->MipsRegState(Opcode.rt) = CRegInfo::STATE_CONST_32; Section->MipsRegLo(Opcode.rt) = Section->MipsRegLo(Opcode.rs) & Opcode.immediate; } else if (Opcode.immediate != 0) { Map_GPR_32bit(Section,Opcode.rt,FALSE,Opcode.rs); AndConstToX86Reg(Section->MipsRegLo(Opcode.rt),Opcode.immediate); } else { Map_GPR_32bit(Section,Opcode.rt,FALSE,0); } } void Compile_R4300i_ORI (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) { return;} if (Section->IsConst(Opcode.rs)) { if (Section->IsMapped(Opcode.rt)) { UnMap_GPR(Section,Opcode.rt, FALSE); } Section->MipsRegState(Opcode.rt) = Section->MipsRegState(Opcode.rs); Section->MipsRegHi(Opcode.rt) = Section->MipsRegHi(Opcode.rs); Section->MipsRegLo(Opcode.rt) = Section->MipsRegLo(Opcode.rs) | Opcode.immediate; } else if (Section->IsMapped(Opcode.rs)) { if (Section->Is64Bit(Opcode.rs)) { Map_GPR_64bit(Section,Opcode.rt,Opcode.rs); } else { Map_GPR_32bit(Section,Opcode.rt,Section->IsSigned(Opcode.rs),Opcode.rs); } OrConstToX86Reg(Opcode.immediate,Section->MipsRegLo(Opcode.rt)); } else { Map_GPR_64bit(Section,Opcode.rt,Opcode.rs); OrConstToX86Reg(Opcode.immediate,Section->MipsRegLo(Opcode.rt)); } } void Compile_R4300i_XORI (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) { return;} if (Section->IsConst(Opcode.rs)) { if (Opcode.rs != Opcode.rt) { UnMap_GPR(Section,Opcode.rt, FALSE); } Section->MipsRegState(Opcode.rt) = Section->MipsRegState(Opcode.rs); Section->MipsRegHi(Opcode.rt) = Section->MipsRegHi(Opcode.rs); Section->MipsRegLo(Opcode.rt) = Section->MipsRegLo(Opcode.rs) ^ Opcode.immediate; } else { if (Section->IsMapped(Opcode.rs) && Section->Is32Bit(Opcode.rs)) { Map_GPR_32bit(Section,Opcode.rt,Section->IsSigned(Opcode.rs),Opcode.rs); } else { Map_GPR_64bit(Section,Opcode.rt,Opcode.rs); } if (Opcode.immediate != 0) { XorConstToX86Reg(Section->MipsRegLo(Opcode.rt),Opcode.immediate); } } } void Compile_R4300i_LUI (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) { return;} if (SPHack && Opcode.rt == 29) { int x86reg = Map_MemoryStack(Section, x86_Any, false); DWORD Address; TranslateVaddr (((short)Opcode.offset << 16), &Address); if (x86reg < 0) { MoveConstToVariable((DWORD)(Address + N64MEM), g_MemoryStack, "MemoryStack"); } else { MoveConstToX86reg((DWORD)(Address + N64MEM), x86reg); } } UnMap_GPR(Section,Opcode.rt, FALSE); Section->MipsRegLo(Opcode.rt) = ((short)Opcode.offset << 16); Section->MipsRegState(Opcode.rt) = CRegInfo::STATE_CONST_32; } void Compile_R4300i_DADDIU (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rs != 0) { UnMap_GPR(Section,Opcode.rs,TRUE); } if (Opcode.rs != 0) { UnMap_GPR(Section,Opcode.rt,TRUE); } Pushad(); MoveConstToVariable(Opcode.Hex, &Opcode.Hex, "Opcode.Hex" ); Call_Direct(r4300i_DADDIU, "r4300i_DADDIU"); Popad(); } void Compile_R4300i_LDL (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.base != 0) { UnMap_GPR(Section,Opcode.base,TRUE); } if (Opcode.rt != 0) { UnMap_GPR(Section,Opcode.rt,TRUE); } Pushad(); MoveConstToVariable(Opcode.Hex, &Opcode.Hex, "Opcode.Hex" ); Call_Direct(r4300i_LDL, "r4300i_LDL"); Popad(); } void Compile_R4300i_LDR (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.base != 0) { UnMap_GPR(Section,Opcode.base,TRUE); } if (Opcode.rt != 0) { UnMap_GPR(Section,Opcode.rt,TRUE); } Pushad(); MoveConstToVariable(Opcode.Hex, &Opcode.Hex, "Opcode.Hex" ); Call_Direct(r4300i_LDR, "r4300i_LDR"); Popad(); } void Compile_R4300i_LB (CBlockSection * Section) { DWORD TempReg1, TempReg2; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) return; if (Section->IsConst(Opcode.base)) { DWORD Address = (Section->MipsRegLo(Opcode.base) + (short)Opcode.offset) ^ 3; Map_GPR_32bit(Section,Opcode.rt,TRUE,0); Compile_LB(Section->MipsRegLo(Opcode.rt),Address,TRUE); return; } if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",TempReg2,TempReg2,4); CompileReadTLBMiss(Section,TempReg1,TempReg2); XorConstToX86Reg(TempReg1,3); Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); MoveSxByteX86regPointerToX86reg(TempReg1, TempReg2,Section->MipsRegLo(Opcode.rt)); } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); XorConstToX86Reg(TempReg1,3); Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); MoveSxN64MemToX86regByte(Section->MipsRegLo(Opcode.rt), TempReg1); } } void Compile_R4300i_LH (CBlockSection * Section) { DWORD TempReg1, TempReg2; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) return; if (Section->IsConst(Opcode.base)) { DWORD Address = (Section->MipsRegLo(Opcode.base) + (short)Opcode.offset) ^ 2; Map_GPR_32bit(Section,Opcode.rt,TRUE,0); Compile_LH(Section->MipsRegLo(Opcode.rt),Address,TRUE); return; } if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",TempReg2,TempReg2,4); CompileReadTLBMiss(Section,TempReg1,TempReg2); XorConstToX86Reg(TempReg1,2); Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); MoveSxHalfX86regPointerToX86reg(TempReg1, TempReg2,Section->MipsRegLo(Opcode.rt)); } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); XorConstToX86Reg(TempReg1,2); Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); MoveSxN64MemToX86regHalf(Section->MipsRegLo(Opcode.rt), TempReg1); } } void Compile_R4300i_LWL (CBlockSection * Section) { DWORD TempReg1, TempReg2, Offset, shift; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) return; if (Section->IsConst(Opcode.base)) { DWORD Address, Value; Address = Section->MipsRegLo(Opcode.base) + (short)Opcode.offset; Offset = Address & 3; Map_GPR_32bit(Section,Opcode.rt,TRUE,Opcode.rt); Value = Map_TempReg(Section,x86_Any,-1,FALSE); Compile_LW(Section, Value,(Address & ~3)); AndConstToX86Reg(Section->MipsRegLo(Opcode.rt),LWL_MASK[Offset]); ShiftLeftSignImmed(Value,(BYTE)LWL_SHIFT[Offset]); AddX86RegToX86Reg(Section->MipsRegLo(Opcode.rt),Value); return; } shift = Map_TempReg(Section,x86_ECX,-1,FALSE); if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } UnProtectGPR(Section,Opcode.base); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",TempReg2,TempReg2,4); CompileReadTLBMiss(Section,TempReg1,TempReg2); } Offset = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, Offset); AndConstToX86Reg(Offset,3); AndConstToX86Reg(TempReg1,~3); Map_GPR_32bit(Section,Opcode.rt,TRUE,Opcode.rt); AndVariableDispToX86Reg(LWL_MASK,"LWL_MASK",Section->MipsRegLo(Opcode.rt),Offset,4); MoveVariableDispToX86Reg(LWL_SHIFT,"LWL_SHIFT",shift,Offset,4); if (UseTlb) { MoveX86regPointerToX86reg(TempReg1, TempReg2,TempReg1); } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); MoveN64MemToX86reg(TempReg1,TempReg1); } ShiftLeftSign(TempReg1); AddX86RegToX86Reg(Section->MipsRegLo(Opcode.rt),TempReg1); } void Compile_R4300i_LW (CBlockSection * Section) { DWORD TempReg1, TempReg2; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) return; if (Opcode.base == 29 && SPHack) { char String[100]; Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); TempReg1 = Map_MemoryStack(Section,x86_Any,true); sprintf(String,"%Xh",(short)Opcode.offset); MoveVariableDispToX86Reg((void *)((DWORD)(short)Opcode.offset),String,Section->MipsRegLo(Opcode.rt),TempReg1,1); } else { if (Section->IsConst(Opcode.base)) { DWORD Address = Section->MipsRegLo(Opcode.base) + (short)Opcode.offset; Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); Compile_LW(Section, Section->MipsRegLo(Opcode.rt),Address); } else { if (UseTlb) { if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base) && Opcode.offset == 0) { ProtectGPR(Section,Opcode.base); TempReg1 = Section->MipsRegLo(Opcode.base); } else { if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } } TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",TempReg2,TempReg2,4); CompileReadTLBMiss(Section,TempReg1,TempReg2); Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); MoveX86regPointerToX86reg(TempReg1, TempReg2,Section->MipsRegLo(Opcode.rt)); } else { if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); LeaSourceAndOffset(Section->MipsRegLo(Opcode.rt),Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { Map_GPR_32bit(Section,Opcode.rt,TRUE,Opcode.base); } } else { Map_GPR_32bit(Section,Opcode.rt,TRUE,Opcode.base); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(Section->MipsRegLo(Opcode.rt)); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(Section->MipsRegLo(Opcode.rt)); } else { AddConstToX86Reg(Section->MipsRegLo(Opcode.rt),(short)Opcode.immediate); } } AndConstToX86Reg(Section->MipsRegLo(Opcode.rt),0x1FFFFFFF); MoveN64MemToX86reg(Section->MipsRegLo(Opcode.rt),Section->MipsRegLo(Opcode.rt)); } } } if (SPHack && Opcode.rt == 29) { Section->ResetX86Protection(); ResetMemoryStack(Section); } } void Compile_R4300i_LBU (CBlockSection * Section) { DWORD TempReg1, TempReg2; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) return; if (Section->IsConst(Opcode.base)) { DWORD Address = (Section->MipsRegLo(Opcode.base) + (short)Opcode.offset) ^ 3; Map_GPR_32bit(Section,Opcode.rt,FALSE,0); Compile_LB(Section->MipsRegLo(Opcode.rt),Address,FALSE); return; } if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",TempReg2,TempReg2,4); CompileReadTLBMiss(Section,TempReg1,TempReg2); XorConstToX86Reg(TempReg1,3); Map_GPR_32bit(Section,Opcode.rt,FALSE,-1); MoveZxByteX86regPointerToX86reg(TempReg1, TempReg2,Section->MipsRegLo(Opcode.rt)); } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); XorConstToX86Reg(TempReg1,3); Map_GPR_32bit(Section,Opcode.rt,FALSE,-1); MoveZxN64MemToX86regByte(Section->MipsRegLo(Opcode.rt), TempReg1); } } void Compile_R4300i_LHU (CBlockSection * Section) { DWORD TempReg1, TempReg2; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) return; if (Section->IsConst(Opcode.base)) { DWORD Address = (Section->MipsRegLo(Opcode.base) + (short)Opcode.offset) ^ 2; Map_GPR_32bit(Section,Opcode.rt,FALSE,0); Compile_LH(Section->MipsRegLo(Opcode.rt),Address,FALSE); return; } if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",TempReg2,TempReg2,4); CompileReadTLBMiss(Section,TempReg1,TempReg2); XorConstToX86Reg(TempReg1,2); Map_GPR_32bit(Section,Opcode.rt,FALSE,-1); MoveZxHalfX86regPointerToX86reg(TempReg1, TempReg2,Section->MipsRegLo(Opcode.rt)); } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); XorConstToX86Reg(TempReg1,2); Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); MoveZxN64MemToX86regHalf(Section->MipsRegLo(Opcode.rt), TempReg1); } } void Compile_R4300i_LWR (CBlockSection * Section) { DWORD TempReg1, TempReg2, Offset, shift; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) return; if (Section->IsConst(Opcode.base)) { DWORD Address, Value; Address = Section->MipsRegLo(Opcode.base) + (short)Opcode.offset; Offset = Address & 3; Map_GPR_32bit(Section,Opcode.rt,TRUE,Opcode.rt); Value = Map_TempReg(Section,x86_Any,-1,FALSE); Compile_LW(Section, Value,(Address & ~3)); AndConstToX86Reg(Section->MipsRegLo(Opcode.rt),LWR_MASK[Offset]); ShiftRightUnsignImmed(Value,(BYTE)LWR_SHIFT[Offset]); AddX86RegToX86Reg(Section->MipsRegLo(Opcode.rt),Value); return; } shift = Map_TempReg(Section,x86_ECX,-1,FALSE); if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } UnProtectGPR(Section,Opcode.base); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",TempReg2,TempReg2,4); CompileReadTLBMiss(Section,TempReg1,TempReg2); } Offset = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, Offset); AndConstToX86Reg(Offset,3); AndConstToX86Reg(TempReg1,~3); Map_GPR_32bit(Section,Opcode.rt,TRUE,Opcode.rt); AndVariableDispToX86Reg(LWR_MASK,"LWR_MASK",Section->MipsRegLo(Opcode.rt),Offset,4); MoveVariableDispToX86Reg(LWR_SHIFT,"LWR_SHIFT",shift,Offset,4); if (UseTlb) { MoveX86regPointerToX86reg(TempReg1, TempReg2,TempReg1); } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); MoveN64MemToX86reg(TempReg1,TempReg1); } ShiftRightUnsign(TempReg1); AddX86RegToX86Reg(Section->MipsRegLo(Opcode.rt),TempReg1); } void Compile_R4300i_LWU (CBlockSection * Section) { //added by Witten DWORD TempReg1, TempReg2; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) return; if (Section->IsConst(Opcode.base)) { DWORD Address = (Section->MipsRegLo(Opcode.base) + (short)Opcode.offset); Map_GPR_32bit(Section,Opcode.rt,FALSE,0); Compile_LW(Section, Section->MipsRegLo(Opcode.rt),Address); return; } if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",TempReg2,TempReg2,4); CompileReadTLBMiss(Section,TempReg1,TempReg2); Map_GPR_32bit(Section,Opcode.rt,FALSE,-1); MoveZxHalfX86regPointerToX86reg(TempReg1, TempReg2,Section->MipsRegLo(Opcode.rt)); } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); MoveZxN64MemToX86regHalf(Section->MipsRegLo(Opcode.rt), TempReg1); } } void Compile_R4300i_SB (CBlockSection * Section){ DWORD TempReg1, TempReg2; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsConst(Opcode.base)) { DWORD Address = (Section->MipsRegLo(Opcode.base) + (short)Opcode.offset) ^ 3; if (Section->IsConst(Opcode.rt)) { Compile_SB_Const((BYTE)Section->MipsRegLo(Opcode.rt), Address); } else if (Section->IsMapped(Opcode.rt) && Is8BitReg(Section->MipsRegLo(Opcode.rt))) { Compile_SB_Register(Section->MipsRegLo(Opcode.rt), Address); } else { Compile_SB_Register(Map_TempReg(Section,x86_Any8Bit,Opcode.rt,FALSE), Address); } return; } if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } UnProtectGPR(Section,Opcode.base); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_WriteMap,"TLB_WriteMap",TempReg2,TempReg2,4); //For tlb miss //0041C522 85 C0 test eax,eax //0041C524 75 01 jne 0041C527 XorConstToX86Reg(TempReg1,3); if (Section->IsConst(Opcode.rt)) { MoveConstByteToX86regPointer((BYTE)Section->MipsRegLo(Opcode.rt),TempReg1, TempReg2); } else if (Section->IsMapped(Opcode.rt) && Is8BitReg(Section->MipsRegLo(Opcode.rt))) { MoveX86regByteToX86regPointer(Section->MipsRegLo(Opcode.rt),TempReg1, TempReg2); } else { UnProtectGPR(Section,Opcode.rt); MoveX86regByteToX86regPointer(Map_TempReg(Section,x86_Any8Bit,Opcode.rt,FALSE),TempReg1, TempReg2); } } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); XorConstToX86Reg(TempReg1,3); if (Section->IsConst(Opcode.rt)) { MoveConstByteToN64Mem((BYTE)Section->MipsRegLo(Opcode.rt),TempReg1); } else if (Section->IsMapped(Opcode.rt) && Is8BitReg(Section->MipsRegLo(Opcode.rt))) { MoveX86regByteToN64Mem(Section->MipsRegLo(Opcode.rt),TempReg1); } else { UnProtectGPR(Section,Opcode.rt); MoveX86regByteToN64Mem(Map_TempReg(Section,x86_Any8Bit,Opcode.rt,FALSE),TempReg1); } } } void Compile_R4300i_SH (CBlockSection * Section){ DWORD TempReg1, TempReg2; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsConst(Opcode.base)) { DWORD Address = (Section->MipsRegLo(Opcode.base) + (short)Opcode.offset) ^ 2; if (Section->IsConst(Opcode.rt)) { Compile_SH_Const((WORD)Section->MipsRegLo(Opcode.rt), Address); } else if (Section->IsMapped(Opcode.rt)) { Compile_SH_Register(Section->MipsRegLo(Opcode.rt), Address); } else { Compile_SH_Register(Map_TempReg(Section,x86_Any,Opcode.rt,FALSE), Address); } return; } if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } UnProtectGPR(Section,Opcode.base); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_WriteMap,"TLB_WriteMap",TempReg2,TempReg2,4); //For tlb miss //0041C522 85 C0 test eax,eax //0041C524 75 01 jne 0041C527 XorConstToX86Reg(TempReg1,2); if (Section->IsConst(Opcode.rt)) { MoveConstHalfToX86regPointer((WORD)Section->MipsRegLo(Opcode.rt),TempReg1, TempReg2); } else if (Section->IsMapped(Opcode.rt)) { MoveX86regHalfToX86regPointer(Section->MipsRegLo(Opcode.rt),TempReg1, TempReg2); } else { MoveX86regHalfToX86regPointer(Map_TempReg(Section,x86_Any,Opcode.rt,FALSE),TempReg1, TempReg2); } } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); XorConstToX86Reg(TempReg1,2); if (Section->IsConst(Opcode.rt)) { MoveConstHalfToN64Mem((WORD)Section->MipsRegLo(Opcode.rt),TempReg1); } else if (Section->IsMapped(Opcode.rt)) { MoveX86regHalfToN64Mem(Section->MipsRegLo(Opcode.rt),TempReg1); } else { MoveX86regHalfToN64Mem(Map_TempReg(Section,x86_Any,Opcode.rt,FALSE),TempReg1); } } } void Compile_R4300i_SWL (CBlockSection * Section) { DWORD TempReg1, TempReg2, Value, Offset, shift; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsConst(Opcode.base)) { DWORD Address; Address = Section->MipsRegLo(Opcode.base) + (short)Opcode.offset; Offset = Address & 3; Value = Map_TempReg(Section,x86_Any,-1,FALSE); Compile_LW(Section, Value,(Address & ~3)); AndConstToX86Reg(Value,SWL_MASK[Offset]); TempReg1 = Map_TempReg(Section,x86_Any,Opcode.rt,FALSE); ShiftRightUnsignImmed(TempReg1,(BYTE)SWL_SHIFT[Offset]); AddX86RegToX86Reg(Value,TempReg1); Compile_SW_Register(Section,Value, (Address & ~3)); return; } shift = Map_TempReg(Section,x86_ECX,-1,FALSE); if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } UnProtectGPR(Section,Opcode.base); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",TempReg2,TempReg2,4); //For tlb miss //0041C522 85 C0 test eax,eax //0041C524 75 01 jne 0041C527 } Offset = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, Offset); AndConstToX86Reg(Offset,3); AndConstToX86Reg(TempReg1,~3); Value = Map_TempReg(Section,x86_Any,-1,FALSE); if (UseTlb) { MoveX86regPointerToX86reg(TempReg1, TempReg2,Value); } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); MoveN64MemToX86reg(Value,TempReg1); } AndVariableDispToX86Reg(SWL_MASK,"SWL_MASK",Value,Offset,4); if (!Section->IsConst(Opcode.rt) || Section->MipsRegLo(Opcode.rt) != 0) { MoveVariableDispToX86Reg(SWL_SHIFT,"SWL_SHIFT",shift,Offset,4); if (Section->IsConst(Opcode.rt)) { MoveConstToX86reg(Section->MipsRegLo(Opcode.rt),Offset); } else if (Section->IsMapped(Opcode.rt)) { MoveX86RegToX86Reg(Section->MipsRegLo(Opcode.rt),Offset); } else { MoveVariableToX86reg(&GPR[Opcode.rt].UW[0],GPR_NameLo[Opcode.rt],Offset); } ShiftRightUnsign(Offset); AddX86RegToX86Reg(Value,Offset); } if (UseTlb) { MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_WriteMap,"TLB_WriteMap",TempReg2,TempReg2,4); MoveX86regToX86regPointer(Value,TempReg1, TempReg2); } else { MoveX86regToN64Mem(Value,TempReg1); } } void Compile_R4300i_SW (CBlockSection * Section){ DWORD TempReg1, TempReg2; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.base == 29 && SPHack) { if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } TempReg1 = Map_MemoryStack(Section,x86_Any,true); if (Section->IsConst(Opcode.rt)) { MoveConstToMemoryDisp (Section->MipsRegLo(Opcode.rt),TempReg1, (DWORD)((short)Opcode.offset)); } else if (Section->IsMapped(Opcode.rt)) { MoveX86regToMemory(Section->MipsRegLo(Opcode.rt),TempReg1,(DWORD)((short)Opcode.offset)); } else { TempReg2 = Map_TempReg(Section,x86_Any,Opcode.rt,FALSE); MoveX86regToMemory(TempReg2,TempReg1,(DWORD)((short)Opcode.offset)); } } else { if (Section->IsConst(Opcode.base)) { DWORD Address = Section->MipsRegLo(Opcode.base) + (short)Opcode.offset; if (Section->IsConst(Opcode.rt)) { Compile_SW_Const(Section->MipsRegLo(Opcode.rt), Address); } else if (Section->IsMapped(Opcode.rt)) { Compile_SW_Register(Section,Section->MipsRegLo(Opcode.rt), Address); } else { Compile_SW_Register(Section,Map_TempReg(Section,x86_Any,Opcode.rt,FALSE), Address); } return; } if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } UnProtectGPR(Section,Opcode.base); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_WriteMap,"TLB_WriteMap",TempReg2,TempReg2,4); //For tlb miss //0041C522 85 C0 test eax,eax //0041C524 75 01 jne 0041C527 if (Section->IsConst(Opcode.rt)) { MoveConstToX86regPointer(Section->MipsRegLo(Opcode.rt),TempReg1, TempReg2); } else if (Section->IsMapped(Opcode.rt)) { MoveX86regToX86regPointer(Section->MipsRegLo(Opcode.rt),TempReg1, TempReg2); } else { MoveX86regToX86regPointer(Map_TempReg(Section,x86_Any,Opcode.rt,FALSE),TempReg1, TempReg2); } } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); if (Section->IsConst(Opcode.rt)) { MoveConstToN64Mem(Section->MipsRegLo(Opcode.rt),TempReg1); } else if (Section->IsMapped(Opcode.rt)) { MoveX86regToN64Mem(Section->MipsRegLo(Opcode.rt),TempReg1); } else { MoveX86regToN64Mem(Map_TempReg(Section,x86_Any,Opcode.rt,FALSE),TempReg1); } } } } void Compile_R4300i_SWR (CBlockSection * Section) { DWORD TempReg1, TempReg2, Value, Offset, shift; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsConst(Opcode.base)) { DWORD Address; Address = Section->MipsRegLo(Opcode.base) + (short)Opcode.offset; Offset = Address & 3; Value = Map_TempReg(Section,x86_Any,-1,FALSE); Compile_LW(Section, Value,(Address & ~3)); AndConstToX86Reg(Value,SWR_MASK[Offset]); TempReg1 = Map_TempReg(Section,x86_Any,Opcode.rt,FALSE); ShiftLeftSignImmed(TempReg1,(BYTE)SWR_SHIFT[Offset]); AddX86RegToX86Reg(Value,TempReg1); Compile_SW_Register(Section,Value, (Address & ~3)); return; } shift = Map_TempReg(Section,x86_ECX,-1,FALSE); if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } UnProtectGPR(Section,Opcode.base); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",TempReg2,TempReg2,4); //For tlb miss //0041C522 85 C0 test eax,eax //0041C524 75 01 jne 0041C527 } Offset = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, Offset); AndConstToX86Reg(Offset,3); AndConstToX86Reg(TempReg1,~3); Value = Map_TempReg(Section,x86_Any,-1,FALSE); if (UseTlb) { MoveX86regPointerToX86reg(TempReg1, TempReg2,Value); } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); MoveN64MemToX86reg(Value,TempReg1); } AndVariableDispToX86Reg(SWR_MASK,"SWR_MASK",Value,Offset,4); if (!Section->IsConst(Opcode.rt) || Section->MipsRegLo(Opcode.rt) != 0) { MoveVariableDispToX86Reg(SWR_SHIFT,"SWR_SHIFT",shift,Offset,4); if (Section->IsConst(Opcode.rt)) { MoveConstToX86reg(Section->MipsRegLo(Opcode.rt),Offset); } else if (Section->IsMapped(Opcode.rt)) { MoveX86RegToX86Reg(Section->MipsRegLo(Opcode.rt),Offset); } else { MoveVariableToX86reg(&GPR[Opcode.rt].UW[0],GPR_NameLo[Opcode.rt],Offset); } ShiftLeftSign(Offset); AddX86RegToX86Reg(Value,Offset); } if (UseTlb) { MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_WriteMap,"TLB_WriteMap",TempReg2,TempReg2,4); MoveX86regToX86regPointer(Value,TempReg1, TempReg2); } else { MoveX86regToN64Mem(Value,TempReg1); } } void Compile_R4300i_SDL (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.base != 0) { UnMap_GPR(Section,Opcode.base,TRUE); } if (Opcode.rt != 0) { UnMap_GPR(Section,Opcode.rt,TRUE); } Pushad(); MoveConstToVariable(Opcode.Hex, &Opcode.Hex, "Opcode.Hex" ); Call_Direct(r4300i_SDL, "r4300i_SDL"); Popad(); } void Compile_R4300i_SDR (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.base != 0) { UnMap_GPR(Section,Opcode.base,TRUE); } if (Opcode.rt != 0) { UnMap_GPR(Section,Opcode.rt,TRUE); } Pushad(); MoveConstToVariable(Opcode.Hex, &Opcode.Hex, "Opcode.Hex" ); Call_Direct(r4300i_SDR, "r4300i_SDR"); Popad(); } void Compile_R4300i_CACHE (CBlockSection * Section){ CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (_Settings->LoadDword(Game_SMM_Cache) == 0) { return; } switch(Opcode.rt) { case 0: case 16: Pushad(); PushImm32("CRecompiler::Remove_Cache",CRecompiler::Remove_Cache); PushImm32("20",20); if (Section->IsConst(Opcode.base)) { DWORD Address = Section->MipsRegLo(Opcode.base) + (short)Opcode.offset; PushImm32("Address",Address); } else if (Section->IsMapped(Opcode.base)) { AddConstToX86Reg(Section->MipsRegLo(Opcode.base),(short)Opcode.offset); Push(Section->MipsRegLo(Opcode.base)); } else { MoveVariableToX86reg(&GPR[Opcode.base].UW[0],GPR_NameLo[Opcode.base],x86_EAX); AddConstToX86Reg(x86_EAX,(short)Opcode.offset); Push(x86_EAX); } MoveConstToX86reg((DWORD)g_N64System->GetRecompiler(),x86_ECX); Call_Direct(AddressOf(CRecompiler::ClearRecompCode_Virt), "CRecompiler::ClearRecompCode_Virt"); Popad(); break; case 1: case 3: case 13: case 5: case 8: case 9: case 17: case 21: case 25: break; #ifndef EXTERNAL_RELEASE default: DisplayError("cache: %d",Opcode.rt); #endif } } void Compile_R4300i_LL (CBlockSection * Section) { DWORD TempReg1, TempReg2; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) return; if (Section->IsConst(Opcode.base)) { DWORD Address = Section->MipsRegLo(Opcode.base) + (short)Opcode.offset; Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); Compile_LW(Section, Section->MipsRegLo(Opcode.rt),Address); MoveConstToVariable(1,g_LLBit,"LLBit"); TranslateVaddr(Address, &Address); MoveConstToVariable(Address,g_LLAddr,"LLAddr"); return; } if (UseTlb) { if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base) && Opcode.offset == 0) { ProtectGPR(Section,Opcode.base); TempReg1 = Section->MipsRegLo(Opcode.base); } else { if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } } TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",TempReg2,TempReg2,4); CompileReadTLBMiss(Section,TempReg1,TempReg2); Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); MoveX86regPointerToX86reg(TempReg1, TempReg2,Section->MipsRegLo(Opcode.rt)); MoveConstToVariable(1,&LLBit,"LLBit"); MoveX86regToVariable(TempReg1,g_LLAddr,"LLAddr"); AddX86regToVariable(TempReg2,g_LLAddr,"LLAddr"); SubConstFromVariable((DWORD)N64MEM,g_LLAddr,"LLAddr"); } else { if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); LeaSourceAndOffset(Section->MipsRegLo(Opcode.rt),Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { Map_GPR_32bit(Section,Opcode.rt,TRUE,Opcode.base); } } else { Map_GPR_32bit(Section,Opcode.rt,TRUE,Opcode.base); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(Section->MipsRegLo(Opcode.rt)); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(Section->MipsRegLo(Opcode.rt)); } else { AddConstToX86Reg(Section->MipsRegLo(Opcode.rt),(short)Opcode.immediate); } } AndConstToX86Reg(Section->MipsRegLo(Opcode.rt),0x1FFFFFFF); MoveX86regToVariable(Section->MipsRegLo(Opcode.rt),g_LLAddr,"LLAddr"); MoveN64MemToX86reg(Section->MipsRegLo(Opcode.rt),Section->MipsRegLo(Opcode.rt)); MoveConstToVariable(1,&LLBit,"LLBit"); } } void Compile_R4300i_SC (CBlockSection * Section){ DWORD TempReg1, TempReg2; BYTE * Jump; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); CompConstToVariable(1,&LLBit,"LLBit"); JneLabel32("LLBitNotSet",0); Jump = RecompPos - 4; if (Section->IsConst(Opcode.base)) { DWORD Address = Section->MipsRegLo(Opcode.base) + (short)Opcode.offset; if (Section->IsConst(Opcode.rt)) { Compile_SW_Const(Section->MipsRegLo(Opcode.rt), Address); } else if (Section->IsMapped(Opcode.rt)) { Compile_SW_Register(Section,Section->MipsRegLo(Opcode.rt), Address); } else { Compile_SW_Register(Section,Map_TempReg(Section,x86_Any,Opcode.rt,FALSE), Address); } CPU_Message(" LLBitNotSet:"); *((DWORD *)(Jump))=(BYTE)(RecompPos - Jump - 4); Map_GPR_32bit(Section,Opcode.rt,FALSE,-1); MoveVariableToX86reg(&LLBit,"LLBit",Section->MipsRegLo(Opcode.rt)); return; } if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } UnProtectGPR(Section,Opcode.base); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_WriteMap,"TLB_WriteMap",TempReg2,TempReg2,4); //For tlb miss //0041C522 85 C0 test eax,eax //0041C524 75 01 jne 0041C527 if (Section->IsConst(Opcode.rt)) { MoveConstToX86regPointer(Section->MipsRegLo(Opcode.rt),TempReg1, TempReg2); } else if (Section->IsMapped(Opcode.rt)) { MoveX86regToX86regPointer(Section->MipsRegLo(Opcode.rt),TempReg1, TempReg2); } else { MoveX86regToX86regPointer(Map_TempReg(Section,x86_Any,Opcode.rt,FALSE),TempReg1, TempReg2); } } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); if (Section->IsConst(Opcode.rt)) { MoveConstToN64Mem(Section->MipsRegLo(Opcode.rt),TempReg1); } else if (Section->IsMapped(Opcode.rt)) { MoveX86regToN64Mem(Section->MipsRegLo(Opcode.rt),TempReg1); } else { MoveX86regToN64Mem(Map_TempReg(Section,x86_Any,Opcode.rt,FALSE),TempReg1); } } CPU_Message(" LLBitNotSet:"); *((DWORD *)(Jump))=(BYTE)(RecompPos - Jump - 4); Map_GPR_32bit(Section,Opcode.rt,FALSE,-1); MoveVariableToX86reg(&LLBit,"LLBit",Section->MipsRegLo(Opcode.rt)); } void Compile_R4300i_LD (CBlockSection * Section) { DWORD TempReg1, TempReg2; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rt == 0) return; if (Section->IsConst(Opcode.base)) { DWORD Address = Section->MipsRegLo(Opcode.base) + (short)Opcode.offset; Map_GPR_64bit(Section,Opcode.rt,-1); Compile_LW(Section, Section->MipsRegHi(Opcode.rt),Address); Compile_LW(Section, Section->MipsRegLo(Opcode.rt),Address + 4); if (SPHack && Opcode.rt == 29) { ResetMemoryStack(Section); } return; } if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base) && Opcode.offset == 0) { if (UseTlb) { ProtectGPR(Section,Opcode.base); TempReg1 = Section->MipsRegLo(Opcode.base); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } } else { if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_ReadMap,"TLB_ReadMap",TempReg2,TempReg2,4); //For tlb miss //0041C522 85 C0 test eax,eax //0041C524 75 01 jne 0041C527 Map_GPR_64bit(Section,Opcode.rt,-1); MoveX86regPointerToX86reg(TempReg1, TempReg2,Section->MipsRegHi(Opcode.rt)); MoveX86regPointerToX86regDisp8(TempReg1, TempReg2,Section->MipsRegLo(Opcode.rt),4); } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); Map_GPR_64bit(Section,Opcode.rt,-1); MoveN64MemToX86reg(Section->MipsRegHi(Opcode.rt),TempReg1); MoveN64MemDispToX86reg(Section->MipsRegLo(Opcode.rt),TempReg1,4); } if (SPHack && Opcode.rt == 29) { Section->ResetX86Protection(); ResetMemoryStack(Section); } } void Compile_R4300i_SD (CBlockSection * Section){ DWORD TempReg1, TempReg2; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsConst(Opcode.base)) { DWORD Address = Section->MipsRegLo(Opcode.base) + (short)Opcode.offset; if (Section->IsConst(Opcode.rt)) { if (Section->Is64Bit(Opcode.rt)) { Compile_SW_Const(Section->MipsRegHi(Opcode.rt), Address); } else { Compile_SW_Const((Section->MipsRegLo_S(Opcode.rt) >> 31), Address); } Compile_SW_Const(Section->MipsRegLo(Opcode.rt), Address + 4); } else if (Section->IsMapped(Opcode.rt)) { if (Section->Is64Bit(Opcode.rt)) { Compile_SW_Register(Section,Section->MipsRegHi(Opcode.rt), Address); } else { Compile_SW_Register(Section,Map_TempReg(Section,x86_Any,Opcode.rt,TRUE), Address); } Compile_SW_Register(Section,Section->MipsRegLo(Opcode.rt), Address + 4); } else { Compile_SW_Register(Section,TempReg1 = Map_TempReg(Section,x86_Any,Opcode.rt,TRUE), Address); Compile_SW_Register(Section,Map_TempReg(Section,TempReg1,Opcode.rt,FALSE), Address + 4); } return; } if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); } if (Section->IsMapped(Opcode.base)) { ProtectGPR(Section,Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(Section,x86_Any,-1,FALSE); LeaSourceAndOffset(TempReg1,Section->MipsRegLo(Opcode.base),(short)Opcode.offset); } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); } } else { TempReg1 = Map_TempReg(Section,x86_Any,Opcode.base,FALSE); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1,(short)Opcode.immediate); } } if (UseTlb) { TempReg2 = Map_TempReg(Section,x86_Any,-1,FALSE); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2,12); MoveVariableDispToX86Reg(TLB_WriteMap,"TLB_WriteMap",TempReg2,TempReg2,4); //For tlb miss //0041C522 85 C0 test eax,eax //0041C524 75 01 jne 0041C527 if (Section->IsConst(Opcode.rt)) { if (Section->Is64Bit(Opcode.rt)) { MoveConstToX86regPointer(Section->MipsRegHi(Opcode.rt),TempReg1, TempReg2); } else { MoveConstToX86regPointer((Section->MipsRegLo_S(Opcode.rt) >> 31),TempReg1, TempReg2); } AddConstToX86Reg(TempReg1,4); MoveConstToX86regPointer(Section->MipsRegLo(Opcode.rt),TempReg1, TempReg2); } else if (Section->IsMapped(Opcode.rt)) { if (Section->Is64Bit(Opcode.rt)) { MoveX86regToX86regPointer(Section->MipsRegHi(Opcode.rt),TempReg1, TempReg2); } else { MoveX86regToX86regPointer(Map_TempReg(Section,x86_Any,Opcode.rt,TRUE),TempReg1, TempReg2); } AddConstToX86Reg(TempReg1,4); MoveX86regToX86regPointer(Section->MipsRegLo(Opcode.rt),TempReg1, TempReg2); } else { int X86Reg = Map_TempReg(Section,x86_Any,Opcode.rt,TRUE); MoveX86regToX86regPointer(X86Reg,TempReg1, TempReg2); AddConstToX86Reg(TempReg1,4); MoveX86regToX86regPointer(Map_TempReg(Section,X86Reg,Opcode.rt,FALSE),TempReg1, TempReg2); } } else { AndConstToX86Reg(TempReg1,0x1FFFFFFF); if (Section->IsConst(Opcode.rt)) { if (Section->Is64Bit(Opcode.rt)) { MoveConstToN64Mem(Section->MipsRegHi(Opcode.rt),TempReg1); } else if (Section->IsSigned(Opcode.rt)) { MoveConstToN64Mem(((int)Section->MipsRegLo(Opcode.rt) >> 31),TempReg1); } else { MoveConstToN64Mem(0,TempReg1); } MoveConstToN64MemDisp(Section->MipsRegLo(Opcode.rt),TempReg1,4); } else if (Section->IsKnown(Opcode.rt) && Section->IsMapped(Opcode.rt)) { if (Section->Is64Bit(Opcode.rt)) { MoveX86regToN64Mem(Section->MipsRegHi(Opcode.rt),TempReg1); } else if (Section->IsSigned(Opcode.rt)) { MoveX86regToN64Mem(Map_TempReg(Section,x86_Any,Opcode.rt,TRUE), TempReg1); } else { MoveConstToN64Mem(0,TempReg1); } MoveX86regToN64MemDisp(Section->MipsRegLo(Opcode.rt),TempReg1, 4); } else { int x86reg; MoveX86regToN64Mem(x86reg = Map_TempReg(Section,x86_Any,Opcode.rt,TRUE), TempReg1); MoveX86regToN64MemDisp(Map_TempReg(Section,x86reg,Opcode.rt,FALSE), TempReg1,4); } } } /********************** R4300i OpCodes: Special **********************/ void Compile_R4300i_SPECIAL_SLL (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rt)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegLo(Opcode.rd) = Section->MipsRegLo(Opcode.rt) << Opcode.sa; Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; return; } if (Opcode.rd != Opcode.rt && Section->IsMapped(Opcode.rt)) { switch (Opcode.sa) { case 0: Map_GPR_32bit(Section,Opcode.rd,TRUE,Opcode.rt); break; case 1: ProtectGPR(Section,Opcode.rt); Map_GPR_32bit(Section,Opcode.rd,TRUE,-1); LeaRegReg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rt), 2); break; case 2: ProtectGPR(Section,Opcode.rt); Map_GPR_32bit(Section,Opcode.rd,TRUE,-1); LeaRegReg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rt), 4); break; case 3: ProtectGPR(Section,Opcode.rt); Map_GPR_32bit(Section,Opcode.rd,TRUE,-1); LeaRegReg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rt), 8); break; default: Map_GPR_32bit(Section,Opcode.rd,TRUE,Opcode.rt); ShiftLeftSignImmed(Section->MipsRegLo(Opcode.rd),(BYTE)Opcode.sa); } } else { Map_GPR_32bit(Section,Opcode.rd,TRUE,Opcode.rt); ShiftLeftSignImmed(Section->MipsRegLo(Opcode.rd),(BYTE)Opcode.sa); } } void Compile_R4300i_SPECIAL_SRL (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rt)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegLo(Opcode.rd) = Section->MipsRegLo(Opcode.rt) >> Opcode.sa; Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; return; } Map_GPR_32bit(Section,Opcode.rd,TRUE,Opcode.rt); ShiftRightUnsignImmed(Section->MipsRegLo(Opcode.rd),(BYTE)Opcode.sa); } void Compile_R4300i_SPECIAL_SRA (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rt)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegLo(Opcode.rd) = Section->MipsRegLo_S(Opcode.rt) >> Opcode.sa; Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; return; } Map_GPR_32bit(Section,Opcode.rd,TRUE,Opcode.rt); ShiftRightSignImmed(Section->MipsRegLo(Opcode.rd),(BYTE)Opcode.sa); } void Compile_R4300i_SPECIAL_SLLV (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rs)) { DWORD Shift = (Section->MipsRegLo(Opcode.rs) & 0x1F); if (Section->IsConst(Opcode.rt)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegLo(Opcode.rd) = Section->MipsRegLo(Opcode.rt) << Shift; Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { Map_GPR_32bit(Section,Opcode.rd,TRUE,Opcode.rt); ShiftLeftSignImmed(Section->MipsRegLo(Opcode.rd),(BYTE)Shift); } return; } Map_TempReg(Section,x86_ECX,Opcode.rs,FALSE); AndConstToX86Reg(x86_ECX,0x1F); Map_GPR_32bit(Section,Opcode.rd,TRUE,Opcode.rt); ShiftLeftSign(Section->MipsRegLo(Opcode.rd)); } void Compile_R4300i_SPECIAL_SRLV (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsKnown(Opcode.rs) && Section->IsConst(Opcode.rs)) { DWORD Shift = (Section->MipsRegLo(Opcode.rs) & 0x1F); if (Section->IsConst(Opcode.rt)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegLo(Opcode.rd) = Section->MipsRegLo(Opcode.rt) >> Shift; Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; return; } Map_GPR_32bit(Section,Opcode.rd,TRUE,Opcode.rt); ShiftRightUnsignImmed(Section->MipsRegLo(Opcode.rd),(BYTE)Shift); return; } Map_TempReg(Section,x86_ECX,Opcode.rs,FALSE); AndConstToX86Reg(x86_ECX,0x1F); Map_GPR_32bit(Section,Opcode.rd,TRUE,Opcode.rt); ShiftRightUnsign(Section->MipsRegLo(Opcode.rd)); } void Compile_R4300i_SPECIAL_SRAV (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsKnown(Opcode.rs) && Section->IsConst(Opcode.rs)) { DWORD Shift = (Section->MipsRegLo(Opcode.rs) & 0x1F); if (Section->IsConst(Opcode.rt)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegLo(Opcode.rd) = Section->MipsRegLo_S(Opcode.rt) >> Shift; Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; return; } Map_GPR_32bit(Section,Opcode.rd,TRUE,Opcode.rt); ShiftRightSignImmed(Section->MipsRegLo(Opcode.rd),(BYTE)Shift); return; } Map_TempReg(Section,x86_ECX,Opcode.rs,FALSE); AndConstToX86Reg(x86_ECX,0x1F); Map_GPR_32bit(Section,Opcode.rd,TRUE,Opcode.rt); ShiftRightSign(Section->MipsRegLo(Opcode.rd)); } void Compile_R4300i_SPECIAL_JR (CBlockSection * Section) { static char JumpLabel[100]; if ( NextInstruction == NORMAL ) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsConst(Opcode.rs)) { sprintf(JumpLabel,"0x%08X",Section->MipsRegLo(Opcode.rs)); Section->Jump.BranchLabel = JumpLabel; Section->Jump.TargetPC = Section->MipsRegLo(Opcode.rs); Section->Jump.FallThrough = TRUE; Section->Jump.LinkLocation = NULL; Section->Jump.LinkLocation2 = NULL; Section->Cont.FallThrough = FALSE; Section->Cont.LinkLocation = NULL; Section->Cont.LinkLocation2 = NULL; if ((Section->CompilePC & 0xFFC) == 0xFFC) { g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); NextInstruction = END_BLOCK; return; } } if ((Section->CompilePC & 0xFFC) == 0xFFC) { if (Section->IsMapped(Opcode.rs)) { MoveX86regToVariable(Section->MipsRegLo(Opcode.rs),&JumpToLocation, "JumpToLocation"); } else { MoveX86regToVariable(Map_TempReg(Section,x86_Any,Opcode.rs,FALSE),&JumpToLocation, "JumpToLocation"); } MoveConstToVariable(Section->CompilePC + 4,&PROGRAM_COUNTER,"PROGRAM_COUNTER"); g_N64System->GetRecompiler()->UpdateCounters(&Section->BlockCycleCount(),&Section->BlockRandomModifier(),FALSE); WriteBackRegisters(Section); if (CPU_Type == CPU_SyncCores) { Call_Direct(SyncToPC, "SyncToPC"); } MoveConstToVariable(DELAY_SLOT,&NextInstruction,"NextInstruction"); Ret(); NextInstruction = END_BLOCK; return; } if (DelaySlotEffectsCompare(Section->CompilePC,Opcode.rs,0)) { if (Section->IsConst(Opcode.rs)) { MoveConstToVariable(Section->MipsRegLo(Opcode.rs),&PROGRAM_COUNTER, "PROGRAM_COUNTER"); } else if (Section->IsMapped(Opcode.rs)) { MoveX86regToVariable(Section->MipsRegLo(Opcode.rs),&PROGRAM_COUNTER, "PROGRAM_COUNTER"); } else { MoveX86regToVariable(Map_TempReg(Section,x86_Any,Opcode.rs,FALSE),&PROGRAM_COUNTER, "PROGRAM_COUNTER"); } } NextInstruction = DO_DELAY_SLOT; } else if (NextInstruction == DELAY_SLOT_DONE ) { if (DelaySlotEffectsCompare(Section->CompilePC,Opcode.rs,0)) { g_N64System->GetRecompiler()->CompileExit (Section,Section->CompilePC,(DWORD)-1,Section->RegWorking,CExitInfo::Normal,TRUE,NULL); } else { if (Section->IsConst(Opcode.rs)) { memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); } else { if (Section->IsMapped(Opcode.rs)) { MoveX86regToVariable(Section->MipsRegLo(Opcode.rs),&PROGRAM_COUNTER, "PROGRAM_COUNTER"); } else { MoveX86regToVariable(Map_TempReg(Section,x86_Any,Opcode.rs,FALSE),&PROGRAM_COUNTER, "PROGRAM_COUNTER"); } g_N64System->GetRecompiler()->CompileExit (Section,-1, (DWORD)-1,Section->RegWorking,CExitInfo::Normal,TRUE,NULL); } } NextInstruction = END_BLOCK; } else { #ifndef EXTERNAL_RELEASE DisplayError("WTF\n\nBranch\nNextInstruction = %X", NextInstruction); #endif } } void Compile_R4300i_SPECIAL_JALR (CBlockSection * Section) { static char JumpLabel[100]; if ( NextInstruction == NORMAL ) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (DelaySlotEffectsCompare(Section->CompilePC,Opcode.rs,0)) { Compile_R4300i_UnknownOpcode(Section); } UnMap_GPR(Section, Opcode.rd, FALSE); Section->MipsRegLo(Opcode.rd) = Section->CompilePC + 8; Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; if ((Section->CompilePC & 0xFFC) == 0xFFC) { if (Section->IsMapped(Opcode.rs)) { MoveX86regToVariable(Section->MipsRegLo(Opcode.rs),&JumpToLocation, "JumpToLocation"); } else { MoveX86regToVariable(Map_TempReg(Section,x86_Any,Opcode.rs,FALSE),&JumpToLocation, "JumpToLocation"); } MoveConstToVariable(Section->CompilePC + 4,&PROGRAM_COUNTER,"PROGRAM_COUNTER"); g_N64System->GetRecompiler()->UpdateCounters(&Section->BlockCycleCount(),&Section->BlockRandomModifier(),FALSE); WriteBackRegisters(Section); if (CPU_Type == CPU_SyncCores) { Call_Direct(SyncToPC, "SyncToPC"); } MoveConstToVariable(DELAY_SLOT,&NextInstruction,"NextInstruction"); Ret(); NextInstruction = END_BLOCK; return; } NextInstruction = DO_DELAY_SLOT; } else if (NextInstruction == DELAY_SLOT_DONE ) { if (Section->IsConst(Opcode.rs)) { memcpy(&Section->Jump.RegSet,&Section->RegWorking,sizeof(CRegInfo)); sprintf(JumpLabel,"0x%08X",Section->MipsRegLo(Opcode.rs)); Section->Jump.BranchLabel = JumpLabel; Section->Jump.TargetPC = Section->MipsRegLo(Opcode.rs); Section->Jump.FallThrough = TRUE; Section->Jump.LinkLocation = NULL; Section->Jump.LinkLocation2 = NULL; Section->Cont.FallThrough = FALSE; Section->Cont.LinkLocation = NULL; Section->Cont.LinkLocation2 = NULL; g_N64System->GetRecompiler()->GenerateSectionLinkage(Section); } else { if (Section->IsMapped(Opcode.rs)) { MoveX86regToVariable(Section->MipsRegLo(Opcode.rs),&PROGRAM_COUNTER, "PROGRAM_COUNTER"); } else { MoveX86regToVariable(Map_TempReg(Section,x86_Any,Opcode.rs,FALSE),&PROGRAM_COUNTER, "PROGRAM_COUNTER"); } g_N64System->GetRecompiler()->CompileExit (Section,Section->CompilePC, (DWORD)-1,Section->RegWorking,CExitInfo::Normal,TRUE,NULL); } NextInstruction = END_BLOCK; } else { #ifndef EXTERNAL_RELEASE DisplayError("WTF\n\nBranch\nNextInstruction = %X", NextInstruction); #endif } } void Compile_R4300i_SPECIAL_SYSCALL (CBlockSection * Section) { g_N64System->GetRecompiler()->CompileExit (Section,Section->CompilePC,Section->CompilePC,Section->RegWorking,CExitInfo::DoSysCall,TRUE,NULL); } void Compile_R4300i_SPECIAL_MFLO (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } Map_GPR_64bit(Section,Opcode.rd,-1); MoveVariableToX86reg(&LO.UW[0],"LO.UW[0]",Section->MipsRegLo(Opcode.rd)); MoveVariableToX86reg(&LO.UW[1],"LO.UW[1]",Section->MipsRegHi(Opcode.rd)); } void Compile_R4300i_SPECIAL_MTLO (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsKnown(Opcode.rs) && Section->IsConst(Opcode.rs)) { if (Section->Is64Bit(Opcode.rs)) { MoveConstToVariable(Section->MipsRegHi(Opcode.rs),&LO.UW[1],"LO.UW[1]"); } else if (Section->IsSigned(Opcode.rs) && ((Section->MipsRegLo(Opcode.rs) & 0x80000000) != 0)) { MoveConstToVariable(0xFFFFFFFF,&LO.UW[1],"LO.UW[1]"); } else { MoveConstToVariable(0,&LO.UW[1],"LO.UW[1]"); } MoveConstToVariable(Section->MipsRegLo(Opcode.rs), &LO.UW[0],"LO.UW[0]"); } else if (Section->IsKnown(Opcode.rs) && Section->IsMapped(Opcode.rs)) { if (Section->Is64Bit(Opcode.rs)) { MoveX86regToVariable(Section->MipsRegHi(Opcode.rs),&LO.UW[1],"LO.UW[1]"); } else if (Section->IsSigned(Opcode.rs)) { MoveX86regToVariable(Map_TempReg(Section,x86_Any,Opcode.rs,TRUE),&LO.UW[1],"LO.UW[1]"); } else { MoveConstToVariable(0,&LO.UW[1],"LO.UW[1]"); } MoveX86regToVariable(Section->MipsRegLo(Opcode.rs), &LO.UW[0],"LO.UW[0]"); } else { int x86reg = Map_TempReg(Section,x86_Any,Opcode.rs,TRUE); MoveX86regToVariable(x86reg,&LO.UW[1],"LO.UW[1]"); MoveX86regToVariable(Map_TempReg(Section,x86reg,Opcode.rs,FALSE), &LO.UW[0],"LO.UW[0]"); } } void Compile_R4300i_SPECIAL_MFHI (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } Map_GPR_64bit(Section,Opcode.rd,-1); MoveVariableToX86reg(&HI.UW[0],"HI.UW[0]",Section->MipsRegLo(Opcode.rd)); MoveVariableToX86reg(&HI.UW[1],"HI.UW[1]",Section->MipsRegHi(Opcode.rd)); } void Compile_R4300i_SPECIAL_MTHI (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsKnown(Opcode.rs) && Section->IsConst(Opcode.rs)) { if (Section->Is64Bit(Opcode.rs)) { MoveConstToVariable(Section->MipsRegHi(Opcode.rs),&HI.UW[1],"HI.UW[1]"); } else if (Section->IsSigned(Opcode.rs) && ((Section->MipsRegLo(Opcode.rs) & 0x80000000) != 0)) { MoveConstToVariable(0xFFFFFFFF,&HI.UW[1],"HI.UW[1]"); } else { MoveConstToVariable(0,&HI.UW[1],"HI.UW[1]"); } MoveConstToVariable(Section->MipsRegLo(Opcode.rs), &HI.UW[0],"HI.UW[0]"); } else if (Section->IsKnown(Opcode.rs) && Section->IsMapped(Opcode.rs)) { if (Section->Is64Bit(Opcode.rs)) { MoveX86regToVariable(Section->MipsRegHi(Opcode.rs),&HI.UW[1],"HI.UW[1]"); } else if (Section->IsSigned(Opcode.rs)) { MoveX86regToVariable(Map_TempReg(Section,x86_Any,Opcode.rs,TRUE),&HI.UW[1],"HI.UW[1]"); } else { MoveConstToVariable(0,&HI.UW[1],"HI.UW[1]"); } MoveX86regToVariable(Section->MipsRegLo(Opcode.rs), &HI.UW[0],"HI.UW[0]"); } else { int x86reg = Map_TempReg(Section,x86_Any,Opcode.rs,TRUE); MoveX86regToVariable(x86reg,&HI.UW[1],"HI.UW[1]"); MoveX86regToVariable(Map_TempReg(Section,x86reg,Opcode.rs,FALSE), &HI.UW[0],"HI.UW[0]"); } } void Compile_R4300i_SPECIAL_DSLLV (CBlockSection * Section) { BYTE * Jump[2]; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rs)) { DWORD Shift = (Section->MipsRegLo(Opcode.rs) & 0x3F); Compile_R4300i_UnknownOpcode(Section); return; } Map_TempReg(Section,x86_ECX,Opcode.rs,FALSE); AndConstToX86Reg(x86_ECX,0x3F); Map_GPR_64bit(Section,Opcode.rd,Opcode.rt); CompConstToX86reg(x86_ECX,0x20); JaeLabel8("MORE32", 0); Jump[0] = RecompPos - 1; ShiftLeftDouble(Section->MipsRegHi(Opcode.rd),Section->MipsRegLo(Opcode.rd)); ShiftLeftSign(Section->MipsRegLo(Opcode.rd)); JmpLabel8("continue", 0); Jump[1] = RecompPos - 1; //MORE32: CPU_Message(""); CPU_Message(" MORE32:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); MoveX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegHi(Opcode.rd)); XorX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rd)); AndConstToX86Reg(x86_ECX,0x1F); ShiftLeftSign(Section->MipsRegHi(Opcode.rd)); //continue: CPU_Message(""); CPU_Message(" continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); } void Compile_R4300i_SPECIAL_DSRLV (CBlockSection * Section) { BYTE * Jump[2]; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rs)) { DWORD Shift = (Section->MipsRegLo(Opcode.rs) & 0x3F); if (Section->IsConst(Opcode.rt)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsReg(Opcode.rd) = Section->Is64Bit(Opcode.rt)?Section->MipsReg(Opcode.rt):(_int64)Section->MipsRegLo_S(Opcode.rt); Section->MipsReg(Opcode.rd) = Section->MipsReg(Opcode.rd) >> Shift; if ((Section->MipsRegHi(Opcode.rd) == 0) && (Section->MipsRegLo(Opcode.rd) & 0x80000000) == 0) { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else if ((Section->MipsRegHi(Opcode.rd) == 0xFFFFFFFF) && (Section->MipsRegLo(Opcode.rd) & 0x80000000) != 0) { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_64; } return; } //if (Shift < 0x20) { //} else { //} //Compile_R4300i_UnknownOpcode(Section); //return; } Map_TempReg(Section,x86_ECX,Opcode.rs,FALSE); AndConstToX86Reg(x86_ECX,0x3F); Map_GPR_64bit(Section,Opcode.rd,Opcode.rt); CompConstToX86reg(x86_ECX,0x20); JaeLabel8("MORE32", 0); Jump[0] = RecompPos - 1; ShiftRightDouble(Section->MipsRegLo(Opcode.rd),Section->MipsRegHi(Opcode.rd)); ShiftRightUnsign(Section->MipsRegHi(Opcode.rd)); JmpLabel8("continue", 0); Jump[1] = RecompPos - 1; //MORE32: CPU_Message(""); CPU_Message(" MORE32:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); MoveX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),Section->MipsRegLo(Opcode.rd)); XorX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),Section->MipsRegHi(Opcode.rd)); AndConstToX86Reg(x86_ECX,0x1F); ShiftRightUnsign(Section->MipsRegLo(Opcode.rd)); //continue: CPU_Message(""); CPU_Message(" continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); } void Compile_R4300i_SPECIAL_DSRAV (CBlockSection * Section) { BYTE * Jump[2]; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rs)) { DWORD Shift = (Section->MipsRegLo(Opcode.rs) & 0x3F); Compile_R4300i_UnknownOpcode(Section); return; } Map_TempReg(Section,x86_ECX,Opcode.rs,FALSE); AndConstToX86Reg(x86_ECX,0x3F); Map_GPR_64bit(Section,Opcode.rd,Opcode.rt); CompConstToX86reg(x86_ECX,0x20); JaeLabel8("MORE32", 0); Jump[0] = RecompPos - 1; ShiftRightDouble(Section->MipsRegLo(Opcode.rd),Section->MipsRegHi(Opcode.rd)); ShiftRightSign(Section->MipsRegHi(Opcode.rd)); JmpLabel8("continue", 0); Jump[1] = RecompPos - 1; //MORE32: CPU_Message(""); CPU_Message(" MORE32:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); MoveX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),Section->MipsRegLo(Opcode.rd)); ShiftRightSignImmed(Section->MipsRegHi(Opcode.rd),0x1F); AndConstToX86Reg(x86_ECX,0x1F); ShiftRightSign(Section->MipsRegLo(Opcode.rd)); //continue: CPU_Message(""); CPU_Message(" continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); } void Compile_R4300i_SPECIAL_MULT ( CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); Section->x86Protected(x86_EDX) = TRUE; Map_TempReg(Section,x86_EAX,Opcode.rs,FALSE); Section->x86Protected(x86_EDX) = FALSE; Map_TempReg(Section,x86_EDX,Opcode.rt,FALSE); imulX86reg(x86_EDX); MoveX86regToVariable(x86_EAX,&LO.UW[0],"LO.UW[0]"); MoveX86regToVariable(x86_EDX,&HI.UW[0],"HI.UW[0]"); ShiftRightSignImmed(x86_EAX,31); /* paired */ ShiftRightSignImmed(x86_EDX,31); MoveX86regToVariable(x86_EAX,&LO.UW[1],"LO.UW[1]"); MoveX86regToVariable(x86_EDX,&HI.UW[1],"HI.UW[1]"); } void Compile_R4300i_SPECIAL_MULTU (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); Section->x86Protected(x86_EDX) = TRUE; Map_TempReg(Section,x86_EAX,Opcode.rs,FALSE); Section->x86Protected(x86_EDX) = FALSE; Map_TempReg(Section,x86_EDX,Opcode.rt,FALSE); MulX86reg(x86_EDX); MoveX86regToVariable(x86_EAX,&LO.UW[0],"LO.UW[0]"); MoveX86regToVariable(x86_EDX,&HI.UW[0],"HI.UW[0]"); ShiftRightSignImmed(x86_EAX,31); /* paired */ ShiftRightSignImmed(x86_EDX,31); MoveX86regToVariable(x86_EAX,&LO.UW[1],"LO.UW[1]"); MoveX86regToVariable(x86_EDX,&HI.UW[1],"HI.UW[1]"); } void Compile_R4300i_SPECIAL_DIV (CBlockSection * Section) { BYTE *Jump[2]; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsConst(Opcode.rt)) { if (Section->MipsRegLo(Opcode.rt) == 0) { MoveConstToVariable(0, &LO.UW[0], "LO.UW[0]"); MoveConstToVariable(0, &LO.UW[1], "LO.UW[1]"); MoveConstToVariable(0, &HI.UW[0], "HI.UW[0]"); MoveConstToVariable(0, &HI.UW[1], "HI.UW[1]"); return; } Jump[1] = NULL; } else { if (Section->IsMapped(Opcode.rt)) { CompConstToX86reg(Section->MipsRegLo(Opcode.rt),0); } else { CompConstToVariable(0, &GPR[Opcode.rt].W[0], GPR_NameLo[Opcode.rt]); } JneLabel8("NoExcept", 0); Jump[0] = RecompPos - 1; MoveConstToVariable(0, &LO.UW[0], "LO.UW[0]"); MoveConstToVariable(0, &LO.UW[1], "LO.UW[1]"); MoveConstToVariable(0, &HI.UW[0], "HI.UW[0]"); MoveConstToVariable(0, &HI.UW[1], "HI.UW[1]"); JmpLabel8("EndDivu", 0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" NoExcept:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); } /* lo = (SD)rs / (SD)rt; hi = (SD)rs % (SD)rt; */ Section->x86Protected(x86_EDX) = TRUE; Map_TempReg(Section,x86_EAX,Opcode.rs,FALSE); /* edx is the signed portion to eax */ Section->x86Protected(x86_EDX) = FALSE; Map_TempReg(Section,x86_EDX, -1, FALSE); MoveX86RegToX86Reg(x86_EAX, x86_EDX); ShiftRightSignImmed(x86_EDX,31); if (Section->IsMapped(Opcode.rt)) { idivX86reg(Section->MipsRegLo(Opcode.rt)); } else { idivX86reg(Map_TempReg(Section,x86_Any,Opcode.rt,FALSE)); } MoveX86regToVariable(x86_EAX,&LO.UW[0],"LO.UW[0]"); MoveX86regToVariable(x86_EDX,&HI.UW[0],"HI.UW[0]"); ShiftRightSignImmed(x86_EAX,31); /* paired */ ShiftRightSignImmed(x86_EDX,31); MoveX86regToVariable(x86_EAX,&LO.UW[1],"LO.UW[1]"); MoveX86regToVariable(x86_EDX,&HI.UW[1],"HI.UW[1]"); if( Jump[1] != NULL ) { CPU_Message(""); CPU_Message(" EndDivu:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); } } void Compile_R4300i_SPECIAL_DIVU ( CBlockSection * Section) { BYTE *Jump[2]; int x86reg; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsConst(Opcode.rt)) { if (Section->MipsRegLo(Opcode.rt) == 0) { MoveConstToVariable(0, &LO.UW[0], "LO.UW[0]"); MoveConstToVariable(0, &LO.UW[1], "LO.UW[1]"); MoveConstToVariable(0, &HI.UW[0], "HI.UW[0]"); MoveConstToVariable(0, &HI.UW[1], "HI.UW[1]"); return; } Jump[1] = NULL; } else { if (Section->IsMapped(Opcode.rt)) { CompConstToX86reg(Section->MipsRegLo(Opcode.rt),0); } else { CompConstToVariable(0, &GPR[Opcode.rt].W[0], GPR_NameLo[Opcode.rt]); } JneLabel8("NoExcept", 0); Jump[0] = RecompPos - 1; MoveConstToVariable(0, &LO.UW[0], "LO.UW[0]"); MoveConstToVariable(0, &LO.UW[1], "LO.UW[1]"); MoveConstToVariable(0, &HI.UW[0], "HI.UW[0]"); MoveConstToVariable(0, &HI.UW[1], "HI.UW[1]"); JmpLabel8("EndDivu", 0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" NoExcept:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); } /* lo = (UD)rs / (UD)rt; hi = (UD)rs % (UD)rt; */ Section->x86Protected(x86_EAX) = TRUE; Map_TempReg(Section,x86_EDX, 0, FALSE); Section->x86Protected(x86_EAX) = FALSE; Map_TempReg(Section,x86_EAX,Opcode.rs,FALSE); x86reg = Map_TempReg(Section,x86_Any,Opcode.rt,FALSE); DivX86reg(x86reg); MoveX86regToVariable(x86_EAX,&LO.UW[0],"LO.UW[0]"); MoveX86regToVariable(x86_EDX,&HI.UW[0],"HI.UW[0]"); /* wouldnt these be zero (???) */ ShiftRightSignImmed(x86_EAX,31); /* paired */ ShiftRightSignImmed(x86_EDX,31); MoveX86regToVariable(x86_EAX,&LO.UW[1],"LO.UW[1]"); MoveX86regToVariable(x86_EDX,&HI.UW[1],"HI.UW[1]"); if( Jump[1] != NULL ) { CPU_Message(""); CPU_Message(" EndDivu:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); } } void Compile_R4300i_SPECIAL_DMULT (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rs != 0) { UnMap_GPR(Section,Opcode.rs,TRUE); } if (Opcode.rs != 0) { UnMap_GPR(Section,Opcode.rt,TRUE); } Pushad(); MoveConstToVariable(Opcode.Hex, &Opcode.Hex, "Opcode.Hex" ); Call_Direct(r4300i_SPECIAL_DMULT, "r4300i_SPECIAL_DMULT"); Popad(); } void Compile_R4300i_SPECIAL_DMULTU (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); /* LO.UDW = (uint64)GPR[Opcode.rs].UW[0] * (uint64)GPR[Opcode.rt].UW[0]; */ Section->x86Protected(x86_EDX) = TRUE; Map_TempReg(Section,x86_EAX,Opcode.rs,FALSE); Section->x86Protected(x86_EDX) = FALSE; Map_TempReg(Section,x86_EDX,Opcode.rt,FALSE); MulX86reg(x86_EDX); MoveX86regToVariable(x86_EAX, &LO.UW[0], "LO.UW[0]"); MoveX86regToVariable(x86_EDX, &LO.UW[1], "LO.UW[1]"); /* HI.UDW = (uint64)GPR[Opcode.rs].UW[1] * (uint64)GPR[Opcode.rt].UW[1]; */ Map_TempReg(Section,x86_EAX,Opcode.rs,TRUE); Map_TempReg(Section,x86_EDX,Opcode.rt,TRUE); MulX86reg(x86_EDX); MoveX86regToVariable(x86_EAX, &HI.UW[0], "HI.UW[0]"); MoveX86regToVariable(x86_EDX, &HI.UW[1], "HI.UW[1]"); /* Tmp[0].UDW = (uint64)GPR[Opcode.rs].UW[1] * (uint64)GPR[Opcode.rt].UW[0]; */ Map_TempReg(Section,x86_EAX,Opcode.rs,TRUE); Map_TempReg(Section,x86_EDX,Opcode.rt,FALSE); Map_TempReg(Section,x86_EBX,-1,FALSE); Map_TempReg(Section,x86_ECX,-1,FALSE); MulX86reg(x86_EDX); MoveX86RegToX86Reg(x86_EAX, x86_EBX); /* EDX:EAX -> ECX:EBX */ MoveX86RegToX86Reg(x86_EDX, x86_ECX); /* Tmp[1].UDW = (uint64)GPR[Opcode.rs].UW[0] * (uint64)GPR[Opcode.rt].UW[1]; */ Map_TempReg(Section,x86_EAX,Opcode.rs,FALSE); Map_TempReg(Section,x86_EDX,Opcode.rt,TRUE); MulX86reg(x86_EDX); Map_TempReg(Section,x86_ESI,-1,FALSE); Map_TempReg(Section,x86_EDI,-1,FALSE); MoveX86RegToX86Reg(x86_EAX, x86_ESI); /* EDX:EAX -> EDI:ESI */ MoveX86RegToX86Reg(x86_EDX, x86_EDI); /* Tmp[2].UDW = (uint64)LO.UW[1] + (uint64)Tmp[0].UW[0] + (uint64)Tmp[1].UW[0]; */ XorX86RegToX86Reg(x86_EDX, x86_EDX); MoveVariableToX86reg(&LO.UW[1], "LO.UW[1]", x86_EAX); AddX86RegToX86Reg(x86_EAX, x86_EBX); AddConstToX86Reg(x86_EDX, 0); AddX86RegToX86Reg(x86_EAX, x86_ESI); AddConstToX86Reg(x86_EDX, 0); /* EDX:EAX */ /* LO.UDW += ((uint64)Tmp[0].UW[0] + (uint64)Tmp[1].UW[0]) << 32; */ /* [low+4] += ebx + esi */ AddX86regToVariable(x86_EBX, &LO.UW[1], "LO.UW[1]"); AddX86regToVariable(x86_ESI, &LO.UW[1], "LO.UW[1]"); /* HI.UDW += (uint64)Tmp[0].UW[1] + (uint64)Tmp[1].UW[1] + Tmp[2].UW[1]; */ /* [hi] += ecx + edi + edx */ AddX86regToVariable(x86_ECX, &HI.UW[0], "HI.UW[0]"); AdcConstToVariable(&HI.UW[1], "HI.UW[1]", 0); AddX86regToVariable(x86_EDI, &HI.UW[0], "HI.UW[0]"); AdcConstToVariable(&HI.UW[1], "HI.UW[1]", 0); AddX86regToVariable(x86_EDX, &HI.UW[0], "HI.UW[0]"); AdcConstToVariable(&HI.UW[1], "HI.UW[1]", 0); } void Compile_R4300i_SPECIAL_DDIV (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); UnMap_GPR(Section,Opcode.rs,TRUE); UnMap_GPR(Section,Opcode.rt,TRUE); Pushad(); MoveConstToVariable(Opcode.Hex, &Opcode.Hex, "Opcode.Hex" ); Call_Direct(r4300i_SPECIAL_DDIV, "r4300i_SPECIAL_DDIV"); Popad(); } void Compile_R4300i_SPECIAL_DDIVU (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); UnMap_GPR(Section,Opcode.rs,TRUE); UnMap_GPR(Section,Opcode.rt,TRUE); Pushad(); MoveConstToVariable(Opcode.Hex, &Opcode.Hex, "Opcode.Hex" ); Call_Direct(r4300i_SPECIAL_DDIVU, "r4300i_SPECIAL_DDIVU"); Popad(); } void Compile_R4300i_SPECIAL_ADD (CBlockSection * Section) { int source1 = Opcode.rd == Opcode.rt?Opcode.rt:Opcode.rs; int source2 = Opcode.rd == Opcode.rt?Opcode.rs:Opcode.rt; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(source1) && Section->IsConst(source2)) { DWORD temp = Section->MipsRegLo(source1) + Section->MipsRegLo(source2); if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegLo(Opcode.rd) = temp; Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; return; } Map_GPR_32bit(Section,Opcode.rd,TRUE, source1); if (Section->IsConst(source2)) { if (Section->MipsRegLo(source2) != 0) { AddConstToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); } } else if (Section->IsKnown(source2) && Section->IsMapped(source2)) { AddX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); } else { AddVariableToX86reg(Section->MipsRegLo(Opcode.rd),&GPR[source2].W[0],GPR_NameLo[source2]); } } void Compile_R4300i_SPECIAL_ADDU (CBlockSection * Section) { int source1 = Opcode.rd == Opcode.rt?Opcode.rt:Opcode.rs; int source2 = Opcode.rd == Opcode.rt?Opcode.rs:Opcode.rt; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(source1) && Section->IsConst(source2)) { DWORD temp = Section->MipsRegLo(source1) + Section->MipsRegLo(source2); if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegLo(Opcode.rd) = temp; Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; return; } Map_GPR_32bit(Section,Opcode.rd,TRUE, source1); if (Section->IsConst(source2)) { if (Section->MipsRegLo(source2) != 0) { AddConstToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); } } else if (Section->IsKnown(source2) && Section->IsMapped(source2)) { AddX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); } else { AddVariableToX86reg(Section->MipsRegLo(Opcode.rd),&GPR[source2].W[0],GPR_NameLo[source2]); } } void Compile_R4300i_SPECIAL_SUB (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rt) && Section->IsConst(Opcode.rs)) { DWORD temp = Section->MipsRegLo(Opcode.rs) - Section->MipsRegLo(Opcode.rt); if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegLo(Opcode.rd) = temp; Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { if (Opcode.rd == Opcode.rt) { int x86Reg = Map_TempReg(Section,x86_Any,Opcode.rt,FALSE); Map_GPR_32bit(Section,Opcode.rd,TRUE, Opcode.rs); SubX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),x86Reg); return; } Map_GPR_32bit(Section,Opcode.rd,TRUE, Opcode.rs); if (Section->IsConst(Opcode.rt)) { SubConstFromX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rt)); } else if (Section->IsMapped(Opcode.rt)) { SubX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rt)); } else { SubVariableFromX86reg(Section->MipsRegLo(Opcode.rd),&GPR[Opcode.rt].W[0],GPR_NameLo[Opcode.rt]); } } } void Compile_R4300i_SPECIAL_SUBU (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rt) && Section->IsConst(Opcode.rs)) { DWORD temp = Section->MipsRegLo(Opcode.rs) - Section->MipsRegLo(Opcode.rt); if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegLo(Opcode.rd) = temp; Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { if (Opcode.rd == Opcode.rt) { int x86Reg = Map_TempReg(Section,x86_Any,Opcode.rt,FALSE); Map_GPR_32bit(Section,Opcode.rd,TRUE, Opcode.rs); SubX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),x86Reg); return; } Map_GPR_32bit(Section,Opcode.rd,TRUE, Opcode.rs); if (Section->IsConst(Opcode.rt)) { SubConstFromX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rt)); } else if (Section->IsMapped(Opcode.rt)) { SubX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rt)); } else { SubVariableFromX86reg(Section->MipsRegLo(Opcode.rd),&GPR[Opcode.rt].W[0],GPR_NameLo[Opcode.rt]); } } } void Compile_R4300i_SPECIAL_AND (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsKnown(Opcode.rt) && Section->IsKnown(Opcode.rs)) { if (Section->IsConst(Opcode.rt) && Section->IsConst(Opcode.rs)) { if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { Section->MipsReg(Opcode.rd) = (Section->Is64Bit(Opcode.rt)?Section->MipsReg(Opcode.rt):(_int64)Section->MipsRegLo_S(Opcode.rt)) & (Section->Is64Bit(Opcode.rs)?Section->MipsReg(Opcode.rs):(_int64)Section->MipsRegLo_S(Opcode.rs)); if (Section->MipsRegLo_S(Opcode.rd) < 0 && Section->MipsRegHi_S(Opcode.rd) == -1){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else if (Section->MipsRegLo_S(Opcode.rd) >= 0 && Section->MipsRegHi_S(Opcode.rd) == 0){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_64; } } else { Section->MipsReg(Opcode.rd) = Section->MipsRegLo(Opcode.rt) & Section->MipsReg(Opcode.rs); Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } } else if (Section->IsMapped(Opcode.rt) && Section->IsMapped(Opcode.rs)) { int source1 = Opcode.rd == Opcode.rt?Opcode.rt:Opcode.rs; int source2 = Opcode.rd == Opcode.rt?Opcode.rs:Opcode.rt; ProtectGPR(Section,source1); ProtectGPR(Section,source2); if (Section->Is32Bit(source1) && Section->Is32Bit(source2)) { int Sign = (Section->IsSigned(Opcode.rt) && Section->IsSigned(Opcode.rs))?TRUE:FALSE; Map_GPR_32bit(Section,Opcode.rd,Sign,source1); AndX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); } else if (Section->Is32Bit(source1) || Section->Is32Bit(source2)) { if (Section->IsUnsigned(Section->Is32Bit(source1)?source1:source2)) { Map_GPR_32bit(Section,Opcode.rd,FALSE,source1); AndX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); } else { Map_GPR_64bit(Section,Opcode.rd,source1); if (Section->Is32Bit(source2)) { AndX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),Map_TempReg(Section,x86_Any,source2,TRUE)); } else { AndX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),Section->MipsRegHi(source2)); } AndX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); } } else { Map_GPR_64bit(Section,Opcode.rd,source1); AndX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),Section->MipsRegHi(source2)); AndX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); } } else { int ConstReg = Section->IsConst(Opcode.rt)?Opcode.rt:Opcode.rs; int MappedReg = Section->IsConst(Opcode.rt)?Opcode.rs:Opcode.rt; if (Section->Is64Bit(ConstReg)) { if (Section->Is32Bit(MappedReg) && Section->IsUnsigned(MappedReg)) { if (Section->MipsRegLo(ConstReg) == 0) { Map_GPR_32bit(Section,Opcode.rd,FALSE, 0); } else { DWORD Value = Section->MipsRegLo(ConstReg); Map_GPR_32bit(Section,Opcode.rd,FALSE, MappedReg); AndConstToX86Reg(Section->MipsRegLo(Opcode.rd),Value); } } else { _int64 Value = Section->MipsReg(ConstReg); Map_GPR_64bit(Section,Opcode.rd,MappedReg); AndConstToX86Reg(Section->MipsRegHi(Opcode.rd),(DWORD)(Value >> 32)); AndConstToX86Reg(Section->MipsRegLo(Opcode.rd),(DWORD)Value); } } else if (Section->Is64Bit(MappedReg)) { DWORD Value = Section->MipsRegLo(ConstReg); if (Value != 0) { Map_GPR_32bit(Section,Opcode.rd,Section->IsSigned(ConstReg)?TRUE:FALSE,MappedReg); AndConstToX86Reg(Section->MipsRegLo(Opcode.rd),(DWORD)Value); } else { Map_GPR_32bit(Section,Opcode.rd,Section->IsSigned(ConstReg)?TRUE:FALSE, 0); } } else { DWORD Value = Section->MipsRegLo(ConstReg); int Sign = FALSE; if (Section->IsSigned(ConstReg) && Section->IsSigned(MappedReg)) { Sign = TRUE; } if (Value != 0) { Map_GPR_32bit(Section,Opcode.rd,Sign,MappedReg); AndConstToX86Reg(Section->MipsRegLo(Opcode.rd),Value); } else { Map_GPR_32bit(Section,Opcode.rd,FALSE, 0); } } } } else if (Section->IsKnown(Opcode.rt) || Section->IsKnown(Opcode.rs)) { DWORD KnownReg = Section->IsKnown(Opcode.rt)?Opcode.rt:Opcode.rs; DWORD UnknownReg = Section->IsKnown(Opcode.rt)?Opcode.rs:Opcode.rt; if (Section->IsConst(KnownReg)) { if (Section->Is64Bit(KnownReg)) { unsigned __int64 Value = Section->MipsReg(KnownReg); Map_GPR_64bit(Section,Opcode.rd,UnknownReg); AndConstToX86Reg(Section->MipsRegHi(Opcode.rd),(DWORD)(Value >> 32)); AndConstToX86Reg(Section->MipsRegLo(Opcode.rd),(DWORD)Value); } else { DWORD Value = Section->MipsRegLo(KnownReg); Map_GPR_32bit(Section,Opcode.rd,Section->IsSigned(KnownReg),UnknownReg); AndConstToX86Reg(Section->MipsRegLo(Opcode.rd),(DWORD)Value); } } else { ProtectGPR(Section,KnownReg); if (KnownReg == Opcode.rd) { if (Section->Is64Bit(KnownReg)) { Map_GPR_64bit(Section,Opcode.rd,KnownReg); AndVariableToX86Reg(&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg],Section->MipsRegHi(Opcode.rd)); AndVariableToX86Reg(&GPR[UnknownReg].W[0],GPR_NameLo[UnknownReg],Section->MipsRegLo(Opcode.rd)); } else { Map_GPR_32bit(Section,Opcode.rd,Section->IsSigned(KnownReg),KnownReg); AndVariableToX86Reg(&GPR[UnknownReg].W[0],GPR_NameLo[UnknownReg],Section->MipsRegLo(Opcode.rd)); } } else { if (Section->Is64Bit(KnownReg)) { Map_GPR_64bit(Section,Opcode.rd,UnknownReg); AndX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),Section->MipsRegHi(KnownReg)); AndX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(KnownReg)); } else { Map_GPR_32bit(Section,Opcode.rd,Section->IsSigned(KnownReg),UnknownReg); AndX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(KnownReg)); } } } } else { Map_GPR_64bit(Section,Opcode.rd,Opcode.rt); AndVariableToX86Reg(&GPR[Opcode.rs].W[1],GPR_NameHi[Opcode.rs],Section->MipsRegHi(Opcode.rd)); AndVariableToX86Reg(&GPR[Opcode.rs].W[0],GPR_NameLo[Opcode.rs],Section->MipsRegLo(Opcode.rd)); } } void Compile_R4300i_SPECIAL_OR (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsKnown(Opcode.rt) && Section->IsKnown(Opcode.rs)) { if (Section->IsConst(Opcode.rt) && Section->IsConst(Opcode.rs)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { Section->MipsReg(Opcode.rd) = (Section->Is64Bit(Opcode.rt)?Section->MipsReg(Opcode.rt):(_int64)Section->MipsRegLo_S(Opcode.rt)) | (Section->Is64Bit(Opcode.rs)?Section->MipsReg(Opcode.rs):(_int64)Section->MipsRegLo_S(Opcode.rs)); if (Section->MipsRegLo_S(Opcode.rd) < 0 && Section->MipsRegHi_S(Opcode.rd) == -1){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else if (Section->MipsRegLo_S(Opcode.rd) >= 0 && Section->MipsRegHi_S(Opcode.rd) == 0){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_64; } } else { Section->MipsRegLo(Opcode.rd) = Section->MipsRegLo(Opcode.rt) | Section->MipsRegLo(Opcode.rs); Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } } else if (Section->IsMapped(Opcode.rt) && Section->IsMapped(Opcode.rs)) { int source1 = Opcode.rd == Opcode.rt?Opcode.rt:Opcode.rs; int source2 = Opcode.rd == Opcode.rt?Opcode.rs:Opcode.rt; ProtectGPR(Section,Opcode.rt); ProtectGPR(Section,Opcode.rs); if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { Map_GPR_64bit(Section,Opcode.rd,source1); if (Section->Is64Bit(source2)) { OrX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),Section->MipsRegHi(source2)); } else { OrX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),Map_TempReg(Section,x86_Any,source2,TRUE)); } } else { ProtectGPR(Section,source2); Map_GPR_32bit(Section,Opcode.rd,TRUE,source1); } OrX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); } else { DWORD ConstReg = Section->IsConst(Opcode.rt)?Opcode.rt:Opcode.rs; DWORD MappedReg = Section->IsConst(Opcode.rt)?Opcode.rs:Opcode.rt; if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { unsigned _int64 Value; if (Section->Is64Bit(ConstReg)) { Value = Section->MipsReg(ConstReg); } else { Value = Section->IsSigned(ConstReg)?Section->MipsRegLo_S(ConstReg):Section->MipsRegLo(ConstReg); } Map_GPR_64bit(Section,Opcode.rd,MappedReg); if ((Value >> 32) != 0) { OrConstToX86Reg((DWORD)(Value >> 32),Section->MipsRegHi(Opcode.rd)); } if ((DWORD)Value != 0) { OrConstToX86Reg((DWORD)Value,Section->MipsRegLo(Opcode.rd)); } } else { int Value = Section->MipsRegLo(ConstReg); Map_GPR_32bit(Section,Opcode.rd,TRUE, MappedReg); if (Value != 0) { OrConstToX86Reg(Value,Section->MipsRegLo(Opcode.rd)); } } } } else if (Section->IsKnown(Opcode.rt) || Section->IsKnown(Opcode.rs)) { int KnownReg = Section->IsKnown(Opcode.rt)?Opcode.rt:Opcode.rs; int UnknownReg = Section->IsKnown(Opcode.rt)?Opcode.rs:Opcode.rt; if (Section->IsConst(KnownReg)) { unsigned _int64 Value; Value = Section->Is64Bit(KnownReg)?Section->MipsReg(KnownReg):Section->MipsRegLo_S(KnownReg); Map_GPR_64bit(Section,Opcode.rd,UnknownReg); if ((Value >> 32) != 0) { OrConstToX86Reg((DWORD)(Value >> 32),Section->MipsRegHi(Opcode.rd)); } if ((DWORD)Value != 0) { OrConstToX86Reg((DWORD)Value,Section->MipsRegLo(Opcode.rd)); } } else { Map_GPR_64bit(Section,Opcode.rd,KnownReg); OrVariableToX86Reg(&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg],Section->MipsRegHi(Opcode.rd)); OrVariableToX86Reg(&GPR[UnknownReg].W[0],GPR_NameLo[UnknownReg],Section->MipsRegLo(Opcode.rd)); } } else { Map_GPR_64bit(Section,Opcode.rd,Opcode.rt); OrVariableToX86Reg(&GPR[Opcode.rs].W[1],GPR_NameHi[Opcode.rs],Section->MipsRegHi(Opcode.rd)); OrVariableToX86Reg(&GPR[Opcode.rs].W[0],GPR_NameLo[Opcode.rs],Section->MipsRegLo(Opcode.rd)); } if (SPHack && Opcode.rd == 29) { Section->ResetX86Protection(); ResetMemoryStack(Section); } } void Compile_R4300i_SPECIAL_XOR (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Opcode.rt == Opcode.rs) { UnMap_GPR(Section, Opcode.rd, FALSE); Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; Section->MipsRegLo(Opcode.rd) = 0; return; } if (Section->IsKnown(Opcode.rt) && Section->IsKnown(Opcode.rs)) { if (Section->IsConst(Opcode.rt) && Section->IsConst(Opcode.rs)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { #ifndef EXTERNAL_RELEASE DisplayError("XOR 1"); #endif Compile_R4300i_UnknownOpcode(Section); } else { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; Section->MipsRegLo(Opcode.rd) = Section->MipsRegLo(Opcode.rt) ^ Section->MipsRegLo(Opcode.rs); } } else if (Section->IsMapped(Opcode.rt) && Section->IsMapped(Opcode.rs)) { int source1 = Opcode.rd == Opcode.rt?Opcode.rt:Opcode.rs; int source2 = Opcode.rd == Opcode.rt?Opcode.rs:Opcode.rt; ProtectGPR(Section,source1); ProtectGPR(Section,source2); if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { Map_GPR_64bit(Section,Opcode.rd,source1); if (Section->Is64Bit(source2)) { XorX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),Section->MipsRegHi(source2)); } else if (Section->IsSigned(source2)) { XorX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),Map_TempReg(Section,x86_Any,source2,TRUE)); } XorX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); } else { if (Section->IsSigned(Opcode.rt) != Section->IsSigned(Opcode.rs)) { Map_GPR_32bit(Section,Opcode.rd,TRUE,source1); } else { Map_GPR_32bit(Section,Opcode.rd,Section->IsSigned(Opcode.rt),source1); } XorX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); } } else { DWORD ConstReg = Section->IsConst(Opcode.rt)?Opcode.rt:Opcode.rs; DWORD MappedReg = Section->IsConst(Opcode.rt)?Opcode.rs:Opcode.rt; if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { DWORD ConstHi, ConstLo; ConstHi = Section->Is32Bit(ConstReg)?(DWORD)(Section->MipsRegLo_S(ConstReg) >> 31):Section->MipsRegHi(ConstReg); ConstLo = Section->MipsRegLo(ConstReg); Map_GPR_64bit(Section,Opcode.rd,MappedReg); if (ConstHi != 0) { XorConstToX86Reg(Section->MipsRegHi(Opcode.rd),ConstHi); } if (ConstLo != 0) { XorConstToX86Reg(Section->MipsRegLo(Opcode.rd),ConstLo); } } else { int Value = Section->MipsRegLo(ConstReg); if (Section->IsSigned(Opcode.rt) != Section->IsSigned(Opcode.rs)) { Map_GPR_32bit(Section,Opcode.rd,TRUE, MappedReg); } else { Map_GPR_32bit(Section,Opcode.rd,Section->IsSigned(MappedReg)?TRUE:FALSE, MappedReg); } if (Value != 0) { XorConstToX86Reg(Section->MipsRegLo(Opcode.rd),Value); } } } } else if (Section->IsKnown(Opcode.rt) || Section->IsKnown(Opcode.rs)) { int KnownReg = Section->IsKnown(Opcode.rt)?Opcode.rt:Opcode.rs; int UnknownReg = Section->IsKnown(Opcode.rt)?Opcode.rs:Opcode.rt; if (Section->IsConst(KnownReg)) { unsigned _int64 Value; if (Section->Is64Bit(KnownReg)) { Value = Section->MipsReg(KnownReg); } else { if (Section->IsSigned(KnownReg)) { Value = (int)Section->MipsRegLo(KnownReg); } else { Value = Section->MipsRegLo(KnownReg); } } Map_GPR_64bit(Section,Opcode.rd,UnknownReg); if ((Value >> 32) != 0) { XorConstToX86Reg(Section->MipsRegHi(Opcode.rd),(DWORD)(Value >> 32)); } if ((DWORD)Value != 0) { XorConstToX86Reg(Section->MipsRegLo(Opcode.rd),(DWORD)Value); } } else { Map_GPR_64bit(Section,Opcode.rd,KnownReg); XorVariableToX86reg(&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg],Section->MipsRegHi(Opcode.rd)); XorVariableToX86reg(&GPR[UnknownReg].W[0],GPR_NameLo[UnknownReg],Section->MipsRegLo(Opcode.rd)); } } else { Map_GPR_64bit(Section,Opcode.rd,Opcode.rt); XorVariableToX86reg(&GPR[Opcode.rs].W[1],GPR_NameHi[Opcode.rs],Section->MipsRegHi(Opcode.rd)); XorVariableToX86reg(&GPR[Opcode.rs].W[0],GPR_NameLo[Opcode.rs],Section->MipsRegLo(Opcode.rd)); } } void Compile_R4300i_SPECIAL_NOR (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsKnown(Opcode.rt) && Section->IsKnown(Opcode.rs)) { if (Section->IsConst(Opcode.rt) && Section->IsConst(Opcode.rs)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { Compile_R4300i_UnknownOpcode(Section); } else { Section->MipsRegLo(Opcode.rd) = ~(Section->MipsRegLo(Opcode.rt) | Section->MipsRegLo(Opcode.rs)); Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } } else if (Section->IsMapped(Opcode.rt) && Section->IsMapped(Opcode.rs)) { int source1 = Opcode.rd == Opcode.rt?Opcode.rt:Opcode.rs; int source2 = Opcode.rd == Opcode.rt?Opcode.rs:Opcode.rt; ProtectGPR(Section,source1); ProtectGPR(Section,source2); if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { Map_GPR_64bit(Section,Opcode.rd,source1); if (Section->Is64Bit(source2)) { OrX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),Section->MipsRegHi(source2)); } else { OrX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),Map_TempReg(Section,x86_Any,source2,TRUE)); } OrX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); NotX86Reg(Section->MipsRegHi(Opcode.rd)); NotX86Reg(Section->MipsRegLo(Opcode.rd)); } else { ProtectGPR(Section,source2); if (Section->IsSigned(Opcode.rt) != Section->IsSigned(Opcode.rs)) { Map_GPR_32bit(Section,Opcode.rd,TRUE,source1); } else { Map_GPR_32bit(Section,Opcode.rd,Section->IsSigned(Opcode.rt),source1); } OrX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); NotX86Reg(Section->MipsRegLo(Opcode.rd)); } } else { DWORD ConstReg = Section->IsConst(Opcode.rt)?Opcode.rt:Opcode.rs; DWORD MappedReg = Section->IsConst(Opcode.rt)?Opcode.rs:Opcode.rt; if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { unsigned _int64 Value; if (Section->Is64Bit(ConstReg)) { Value = Section->MipsReg(ConstReg); } else { Value = Section->IsSigned(ConstReg)?Section->MipsRegLo_S(ConstReg):Section->MipsRegLo(ConstReg); } Map_GPR_64bit(Section,Opcode.rd,MappedReg); if ((Value >> 32) != 0) { OrConstToX86Reg((DWORD)(Value >> 32),Section->MipsRegHi(Opcode.rd)); } if ((DWORD)Value != 0) { OrConstToX86Reg((DWORD)Value,Section->MipsRegLo(Opcode.rd)); } NotX86Reg(Section->MipsRegHi(Opcode.rd)); NotX86Reg(Section->MipsRegLo(Opcode.rd)); } else { int Value = Section->MipsRegLo(ConstReg); if (Section->IsSigned(Opcode.rt) != Section->IsSigned(Opcode.rs)) { Map_GPR_32bit(Section,Opcode.rd,TRUE, MappedReg); } else { Map_GPR_32bit(Section,Opcode.rd,Section->IsSigned(MappedReg)?TRUE:FALSE, MappedReg); } if (Value != 0) { OrConstToX86Reg(Value,Section->MipsRegLo(Opcode.rd)); } NotX86Reg(Section->MipsRegLo(Opcode.rd)); } } } else if (Section->IsKnown(Opcode.rt) || Section->IsKnown(Opcode.rs)) { int KnownReg = Section->IsKnown(Opcode.rt)?Opcode.rt:Opcode.rs; int UnknownReg = Section->IsKnown(Opcode.rt)?Opcode.rs:Opcode.rt; if (Section->IsConst(KnownReg)) { unsigned _int64 Value; Value = Section->Is64Bit(KnownReg)?Section->MipsReg(KnownReg):Section->MipsRegLo_S(KnownReg); Map_GPR_64bit(Section,Opcode.rd,UnknownReg); if ((Value >> 32) != 0) { OrConstToX86Reg((DWORD)(Value >> 32),Section->MipsRegHi(Opcode.rd)); } if ((DWORD)Value != 0) { OrConstToX86Reg((DWORD)Value,Section->MipsRegLo(Opcode.rd)); } } else { Map_GPR_64bit(Section,Opcode.rd,KnownReg); OrVariableToX86Reg(&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg],Section->MipsRegHi(Opcode.rd)); OrVariableToX86Reg(&GPR[UnknownReg].W[0],GPR_NameLo[UnknownReg],Section->MipsRegLo(Opcode.rd)); } NotX86Reg(Section->MipsRegHi(Opcode.rd)); NotX86Reg(Section->MipsRegLo(Opcode.rd)); } else { Map_GPR_64bit(Section,Opcode.rd,Opcode.rt); OrVariableToX86Reg(&GPR[Opcode.rs].W[1],GPR_NameHi[Opcode.rs],Section->MipsRegHi(Opcode.rd)); OrVariableToX86Reg(&GPR[Opcode.rs].W[0],GPR_NameLo[Opcode.rs],Section->MipsRegLo(Opcode.rd)); NotX86Reg(Section->MipsRegHi(Opcode.rd)); NotX86Reg(Section->MipsRegLo(Opcode.rd)); } } void Compile_R4300i_SPECIAL_SLT (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsKnown(Opcode.rt) && Section->IsKnown(Opcode.rs)) { if (Section->IsConst(Opcode.rt) && Section->IsConst(Opcode.rs)) { if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { DisplayError("1"); Compile_R4300i_UnknownOpcode(Section); } else { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; if (Section->MipsRegLo_S(Opcode.rs) < Section->MipsRegLo_S(Opcode.rt)) { Section->MipsRegLo(Opcode.rd) = 1; } else { Section->MipsRegLo(Opcode.rd) = 0; } } } else if (Section->IsMapped(Opcode.rt) && Section->IsMapped(Opcode.rs)) { ProtectGPR(Section,Opcode.rt); ProtectGPR(Section,Opcode.rs); if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { BYTE *Jump[2]; CompX86RegToX86Reg( Section->Is64Bit(Opcode.rs)?Section->MipsRegHi(Opcode.rs):Map_TempReg(Section,x86_Any,Opcode.rs,TRUE), Section->Is64Bit(Opcode.rt)?Section->MipsRegHi(Opcode.rt):Map_TempReg(Section,x86_Any,Opcode.rt,TRUE) ); JeLabel8("Low Compare",0); Jump[0] = RecompPos - 1; SetlVariable(&BranchCompare,"BranchCompare"); JmpLabel8("Continue",0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" Low Compare:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); CompX86RegToX86Reg(Section->MipsRegLo(Opcode.rs), Section->MipsRegLo(Opcode.rt)); SetbVariable(&BranchCompare,"BranchCompare"); CPU_Message(""); CPU_Message(" Continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); Map_GPR_32bit(Section,Opcode.rd,TRUE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rd)); } else { Map_GPR_32bit(Section,Opcode.rd,TRUE, -1); CompX86RegToX86Reg(Section->MipsRegLo(Opcode.rs), Section->MipsRegLo(Opcode.rt)); if (Section->MipsRegLo(Opcode.rd) > x86_EDX) { SetlVariable(&BranchCompare,"BranchCompare"); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rd)); } else { Setl(Section->MipsRegLo(Opcode.rd)); AndConstToX86Reg(Section->MipsRegLo(Opcode.rd), 1); } } } else { DWORD ConstReg = Section->IsConst(Opcode.rs)?Opcode.rs:Opcode.rt; DWORD MappedReg = Section->IsConst(Opcode.rs)?Opcode.rt:Opcode.rs; ProtectGPR(Section,MappedReg); if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { BYTE *Jump[2]; CompConstToX86reg( Section->Is64Bit(MappedReg)?Section->MipsRegHi(MappedReg):Map_TempReg(Section,x86_Any,MappedReg,TRUE), Section->Is64Bit(ConstReg)?Section->MipsRegHi(ConstReg):(Section->MipsRegLo_S(ConstReg) >> 31) ); JeLabel8("Low Compare",0); Jump[0] = RecompPos - 1; if (MappedReg == Opcode.rs) { SetlVariable(&BranchCompare,"BranchCompare"); } else { SetgVariable(&BranchCompare,"BranchCompare"); } JmpLabel8("Continue",0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" Low Compare:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); CompConstToX86reg(Section->MipsRegLo(MappedReg), Section->MipsRegLo(ConstReg)); if (MappedReg == Opcode.rs) { SetbVariable(&BranchCompare,"BranchCompare"); } else { SetaVariable(&BranchCompare,"BranchCompare"); } CPU_Message(""); CPU_Message(" Continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); Map_GPR_32bit(Section,Opcode.rd,TRUE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rd)); } else { DWORD Constant = Section->MipsRegLo(ConstReg); Map_GPR_32bit(Section,Opcode.rd,TRUE, -1); CompConstToX86reg(Section->MipsRegLo(MappedReg), Constant); if (Section->MipsRegLo(Opcode.rd) > x86_EDX) { if (MappedReg == Opcode.rs) { SetlVariable(&BranchCompare,"BranchCompare"); } else { SetgVariable(&BranchCompare,"BranchCompare"); } MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rd)); } else { if (MappedReg == Opcode.rs) { Setl(Section->MipsRegLo(Opcode.rd)); } else { Setg(Section->MipsRegLo(Opcode.rd)); } AndConstToX86Reg(Section->MipsRegLo(Opcode.rd), 1); } } } } else if (Section->IsKnown(Opcode.rt) || Section->IsKnown(Opcode.rs)) { DWORD KnownReg = Section->IsKnown(Opcode.rt)?Opcode.rt:Opcode.rs; DWORD UnknownReg = Section->IsKnown(Opcode.rt)?Opcode.rs:Opcode.rt; BYTE *Jump[2]; if (Section->IsConst(KnownReg)) { if (Section->Is64Bit(KnownReg)) { CompConstToVariable(Section->MipsRegHi(KnownReg),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } else { CompConstToVariable(((int)Section->MipsRegLo(KnownReg) >> 31),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } } else { if (Section->Is64Bit(KnownReg)) { CompX86regToVariable(Section->MipsRegHi(KnownReg),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } else { ProtectGPR(Section,KnownReg); CompX86regToVariable(Map_TempReg(Section,x86_Any,KnownReg,TRUE),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } } JeLabel8("Low Compare",0); Jump[0] = RecompPos - 1; if (KnownReg == (Section->IsConst(KnownReg)?Opcode.rs:Opcode.rt)) { SetgVariable(&BranchCompare,"BranchCompare"); } else { SetlVariable(&BranchCompare,"BranchCompare"); } JmpLabel8("Continue",0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" Low Compare:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); if (Section->IsConst(KnownReg)) { CompConstToVariable(Section->MipsRegLo(KnownReg),&GPR[UnknownReg].W[0],GPR_NameLo[UnknownReg]); } else { CompX86regToVariable(Section->MipsRegLo(KnownReg),&GPR[UnknownReg].W[0],GPR_NameLo[UnknownReg]); } if (KnownReg == (Section->IsConst(KnownReg)?Opcode.rs:Opcode.rt)) { SetaVariable(&BranchCompare,"BranchCompare"); } else { SetbVariable(&BranchCompare,"BranchCompare"); } CPU_Message(""); CPU_Message(" Continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); Map_GPR_32bit(Section,Opcode.rd,TRUE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rd)); } else { BYTE *Jump[2]; int x86Reg; x86Reg = Map_TempReg(Section,x86_Any,Opcode.rs,TRUE); CompX86regToVariable(x86Reg,&GPR[Opcode.rt].W[1],GPR_NameHi[Opcode.rt]); JeLabel8("Low Compare",0); Jump[0] = RecompPos - 1; SetlVariable(&BranchCompare,"BranchCompare"); JmpLabel8("Continue",0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" Low Compare:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); CompX86regToVariable(Map_TempReg(Section,x86Reg,Opcode.rs,FALSE),&GPR[Opcode.rt].W[0],GPR_NameLo[Opcode.rt]); SetbVariable(&BranchCompare,"BranchCompare"); CPU_Message(""); CPU_Message(" Continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); Map_GPR_32bit(Section,Opcode.rd,TRUE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rd)); } } void Compile_R4300i_SPECIAL_SLTU (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsKnown(Opcode.rt) && Section->IsKnown(Opcode.rs)) { if (Section->IsConst(Opcode.rt) && Section->IsConst(Opcode.rs)) { if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { #ifndef EXTERNAL_RELEASE DisplayError("1"); #endif Compile_R4300i_UnknownOpcode(Section); } else { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; if (Section->MipsRegLo(Opcode.rs) < Section->MipsRegLo(Opcode.rt)) { Section->MipsRegLo(Opcode.rd) = 1; } else { Section->MipsRegLo(Opcode.rd) = 0; } } } else if (Section->IsMapped(Opcode.rt) && Section->IsMapped(Opcode.rs)) { ProtectGPR(Section,Opcode.rt); ProtectGPR(Section,Opcode.rs); if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { BYTE *Jump[2]; CompX86RegToX86Reg( Section->Is64Bit(Opcode.rs)?Section->MipsRegHi(Opcode.rs):Map_TempReg(Section,x86_Any,Opcode.rs,TRUE), Section->Is64Bit(Opcode.rt)?Section->MipsRegHi(Opcode.rt):Map_TempReg(Section,x86_Any,Opcode.rt,TRUE) ); JeLabel8("Low Compare",0); Jump[0] = RecompPos - 1; SetbVariable(&BranchCompare,"BranchCompare"); JmpLabel8("Continue",0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" Low Compare:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); CompX86RegToX86Reg(Section->MipsRegLo(Opcode.rs), Section->MipsRegLo(Opcode.rt)); SetbVariable(&BranchCompare,"BranchCompare"); CPU_Message(""); CPU_Message(" Continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); Map_GPR_32bit(Section,Opcode.rd,TRUE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rd)); } else { CompX86RegToX86Reg(Section->MipsRegLo(Opcode.rs), Section->MipsRegLo(Opcode.rt)); SetbVariable(&BranchCompare,"BranchCompare"); Map_GPR_32bit(Section,Opcode.rd,TRUE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rd)); } } else { if (Section->Is64Bit(Opcode.rt) || Section->Is64Bit(Opcode.rs)) { DWORD MappedRegHi, MappedRegLo, ConstHi, ConstLo, MappedReg, ConstReg; BYTE *Jump[2]; ConstReg = Section->IsConst(Opcode.rt)?Opcode.rt:Opcode.rs; MappedReg = Section->IsConst(Opcode.rt)?Opcode.rs:Opcode.rt; ConstLo = Section->MipsRegLo(ConstReg); ConstHi = (int)ConstLo >> 31; if (Section->Is64Bit(ConstReg)) { ConstHi = Section->MipsRegHi(ConstReg); } ProtectGPR(Section,MappedReg); MappedRegLo = Section->MipsRegLo(MappedReg); MappedRegHi = Section->MipsRegHi(MappedReg); if (Section->Is32Bit(MappedReg)) { MappedRegHi = Map_TempReg(Section,x86_Any,MappedReg,TRUE); } Map_GPR_32bit(Section,Opcode.rd,TRUE, -1); CompConstToX86reg(MappedRegHi, ConstHi); JeLabel8("Low Compare",0); Jump[0] = RecompPos - 1; if (MappedReg == Opcode.rs) { SetbVariable(&BranchCompare,"BranchCompare"); } else { SetaVariable(&BranchCompare,"BranchCompare"); } JmpLabel8("Continue",0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" Low Compare:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); CompConstToX86reg(MappedRegLo, ConstLo); if (MappedReg == Opcode.rs) { SetbVariable(&BranchCompare,"BranchCompare"); } else { SetaVariable(&BranchCompare,"BranchCompare"); } CPU_Message(""); CPU_Message(" Continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); Map_GPR_32bit(Section,Opcode.rd,TRUE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rd)); } else { DWORD Const = Section->IsConst(Opcode.rs)?Section->MipsRegLo(Opcode.rs):Section->MipsRegLo(Opcode.rt); DWORD MappedReg = Section->IsConst(Opcode.rt)?Opcode.rs:Opcode.rt; CompConstToX86reg(Section->MipsRegLo(MappedReg), Const); if (MappedReg == Opcode.rs) { SetbVariable(&BranchCompare,"BranchCompare"); } else { SetaVariable(&BranchCompare,"BranchCompare"); } Map_GPR_32bit(Section,Opcode.rd,TRUE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rd)); } } } else if (Section->IsKnown(Opcode.rt) || Section->IsKnown(Opcode.rs)) { DWORD KnownReg = Section->IsKnown(Opcode.rt)?Opcode.rt:Opcode.rs; DWORD UnknownReg = Section->IsKnown(Opcode.rt)?Opcode.rs:Opcode.rt; BYTE *Jump[2]; if (Section->IsConst(KnownReg)) { if (Section->Is64Bit(KnownReg)) { CompConstToVariable(Section->MipsRegHi(KnownReg),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } else { CompConstToVariable(((int)Section->MipsRegLo(KnownReg) >> 31),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } } else { if (Section->Is64Bit(KnownReg)) { CompX86regToVariable(Section->MipsRegHi(KnownReg),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } else { ProtectGPR(Section,KnownReg); CompX86regToVariable(Map_TempReg(Section,x86_Any,KnownReg,TRUE),&GPR[UnknownReg].W[1],GPR_NameHi[UnknownReg]); } } JeLabel8("Low Compare",0); Jump[0] = RecompPos - 1; if (KnownReg == (Section->IsConst(KnownReg)?Opcode.rs:Opcode.rt)) { SetaVariable(&BranchCompare,"BranchCompare"); } else { SetbVariable(&BranchCompare,"BranchCompare"); } JmpLabel8("Continue",0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" Low Compare:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); if (Section->IsConst(KnownReg)) { CompConstToVariable(Section->MipsRegLo(KnownReg),&GPR[UnknownReg].W[0],GPR_NameLo[UnknownReg]); } else { CompX86regToVariable(Section->MipsRegLo(KnownReg),&GPR[UnknownReg].W[0],GPR_NameLo[UnknownReg]); } if (KnownReg == (Section->IsConst(KnownReg)?Opcode.rs:Opcode.rt)) { SetaVariable(&BranchCompare,"BranchCompare"); } else { SetbVariable(&BranchCompare,"BranchCompare"); } CPU_Message(""); CPU_Message(" Continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); Map_GPR_32bit(Section,Opcode.rd,TRUE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rd)); } else { BYTE *Jump[2]; int x86Reg; x86Reg = Map_TempReg(Section,x86_Any,Opcode.rs,TRUE); CompX86regToVariable(x86Reg,&GPR[Opcode.rt].W[1],GPR_NameHi[Opcode.rt]); JeLabel8("Low Compare",0); Jump[0] = RecompPos - 1; SetbVariable(&BranchCompare,"BranchCompare"); JmpLabel8("Continue",0); Jump[1] = RecompPos - 1; CPU_Message(""); CPU_Message(" Low Compare:"); *((BYTE *)(Jump[0]))=(BYTE)(RecompPos - Jump[0] - 1); CompX86regToVariable(Map_TempReg(Section,x86Reg,Opcode.rs,FALSE),&GPR[Opcode.rt].W[0],GPR_NameLo[Opcode.rt]); SetbVariable(&BranchCompare,"BranchCompare"); CPU_Message(""); CPU_Message(" Continue:"); *((BYTE *)(Jump[1]))=(BYTE)(RecompPos - Jump[1] - 1); Map_GPR_32bit(Section,Opcode.rd,TRUE, -1); MoveVariableToX86reg(&BranchCompare,"BranchCompare",Section->MipsRegLo(Opcode.rd)); } } void Compile_R4300i_SPECIAL_DADD (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rt) && Section->IsConst(Opcode.rs)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsReg(Opcode.rd) = Section->Is64Bit(Opcode.rs)?Section->MipsReg(Opcode.rs):(_int64)Section->MipsRegLo_S(Opcode.rs) + Section->Is64Bit(Opcode.rt)?Section->MipsReg(Opcode.rt):(_int64)Section->MipsRegLo_S(Opcode.rt); if (Section->MipsRegLo_S(Opcode.rd) < 0 && Section->MipsRegHi_S(Opcode.rd) == -1){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else if (Section->MipsRegLo_S(Opcode.rd) >= 0 && Section->MipsRegHi_S(Opcode.rd) == 0){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_64; } } else { int source1 = Opcode.rd == Opcode.rt?Opcode.rt:Opcode.rs; int source2 = Opcode.rd == Opcode.rt?Opcode.rs:Opcode.rt; Map_GPR_64bit(Section,Opcode.rd,source1); if (Section->IsConst(source2)) { AddConstToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); AddConstToX86Reg(Section->MipsRegHi(Opcode.rd),Section->MipsRegHi(source2)); } else if (Section->IsMapped(source2)) { int HiReg = Section->Is64Bit(source2)?Section->MipsRegHi(source2):Map_TempReg(Section,x86_Any,source2,TRUE); ProtectGPR(Section,source2); AddX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); AdcX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),HiReg); } else { AddVariableToX86reg(Section->MipsRegLo(Opcode.rd),&GPR[source2].W[0],GPR_NameLo[source2]); AdcVariableToX86reg(Section->MipsRegHi(Opcode.rd),&GPR[source2].W[1],GPR_NameHi[source2]); } } } void Compile_R4300i_SPECIAL_DADDU (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rt) && Section->IsConst(Opcode.rs)) { __int64 ValRs = Section->Is64Bit(Opcode.rs)?Section->MipsReg(Opcode.rs):(_int64)Section->MipsRegLo_S(Opcode.rs); __int64 ValRt = Section->Is64Bit(Opcode.rt)?Section->MipsReg(Opcode.rt):(_int64)Section->MipsRegLo_S(Opcode.rt); if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsReg(Opcode.rd) = ValRs + ValRt; if ((Section->MipsRegHi(Opcode.rd) == 0) && (Section->MipsRegLo(Opcode.rd) & 0x80000000) == 0) { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else if ((Section->MipsRegHi(Opcode.rd) == 0xFFFFFFFF) && (Section->MipsRegLo(Opcode.rd) & 0x80000000) != 0) { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_64; } } else { int source1 = Opcode.rd == Opcode.rt?Opcode.rt:Opcode.rs; int source2 = Opcode.rd == Opcode.rt?Opcode.rs:Opcode.rt; Map_GPR_64bit(Section,Opcode.rd,source1); if (Section->IsConst(source2)) { AddConstToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); AddConstToX86Reg(Section->MipsRegHi(Opcode.rd),Section->MipsRegHi(source2)); } else if (Section->IsMapped(source2)) { int HiReg = Section->Is64Bit(source2)?Section->MipsRegHi(source2):Map_TempReg(Section,x86_Any,source2,TRUE); ProtectGPR(Section,source2); AddX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(source2)); AdcX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),HiReg); } else { AddVariableToX86reg(Section->MipsRegLo(Opcode.rd),&GPR[source2].W[0],GPR_NameLo[source2]); AdcVariableToX86reg(Section->MipsRegHi(Opcode.rd),&GPR[source2].W[1],GPR_NameHi[source2]); } } } void Compile_R4300i_SPECIAL_DSUB (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rt) && Section->IsConst(Opcode.rs)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsReg(Opcode.rd) = Section->Is64Bit(Opcode.rs)?Section->MipsReg(Opcode.rs):(_int64)Section->MipsRegLo_S(Opcode.rs) - Section->Is64Bit(Opcode.rt)?Section->MipsReg(Opcode.rt):(_int64)Section->MipsRegLo_S(Opcode.rt); if (Section->MipsRegLo_S(Opcode.rd) < 0 && Section->MipsRegHi_S(Opcode.rd) == -1){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else if (Section->MipsRegLo_S(Opcode.rd) >= 0 && Section->MipsRegHi_S(Opcode.rd) == 0){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_64; } } else { if (Opcode.rd == Opcode.rt) { int HiReg = Map_TempReg(Section,x86_Any,Opcode.rt,TRUE); int LoReg = Map_TempReg(Section,x86_Any,Opcode.rt,FALSE); Map_GPR_64bit(Section,Opcode.rd,Opcode.rs); SubX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),LoReg); SbbX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),HiReg); return; } Map_GPR_64bit(Section,Opcode.rd,Opcode.rs); if (Section->IsConst(Opcode.rt)) { SubConstFromX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rt)); SbbConstFromX86Reg(Section->MipsRegHi(Opcode.rd),Section->MipsRegHi(Opcode.rt)); } else if (Section->IsMapped(Opcode.rt)) { int HiReg = Section->Is64Bit(Opcode.rt)?Section->MipsRegHi(Opcode.rt):Map_TempReg(Section,x86_Any,Opcode.rt,TRUE); ProtectGPR(Section,Opcode.rt); SubX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rt)); SbbX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),HiReg); } else { SubVariableFromX86reg(Section->MipsRegLo(Opcode.rd),&GPR[Opcode.rt].W[0],GPR_NameLo[Opcode.rt]); SbbVariableFromX86reg(Section->MipsRegHi(Opcode.rd),&GPR[Opcode.rt].W[1],GPR_NameHi[Opcode.rt]); } } } void Compile_R4300i_SPECIAL_DSUBU (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rt) && Section->IsConst(Opcode.rs)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsReg(Opcode.rd) = Section->Is64Bit(Opcode.rs)?Section->MipsReg(Opcode.rs):(_int64)Section->MipsRegLo_S(Opcode.rs) - Section->Is64Bit(Opcode.rt)?Section->MipsReg(Opcode.rt):(_int64)Section->MipsRegLo_S(Opcode.rt); if (Section->MipsRegLo_S(Opcode.rd) < 0 && Section->MipsRegHi_S(Opcode.rd) == -1){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else if (Section->MipsRegLo_S(Opcode.rd) >= 0 && Section->MipsRegHi_S(Opcode.rd) == 0){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_64; } } else { if (Opcode.rd == Opcode.rt) { int HiReg = Map_TempReg(Section,x86_Any,Opcode.rt,TRUE); int LoReg = Map_TempReg(Section,x86_Any,Opcode.rt,FALSE); Map_GPR_64bit(Section,Opcode.rd,Opcode.rs); SubX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),LoReg); SbbX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),HiReg); return; } Map_GPR_64bit(Section,Opcode.rd,Opcode.rs); if (Section->IsConst(Opcode.rt)) { SubConstFromX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rt)); SbbConstFromX86Reg(Section->MipsRegHi(Opcode.rd),Section->MipsRegHi(Opcode.rt)); } else if (Section->IsMapped(Opcode.rt)) { int HiReg = Section->Is64Bit(Opcode.rt)?Section->MipsRegHi(Opcode.rt):Map_TempReg(Section,x86_Any,Opcode.rt,TRUE); ProtectGPR(Section,Opcode.rt); SubX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rt)); SbbX86RegToX86Reg(Section->MipsRegHi(Opcode.rd),HiReg); } else { SubVariableFromX86reg(Section->MipsRegLo(Opcode.rd),&GPR[Opcode.rt].W[0],GPR_NameLo[Opcode.rt]); SbbVariableFromX86reg(Section->MipsRegHi(Opcode.rd),&GPR[Opcode.rt].W[1],GPR_NameHi[Opcode.rt]); } } } void Compile_R4300i_SPECIAL_DSLL (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rt)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsReg(Opcode.rd) = Section->Is64Bit(Opcode.rt)?Section->MipsReg(Opcode.rt):(_int64)Section->MipsRegLo_S(Opcode.rt) << Opcode.sa; if (Section->MipsRegLo_S(Opcode.rd) < 0 && Section->MipsRegHi_S(Opcode.rd) == -1){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else if (Section->MipsRegLo_S(Opcode.rd) >= 0 && Section->MipsRegHi_S(Opcode.rd) == 0){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_64; } return; } Map_GPR_64bit(Section,Opcode.rd,Opcode.rt); ShiftLeftDoubleImmed(Section->MipsRegHi(Opcode.rd),Section->MipsRegLo(Opcode.rd),(BYTE)Opcode.sa); ShiftLeftSignImmed( Section->MipsRegLo(Opcode.rd),(BYTE)Opcode.sa); } void Compile_R4300i_SPECIAL_DSRL (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rt)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsReg(Opcode.rd) = Section->Is64Bit(Opcode.rt)?Section->MipsReg(Opcode.rt):(QWORD)Section->MipsRegLo_S(Opcode.rt) >> Opcode.sa; if (Section->MipsRegLo_S(Opcode.rd) < 0 && Section->MipsRegHi_S(Opcode.rd) == -1){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else if (Section->MipsRegLo_S(Opcode.rd) >= 0 && Section->MipsRegHi_S(Opcode.rd) == 0){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_64; } return; } Map_GPR_64bit(Section,Opcode.rd,Opcode.rt); ShiftRightDoubleImmed(Section->MipsRegLo(Opcode.rd),Section->MipsRegHi(Opcode.rd),(BYTE)Opcode.sa); ShiftRightUnsignImmed(Section->MipsRegHi(Opcode.rd),(BYTE)Opcode.sa); } void Compile_R4300i_SPECIAL_DSRA (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rt)) { if (Section->IsMapped(Opcode.rd)) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsReg_S(Opcode.rd) = Section->Is64Bit(Opcode.rt)?Section->MipsReg_S(Opcode.rt):(_int64)Section->MipsRegLo_S(Opcode.rt) >> Opcode.sa; if (Section->MipsRegLo_S(Opcode.rd) < 0 && Section->MipsRegHi_S(Opcode.rd) == -1){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else if (Section->MipsRegLo_S(Opcode.rd) >= 0 && Section->MipsRegHi_S(Opcode.rd) == 0){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_64; } return; } Map_GPR_64bit(Section,Opcode.rd,Opcode.rt); ShiftRightDoubleImmed(Section->MipsRegLo(Opcode.rd),Section->MipsRegHi(Opcode.rd),(BYTE)Opcode.sa); ShiftRightSignImmed(Section->MipsRegHi(Opcode.rd),(BYTE)Opcode.sa); } void Compile_R4300i_SPECIAL_DSLL32 (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Opcode.rd == 0) { return; } if (Section->IsConst(Opcode.rt)) { if (Opcode.rt != Opcode.rd) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegHi(Opcode.rd) = Section->MipsRegLo(Opcode.rt) << Opcode.sa; Section->MipsRegLo(Opcode.rd) = 0; if (Section->MipsRegLo_S(Opcode.rd) < 0 && Section->MipsRegHi_S(Opcode.rd) == -1){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else if (Section->MipsRegLo_S(Opcode.rd) >= 0 && Section->MipsRegHi_S(Opcode.rd) == 0){ Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; } else { Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_64; } } else if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); Map_GPR_64bit(Section,Opcode.rd,-1); if (Opcode.rt != Opcode.rd) { MoveX86RegToX86Reg(Section->MipsRegLo(Opcode.rt),Section->MipsRegHi(Opcode.rd)); } else { int HiReg = Section->MipsRegHi(Opcode.rt); Section->MipsRegHi(Opcode.rt) = Section->MipsRegLo(Opcode.rt); Section->MipsRegLo(Opcode.rt) = HiReg; } if ((BYTE)Opcode.sa != 0) { ShiftLeftSignImmed(Section->MipsRegHi(Opcode.rd),(BYTE)Opcode.sa); } XorX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rd)); } else { Map_GPR_64bit(Section,Opcode.rd,-1); MoveVariableToX86reg(&GPR[Opcode.rt],GPR_NameHi[Opcode.rt],Section->MipsRegHi(Opcode.rd)); if ((BYTE)Opcode.sa != 0) { ShiftLeftSignImmed(Section->MipsRegHi(Opcode.rd),(BYTE)Opcode.sa); } XorX86RegToX86Reg(Section->MipsRegLo(Opcode.rd),Section->MipsRegLo(Opcode.rd)); } } void Compile_R4300i_SPECIAL_DSRL32 (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsConst(Opcode.rt)) { if (Opcode.rt != Opcode.rd) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; Section->MipsRegLo(Opcode.rd) = (DWORD)(Section->MipsReg(Opcode.rt) >> (Opcode.sa + 32)); } else if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); if (Section->Is64Bit(Opcode.rt)) { if (Opcode.rt == Opcode.rd) { int HiReg = Section->MipsRegHi(Opcode.rt); Section->MipsRegHi(Opcode.rt) = Section->MipsRegLo(Opcode.rt); Section->MipsRegLo(Opcode.rt) = HiReg; Map_GPR_32bit(Section,Opcode.rd,FALSE,-1); } else { Map_GPR_32bit(Section,Opcode.rd,FALSE,-1); MoveX86RegToX86Reg(Section->MipsRegHi(Opcode.rt),Section->MipsRegLo(Opcode.rd)); } if ((BYTE)Opcode.sa != 0) { ShiftRightUnsignImmed(Section->MipsRegLo(Opcode.rd),(BYTE)Opcode.sa); } } else { Compile_R4300i_UnknownOpcode(Section); } } else { Map_GPR_32bit(Section,Opcode.rd,FALSE,-1); MoveVariableToX86reg(&GPR[Opcode.rt].UW[1],GPR_NameLo[Opcode.rt],Section->MipsRegLo(Opcode.rd)); if ((BYTE)Opcode.sa != 0) { ShiftRightUnsignImmed(Section->MipsRegLo(Opcode.rd),(BYTE)Opcode.sa); } } } void Compile_R4300i_SPECIAL_DSRA32 (CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (Section->IsConst(Opcode.rt)) { if (Opcode.rt != Opcode.rd) { UnMap_GPR(Section,Opcode.rd, FALSE); } Section->MipsRegState(Opcode.rd) = CRegInfo::STATE_CONST_32; Section->MipsRegLo(Opcode.rd) = (DWORD)(Section->MipsReg_S(Opcode.rt) >> (Opcode.sa + 32)); } else if (Section->IsMapped(Opcode.rt)) { ProtectGPR(Section,Opcode.rt); if (Section->Is64Bit(Opcode.rt)) { if (Opcode.rt == Opcode.rd) { int HiReg = Section->MipsRegHi(Opcode.rt); Section->MipsRegHi(Opcode.rt) = Section->MipsRegLo(Opcode.rt); Section->MipsRegLo(Opcode.rt) = HiReg; Map_GPR_32bit(Section,Opcode.rd,TRUE,-1); } else { Map_GPR_32bit(Section,Opcode.rd,TRUE,-1); MoveX86RegToX86Reg(Section->MipsRegHi(Opcode.rt),Section->MipsRegLo(Opcode.rd)); } if ((BYTE)Opcode.sa != 0) { ShiftRightSignImmed(Section->MipsRegLo(Opcode.rd),(BYTE)Opcode.sa); } } else { Compile_R4300i_UnknownOpcode(Section); } } else { Map_GPR_32bit(Section,Opcode.rd,TRUE,-1); MoveVariableToX86reg(&GPR[Opcode.rt].UW[1],GPR_NameLo[Opcode.rt],Section->MipsRegLo(Opcode.rd)); if ((BYTE)Opcode.sa != 0) { ShiftRightSignImmed(Section->MipsRegLo(Opcode.rd),(BYTE)Opcode.sa); } } } /************************** COP0 functions **************************/ void Compile_R4300i_COP0_MF(CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); switch (Opcode.rd) { case 9: //Count g_N64System->GetRecompiler()->UpdateCounters(&Section->BlockCycleCount(),&Section->BlockRandomModifier(),FALSE); Section->BlockCycleCount() = 0; Section->BlockRandomModifier() = 0; } Map_GPR_32bit(Section,Opcode.rt,TRUE,-1); MoveVariableToX86reg(&CP0[Opcode.rd],Cop0_Name[Opcode.rd],Section->MipsRegLo(Opcode.rt)); } void Compile_R4300i_COP0_MT (CBlockSection * Section) { int OldStatusReg; BYTE *Jump; CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); switch (Opcode.rd) { case 0: //Index case 2: //EntryLo0 case 3: //EntryLo1 case 4: //Context case 5: //PageMask case 10: //Entry Hi case 11: //Compare case 14: //EPC case 16: //Config case 18: //WatchLo case 19: //WatchHi case 28: //Tag lo case 29: //Tag Hi case 30: //ErrEPC if (Section->IsConst(Opcode.rt)) { MoveConstToVariable(Section->MipsRegLo(Opcode.rt), &CP0[Opcode.rd], Cop0_Name[Opcode.rd]); } else if (Section->IsMapped(Opcode.rt)) { MoveX86regToVariable(Section->MipsRegLo(Opcode.rt), &CP0[Opcode.rd], Cop0_Name[Opcode.rd]); } else { MoveX86regToVariable(Map_TempReg(Section,x86_Any,Opcode.rt,FALSE), &CP0[Opcode.rd], Cop0_Name[Opcode.rd]); } switch (Opcode.rd) { case 4: //Context AndConstToVariable(0xFF800000,&CP0[Opcode.rd], Cop0_Name[Opcode.rd]); break; case 11: //Compare g_N64System->GetRecompiler()->UpdateCounters(&Section->BlockCycleCount(),&Section->BlockRandomModifier(),FALSE); Section->BlockCycleCount() = 0; Section->BlockRandomModifier() = 0; AndConstToVariable(~CAUSE_IP7,&FAKE_CAUSE_REGISTER,"FAKE_CAUSE_REGISTER"); Pushad(); Call_Direct(ChangeCompareTimer,"ChangeCompareTimer"); Popad(); } break; case 9: //Count g_N64System->GetRecompiler()->UpdateCounters(&Section->BlockCycleCount(),&Section->BlockRandomModifier(),FALSE); Section->BlockCycleCount() = 0; Section->BlockRandomModifier() = 0; if (Section->IsConst(Opcode.rt)) { MoveConstToVariable(Section->MipsRegLo(Opcode.rt), &CP0[Opcode.rd], Cop0_Name[Opcode.rd]); } else if (Section->IsMapped(Opcode.rt)) { MoveX86regToVariable(Section->MipsRegLo(Opcode.rt), &CP0[Opcode.rd], Cop0_Name[Opcode.rd]); } else { MoveX86regToVariable(Map_TempReg(Section,x86_Any,Opcode.rt,FALSE), &CP0[Opcode.rd], Cop0_Name[Opcode.rd]); } Pushad(); Call_Direct(ChangeCompareTimer,"ChangeCompareTimer"); Popad(); break; case 12: //Status OldStatusReg = Map_TempReg(Section,x86_Any,-1,FALSE); MoveVariableToX86reg(&CP0[Opcode.rd],Cop0_Name[Opcode.rd],OldStatusReg); if (Section->IsConst(Opcode.rt)) { MoveConstToVariable(Section->MipsRegLo(Opcode.rt), &CP0[Opcode.rd], Cop0_Name[Opcode.rd]); } else if (Section->IsMapped(Opcode.rt)) { MoveX86regToVariable(Section->MipsRegLo(Opcode.rt), &CP0[Opcode.rd], Cop0_Name[Opcode.rd]); } else { MoveX86regToVariable(Map_TempReg(Section,x86_Any,Opcode.rt,FALSE), &CP0[Opcode.rd], Cop0_Name[Opcode.rd]); } XorVariableToX86reg(&CP0[Opcode.rd], Cop0_Name[Opcode.rd],OldStatusReg); TestConstToX86Reg(STATUS_FR,OldStatusReg); JeLabel8("FpuFlagFine",0); Jump = RecompPos - 1; Pushad(); Call_Direct(SetFpuLocations,"SetFpuLocations"); Popad(); *(BYTE *)(Jump)= (BYTE )(((BYTE )(RecompPos)) - (((BYTE )(Jump)) + 1)); //TestConstToX86Reg(STATUS_FR,OldStatusReg); //BreakPoint(__FILE__,__LINE__); //g_N64System->GetRecompiler()->CompileExit (Section,Section->CompilePC+4,Section->RegWorking,ExitResetRecompCode,FALSE,JneLabel32); Pushad(); Call_Direct(CheckInterrupts,"CheckInterrupts"); Popad(); break; case 6: //Wired Pushad(); g_N64System->GetRecompiler()->UpdateCounters(&Section->BlockCycleCount(),&Section->BlockRandomModifier(),FALSE); Section->BlockCycleCount() = 0; Section->BlockRandomModifier() = 0; Call_Direct(FixRandomReg,"FixRandomReg"); Popad(); if (Section->IsConst(Opcode.rt)) { MoveConstToVariable(Section->MipsRegLo(Opcode.rt), &CP0[Opcode.rd], Cop0_Name[Opcode.rd]); } else if (Section->IsMapped(Opcode.rt)) { MoveX86regToVariable(Section->MipsRegLo(Opcode.rt), &CP0[Opcode.rd], Cop0_Name[Opcode.rd]); } else { MoveX86regToVariable(Map_TempReg(Section,x86_Any,Opcode.rt,FALSE), &CP0[Opcode.rd], Cop0_Name[Opcode.rd]); } break; case 13: //cause if (Section->IsConst(Opcode.rt)) { AndConstToVariable(0xFFFFCFF,&CP0[Opcode.rd], Cop0_Name[Opcode.rd]); #ifndef EXTERNAL_RELEASE if ((Section->MipsRegLo(Opcode.rt) & 0x300) != 0 ){ DisplayError("Set IP0 or IP1"); } #endif } else { Compile_R4300i_UnknownOpcode(Section); } Pushad(); Call_Direct(CheckInterrupts,"CheckInterrupts"); Popad(); break; default: Compile_R4300i_UnknownOpcode(Section); } } /************************** COP0 CO functions ***********************/ void Compile_R4300i_COP0_CO_TLBR( CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (!UseTlb) { return; } Pushad(); Call_Direct(TLB_ReadEntry,"TLB_ReadEntry"); Popad(); } void Compile_R4300i_COP0_CO_TLBWI( CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (!UseTlb) { return; } Pushad(); PushImm32("FALSE",FALSE); MoveVariableToX86reg(&INDEX_REGISTER,"INDEX_REGISTER",x86_ECX); AndConstToX86Reg(x86_ECX,0x1F); Push(x86_ECX); Call_Direct(TLB_WriteEntry,"TLB_WriteEntry"); AddConstToX86Reg(x86_ESP,8); Popad(); } void Compile_R4300i_COP0_CO_TLBWR( CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (!UseTlb) { return; } g_N64System->GetRecompiler()->UpdateCounters(&Section->BlockCycleCount(),&Section->BlockRandomModifier(),FALSE); Section->BlockCycleCount() = 0; Section->BlockRandomModifier() = 0; Pushad(); Call_Direct(FixRandomReg,"FixRandomReg"); PushImm32("TRUE",TRUE); MoveVariableToX86reg(&RANDOM_REGISTER,"RANDOM_REGISTER",x86_ECX); AndConstToX86Reg(x86_ECX,0x1F); Push(x86_ECX); Call_Direct(TLB_WriteEntry,"TLB_WriteEntry"); AddConstToX86Reg(x86_ESP,8); Popad(); } void Compile_R4300i_COP0_CO_TLBP( CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); if (!UseTlb) { return; } Pushad(); Call_Direct(TLB_Probe,"TLB_Probe"); Popad(); } void compiler_COP0_CO_ERET (void) { if ((STATUS_REGISTER & STATUS_ERL) != 0) { PROGRAM_COUNTER = ERROREPC_REGISTER; STATUS_REGISTER &= ~STATUS_ERL; } else { PROGRAM_COUNTER = EPC_REGISTER; STATUS_REGISTER &= ~STATUS_EXL; } LLBit = 0; CheckInterrupts(); } void Compile_R4300i_COP0_CO_ERET( CBlockSection * Section) { CPU_Message(" %X %s",Section->CompilePC,R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); WriteBackRegisters(Section); Call_Direct(compiler_COP0_CO_ERET,"compiler_COP0_CO_ERET"); g_N64System->GetRecompiler()->CompileExit (Section,Section->CompilePC, (DWORD)-1,Section->RegWorking,CExitInfo::Normal,TRUE,NULL); NextInstruction = END_BLOCK; } /************************** Other functions **************************/ void Compile_R4300i_UnknownOpcode (CBlockSection * Section) { CPU_Message(" %X Unhandled Opcode: %s",Section->CompilePC, R4300iOpcodeName(Opcode.Hex,Section->CompilePC)); // FreeSection(Section->ContinueSection,Section); // FreeSection(Section->JumpSection,Section); Section->BlockCycleCount() -= CountPerOp; Section->BlockRandomModifier() -= 1; MoveConstToVariable(Section->CompilePC,&PROGRAM_COUNTER,"PROGRAM_COUNTER"); WriteBackRegisters(Section); g_N64System->GetRecompiler()->UpdateCounters(&Section->BlockCycleCount(),&Section->BlockRandomModifier(),FALSE); if (CPU_Type == CPU_SyncCores) { Call_Direct(SyncToPC, "SyncToPC"); } MoveConstToVariable(Opcode.Hex,&Opcode.Hex,"Opcode.Hex"); Call_Direct(R4300i_UnknownOpcode, "R4300i_UnknownOpcode"); Ret(); if (NextInstruction == NORMAL) { NextInstruction = END_BLOCK; } }