diff options
| author | Tillmann Karras <tilkax@gmail.com> | 2014-04-23 21:15:09 +0200 |
|---|---|---|
| committer | Tillmann Karras <tilkax@gmail.com> | 2014-04-23 21:15:09 +0200 |
| commit | 957649b7af57abc476ace647cd8fcbfaafac499c (patch) | |
| tree | f7eb222765416e00b059d5e41aa6fd7a7a411e11 /Source/Core/Common/x64Emitter.cpp | |
| parent | 65e0579d9f86c4aad4f1b46bc60e916451ffbee3 (diff) | |
Optimize NOPs
Diffstat (limited to 'Source/Core/Common/x64Emitter.cpp')
| -rw-r--r-- | Source/Core/Common/x64Emitter.cpp | 68 |
1 files changed, 54 insertions, 14 deletions
diff --git a/Source/Core/Common/x64Emitter.cpp b/Source/Core/Common/x64Emitter.cpp index 6567fe5543..23c3d2647e 100644 --- a/Source/Core/Common/x64Emitter.cpp +++ b/Source/Core/Common/x64Emitter.cpp @@ -515,23 +515,63 @@ void XEmitter::INT3() {Write8(0xCC);} void XEmitter::RET() {Write8(0xC3);} void XEmitter::RET_FAST() {Write8(0xF3); Write8(0xC3);} //two-byte return (rep ret) - recommended by AMD optimization manual for the case of jumping to a ret -void XEmitter::NOP(int count) +// The first sign of decadence: optimized NOPs. +void XEmitter::NOP(int size) { - // TODO: look up the fastest nop sleds for various sizes - int i; - switch (count) { - case 1: - Write8(0x90); - break; - case 2: - Write8(0x66); - Write8(0x90); - break; - default: - for (i = 0; i < count; i++) { + while (true) + { + switch (size) + { + case 0: + return; + case 1: Write8(0x90); + return; + case 2: + Write8(0x66); Write8(0x90); + return; + case 3: + Write8(0x0F); Write8(0x1F); Write8(0x00); + return; + case 4: + Write8(0x0F); Write8(0x1F); Write8(0x40); Write8(0x00); + return; + case 5: + Write8(0x0F); Write8(0x1F); Write8(0x44); Write8(0x00); + Write8(0x00); + return; + case 6: + Write8(0x66); Write8(0x0F); Write8(0x1F); Write8(0x44); + Write8(0x00); Write8(0x00); + return; + case 7: + Write8(0x0F); Write8(0x1F); Write8(0x80); Write8(0x00); + Write8(0x00); Write8(0x00); Write8(0x00); + return; + case 8: + Write8(0x0F); Write8(0x1F); Write8(0x84); Write8(0x00); + Write8(0x00); Write8(0x00); Write8(0x00); Write8(0x00); + return; + case 9: + Write8(0x66); Write8(0x0F); Write8(0x1F); Write8(0x84); + Write8(0x00); Write8(0x00); Write8(0x00); Write8(0x00); + Write8(0x00); + return; + case 10: + Write8(0x66); Write8(0x66); Write8(0x0F); Write8(0x1F); + Write8(0x84); Write8(0x00); Write8(0x00); Write8(0x00); + Write8(0x00); Write8(0x00); + return; + default: + // Even though x86 instructions are allowed to be up to 15 bytes long, + // AMD advises against using NOPs longer than 11 bytes because they + // carry a performance penalty on CPUs older than AMD family 16h. + Write8(0x66); Write8(0x66); Write8(0x66); Write8(0x0F); + Write8(0x1F); Write8(0x84); Write8(0x00); Write8(0x00); + Write8(0x00); Write8(0x00); Write8(0x00); + size -= 11; + continue; } - break; } } |
