ARM64: Shortcut moves between gpr and vfpu when not mapped

This commit is contained in:
Henrik Rydgard 2015-07-11 22:13:54 +02:00
parent 56f9aaa164
commit 9fe382ad18
5 changed files with 34 additions and 9 deletions

View file

@ -929,9 +929,14 @@ namespace MIPSComp {
// rt = 0, imm = 255 appears to be used as a CPU interlock by some games.
if (rt != 0) {
if (imm < 128) { //R(rt) = VI(imm);
fpr.MapRegV(imm, 0);
gpr.MapReg(rt, MAP_NOINIT | MAP_DIRTY);
fp.FMOV(gpr.R(rt), fpr.V(imm));
if (!fpr.IsInRAMV(imm)) {
fpr.MapRegV(imm, 0);
gpr.MapReg(rt, MAP_NOINIT | MAP_DIRTY);
fp.FMOV(gpr.R(rt), fpr.V(imm));
} else {
gpr.MapReg(rt, MAP_NOINIT | MAP_DIRTY);
LDR(INDEX_UNSIGNED, gpr.R(rt), CTXREG, fpr.GetMipsRegOffsetV(imm));
}
} else if (imm < 128 + VFPU_CTRL_MAX) { //mtvc
if (imm - 128 == VFPU_CTRL_CC) {
if (gpr.IsImm(MIPS_REG_VFPUCC)) {
@ -955,9 +960,17 @@ namespace MIPSComp {
case 7: // mtv
if (imm < 128) {
gpr.MapReg(rt);
fpr.MapRegV(imm, MAP_DIRTY | MAP_NOINIT);
fp.FMOV(fpr.V(imm), gpr.R(rt));
if (rt == MIPS_REG_ZERO) {
fpr.MapRegV(imm, MAP_DIRTY | MAP_NOINIT);
fp.MOVI2F(fpr.V(imm), 0.0f, SCRATCH1);
} else if (!gpr.IsInRAM(rt)) {
gpr.MapReg(rt);
fpr.MapRegV(imm, MAP_DIRTY | MAP_NOINIT);
fp.FMOV(fpr.V(imm), gpr.R(rt));
} else {
fpr.MapRegV(imm, MAP_DIRTY | MAP_NOINIT);
fp.LDR(32, INDEX_UNSIGNED, fpr.V(imm), CTXREG, gpr.GetMipsRegOffset(rt));
}
} else if (imm < 128 + VFPU_CTRL_MAX) { //mtvc //currentMIPS->vfpuCtrl[imm - 128] = R(rt);
if (imm - 128 == VFPU_CTRL_CC) {
if (gpr.IsImm(rt)) {

View file

@ -134,6 +134,10 @@ void Arm64RegCache::FlushBeforeCall() {
FlushArmReg(W30);
}
bool Arm64RegCache::IsInRAM(MIPSGPReg reg) {
return mr[reg].loc == ML_MEM;
}
bool Arm64RegCache::IsMapped(MIPSGPReg mipsReg) {
return mr[mipsReg].loc == ML_ARMREG || mr[mipsReg].loc == ML_ARMREG_IMM;
}

View file

@ -109,6 +109,7 @@ public:
bool IsMapped(MIPSGPReg reg);
bool IsMappedAsPointer(MIPSGPReg reg);
bool IsInRAM(MIPSGPReg reg);
void MarkDirty(Arm64Gen::ARM64Reg reg);
void MapIn(MIPSGPReg rs);

View file

@ -110,6 +110,10 @@ bool Arm64RegCacheFPU::IsMapped(MIPSReg r) {
return mr[r].loc == ML_ARMREG;
}
bool Arm64RegCacheFPU::IsInRAM(MIPSReg r) {
return mr[r].loc == ML_MEM;
}
ARM64Reg Arm64RegCacheFPU::MapReg(MIPSReg mipsReg, int mapFlags) {
// INFO_LOG(JIT, "FPR MapReg: %i flags=%i", mipsReg, mapFlags);
if (jo_->useASIMDVFPU && mipsReg >= 32) {

View file

@ -114,6 +114,9 @@ public:
void MapDirtyIn(MIPSReg rd, MIPSReg rs, bool avoidLoad = true);
void MapDirtyInIn(MIPSReg rd, MIPSReg rs, MIPSReg rt, bool avoidLoad = true);
bool IsMapped(MIPSReg r);
bool IsMappedV(MIPSReg r) { return IsMapped((MIPSReg)(r + 32)); }
bool IsInRAM(MIPSReg r);
bool IsInRAMV(MIPSReg r) { return IsInRAM((MIPSReg)(r + 32)); }
void FlushArmReg(Arm64Gen::ARM64Reg r);
void FlushR(MIPSReg r);
void DiscardR(MIPSReg r);
@ -145,14 +148,14 @@ public:
void SetEmitter(Arm64Gen::ARM64XEmitter *emitter, Arm64Gen::ARM64FloatEmitter *fp) { emit_ = emitter; fp_ = fp; }
int GetMipsRegOffset(MIPSReg r);
int GetMipsRegOffsetV(MIPSReg r) {
return GetMipsRegOffset(r + 32);
}
private:
Arm64Gen::ARM64Reg ARM64RegForFlush(int r);
MIPSReg GetTempR();
const Arm64Gen::ARM64Reg *GetMIPSAllocationOrder(int &count);
int GetMipsRegOffsetV(MIPSReg r) {
return GetMipsRegOffset(r + 32);
}
void SetupInitialRegs();