Commit 9b9dcd1e authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r261365:

------------------------------------------------------------------------
r261365 | hans | 2016-02-19 13:26:31 -0800 (Fri, 19 Feb 2016) | 3 lines

Revert r253557 "Alternative to long nops for X86 CPUs, by Andrey Turetsky"

Turns out the new nop sequences aren't actually nops on x86_64 (PR26554).
------------------------------------------------------------------------

llvm-svn: 261366
parent cf401074
Loading
Loading
Loading
Loading
+14 −32
Original line number Diff line number Diff line
@@ -69,19 +69,15 @@ public:
class X86AsmBackend : public MCAsmBackend {
  const StringRef CPU;
  bool HasNopl;
  uint64_t MaxNopLength;
  const uint64_t MaxNopLength;
public:
  X86AsmBackend(const Target &T, StringRef CPU) : MCAsmBackend(), CPU(CPU) {
  X86AsmBackend(const Target &T, StringRef CPU)
      : MCAsmBackend(), CPU(CPU), MaxNopLength(CPU == "slm" ? 7 : 15) {
    HasNopl = CPU != "generic" && CPU != "i386" && CPU != "i486" &&
              CPU != "i586" && CPU != "pentium" && CPU != "pentium-mmx" &&
              CPU != "i686" && CPU != "k6" && CPU != "k6-2" && CPU != "k6-3" &&
              CPU != "geode" && CPU != "winchip-c6" && CPU != "winchip2" &&
              CPU != "c3" && CPU != "c3-2";
    // Max length of true long nop instruction is 15 bytes.
    // Max length of long nop replacement instruction is 7 bytes.
    // Taking into account SilverMont architecture features max length of nops
    // is reduced for it to achieve better performance.
    MaxNopLength = (!HasNopl || CPU == "slm") ? 7 : 15;
  }

  unsigned getNumFixupKinds() const override {
@@ -299,7 +295,7 @@ void X86AsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const {
/// bytes.
/// \return - true on success, false on failure
bool X86AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
  static const uint8_t TrueNops[10][10] = {
  static const uint8_t Nops[10][10] = {
    // nop
    {0x90},
    // xchg %ax,%ax
@@ -322,31 +318,17 @@ bool X86AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
    {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
  };

  // Alternative nop instructions for CPUs which don't support long nops.
  static const uint8_t AltNops[7][10] = {
      // nop
      {0x90},
      // xchg %ax,%ax
      {0x66, 0x90},
      // lea 0x0(%esi),%esi
      {0x8d, 0x76, 0x00},
      // lea 0x0(%esi),%esi
      {0x8d, 0x74, 0x26, 0x00},
      // nop + lea 0x0(%esi),%esi
      {0x90, 0x8d, 0x74, 0x26, 0x00},
      // lea 0x0(%esi),%esi
      {0x8d, 0xb6, 0x00, 0x00, 0x00, 0x00 },
      // lea 0x0(%esi),%esi
      {0x8d, 0xb4, 0x26, 0x00, 0x00, 0x00, 0x00},
  };

  // Select the right NOP table.
  // FIXME: Can we get if CPU supports long nops from the subtarget somehow?
  const uint8_t (*Nops)[10] = HasNopl ? TrueNops : AltNops;
  assert(HasNopl || MaxNopLength <= 7);
  // This CPU doesn't support long nops. If needed add more.
  // FIXME: Can we get this from the subtarget somehow?
  // FIXME: We could generated something better than plain 0x90.
  if (!HasNopl) {
    for (uint64_t i = 0; i < Count; ++i)
      OW->write8(0x90);
    return true;
  }

  // Emit as many largest nops as needed, then emit a nop of the remaining
  // length.
  // 15 is the longest single nop instruction.  Emit as many 15-byte nops as
  // needed, then emit a nop of the remaining length.
  do {
    const uint8_t ThisNopLength = (uint8_t) std::min(Count, MaxNopLength);
    const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10;
+7 −1
Original line number Diff line number Diff line
@@ -22,7 +22,13 @@ inc %eax
inc %eax

// CHECK: 0:	40                                           	incl	%eax
// CHECK: 1:	8d b4 26 00 00 00 00                            leal (%esi), %esi
// CHECK: 1:	90                                           	nop
// CHECK: 2:	90                                           	nop
// CHECK: 3:	90                                           	nop
// CHECK: 4:	90                                           	nop
// CHECK: 5:	90                                           	nop
// CHECK: 6:	90                                           	nop
// CHECK: 7:	90                                           	nop
// CHECK: 8:	40                                           	incl	%eax