[PATCH] D69411: [MC] Calculate difference of symbols in two fragments when possible

Jian Cai via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 24 15:03:51 PDT 2019


jcai19 created this revision.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.

Parse .if directive substracting dot symbol to a label right before,
when they are assgiend to two different MCFragments and both fragments
are not relaxable, e.g. 9997: inst ; .if . - 9997b == 2.
https://bugs.llvm.org/show_bug.cgi?id=43795


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D69411

Files:
  llvm/lib/MC/MCExpr.cpp


Index: llvm/lib/MC/MCExpr.cpp
===================================================================
--- llvm/lib/MC/MCExpr.cpp
+++ llvm/lib/MC/MCExpr.cpp
@@ -513,6 +513,8 @@
 
   const MCSymbol &SA = A->getSymbol();
   const MCSymbol &SB = B->getSymbol();
+  const MCFragment *FragA = SA.getFragment();
+  const MCFragment *FragB = SB.getFragment();
 
   if (SA.isUndefined() || SB.isUndefined())
     return;
@@ -520,8 +522,9 @@
   if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet))
     return;
 
-  if (SA.getFragment() == SB.getFragment() && !SA.isVariable() &&
-      !SA.isUnset() && !SB.isVariable() && !SB.isUnset()) {
+  if (FragA == FragB && !SA.isVariable() && !SA.isUnset() && !SB.isVariable() &&
+      !SB.isUnset()) {
+
     Addend += (SA.getOffset() - SB.getOffset());
 
     // Pointers to Thumb symbols need to have their low-bit set to allow
@@ -540,13 +543,39 @@
     return;
   }
 
-  if (!Layout)
+  const MCSection &SecA = *FragA->getParent();
+  const MCSection &SecB = *FragB->getParent();
+
+  if ((&SecA != &SecB) && !Addrs)
     return;
 
-  const MCSection &SecA = *SA.getFragment()->getParent();
-  const MCSection &SecB = *SB.getFragment()->getParent();
+     // Pointers to Thumb symbols need to have their low-bit set to allow
+   if ((&SecA != &SecB) && !Addrs)
+     return;
 
-  if ((&SecA != &SecB) && !Addrs)
+   if (SecB.getFragmentList().getNextNode(*FragB) == FragA &&
+       dyn_cast<MCDataFragment>(FragA) && dyn_cast<MCDataFragment>(FragB)) {
+     Addend +=
+         (SA.getOffset() + (cast<MCDataFragment>(FragB))->getContents().size() -
+          SB.getOffset());
+
+    // Pointers to Thumb symbols need to have their low-bit set to allow
+    // for interworking.
+    if (Asm->isThumbFunc(&SA))
+      Addend |= 1;
+
+    // If symbol is labeled as micromips, we set low-bit to ensure
+    // correct offset in .gcc_except_table
+    if (Asm->getBackend().isMicroMips(&SA))
+      Addend |= 1;
+
+    // Clear the symbol expr pointers to indicate we have folded these
+    // operands.
+    A = B = nullptr;
+    return;
+  }
+
+  if (!Layout)
     return;
 
   // Eagerly evaluate.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D69411.226341.patch
Type: text/x-patch
Size: 2160 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191024/bbba2847/attachment.bin>


More information about the llvm-commits mailing list