mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Regcache fixes, etc. thing still don't work when I turn on addiu :(
This commit is contained in:
parent
ea3055322c
commit
dafc9f62df
@ -29,6 +29,33 @@
|
||||
namespace ArmGen
|
||||
{
|
||||
|
||||
inline u32 RotR(u32 a, int amount) {
|
||||
return (a >> amount) | (a << (31 - amount));
|
||||
}
|
||||
|
||||
bool TryMakeOperand2(u32 imm, Operand2 &op2) {
|
||||
// Just brute force it.
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((imm & 0xFF) == imm) {
|
||||
op2 = Operand2((u8)imm, (u8)i);
|
||||
return true;
|
||||
}
|
||||
imm = RotR(imm, 2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TryMakeOperand2_AllowInverse(u32 imm, Operand2 &op2, bool *inverse)
|
||||
{
|
||||
if (!TryMakeOperand2(imm, op2)) {
|
||||
*inverse = true;
|
||||
return TryMakeOperand2(~imm, op2);
|
||||
} else {
|
||||
*inverse = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void ARMXEmitter::SetCodePtr(u8 *ptr)
|
||||
{
|
||||
code = ptr;
|
||||
|
@ -112,7 +112,6 @@ enum OpType
|
||||
TYPE_MEM
|
||||
};
|
||||
|
||||
|
||||
// This is no longer a proper operand2 class. Need to split up.
|
||||
class Operand2
|
||||
{
|
||||
@ -298,6 +297,12 @@ public:
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
bool TryMakeOperand2(u32 imm, Operand2 &op2);
|
||||
bool TryMakeOperand2_AllowInverse(u32 imm, Operand2 &op2, bool *inverse);
|
||||
|
||||
|
||||
inline Operand2 R(ARMReg Reg) { return Operand2(Reg, TYPE_REG); }
|
||||
inline Operand2 IMM(u32 Imm) { return Operand2(Imm, TYPE_IMM); }
|
||||
inline Operand2 Mem(void *ptr) { return Operand2((u32)ptr, TYPE_IMM); }
|
||||
@ -401,7 +406,7 @@ public:
|
||||
void LSLS(ARMReg dest, ARMReg src, ARMReg op2);
|
||||
void SBC (ARMReg dest, ARMReg src, Operand2 op2);
|
||||
void SBCS(ARMReg dest, ARMReg src, Operand2 op2);
|
||||
void REV (ARMReg dest, ARMReg src );
|
||||
void REV (ARMReg dest, ARMReg src);
|
||||
void RSC (ARMReg dest, ARMReg src, Operand2 op2);
|
||||
void RSCS(ARMReg dest, ARMReg src, Operand2 op2);
|
||||
void TST ( ARMReg src, Operand2 op2);
|
||||
@ -429,7 +434,7 @@ public:
|
||||
void SXTB(ARMReg dest, ARMReg op2);
|
||||
void SXTH(ARMReg dest, ARMReg op2, u8 rotation = 0);
|
||||
void SXTAH(ARMReg dest, ARMReg src, ARMReg op2, u8 rotation = 0);
|
||||
// Using just MSR here messes with our defines on the PPC side of stuff
|
||||
// Using just MSR here messes with our defines on the PPC side of stuff (when this code was in dolphin...)
|
||||
// Just need to put an underscore here, bit annoying.
|
||||
void _MSR (bool nzcvq, bool g, Operand2 op2);
|
||||
void _MSR (bool nzcvq, bool g, ARMReg src );
|
||||
|
@ -718,7 +718,7 @@ u32 sceMpegUnRegistStream(u32 mpeg, int streamUid)
|
||||
return -1;
|
||||
}
|
||||
|
||||
StreamInfo info;
|
||||
StreamInfo info = {0};
|
||||
|
||||
switch (info.type) {
|
||||
case MPEG_AVC_STREAM:
|
||||
@ -1051,7 +1051,8 @@ u32 sceMpegChangeGetAuMode(u32 mpeg, int streamUid, int mode)
|
||||
return -1;
|
||||
}
|
||||
|
||||
StreamInfo info;
|
||||
// NOTE: Where is the info supposed to come from?
|
||||
StreamInfo info = {0};
|
||||
info.sid = streamUid;
|
||||
if (info.sid) {
|
||||
switch (info.type) {
|
||||
|
@ -34,20 +34,25 @@ using namespace MIPSAnalyst;
|
||||
|
||||
namespace MIPSComp
|
||||
{
|
||||
/*
|
||||
void Jit::CompImmLogic(u32 op, void (ARMXEmitter::*arith)(ARMReg dst, ARMReg src, Operand2 op2))
|
||||
u32 EvalOR(u32 a, u32 b) { return a | b; }
|
||||
u32 EvalXOR(u32 a, u32 b) { return a ^ b; }
|
||||
u32 EvalAND(u32 a, u32 b) { return a & b; }
|
||||
|
||||
|
||||
void Jit::CompImmLogic(int rs, int rt, u32 uimm, void (ARMXEmitter::*arith)(ARMReg dst, ARMReg src, Operand2 op2), u32 (*eval)(u32 a, u32 b))
|
||||
{
|
||||
u32 uimm = (u16)(op & 0xFFFF);
|
||||
gpr.SpillLock()
|
||||
int rt = _RT;
|
||||
int rs = _RS;
|
||||
gpr.Lock(rt, rs);
|
||||
gpr.BindToRegister(rt, rt == rs, true);
|
||||
if (rt != rs)
|
||||
MOV(32, gpr.R(rt), gpr.R(rs));
|
||||
(this->*arith)(32, gpr.R(rt), Imm32(uimm));
|
||||
gpr.UnlockAll();
|
||||
}*/
|
||||
if (gpr.IsImm(rs)) {
|
||||
gpr.SetImm(rt, (*eval)(gpr.GetImm(rs), uimm));
|
||||
} else {
|
||||
gpr.SpillLock(rs, rt);
|
||||
gpr.MapReg(rt, MAP_INITVAL | MAP_DIRTY);
|
||||
gpr.MapReg(rs, MAP_INITVAL);
|
||||
gpr.ReleaseSpillLocks();
|
||||
// TODO: Special case when uimm can be represented as an Operand2
|
||||
ARMABI_MOVI2R(R0, (u32)uimm);
|
||||
(this->*arith)(gpr.R(rt), gpr.R(rs), R0);
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::Comp_IType(u32 op)
|
||||
{
|
||||
@ -59,26 +64,31 @@ namespace MIPSComp
|
||||
|
||||
switch (op >> 26)
|
||||
{
|
||||
/*
|
||||
case 8: // same as addiu?
|
||||
case 9: //R(rt) = R(rs) + simm; break; //addiu
|
||||
{
|
||||
if (gpr.IsImm(rs))
|
||||
{
|
||||
if (gpr.IsImm(rs)) {
|
||||
gpr.SetImm(rt, gpr.GetImm(rs) + simm);
|
||||
break;
|
||||
} else if (rs == 0) {
|
||||
}/* else if (rs == 0) {
|
||||
gpr.SetImm(rt, simm);
|
||||
} else {
|
||||
gpr.SpillLock(rs, rt);
|
||||
gpr.MapReg(rs, MAP_INITVAL);
|
||||
gpr.MapReg(rt, MAP_INITVAL | MAP_DIRTY);
|
||||
Operand2 op2;
|
||||
if (false && TryMakeOperand2(simm, op2)) {
|
||||
ADD(gpr.R(rt), gpr.R(rs), op2);
|
||||
} else {
|
||||
ARMABI_MOVI2R(R0, (u32)simm);
|
||||
ADD(gpr.R(rt), gpr.R(rs), R0);
|
||||
}
|
||||
gpr.ReleaseSpillLocks();
|
||||
}*/
|
||||
else {
|
||||
Comp_Generic(op);
|
||||
}
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
/*
|
||||
case 13: // OR
|
||||
{
|
||||
|
@ -63,7 +63,6 @@ void Jit::BranchRSRTComp(u32 op, ArmGen::CCFlags cc, bool likely)
|
||||
}
|
||||
// The delay slot being nice doesn't really matter though...
|
||||
|
||||
/*
|
||||
if (rt == 0)
|
||||
{
|
||||
gpr.MapReg(rs, MAP_INITVAL);
|
||||
@ -74,9 +73,7 @@ void Jit::BranchRSRTComp(u32 op, ArmGen::CCFlags cc, bool likely)
|
||||
gpr.MapReg(rt, MAP_INITVAL);
|
||||
CMP(gpr.R(rt), Operand2(0));
|
||||
}
|
||||
|
||||
else
|
||||
*/
|
||||
{
|
||||
gpr.SpillLock(rs, rt);
|
||||
gpr.MapReg(rs, MAP_INITVAL);
|
||||
|
@ -115,6 +115,7 @@ void Jit::Comp_FPULS(u32 op)
|
||||
|
||||
void Jit::Comp_FPU2op(u32 op)
|
||||
{
|
||||
OLDD
|
||||
int fs = _FS;
|
||||
int fd = _FD;
|
||||
|
||||
@ -173,6 +174,7 @@ void Jit::Comp_FPU2op(u32 op)
|
||||
|
||||
void Jit::Comp_mxc1(u32 op)
|
||||
{
|
||||
OLDD
|
||||
int fs = _FS;
|
||||
int rt = _RT;
|
||||
|
||||
|
@ -127,7 +127,11 @@ const u8 *Jit::DoJit(u32 em_address, ArmJitBlock *b)
|
||||
|
||||
int numInstructions = 0;
|
||||
int cycles = 0;
|
||||
// #define LOGASM
|
||||
|
||||
static int logBlocks = 20;
|
||||
if (logBlocks > 0) logBlocks--;
|
||||
|
||||
#define LOGASM
|
||||
#ifdef LOGASM
|
||||
char temp[256];
|
||||
#endif
|
||||
@ -135,8 +139,10 @@ const u8 *Jit::DoJit(u32 em_address, ArmJitBlock *b)
|
||||
{
|
||||
u32 inst = Memory::Read_Instruction(js.compilerPC);
|
||||
#ifdef LOGASM
|
||||
if (logBlocks > 0) {
|
||||
MIPSDisAsm(inst, js.compilerPC, temp, true);
|
||||
INFO_LOG(DYNA_REC, "M: %08x %s", js.compilerPC, temp);
|
||||
}
|
||||
#endif
|
||||
js.downcountAmount += MIPSGetInstructionCycleEstimate(inst);
|
||||
|
||||
@ -146,14 +152,19 @@ const u8 *Jit::DoJit(u32 em_address, ArmJitBlock *b)
|
||||
numInstructions++;
|
||||
}
|
||||
#ifdef LOGASM
|
||||
if (logBlocks > 0) {
|
||||
MIPSDisAsm(Memory::Read_Instruction(js.compilerPC), js.compilerPC, temp, true);
|
||||
INFO_LOG(DYNA_REC, "M: %08x %s", js.compilerPC, temp);
|
||||
}
|
||||
#endif
|
||||
|
||||
b->codeSize = GetCodePtr() - b->normalEntry;
|
||||
|
||||
#ifdef LOGASM
|
||||
DisassembleArm(b->checkedEntry, GetCodePtr() - b->checkedEntry);
|
||||
if (logBlocks > 0) {
|
||||
INFO_LOG(DYNA_REC, "=============== ARM ===============");
|
||||
DisassembleArm(b->normalEntry, GetCodePtr() - b->normalEntry);
|
||||
}
|
||||
#endif
|
||||
AlignCode16();
|
||||
|
||||
|
@ -110,8 +110,8 @@ private:
|
||||
void BranchRSRTComp(u32 op, ArmGen::CCFlags cc, bool likely);
|
||||
|
||||
// Utilities to reduce duplicated code
|
||||
void CompImmLogic(int rs, int rt, u32 uimm, void (ARMXEmitter::*arith)(ARMReg dst, ARMReg src, Operand2 op2), u32 (*eval)(u32 a, u32 b));
|
||||
/*
|
||||
void CompImmLogic(u32 op, void (ARMXEmitter::*arith)(ARMReg dst, ARMReg src, Operand2 op2));
|
||||
void CompImmLogic(u32 op, void (ARMXEmitter::*arith)(int, const OpArg &, const OpArg &));
|
||||
void CompTriArith(u32 op, void (ARMXEmitter::*arith)(int, const OpArg &, const OpArg &));
|
||||
void CompShiftImm(u32 op, void (ARMXEmitter::*shift)(int, OpArg, OpArg));
|
||||
|
@ -57,17 +57,20 @@ static const ARMReg *GetMIPSAllocationOrder(int &count) {
|
||||
}
|
||||
|
||||
ARMReg ArmRegCache::MapReg(MIPSReg mipsReg, int mapFlags) {
|
||||
// Let's see if it's already mapped.
|
||||
for (int i = 0; i < NUM_ARMREG; i++) {
|
||||
if (ar[i].mipsReg == mipsReg) {
|
||||
if (mapFlags & MAP_DIRTY)
|
||||
ar[i].isDirty = true;
|
||||
// Already mapped, no need to do anything more.
|
||||
return (ARMReg)i;
|
||||
// Let's see if it's already mapped. If so we just need to update the dirty flag.
|
||||
// We don't need to check for ML_INITVAL because we assume that anyone who maps
|
||||
// with that flag immediately writes a "known" value to the register.
|
||||
if (mr[mipsReg].loc == ML_ARMREG) {
|
||||
if (ar[mr[mipsReg].reg].mipsReg != mipsReg) {
|
||||
ERROR_LOG(HLE, "Mapping out of sync! %i", mipsReg);
|
||||
}
|
||||
if (mapFlags & MAP_DIRTY) {
|
||||
ar[mr[mipsReg].reg].isDirty = true;
|
||||
}
|
||||
return mr[mipsReg].reg;
|
||||
}
|
||||
|
||||
// Okay, so we need to allocate one.
|
||||
// Okay, not mapped, so we need to allocate an ARM register.
|
||||
|
||||
int allocCount;
|
||||
const ARMReg *allocOrder = GetMIPSAllocationOrder(allocCount);
|
||||
@ -114,6 +117,7 @@ void ArmRegCache::FlushArmReg(ARMReg r) {
|
||||
if (ar[r].mipsReg != -1) {
|
||||
if (ar[r].isDirty && mr[ar[r].mipsReg].loc == ML_ARMREG)
|
||||
emit->STR(CTXREG, r, 4 * ar[r].mipsReg);
|
||||
// IMMs won't be in an ARM reg.
|
||||
mr[ar[r].mipsReg].loc = ML_MEM;
|
||||
} else {
|
||||
ERROR_LOG(HLE, "Dirty but no mipsreg?");
|
||||
@ -151,11 +155,12 @@ void ArmRegCache::FlushAll() {
|
||||
}
|
||||
|
||||
void ArmRegCache::SetImm(MIPSReg r, u32 immVal) {
|
||||
// Zap existing value
|
||||
// Zap existing value if cached in a reg
|
||||
if (mr[r].loc == ML_ARMREG)
|
||||
ar[mr[r].reg].mipsReg = -1;
|
||||
mr[r].loc = ML_IMM;
|
||||
mr[r].imm = immVal;
|
||||
mr[r].reg = INVALID_REG;
|
||||
}
|
||||
|
||||
bool ArmRegCache::IsImm(MIPSReg r) const {
|
||||
@ -163,7 +168,9 @@ bool ArmRegCache::IsImm(MIPSReg r) const {
|
||||
}
|
||||
|
||||
u32 ArmRegCache::GetImm(MIPSReg r) const {
|
||||
// TODO: Check.
|
||||
if (mr[r].loc != ML_IMM) {
|
||||
ERROR_LOG(JIT, "Trying to get imm from non-imm register %i", r);
|
||||
}
|
||||
return mr[r].imm;
|
||||
}
|
||||
|
||||
@ -176,8 +183,8 @@ int ArmRegCache::GetMipsRegOffset(MIPSReg r) {
|
||||
case MIPSREG_LO:
|
||||
return offsetof(MIPSState, lo);
|
||||
}
|
||||
_dbg_assert_msg_(JIT, false, "bad mips register %i", (int)r);
|
||||
return -999; // boom!
|
||||
ERROR_LOG(JIT, "bad mips register %i", r);
|
||||
return 0; // or what?
|
||||
}
|
||||
|
||||
void ArmRegCache::SpillLock(MIPSReg r1, MIPSReg r2, MIPSReg r3) {
|
||||
@ -187,7 +194,7 @@ void ArmRegCache::SpillLock(MIPSReg r1, MIPSReg r2, MIPSReg r3) {
|
||||
}
|
||||
|
||||
void ArmRegCache::ReleaseSpillLocks() {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
for (int i = 0; i < NUM_ARMREG; i++) {
|
||||
ar[i].spillLock = false;
|
||||
}
|
||||
}
|
||||
|
@ -113,6 +113,7 @@ public:
|
||||
void Reset();
|
||||
void DoState(PointerWrap &p);
|
||||
|
||||
// MUST start with r!
|
||||
u32 r[32];
|
||||
float f[32];
|
||||
float v[128];
|
||||
|
Loading…
Reference in New Issue
Block a user