Index: src/ia32/assembler-ia32.cc |
=================================================================== |
--- src/ia32/assembler-ia32.cc (revision 10131) |
+++ src/ia32/assembler-ia32.cc (working copy) |
@@ -388,9 +388,92 @@ |
void Assembler::Align(int m) { |
ASSERT(IsPowerOf2(m)); |
- while ((pc_offset() & (m - 1)) != 0) { |
- nop(); |
+ int mask = m - 1; |
+ int addr = pc_offset(); |
+ Nop((m - (addr & mask)) & mask); |
+} |
+ |
+ |
+bool Assembler::IsNop(Address addr) { |
+ Address a = addr; |
+ while (*a == 0x66) a++; |
+ if (*a == 0x90) return true; |
+ if (a[0] == 0xf && a[1] == 0x1f) return true; |
+ return false; |
+} |
+ |
+ |
+void Assembler::Nop(int bytes) { |
+ EnsureSpace ensure_space(this); |
+ |
+ if (!CpuFeatures::IsSupported(SSE2)) { |
+ // Older CPUs that do not support SSE2 may not support multibyte NOP |
+ // instructions. |
+ for (; bytes > 0; bytes--) { |
+ EMIT(0x90); |
+ } |
+ return; |
} |
+ |
+ // Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf |
+ while (bytes > 0) { |
+ switch (bytes) { |
+ case 2: |
+ EMIT(0x66); |
+ case 1: |
+ EMIT(0x90); |
+ return; |
+ case 3: |
+ EMIT(0xf); |
+ EMIT(0x1f); |
+ EMIT(0); |
+ return; |
+ case 4: |
+ EMIT(0xf); |
+ EMIT(0x1f); |
+ EMIT(0x40); |
+ EMIT(0); |
+ return; |
+ case 6: |
+ EMIT(0x66); |
+ case 5: |
+ EMIT(0xf); |
+ EMIT(0x1f); |
+ EMIT(0x44); |
+ EMIT(0); |
+ EMIT(0); |
+ return; |
+ case 7: |
+ EMIT(0xf); |
+ EMIT(0x1f); |
+ EMIT(0x80); |
+ EMIT(0); |
+ EMIT(0); |
+ EMIT(0); |
+ EMIT(0); |
+ return; |
+ default: |
+ case 11: |
+ EMIT(0x66); |
+ bytes--; |
+ case 10: |
+ EMIT(0x66); |
+ bytes--; |
+ case 9: |
+ EMIT(0x66); |
+ bytes--; |
+ case 8: |
+ EMIT(0xf); |
+ EMIT(0x1f); |
+ EMIT(0x84); |
+ EMIT(0); |
+ EMIT(0); |
+ EMIT(0); |
+ EMIT(0); |
+ EMIT(0); |
+ bytes -= 8; |
+ } |
+ } |
} |