mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-02 02:52:30 +02:00
Merge pull request #2272 from phire/jitil-floatbug
JitIL: Fix a bug in floatpoint load/store instructions.
This commit is contained in:
commit
3817dd0f91
@ -43,8 +43,19 @@ struct RegInfo
|
|||||||
JitIL *Jit;
|
JitIL *Jit;
|
||||||
IRBuilder* Build;
|
IRBuilder* Build;
|
||||||
InstLoc FirstI;
|
InstLoc FirstI;
|
||||||
|
|
||||||
|
// IInfo contains (per instruction)
|
||||||
|
// Bits 0-1: Saturating count of number of instructions referencing this instruction.
|
||||||
|
// Bits 2-3: single bit per operand marking if this is the last instruction to reference that operand's result.
|
||||||
|
// Used to decide if we should free any registers associated with the operands after this instruction
|
||||||
|
// and if we can clobber the operands registers.
|
||||||
|
// Warning, Memory instruction use these bits slightly differently.
|
||||||
|
// Bits 15-31: Spill location
|
||||||
std::vector<unsigned> IInfo;
|
std::vector<unsigned> IInfo;
|
||||||
|
|
||||||
|
// The last instruction which uses the result of this instruction. Used by the register allocator.
|
||||||
std::vector<InstLoc> lastUsed;
|
std::vector<InstLoc> lastUsed;
|
||||||
|
|
||||||
InstLoc regs[MAX_NUMBER_OF_REGS];
|
InstLoc regs[MAX_NUMBER_OF_REGS];
|
||||||
InstLoc fregs[MAX_NUMBER_OF_REGS];
|
InstLoc fregs[MAX_NUMBER_OF_REGS];
|
||||||
unsigned numSpills;
|
unsigned numSpills;
|
||||||
@ -412,6 +423,8 @@ static X64Reg regBinLHSReg(RegInfo& RI, InstLoc I)
|
|||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear any registers which end their lifetime at I
|
||||||
|
// Don't use this for special instructions like memory load/stores
|
||||||
static void regNormalRegClear(RegInfo& RI, InstLoc I)
|
static void regNormalRegClear(RegInfo& RI, InstLoc I)
|
||||||
{
|
{
|
||||||
if (RI.IInfo[I - RI.FirstI] & 4)
|
if (RI.IInfo[I - RI.FirstI] & 4)
|
||||||
@ -420,6 +433,7 @@ static void regNormalRegClear(RegInfo& RI, InstLoc I)
|
|||||||
regClearInst(RI, getOp2(I));
|
regClearInst(RI, getOp2(I));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear any floating point registers which end their lifetime at I
|
||||||
static void fregNormalRegClear(RegInfo& RI, InstLoc I)
|
static void fregNormalRegClear(RegInfo& RI, InstLoc I)
|
||||||
{
|
{
|
||||||
if (RI.IInfo[I - RI.FirstI] & 4)
|
if (RI.IInfo[I - RI.FirstI] & 4)
|
||||||
@ -1563,7 +1577,6 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
|||||||
RI.Jit->SafeLoadToReg(RSCRATCH2, info.first, 32, info.second, regsInUse(RI), false);
|
RI.Jit->SafeLoadToReg(RSCRATCH2, info.first, 32, info.second, regsInUse(RI), false);
|
||||||
Jit->MOVD_xmm(reg, R(RSCRATCH2));
|
Jit->MOVD_xmm(reg, R(RSCRATCH2));
|
||||||
RI.fregs[reg] = I;
|
RI.fregs[reg] = I;
|
||||||
regNormalRegClear(RI, I);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LoadDouble:
|
case LoadDouble:
|
||||||
@ -1577,7 +1590,6 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
|||||||
RI.Jit->SafeLoadToReg(RSCRATCH2, info.first, 64, info.second, regsInUse(RI), false);
|
RI.Jit->SafeLoadToReg(RSCRATCH2, info.first, 64, info.second, regsInUse(RI), false);
|
||||||
Jit->MOVQ_xmm(reg, R(RSCRATCH2));
|
Jit->MOVQ_xmm(reg, R(RSCRATCH2));
|
||||||
RI.fregs[reg] = I;
|
RI.fregs[reg] = I;
|
||||||
regNormalRegClear(RI, I);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LoadPaired:
|
case LoadPaired:
|
||||||
@ -1624,8 +1636,6 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
|||||||
|
|
||||||
if (RI.IInfo[I - RI.FirstI] & 4)
|
if (RI.IInfo[I - RI.FirstI] & 4)
|
||||||
fregClearInst(RI, getOp1(I));
|
fregClearInst(RI, getOp1(I));
|
||||||
if (RI.IInfo[I - RI.FirstI] & 8)
|
|
||||||
regClearInst(RI, getOp2(I));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case StoreDouble:
|
case StoreDouble:
|
||||||
@ -1646,8 +1656,6 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress)
|
|||||||
|
|
||||||
if (RI.IInfo[I - RI.FirstI] & 4)
|
if (RI.IInfo[I - RI.FirstI] & 4)
|
||||||
fregClearInst(RI, getOp1(I));
|
fregClearInst(RI, getOp1(I));
|
||||||
if (RI.IInfo[I - RI.FirstI] & 8)
|
|
||||||
regClearInst(RI, getOp2(I));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case StorePaired:
|
case StorePaired:
|
||||||
|
Loading…
Reference in New Issue
Block a user