diff --git a/Common/x64Emitter.cpp b/Common/x64Emitter.cpp index 1d98544e68..73e84a3739 100644 --- a/Common/x64Emitter.cpp +++ b/Common/x64Emitter.cpp @@ -140,6 +140,37 @@ const u8 *XEmitter::AlignCodePage() return code; } +const u8 *XEmitter::NopAlignCode16() { + int nops = 16 - ((u64)code & 15); + if (nops == 16) + return code; + + // note: the string lengths are obviously not computable with strlen, but are equal to the index. + // Nop strings from https://stackoverflow.com/questions/25545470/long-multi-byte-nops-commonly-understood-macros-or-other-notation + static const char * const nopStrings[16] = { + "", + "\x90", + "\x66\x90", + "\x0f\x1f\00", + "\x0f\x1f\x40\x00", + "\x0f\x1f\x44\x00\x00", + "\x66\x0f\x1f\x44\x00\x00", + "\x0f\x1f\x80\x00\x00\x00\x00", + "\x0f\x1f\x84\x00\x00\x00\x00\x00", + "\x66\x0f\x1f\x84\x00\x00\x00\x00\x00", + "\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00", + "\x66\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00", + "\x66\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x90", + "\x66\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x66\x90", + "\x66\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\00", + "\x66\x66\x66\x0f\x1f\x84\x00\x00\x00\x00\x00\x0f\x1f\x40\x00", + }; + + memcpy(code, nopStrings[nops], nops); + code += nops; + return code; +} + // This operation modifies flags; check to see the flags are locked. // If the flags are locked, we should immediately and loudly fail before // causing a subtle JIT bug. diff --git a/Common/x64Emitter.h b/Common/x64Emitter.h index b52a81f35b..4dcfda6d70 100644 --- a/Common/x64Emitter.h +++ b/Common/x64Emitter.h @@ -406,6 +406,10 @@ public: const u8 *AlignCode4(); const u8 *AlignCode16(); const u8 *AlignCodePage(); + + // Nops until the code pointer is 16-byte aligned. Good for loops. + const u8 *NopAlignCode16(); + u8 *GetWritableCodePtr(); void LockFlags() { flags_locked = true; } diff --git a/GPU/Common/VertexDecoderX86.cpp b/GPU/Common/VertexDecoderX86.cpp index 9a4dc23449..d92bc964bb 100644 --- a/GPU/Common/VertexDecoderX86.cpp +++ b/GPU/Common/VertexDecoderX86.cpp @@ -272,7 +272,7 @@ JittedVertexDecoder VertexDecoderJitCache::Compile(const VertexDecoder &dec, int } // Let's not bother with a proper stack frame. We just grab the arguments and go. - JumpTarget loopStart = GetCodePtr(); + JumpTarget loopStart = NopAlignCode16(); for (int i = 0; i < dec.numSteps_; i++) { if (!CompileStep(dec, i)) { EndWrite();