x86/x64: Nop-align the main loop of vertex decoder loops

This commit is contained in:
Henrik Rydgård 2023-06-12 20:38:41 +02:00
parent 01cea7f088
commit c4e44d66b0
3 changed files with 36 additions and 1 deletions

View file

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

View file

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

View file

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