From f6662054bdd82188db1b4ef46ad5fcd1fc16a432 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 5 Nov 2013 00:25:42 -0800 Subject: [PATCH 1/2] Fix arm emitter bug in LDRH and friends. --- Common/ArmEmitter.cpp | 2 +- GPU/GLES/VertexDecoder.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Common/ArmEmitter.cpp b/Common/ArmEmitter.cpp index 75a9b68af2..96ebc1e11a 100644 --- a/Common/ArmEmitter.cpp +++ b/Common/ArmEmitter.cpp @@ -816,7 +816,7 @@ void ARMXEmitter::WriteStoreOp(u32 Op, ARMReg Rt, ARMReg Rn, Operand2 Rm, bool R Data = abs(Temp); // The offset is encoded differently on this one. if (SpecialOp) - Data = (Data & 0xF0 << 4) | (Data & 0xF); + Data = ((Data & 0xF0) << 4) | (Data & 0xF); if (Temp >= 0) Add = true; } break; diff --git a/GPU/GLES/VertexDecoder.cpp b/GPU/GLES/VertexDecoder.cpp index 5c3e30a7d7..395ed92eab 100644 --- a/GPU/GLES/VertexDecoder.cpp +++ b/GPU/GLES/VertexDecoder.cpp @@ -1078,7 +1078,7 @@ void VertexDecoderJitCache::Jit_PosS8() { // Copy 6 bytes and then 2 zeroes. void VertexDecoderJitCache::Jit_PosS16() { LDR(tempReg1, srcReg, dec_->posoff); - LDR(tempReg2, srcReg, dec_->posoff + 4); // WARNING: This SHOULD be an LDRH but things break! why? + LDRH(tempReg2, srcReg, dec_->posoff + 4); STR(tempReg1, dstReg, dec_->decFmt.posoff); STR(tempReg2, dstReg, dec_->decFmt.posoff + 4); } @@ -1474,7 +1474,7 @@ void VertexDecoderJitCache::Jit_PosFloat() { bool VertexDecoderJitCache::CompileStep(const VertexDecoder &dec, int step) { // See if we find a matching JIT function - for (int i = 0; i < ARRAY_SIZE(jitLookup); i++) { + for (size_t i = 0; i < ARRAY_SIZE(jitLookup); i++) { if (dec.steps_[step] == jitLookup[i].func) { ((*this).*jitLookup[i].jitFunc)(); return true; From c7edf73cdb89d046c81d36a032aad0b5a0902267 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 5 Nov 2013 00:31:00 -0800 Subject: [PATCH 2/2] Small optimizations to the vertexjit. --- GPU/GLES/VertexDecoder.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/GPU/GLES/VertexDecoder.cpp b/GPU/GLES/VertexDecoder.cpp index 395ed92eab..91126e8aaa 100644 --- a/GPU/GLES/VertexDecoder.cpp +++ b/GPU/GLES/VertexDecoder.cpp @@ -1034,16 +1034,13 @@ void VertexDecoderJitCache::Jit_NormalS16() { } void VertexDecoderJitCache::Jit_NormalFloat() { - //ADD(scratchReg, srcReg, dec_->nrmoff); - //LDMIA(scratchReg, false, 3, tempReg1, tempReg2, tempReg3); - //ADD(scratchReg, dstReg, dec_->decFmt.nrmoff); - //STMIA(scratchReg, false, 3, tempReg1, tempReg2, tempReg3); + // Might not be aligned to 4, so we can't use LDMIA. LDR(tempReg1, srcReg, dec_->nrmoff); LDR(tempReg2, srcReg, dec_->nrmoff + 4); LDR(tempReg3, srcReg, dec_->nrmoff + 8); - STR(tempReg1, dstReg, dec_->decFmt.nrmoff); - STR(tempReg2, dstReg, dec_->decFmt.nrmoff + 4); - STR(tempReg3, dstReg, dec_->decFmt.nrmoff + 8); + // But this is always aligned to 4 so we're safe. + ADD(scratchReg, dstReg, dec_->decFmt.nrmoff); + STMIA(scratchReg, false, 3, tempReg1, tempReg2, tempReg3); } // Through expands into floats, always. Might want to look at changing this. @@ -1085,16 +1082,13 @@ void VertexDecoderJitCache::Jit_PosS16() { // Just copy 12 bytes. void VertexDecoderJitCache::Jit_PosFloat() { - //ADD(scratchReg, srcReg, dec_->posoff); - //LDMIA(scratchReg, false, 3, tempReg1, tempReg2, tempReg3); - //ADD(scratchReg, dstReg, dec_->decFmt.posoff); - //STMIA(scratchReg, false, 3, tempReg1, tempReg2, tempReg3); + // Might not be aligned to 4, so we can't use LDMIA. LDR(tempReg1, srcReg, dec_->posoff); LDR(tempReg2, srcReg, dec_->posoff + 4); LDR(tempReg3, srcReg, dec_->posoff + 8); - STR(tempReg1, dstReg, dec_->decFmt.posoff); - STR(tempReg2, dstReg, dec_->decFmt.posoff + 4); - STR(tempReg3, dstReg, dec_->decFmt.posoff + 8); + // But this is always aligned to 4 so we're safe. + ADD(scratchReg, dstReg, dec_->decFmt.posoff); + STMIA(scratchReg, false, 3, tempReg1, tempReg2, tempReg3); } #elif defined(_M_X64) || defined(_M_IX86) @@ -1278,10 +1272,15 @@ void VertexDecoderJitCache::Jit_TcU16Through() { } void VertexDecoderJitCache::Jit_TcFloatThrough() { +#ifdef _M_X64 + MOV(64, R(tempReg1), MDisp(srcReg, dec_->tcoff)); + MOV(64, MDisp(dstReg, dec_->decFmt.uvoff), R(tempReg1)); +#else MOV(32, R(tempReg1), MDisp(srcReg, dec_->tcoff)); MOV(32, R(tempReg2), MDisp(srcReg, dec_->tcoff + 4)); MOV(32, MDisp(dstReg, dec_->decFmt.uvoff), R(tempReg1)); MOV(32, MDisp(dstReg, dec_->decFmt.uvoff + 4), R(tempReg2)); +#endif } void VertexDecoderJitCache::Jit_Color8888() {