2010-05-30 01:54:42 +00:00
|
|
|
#include "stdafx.h"
|
|
|
|
|
|
|
|
unsigned int CRegInfo::m_fpuControl = 0;
|
|
|
|
|
2010-06-04 06:25:07 +00:00
|
|
|
char *Format_Name[] = {"Unknown","dword","qword","float","double"};
|
|
|
|
|
2012-10-14 01:05:52 +00:00
|
|
|
CRegInfo::CRegInfo ( void ) :
|
|
|
|
m_CycleCount(0),
|
|
|
|
m_Stack_TopPos(0),
|
|
|
|
m_Fpu_Used(false),
|
|
|
|
m_RoundingModel(RoundUnknown)
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
2012-10-14 01:05:52 +00:00
|
|
|
m_MIPS_RegState[0] = STATE_CONST_32;
|
|
|
|
m_MIPS_RegVal[0].DW = 0;
|
|
|
|
m_RegMapLo[0] = x86_Unknown;
|
|
|
|
m_RegMapHi[0] = x86_Unknown;
|
2010-05-30 01:54:42 +00:00
|
|
|
|
2012-10-14 01:05:52 +00:00
|
|
|
for (int i = 1; i < 32; i++ )
|
|
|
|
{
|
|
|
|
m_MIPS_RegState[i] = STATE_UNKNOWN;
|
|
|
|
m_MIPS_RegVal[i].DW = 0;
|
|
|
|
m_RegMapLo[i] = x86_Unknown;
|
|
|
|
m_RegMapHi[i] = x86_Unknown;
|
|
|
|
}
|
|
|
|
for (int i = 0, n = sizeof(m_x86reg_MappedTo) / sizeof(m_x86reg_MappedTo[0]); i < n; i++ )
|
|
|
|
{
|
|
|
|
m_x86reg_MappedTo[i] = NotMapped;
|
|
|
|
m_x86reg_Protected[i] = false;
|
|
|
|
m_x86reg_MapOrder[i] = 0;
|
|
|
|
}
|
|
|
|
for (int i = 0, n = sizeof(x86fpu_MappedTo) / sizeof(x86fpu_MappedTo[0]); i < n; i++ )
|
|
|
|
{
|
|
|
|
x86fpu_MappedTo[i] = -1;
|
|
|
|
x86fpu_State[i] = FPU_Unknown;
|
|
|
|
x86fpu_StateChanged[i] = false;
|
|
|
|
x86fpu_RoundingModel[i] = RoundDefault;
|
|
|
|
}
|
|
|
|
}
|
2010-10-23 18:53:01 +00:00
|
|
|
|
2012-10-14 01:05:52 +00:00
|
|
|
CRegInfo::CRegInfo(const CRegInfo& rhs)
|
|
|
|
{
|
|
|
|
*this = rhs;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegInfo::~CRegInfo()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegInfo& CRegInfo::operator=(const CRegInfo& right)
|
|
|
|
{
|
|
|
|
m_CycleCount = right.m_CycleCount;
|
|
|
|
m_Stack_TopPos = right.m_Stack_TopPos;
|
|
|
|
m_Fpu_Used = right.m_Fpu_Used;
|
|
|
|
m_RoundingModel = right.m_RoundingModel;
|
|
|
|
|
|
|
|
memcpy(&m_MIPS_RegState,&right.m_MIPS_RegState,sizeof(m_MIPS_RegState));
|
|
|
|
memcpy(&m_MIPS_RegVal,&right.m_MIPS_RegVal,sizeof(m_MIPS_RegVal));
|
|
|
|
memcpy(&m_RegMapLo,&right.m_RegMapLo,sizeof(m_RegMapLo));
|
|
|
|
memcpy(&m_RegMapHi,&right.m_RegMapHi,sizeof(m_RegMapHi));
|
|
|
|
memcpy(&m_x86reg_MappedTo,&right.m_x86reg_MappedTo,sizeof(m_x86reg_MappedTo));
|
|
|
|
memcpy(&m_x86reg_Protected,&right.m_x86reg_Protected,sizeof(m_x86reg_Protected));
|
|
|
|
memcpy(&m_x86reg_MapOrder,&right.m_x86reg_MapOrder,sizeof(m_x86reg_MapOrder));
|
|
|
|
|
|
|
|
memcpy(&x86fpu_MappedTo,&right.x86fpu_MappedTo,sizeof(x86fpu_MappedTo));
|
|
|
|
memcpy(&x86fpu_State,&right.x86fpu_State,sizeof(x86fpu_State));
|
|
|
|
memcpy(&x86fpu_StateChanged,&right.x86fpu_StateChanged,sizeof(x86fpu_StateChanged));
|
|
|
|
memcpy(&x86fpu_RoundingModel,&right.x86fpu_RoundingModel,sizeof(x86fpu_RoundingModel));
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
if (*this != right)
|
|
|
|
{
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__,__LINE__);
|
2012-10-14 01:05:52 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CRegInfo::operator==(const CRegInfo& right) const
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
|
|
|
|
for (count = 0; count < 32; count ++ ) {
|
|
|
|
if (m_MIPS_RegState[count] != right.m_MIPS_RegState[count])
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (m_MIPS_RegState[count] == STATE_UNKNOWN)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (m_MIPS_RegVal[count].DW != right.m_MIPS_RegVal[count].DW)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
for (count = 0; count < 10; count ++ ) {
|
2012-10-14 01:05:52 +00:00
|
|
|
if (m_x86reg_MappedTo[count] != right.m_x86reg_MappedTo[count]) { return false; }
|
|
|
|
if (m_x86reg_Protected[count] != right.m_x86reg_Protected[count]) { return false; }
|
|
|
|
if (m_x86reg_MapOrder[count] != right.m_x86reg_MapOrder[count]) { return false; }
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
2012-10-14 01:05:52 +00:00
|
|
|
if (m_CycleCount != right.m_CycleCount) { return false; }
|
|
|
|
if (m_Stack_TopPos != right.m_Stack_TopPos) { return false; }
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
for (count = 0; count < 8; count ++ ) {
|
2012-10-14 01:05:52 +00:00
|
|
|
if (x86fpu_MappedTo[count] != right.x86fpu_MappedTo[count]) { return false; }
|
|
|
|
if (x86fpu_State[count] != right.x86fpu_State[count]) { return false; }
|
|
|
|
if (x86fpu_RoundingModel[count] != right.x86fpu_RoundingModel[count]) { return false; }
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
2012-10-14 01:05:52 +00:00
|
|
|
if (m_Fpu_Used != right.m_Fpu_Used) { return false; }
|
|
|
|
if (GetRoundingModel() != right.GetRoundingModel()) { return false; }
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CRegInfo::operator!=(const CRegInfo& right) const
|
|
|
|
{
|
|
|
|
return !(right == *this);
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegInfo::REG_STATE CRegInfo::ConstantsType (__int64 Value)
|
|
|
|
{
|
|
|
|
if (((Value >> 32) == -1) && ((Value & 0x80000000) != 0)) { return STATE_CONST_32; }
|
|
|
|
if (((Value >> 32) == 0) && ((Value & 0x80000000) == 0)) { return STATE_CONST_32; }
|
|
|
|
return STATE_CONST_64;
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CRegInfo::FixRoundModel(FPU_ROUND RoundMethod )
|
|
|
|
{
|
2010-07-23 10:45:35 +00:00
|
|
|
if (GetRoundingModel() == RoundMethod)
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
CPU_Message(" FixRoundModel: CurrentRoundingModel: %s targetRoundModel: %s",RoundingModelName(GetRoundingModel()),RoundingModelName(RoundMethod));
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
m_fpuControl = 0;
|
|
|
|
fpuStoreControl(&m_fpuControl, "m_fpuControl");
|
|
|
|
x86Reg reg = Map_TempReg(x86_Any,-1,FALSE);
|
|
|
|
MoveVariableToX86reg(&m_fpuControl, "m_fpuControl", reg);
|
|
|
|
AndConstToX86Reg(reg, 0xF3FF);
|
|
|
|
|
2010-06-04 06:25:07 +00:00
|
|
|
if (RoundMethod == RoundDefault)
|
|
|
|
{
|
|
|
|
x86Reg RoundReg = Map_TempReg(x86_Any,-1,FALSE);
|
2012-11-17 02:18:14 +00:00
|
|
|
MoveVariableToX86reg(&g_Reg->m_RoundingModel,"m_RoundingModel", RoundReg);
|
2010-06-04 06:25:07 +00:00
|
|
|
ShiftLeftSignImmed(RoundReg,2);
|
|
|
|
OrX86RegToX86Reg(reg,RoundReg);
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Protected(RoundReg,false);
|
2010-06-04 06:25:07 +00:00
|
|
|
} else {
|
|
|
|
switch (RoundMethod) {
|
|
|
|
case RoundTruncate: OrConstToX86Reg(0x0C00, reg); break;
|
|
|
|
case RoundNearest: /*OrConstToX86Reg(0x0000, reg);*/ break;
|
|
|
|
case RoundDown: OrConstToX86Reg(0x0400, reg); break;
|
|
|
|
case RoundUp: OrConstToX86Reg(0x0800, reg); break;
|
|
|
|
default:
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->DisplayError("Unknown Rounding model");
|
2010-06-04 06:25:07 +00:00
|
|
|
}
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
MoveX86regToVariable(reg, &m_fpuControl, "m_fpuControl");
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Protected(reg,false);
|
2010-05-30 01:54:42 +00:00
|
|
|
fpuLoadControl(&m_fpuControl, "m_fpuControl");
|
2010-07-23 10:45:35 +00:00
|
|
|
SetRoundingModel(RoundMethod);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
|
2010-06-04 06:25:07 +00:00
|
|
|
void CRegInfo::ChangeFPURegFormat (int Reg, FPU_STATE OldFormat, FPU_STATE NewFormat, FPU_ROUND RoundingModel)
|
|
|
|
{
|
|
|
|
for (DWORD i = 0; i < 8; i++)
|
|
|
|
{
|
2012-10-04 20:28:59 +00:00
|
|
|
if (x86fpu_MappedTo[i] != Reg)
|
2010-06-04 06:25:07 +00:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2010-06-14 21:14:58 +00:00
|
|
|
if (x86fpu_State[i] != OldFormat || x86fpu_StateChanged[i])
|
|
|
|
{
|
2010-06-04 06:25:07 +00:00
|
|
|
UnMap_FPR(Reg,TRUE);
|
|
|
|
Load_FPR_ToTop(Reg,Reg,OldFormat);
|
2010-06-14 21:14:58 +00:00
|
|
|
} else {
|
|
|
|
CPU_Message(" regcache: Changed format of ST(%d) from %s to %s", (i - StackTopPos() + 8) & 7,Format_Name[OldFormat],Format_Name[NewFormat]);
|
2010-06-04 06:25:07 +00:00
|
|
|
}
|
2010-06-14 21:14:58 +00:00
|
|
|
FpuRoundingModel(i) = RoundingModel;
|
|
|
|
x86fpu_State[i] = NewFormat;
|
|
|
|
x86fpu_StateChanged[i] = true;
|
2010-06-04 06:25:07 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef EXTERNAL_RELEASE
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->DisplayError("ChangeFormat: Register not on stack!!");
|
2010-06-04 06:25:07 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRegInfo::Load_FPR_ToTop ( int Reg, int RegToLoad, FPU_STATE Format)
|
|
|
|
{
|
2010-07-23 10:45:35 +00:00
|
|
|
if (GetRoundingModel() != RoundDefault)
|
2010-06-04 06:25:07 +00:00
|
|
|
{
|
|
|
|
FixRoundModel(RoundDefault);
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
CPU_Message("CurrentRoundingModel: %s FpuRoundingModel(StackTopPos()): %s",RoundingModelName(GetRoundingModel()),RoundingModelName(FpuRoundingModel(StackTopPos())));
|
2010-06-04 06:25:07 +00:00
|
|
|
int i;
|
|
|
|
|
2012-11-17 00:58:31 +00:00
|
|
|
if (RegToLoad < 0) { g_Notify->DisplayError("Load_FPR_ToTop\nRegToLoad < 0 ???"); return; }
|
|
|
|
if (Reg < 0) { g_Notify->DisplayError("Load_FPR_ToTop\nReg < 0 ???"); return; }
|
2010-06-04 06:25:07 +00:00
|
|
|
|
|
|
|
if (Format == FPU_Double || Format == FPU_Qword) {
|
|
|
|
UnMap_FPR(Reg + 1,TRUE);
|
|
|
|
UnMap_FPR(RegToLoad + 1,TRUE);
|
|
|
|
} else {
|
|
|
|
if ((Reg & 1) != 0) {
|
|
|
|
for (i = 0; i < 8; i++) {
|
2012-10-04 20:28:59 +00:00
|
|
|
if (x86fpu_MappedTo[i] == (Reg - 1)) {
|
2010-06-14 21:14:58 +00:00
|
|
|
if (x86fpu_State[i] == FPU_Double || x86fpu_State[i] == FPU_Qword) {
|
2010-06-04 06:25:07 +00:00
|
|
|
UnMap_FPR(Reg,TRUE);
|
|
|
|
}
|
|
|
|
i = 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((RegToLoad & 1) != 0) {
|
|
|
|
for (i = 0; i < 8; i++) {
|
2012-10-04 20:28:59 +00:00
|
|
|
if (x86fpu_MappedTo[i] == (RegToLoad - 1)) {
|
2010-06-14 21:14:58 +00:00
|
|
|
if (x86fpu_State[i] == FPU_Double || x86fpu_State[i] == FPU_Qword) {
|
2010-06-04 06:25:07 +00:00
|
|
|
UnMap_FPR(RegToLoad,TRUE);
|
|
|
|
}
|
|
|
|
i = 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Reg == RegToLoad) {
|
|
|
|
//if different format then unmap original reg from stack
|
|
|
|
for (i = 0; i < 8; i++) {
|
2012-10-04 20:28:59 +00:00
|
|
|
if (x86fpu_MappedTo[i] != Reg)
|
2010-06-07 02:23:58 +00:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2012-10-04 20:28:59 +00:00
|
|
|
if (x86fpu_State[i] != Format) {
|
2010-06-07 02:23:58 +00:00
|
|
|
UnMap_FPR(Reg,TRUE);
|
2010-06-04 06:25:07 +00:00
|
|
|
}
|
2010-06-07 02:23:58 +00:00
|
|
|
break;
|
2010-06-04 06:25:07 +00:00
|
|
|
}
|
|
|
|
} else {
|
2010-06-07 02:23:58 +00:00
|
|
|
//if different format then unmap original reg from stack
|
|
|
|
for (i = 0; i < 8; i++)
|
|
|
|
{
|
2012-10-04 20:28:59 +00:00
|
|
|
if (x86fpu_MappedTo[i] != Reg)
|
2010-06-07 02:23:58 +00:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2012-10-04 20:28:59 +00:00
|
|
|
UnMap_FPR(Reg,x86fpu_State[i] != Format);
|
2010-06-07 02:23:58 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-06-04 06:25:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (RegInStack(RegToLoad,Format)) {
|
|
|
|
if (Reg != RegToLoad) {
|
2012-10-04 20:28:59 +00:00
|
|
|
if (x86fpu_MappedTo[(StackTopPos() - 1) & 7] != RegToLoad) {
|
2010-06-14 21:14:58 +00:00
|
|
|
UnMap_FPR(x86fpu_MappedTo[(StackTopPos() - 1) & 7],TRUE);
|
2010-06-04 06:25:07 +00:00
|
|
|
CPU_Message(" regcache: allocate ST(0) to %s", CRegName::FPR[Reg]);
|
|
|
|
fpuLoadReg(&StackTopPos(),StackPosition(RegToLoad));
|
2010-06-14 21:14:58 +00:00
|
|
|
FpuRoundingModel(StackTopPos()) = RoundDefault;
|
|
|
|
x86fpu_MappedTo[StackTopPos()] = Reg;
|
|
|
|
x86fpu_State[StackTopPos()] = Format;
|
|
|
|
x86fpu_StateChanged[StackTopPos()] = false;
|
2010-06-04 06:25:07 +00:00
|
|
|
} else {
|
2010-06-14 21:14:58 +00:00
|
|
|
UnMap_FPR(x86fpu_MappedTo[(StackTopPos() - 1) & 7],TRUE);
|
2010-06-04 06:25:07 +00:00
|
|
|
Load_FPR_ToTop (Reg, RegToLoad, Format);
|
|
|
|
}
|
|
|
|
} else {
|
2012-10-04 20:28:59 +00:00
|
|
|
x86FpuValues RegPos = x86_ST_Unknown;
|
|
|
|
for (DWORD i = 0; i < 8; i++) {
|
|
|
|
if (x86fpu_MappedTo[i] == Reg) {
|
2010-06-04 06:25:07 +00:00
|
|
|
RegPos = (x86FpuValues)i;
|
|
|
|
i = 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (RegPos == StackTopPos()) {
|
|
|
|
return;
|
|
|
|
}
|
2012-10-04 20:28:59 +00:00
|
|
|
x86FpuValues StackPos = StackPosition(Reg);
|
2010-06-04 06:25:07 +00:00
|
|
|
|
|
|
|
FpuRoundingModel(RegPos) = FpuRoundingModel(StackTopPos());
|
2010-06-14 21:14:58 +00:00
|
|
|
x86fpu_MappedTo[RegPos] = x86fpu_MappedTo[StackTopPos()];
|
|
|
|
x86fpu_State[RegPos] = x86fpu_State[StackTopPos()];
|
|
|
|
x86fpu_StateChanged[RegPos] = x86fpu_StateChanged[StackTopPos()];
|
|
|
|
CPU_Message(" regcache: allocate ST(%d) to %s", StackPos,CRegName::FPR[x86fpu_MappedTo[RegPos]]);
|
2010-06-04 06:25:07 +00:00
|
|
|
CPU_Message(" regcache: allocate ST(0) to %s", CRegName::FPR[Reg]);
|
|
|
|
|
|
|
|
fpuExchange(StackPos);
|
|
|
|
|
|
|
|
FpuRoundingModel(StackTopPos()) = RoundDefault;
|
2010-06-14 21:14:58 +00:00
|
|
|
x86fpu_MappedTo[StackTopPos()] = Reg;
|
|
|
|
x86fpu_State[StackTopPos()] = Format;
|
|
|
|
x86fpu_StateChanged[StackTopPos()] = false;
|
2010-06-04 06:25:07 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
char Name[50];
|
|
|
|
x86Reg TempReg;
|
|
|
|
|
2010-06-14 21:14:58 +00:00
|
|
|
UnMap_FPR(x86fpu_MappedTo[(StackTopPos() - 1) & 7],TRUE);
|
2010-06-04 06:25:07 +00:00
|
|
|
for (i = 0; i < 8; i++) {
|
2012-10-04 20:28:59 +00:00
|
|
|
if (x86fpu_MappedTo[i] == RegToLoad) {
|
2010-06-04 06:25:07 +00:00
|
|
|
UnMap_FPR(RegToLoad,TRUE);
|
|
|
|
i = 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CPU_Message(" regcache: allocate ST(0) to %s", CRegName::FPR[Reg]);
|
|
|
|
TempReg = Map_TempReg(x86_Any,-1,FALSE);
|
|
|
|
switch (Format) {
|
|
|
|
case FPU_Dword:
|
|
|
|
sprintf(Name,"m_FPR_S[%d]",RegToLoad);
|
2012-11-17 02:18:14 +00:00
|
|
|
MoveVariableToX86reg(&g_Reg->m_FPR_S[RegToLoad],Name,TempReg);
|
2010-06-04 06:25:07 +00:00
|
|
|
fpuLoadIntegerDwordFromX86Reg(&StackTopPos(),TempReg);
|
|
|
|
break;
|
|
|
|
case FPU_Qword:
|
|
|
|
sprintf(Name,"m_FPR_D[%d]",RegToLoad);
|
2012-11-17 02:18:14 +00:00
|
|
|
MoveVariableToX86reg(&g_Reg->m_FPR_D[RegToLoad],Name,TempReg);
|
2010-06-04 06:25:07 +00:00
|
|
|
fpuLoadIntegerQwordFromX86Reg(&StackTopPos(),TempReg);
|
|
|
|
break;
|
|
|
|
case FPU_Float:
|
|
|
|
sprintf(Name,"m_FPR_S[%d]",RegToLoad);
|
2012-11-17 02:18:14 +00:00
|
|
|
MoveVariableToX86reg(&g_Reg->m_FPR_S[RegToLoad],Name,TempReg);
|
2010-06-04 06:25:07 +00:00
|
|
|
fpuLoadDwordFromX86Reg(&StackTopPos(),TempReg);
|
|
|
|
break;
|
|
|
|
case FPU_Double:
|
|
|
|
sprintf(Name,"m_FPR_D[%d]",RegToLoad);
|
2012-11-17 02:18:14 +00:00
|
|
|
MoveVariableToX86reg(&g_Reg->m_FPR_D[RegToLoad],Name,TempReg);
|
2010-06-04 06:25:07 +00:00
|
|
|
fpuLoadQwordFromX86Reg(&StackTopPos(),TempReg);
|
|
|
|
break;
|
|
|
|
#ifndef EXTERNAL_RELEASE
|
|
|
|
default:
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->DisplayError("Load_FPR_ToTop\nUnkown format to load %d",Format);
|
2010-06-04 06:25:07 +00:00
|
|
|
#endif
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Protected(TempReg,FALSE);
|
2010-06-04 06:25:07 +00:00
|
|
|
FpuRoundingModel(StackTopPos()) = RoundDefault;
|
2010-06-14 21:14:58 +00:00
|
|
|
x86fpu_MappedTo[StackTopPos()] = Reg;
|
|
|
|
x86fpu_State[StackTopPos()] = Format;
|
|
|
|
x86fpu_StateChanged[StackTopPos()] = false;
|
2010-06-04 06:25:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CRegInfo::x86FpuValues CRegInfo::StackPosition (int Reg)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < 8; i++) {
|
2012-10-04 20:28:59 +00:00
|
|
|
if (x86fpu_MappedTo[i] == Reg) {
|
2010-06-04 06:25:07 +00:00
|
|
|
return (x86FpuValues)((i - StackTopPos()) & 7);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return x86_ST_Unknown;
|
|
|
|
}
|
|
|
|
|
2010-05-30 01:54:42 +00:00
|
|
|
CX86Ops::x86Reg CRegInfo::FreeX86Reg ( void )
|
|
|
|
{
|
2010-07-23 10:45:35 +00:00
|
|
|
if (GetX86Mapped(x86_EDI) == NotMapped && !GetX86Protected(x86_EDI)) { return x86_EDI; }
|
|
|
|
if (GetX86Mapped(x86_ESI) == NotMapped && !GetX86Protected(x86_ESI)) { return x86_ESI; }
|
|
|
|
if (GetX86Mapped(x86_EBX) == NotMapped && !GetX86Protected(x86_EBX)) { return x86_EBX; }
|
|
|
|
if (GetX86Mapped(x86_EAX) == NotMapped && !GetX86Protected(x86_EAX)) { return x86_EAX; }
|
|
|
|
if (GetX86Mapped(x86_EDX) == NotMapped && !GetX86Protected(x86_EDX)) { return x86_EDX; }
|
|
|
|
if (GetX86Mapped(x86_ECX) == NotMapped && !GetX86Protected(x86_ECX)) { return x86_ECX; }
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
x86Reg Reg = UnMap_TempReg();
|
|
|
|
if (Reg != x86_Unknown) { return Reg; }
|
|
|
|
|
2010-06-04 06:25:07 +00:00
|
|
|
int count, MapCount[10];
|
|
|
|
x86Reg MapReg[10];
|
|
|
|
|
2010-05-30 01:54:42 +00:00
|
|
|
for (count = 0; count < 10; count ++)
|
|
|
|
{
|
2010-07-23 10:45:35 +00:00
|
|
|
MapCount[count] = GetX86MapOrder((x86Reg)count);
|
2010-06-04 06:25:07 +00:00
|
|
|
MapReg[count] = (x86Reg)count;
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
for (count = 0; count < 10; count ++) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < 9; i ++) {
|
2010-06-04 06:25:07 +00:00
|
|
|
x86Reg tempReg;
|
|
|
|
DWORD temp;
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
if (MapCount[i] < MapCount[i+1]) {
|
|
|
|
temp = MapCount[i];
|
|
|
|
MapCount[i] = MapCount[i+1];
|
|
|
|
MapCount[i+1] = temp;
|
2010-06-04 06:25:07 +00:00
|
|
|
tempReg = MapReg[i];
|
2010-05-30 01:54:42 +00:00
|
|
|
MapReg[i] = MapReg[i+1];
|
2010-06-04 06:25:07 +00:00
|
|
|
MapReg[i+1] = tempReg;
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
x86Reg StackReg = x86_Unknown;
|
|
|
|
for (count = 0; count < 10; count ++)
|
|
|
|
{
|
2010-07-23 10:45:35 +00:00
|
|
|
if (MapCount[count] > 0 && GetX86Mapped(MapReg[count]) != Stack_Mapped)
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
|
|
|
if (UnMap_X86reg((x86Reg)MapReg[count]))
|
|
|
|
{
|
|
|
|
return (x86Reg)MapReg[count];
|
|
|
|
}
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
if (GetX86Mapped(MapReg[count]) == Stack_Mapped) { StackReg = MapReg[count]; }
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
if (StackReg != x86_Unknown) {
|
|
|
|
UnMap_X86reg(StackReg);
|
|
|
|
return StackReg;
|
|
|
|
}
|
2010-06-04 06:25:07 +00:00
|
|
|
|
2010-05-30 01:54:42 +00:00
|
|
|
return x86_Unknown;
|
|
|
|
}
|
|
|
|
|
|
|
|
CX86Ops::x86Reg CRegInfo::Free8BitX86Reg ( void )
|
|
|
|
{
|
|
|
|
|
2010-07-23 10:45:35 +00:00
|
|
|
if (GetX86Mapped(x86_EBX) == NotMapped && !GetX86Protected(x86_EBX)) {return x86_EBX; }
|
|
|
|
if (GetX86Mapped(x86_EAX) == NotMapped && !GetX86Protected(x86_EAX)) {return x86_EAX; }
|
|
|
|
if (GetX86Mapped(x86_EDX) == NotMapped && !GetX86Protected(x86_EDX)) {return x86_EDX; }
|
|
|
|
if (GetX86Mapped(x86_ECX) == NotMapped && !GetX86Protected(x86_ECX)) {return x86_ECX; }
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
|
2010-06-04 06:25:07 +00:00
|
|
|
x86Reg Reg = UnMap_8BitTempReg();
|
|
|
|
if (Reg > 0) { return Reg; }
|
2010-05-30 01:54:42 +00:00
|
|
|
|
2010-06-04 06:25:07 +00:00
|
|
|
int count, MapCount[10], MapReg[10];
|
2010-05-30 01:54:42 +00:00
|
|
|
for (count = 0; count < 10; count ++) {
|
2010-07-23 10:45:35 +00:00
|
|
|
MapCount[count] = GetX86MapOrder((x86Reg)count);
|
2010-05-30 01:54:42 +00:00
|
|
|
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) {
|
2010-06-04 06:25:07 +00:00
|
|
|
if (!Is8BitReg((x86Reg)count)) { continue; }
|
|
|
|
if (UnMap_X86reg((x86Reg)count)) {
|
|
|
|
return (x86Reg)count;
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-06-04 06:25:07 +00:00
|
|
|
return x86_Unknown;
|
|
|
|
}
|
2010-05-30 01:54:42 +00:00
|
|
|
|
2010-06-04 06:25:07 +00:00
|
|
|
CX86Ops::x86Reg CRegInfo::UnMap_8BitTempReg (void )
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
|
|
|
|
for (count = 0; count < 10; count ++) {
|
|
|
|
if (!Is8BitReg((x86Reg)count)) { continue; }
|
2012-11-06 08:19:22 +00:00
|
|
|
if (GetMipsRegState((x86Reg)count) == Temp_Mapped) {
|
2010-07-23 10:45:35 +00:00
|
|
|
if (GetX86Protected((x86Reg)count) == FALSE) {
|
2010-06-04 06:25:07 +00:00
|
|
|
CPU_Message(" regcache: unallocate %s from temp storage",x86_Name((x86Reg)count));
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Mapped((x86Reg)count, CRegInfo::NotMapped);
|
2010-06-04 06:25:07 +00:00
|
|
|
return (x86Reg)count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-05-30 01:54:42 +00:00
|
|
|
return x86_Unknown;
|
|
|
|
}
|
|
|
|
|
2010-10-29 03:20:25 +00:00
|
|
|
CRegInfo::x86Reg CRegInfo::Get_MemoryStack ( void ) const
|
2010-07-23 10:45:35 +00:00
|
|
|
{
|
2010-10-29 03:20:25 +00:00
|
|
|
for (int i = 0, n = sizeof(x86_Registers)/ sizeof(x86_Registers[0]); i < n; i++)
|
|
|
|
{
|
|
|
|
if (GetX86Mapped(x86_Registers[i]) == Stack_Mapped)
|
|
|
|
{
|
|
|
|
return x86_Registers[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return x86_Unknown;
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
|
2010-10-29 03:20:25 +00:00
|
|
|
CRegInfo::x86Reg CRegInfo::Map_MemoryStack ( x86Reg Reg, bool bMapRegister, bool LoadValue)
|
|
|
|
{
|
|
|
|
x86Reg CurrentMap = Get_MemoryStack();
|
2010-07-23 10:45:35 +00:00
|
|
|
if (!bMapRegister)
|
|
|
|
{
|
|
|
|
//if not mapping then just return what the current mapping is
|
|
|
|
return CurrentMap;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CurrentMap != x86_Unknown && CurrentMap == Reg)
|
|
|
|
{
|
|
|
|
//already mapped to correct reg
|
|
|
|
return CurrentMap;
|
|
|
|
}
|
|
|
|
// map a register
|
|
|
|
if (Reg == x86_Any)
|
|
|
|
{
|
|
|
|
if (CurrentMap != x86_Unknown)
|
|
|
|
{
|
|
|
|
return CurrentMap;
|
|
|
|
}
|
|
|
|
Reg = FreeX86Reg();
|
|
|
|
if (Reg == x86_Unknown)
|
|
|
|
{
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->DisplayError("Map_MemoryStack\n\nOut of registers");
|
|
|
|
g_Notify->BreakPoint(__FILE__,__LINE__);
|
2010-07-23 10:45:35 +00:00
|
|
|
}
|
|
|
|
SetX86Mapped(Reg,CRegInfo::Stack_Mapped);
|
|
|
|
CPU_Message(" regcache: allocate %s as Memory Stack",x86_Name(Reg));
|
2010-10-29 03:20:25 +00:00
|
|
|
if (LoadValue)
|
|
|
|
{
|
2012-11-17 01:15:55 +00:00
|
|
|
MoveVariableToX86reg(&g_Recompiler->MemoryStackPos(),"MemoryStack",Reg);
|
2010-10-29 03:20:25 +00:00
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
return Reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
//move to a register/allocate register
|
2010-10-23 18:53:01 +00:00
|
|
|
UnMap_X86reg(Reg);
|
|
|
|
if (CurrentMap != x86_Unknown)
|
2010-07-23 10:45:35 +00:00
|
|
|
{
|
|
|
|
CPU_Message(" regcache: change allocation of Memory Stack from %s to %s",x86_Name(CurrentMap),x86_Name(Reg));
|
2010-10-23 18:53:01 +00:00
|
|
|
SetX86Mapped(Reg, CRegInfo::Stack_Mapped);
|
|
|
|
SetX86Mapped(CurrentMap,CRegInfo::NotMapped);
|
2010-07-23 10:45:35 +00:00
|
|
|
MoveX86RegToX86Reg(CurrentMap,Reg);
|
|
|
|
} else {
|
2010-10-23 18:53:01 +00:00
|
|
|
SetX86Mapped(Reg,CRegInfo::Stack_Mapped);
|
2010-07-23 10:45:35 +00:00
|
|
|
CPU_Message(" regcache: allocate %s as Memory Stack",x86_Name(Reg));
|
2010-10-29 03:20:25 +00:00
|
|
|
if (LoadValue)
|
|
|
|
{
|
2012-11-17 01:15:55 +00:00
|
|
|
MoveVariableToX86reg(&g_Recompiler->MemoryStackPos(),"MemoryStack",Reg);
|
2010-10-29 03:20:25 +00:00
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
}
|
|
|
|
return Reg;
|
|
|
|
}
|
|
|
|
|
2012-10-22 10:36:57 +00:00
|
|
|
void CRegInfo::Map_GPR_32bit (int MipsReg, bool SignValue, int MipsRegToLoad)
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
|
|
|
int count;
|
|
|
|
|
|
|
|
x86Reg Reg;
|
2012-10-22 10:36:57 +00:00
|
|
|
if (MipsReg == 0)
|
|
|
|
{
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__,__LINE__);
|
2010-05-30 01:54:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-10-22 10:36:57 +00:00
|
|
|
if (IsUnknown(MipsReg) || IsConst(MipsReg))
|
|
|
|
{
|
2010-05-30 01:54:42 +00:00
|
|
|
Reg = FreeX86Reg();
|
|
|
|
if (Reg < 0) {
|
|
|
|
#ifndef EXTERNAL_RELEASE
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->DisplayError("Map_GPR_32bit\n\nOut of registers");
|
2010-05-30 01:54:42 +00:00
|
|
|
#endif
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__,__LINE__);
|
2010-05-30 01:54:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
CPU_Message(" regcache: allocate %s to %s",x86_Name(Reg),CRegName::GPR[MipsReg]);
|
|
|
|
} else {
|
2012-10-22 10:36:57 +00:00
|
|
|
if (Is64Bit(MipsReg))
|
|
|
|
{
|
2012-11-03 01:18:08 +00:00
|
|
|
CPU_Message(" regcache: unallocate %s from high 32bit of %s",x86_Name(GetMipsRegMapHi(MipsReg)),CRegName::GPR_Hi[MipsReg]);
|
|
|
|
SetX86MapOrder(GetMipsRegMapHi(MipsReg),0);
|
|
|
|
SetX86Mapped(GetMipsRegMapHi(MipsReg),NotMapped);
|
|
|
|
SetX86Protected(GetMipsRegMapHi(MipsReg),FALSE);
|
|
|
|
SetMipsRegHi(MipsReg,0);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
Reg = GetMipsRegMapLo(MipsReg);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
for (count = 0; count < 10; count ++)
|
|
|
|
{
|
|
|
|
DWORD Count = GetX86MapOrder((x86Reg)count);
|
2012-10-22 10:36:57 +00:00
|
|
|
if ( Count > 0)
|
|
|
|
{
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86MapOrder((x86Reg)count,Count + 1);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86MapOrder(Reg,1);
|
2010-05-30 01:54:42 +00:00
|
|
|
|
2012-10-22 10:36:57 +00:00
|
|
|
if (MipsRegToLoad > 0)
|
|
|
|
{
|
|
|
|
if (IsUnknown(MipsRegToLoad))
|
|
|
|
{
|
2010-05-30 01:54:42 +00:00
|
|
|
MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[0],CRegName::GPR_Lo[MipsRegToLoad],Reg);
|
|
|
|
} else if (IsMapped(MipsRegToLoad)) {
|
2012-10-22 10:36:57 +00:00
|
|
|
if (MipsReg != MipsRegToLoad)
|
|
|
|
{
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad),Reg);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
} else {
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveConstToX86reg(GetMipsRegLo(MipsRegToLoad),Reg);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
} else if (MipsRegToLoad == 0) {
|
|
|
|
XorX86RegToX86Reg(Reg,Reg);
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Mapped(Reg,GPR_Mapped);
|
|
|
|
SetX86Protected(Reg,TRUE);
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegMapLo(MipsReg,Reg);
|
|
|
|
SetMipsRegState(MipsReg,SignValue ? STATE_MAPPED_32_SIGN : STATE_MAPPED_32_ZERO);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CRegInfo::Map_GPR_64bit ( int MipsReg, int MipsRegToLoad)
|
|
|
|
{
|
|
|
|
x86Reg x86Hi, x86lo;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
if (MipsReg == 0) {
|
|
|
|
#ifndef EXTERNAL_RELEASE
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->DisplayError("Map_GPR_32bit\n\nWhy are you trying to map reg 0");
|
2010-05-30 01:54:42 +00:00
|
|
|
#endif
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ProtectGPR(MipsReg);
|
|
|
|
if (IsUnknown(MipsReg) || IsConst(MipsReg)) {
|
|
|
|
x86Hi = FreeX86Reg();
|
2012-11-17 00:58:31 +00:00
|
|
|
if (x86Hi < 0) { g_Notify->DisplayError("Map_GPR_64bit\n\nOut of registers"); return; }
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Protected(x86Hi,TRUE);
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
x86lo = FreeX86Reg();
|
2012-11-17 00:58:31 +00:00
|
|
|
if (x86lo < 0) { g_Notify->DisplayError("Map_GPR_64bit\n\nOut of registers"); return; }
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Protected(x86lo,TRUE);
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
CPU_Message(" regcache: allocate %s to hi word of %s",x86_Name(x86Hi),CRegName::GPR[MipsReg]);
|
|
|
|
CPU_Message(" regcache: allocate %s to low word of %s",x86_Name(x86lo),CRegName::GPR[MipsReg]);
|
|
|
|
} else {
|
2012-11-03 01:18:08 +00:00
|
|
|
x86lo = GetMipsRegMapLo(MipsReg);
|
2010-05-30 01:54:42 +00:00
|
|
|
if (Is32Bit(MipsReg)) {
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Protected(x86lo,TRUE);
|
2010-05-30 01:54:42 +00:00
|
|
|
x86Hi = FreeX86Reg();
|
2012-10-23 08:06:13 +00:00
|
|
|
if (x86Hi == x86_Unknown)
|
|
|
|
{
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__,__LINE__);
|
2012-10-23 08:06:13 +00:00
|
|
|
return;
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Protected(x86Hi,TRUE);
|
2010-10-23 18:53:01 +00:00
|
|
|
|
|
|
|
CPU_Message(" regcache: allocate %s to hi word of %s",x86_Name(x86Hi),CRegName::GPR[MipsReg]);
|
2010-05-30 01:54:42 +00:00
|
|
|
} else {
|
2012-11-03 01:18:08 +00:00
|
|
|
x86Hi = GetMipsRegMapHi(MipsReg);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-23 10:45:35 +00:00
|
|
|
for (count = 0; count < 10; count ++)
|
|
|
|
{
|
|
|
|
int MapOrder = GetX86MapOrder((x86Reg)count);
|
|
|
|
if (MapOrder > 0)
|
|
|
|
{
|
|
|
|
SetX86MapOrder((x86Reg)count,MapOrder + 1);
|
|
|
|
}
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86MapOrder(x86Hi,1);
|
|
|
|
SetX86MapOrder(x86lo,1);
|
2010-05-30 01:54:42 +00:00
|
|
|
if (MipsRegToLoad > 0) {
|
|
|
|
if (IsUnknown(MipsRegToLoad)) {
|
|
|
|
MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[1],CRegName::GPR_Hi[MipsRegToLoad],x86Hi);
|
|
|
|
MoveVariableToX86reg(&_GPR[MipsRegToLoad].UW[0],CRegName::GPR_Lo[MipsRegToLoad],x86lo);
|
|
|
|
} else if (IsMapped(MipsRegToLoad)) {
|
|
|
|
if (Is32Bit(MipsRegToLoad)) {
|
|
|
|
if (IsSigned(MipsRegToLoad)) {
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad),x86Hi);
|
2010-05-30 01:54:42 +00:00
|
|
|
ShiftRightSignImmed(x86Hi,31);
|
|
|
|
} else {
|
|
|
|
XorX86RegToX86Reg(x86Hi,x86Hi);
|
|
|
|
}
|
|
|
|
if (MipsReg != MipsRegToLoad) {
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad),x86lo);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (MipsReg != MipsRegToLoad) {
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveX86RegToX86Reg(GetMipsRegMapHi(MipsRegToLoad),x86Hi);
|
|
|
|
MoveX86RegToX86Reg(GetMipsRegMapLo(MipsRegToLoad),x86lo);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
CPU_Message("Map_GPR_64bit 11");
|
|
|
|
if (Is32Bit(MipsRegToLoad)) {
|
|
|
|
if (IsSigned(MipsRegToLoad)) {
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveConstToX86reg(GetMipsRegLo_S(MipsRegToLoad) >> 31,x86Hi);
|
2010-05-30 01:54:42 +00:00
|
|
|
} else {
|
|
|
|
MoveConstToX86reg(0,x86Hi);
|
|
|
|
}
|
|
|
|
} else {
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveConstToX86reg(GetMipsRegHi(MipsRegToLoad),x86Hi);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveConstToX86reg(GetMipsRegLo(MipsRegToLoad),x86lo);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
} else if (MipsRegToLoad == 0) {
|
|
|
|
XorX86RegToX86Reg(x86Hi,x86Hi);
|
|
|
|
XorX86RegToX86Reg(x86lo,x86lo);
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Mapped(x86Hi,GPR_Mapped);
|
|
|
|
SetX86Mapped(x86lo,GPR_Mapped);
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegMapHi(MipsReg,x86Hi);
|
|
|
|
SetMipsRegMapLo(MipsReg,x86lo);
|
|
|
|
SetMipsRegState(MipsReg,STATE_MAPPED_64);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CX86Ops::x86Reg CRegInfo::Map_TempReg (CX86Ops::x86Reg Reg, int MipsReg, BOOL LoadHiWord)
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
|
|
|
|
if (Reg == x86_Any)
|
|
|
|
{
|
2010-07-23 10:45:35 +00:00
|
|
|
if (GetX86Mapped(x86_EAX) == Temp_Mapped && !GetX86Protected(x86_EAX)) { Reg = x86_EAX; }
|
|
|
|
else if (GetX86Mapped(x86_EBX) == Temp_Mapped && !GetX86Protected(x86_EBX)) { Reg = x86_EBX; }
|
|
|
|
else if (GetX86Mapped(x86_ECX) == Temp_Mapped && !GetX86Protected(x86_ECX)) { Reg = x86_ECX; }
|
|
|
|
else if (GetX86Mapped(x86_EDX) == Temp_Mapped && !GetX86Protected(x86_EDX)) { Reg = x86_EDX; }
|
|
|
|
else if (GetX86Mapped(x86_ESI) == Temp_Mapped && !GetX86Protected(x86_ESI)) { Reg = x86_ESI; }
|
|
|
|
else if (GetX86Mapped(x86_EDI) == Temp_Mapped && !GetX86Protected(x86_EDI)) { Reg = x86_EDI; }
|
|
|
|
else if (GetX86Mapped(x86_EBP) == Temp_Mapped && !GetX86Protected(x86_EBP)) { Reg = x86_EBP; }
|
|
|
|
else if (GetX86Mapped(x86_ESP) == Temp_Mapped && !GetX86Protected(x86_ESP)) { Reg = x86_ESP; }
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
if (Reg == x86_Any) {
|
|
|
|
Reg = FreeX86Reg();
|
|
|
|
if (Reg == x86_Unknown)
|
|
|
|
{
|
|
|
|
WriteTrace(TraceError,"CRegInfo::Map_TempReg: Failed to find a free register");
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__,__LINE__);
|
2010-05-30 01:54:42 +00:00
|
|
|
return x86_Unknown;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (Reg == x86_Any8Bit)
|
|
|
|
{
|
2010-07-23 10:45:35 +00:00
|
|
|
if (GetX86Mapped(x86_EAX) == Temp_Mapped && !GetX86Protected(x86_EAX)) { Reg = x86_EAX; }
|
|
|
|
else if (GetX86Mapped(x86_EBX) == Temp_Mapped && !GetX86Protected(x86_EBX)) { Reg = x86_EBX; }
|
|
|
|
else if (GetX86Mapped(x86_ECX) == Temp_Mapped && !GetX86Protected(x86_ECX)) { Reg = x86_ECX; }
|
|
|
|
else if (GetX86Mapped(x86_EDX) == Temp_Mapped && !GetX86Protected(x86_EDX)) { Reg = x86_EDX; }
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
if (Reg == x86_Any8Bit)
|
|
|
|
{
|
|
|
|
Reg = Free8BitX86Reg();
|
|
|
|
if (Reg < 0) {
|
|
|
|
WriteTrace(TraceError,"CRegInfo::Map_TempReg: Failed to find a free 8 bit register");
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__,__LINE__);
|
2010-05-30 01:54:42 +00:00
|
|
|
return x86_Unknown;
|
|
|
|
}
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
} else if (GetX86Mapped(Reg) == GPR_Mapped) {
|
|
|
|
if (GetX86Protected(Reg))
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
|
|
|
WriteTrace(TraceError,"CRegInfo::Map_TempReg: Register is protected");
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__,__LINE__);
|
2010-05-30 01:54:42 +00:00
|
|
|
return x86_Unknown;
|
|
|
|
}
|
|
|
|
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Protected(Reg,true);
|
2010-05-30 01:54:42 +00:00
|
|
|
x86Reg NewReg = FreeX86Reg();
|
|
|
|
for (count = 1; count < 32; count ++)
|
|
|
|
{
|
|
|
|
if (!IsMapped(count))
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
if (GetMipsRegMapLo(count) == Reg)
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
|
|
|
if (NewReg == x86_Unknown)
|
|
|
|
{
|
|
|
|
UnMap_GPR(count,TRUE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
CPU_Message(" regcache: change allocation of %s from %s to %s",CRegName::GPR[count],x86_Name(Reg),x86_Name(NewReg));
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Mapped(NewReg,GPR_Mapped);
|
|
|
|
SetX86MapOrder(NewReg,GetX86MapOrder(Reg));
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegMapLo(count,NewReg);
|
2010-05-30 01:54:42 +00:00
|
|
|
MoveX86RegToX86Reg(Reg,NewReg);
|
|
|
|
if (MipsReg == count && LoadHiWord == FALSE) { MipsReg = -1; }
|
|
|
|
break;
|
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
if (Is64Bit(count) && GetMipsRegMapHi(count) == Reg)
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
|
|
|
if (NewReg == x86_Unknown)
|
|
|
|
{
|
|
|
|
UnMap_GPR(count,TRUE);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
CPU_Message(" regcache: change allocation of %s from %s to %s",CRegName::GPR_Hi[count],x86_Name(Reg),x86_Name(NewReg));
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Mapped(NewReg,GPR_Mapped);
|
|
|
|
SetX86MapOrder(NewReg,GetX86MapOrder(Reg));
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegMapHi(count,NewReg);
|
2010-05-30 01:54:42 +00:00
|
|
|
MoveX86RegToX86Reg(Reg,NewReg);
|
|
|
|
if (MipsReg == count && LoadHiWord == TRUE) { MipsReg = -1; }
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
else if (GetX86Mapped(Reg) == Stack_Mapped)
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
|
|
|
UnMap_X86reg(Reg);
|
|
|
|
}
|
2010-06-16 07:31:47 +00:00
|
|
|
CPU_Message(" regcache: allocate %s as temp storage",x86_Name(Reg));
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
if (MipsReg >= 0) {
|
|
|
|
if (LoadHiWord) {
|
|
|
|
if (IsUnknown(MipsReg))
|
|
|
|
{
|
|
|
|
MoveVariableToX86reg(&_GPR[MipsReg].UW[1],CRegName::GPR_Hi[MipsReg],Reg);
|
|
|
|
}
|
|
|
|
else if (IsMapped(MipsReg))
|
|
|
|
{
|
|
|
|
if (Is64Bit(MipsReg)) {
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveX86RegToX86Reg(GetMipsRegMapHi(MipsReg),Reg);
|
2010-05-30 01:54:42 +00:00
|
|
|
} else if (IsSigned(MipsReg)){
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveX86RegToX86Reg(GetMipsRegMapLo(MipsReg),Reg);
|
2010-05-30 01:54:42 +00:00
|
|
|
ShiftRightSignImmed(Reg,31);
|
|
|
|
} else {
|
|
|
|
MoveConstToX86reg(0,Reg);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (Is64Bit(MipsReg))
|
|
|
|
{
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveConstToX86reg(GetMipsRegHi(MipsReg),Reg);
|
2010-05-30 01:54:42 +00:00
|
|
|
} else {
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveConstToX86reg(GetMipsRegLo_S(MipsReg) >> 31,Reg);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (IsUnknown(MipsReg)) {
|
|
|
|
MoveVariableToX86reg(&_GPR[MipsReg].UW[0],CRegName::GPR_Lo[MipsReg],Reg);
|
|
|
|
} else if (IsMapped(MipsReg)) {
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveX86RegToX86Reg(GetMipsRegMapLo(MipsReg),Reg);
|
2010-05-30 01:54:42 +00:00
|
|
|
} else {
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveConstToX86reg(GetMipsRegLo(MipsReg),Reg);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Mapped(Reg,Temp_Mapped);
|
|
|
|
SetX86Protected(Reg,TRUE);
|
|
|
|
for (count = 0; count < 10; count ++)
|
|
|
|
{
|
|
|
|
int MapOrder = GetX86MapOrder((x86Reg)count);
|
|
|
|
if (MapOrder > 0) {
|
|
|
|
SetX86MapOrder((x86Reg)count,MapOrder + 1);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86MapOrder(Reg,1);
|
2010-05-30 01:54:42 +00:00
|
|
|
return Reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRegInfo::ProtectGPR(DWORD Reg) {
|
2010-05-31 00:21:08 +00:00
|
|
|
if (IsUnknown(Reg) || IsConst(Reg)) { return; }
|
2010-05-30 01:54:42 +00:00
|
|
|
if (Is64Bit(Reg)) {
|
2012-11-03 01:18:08 +00:00
|
|
|
SetX86Protected(GetMipsRegMapHi(Reg),TRUE);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
SetX86Protected(GetMipsRegMapLo(Reg),TRUE);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
|
2010-05-31 00:21:08 +00:00
|
|
|
void CRegInfo::UnProtectGPR(DWORD Reg) {
|
|
|
|
if (IsUnknown(Reg) || IsConst(Reg)) { return; }
|
|
|
|
if (Is64Bit(Reg)) {
|
2012-11-03 01:18:08 +00:00
|
|
|
SetX86Protected(GetMipsRegMapHi(Reg),false);
|
2010-05-31 00:21:08 +00:00
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
SetX86Protected(GetMipsRegMapLo(Reg),false);
|
2010-05-31 00:21:08 +00:00
|
|
|
}
|
|
|
|
|
2010-05-30 01:54:42 +00:00
|
|
|
void CRegInfo::ResetX86Protection (void)
|
|
|
|
{
|
2010-06-04 06:25:07 +00:00
|
|
|
for (int count = 0; count < 10; count ++)
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Protected((x86Reg)count, false);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-04 06:25:07 +00:00
|
|
|
BOOL CRegInfo::RegInStack( int Reg, FPU_STATE Format) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < 8; i++)
|
|
|
|
{
|
2012-10-04 20:28:59 +00:00
|
|
|
if (x86fpu_MappedTo[i] == Reg)
|
2010-06-04 06:25:07 +00:00
|
|
|
{
|
2010-06-14 21:14:58 +00:00
|
|
|
if (x86fpu_State[i] == Format || Format == FPU_Any)
|
2010-06-04 06:25:07 +00:00
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-05-30 01:54:42 +00:00
|
|
|
void CRegInfo::UnMap_AllFPRs ( void )
|
|
|
|
{
|
|
|
|
for (;;) {
|
2012-10-04 20:28:59 +00:00
|
|
|
int StackPos = StackTopPos();
|
|
|
|
if (x86fpu_MappedTo[StackPos] != -1 ) {
|
|
|
|
UnMap_FPR(x86fpu_MappedTo[StackPos],TRUE);
|
2010-05-30 01:54:42 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
//see if any more registers mapped
|
2012-10-04 20:28:59 +00:00
|
|
|
int StartPos = StackTopPos();
|
|
|
|
for (int i = 0; i < 8; i++) {
|
2010-06-14 21:14:58 +00:00
|
|
|
if (x86fpu_MappedTo[(StartPos + i) & 7] != -1 ) { fpuIncStack(&StackTopPos()); }
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
if (StackPos != StackTopPos()) { continue; }
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRegInfo::UnMap_FPR (int Reg, int WriteBackValue )
|
|
|
|
{
|
|
|
|
char Name[50];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (Reg < 0) { return; }
|
|
|
|
for (i = 0; i < 8; i++) {
|
2012-10-04 20:28:59 +00:00
|
|
|
if (x86fpu_MappedTo[i] != Reg) { continue; }
|
2010-05-30 01:54:42 +00:00
|
|
|
CPU_Message(" regcache: unallocate %s from ST(%d)",CRegName::FPR[Reg],(i - StackTopPos() + 8) & 7);
|
|
|
|
if (WriteBackValue) {
|
|
|
|
int RegPos;
|
|
|
|
|
2010-06-14 21:14:58 +00:00
|
|
|
if (((i - StackTopPos() + 8) & 7) != 0)
|
|
|
|
{
|
|
|
|
if (x86fpu_MappedTo[StackTopPos()] == -1 && x86fpu_MappedTo[(StackTopPos() + 1) & 7] == Reg)
|
|
|
|
{
|
|
|
|
fpuIncStack(&StackTopPos());
|
|
|
|
} else {
|
|
|
|
CRegInfo::FPU_ROUND RoundingModel = FpuRoundingModel(StackTopPos());
|
|
|
|
FPU_STATE RegState = x86fpu_State[StackTopPos()];
|
|
|
|
BOOL Changed = x86fpu_StateChanged[StackTopPos()];
|
|
|
|
DWORD MappedTo = x86fpu_MappedTo[StackTopPos()];
|
|
|
|
FpuRoundingModel(StackTopPos()) = FpuRoundingModel(i);
|
|
|
|
x86fpu_MappedTo[StackTopPos()] = x86fpu_MappedTo[i];
|
|
|
|
x86fpu_State[StackTopPos()] = x86fpu_State[i];
|
|
|
|
x86fpu_StateChanged[StackTopPos()] = x86fpu_StateChanged[i];
|
|
|
|
FpuRoundingModel(i) = RoundingModel;
|
|
|
|
x86fpu_MappedTo[i] = MappedTo;
|
|
|
|
x86fpu_State[i] = RegState;
|
|
|
|
x86fpu_StateChanged[i] = Changed;
|
|
|
|
fpuExchange((x86FpuValues)((i - StackTopPos()) & 7));
|
|
|
|
}
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
FixRoundModel(FpuRoundingModel(i));
|
|
|
|
|
|
|
|
RegPos = StackTopPos();
|
|
|
|
x86Reg TempReg = Map_TempReg(x86_Any,-1,FALSE);
|
2010-06-14 21:14:58 +00:00
|
|
|
switch (x86fpu_State[StackTopPos()]) {
|
2010-06-04 06:25:07 +00:00
|
|
|
case FPU_Dword:
|
2010-06-14 21:14:58 +00:00
|
|
|
sprintf(Name,"_FPR_S[%d]",x86fpu_MappedTo[StackTopPos()]);
|
|
|
|
MoveVariableToX86reg(&_FPR_S[x86fpu_MappedTo[StackTopPos()]],Name,TempReg);
|
2010-05-30 01:54:42 +00:00
|
|
|
fpuStoreIntegerDwordFromX86Reg(&StackTopPos(),TempReg, TRUE);
|
|
|
|
break;
|
2010-06-04 06:25:07 +00:00
|
|
|
case FPU_Qword:
|
2010-06-14 21:14:58 +00:00
|
|
|
sprintf(Name,"_FPR_D[%d]",x86fpu_MappedTo[StackTopPos()]);
|
|
|
|
MoveVariableToX86reg(&_FPR_D[x86fpu_MappedTo[StackTopPos()]],Name,TempReg);
|
2010-05-30 01:54:42 +00:00
|
|
|
fpuStoreIntegerQwordFromX86Reg(&StackTopPos(),TempReg, TRUE);
|
|
|
|
break;
|
2010-06-04 06:25:07 +00:00
|
|
|
case FPU_Float:
|
2010-06-14 21:14:58 +00:00
|
|
|
sprintf(Name,"_FPR_S[%d]",x86fpu_MappedTo[StackTopPos()]);
|
|
|
|
MoveVariableToX86reg(&_FPR_S[x86fpu_MappedTo[StackTopPos()]],Name,TempReg);
|
2010-05-30 01:54:42 +00:00
|
|
|
fpuStoreDwordFromX86Reg(&StackTopPos(),TempReg, TRUE);
|
|
|
|
break;
|
2010-06-04 06:25:07 +00:00
|
|
|
case FPU_Double:
|
2010-06-14 21:14:58 +00:00
|
|
|
sprintf(Name,"_FPR_D[%d]",x86fpu_MappedTo[StackTopPos()]);
|
|
|
|
MoveVariableToX86reg(&_FPR_D[x86fpu_MappedTo[StackTopPos()]],Name,TempReg);
|
2010-05-30 01:54:42 +00:00
|
|
|
fpuStoreQwordFromX86Reg(&StackTopPos(),TempReg, TRUE);
|
|
|
|
break;
|
|
|
|
#ifndef EXTERNAL_RELEASE
|
|
|
|
default:
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->DisplayError("UnMap_FPR\nUnknown format to load %d",x86fpu_State[StackTopPos()]);
|
2010-05-30 01:54:42 +00:00
|
|
|
#endif
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Protected(TempReg,FALSE);
|
2010-06-04 06:25:07 +00:00
|
|
|
FpuRoundingModel(RegPos) = RoundDefault;
|
2010-06-14 21:14:58 +00:00
|
|
|
x86fpu_MappedTo[RegPos] = -1;
|
|
|
|
x86fpu_State[RegPos] = FPU_Unknown;
|
|
|
|
x86fpu_StateChanged[RegPos] = false;
|
2010-05-30 01:54:42 +00:00
|
|
|
} else {
|
|
|
|
fpuFree((x86FpuValues)((i - StackTopPos()) & 7));
|
2010-06-04 06:25:07 +00:00
|
|
|
FpuRoundingModel(i) = RoundDefault;
|
2010-06-14 21:14:58 +00:00
|
|
|
x86fpu_MappedTo[i] = -1;
|
|
|
|
x86fpu_State[i] = FPU_Unknown;
|
|
|
|
x86fpu_StateChanged[i] = false;
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRegInfo::UnMap_GPR (DWORD Reg, bool WriteBackValue)
|
|
|
|
{
|
|
|
|
if (Reg == 0) {
|
|
|
|
#ifndef EXTERNAL_RELEASE
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->DisplayError("UnMap_GPR\n\nWhy are you trying to unmap reg 0");
|
2010-05-30 01:54:42 +00:00
|
|
|
#endif
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IsUnknown(Reg)) { return; }
|
|
|
|
//CPU_Message("UnMap_GPR: State: %X\tReg: %s\tWriteBack: %s",State,CRegName::GPR[Reg],WriteBackValue?"TRUE":"FALSE");
|
|
|
|
if (IsConst(Reg)) {
|
|
|
|
if (!WriteBackValue) {
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegState(Reg,STATE_UNKNOWN);
|
2010-05-30 01:54:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (Is64Bit(Reg)) {
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveConstToVariable(GetMipsRegHi(Reg),&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
|
|
|
|
MoveConstToVariable(GetMipsRegLo(Reg),&_GPR[Reg].UW[0],CRegName::GPR_Lo[Reg]);
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegState(Reg,STATE_UNKNOWN);
|
2010-05-30 01:54:42 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
if ((GetMipsRegLo(Reg) & 0x80000000) != 0) {
|
2010-05-30 01:54:42 +00:00
|
|
|
MoveConstToVariable(0xFFFFFFFF,&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
|
|
|
|
} else {
|
|
|
|
MoveConstToVariable(0,&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
|
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveConstToVariable(GetMipsRegLo(Reg),&_GPR[Reg].UW[0],CRegName::GPR_Lo[Reg]);
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegState(Reg,STATE_UNKNOWN);
|
2010-05-30 01:54:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (Is64Bit(Reg)) {
|
2012-11-03 01:18:08 +00:00
|
|
|
CPU_Message(" regcache: unallocate %s from %s",x86_Name(GetMipsRegMapHi(Reg)),CRegName::GPR_Hi[Reg]);
|
|
|
|
SetX86Mapped(GetMipsRegMapHi(Reg),NotMapped);
|
|
|
|
SetX86Protected(GetMipsRegMapHi(Reg),FALSE);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
CPU_Message(" regcache: unallocate %s from %s",x86_Name(GetMipsRegMapLo(Reg)),CRegName::GPR_Lo[Reg]);
|
|
|
|
SetX86Mapped(GetMipsRegMapLo(Reg),NotMapped);
|
|
|
|
SetX86Protected(GetMipsRegMapLo(Reg),FALSE);
|
2010-07-23 10:45:35 +00:00
|
|
|
if (!WriteBackValue)
|
|
|
|
{
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegState(Reg,STATE_UNKNOWN);
|
2010-05-30 01:54:42 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveX86regToVariable(GetMipsRegMapLo(Reg),&_GPR[Reg].UW[0],CRegName::GPR_Lo[Reg]);
|
2010-05-30 01:54:42 +00:00
|
|
|
if (Is64Bit(Reg)) {
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegMapLo(Reg, x86_Unknown);
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveX86regToVariable(GetMipsRegMapHi(Reg),&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegMapHi(Reg,x86_Unknown);
|
2010-11-12 05:30:08 +00:00
|
|
|
} else {
|
2012-10-14 01:05:52 +00:00
|
|
|
if (!b32BitCore()) {
|
2010-11-12 05:30:08 +00:00
|
|
|
if (IsSigned(Reg)) {
|
2012-11-03 01:18:08 +00:00
|
|
|
ShiftRightSignImmed(GetMipsRegMapLo(Reg),31);
|
|
|
|
MoveX86regToVariable(GetMipsRegMapLo(Reg),&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
|
2010-11-12 05:30:08 +00:00
|
|
|
} else {
|
|
|
|
MoveConstToVariable(0,&_GPR[Reg].UW[1],CRegName::GPR_Hi[Reg]);
|
|
|
|
}
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegMapLo(Reg, x86_Unknown);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegState(Reg,STATE_UNKNOWN);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CX86Ops::x86Reg CRegInfo::UnMap_TempReg ( void )
|
|
|
|
{
|
|
|
|
CX86Ops::x86Reg Reg = x86_Unknown;
|
|
|
|
|
2010-07-23 10:45:35 +00:00
|
|
|
if (GetX86Mapped(x86_EAX) == Temp_Mapped && !GetX86Protected(x86_EAX)) { Reg = x86_EAX; }
|
|
|
|
else if (GetX86Mapped(x86_EBX) == Temp_Mapped && !GetX86Protected(x86_EBX)) { Reg = x86_EBX; }
|
|
|
|
else if (GetX86Mapped(x86_ECX) == Temp_Mapped && !GetX86Protected(x86_ECX)) { Reg = x86_ECX; }
|
|
|
|
else if (GetX86Mapped(x86_EDX) == Temp_Mapped && !GetX86Protected(x86_EDX)) { Reg = x86_EDX; }
|
|
|
|
else if (GetX86Mapped(x86_ESI) == Temp_Mapped && !GetX86Protected(x86_ESI)) { Reg = x86_ESI; }
|
|
|
|
else if (GetX86Mapped(x86_EDI) == Temp_Mapped && !GetX86Protected(x86_EDI)) { Reg = x86_EDI; }
|
|
|
|
else if (GetX86Mapped(x86_EBP) == Temp_Mapped && !GetX86Protected(x86_EBP)) { Reg = x86_EBP; }
|
|
|
|
else if (GetX86Mapped(x86_ESP) == Temp_Mapped && !GetX86Protected(x86_ESP)) { Reg = x86_ESP; }
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
if (Reg != x86_Unknown)
|
|
|
|
{
|
2010-07-23 10:45:35 +00:00
|
|
|
if (GetX86Mapped(Reg) == Temp_Mapped)
|
2010-05-31 00:21:08 +00:00
|
|
|
{
|
|
|
|
CPU_Message(" regcache: unallocate %s from temp storage",x86_Name(Reg));
|
|
|
|
}
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Mapped(Reg,NotMapped);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
return Reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CRegInfo::UnMap_X86reg ( CX86Ops::x86Reg Reg )
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
|
2010-10-29 03:20:25 +00:00
|
|
|
if (GetX86Mapped(Reg) == NotMapped)
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
2010-10-29 03:20:25 +00:00
|
|
|
if (!GetX86Protected(Reg))
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
2010-10-29 03:20:25 +00:00
|
|
|
return TRUE;
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
2010-10-29 03:20:25 +00:00
|
|
|
} else if (GetX86Mapped(Reg) == CRegInfo::GPR_Mapped) {
|
|
|
|
for (count = 1; count < 32; count ++)
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
2010-10-29 03:20:25 +00:00
|
|
|
if (!IsMapped(count))
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
2010-10-29 03:20:25 +00:00
|
|
|
continue;
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
if (Is64Bit(count) && GetMipsRegMapHi(count) == Reg)
|
2010-10-29 03:20:25 +00:00
|
|
|
{
|
|
|
|
if (GetX86Protected(Reg) == FALSE)
|
|
|
|
{
|
|
|
|
UnMap_GPR(count,TRUE);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
if (GetMipsRegMapLo(count) == Reg)
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
2010-10-29 03:20:25 +00:00
|
|
|
if (GetX86Protected(Reg) == FALSE)
|
|
|
|
{
|
|
|
|
UnMap_GPR(count,TRUE);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
2010-10-29 03:20:25 +00:00
|
|
|
} else if (GetX86Mapped(Reg) == CRegInfo::Temp_Mapped) {
|
|
|
|
if (GetX86Protected(Reg) == FALSE) {
|
|
|
|
CPU_Message(" regcache: unallocate %s from temp storage",x86_Name(Reg));
|
|
|
|
SetX86Mapped(Reg,NotMapped);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
} else if (GetX86Mapped(Reg) == CRegInfo::Stack_Mapped) {
|
2010-05-30 01:54:42 +00:00
|
|
|
CPU_Message(" regcache: unallocate %s from Memory Stack",x86_Name(Reg));
|
2012-11-17 01:15:55 +00:00
|
|
|
MoveX86regToVariable(Reg,&(g_Recompiler->MemoryStackPos()),"MemoryStack");
|
2010-07-23 10:45:35 +00:00
|
|
|
SetX86Mapped(Reg,NotMapped);
|
2010-05-30 01:54:42 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2010-10-23 18:53:01 +00:00
|
|
|
void CRegInfo::WriteBackRegisters ()
|
2010-05-30 01:54:42 +00:00
|
|
|
{
|
2010-06-14 21:14:58 +00:00
|
|
|
UnMap_AllFPRs();
|
|
|
|
|
2010-05-30 01:54:42 +00:00
|
|
|
int count;
|
|
|
|
BOOL bEdiZero = FALSE;
|
|
|
|
BOOL bEsiSign = FALSE;
|
|
|
|
|
2010-10-23 18:53:01 +00:00
|
|
|
int X86RegCount = sizeof(x86_Registers)/ sizeof(x86_Registers[0]);
|
|
|
|
for (int i = 0; i < X86RegCount; i++) { SetX86Protected(x86_Registers[i],FALSE); }
|
|
|
|
for (int i = 0; i < X86RegCount; i++) { UnMap_X86reg(x86_Registers[i]); }
|
2010-05-30 01:54:42 +00:00
|
|
|
|
|
|
|
/*************************************/
|
|
|
|
|
|
|
|
for (count = 1; count < 32; count ++) {
|
2012-11-06 08:19:22 +00:00
|
|
|
switch (GetMipsRegState(count)) {
|
2010-05-30 01:54:42 +00:00
|
|
|
case CRegInfo::STATE_UNKNOWN: break;
|
|
|
|
case CRegInfo::STATE_CONST_32:
|
2012-10-14 01:05:52 +00:00
|
|
|
if (!b32BitCore())
|
2010-10-23 18:53:01 +00:00
|
|
|
{
|
2012-11-03 01:18:08 +00:00
|
|
|
if (!bEdiZero && (!GetMipsRegLo(count) || !(GetMipsRegLo(count) & 0x80000000))) {
|
2010-10-23 18:53:01 +00:00
|
|
|
XorX86RegToX86Reg(x86_EDI, x86_EDI);
|
|
|
|
bEdiZero = TRUE;
|
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
if (!bEsiSign && (GetMipsRegLo(count) & 0x80000000)) {
|
2010-10-23 18:53:01 +00:00
|
|
|
MoveConstToX86reg(0xFFFFFFFF, x86_ESI);
|
|
|
|
bEsiSign = TRUE;
|
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
if ((GetMipsRegLo(count) & 0x80000000) != 0) {
|
2010-10-23 18:53:01 +00:00
|
|
|
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[1],CRegName::GPR_Hi[count]);
|
|
|
|
} else {
|
|
|
|
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[1],CRegName::GPR_Hi[count]);
|
|
|
|
}
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
|
2012-11-03 01:18:08 +00:00
|
|
|
if (GetMipsRegLo(count) == 0) {
|
2012-10-14 01:05:52 +00:00
|
|
|
if (b32BitCore())
|
2010-10-23 18:53:01 +00:00
|
|
|
{
|
|
|
|
if (!bEdiZero)
|
|
|
|
{
|
|
|
|
XorX86RegToX86Reg(x86_EDI, x86_EDI);
|
|
|
|
bEdiZero = TRUE;
|
|
|
|
}
|
|
|
|
}
|
2010-05-30 01:54:42 +00:00
|
|
|
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[0],CRegName::GPR_Lo[count]);
|
2012-11-03 01:18:08 +00:00
|
|
|
} else if (GetMipsRegLo(count) == 0xFFFFFFFF) {
|
2012-10-14 01:05:52 +00:00
|
|
|
if (b32BitCore())
|
2010-10-23 18:53:01 +00:00
|
|
|
{
|
|
|
|
if (!bEsiSign)
|
|
|
|
{
|
|
|
|
MoveConstToX86reg(0xFFFFFFFF, x86_ESI);
|
|
|
|
bEsiSign = TRUE;
|
|
|
|
}
|
|
|
|
}
|
2010-05-30 01:54:42 +00:00
|
|
|
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[0],CRegName::GPR_Lo[count]);
|
|
|
|
} else
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveConstToVariable(GetMipsRegLo(count),&_GPR[count].UW[0],CRegName::GPR_Lo[count]);
|
2010-05-30 01:54:42 +00:00
|
|
|
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegState(count, CRegInfo::STATE_UNKNOWN);
|
2010-05-30 01:54:42 +00:00
|
|
|
break;
|
|
|
|
case CRegInfo::STATE_CONST_64:
|
2012-11-03 01:18:08 +00:00
|
|
|
if (GetMipsRegLo(count) == 0 || GetMipsRegHi(count) == 0) {
|
2010-05-30 01:54:42 +00:00
|
|
|
XorX86RegToX86Reg(x86_EDI, x86_EDI);
|
|
|
|
bEdiZero = TRUE;
|
|
|
|
}
|
2012-11-03 01:18:08 +00:00
|
|
|
if (GetMipsRegLo(count) == 0xFFFFFFFF || GetMipsRegHi(count) == 0xFFFFFFFF) {
|
2010-05-30 01:54:42 +00:00
|
|
|
MoveConstToX86reg(0xFFFFFFFF, x86_ESI);
|
|
|
|
bEsiSign = TRUE;
|
|
|
|
}
|
|
|
|
|
2012-11-03 01:18:08 +00:00
|
|
|
if (GetMipsRegHi(count) == 0) {
|
2010-05-30 01:54:42 +00:00
|
|
|
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[1],CRegName::GPR_Hi[count]);
|
2012-11-03 01:18:08 +00:00
|
|
|
} else if (GetMipsRegLo(count) == 0xFFFFFFFF) {
|
2010-05-30 01:54:42 +00:00
|
|
|
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[1],CRegName::GPR_Hi[count]);
|
|
|
|
} else {
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveConstToVariable(GetMipsRegHi(count),&_GPR[count].UW[1],CRegName::GPR_Hi[count]);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
|
2012-11-03 01:18:08 +00:00
|
|
|
if (GetMipsRegLo(count) == 0) {
|
2010-05-30 01:54:42 +00:00
|
|
|
MoveX86regToVariable(x86_EDI,&_GPR[count].UW[0],CRegName::GPR_Lo[count]);
|
2012-11-03 01:18:08 +00:00
|
|
|
} else if (GetMipsRegLo(count) == 0xFFFFFFFF) {
|
2010-05-30 01:54:42 +00:00
|
|
|
MoveX86regToVariable(x86_ESI,&_GPR[count].UW[0],CRegName::GPR_Lo[count]);
|
|
|
|
} else {
|
2012-11-03 01:18:08 +00:00
|
|
|
MoveConstToVariable(GetMipsRegLo(count),&_GPR[count].UW[0],CRegName::GPR_Lo[count]);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
2012-10-04 11:01:10 +00:00
|
|
|
SetMipsRegState(count, CRegInfo::STATE_UNKNOWN);
|
2010-05-30 01:54:42 +00:00
|
|
|
break;
|
|
|
|
default:
|
2012-11-06 08:19:22 +00:00
|
|
|
CPU_Message(__FUNCTION__ ": Unknown State: %d reg %d (%s)",GetMipsRegState(count),count,CRegName::GPR[count])
|
2012-11-17 00:58:31 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__,__LINE__);
|
2010-05-30 01:54:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-06-04 06:25:07 +00:00
|
|
|
|
|
|
|
const char * CRegInfo::RoundingModelName ( FPU_ROUND RoundType )
|
|
|
|
{
|
|
|
|
switch (RoundType)
|
|
|
|
{
|
|
|
|
case RoundUnknown: return "RoundUnknown";
|
|
|
|
case RoundDefault: return "RoundDefault";
|
|
|
|
case RoundTruncate: return "RoundTruncate";
|
|
|
|
case RoundNearest: return "RoundNearest";
|
|
|
|
case RoundDown: return "RoundDown";
|
|
|
|
case RoundUp: return "RoundUp";
|
|
|
|
}
|
|
|
|
return "** Invalid **";
|
|
|
|
}
|