[llvm-commits] [llvm] r95708 - in /llvm/trunk: include/llvm/MC/MCCodeEmitter.h include/llvm/MC/MCFixup.h lib/MC/MCAsmStreamer.cpp lib/MC/MCMachOStreamer.cpp lib/Target/X86/X86CodeEmitter.cpp lib/Target/X86/X86MCCodeEmitter.cpp

Daniel Dunbar daniel at zuster.org
Tue Feb 9 14:59:55 PST 2010


Author: ddunbar
Date: Tue Feb  9 16:59:55 2010
New Revision: 95708

URL: http://llvm.org/viewvc/llvm-project?rev=95708&view=rev
Log:
MC: First cut at MCFixup, for getting fixup/relocation information out of an MCCodeEmitter.

Added:
    llvm/trunk/include/llvm/MC/MCFixup.h
Modified:
    llvm/trunk/include/llvm/MC/MCCodeEmitter.h
    llvm/trunk/lib/MC/MCAsmStreamer.cpp
    llvm/trunk/lib/MC/MCMachOStreamer.cpp
    llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp
    llvm/trunk/lib/Target/X86/X86MCCodeEmitter.cpp

Modified: llvm/trunk/include/llvm/MC/MCCodeEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCCodeEmitter.h?rev=95708&r1=95707&r2=95708&view=diff

==============================================================================
--- llvm/trunk/include/llvm/MC/MCCodeEmitter.h (original)
+++ llvm/trunk/include/llvm/MC/MCCodeEmitter.h Tue Feb  9 16:59:55 2010
@@ -10,23 +10,60 @@
 #ifndef LLVM_MC_MCCODEEMITTER_H
 #define LLVM_MC_MCCODEEMITTER_H
 
+#include "llvm/MC/MCFixup.h"
+
+#include <cassert>
+
 namespace llvm {
+class MCExpr;
 class MCInst;
 class raw_ostream;
+template<typename T> class SmallVectorImpl;
+
+/// MCFixupKindInfo - Target independent information on a fixup kind.
+struct MCFixupKindInfo {
+  /// A target specific name for the fixup kind. The names will be unique for
+  /// distinct kinds on any given target.
+  const char *Name;
+
+  /// The bit offset to write the relocation into.
+  //
+  // FIXME: These two fields are under-specified and not general enough, but it
+  // is covers many things, and is enough to let the AsmStreamer pretty-print
+  // the encoding.
+  unsigned TargetOffset;
+
+  /// The number of bits written by this fixup. The bits are assumed to be
+  /// contiguous.
+  unsigned TargetSize;
+};
 
 /// MCCodeEmitter - Generic instruction encoding interface.
 class MCCodeEmitter {
+private:
   MCCodeEmitter(const MCCodeEmitter &);   // DO NOT IMPLEMENT
   void operator=(const MCCodeEmitter &);  // DO NOT IMPLEMENT
 protected: // Can only create subclasses.
   MCCodeEmitter();
- 
+
 public:
   virtual ~MCCodeEmitter();
 
+  /// @name Target Independent Fixup Information
+  /// @{
+
+  /// getNumFixupKinds - Get the number of target specific fixup kinds.
+  virtual unsigned getNumFixupKinds() const = 0;
+
+  /// getFixupKindInfo - Get information on a fixup kind.
+  virtual MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const = 0;
+
+  /// @}
+
   /// EncodeInstruction - Encode the given \arg Inst to bytes on the output
   /// stream \arg OS.
-  virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS) const = 0;
+  virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS,
+                                 SmallVectorImpl<MCFixup> &Fixups) const = 0;
 };
 
 } // End llvm namespace

Added: llvm/trunk/include/llvm/MC/MCFixup.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCFixup.h?rev=95708&view=auto

