[llvm-commits] [llvm] r99248 - in /llvm/trunk: include/llvm/Target/TargetAsmBackend.h lib/MC/MCAssembler.cpp lib/MC/MCMachOStreamer.cpp lib/Target/X86/X86AsmBackend.cpp
Daniel Dunbar
daniel at zuster.org
Mon Mar 22 19:36:58 PDT 2010
Author: ddunbar
Date: Mon Mar 22 21:36:58 2010
New Revision: 99248
URL: http://llvm.org/viewvc/llvm-project?rev=99248&view=rev
Log:
MC: Add TargetAsmBackend::WriteNopData and use to eliminate some target dependencies in MCMachOStreamer and MCAssembler.
Modified:
llvm/trunk/include/llvm/Target/TargetAsmBackend.h
llvm/trunk/lib/MC/MCAssembler.cpp
llvm/trunk/lib/MC/MCMachOStreamer.cpp
llvm/trunk/lib/Target/X86/X86AsmBackend.cpp
Modified: llvm/trunk/include/llvm/Target/TargetAsmBackend.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmBackend.h?rev=99248&r1=99247&r2=99248&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetAsmBackend.h (original)
+++ llvm/trunk/include/llvm/Target/TargetAsmBackend.h Mon Mar 22 21:36:58 2010
@@ -102,6 +102,13 @@
/// wider instruction.
virtual void RelaxInstruction(const MCInstFragment *IF,
MCInst &Res) const = 0;
+
+ /// WriteNopData - Write an (optimal) nop sequence of Count bytes to the given
+ /// output. If the target cannot generate such a sequence, it should return an
+ /// error.
+ ///
+ /// \return - True on success.
+ virtual bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const = 0;
};
} // End llvm namespace
Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=99248&r1=99247&r2=99248&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Mon Mar 22 21:36:58 2010
@@ -373,66 +373,9 @@
SD.setFileSize(Address - SD.getAddress());
}
-/// WriteNopData - Write optimal nops to the output file for the \arg Count
-/// bytes. This returns the number of bytes written. It may return 0 if
-/// the \arg Count is more than the maximum optimal nops.
-///
-/// FIXME this is X86 32-bit specific and should move to a better place.
-static uint64_t WriteNopData(uint64_t Count, MCObjectWriter *OW) {
- 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++)
- OW->Write8(uint8_t(Nops[Count - 1][i]));
-
- return Count;
-}
-
/// WriteFragmentData - Write the \arg F data to the output file.
-static void WriteFragmentData(const MCFragment &F, MCObjectWriter *OW) {
+static void WriteFragmentData(const MCAssembler &Asm, const MCFragment &F,
+ MCObjectWriter *OW) {
uint64_t Start = OW->getStream().tell();
(void) Start;
@@ -456,11 +399,15 @@
// See if we are aligning with nops, and if so do that first to try to fill
// the Count bytes. Then if that did not fill any bytes or there are any
// bytes left to fill use the the Value and ValueSize to fill the rest.
+ // If we are aligning with nops, ask that target to emit the right data.
if (AF.getEmitNops()) {
- uint64_t NopByteCount = WriteNopData(Count, OW);
- Count -= NopByteCount;
+ if (!Asm.getBackend().WriteNopData(Count, OW))
+ llvm_report_error("unable to write nop sequence of " +
+ Twine(Count) + " bytes");
+ break;
}
+ // Otherwise, write out in multiples of the value size.
for (uint64_t i = 0; i != Count; ++i) {
switch (AF.getValueSize()) {
default:
@@ -531,7 +478,7 @@
for (MCSectionData::const_iterator it = SD->begin(),
ie = SD->end(); it != ie; ++it)
- WriteFragmentData(*it, OW);
+ WriteFragmentData(*this, *it, OW);
// Add section padding.
assert(SD->getFileSize() >= SD->getSize() && "Invalid section sizes!");
Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=99248&r1=99247&r2=99248&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Mon Mar 22 21:36:58 2010
@@ -353,8 +353,7 @@
unsigned MaxBytesToEmit) {
if (MaxBytesToEmit == 0)
MaxBytesToEmit = ByteAlignment;
- // FIXME: The 0x90 is the default x86 1 byte nop opcode.
- new MCAlignFragment(ByteAlignment, 0x90, 1, MaxBytesToEmit,
+ new MCAlignFragment(ByteAlignment, 0, 1, MaxBytesToEmit,
true /* EmitNops */, CurSectionData);
// Update the maximum alignment on the current section if necessary.
Modified: llvm/trunk/lib/Target/X86/X86AsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmBackend.cpp?rev=99248&r1=99247&r2=99248&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86AsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86AsmBackend.cpp Mon Mar 22 21:36:58 2010
@@ -53,6 +53,8 @@
}
void RelaxInstruction(const MCInstFragment *IF, MCInst &Res) const;
+
+ bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const;
};
static unsigned getRelaxedOpcode(unsigned Op) {
@@ -98,6 +100,67 @@
Res.setOpcode(RelaxedOp);
}
+/// WriteNopData - Write optimal nops to the output file for the \arg Count
+/// bytes. This returns the number of bytes written. It may return 0 if
+/// the \arg Count is more than the maximum optimal nops.
+///
+/// FIXME this is X86 32-bit specific and should move to a better place.
+bool X86AsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const {
+ 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}
+ };
+
+ // Write an optimal sequence for the first 15 bytes.
+ uint64_t OptimalCount = (Count < 16) ? Count : 15;
+ for (uint64_t i = 0, e = OptimalCount; i != e; i++)
+ OW->Write8(Nops[OptimalCount - 1][i]);
+
+ // Finish with single byte nops.
+ for (uint64_t i = OptimalCount, e = Count; i != e; ++i)
+ OW->Write8(0x90);
+
+ return true;
+}
+
/* *** */
class ELFX86AsmBackend : public X86AsmBackend {
More information about the llvm-commits
mailing list