Regcache fixes, etc. thing still don't work when I turn on addiu :(

This commit is contained in:
Henrik Rydgard 2013-01-09 11:20:48 +01:00
parent ea3055322c
commit dafc9f62df
10 changed files with 112 additions and 51 deletions

View File

@ -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;

View File

@ -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); }
@ -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 );

View File

@ -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) {

View File

@ -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
{

View File

@ -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);

View File

@ -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;

View File

@ -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();

View File

@ -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));

View File

@ -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;
}
}

View File

@ -113,6 +113,7 @@ public:
void Reset();
void DoState(PointerWrap &p);
// MUST start with r!
u32 r[32];
float f[32];
float v[128];