This is the second patch to allow x86 code to be aligned with optimal nops.
authorKevin Enderby <enderby@apple.com>
Tue, 23 Feb 2010 21:41:24 +0000 (21:41 +0000)
committerKevin Enderby <enderby@apple.com>
Tue, 23 Feb 2010 21:41:24 +0000 (21:41 +0000)
With the compiler changed to use EmitCodeAlignment() it does change the
functionality.  But X86 assembly code assembled with llvm-mc does not change
its output.  For that we will eventually change the assembler frontend to
detect a '.align x, 0x90' when used in a section that 'hasInstructions' and use
EmitCodeAlignment, but will wait until we have better target hooks.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96988 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/MCAssembler.cpp

index 2c698e76f92b48ce1284d17e086c8fc02700bc1c..96227dbee508cbc38d86d2c45e5c4586184751b4 100644 (file)
@@ -1066,9 +1066,54 @@ void MCAssembler::LayoutSection(MCSectionData &SD) {
 ///
 /// FIXME this is X86 32-bit specific and should move to a better place.
 static uint64_t WriteNopData(uint64_t Count, MachObjectWriter &MOW) {
-  // FIXME for now just use the 0x90 nop opcode byte.
+  static const uint8_t Nops[16][16] = {
+    // nop
+    {0x90},
+    // xchg %ax,%ax
+    {0x66, 0x90},
+    // nopl (%[re]ax)
+    {0x0f, 0x1f, 0x00},
+    // nopl 0(%[re]ax)
+    {0x0f, 0x1f, 0x40, 0x00},
+    // nopl 0(%[re]ax,%[re]ax,1)
+    {0x0f, 0x1f, 0x44, 0x00, 0x00},
+    // nopw 0(%[re]ax,%[re]ax,1)
+    {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
+    // nopl 0L(%[re]ax)
+    {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
+    // nopl 0L(%[re]ax,%[re]ax,1)
+    {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
+    // nopw 0L(%[re]ax,%[re]ax,1)
+    {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
+    // nopw %cs:0L(%[re]ax,%[re]ax,1)
+    {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
+    // nopl 0(%[re]ax,%[re]ax,1)
+    // nopw 0(%[re]ax,%[re]ax,1)
+    {0x0f, 0x1f, 0x44, 0x00, 0x00,
+     0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
+    // nopw 0(%[re]ax,%[re]ax,1)
+    // nopw 0(%[re]ax,%[re]ax,1)
+    {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
+     0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00},
+    // nopw 0(%[re]ax,%[re]ax,1)
+    // nopl 0L(%[re]ax) */
+    {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00,
+     0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
+    // nopl 0L(%[re]ax)
+    // nopl 0L(%[re]ax)
+    {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
+     0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00},
+    // nopl 0L(%[re]ax)
+    // nopl 0L(%[re]ax,%[re]ax,1)
+    {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
+     0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}
+  };
+
+  if (Count > 15)
+    return 0;
+
   for (uint64_t i = 0; i < Count; i++)
-    MOW.Write8 (uint8_t(0x90));
+    MOW.Write8 (uint8_t(Nops[Count - 1][i]));
 
   return Count;
 }