summaryrefslogtreecommitdiff
path: root/Source/Core/Common/x64Emitter.cpp
diff options
context:
space:
mode:
authorTillmann Karras <tilkax@gmail.com>2014-04-23 21:15:09 +0200
committerTillmann Karras <tilkax@gmail.com>2014-04-23 21:15:09 +0200
commit957649b7af57abc476ace647cd8fcbfaafac499c (patch)
treef7eb222765416e00b059d5e41aa6fd7a7a411e11 /Source/Core/Common/x64Emitter.cpp
parent65e0579d9f86c4aad4f1b46bc60e916451ffbee3 (diff)
Optimize NOPs
Diffstat (limited to 'Source/Core/Common/x64Emitter.cpp')
-rw-r--r--Source/Core/Common/x64Emitter.cpp68
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;
}
}