1435 lines
50 KiB
C++
1435 lines
50 KiB
C++
/*
|
|
* 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 <windows.h>
|
|
#include <stdio.h>
|
|
#include "c core.h"
|
|
#include "main.h"
|
|
#include "cpu.h"
|
|
#include "x86.h"
|
|
#include "debugger.h"
|
|
|
|
char *GPR_Name[32] = {"r0","at","v0","v1","a0","a1","a2","a3",
|
|
"t0","t1","t2","t3","t4","t5","t6","t7",
|
|
"s0","s1","s2","s3","s4","s5","s6","s7",
|
|
"t8","t9","k0","k1","gp","sp","s8","ra"};
|
|
|
|
char *GPR_NameHi[32] = {"r0.HI","at.HI","v0.HI","v1.HI","a0.HI","a1.HI",
|
|
"a2.HI","a3.HI","t0.HI","t1.HI","t2.HI","t3.HI",
|
|
"t4.HI","t5.HI","t6.HI","t7.HI","s0.HI","s1.HI",
|
|
"s2.HI","s3.HI","s4.HI","s5.HI","s6.HI","s7.HI",
|
|
"t8.HI","t9.HI","k0.HI","k1.HI","gp.HI","sp.HI",
|
|
"s8.HI","ra.HI"};
|
|
|
|
char *GPR_NameLo[32] = {"r0.LO","at.LO","v0.LO","v1.LO","a0.LO","a1.LO",
|
|
"a2.LO","a3.LO","t0.LO","t1.LO","t2.LO","t3.LO",
|
|
"t4.LO","t5.LO","t6.LO","t7.LO","s0.LO","s1.LO",
|
|
"s2.LO","s3.LO","s4.LO","s5.LO","s6.LO","s7.LO",
|
|
"t8.LO","t9.LO","k0.LO","k1.LO","gp.LO","sp.LO",
|
|
"s8.LO","ra.LO"};
|
|
|
|
char *FPR_Name[32] = {"f0","f1","f2","f3","f4","f5","f6","f7",
|
|
"f8","f9","f10","f11","f12","f13","f14","f15",
|
|
"f16","f17","f18","f19","f20","f21","f22","f23",
|
|
"f24","f25","f26","f27","f28","f29","f30","f31"};
|
|
|
|
char *FPR_NameHi[32] = {"f0.hi","f1.hi","f2.hi","f3.hi","f4.hi","f5.hi","f6.hi","f7.hi",
|
|
"f8.hi","f9.hi","f10.hi","f11.hi","f12.hi","f13.hi","f14.hi","f15.hi",
|
|
"f16.hi","f17.hi","f18.hi","f19.hi","f20.hi","f21.hi","f22.hi","f23.hi",
|
|
"f24.hi","f25.hi","f26.hi","f27.hi","f28.hi","f29.hi","f30.hi","f31.hi"};
|
|
|
|
char *FPR_NameLo[32] = {"f0.lo","f1.lo","f2.lo","f3.lo","f4.lo","f5.lo","f6.lo","f7.lo",
|
|
"f8.lo","f9.lo","f10.lo","f11.lo","f12.lo","f13.lo","f14.lo","f15.lo",
|
|
"f16.lo","f17.lo","f18.lo","f19.lo","f20.lo","f21.lo","f22.lo","f23.lo",
|
|
"f24.lo","f25.lo","f26.lo","f27.lo","f28.lo","f29.lo","f30.lo","f31.lo"};
|
|
|
|
char *FPR_Ctrl_Name[32] = {"Revision","Unknown","Unknown","Unknown","Unknown",
|
|
"Unknown","Unknown","Unknown","Unknown","Unknown","Unknown",
|
|
"Unknown","Unknown","Unknown","Unknown","Unknown","Unknown",
|
|
"Unknown","Unknown","Unknown","Unknown","Unknown","Unknown",
|
|
"Unknown","Unknown","Unknown","Unknown","Unknown","Unknown",
|
|
"Unknown","Unknown","FCSR"};
|
|
|
|
DWORD RegModValue;
|
|
//DWORD RegModValue, ViFieldNumber, LLBit, LLAddr;
|
|
//N64_REGISTERS Registers;
|
|
int fpuControl;
|
|
|
|
|
|
int UnMap_8BitTempReg (CBlockSection * Section);
|
|
int UnMap_TempReg (CBlockSection * Section);
|
|
BOOL UnMap_X86reg (CBlockSection * Section, DWORD x86Reg);
|
|
|
|
char *Format_Name[] = {"Unkown","dword","qword","float","double"};
|
|
|
|
void ChangeFPURegFormat (CBlockSection * Section, int Reg, CRegInfo::FPU_STATE OldFormat, CRegInfo::FPU_STATE NewFormat, CRegInfo::FPU_ROUND RoundingModel) {
|
|
DWORD i;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
if (Section->FpuMappedTo(i) == (DWORD)Reg) {
|
|
if (Section->FpuState(i) != OldFormat) {
|
|
UnMap_FPR(Section,Reg,TRUE);
|
|
Load_FPR_ToTop(Section,Reg,Reg,OldFormat);
|
|
ChangeFPURegFormat(Section,Reg,OldFormat,NewFormat,RoundingModel);
|
|
return;
|
|
}
|
|
CPU_Message(" regcache: Changed format of ST(%d) from %s to %s",
|
|
(i - Section->StackTopPos() + 8) & 7,Format_Name[OldFormat],Format_Name[NewFormat]);
|
|
Section->FpuRoundingModel(i) = RoundingModel;
|
|
Section->FpuState(i) = NewFormat;
|
|
return;
|
|
}
|
|
}
|
|
|
|
#ifndef EXTERNAL_RELEASE
|
|
DisplayError("ChangeFormat: Register not on stack!!");
|
|
#endif
|
|
}
|
|
|
|
void ChangeMiIntrMask (void) {
|
|
if ( ( RegModValue & MI_INTR_MASK_CLR_SP ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_SP; }
|
|
if ( ( RegModValue & MI_INTR_MASK_SET_SP ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_SP; }
|
|
if ( ( RegModValue & MI_INTR_MASK_CLR_SI ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_SI; }
|
|
if ( ( RegModValue & MI_INTR_MASK_SET_SI ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_SI; }
|
|
if ( ( RegModValue & MI_INTR_MASK_CLR_AI ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_AI; }
|
|
if ( ( RegModValue & MI_INTR_MASK_SET_AI ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_AI; }
|
|
if ( ( RegModValue & MI_INTR_MASK_CLR_VI ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_VI; }
|
|
if ( ( RegModValue & MI_INTR_MASK_SET_VI ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_VI; }
|
|
if ( ( RegModValue & MI_INTR_MASK_CLR_PI ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_PI; }
|
|
if ( ( RegModValue & MI_INTR_MASK_SET_PI ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_PI; }
|
|
if ( ( RegModValue & MI_INTR_MASK_CLR_DP ) != 0 ) { MI_INTR_MASK_REG &= ~MI_INTR_MASK_DP; }
|
|
if ( ( RegModValue & MI_INTR_MASK_SET_DP ) != 0 ) { MI_INTR_MASK_REG |= MI_INTR_MASK_DP; }
|
|
}
|
|
|
|
void ChangeMiModeReg (void) {
|
|
MI_MODE_REG &= ~0x7F;
|
|
MI_MODE_REG |= (RegModValue & 0x7F);
|
|
if ( ( RegModValue & MI_CLR_INIT ) != 0 ) { MI_MODE_REG &= ~MI_MODE_INIT; }
|
|
if ( ( RegModValue & MI_SET_INIT ) != 0 ) { MI_MODE_REG |= MI_MODE_INIT; }
|
|
if ( ( RegModValue & MI_CLR_EBUS ) != 0 ) { MI_MODE_REG &= ~MI_MODE_EBUS; }
|
|
if ( ( RegModValue & MI_SET_EBUS ) != 0 ) { MI_MODE_REG |= MI_MODE_EBUS; }
|
|
if ( ( RegModValue & MI_CLR_DP_INTR ) != 0 ) { MI_INTR_REG &= ~MI_INTR_DP; }
|
|
if ( ( RegModValue & MI_CLR_RDRAM ) != 0 ) { MI_MODE_REG &= ~MI_MODE_RDRAM; }
|
|
if ( ( RegModValue & MI_SET_RDRAM ) != 0 ) { MI_MODE_REG |= MI_MODE_RDRAM; }
|
|
}
|
|
|
|
void ChangeSpStatus (void) {
|
|
if ( ( RegModValue & SP_CLR_HALT ) != 0) { SP_STATUS_REG &= ~SP_STATUS_HALT; }
|
|
if ( ( RegModValue & SP_SET_HALT ) != 0) { SP_STATUS_REG |= SP_STATUS_HALT; }
|
|
if ( ( RegModValue & SP_CLR_BROKE ) != 0) { SP_STATUS_REG &= ~SP_STATUS_BROKE; }
|
|
if ( ( RegModValue & SP_CLR_INTR ) != 0) {
|
|
MI_INTR_REG &= ~MI_INTR_SP;
|
|
CheckInterrupts();
|
|
}
|
|
#ifndef EXTERNAL_RELEASE
|
|
if ( ( RegModValue & SP_SET_INTR ) != 0) { DisplayError("SP_SET_INTR"); }
|
|
#endif
|
|
if ( ( RegModValue & SP_CLR_SSTEP ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SSTEP; }
|
|
if ( ( RegModValue & SP_SET_SSTEP ) != 0) { SP_STATUS_REG |= SP_STATUS_SSTEP; }
|
|
if ( ( RegModValue & SP_CLR_INTR_BREAK ) != 0) { SP_STATUS_REG &= ~SP_STATUS_INTR_BREAK; }
|
|
if ( ( RegModValue & SP_SET_INTR_BREAK ) != 0) { SP_STATUS_REG |= SP_STATUS_INTR_BREAK; }
|
|
if ( ( RegModValue & SP_CLR_SIG0 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG0; }
|
|
if ( ( RegModValue & SP_SET_SIG0 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG0; }
|
|
if ( ( RegModValue & SP_CLR_SIG1 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG1; }
|
|
if ( ( RegModValue & SP_SET_SIG1 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG1; }
|
|
if ( ( RegModValue & SP_CLR_SIG2 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG2; }
|
|
if ( ( RegModValue & SP_SET_SIG2 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG2; }
|
|
if ( ( RegModValue & SP_CLR_SIG3 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG3; }
|
|
if ( ( RegModValue & SP_SET_SIG3 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG3; }
|
|
if ( ( RegModValue & SP_CLR_SIG4 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG4; }
|
|
if ( ( RegModValue & SP_SET_SIG4 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG4; }
|
|
if ( ( RegModValue & SP_CLR_SIG5 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG5; }
|
|
if ( ( RegModValue & SP_SET_SIG5 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG5; }
|
|
if ( ( RegModValue & SP_CLR_SIG6 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG6; }
|
|
if ( ( RegModValue & SP_SET_SIG6 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG6; }
|
|
if ( ( RegModValue & SP_CLR_SIG7 ) != 0) { SP_STATUS_REG &= ~SP_STATUS_SIG7; }
|
|
if ( ( RegModValue & SP_SET_SIG7 ) != 0) { SP_STATUS_REG |= SP_STATUS_SIG7; }
|
|
|
|
if ( ( RegModValue & SP_SET_SIG0 ) != 0 && AudioSignal)
|
|
{
|
|
MI_INTR_REG |= MI_INTR_SP;
|
|
CheckInterrupts();
|
|
}
|
|
//if (*( DWORD *)(DMEM + 0xFC0) == 1) {
|
|
// ChangeTimer(RspTimer,0x40000);
|
|
//} else {
|
|
RunRsp();
|
|
//}
|
|
}
|
|
|
|
int Free8BitX86Reg (CBlockSection * Section) {
|
|
int x86Reg, count, MapCount[10], MapReg[10];
|
|
|
|
if (Section->x86Mapped(x86_EBX) == CRegInfo::NotMapped && !Section->x86Protected(x86_EBX)) {return x86_EBX; }
|
|
if (Section->x86Mapped(x86_EAX) == CRegInfo::NotMapped && !Section->x86Protected(x86_EAX)) {return x86_EAX; }
|
|
if (Section->x86Mapped(x86_EDX) == CRegInfo::NotMapped && !Section->x86Protected(x86_EDX)) {return x86_EDX; }
|
|
if (Section->x86Mapped(x86_ECX) == CRegInfo::NotMapped && !Section->x86Protected(x86_ECX)) {return x86_ECX; }
|
|
|
|
x86Reg = UnMap_8BitTempReg(Section);
|
|
if (x86Reg > 0) { return x86Reg; }
|
|
|
|
for (count = 0; count < 10; count ++) {
|
|
MapCount[count] = Section->x86MapOrder(count);
|
|
MapReg[count] = count;
|
|
}
|
|
for (count = 0; count < 10; count ++) {
|
|
int i;
|
|
|
|
for (i = 0; i < 9; i ++) {
|
|
int temp;
|
|
|
|
if (MapCount[i] < MapCount[i+1]) {
|
|
temp = MapCount[i];
|
|
MapCount[i] = MapCount[i+1];
|
|
MapCount[i+1] = temp;
|
|
temp = MapReg[i];
|
|
MapReg[i] = MapReg[i+1];
|
|
MapReg[i+1] = temp;
|
|
}
|
|
}
|
|
|
|
}
|
|
for (count = 0; count < 10; count ++) {
|
|
if (MapCount[count] > 0) {
|
|
if (!Is8BitReg(count)) { continue; }
|
|
if (UnMap_X86reg(Section,count)) {
|
|
return count;
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int FreeX86Reg (CBlockSection * Section) {
|
|
int x86Reg, count, MapCount[10], MapReg[10], StackReg;
|
|
|
|
if (Section->x86Mapped(x86_EDI) == CRegInfo::NotMapped && !Section->x86Protected(x86_EDI)) {return x86_EDI; }
|
|
if (Section->x86Mapped(x86_ESI) == CRegInfo::NotMapped && !Section->x86Protected(x86_ESI)) {return x86_ESI; }
|
|
if (Section->x86Mapped(x86_EBX) == CRegInfo::NotMapped && !Section->x86Protected(x86_EBX)) {return x86_EBX; }
|
|
if (Section->x86Mapped(x86_EAX) == CRegInfo::NotMapped && !Section->x86Protected(x86_EAX)) {return x86_EAX; }
|
|
if (Section->x86Mapped(x86_EDX) == CRegInfo::NotMapped && !Section->x86Protected(x86_EDX)) {return x86_EDX; }
|
|
if (Section->x86Mapped(x86_ECX) == CRegInfo::NotMapped && !Section->x86Protected(x86_ECX)) {return x86_ECX; }
|
|
|
|
x86Reg = UnMap_TempReg(Section);
|
|
if (x86Reg > 0) { return x86Reg; }
|
|
|
|
for (count = 0; count < 10; count ++) {
|
|
MapCount[count] = Section->x86MapOrder(count);
|
|
MapReg[count] = count;
|
|
}
|
|
for (count = 0; count < 10; count ++) {
|
|
int i;
|
|
|
|
for (i = 0; i < 9; i ++) {
|
|
int temp;
|
|
|
|
if (MapCount[i] < MapCount[i+1]) {
|
|
temp = MapCount[i];
|
|
MapCount[i] = MapCount[i+1];
|
|
MapCount[i+1] = temp;
|
|
temp = MapReg[i];
|
|
MapReg[i] = MapReg[i+1];
|
|
MapReg[i+1] = temp;
|
|
}
|
|
}
|
|
|
|
}
|
|
StackReg = -1;
|
|
for (count = 0; count < 10; count ++) {
|
|
if (MapCount[count] > 0 && Section->x86Mapped(MapReg[count]) != CRegInfo::Stack_Mapped) {
|
|
if (UnMap_X86reg(Section,MapReg[count])) {
|
|
return MapReg[count];
|
|
}
|
|
}
|
|
if (Section->x86Mapped(MapReg[count]) == CRegInfo::Stack_Mapped) { StackReg = MapReg[count]; }
|
|
}
|
|
if (StackReg > 0) {
|
|
UnMap_X86reg(Section,StackReg);
|
|
return StackReg;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
#ifdef ggg
|
|
void InitalizeR4300iRegisters (int UsePif, int Country, int CIC_Chip) {
|
|
memset(CP0,0,sizeof(Registers.CP0));
|
|
memset(FPCR,0,sizeof(Registers.FPCR));
|
|
memset(RegRDRAM,0,sizeof(Registers.RDRAM));
|
|
memset(RegSP,0,sizeof(Registers.SP));
|
|
memset(RegDPC,0,sizeof(Registers.DPC));
|
|
memset(RegMI,0,sizeof(Registers.MI));
|
|
memset(RegVI,0,sizeof(Registers.VI));
|
|
memset(RegAI,0,sizeof(Registers.AI));
|
|
memset(RegPI,0,sizeof(Registers.PI));
|
|
memset(RegRI,0,sizeof(Registers.RI));
|
|
memset(RegSI,0,sizeof(Registers.SI));
|
|
memset(_GPR,0,sizeof(Registers._GPR));
|
|
memset(FPR,0,sizeof(Registers.FPR));
|
|
|
|
if (CIC_Chip < 0) {
|
|
DisplayError(GS(MSG_UNKNOWN_CIC_CHIP));
|
|
CIC_Chip = 2;
|
|
}
|
|
LO.DW = 0x0;
|
|
HI.DW = 0x0;
|
|
RANDOM_REGISTER = 0x1F;
|
|
COUNT_REGISTER = 0x5000;
|
|
MI_VERSION_REG = 0x02020102;
|
|
SP_STATUS_REG = 0x00000001;
|
|
CAUSE_REGISTER = 0x0000005C;
|
|
//ENTRYHI_REGISTER = 0xFFFFE0FF;
|
|
CONTEXT_REGISTER = 0x007FFFF0;
|
|
EPC_REGISTER = 0xFFFFFFFF;
|
|
BAD_VADDR_REGISTER = 0xFFFFFFFF;
|
|
ERROREPC_REGISTER = 0xFFFFFFFF;
|
|
CONFIG_REGISTER = 0x0006E463;
|
|
REVISION_REGISTER = 0x00000511;
|
|
STATUS_REGISTER = 0x34000000;
|
|
SetFpuLocations();
|
|
if (UsePif) {
|
|
PROGRAM_COUNTER = 0xBFC00000;
|
|
switch (CIC_Chip) {
|
|
case 1:
|
|
PIF_Ram[36] = 0x00;
|
|
PIF_Ram[37] = 0x06;
|
|
PIF_Ram[38] = 0x3F;
|
|
PIF_Ram[39] = 0x3F;
|
|
break;
|
|
case 2:
|
|
PIF_Ram[36] = 0x00;
|
|
PIF_Ram[37] = 0x02;
|
|
PIF_Ram[38] = 0x3F;
|
|
PIF_Ram[39] = 0x3F;
|
|
break;
|
|
case 3:
|
|
PIF_Ram[36] = 0x00;
|
|
PIF_Ram[37] = 0x02;
|
|
PIF_Ram[38] = 0x78;
|
|
PIF_Ram[39] = 0x3F;
|
|
break;
|
|
case 5:
|
|
PIF_Ram[36] = 0x00;
|
|
PIF_Ram[37] = 0x02;
|
|
PIF_Ram[38] = 0x91;
|
|
PIF_Ram[39] = 0x3F;
|
|
break;
|
|
case 6:
|
|
PIF_Ram[36] = 0x00;
|
|
PIF_Ram[37] = 0x02;
|
|
PIF_Ram[38] = 0x85;
|
|
PIF_Ram[39] = 0x3F;
|
|
break;
|
|
}
|
|
} else {
|
|
memcpy( (N64MEM+0x4000040), (ROM + 0x040), 0xFBC);
|
|
PROGRAM_COUNTER = 0xA4000040;
|
|
|
|
_GPR[0].DW=0x0000000000000000;
|
|
_GPR[6].DW=0xFFFFFFFFA4001F0C;
|
|
_GPR[7].DW=0xFFFFFFFFA4001F08;
|
|
_GPR[8].DW=0x00000000000000C0;
|
|
_GPR[9].DW=0x0000000000000000;
|
|
_GPR[10].DW=0x0000000000000040;
|
|
_GPR[11].DW=0xFFFFFFFFA4000040;
|
|
_GPR[16].DW=0x0000000000000000;
|
|
_GPR[17].DW=0x0000000000000000;
|
|
_GPR[18].DW=0x0000000000000000;
|
|
_GPR[19].DW=0x0000000000000000;
|
|
_GPR[21].DW=0x0000000000000000;
|
|
_GPR[26].DW=0x0000000000000000;
|
|
_GPR[27].DW=0x0000000000000000;
|
|
_GPR[28].DW=0x0000000000000000;
|
|
_GPR[29].DW=0xFFFFFFFFA4001FF0;
|
|
_GPR[30].DW=0x0000000000000000;
|
|
|
|
switch (Country) {
|
|
case 0x44: //Germany
|
|
case 0x46: //french
|
|
case 0x49: //Italian
|
|
case 0x50: //Europe
|
|
case 0x53: //Spanish
|
|
case 0x55: //Australia
|
|
case 0x58: // ????
|
|
case 0x59: // X (PAL)
|
|
switch (CIC_Chip) {
|
|
case 2:
|
|
_GPR[5].DW=0xFFFFFFFFC0F1D859;
|
|
_GPR[14].DW=0x000000002DE108EA;
|
|
_GPR[24].DW=0x0000000000000000;
|
|
break;
|
|
case 3:
|
|
_GPR[5].DW=0xFFFFFFFFD4646273;
|
|
_GPR[14].DW=0x000000001AF99984;
|
|
_GPR[24].DW=0x0000000000000000;
|
|
break;
|
|
case 5:
|
|
*(DWORD *)&IMEM[0x04] = 0xBDA807FC;
|
|
_GPR[5].DW=0xFFFFFFFFDECAAAD1;
|
|
_GPR[14].DW=0x000000000CF85C13;
|
|
_GPR[24].DW=0x0000000000000002;
|
|
break;
|
|
case 6:
|
|
_GPR[5].DW=0xFFFFFFFFB04DC903;
|
|
_GPR[14].DW=0x000000001AF99984;
|
|
_GPR[24].DW=0x0000000000000002;
|
|
break;
|
|
}
|
|
|
|
_GPR[20].DW=0x0000000000000000;
|
|
_GPR[23].DW=0x0000000000000006;
|
|
_GPR[31].DW=0xFFFFFFFFA4001554;
|
|
break;
|
|
case 0x37: // 7 (Beta)
|
|
case 0x41: // ????
|
|
case 0x45: //USA
|
|
case 0x4A: //Japan
|
|
default:
|
|
switch (CIC_Chip) {
|
|
case 2:
|
|
_GPR[5].DW=0xFFFFFFFFC95973D5;
|
|
_GPR[14].DW=0x000000002449A366;
|
|
break;
|
|
case 3:
|
|
_GPR[5].DW=0xFFFFFFFF95315A28;
|
|
_GPR[14].DW=0x000000005BACA1DF;
|
|
break;
|
|
case 5:
|
|
*(DWORD *)&IMEM[0x04] = 0x8DA807FC;
|
|
_GPR[5].DW=0x000000005493FB9A;
|
|
_GPR[14].DW=0xFFFFFFFFC2C20384;
|
|
case 6:
|
|
_GPR[5].DW=0xFFFFFFFFE067221F;
|
|
_GPR[14].DW=0x000000005CD2B70F;
|
|
break;
|
|
}
|
|
_GPR[20].DW=0x0000000000000001;
|
|
_GPR[23].DW=0x0000000000000000;
|
|
_GPR[24].DW=0x0000000000000003;
|
|
_GPR[31].DW=0xFFFFFFFFA4001550;
|
|
}
|
|
|
|
switch (CIC_Chip) {
|
|
case 1:
|
|
_GPR[22].DW=0x000000000000003F;
|
|
break;
|
|
case 2:
|
|
_GPR[1].DW=0x0000000000000001;
|
|
_GPR[2].DW=0x000000000EBDA536;
|
|
_GPR[3].DW=0x000000000EBDA536;
|
|
_GPR[4].DW=0x000000000000A536;
|
|
_GPR[12].DW=0xFFFFFFFFED10D0B3;
|
|
_GPR[13].DW=0x000000001402A4CC;
|
|
_GPR[15].DW=0x000000003103E121;
|
|
_GPR[22].DW=0x000000000000003F;
|
|
_GPR[25].DW=0xFFFFFFFF9DEBB54F;
|
|
break;
|
|
case 3:
|
|
_GPR[1].DW=0x0000000000000001;
|
|
_GPR[2].DW=0x0000000049A5EE96;
|
|
_GPR[3].DW=0x0000000049A5EE96;
|
|
_GPR[4].DW=0x000000000000EE96;
|
|
_GPR[12].DW=0xFFFFFFFFCE9DFBF7;
|
|
_GPR[13].DW=0xFFFFFFFFCE9DFBF7;
|
|
_GPR[15].DW=0x0000000018B63D28;
|
|
_GPR[22].DW=0x0000000000000078;
|
|
_GPR[25].DW=0xFFFFFFFF825B21C9;
|
|
break;
|
|
case 5:
|
|
*(DWORD *)&IMEM[0x00] = 0x3C0DBFC0;
|
|
*(DWORD *)&IMEM[0x08] = 0x25AD07C0;
|
|
*(DWORD *)&IMEM[0x0C] = 0x31080080;
|
|
*(DWORD *)&IMEM[0x10] = 0x5500FFFC;
|
|
*(DWORD *)&IMEM[0x14] = 0x3C0DBFC0;
|
|
*(DWORD *)&IMEM[0x18] = 0x8DA80024;
|
|
*(DWORD *)&IMEM[0x1C] = 0x3C0BB000;
|
|
_GPR[1].DW=0x0000000000000000;
|
|
_GPR[2].DW=0xFFFFFFFFF58B0FBF;
|
|
_GPR[3].DW=0xFFFFFFFFF58B0FBF;
|
|
_GPR[4].DW=0x0000000000000FBF;
|
|
_GPR[12].DW=0xFFFFFFFF9651F81E;
|
|
_GPR[13].DW=0x000000002D42AAC5;
|
|
_GPR[15].DW=0x0000000056584D60;
|
|
_GPR[22].DW=0x0000000000000091;
|
|
_GPR[25].DW=0xFFFFFFFFCDCE565F;
|
|
break;
|
|
case 6:
|
|
_GPR[1].DW=0x0000000000000000;
|
|
_GPR[2].DW=0xFFFFFFFFA95930A4;
|
|
_GPR[3].DW=0xFFFFFFFFA95930A4;
|
|
_GPR[4].DW=0x00000000000030A4;
|
|
_GPR[12].DW=0xFFFFFFFFBCB59510;
|
|
_GPR[13].DW=0xFFFFFFFFBCB59510;
|
|
_GPR[15].DW=0x000000007A3C07F4;
|
|
_GPR[22].DW=0x0000000000000085;
|
|
_GPR[25].DW=0x00000000465E3F72;
|
|
break;
|
|
}
|
|
}
|
|
#ifdef Interpreter_StackTest
|
|
StackValue = _GPR[29].W[0];
|
|
#endif
|
|
MemoryStack = (DWORD)(N64MEM+(_GPR[29].W[0] & 0x1FFFFFFF));
|
|
}
|
|
#endif
|
|
|
|
BOOL Is8BitReg (int x86Reg) {
|
|
if (x86Reg == x86_EAX) { return TRUE; }
|
|
if (x86Reg == x86_EBX) { return TRUE; }
|
|
if (x86Reg == x86_ECX) { return TRUE; }
|
|
if (x86Reg == x86_EDX) { return TRUE; }
|
|
return FALSE;
|
|
}
|
|
|
|
void Load_FPR_ToTop (CBlockSection * Section, int Reg, int RegToLoad, CRegInfo::FPU_STATE Format) {
|
|
int i;
|
|
|
|
if (RegToLoad < 0) { DisplayError("Load_FPR_ToTop\nRegToLoad < 0 ???"); return; }
|
|
if (Reg < 0) { DisplayError("Load_FPR_ToTop\nReg < 0 ???"); return; }
|
|
|
|
if (Format == CRegInfo::FPU_Double || Format == CRegInfo::FPU_Qword) {
|
|
UnMap_FPR(Section,Reg + 1,TRUE);
|
|
UnMap_FPR(Section,RegToLoad + 1,TRUE);
|
|
} else {
|
|
if ((Reg & 1) != 0) {
|
|
for (i = 0; i < 8; i++) {
|
|
if (Section->FpuMappedTo(i) == (DWORD)(Reg - 1)) {
|
|
if (Section->FpuState(i) == CRegInfo::FPU_Double || Section->FpuState(i) == CRegInfo::FPU_Qword) {
|
|
UnMap_FPR(Section,Reg,TRUE);
|
|
}
|
|
i = 8;
|
|
}
|
|
}
|
|
}
|
|
if ((RegToLoad & 1) != 0) {
|
|
for (i = 0; i < 8; i++) {
|
|
if (Section->FpuMappedTo(i) == (DWORD)(RegToLoad - 1)) {
|
|
if (Section->FpuState(i) == CRegInfo::FPU_Double || Section->FpuState(i) == CRegInfo::FPU_Qword) {
|
|
UnMap_FPR(Section,RegToLoad,TRUE);
|
|
}
|
|
i = 8;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Reg == RegToLoad) {
|
|
//if different format then unmap original reg from stack
|
|
for (i = 0; i < 8; i++) {
|
|
if (Section->FpuMappedTo(i) == (DWORD)Reg) {
|
|
if (Section->FpuState(i) != (DWORD)Format) {
|
|
UnMap_FPR(Section,Reg,TRUE);
|
|
}
|
|
i = 8;
|
|
}
|
|
}
|
|
} else {
|
|
UnMap_FPR(Section,Reg,FALSE);
|
|
}
|
|
|
|
if (RegInStack(Section,RegToLoad,Format)) {
|
|
if (Reg != RegToLoad) {
|
|
if (Section->FpuMappedTo((Section->StackTopPos() - 1) & 7) != (DWORD)RegToLoad) {
|
|
UnMap_FPR(Section,Section->FpuMappedTo((Section->StackTopPos() - 1) & 7),TRUE);
|
|
CPU_Message(" regcache: allocate ST(0) to %s", FPR_Name[Reg]);
|
|
fpuLoadReg(&Section->StackTopPos(),StackPosition(Section,RegToLoad));
|
|
Section->FpuRoundingModel(Section->StackTopPos()) = CRegInfo::RoundDefault;
|
|
Section->FpuMappedTo(Section->StackTopPos()) = Reg;
|
|
Section->FpuState(Section->StackTopPos()) = Format;
|
|
} else {
|
|
UnMap_FPR(Section,Section->FpuMappedTo((Section->StackTopPos() - 1) & 7),TRUE);
|
|
Load_FPR_ToTop (Section,Reg, RegToLoad, Format);
|
|
}
|
|
} else {
|
|
DWORD RegPos, StackPos, i;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
if (Section->FpuMappedTo(i) == (DWORD)Reg) {
|
|
RegPos = i;
|
|
i = 8;
|
|
}
|
|
}
|
|
|
|
if (RegPos == Section->StackTopPos()) {
|
|
return;
|
|
}
|
|
StackPos = StackPosition(Section,Reg);
|
|
|
|
Section->FpuRoundingModel(RegPos) = Section->FpuRoundingModel(Section->StackTopPos());
|
|
Section->FpuMappedTo(RegPos) = Section->FpuMappedTo(Section->StackTopPos());
|
|
Section->FpuState(RegPos) = Section->FpuState(Section->StackTopPos());
|
|
CPU_Message(" regcache: allocate ST(%d) to %s", StackPos,FPR_Name[Section->FpuMappedTo(RegPos)]);
|
|
CPU_Message(" regcache: allocate ST(0) to %s", FPR_Name[Reg]);
|
|
|
|
fpuExchange(StackPos);
|
|
|
|
Section->FpuRoundingModel(Section->StackTopPos()) = CRegInfo::RoundDefault;
|
|
Section->FpuMappedTo(Section->StackTopPos()) = Reg;
|
|
Section->FpuState(Section->StackTopPos()) = Format;
|
|
}
|
|
} else {
|
|
char Name[50];
|
|
int TempReg;
|
|
|
|
UnMap_FPR(Section,Section->FpuMappedTo((Section->StackTopPos() - 1) & 7),TRUE);
|
|
for (i = 0; i < 8; i++) {
|
|
if (Section->FpuMappedTo(i) == (DWORD)RegToLoad) {
|
|
UnMap_FPR(Section,RegToLoad,TRUE);
|
|
i = 8;
|
|
}
|
|
}
|
|
CPU_Message(" regcache: allocate ST(0) to %s", FPR_Name[Reg]);
|
|
TempReg = Map_TempReg(Section,x86_Any,-1,FALSE);
|
|
switch (Format) {
|
|
case CRegInfo::FPU_Dword:
|
|
sprintf(Name,"_FPRFloatLocation[%d]",RegToLoad);
|
|
MoveVariableToX86reg(&_FPRFloatLocation[RegToLoad],Name,TempReg);
|
|
fpuLoadIntegerDwordFromX86Reg(&Section->StackTopPos(),TempReg);
|
|
break;
|
|
case CRegInfo::FPU_Qword:
|
|
sprintf(Name,"_FPRDoubleLocation[%d]",RegToLoad);
|
|
MoveVariableToX86reg(&_FPRDoubleLocation[RegToLoad],Name,TempReg);
|
|
fpuLoadIntegerQwordFromX86Reg(&Section->StackTopPos(),TempReg);
|
|
break;
|
|
case CRegInfo::FPU_Float:
|
|
sprintf(Name,"_FPRFloatLocation[%d]",RegToLoad);
|
|
MoveVariableToX86reg(&_FPRFloatLocation[RegToLoad],Name,TempReg);
|
|
fpuLoadDwordFromX86Reg(&Section->StackTopPos(),TempReg);
|
|
break;
|
|
case CRegInfo::FPU_Double:
|
|
sprintf(Name,"_FPRDoubleLocation[%d]",RegToLoad);
|
|
MoveVariableToX86reg(&_FPRDoubleLocation[RegToLoad],Name,TempReg);
|
|
fpuLoadQwordFromX86Reg(&Section->StackTopPos(),TempReg);
|
|
break;
|
|
#ifndef EXTERNAL_RELEASE
|
|
default:
|
|
DisplayError("Load_FPR_ToTop\nUnkown format to load %d",Format);
|
|
#endif
|
|
}
|
|
Section->x86Protected(TempReg) = FALSE;
|
|
Section->FpuRoundingModel(Section->StackTopPos()) = CRegInfo::RoundDefault;
|
|
Section->FpuMappedTo(Section->StackTopPos()) = Reg;
|
|
Section->FpuState(Section->StackTopPos()) = Format;
|
|
}
|
|
CPU_Message("CurrentRoundingModel: %d FpuRoundingModel(StackTopPos()): %d",
|
|
Section->CurrentRoundingModel(),Section->FpuRoundingModel(Section->StackTopPos()));
|
|
}
|
|
|
|
void Map_GPR_32bit (CBlockSection * Section, int Reg, BOOL SignValue, int MipsRegToLoad) {
|
|
int x86Reg,count;
|
|
|
|
if (Reg == 0) {
|
|
#ifndef EXTERNAL_RELEASE
|
|
DisplayError("Map_GPR_32bit\n\nWhy are you trying to map reg 0");
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
if (Section->IsUnknown(Reg) || Section->IsConst(Reg)) {
|
|
x86Reg = FreeX86Reg(Section);
|
|
if (x86Reg < 0) {
|
|
#ifndef EXTERNAL_RELEASE
|
|
DisplayError("Map_GPR_32bit\n\nOut of registers");
|
|
BreakPoint(__FILE__,__LINE__);
|
|
#endif
|
|
return;
|
|
}
|
|
CPU_Message(" regcache: allocate %s to %s",x86_Name(x86Reg),GPR_Name[Reg]);
|
|
} else {
|
|
if (Section->Is64Bit(Reg)) {
|
|
CPU_Message(" regcache: unallocate %s from high 32bit of %s",x86_Name(Section->MipsRegHi(Reg)),GPR_NameHi[Reg]);
|
|
Section->x86MapOrder(Section->MipsRegHi(Reg)) = 0;
|
|
Section->x86Mapped(Section->MipsRegHi(Reg)) = CRegInfo::NotMapped;
|
|
Section->x86Protected(Section->MipsRegHi(Reg)) = FALSE;
|
|
Section->MipsRegHi(Reg) = 0;
|
|
}
|
|
x86Reg = Section->MipsRegLo(Reg);
|
|
}
|
|
for (count = 0; count < 10; count ++) {
|
|
if (Section->x86MapOrder(count) > 0) {
|
|
Section->x86MapOrder(count) += 1;
|
|
}
|
|
}
|
|
Section->x86MapOrder(x86Reg) = 1;
|
|
|
|
if (MipsRegToLoad > 0) {
|
|
if (Section->IsUnknown(MipsRegToLoad)) {
|
|
MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[0],GPR_NameLo[MipsRegToLoad],x86Reg);
|
|
} else if (Section->IsMapped(MipsRegToLoad)) {
|
|
if (Reg != MipsRegToLoad) {
|
|
MoveX86RegToX86Reg(Section->MipsRegLo(MipsRegToLoad),x86Reg);
|
|
}
|
|
} else {
|
|
if (Section->MipsRegLo(MipsRegToLoad) != 0) {
|
|
MoveConstToX86reg(Section->MipsRegLo(MipsRegToLoad),x86Reg);
|
|
} else {
|
|
XorX86RegToX86Reg(x86Reg,x86Reg);
|
|
}
|
|
}
|
|
} else if (MipsRegToLoad == 0) {
|
|
XorX86RegToX86Reg(x86Reg,x86Reg);
|
|
}
|
|
Section->x86Mapped(x86Reg) = CRegInfo::GPR_Mapped;
|
|
Section->x86Protected(x86Reg) = TRUE;
|
|
Section->MipsRegLo(Reg) = x86Reg;
|
|
Section->MipsRegState(Reg) = SignValue ? CRegInfo::STATE_MAPPED_32_SIGN : CRegInfo::STATE_MAPPED_32_ZERO;
|
|
}
|
|
|
|
void Map_GPR_64bit (CBlockSection * Section, int Reg, int MipsRegToLoad) {
|
|
int x86Hi, x86lo, count;
|
|
|
|
if (Reg == 0) {
|
|
#ifndef EXTERNAL_RELEASE
|
|
DisplayError("Map_GPR_32bit\n\nWhy are you trying to map reg 0");
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
ProtectGPR(Section,Reg);
|
|
if (Section->IsUnknown(Reg) || Section->IsConst(Reg)) {
|
|
x86Hi = FreeX86Reg(Section);
|
|
if (x86Hi < 0) { DisplayError("Map_GPR_64bit\n\nOut of registers"); return; }
|
|
Section->x86Protected(x86Hi) = TRUE;
|
|
|
|
x86lo = FreeX86Reg(Section);
|
|
if (x86lo < 0) { DisplayError("Map_GPR_64bit\n\nOut of registers"); return; }
|
|
Section->x86Protected(x86lo) = TRUE;
|
|
|
|
CPU_Message(" regcache: allocate %s to hi word of %s",x86_Name(x86Hi),GPR_Name[Reg]);
|
|
CPU_Message(" regcache: allocate %s to low word of %s",x86_Name(x86lo),GPR_Name[Reg]);
|
|
} else {
|
|
x86lo = Section->MipsRegLo(Reg);
|
|
if (Section->Is32Bit(Reg)) {
|
|
Section->x86Protected(x86lo) = TRUE;
|
|
x86Hi = FreeX86Reg(Section);
|
|
if (x86Hi < 0) { DisplayError("Map_GPR_64bit\n\nOut of registers"); return; }
|
|
Section->x86Protected(x86Hi) = TRUE;
|
|
} else {
|
|
x86Hi = Section->MipsRegHi(Reg);
|
|
}
|
|
}
|
|
|
|
for (count = 0; count < 10; count ++) {
|
|
if (Section->x86MapOrder(count) > 0) { Section->x86MapOrder(count) += 1; }
|
|
}
|
|
|
|
Section->x86MapOrder(x86Hi) = 1;
|
|
Section->x86MapOrder(x86lo) = 1;
|
|
if (MipsRegToLoad > 0) {
|
|
if (Section->IsUnknown(MipsRegToLoad)) {
|
|
MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[1],GPR_NameHi[MipsRegToLoad],x86Hi);
|
|
MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[0],GPR_NameLo[MipsRegToLoad],x86lo);
|
|
} else if (Section->IsMapped(MipsRegToLoad)) {
|
|
if (Section->Is32Bit(MipsRegToLoad)) {
|
|
if (Section->IsSigned(MipsRegToLoad)) {
|
|
MoveX86RegToX86Reg(Section->MipsRegLo(MipsRegToLoad),x86Hi);
|
|
ShiftRightSignImmed(x86Hi,31);
|
|
} else {
|
|
XorX86RegToX86Reg(x86Hi,x86Hi);
|
|
}
|
|
if (Reg != MipsRegToLoad) {
|
|
MoveX86RegToX86Reg(Section->MipsRegLo(MipsRegToLoad),x86lo);
|
|
}
|
|
} else {
|
|
if (Reg != MipsRegToLoad) {
|
|
MoveX86RegToX86Reg(Section->MipsRegHi(MipsRegToLoad),x86Hi);
|
|
MoveX86RegToX86Reg(Section->MipsRegLo(MipsRegToLoad),x86lo);
|
|
}
|
|
}
|
|
} else {
|
|
CPU_Message("Map_GPR_64bit 11");
|
|
if (Section->Is32Bit(MipsRegToLoad)) {
|
|
if (Section->IsSigned(MipsRegToLoad)) {
|
|
if (Section->MipsRegLo((int)Section->MipsRegLo(MipsRegToLoad) >> 31) != 0) {
|
|
MoveConstToX86reg((int)Section->MipsRegLo(MipsRegToLoad) >> 31,x86Hi);
|
|
} else {
|
|
XorX86RegToX86Reg(x86Hi,x86Hi);
|
|
}
|
|
} else {
|
|
XorX86RegToX86Reg(x86Hi,x86Hi);
|
|
}
|
|
} else {
|
|
if (Section->MipsRegHi(MipsRegToLoad) != 0) {
|
|
MoveConstToX86reg(Section->MipsRegHi(MipsRegToLoad),x86Hi);
|
|
} else {
|
|
XorX86RegToX86Reg(x86Hi,x86Hi);
|
|
}
|
|
}
|
|
if (Section->MipsRegLo(MipsRegToLoad) != 0) {
|
|
MoveConstToX86reg(Section->MipsRegLo(MipsRegToLoad),x86lo);
|
|
} else {
|
|
XorX86RegToX86Reg(x86lo,x86lo);
|
|
}
|
|
}
|
|
} else if (MipsRegToLoad == 0) {
|
|
XorX86RegToX86Reg(x86Hi,x86Hi);
|
|
XorX86RegToX86Reg(x86lo,x86lo);
|
|
}
|
|
Section->x86Mapped(x86Hi) = CRegInfo::GPR_Mapped;
|
|
Section->x86Mapped(x86lo) = CRegInfo::GPR_Mapped;
|
|
Section->MipsRegHi(Reg) = x86Hi;
|
|
Section->MipsRegLo(Reg) = x86lo;
|
|
Section->MipsRegState(Reg) = CRegInfo::STATE_MAPPED_64;
|
|
}
|
|
|
|
int Map_MemoryStack (CBlockSection * Section, int Reg, bool MapRegister)
|
|
{
|
|
int CurrentMap = -1;
|
|
|
|
// check to see what the current mapping is
|
|
for (int x86Reg = 0; x86Reg < 10; x86Reg ++ ) {
|
|
if (Section->x86Mapped(x86Reg) == CRegInfo::Stack_Mapped) {
|
|
CurrentMap = x86Reg;
|
|
}
|
|
}
|
|
if (!MapRegister)
|
|
{
|
|
//if not mapping then just return what the current mapping is
|
|
return CurrentMap;
|
|
}
|
|
|
|
if (CurrentMap > 0 && CurrentMap == Reg)
|
|
{
|
|
//already mapped to correct reg
|
|
return CurrentMap;
|
|
}
|
|
// map a register
|
|
_Notify->BreakPoint(__FILE__,__LINE__);
|
|
#ifdef tofix
|
|
if (Reg == x86_Any)
|
|
{
|
|
if (CurrentMap > 0)
|
|
{
|
|
return CurrentMap;
|
|
}
|
|
x86Reg = FreeX86Reg(Section);
|
|
if (x86Reg < 0) {
|
|
#ifndef EXTERNAL_RELEASE
|
|
DisplayError("Map_MemoryStack\n\nOut of registers");
|
|
BreakPoint(__FILE__,__LINE__);
|
|
#endif
|
|
}
|
|
Section->x86Mapped(x86Reg) = CRegInfo::Stack_Mapped;
|
|
CPU_Message(" regcache: allocate %s as Memory Stack",x86_Name(x86Reg));
|
|
MoveVariableToX86reg(g_MemoryStack,"MemoryStack",x86Reg);
|
|
return x86Reg;
|
|
}
|
|
|
|
//move to a register/allocate register
|
|
UnMap_X86reg(Section, Reg);
|
|
if (CurrentMap >= 0)
|
|
{
|
|
CPU_Message(" regcache: change allocation of Memory Stack from %s to %s",x86_Name(CurrentMap),x86_Name(Reg));
|
|
Section->x86Mapped(Reg) = CRegInfo::Stack_Mapped;
|
|
Section->x86Mapped(CurrentMap) = CRegInfo::NotMapped;
|
|
MoveX86RegToX86Reg(CurrentMap,Reg);
|
|
} else {
|
|
Section->x86Mapped(Reg) = CRegInfo::Stack_Mapped;
|
|
CPU_Message(" regcache: allocate %s as Memory Stack",x86_Name(Reg));
|
|
MoveVariableToX86reg(g_MemoryStack,"MemoryStack",Reg);
|
|
}
|
|
#endif
|
|
return Reg;
|
|
}
|
|
|
|
int Map_TempReg (CBlockSection * Section, int x86Reg, int MipsReg, BOOL LoadHiWord) {
|
|
int count;
|
|
|
|
if (x86Reg == x86_Any) {
|
|
for (count = 0; count < 10; count ++ ) {
|
|
if (Section->x86Mapped(count) == CRegInfo::Temp_Mapped) {
|
|
if (Section->x86Protected(count) == FALSE) { x86Reg = count; }
|
|
}
|
|
}
|
|
|
|
if (x86Reg == x86_Any) {
|
|
x86Reg = FreeX86Reg(Section);
|
|
if (x86Reg < 0) {
|
|
#ifndef EXTERNAL_RELEASE
|
|
DisplayError("Map_TempReg\n\nOut of registers");
|
|
BreakPoint(__FILE__,__LINE__);
|
|
#endif
|
|
|
|
x86Reg = FreeX86Reg(Section);
|
|
return -1;
|
|
}
|
|
CPU_Message(" regcache: allocate %s as temp storage",x86_Name(x86Reg));
|
|
}
|
|
} else if (x86Reg == x86_Any8Bit) {
|
|
if (Section->x86Mapped(x86_EBX) == CRegInfo::Temp_Mapped && !Section->x86Protected(x86_EBX)) { x86Reg = x86_EBX; }
|
|
if (Section->x86Mapped(x86_EAX) == CRegInfo::Temp_Mapped && !Section->x86Protected(x86_EAX)) { x86Reg = x86_EAX; }
|
|
if (Section->x86Mapped(x86_EDX) == CRegInfo::Temp_Mapped && !Section->x86Protected(x86_EDX)) { x86Reg = x86_EDX; }
|
|
if (Section->x86Mapped(x86_ECX) == CRegInfo::Temp_Mapped && !Section->x86Protected(x86_ECX)) { x86Reg = x86_ECX; }
|
|
|
|
if (x86Reg == x86_Any8Bit) {
|
|
x86Reg = Free8BitX86Reg(Section);
|
|
if (x86Reg < 0) {
|
|
#ifndef EXTERNAL_RELEASE
|
|
DisplayError("Map_GPR_8bit\n\nOut of registers");
|
|
BreakPoint(__FILE__,__LINE__);
|
|
#endif
|
|
return -1;
|
|
}
|
|
}
|
|
} else {
|
|
int NewReg;
|
|
|
|
if (Section->x86Mapped(x86Reg) == CRegInfo::GPR_Mapped) {
|
|
if (Section->x86Protected(x86Reg) == TRUE) {
|
|
#ifndef EXTERNAL_RELEASE
|
|
DisplayError("Map_TempReg\nRegister is protected !!!");
|
|
#endif
|
|
return -1;
|
|
}
|
|
Section->x86Protected(x86Reg) = TRUE;
|
|
NewReg = FreeX86Reg(Section);
|
|
for (count = 1; count < 32; count ++) {
|
|
if (Section->IsMapped(count)) {
|
|
if (Section->MipsRegLo(count) == (DWORD)x86Reg) {
|
|
if (NewReg < 0) {
|
|
UnMap_GPR(Section,count,TRUE);
|
|
count = 32;
|
|
continue;
|
|
}
|
|
CPU_Message(" regcache: change allocation of %s from %s to %s",
|
|
GPR_Name[count],x86_Name(x86Reg),x86_Name(NewReg));
|
|
Section->x86Mapped(NewReg) = CRegInfo::GPR_Mapped;
|
|
Section->x86MapOrder(NewReg) = Section->x86MapOrder(x86Reg);
|
|
Section->MipsRegLo(count) = NewReg;
|
|
MoveX86RegToX86Reg(x86Reg,NewReg);
|
|
if (MipsReg == count && LoadHiWord == FALSE) { MipsReg = -1; }
|
|
count = 32;
|
|
}
|
|
if (Section->Is64Bit(count) && Section->MipsRegHi(count) == (DWORD)x86Reg) {
|
|
if (NewReg < 0) {
|
|
UnMap_GPR(Section,count,TRUE);
|
|
count = 32;
|
|
continue;
|
|
}
|
|
CPU_Message(" regcache: change allocation of %s from %s to %s",
|
|
GPR_NameHi[count],x86_Name(x86Reg),x86_Name(NewReg));
|
|
Section->x86Mapped(NewReg) = CRegInfo::GPR_Mapped;
|
|
Section->x86MapOrder(NewReg) = Section->x86MapOrder(x86Reg);
|
|
Section->MipsRegHi(count) = NewReg;
|
|
MoveX86RegToX86Reg(x86Reg,NewReg);
|
|
if (MipsReg == count && LoadHiWord == TRUE) { MipsReg = -1; }
|
|
count = 32;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (Section->x86Mapped(x86Reg) == CRegInfo::Stack_Mapped) {
|
|
UnMap_X86reg(Section,x86Reg);
|
|
}
|
|
CPU_Message(" regcache: allocate %s as temp storage",x86_Name(x86Reg));
|
|
}
|
|
if (MipsReg >= 0) {
|
|
if (LoadHiWord) {
|
|
if (Section->IsUnknown(MipsReg)) {
|
|
MoveVariableToX86reg(&_GPR[MipsReg].UW[1],GPR_NameHi[MipsReg],x86Reg);
|
|
} else if (Section->IsMapped(MipsReg)) {
|
|
if (Section->Is64Bit(MipsReg)) {
|
|
MoveX86RegToX86Reg(Section->MipsRegHi(MipsReg),x86Reg);
|
|
} else if (Section->IsSigned(MipsReg)){
|
|
MoveX86RegToX86Reg(Section->MipsRegLo(MipsReg),x86Reg);
|
|
ShiftRightSignImmed(x86Reg,31);
|
|
} else {
|
|
MoveConstToX86reg(0,x86Reg);
|
|
}
|
|
} else {
|
|
if (Section->Is64Bit(MipsReg)) {
|
|
if (Section->MipsRegHi(MipsReg) != 0) {
|
|
MoveConstToX86reg(Section->MipsRegHi(MipsReg),x86Reg);
|
|
} else {
|
|
XorX86RegToX86Reg(x86Reg,x86Reg);
|
|
}
|
|
} else {
|
|
if ((int)Section->MipsRegLo(MipsReg) >> 31 != 0) {
|
|
MoveConstToX86reg((int)Section->MipsRegLo(MipsReg) >> 31,x86Reg);
|
|
} else {
|
|
XorX86RegToX86Reg(x86Reg,x86Reg);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (Section->IsUnknown(MipsReg)) {
|
|
MoveVariableToX86reg(&_GPR[MipsReg].UW[0],GPR_NameLo[MipsReg],x86Reg);
|
|
} else if (Section->IsMapped(MipsReg)) {
|
|
MoveX86RegToX86Reg(Section->MipsRegLo(MipsReg),x86Reg);
|
|
} else {
|
|
if (Section->MipsRegLo(MipsReg) != 0) {
|
|
MoveConstToX86reg(Section->MipsRegLo(MipsReg),x86Reg);
|
|
} else {
|
|
XorX86RegToX86Reg(x86Reg,x86Reg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Section->x86Mapped(x86Reg) = CRegInfo::Temp_Mapped;
|
|
Section->x86Protected(x86Reg) = TRUE;
|
|
for (count = 0; count < 10; count ++) {
|
|
if (Section->x86MapOrder(count) > 0) {
|
|
Section->x86MapOrder(count) += 1;
|
|
}
|
|
}
|
|
Section->x86MapOrder(x86Reg) = 1;
|
|
return x86Reg;
|
|
}
|
|
|
|
void ProtectGPR(CBlockSection * Section, DWORD Reg) {
|
|
if (Section->IsUnknown(Reg)) { return; }
|
|
if (Section->IsConst(Reg)) { return; }
|
|
if (Section->Is64Bit(Reg)) {
|
|
Section->x86Protected(Section->MipsRegHi(Reg)) = TRUE;
|
|
}
|
|
Section->x86Protected(Section->MipsRegLo(Reg)) = TRUE;
|
|
}
|
|
|
|
BOOL RegInStack(CBlockSection * Section,int Reg, int Format) {
|
|
int i;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
if (Section->FpuMappedTo(i) == (DWORD)Reg) {
|
|
if (Section->FpuState(i) == (DWORD)Format) { return TRUE; }
|
|
else if (Format == -1) { return TRUE; }
|
|
return FALSE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
#ifdef ggg
|
|
void SetFpuLocations (void) {
|
|
int count;
|
|
|
|
if ((STATUS_REGISTER & STATUS_FR) == 0) {
|
|
for (count = 0; count < 32; count ++) {
|
|
_FPRFloatLocation[count] = (void *)(&FPR[count >> 1].W[count & 1]);
|
|
//_FPRDoubleLocation[count] = _FPRFloatLocation[count];
|
|
_FPRDoubleLocation[count] = (void *)(&FPR[count >> 1].DW);
|
|
}
|
|
} else {
|
|
for (count = 0; count < 32; count ++) {
|
|
_FPRFloatLocation[count] = (void *)(&FPR[count].W[1]);
|
|
//_FPRDoubleLocation[count] = _FPRFloatLocation[count];
|
|
_FPRDoubleLocation[count] = (void *)(&FPR[count].DW);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SetupRegisters(N64_REGISTERS * n64_Registers) {
|
|
PROGRAM_COUNTER = n64_Registers->PROGRAM_COUNTER;
|
|
HI.DW = n64_Registers->HI.DW;
|
|
LO.DW = n64_Registers->LO.DW;
|
|
CP0 = n64_Registers->CP0;
|
|
_GPR = n64_Registers->_GPR;
|
|
FPR = n64_Registers->FPR;
|
|
FPCR = n64_Registers->FPCR;
|
|
RegRDRAM = n64_Registers->RDRAM;
|
|
RegSP = n64_Registers->SP;
|
|
RegDPC = n64_Registers->DPC;
|
|
RegMI = n64_Registers->MI;
|
|
RegVI = n64_Registers->VI;
|
|
RegAI = n64_Registers->AI;
|
|
RegPI = n64_Registers->PI;
|
|
RegRI = n64_Registers->RI;
|
|
RegSI = n64_Registers->SI;
|
|
PIF_Ram = n64_Registers->PIF_Ram;
|
|
DMAUsed = n64_Registers->DMAUsed;
|
|
}
|
|
#endif
|
|
|
|
int StackPosition (CBlockSection * Section,int Reg) {
|
|
int i;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
if (Section->FpuMappedTo(i) == (DWORD)Reg) {
|
|
return ((i - Section->StackTopPos()) & 7);
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int UnMap_8BitTempReg (CBlockSection * Section) {
|
|
int count;
|
|
|
|
for (count = 0; count < 10; count ++) {
|
|
if (!Is8BitReg(count)) { continue; }
|
|
if (Section->MipsRegState(count) == CRegInfo::Temp_Mapped) {
|
|
if (Section->x86Protected(count) == FALSE) {
|
|
CPU_Message(" regcache: unallocate %s from temp storage",x86_Name(count));
|
|
Section->x86Mapped(count) = CRegInfo::NotMapped;
|
|
return count;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void UnMap_AllFPRs ( CBlockSection * Section ) {
|
|
DWORD StackPos;
|
|
|
|
for (;;) {
|
|
int i, StartPos;
|
|
StackPos = Section->StackTopPos();
|
|
if (Section->FpuMappedTo(Section->StackTopPos()) != -1 ) {
|
|
UnMap_FPR(Section,Section->FpuMappedTo(Section->StackTopPos()),TRUE);
|
|
continue;
|
|
}
|
|
//see if any more registers mapped
|
|
StartPos = Section->StackTopPos();
|
|
for (i = 0; i < 8; i++) {
|
|
if (Section->FpuMappedTo((StartPos + i) & 7) != -1 ) { fpuIncStack(&Section->StackTopPos()); }
|
|
}
|
|
if (StackPos != Section->StackTopPos()) { continue; }
|
|
return;
|
|
}
|
|
}
|
|
|
|
void FixRoundModel(CBlockSection * Section, CRegInfo::FPU_ROUND RoundMethod )
|
|
{
|
|
if (Section->CurrentRoundingModel() == RoundMethod)
|
|
{
|
|
return;
|
|
}
|
|
|
|
fpuControl = 0;
|
|
fpuStoreControl(&fpuControl, "fpuControl");
|
|
int x86reg = Map_TempReg(Section,x86_Any,-1,FALSE);
|
|
MoveVariableToX86reg(&fpuControl, "fpuControl", x86reg);
|
|
AndConstToX86Reg(x86reg, 0xF3FF);
|
|
|
|
switch (RoundMethod) {
|
|
case CRegInfo::RoundDefault: OrVariableToX86Reg(&FPU_RoundingMode,"FPU_RoundingMode", x86reg); break;
|
|
case CRegInfo::RoundTruncate: OrConstToX86Reg(0x0C00, x86reg); break;
|
|
case CRegInfo::RoundNearest: /*OrConstToX86Reg(0x0000, x86reg);*/ break;
|
|
case CRegInfo::RoundDown: OrConstToX86Reg(0x0400, x86reg); break;
|
|
case CRegInfo::RoundUp: OrConstToX86Reg(0x0800, x86reg); break;
|
|
default:
|
|
DisplayError("Unknown Rounding model");
|
|
}
|
|
MoveX86regToVariable(x86reg, &fpuControl, "fpuControl");
|
|
fpuLoadControl(&fpuControl, "fpuControl");
|
|
Section->CurrentRoundingModel() = RoundMethod;
|
|
}
|
|
|
|
void UnMap_FPR (CBlockSection * Section, int Reg, int WriteBackValue ) {
|
|
char Name[50];
|
|
int TempReg;
|
|
int i;
|
|
|
|
if (Reg < 0) { return; }
|
|
for (i = 0; i < 8; i++) {
|
|
if (Section->FpuMappedTo(i) != (DWORD)Reg) { continue; }
|
|
CPU_Message(" regcache: unallocate %s from ST(%d)",FPR_Name[Reg],(i - Section->StackTopPos() + 8) & 7);
|
|
if (WriteBackValue) {
|
|
int RegPos;
|
|
|
|
if (((i - Section->StackTopPos() + 8) & 7) != 0) {
|
|
CRegInfo::FPU_ROUND RoundingModel = Section->FpuRoundingModel(Section->StackTopPos());
|
|
CRegInfo::FPU_STATE RegState = Section->FpuState(Section->StackTopPos());
|
|
DWORD MappedTo = Section->FpuMappedTo(Section->StackTopPos());
|
|
Section->FpuRoundingModel(Section->StackTopPos()) = Section->FpuRoundingModel(i);
|
|
Section->FpuMappedTo(Section->StackTopPos()) = Section->FpuMappedTo(i);
|
|
Section->FpuState(Section->StackTopPos()) = Section->FpuState(i);
|
|
Section->FpuRoundingModel(i) = RoundingModel;
|
|
Section->FpuMappedTo(i) = MappedTo;
|
|
Section->FpuState(i) = RegState;
|
|
fpuExchange((i - Section->StackTopPos()) & 7);
|
|
}
|
|
|
|
CPU_Message("CurrentRoundingModel: %d Section->FpuRoundingModel(i): %d",
|
|
Section->CurrentRoundingModel(),Section->FpuRoundingModel(i));
|
|
|
|
FixRoundModel(Section,Section->FpuRoundingModel(i));
|
|
|
|
RegPos = Section->StackTopPos();
|
|
TempReg = Map_TempReg(Section,x86_Any,-1,FALSE);
|
|
switch (Section->FpuState(Section->StackTopPos())) {
|
|
case CRegInfo::FPU_Dword:
|
|
sprintf(Name,"_FPRFloatLocation[%d]",Section->FpuMappedTo(Section->StackTopPos()));
|
|
MoveVariableToX86reg(&_FPRFloatLocation[Section->FpuMappedTo(Section->StackTopPos())],Name,TempReg);
|
|
fpuStoreIntegerDwordFromX86Reg(&Section->StackTopPos(),TempReg, TRUE);
|
|
break;
|
|
case CRegInfo::FPU_Qword:
|
|
sprintf(Name,"_FPRDoubleLocation[%d]",Section->FpuMappedTo(Section->StackTopPos()));
|
|
MoveVariableToX86reg(&_FPRDoubleLocation[Section->FpuMappedTo(Section->StackTopPos())],Name,TempReg);
|
|
fpuStoreIntegerQwordFromX86Reg(&Section->StackTopPos(),TempReg, TRUE);
|
|
break;
|
|
case CRegInfo::FPU_Float:
|
|
sprintf(Name,"_FPRFloatLocation[%d]",Section->FpuMappedTo(Section->StackTopPos()));
|
|
MoveVariableToX86reg(&_FPRFloatLocation[Section->FpuMappedTo(Section->StackTopPos())],Name,TempReg);
|
|
fpuStoreDwordFromX86Reg(&Section->StackTopPos(),TempReg, TRUE);
|
|
break;
|
|
case CRegInfo::FPU_Double:
|
|
sprintf(Name,"_FPRDoubleLocation[%d]",Section->FpuMappedTo(Section->StackTopPos()));
|
|
MoveVariableToX86reg(&_FPRDoubleLocation[Section->FpuMappedTo(Section->StackTopPos())],Name,TempReg);
|
|
fpuStoreQwordFromX86Reg(&Section->StackTopPos(),TempReg, TRUE);
|
|
break;
|
|
#ifndef EXTERNAL_RELEASE
|
|
default:
|
|
DisplayError("UnMap_FPR\nUnknown format to load %d",Section->FpuState(Section->StackTopPos()));
|
|
#endif
|
|
}
|
|
Section->x86Protected(TempReg) = FALSE;
|
|
Section->FpuRoundingModel(RegPos) = CRegInfo::RoundDefault;
|
|
Section->FpuMappedTo(RegPos) = -1;
|
|
Section->FpuState(RegPos) = CRegInfo::FPU_Unkown;
|
|
} else {
|
|
fpuFree((i - Section->StackTopPos()) & 7);
|
|
Section->FpuRoundingModel(i) = CRegInfo::RoundDefault;
|
|
Section->FpuMappedTo(i) = -1;
|
|
Section->FpuState(i) = CRegInfo::FPU_Unkown;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
void UnMap_GPR (CBlockSection * Section, DWORD Reg, int WriteBackValue) {
|
|
if (Reg == 0) {
|
|
#ifndef EXTERNAL_RELEASE
|
|
DisplayError("UnMap_GPR\n\nWhy are you trying to unmap reg 0");
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
if (Section->IsUnknown(Reg)) { return; }
|
|
//CPU_Message("UnMap_GPR: State: %X\tReg: %s\tWriteBack: %s",State,GPR_Name[Reg],WriteBackValue?"TRUE":"FALSE");
|
|
if (Section->IsConst(Reg)) {
|
|
if (!WriteBackValue) {
|
|
Section->MipsRegState(Reg) = CRegInfo::STATE_UNKNOWN;
|
|
return;
|
|
}
|
|
if (Section->Is64Bit(Reg)) {
|
|
MoveConstToVariable(Section->MipsRegHi(Reg),&_GPR[Reg].UW[1],GPR_NameHi[Reg]);
|
|
MoveConstToVariable(Section->MipsRegLo(Reg),&_GPR[Reg].UW[0],GPR_NameLo[Reg]);
|
|
Section->MipsRegState(Reg) = CRegInfo::STATE_UNKNOWN;
|
|
return;
|
|
}
|
|
if ((Section->MipsRegLo(Reg) & 0x80000000) != 0) {
|
|
MoveConstToVariable(0xFFFFFFFF,&_GPR[Reg].UW[1],GPR_NameHi[Reg]);
|
|
} else {
|
|
MoveConstToVariable(0,&_GPR[Reg].UW[1],GPR_NameHi[Reg]);
|
|
}
|
|
MoveConstToVariable(Section->MipsRegLo(Reg),&_GPR[Reg].UW[0],GPR_NameLo[Reg]);
|
|
Section->MipsRegState(Reg) = CRegInfo::STATE_UNKNOWN;
|
|
return;
|
|
}
|
|
if (Section->Is64Bit(Reg)) {
|
|
CPU_Message(" regcache: unallocate %s from %s",x86_Name(Section->MipsRegHi(Reg)),GPR_NameHi[Reg]);
|
|
Section->x86Mapped(Section->MipsRegHi(Reg)) = CRegInfo::NotMapped;
|
|
Section->x86Protected(Section->MipsRegHi(Reg)) = FALSE;
|
|
}
|
|
CPU_Message(" regcache: unallocate %s from %s",x86_Name(Section->MipsRegLo(Reg)),GPR_NameLo[Reg]);
|
|
Section->x86Mapped(Section->MipsRegLo(Reg)) = CRegInfo::NotMapped;
|
|
Section->x86Protected(Section->MipsRegLo(Reg)) = FALSE;
|
|
if (!WriteBackValue) {
|
|
Section->MipsRegState(Reg) = CRegInfo::STATE_UNKNOWN;
|
|
return;
|
|
}
|
|
MoveX86regToVariable(Section->MipsRegLo(Reg),&_GPR[Reg].UW[0],GPR_NameLo[Reg]);
|
|
if (Section->Is64Bit(Reg)) {
|
|
MoveX86regToVariable(Section->MipsRegHi(Reg),&_GPR[Reg].UW[1],GPR_NameHi[Reg]);
|
|
} else {
|
|
if (Section->IsSigned(Reg)) {
|
|
ShiftRightSignImmed(Section->MipsRegLo(Reg),31);
|
|
MoveX86regToVariable(Section->MipsRegLo(Reg),&_GPR[Reg].UW[1],GPR_NameHi[Reg]);
|
|
} else {
|
|
MoveConstToVariable(0,&_GPR[Reg].UW[1],GPR_NameHi[Reg]);
|
|
}
|
|
}
|
|
Section->MipsRegState(Reg) = CRegInfo::STATE_UNKNOWN;
|
|
}
|
|
|
|
int UnMap_TempReg (CBlockSection * Section) {
|
|
int count;
|
|
|
|
for (count = 0; count < 10; count ++) {
|
|
if (Section->x86Mapped(count) == CRegInfo::Temp_Mapped) {
|
|
if (Section->x86Protected(count) == FALSE) {
|
|
CPU_Message(" regcache: unallocate %s from temp storage",x86_Name(count));
|
|
Section->x86Mapped(count) = CRegInfo::NotMapped;
|
|
return count;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
BOOL UnMap_X86reg (CBlockSection * Section, DWORD x86Reg) {
|
|
int count;
|
|
|
|
if (Section->x86Mapped(x86Reg) == CRegInfo::NotMapped && Section->x86Protected(x86Reg) == FALSE) { return TRUE; }
|
|
if (Section->x86Mapped(x86Reg) == CRegInfo::Temp_Mapped) {
|
|
if (Section->x86Protected(x86Reg) == FALSE) {
|
|
CPU_Message(" regcache: unallocate %s from temp storage",x86_Name(x86Reg));
|
|
Section->x86Mapped(x86Reg) = CRegInfo::NotMapped;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
for (count = 1; count < 32; count ++) {
|
|
if (Section->IsMapped(count)) {
|
|
if (Section->Is64Bit(count)) {
|
|
if (Section->MipsRegHi(count) == x86Reg) {
|
|
if (Section->x86Protected(x86Reg) == FALSE) {
|
|
UnMap_GPR(Section,count,TRUE);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (Section->MipsRegLo(count) == x86Reg) {
|
|
if (Section->x86Protected(x86Reg) == FALSE) {
|
|
UnMap_GPR(Section,count,TRUE);
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
_Notify->BreakPoint(__FILE__,__LINE__);
|
|
#ifdef tofix
|
|
if (Section->x86Mapped(x86Reg) == CRegInfo::Stack_Mapped) {
|
|
CPU_Message(" regcache: unallocate %s from Memory Stack",x86_Name(x86Reg));
|
|
MoveX86regToVariable(x86Reg,g_MemoryStack,"MemoryStack");
|
|
Section->x86Mapped(x86Reg) = CRegInfo::NotMapped;
|
|
return TRUE;
|
|
}
|
|
#endif
|
|
return FALSE;
|
|
}
|
|
|
|
void UnProtectGPR(CBlockSection * Section, DWORD Reg) {
|
|
if (Section->IsUnknown(Reg)) { return; }
|
|
if (Section->IsConst(Reg)) { return; }
|
|
if (Section->Is64Bit(Reg)) {
|
|
Section->x86Protected(Section->MipsRegHi(Reg)) = FALSE;
|
|
}
|
|
Section->x86Protected(Section->MipsRegLo(Reg)) = FALSE;
|
|
}
|
|
|
|
/*void WriteBackRegisters (CBlockSection * Section) {
|
|
int count;
|
|
|
|
for (count = 1; count < 10; count ++) { Section->x86Protected(count) = FALSE; }
|
|
for (count = 1; count < 10; count ++) { UnMap_X86reg (Section, count); }
|
|
for (count = 1; count < 32; count ++) {
|
|
switch (Section->MipsRegState(count)) {
|
|
case CRegInfo::STATE_UNKNOWN: break;
|
|
case STATE_CONST_32:
|
|
if ((Section->MipsRegLo(count) & 0x80000000) != 0) {
|
|
MoveConstToVariable(0xFFFFFFFF,&_GPR[count].UW[1],GPR_NameHi[count]);
|
|
} else {
|
|
MoveConstToVariable(0,&_GPR[count].UW[1],GPR_NameHi[count]);
|
|
}
|
|
MoveConstToVariable(Section->MipsRegLo(count),&_GPR[count].UW[0],GPR_NameLo[count]);
|
|
Section->MipsRegState(count) = CRegInfo::STATE_UNKNOWN;
|
|
break;
|
|
default:
|
|
DisplayError("Unknown State: %d\nin WriteBackRegisters",Section->MipsRegState(count));
|
|
}
|
|
}
|
|
UnMap_AllFPRs(Section);
|
|
}*/
|
|
void WriteBackRegisters (CBlockSection * Section) {
|
|
int count;
|
|
BOOL bEdiZero = FALSE;
|
|
BOOL bEsiSign = FALSE;
|
|
/*** coming soon ***/
|
|
BOOL bEaxGprLo = FALSE;
|
|
BOOL bEbxGprHi = FALSE;
|
|
|
|
for (count = 1; count < 10; count ++) { Section->x86Protected(count) = FALSE; }
|
|
for (count = 1; count < 10; count ++) { UnMap_X86reg (Section, count); }
|
|
|
|
/*************************************/
|
|
|
|
for (count = 1; count < 32; count ++) {
|
|
switch (Section->MipsRegState(count)) {
|
|
case CRegInfo::STATE_UNKNOWN: break;
|
|
case CRegInfo::STATE_CONST_32:
|
|
if (!bEdiZero && (!Section->MipsRegLo(count) || !(Section->MipsRegLo(count) & 0x80000000))) {
|
|
XorX86RegToX86Reg(x86_EDI, x86_EDI);
|
|
bEdiZero = TRUE;
|
|
}
|
|
if (!bEsiSign && (Section->MipsRegLo(count) & 0x80000000)) {
|
|
MoveConstToX86reg(0xFFFFFFFF, x86_ESI);
|
|
bEsiSign = TRUE;
|
|
}
|
|
|
|
if ((Section->MipsRegLo(count) & 0x80000000) != 0) {
|
|
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[1],GPR_NameHi[count]);
|
|
} else {
|
|
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[1],GPR_NameHi[count]);
|
|
}
|
|
|
|
if (Section->MipsRegLo(count) == 0) {
|
|
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[0],GPR_NameLo[count]);
|
|
} else if (Section->MipsRegLo(count) == 0xFFFFFFFF) {
|
|
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[0],GPR_NameLo[count]);
|
|
} else
|
|
MoveConstToVariable(Section->MipsRegLo(count),&_GPR[count].UW[0],GPR_NameLo[count]);
|
|
|
|
Section->MipsRegState(count) = CRegInfo::STATE_UNKNOWN;
|
|
break;
|
|
case CRegInfo::STATE_CONST_64:
|
|
if (Section->MipsRegLo(count) == 0 || Section->MipsRegHi(count) == 0) {
|
|
XorX86RegToX86Reg(x86_EDI, x86_EDI);
|
|
bEdiZero = TRUE;
|
|
}
|
|
if (Section->MipsRegLo(count) == 0xFFFFFFFF || Section->MipsRegHi(count) == 0xFFFFFFFF) {
|
|
MoveConstToX86reg(0xFFFFFFFF, x86_ESI);
|
|
bEsiSign = TRUE;
|
|
}
|
|
|
|
if (Section->MipsRegHi(count) == 0) {
|
|
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[1],GPR_NameHi[count]);
|
|
} else if (Section->MipsRegLo(count) == 0xFFFFFFFF) {
|
|
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[1],GPR_NameHi[count]);
|
|
} else {
|
|
MoveConstToVariable(Section->MipsRegHi(count),&_GPR[count].UW[1],GPR_NameHi[count]);
|
|
}
|
|
|
|
if (Section->MipsRegLo(count) == 0) {
|
|
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[0],GPR_NameLo[count]);
|
|
} else if (Section->MipsRegLo(count) == 0xFFFFFFFF) {
|
|
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[0],GPR_NameLo[count]);
|
|
} else {
|
|
MoveConstToVariable(Section->MipsRegLo(count),&_GPR[count].UW[0],GPR_NameLo[count]);
|
|
}
|
|
Section->MipsRegState(count) = CRegInfo::STATE_UNKNOWN;
|
|
break;
|
|
#ifndef EXTERNAL_RELEASE
|
|
default:
|
|
DisplayError("Unknown State: %d\nin WriteBackRegisters",Section->MipsRegState(count));
|
|
#endif
|
|
}
|
|
}
|
|
UnMap_AllFPRs(Section);
|
|
}
|
|
|