]> granicus.if.org Git - llvm/commitdiff
Merging r222672:
authorHal Finkel <hfinkel@anl.gov>
Tue, 9 Dec 2014 02:30:53 +0000 (02:30 +0000)
committerHal Finkel <hfinkel@anl.gov>
Tue, 9 Dec 2014 02:30:53 +0000 (02:30 +0000)
------------------------------------------------------------------------
r222672 | uweigand | 2014-11-24 18:09:47 +0000 (Mon, 24 Nov 2014) | 10 lines

[PowerPC] Fix PR 21652 - copy st_other bits on symbol assignment

When processing an assignment in the integrated assembler that sets
a symbol to the value of another symbol, we need to copy the st_other
bits that encode the local entry point offset.

Modeled after MipsTargetELFStreamer::emitAssignment handling of the
ELF::STO_MIPS_MICROMIPS flag.

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_35@223743 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
test/MC/PowerPC/ppc64-localentry.s

index 4c6780ff75a7c4c6e9fb83de33b8cbf30bce71cc..1bb5173e1937457277d9acf03cac870f370ebc0d 100644 (file)
@@ -184,6 +184,23 @@ public:
     if ((Flags & ELF::EF_PPC64_ABI) == 0)
       MCA.setELFHeaderEFlags(Flags | 2);
   }
+  void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override {
+    // When encoding an assignment to set symbol A to symbol B, also copy
+    // the st_other bits encoding the local entry point offset.
+    if (Value->getKind() != MCExpr::SymbolRef)
+      return;
+    const MCSymbol &RhsSym =
+        static_cast<const MCSymbolRefExpr *>(Value)->getSymbol();
+    MCSymbolData &Data = getStreamer().getOrCreateSymbolData(&RhsSym);
+    MCSymbolData &SymbolData = getStreamer().getOrCreateSymbolData(Symbol);
+    // The "other" values are stored in the last 6 bits of the second byte.
+    // The traditional defines for STO values assume the full byte and thus
+    // the shift to pack it.
+    unsigned Other = MCELF::getOther(SymbolData) << 2;
+    Other &= ~ELF::STO_PPC64_LOCAL_MASK;
+    Other |= (MCELF::getOther(Data) << 2) & ELF::STO_PPC64_LOCAL_MASK;
+    MCELF::setOther(SymbolData, Other >> 2);
+  }
 };
 
 class PPCTargetMachOStreamer : public PPCTargetStreamer {
index 6d2c120722897dac656b35eed72352504f10e31a..03f760ef86ea95055ca5d9482bd729c095494e59 100644 (file)
@@ -35,6 +35,9 @@ caller_other:
        nop
        .size caller_other, .-caller_other
 
+copy1 = callee1
+copy2 = callee2
+
 # Verify that use of .localentry implies ABI version 2
 # CHECK: ElfHeader {
 # CHECK: Flags [ (0x2)
@@ -68,3 +71,19 @@ caller_other:
 # CHECK-NEXT:  Other: 0
 # CHECK-NEXT:  Section: .text
 
+# Verify that symbol assignment copies the Other bits.
+# CHECK:       Name: copy1
+# CHECK-NEXT:  Value:
+# CHECK-NEXT:  Size: 16
+# CHECK-NEXT:  Binding: Local
+# CHECK-NEXT:  Type: Function
+# CHECK-NEXT:  Other: 96
+# CHECK-NEXT:  Section: .text
+# CHECK:       Name: copy2
+# CHECK-NEXT:  Value:
+# CHECK-NEXT:  Size: 8
+# CHECK-NEXT:  Binding: Local
+# CHECK-NEXT:  Type: Function
+# CHECK-NEXT:  Other: 0
+# CHECK-NEXT:  Section: .text
+