[llvm-commits] [llvm] r98381 - in /llvm/trunk: include/llvm/MC/MCAssembler.h lib/MC/MCAssembler.cpp

Daniel Dunbar daniel at zuster.org
Fri Mar 12 13:00:49 PST 2010


Author: ddunbar
Date: Fri Mar 12 15:00:49 2010
New Revision: 98381

URL: http://llvm.org/viewvc/llvm-project?rev=98381&view=rev
Log:
MC: Factor out MCAssembler::EvaluateFixup, and simplify.

Modified:
    llvm/trunk/include/llvm/MC/MCAssembler.h
    llvm/trunk/lib/MC/MCAssembler.cpp

Modified: llvm/trunk/include/llvm/MC/MCAssembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=98381&r1=98380&r2=98381&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Fri Mar 12 15:00:49 2010
@@ -21,6 +21,7 @@
 
 namespace llvm {
 class raw_ostream;
+class MCAsmLayout;
 class MCAssembler;
 class MCContext;
 class MCExpr;
@@ -28,6 +29,7 @@
 class MCSection;
 class MCSectionData;
 class MCSymbol;
+class MCValue;
 class TargetAsmBackend;
 
 /// MCAsmFixup - Represent a fixed size region of bytes inside some fragment
@@ -624,6 +626,25 @@
   /// already have been computed.
   void LayoutSection(MCSectionData &SD);
 
+  // FIXME: Make protected once we factor out object writer classes.
+public:
+  /// Evaluate a fixup to a relocatable expression and the value which should be
+  /// placed into the fixup.
+  ///
+  /// \param Layout The layout to use for evaluation.
+  /// \param Fixup The fixup to evaluate.
+  /// \param DF The fragment the fixup is inside.
+  /// \param Target [out] On return, the relocatable expression the fixup
+  /// evaluates to.
+  /// \param Value [out] On return, the value of the fixup as currently layed
+  /// out.
+  /// \return Whether the fixup value was fully resolved. This is true if the
+  /// \arg Value result is fixed, otherwise the value may change due to
+  /// relocation.
+  bool EvaluateFixup(const MCAsmLayout &Layout,
+                     MCAsmFixup &Fixup, MCDataFragment *DF,
+                     MCValue &Target, uint64_t &Value) const;
+
 public:
   /// Construct a new assembler instance.
   ///

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=98381&r1=98380&r2=98381&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Fri Mar 12 15:00:49 2010
@@ -24,6 +24,7 @@
 #include "llvm/Support/MachO.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Target/TargetAsmBackend.h"
 
 // FIXME: Gross.
 #include "../Target/X86/X86FixupKinds.h"
@@ -471,19 +472,6 @@
       Value2 = B_SD->getAddress();
     }
 
-    // The value which goes in the fixup is current value of the expression.
-    Fixup.FixedValue = Value - Value2 + Target.getConstant();
-    if (IsPCRel)
-      Fixup.FixedValue -= Address;
-
-    // If this fixup is a vanilla PC relative relocation for a local label, we
-    // don't need a relocation.
-    //
-    // FIXME: Implement proper atom support.
-    if (IsPCRel && Target.getSymA() && Target.getSymA()->isTemporary() &&
-        !Target.getSymB())
-      return;
-
     MachRelocationEntry MRE;
     MRE.Word0 = ((Address   <<  0) |
                  (Type      << 24) |
@@ -514,9 +502,10 @@
     // FIXME: Share layout object.
     MCAsmLayout Layout(Asm);
 
+    // Evaluate the fixup; if the value was resolved, no relocation is needed.
     MCValue Target;
-    if (!Fixup.Value->EvaluateAsRelocatable(Target, &Layout))
-      llvm_report_error("expected relocatable expression");
+    if (Asm.EvaluateFixup(Layout, Fixup, &Fragment, Target, Fixup.FixedValue))
+      return;
 
     // If this is a difference or a defined symbol plus an offset, then we need
     // a scattered relocation entry.
@@ -567,24 +556,6 @@
       Type = RIT_Vanilla;
     }
 
-    // The value which goes in the fixup is current value of the expression.
-    Fixup.FixedValue = Value + Target.getConstant();
-    if (IsPCRel)
-      Fixup.FixedValue -= Address;
-
-    // If the target evaluates to a constant, we don't need a relocation. This
-    // occurs with absolutized expressions which are not resolved to constants
-    // until after relaxation.
-    if (Target.isAbsolute())
-      return;
-
-    // If this fixup is a vanilla PC relative relocation for a local label, we
-    // don't need a relocation.
-    //
-    // FIXME: Implement proper atom support.
-    if (IsPCRel && Target.getSymA() && Target.getSymA()->isTemporary())
-      return;
-
     // struct relocation_info (8 bytes)
     MachRelocationEntry MRE;
     MRE.Word0 = Address;
@@ -1010,6 +981,54 @@
 MCAssembler::~MCAssembler() {
 }
 
+bool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout, MCAsmFixup &Fixup,
+                                MCDataFragment *DF,
+                                MCValue &Target, uint64_t &Value) const {
+  if (!Fixup.Value->EvaluateAsRelocatable(Target, &Layout))
+    llvm_report_error("expected relocatable expression");
+
+  // FIXME: How do non-scattered symbols work in ELF? I presume the linker
+  // doesn't support small relocations, but then under what criteria does the
+  // assembler allow symbol differences?
+
+  Value = Target.getConstant();
+
+  // FIXME: This "resolved" check isn't quite right. The assumption is that if
+  // we have a PCrel access to a temporary, then that temporary is in the same
+  // atom, and so the value is resolved. We need explicit atom's to implement
+  // this more precisely.
+  bool IsResolved = true, IsPCRel = isFixupKindPCRel(Fixup.Kind);
+  if (const MCSymbol *Symbol = Target.getSymA()) {
+    if (Symbol->isDefined())
+      Value += getSymbolData(*Symbol).getAddress();
+    else
+      IsResolved = false;
+
+    // With scattered symbols, we assume anything that isn't a PCrel temporary
+    // access can have an arbitrary value.
+    if (getBackend().hasScatteredSymbols() &&
+        (!IsPCRel || !Symbol->isTemporary()))
+      IsResolved = false;
+  }
+  if (const MCSymbol *Symbol = Target.getSymB()) {
+    if (Symbol->isDefined())
+      Value -= getSymbolData(*Symbol).getAddress();
+    else
+      IsResolved = false;
+
+    // With scattered symbols, we assume anything that isn't a PCrel temporary
+    // access can have an arbitrary value.
+    if (getBackend().hasScatteredSymbols() &&
+        (!IsPCRel || !Symbol->isTemporary()))
+      IsResolved = false;
+  }
+
+  if (IsPCRel)
+    Value -= DF->getOffset() + Fixup.Offset;
+
+  return IsResolved;
+}
+
 void MCAssembler::LayoutSection(MCSectionData &SD) {
   MCAsmLayout Layout(*this);
   uint64_t Address = SD.getAddress();





More information about the llvm-commits mailing list