==============================================================================
--- llvm/trunk/include/llvm/MC/MCFixup.h (added)
+++ llvm/trunk/include/llvm/MC/MCFixup.h Tue Feb  9 16:59:55 2010
@@ -0,0 +1,95 @@
+//===-- llvm/MC/MCFixup.h - Instruction Relocation and Patching -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCFIXUP_H
+#define LLVM_MC_MCFIXUP_H
+
+#include <cassert>
+
+namespace llvm {
+
+// Private constants, do not use.
+//
+// This is currently layed out so that the MCFixup fields can be efficiently
+// accessed, while keeping the offset field large enought that the assembler
+// backend can reasonably use the MCFixup representation for an entire fragment
+// (splitting any overly large fragments).
+//
+// The division of bits between the kind and the opindex can be tweaked if we
+// end up needing more bits for target dependent kinds.
+enum {
+  MCFIXUP_NUM_GENERIC_KINDS = 128,
+  MCFIXUP_NUM_KIND_BITS = 8,
+  MCFIXUP_NUM_OPINDEX_BITS = 8,
+  MCFIXUP_NUM_OFFSET_BITS = (32 - MCFIXUP_NUM_OPINDEX_BITS -
+                             MCFIXUP_NUM_OPINDEX_BITS)
+};
+
+/// MCFixupKind - Extensible enumeration to represent the type of a fixup.
+enum MCFixupKind {
+  FK_Data_1 = 0, ///< A one-byte fixup.
+  FK_Data_2,     ///< A two-byte fixup.
+  FK_Data_4,     ///< A four-byte fixup.
+  FK_Data_8,     ///< A eight-byte fixup.
+
+  FirstTargetFixupKind = MCFIXUP_NUM_GENERIC_KINDS,
+
+  MaxTargetFixupKind = (1 << MCFIXUP_NUM_KIND_BITS)
+};
+
+/// MCFixup - Encode information on a single operation to perform on an byte
+/// sequence (e.g., an encoded instruction) which requires assemble- or run-
+/// time patching.
+///
+/// Fixups are used any time the target instruction encoder needs to represent
+/// some value in an instruction which is not yet concrete. The encoder will
+/// encode the instruction assuming the value is 0, and emit a fixup which
+/// communicates to the assembler backend how it should rewrite the encoded
+/// value.
+///
+/// During the process of relaxation, the assembler will apply fixups as
+/// symbolic values become concrete. When relaxation is complete, any remaining
+/// fixups become relocations in the object file (or errors, if the fixup cannot
+/// be encoded on the target).
+class MCFixup {
+  static const unsigned MaxOffset = 1 << MCFIXUP_NUM_KIND_BITS;
+
+  /// The byte index of start of the relocation inside the encoded instruction.
+  unsigned Offset : MCFIXUP_NUM_OFFSET_BITS;
+
+  /// The index of the operand to encode into the instruction.
+  unsigned OpIndex : MCFIXUP_NUM_OPINDEX_BITS;
+
+  /// The target dependent kind of fixup item this is. The kind is used to
+  /// determine how the operand value should be encoded into the instruction.
+  unsigned Kind : MCFIXUP_NUM_KIND_BITS;
+
+public:
+  static MCFixup Create(unsigned Offset, unsigned OpIndex, MCFixupKind Kind) {
+    MCFixup FI;
+    FI.Offset = Offset;
+    FI.OpIndex = OpIndex;
+    FI.Kind = unsigned(Kind);
+
+    assert(Offset == FI.Offset && "Offset out of range!");
+    assert(OpIndex == FI.OpIndex && "Operand index out of range!");
+    assert(Kind == FI.Kind && "Kind out of range!");
+    return FI;
+  }
+
+  unsigned getOffset() const { return Offset; }
+
+  unsigned getOpIndex() const { return OpIndex; }
+
+  MCFixupKind getKind() const { return MCFixupKind(Kind); }
+};
+
+} // End llvm namespace
+
+#endif

Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=95708&r1=95707&r2=95708&view=diff

==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Tue Feb  9 16:59:55 2010
@@ -535,8 +535,9 @@
   // Show the encoding in a comment if we have a code emitter.
   if (Emitter) {
     SmallString<256> Code;
+    SmallVector<MCFixup, 4> Fixups;
     raw_svector_ostream VecOS(Code);
-    Emitter->EncodeInstruction(Inst, VecOS);
+    Emitter->EncodeInstruction(Inst, VecOS, Fixups);
     VecOS.flush();
 
     raw_ostream &OS = GetCommentOS();

Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=95708&r1=95707&r2=95708&view=diff

==============================================================================
--- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Tue Feb  9 16:59:55 2010
@@ -366,9 +366,10 @@
   CurSectionData->setHasInstructions(true);
 
   // FIXME: Relocations!
+  SmallVector<MCFixup, 4> Fixups;
   SmallString<256> Code;
   raw_svector_ostream VecOS(Code);
-  Emitter->EncodeInstruction(Inst, VecOS);
+  Emitter->EncodeInstruction(Inst, VecOS, Fixups);
   EmitBytes(VecOS.str(), 0);
 }
 

Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=95708&r1=95707&r2=95708&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Tue Feb  9 16:59:55 2010
@@ -944,6 +944,24 @@
     delete DummyF;
   }
 
+  unsigned getNumFixupKinds() const {
+    return 5;
+  }
+
+  MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
+    static MCFixupKindInfo Infos[] = {
+      { "reloc_pcrel_word", 0, 4 * 8 },
+      { "reloc_picrel_word", 0, 4 * 8 },
+      { "reloc_absolute_word", 0, 4 * 8 },
+      { "reloc_absolute_word_sext", 0, 4 * 8 },
+      { "reloc_absolute_dword", 0, 8 * 8 }
+    };
+
+    assert(Kind >= FirstTargetFixupKind && Kind < MaxTargetFixupKind &&
+           "Invalid kind!");
+    return Infos[Kind - FirstTargetFixupKind];
+  }
+
   bool AddRegToInstr(const MCInst &MI, MachineInstr *Instr,
                      unsigned Start) const {
     if (Start + 1 > MI.getNumOperands())
@@ -997,7 +1015,8 @@
             AddRegToInstr(MI, Instr, Start + 4));
   }
 
-  void EncodeInstruction(const MCInst &MI, raw_ostream &OS) const {
+  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
+                         SmallVectorImpl<MCFixup> &Fixups) const {
     // Don't look yet!
 
     // Convert the MCInst to a MachineInstr so we can (ab)use the regular

Modified: llvm/trunk/lib/Target/X86/X86MCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86MCCodeEmitter.cpp?rev=95708&r1=95707&r2=95708&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86MCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86MCCodeEmitter.cpp Tue Feb  9 16:59:55 2010
@@ -33,6 +33,24 @@
   }
 
   ~X86MCCodeEmitter() {}
+
+  unsigned getNumFixupKinds() const {
+    return 5;
+  }
+
+  MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
+    static MCFixupKindInfo Infos[] = {
+      { "reloc_pcrel_word", 0, 4 * 8 },
+      { "reloc_picrel_word", 0, 4 * 8 },
+      { "reloc_absolute_word", 0, 4 * 8 },
+      { "reloc_absolute_word_sext", 0, 4 * 8 },
+      { "reloc_absolute_dword", 0, 8 * 8 }
+    };
+
+    assert(Kind >= FirstTargetFixupKind && Kind < MaxTargetFixupKind &&
+           "Invalid kind!");
+    return Infos[Kind - FirstTargetFixupKind];
+  }
   
   static unsigned GetX86RegNum(const MCOperand &MO) {
     return X86RegisterInfo::getX86RegNum(MO.getReg());
@@ -75,7 +93,8 @@
                         unsigned RegOpcodeField, intptr_t PCAdj,
                         raw_ostream &OS) const;
   
-  void EncodeInstruction(const MCInst &MI, raw_ostream &OS) const;
+  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
+                         SmallVectorImpl<MCFixup> &Fixups) const;
   
 };
 
@@ -379,7 +398,8 @@
 }
 
 void X86MCCodeEmitter::
-EncodeInstruction(const MCInst &MI, raw_ostream &OS) const {
+EncodeInstruction(const MCInst &MI, raw_ostream &OS,
+                  SmallVectorImpl<MCFixup> &Fixups) const {
   unsigned Opcode = MI.getOpcode();
   const TargetInstrDesc &Desc = TII.get(Opcode);
   unsigned TSFlags = Desc.TSFlags;





More information about the llvm-commits mailing list