svn commit: r354469 - in head/contrib/llvm: include/llvm/DebugInfo/DWARF include/llvm/MC lib/DebugInfo/DWARF lib/MC lib/Object lib/Target/RISCV lib/Target/RISCV/AsmParser lib/Target/RISCV/MCTargetD...

Dimitry Andric dim at FreeBSD.org
Thu Nov 7 19:54:14 UTC 2019


Author: dim
Date: Thu Nov  7 19:54:08 2019
New Revision: 354469
URL: https://svnweb.freebsd.org/changeset/base/354469

Log:
  Merge commit f596f4507 from llvm git (by Sam Elliott):
  
    [RISCV] Add Custom Parser for Atomic Memory Operands
  
    Summary:
    GCC Accepts both (reg) and 0(reg) for atomic instruction memory
    operands. These instructions do not allow for an offset in their
    encoding, so in the latter case, the 0 is silently dropped.
  
    Due to how we have structured the RISCVAsmParser, the easiest way to
    add support for parsing this offset is to add a custom AsmOperand and
    parser. This parser drops all the parens, and just keeps the
    register.
  
    This commit also adds a custom printer for these operands, which
    matches the GCC canonical printer, printing both `(a0)` and `0(a0)`
    as `(a0)`.
  
    Reviewers: asb, lewis-revill
  
    Reviewed By: asb
  
    Subscribers: s.egerton, hiraditya, rbar, johnrusso, simoncook,
    apazos, sabuasal, niosHD, kito-cheng, shiva0217, jrtc27, MaskRay,
    zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o,
    rkruppe, jfb, PkmX, jocewei, psnobl, benna, Jim, llvm-commits
  
    Tags: #llvm
  
    Differential Revision: https://reviews.llvm.org/D65205
  
    llvm-svn: 367553
  
  Merge commit f596f4507 from llvm git (by Sam Elliott):
  
    [RISCV] Add FreeBSD targets
  
    Reviewers: asb
  
    Reviewed By: asb
  
    Subscribers: simoncook, s.egerton, lenary, psnobl, benna, mhorne,
    emaste, kito-cheng, shiva0217, rogfer01, rkruppe, cfe-commits
  
    Tags: #clang
  
    Differential Revision: https://reviews.llvm.org/D57795
  
    Patch by James Clarke (jrtc27)
  
    llvm-svn: 367557
  
  Merge commit f596f4507 from llvm git (by Hsiangkai Wang):
  
    [DebugInfo] Generate fixups as emitting DWARF .debug_frame/.eh_frame.
  
    It is necessary to generate fixups in .debug_frame or .eh_frame as
    relaxation is enabled due to the address delta may be changed after
    relaxation.
  
    There is an opcode with 6-bits data in debug frame encoding. So, we
    also need 6-bits fixup types.
  
    Differential Revision: https://reviews.llvm.org/D58335
  
    llvm-svn: 366524
  
  Merge commit f596f4507 from llvm git (by Hsiangkai Wang):
  
    [DebugInfo] Some fields do not need relocations even relax is enabled.
  
    In debug frame information, some fields, e.g., Length in CIE/FDE and
    Offset in FDE are attributes to describe the structure of CIE/FDE.
    They are not related to the relaxed code. However, these attributes
    are symbol differences. So, in current design, these attributes will
    be filled as zero and LLVM generates relocations for them.
  
    We only need to generate relocations for symbols in executable
    sections.  So, if the symbols are not located in executable sections,
    we still evaluate their values under relaxation.
  
    Differential Revision: https://reviews.llvm.org/D61584
  
    llvm-svn: 366531
  
  Merge commit f596f4507 from llvm git (by Alex Bradbury):
  
    [RISCV] Don't force absolute FK_Data_X fixups to relocs
  
    The current behavior of shouldForceRelocation forces relocations for
    the majority of fixups when relaxation is enabled. This makes sense
    for fixups which incorporate symbols but is unnecessary for simple
    data fixups where the fixup target is already resolved to an absolute
    value.
  
    Differential Revision: https://reviews.llvm.org/D63404
    Patch by Edward Jones.
  
    llvm-svn: 369257
  
  Merge commit f596f4507 from llvm git (by Alex Bradbury):
  
    [RISCV] Implement getExprForFDESymbol to ensure RISCV_32_PCREL is
    used for the FDE location
  
    Follow binutils in using RISCV_32_PCREL for the FDE initial location.
    As explained in the relevant binutils commit
    <https://github.com/riscv/riscv-binutils-gdb/commit/a6cbf936e3dce68114d28cdf60d510a3f78a6d40>,
    the ADD/SUB pair of relocations is problematic in the presence of
    linker relaxation.
  
    This patch has the same end goal as D64715 but includes test changes
    and avoids adding a new global VariantKind to MCExpr.h (preferring
    RISCVMCExpr VKs like the rest of the RISC-V backend).
  
    Differential Revision: https://reviews.llvm.org/D66419
  
    llvm-svn: 369375
  
  This series of merges will permit riscv64 kernels and riscv64sf worlds
  to build with clang instead of gcc (but still using the bfd linker).
  
  Requested by:	jhb
  Obtained from:	https://github.com/freebsd/freebsd/compare/master...bsdjhb:riscv_clang
  MFC after:	1 month
  X-MFC-With:	r353358

Modified:
  head/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
  head/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h
  head/contrib/llvm/include/llvm/MC/MCDwarf.h
  head/contrib/llvm/include/llvm/MC/MCFixup.h
  head/contrib/llvm/include/llvm/MC/MCFragment.h
  head/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
  head/contrib/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
  head/contrib/llvm/lib/MC/MCAsmBackend.cpp
  head/contrib/llvm/lib/MC/MCAssembler.cpp
  head/contrib/llvm/lib/MC/MCDwarf.cpp
  head/contrib/llvm/lib/MC/MCExpr.cpp
  head/contrib/llvm/lib/Object/RelocationResolver.cpp
  head/contrib/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
  head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
  head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
  head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
  head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
  head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
  head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h
  head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
  head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
  head/contrib/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
  head/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
  head/contrib/llvm/tools/clang/lib/Driver/ToolChains/FreeBSD.cpp

Modified: head/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
==============================================================================
--- head/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h	Thu Nov  7 19:54:08 2019	(r354469)
@@ -69,7 +69,7 @@ class CFIProgram { (public)
   /// starting at *Offset and ending at EndOffset. *Offset is updated
   /// to EndOffset upon successful parsing, or indicates the offset
   /// where a problem occurred in case an error is returned.
-  Error parse(DataExtractor Data, uint32_t *Offset, uint32_t EndOffset);
+  Error parse(DWARFDataExtractor Data, uint32_t *Offset, uint32_t EndOffset);
 
   void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
             unsigned IndentLevel = 1) const;

Modified: head/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h
==============================================================================
--- head/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h	Thu Nov  7 19:54:08 2019	(r354469)
@@ -40,8 +40,8 @@ class DWARFObject { (public)
   virtual const DWARFSection &getLocSection() const { return Dummy; }
   virtual const DWARFSection &getLoclistsSection() const { return Dummy; }
   virtual StringRef getARangeSection() const { return ""; }
-  virtual StringRef getDebugFrameSection() const { return ""; }
-  virtual StringRef getEHFrameSection() const { return ""; }
+  virtual const DWARFSection &getDebugFrameSection() const { return Dummy; }
+  virtual const DWARFSection &getEHFrameSection() const { return Dummy; }
   virtual const DWARFSection &getLineSection() const { return Dummy; }
   virtual StringRef getLineStringSection() const { return ""; }
   virtual StringRef getStringSection() const { return ""; }

Modified: head/contrib/llvm/include/llvm/MC/MCDwarf.h
==============================================================================
--- head/contrib/llvm/include/llvm/MC/MCDwarf.h	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/include/llvm/MC/MCDwarf.h	Thu Nov  7 19:54:08 2019	(r354469)
@@ -629,7 +629,8 @@ class MCDwarfFrameEmitter { (public)
   static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH);
   static void EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta);
   static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta,
-                               raw_ostream &OS);
+                               raw_ostream &OS, uint32_t *Offset = nullptr,
+                               uint32_t *Size = nullptr);
 };
 
 } // end namespace llvm

Modified: head/contrib/llvm/include/llvm/MC/MCFixup.h
==============================================================================
--- head/contrib/llvm/include/llvm/MC/MCFixup.h	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/include/llvm/MC/MCFixup.h	Thu Nov  7 19:54:08 2019	(r354469)
@@ -20,35 +20,38 @@ class MCExpr;
 
 /// Extensible enumeration to represent the type of a fixup.
 enum MCFixupKind {
-  FK_NONE = 0,   ///< A no-op fixup.
-  FK_Data_1,     ///< 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.
-  FK_PCRel_1,    ///< A one-byte pc relative fixup.
-  FK_PCRel_2,    ///< A two-byte pc relative fixup.
-  FK_PCRel_4,    ///< A four-byte pc relative fixup.
-  FK_PCRel_8,    ///< A eight-byte pc relative fixup.
-  FK_GPRel_1,    ///< A one-byte gp relative fixup.
-  FK_GPRel_2,    ///< A two-byte gp relative fixup.
-  FK_GPRel_4,    ///< A four-byte gp relative fixup.
-  FK_GPRel_8,    ///< A eight-byte gp relative fixup.
-  FK_DTPRel_4,   ///< A four-byte dtp relative fixup.
-  FK_DTPRel_8,   ///< A eight-byte dtp relative fixup.
-  FK_TPRel_4,    ///< A four-byte tp relative fixup.
-  FK_TPRel_8,    ///< A eight-byte tp relative fixup.
-  FK_SecRel_1,   ///< A one-byte section relative fixup.
-  FK_SecRel_2,   ///< A two-byte section relative fixup.
-  FK_SecRel_4,   ///< A four-byte section relative fixup.
-  FK_SecRel_8,   ///< A eight-byte section relative fixup.
-  FK_Data_Add_1, ///< A one-byte add fixup.
-  FK_Data_Add_2, ///< A two-byte add fixup.
-  FK_Data_Add_4, ///< A four-byte add fixup.
-  FK_Data_Add_8, ///< A eight-byte add fixup.
-  FK_Data_Sub_1, ///< A one-byte sub fixup.
-  FK_Data_Sub_2, ///< A two-byte sub fixup.
-  FK_Data_Sub_4, ///< A four-byte sub fixup.
-  FK_Data_Sub_8, ///< A eight-byte sub fixup.
+  FK_NONE = 0,    ///< A no-op fixup.
+  FK_Data_1,      ///< 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.
+  FK_Data_6b,     ///< A six-bits fixup.
+  FK_PCRel_1,     ///< A one-byte pc relative fixup.
+  FK_PCRel_2,     ///< A two-byte pc relative fixup.
+  FK_PCRel_4,     ///< A four-byte pc relative fixup.
+  FK_PCRel_8,     ///< A eight-byte pc relative fixup.
+  FK_GPRel_1,     ///< A one-byte gp relative fixup.
+  FK_GPRel_2,     ///< A two-byte gp relative fixup.
+  FK_GPRel_4,     ///< A four-byte gp relative fixup.
+  FK_GPRel_8,     ///< A eight-byte gp relative fixup.
+  FK_DTPRel_4,    ///< A four-byte dtp relative fixup.
+  FK_DTPRel_8,    ///< A eight-byte dtp relative fixup.
+  FK_TPRel_4,     ///< A four-byte tp relative fixup.
+  FK_TPRel_8,     ///< A eight-byte tp relative fixup.
+  FK_SecRel_1,    ///< A one-byte section relative fixup.
+  FK_SecRel_2,    ///< A two-byte section relative fixup.
+  FK_SecRel_4,    ///< A four-byte section relative fixup.
+  FK_SecRel_8,    ///< A eight-byte section relative fixup.
+  FK_Data_Add_1,  ///< A one-byte add fixup.
+  FK_Data_Add_2,  ///< A two-byte add fixup.
+  FK_Data_Add_4,  ///< A four-byte add fixup.
+  FK_Data_Add_8,  ///< A eight-byte add fixup.
+  FK_Data_Add_6b, ///< A six-bits add fixup.
+  FK_Data_Sub_1,  ///< A one-byte sub fixup.
+  FK_Data_Sub_2,  ///< A two-byte sub fixup.
+  FK_Data_Sub_4,  ///< A four-byte sub fixup.
+  FK_Data_Sub_8,  ///< A eight-byte sub fixup.
+  FK_Data_Sub_6b, ///< A six-bits sub fixup.
 
   FirstTargetFixupKind = 128,
 
@@ -129,16 +132,40 @@ class MCFixup { (public)
 
   /// Return the generic fixup kind for a value with the given size. It
   /// is an error to pass an unsupported size.
-  static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) {
+  static MCFixupKind getKindForSize(unsigned Size, bool IsPCRel) {
     switch (Size) {
     default: llvm_unreachable("Invalid generic fixup size!");
-    case 1: return isPCRel ? FK_PCRel_1 : FK_Data_1;
-    case 2: return isPCRel ? FK_PCRel_2 : FK_Data_2;
-    case 4: return isPCRel ? FK_PCRel_4 : FK_Data_4;
-    case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8;
+    case 1:
+      return IsPCRel ? FK_PCRel_1 : FK_Data_1;
+    case 2:
+      return IsPCRel ? FK_PCRel_2 : FK_Data_2;
+    case 4:
+      return IsPCRel ? FK_PCRel_4 : FK_Data_4;
+    case 8:
+      return IsPCRel ? FK_PCRel_8 : FK_Data_8;
     }
   }
 
+  /// Return the generic fixup kind for a value with the given size in bits.
+  /// It is an error to pass an unsupported size.
+  static MCFixupKind getKindForSizeInBits(unsigned Size, bool IsPCRel) {
+    switch (Size) {
+    default:
+      llvm_unreachable("Invalid generic fixup size!");
+    case 6:
+      assert(!IsPCRel && "Invalid pc-relative fixup size!");
+      return FK_Data_6b;
+    case 8:
+      return IsPCRel ? FK_PCRel_1 : FK_Data_1;
+    case 16:
+      return IsPCRel ? FK_PCRel_2 : FK_Data_2;
+    case 32:
+      return IsPCRel ? FK_PCRel_4 : FK_Data_4;
+    case 64:
+      return IsPCRel ? FK_PCRel_8 : FK_Data_8;
+    }
+  }
+
   /// Return the generic fixup kind for an addition with a given size. It
   /// is an error to pass an unsupported size.
   static MCFixupKind getAddKindForKind(unsigned Kind) {
@@ -148,6 +175,7 @@ class MCFixup { (public)
     case FK_Data_2: return FK_Data_Add_2;
     case FK_Data_4: return FK_Data_Add_4;
     case FK_Data_8: return FK_Data_Add_8;
+    case FK_Data_6b: return FK_Data_Add_6b;
     }
   }
 
@@ -160,6 +188,7 @@ class MCFixup { (public)
     case FK_Data_2: return FK_Data_Sub_2;
     case FK_Data_4: return FK_Data_Sub_4;
     case FK_Data_8: return FK_Data_Sub_8;
+    case FK_Data_6b: return FK_Data_Sub_6b;
     }
   }
 

Modified: head/contrib/llvm/include/llvm/MC/MCFragment.h
==============================================================================
--- head/contrib/llvm/include/llvm/MC/MCFragment.h	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/include/llvm/MC/MCFragment.h	Thu Nov  7 19:54:08 2019	(r354469)
@@ -149,6 +149,7 @@ class MCEncodedFragment : public MCFragment { (public)
     case MCFragment::FT_CompactEncodedInst:
     case MCFragment::FT_Data:
     case MCFragment::FT_Dwarf:
+    case MCFragment::FT_DwarfFrame:
       return true;
     }
   }
@@ -232,7 +233,8 @@ class MCEncodedFragmentWithFixups : (public)
   static bool classof(const MCFragment *F) {
     MCFragment::FragmentType Kind = F->getKind();
     return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||
-           Kind == MCFragment::FT_CVDefRange || Kind == MCFragment::FT_Dwarf;;
+           Kind == MCFragment::FT_CVDefRange || Kind == MCFragment::FT_Dwarf ||
+           Kind == MCFragment::FT_DwarfFrame;
   }
 };
 
@@ -543,26 +545,20 @@ class MCDwarfLineAddrFragment : public MCEncodedFragme
   }
 };
 
-class MCDwarfCallFrameFragment : public MCFragment {
+class MCDwarfCallFrameFragment : public MCEncodedFragmentWithFixups<8, 1> {
   /// AddrDelta - The expression for the difference of the two symbols that
   /// make up the address delta between two .cfi_* dwarf directives.
   const MCExpr *AddrDelta;
 
-  SmallString<8> Contents;
-
 public:
   MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
-      : MCFragment(FT_DwarfFrame, false, Sec), AddrDelta(&AddrDelta) {
-    Contents.push_back(0);
-  }
+      : MCEncodedFragmentWithFixups<8, 1>(FT_DwarfFrame, false, Sec),
+        AddrDelta(&AddrDelta) {}
 
   /// \name Accessors
   /// @{
 
   const MCExpr &getAddrDelta() const { return *AddrDelta; }
-
-  SmallString<8> &getContents() { return Contents; }
-  const SmallString<8> &getContents() const { return Contents; }
 
   /// @}
 

Modified: head/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
==============================================================================
--- head/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -402,11 +402,11 @@ void DWARFContext::dump(
   }
 
   if (const auto *Off = shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
-                                   DObj->getDebugFrameSection()))
+                                   DObj->getDebugFrameSection().Data))
     getDebugFrame()->dump(OS, getRegisterInfo(), *Off);
 
   if (const auto *Off = shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
-                                   DObj->getEHFrameSection()))
+                                   DObj->getEHFrameSection().Data))
     getEHFrame()->dump(OS, getRegisterInfo(), *Off);
 
   if (DumpType & DIDT_DebugMacro) {
@@ -766,7 +766,7 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() {
   // provides this information). This problem is fixed in DWARFv4
   // See this dwarf-discuss discussion for more details:
   // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
-  DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),
+  DWARFDataExtractor debugFrameData(*DObj, DObj->getDebugFrameSection(),
                                     isLittleEndian(), DObj->getAddressSize());
   DebugFrame.reset(new DWARFDebugFrame(getArch(), false /* IsEH */));
   DebugFrame->parse(debugFrameData);
@@ -777,8 +777,8 @@ const DWARFDebugFrame *DWARFContext::getEHFrame() {
   if (EHFrame)
     return EHFrame.get();
 
-  DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
-                                    DObj->getAddressSize());
+  DWARFDataExtractor debugFrameData(*DObj, DObj->getEHFrameSection(),
+                                    isLittleEndian(), DObj->getAddressSize());
   DebugFrame.reset(new DWARFDebugFrame(getArch(), true /* IsEH */));
   DebugFrame->parse(debugFrameData);
   return DebugFrame.get();
@@ -1385,6 +1385,8 @@ class DWARFObjInMemory final : public DWARFObject {
   DWARFSectionMap RnglistsSection;
   DWARFSectionMap StringOffsetSection;
   DWARFSectionMap LineDWOSection;
+  DWARFSectionMap DebugFrameSection;
+  DWARFSectionMap EHFrameSection;
   DWARFSectionMap LocDWOSection;
   DWARFSectionMap StringOffsetDWOSection;
   DWARFSectionMap RangeDWOSection;
@@ -1405,6 +1407,8 @@ class DWARFObjInMemory final : public DWARFObject {
         .Case("debug_loc", &LocSection)
         .Case("debug_loclists", &LocListsSection)
         .Case("debug_line", &LineSection)
+        .Case("debug_frame", &DebugFrameSection)
+        .Case("eh_frame", &EHFrameSection)
         .Case("debug_str_offsets", &StringOffsetSection)
         .Case("debug_ranges", &RangeSection)
         .Case("debug_rnglists", &RnglistsSection)
@@ -1428,8 +1432,6 @@ class DWARFObjInMemory final : public DWARFObject {
 
   StringRef AbbrevSection;
   StringRef ARangeSection;
-  StringRef DebugFrameSection;
-  StringRef EHFrameSection;
   StringRef StringSection;
   StringRef MacinfoSection;
   StringRef AbbrevDWOSection;
@@ -1449,8 +1451,6 @@ class DWARFObjInMemory final : public DWARFObject {
     return StringSwitch<StringRef *>(Name)
         .Case("debug_abbrev", &AbbrevSection)
         .Case("debug_aranges", &ARangeSection)
-        .Case("debug_frame", &DebugFrameSection)
-        .Case("eh_frame", &EHFrameSection)
         .Case("debug_str", &StringSection)
         .Case("debug_macinfo", &MacinfoSection)
         .Case("debug_abbrev.dwo", &AbbrevDWOSection)
@@ -1747,8 +1747,12 @@ class DWARFObjInMemory final : public DWARFObject {
   const DWARFSection &getLocSection() const override { return LocSection; }
   const DWARFSection &getLoclistsSection() const override { return LocListsSection; }
   StringRef getARangeSection() const override { return ARangeSection; }
-  StringRef getDebugFrameSection() const override { return DebugFrameSection; }
-  StringRef getEHFrameSection() const override { return EHFrameSection; }
+  const DWARFSection &getDebugFrameSection() const override {
+    return DebugFrameSection;
+  }
+  const DWARFSection &getEHFrameSection() const override {
+    return EHFrameSection;
+  }
   const DWARFSection &getLineSection() const override { return LineSection; }
   StringRef getStringSection() const override { return StringSection; }
   const DWARFSection &getRangeSection() const override { return RangeSection; }

Modified: head/contrib/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
==============================================================================
--- head/contrib/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -34,10 +34,10 @@ using namespace dwarf;
 const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
 const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
 
-Error CFIProgram::parse(DataExtractor Data, uint32_t *Offset,
+Error CFIProgram::parse(DWARFDataExtractor Data, uint32_t *Offset,
                         uint32_t EndOffset) {
   while (*Offset < EndOffset) {
-    uint8_t Opcode = Data.getU8(Offset);
+    uint8_t Opcode = Data.getRelocatedValue(1, Offset);
     // Some instructions have a primary opcode encoded in the top bits.
     uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK;
 
@@ -74,19 +74,19 @@ Error CFIProgram::parse(DataExtractor Data, uint32_t *
         break;
       case DW_CFA_set_loc:
         // Operands: Address
-        addInstruction(Opcode, Data.getAddress(Offset));
+        addInstruction(Opcode, Data.getRelocatedAddress(Offset));
         break;
       case DW_CFA_advance_loc1:
         // Operands: 1-byte delta
-        addInstruction(Opcode, Data.getU8(Offset));
+        addInstruction(Opcode, Data.getRelocatedValue(1, Offset));
         break;
       case DW_CFA_advance_loc2:
         // Operands: 2-byte delta
-        addInstruction(Opcode, Data.getU16(Offset));
+        addInstruction(Opcode, Data.getRelocatedValue(2, Offset));
         break;
       case DW_CFA_advance_loc4:
         // Operands: 4-byte delta
-        addInstruction(Opcode, Data.getU32(Offset));
+        addInstruction(Opcode, Data.getRelocatedValue(4, Offset));
         break;
       case DW_CFA_restore_extended:
       case DW_CFA_undefined:
@@ -361,7 +361,7 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
     uint32_t StartOffset = Offset;
 
     bool IsDWARF64 = false;
-    uint64_t Length = Data.getU32(&Offset);
+    uint64_t Length = Data.getRelocatedValue(4, &Offset);
     uint64_t Id;
 
     if (Length == UINT32_MAX) {
@@ -369,7 +369,7 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
       // field being 0xffffffff. Then, the next 64 bits are the actual entry
       // length.
       IsDWARF64 = true;
-      Length = Data.getU64(&Offset);
+      Length = Data.getRelocatedValue(8, &Offset);
     }
 
     // At this point, Offset points to the next field after Length.
@@ -512,8 +512,8 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
             ReportError(StartOffset, "Parsing augmentation data at %lx failed");
         }
       } else {
-        InitialLocation = Data.getAddress(&Offset);
-        AddressRange = Data.getAddress(&Offset);
+        InitialLocation = Data.getRelocatedAddress(&Offset);
+        AddressRange = Data.getRelocatedAddress(&Offset);
       }
 
       Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,

Modified: head/contrib/llvm/lib/MC/MCAsmBackend.cpp
==============================================================================
--- head/contrib/llvm/lib/MC/MCAsmBackend.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/MC/MCAsmBackend.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -73,6 +73,7 @@ const MCFixupKindInfo &MCAsmBackend::getFixupKindInfo(
       {"FK_Data_2", 0, 16, 0},
       {"FK_Data_4", 0, 32, 0},
       {"FK_Data_8", 0, 64, 0},
+      {"FK_Data_6b", 0, 6, 0},
       {"FK_PCRel_1", 0, 8, MCFixupKindInfo::FKF_IsPCRel},
       {"FK_PCRel_2", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
       {"FK_PCRel_4", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
@@ -93,10 +94,12 @@ const MCFixupKindInfo &MCAsmBackend::getFixupKindInfo(
       {"FK_Data_Add_2", 0, 16, 0},
       {"FK_Data_Add_4", 0, 32, 0},
       {"FK_Data_Add_8", 0, 64, 0},
+      {"FK_Data_Add_6b", 0, 6, 0},
       {"FK_Data_Sub_1", 0, 8, 0},
       {"FK_Data_Sub_2", 0, 16, 0},
       {"FK_Data_Sub_4", 0, 32, 0},
-      {"FK_Data_Sub_8", 0, 64, 0}};
+      {"FK_Data_Sub_8", 0, 64, 0},
+      {"FK_Data_Sub_6b", 0, 6, 0}};
 
   assert((size_t)Kind <= array_lengthof(Builtins) && "Unknown fixup kind");
   return Builtins[Kind];

Modified: head/contrib/llvm/lib/MC/MCAssembler.cpp
==============================================================================
--- head/contrib/llvm/lib/MC/MCAssembler.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/MC/MCAssembler.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -840,6 +840,10 @@ void MCAssembler::layout(MCAsmLayout &Layout) {
           getBackend().shouldInsertFixupForCodeAlign(*this, Layout, *AF);
         }
         continue;
+      } else if (auto *FragWithFixups =
+                     dyn_cast<MCDwarfCallFrameFragment>(&Frag)) {
+        Fixups = FragWithFixups->getFixups();
+        Contents = FragWithFixups->getContents();
       } else
         llvm_unreachable("Unknown fragment with fixups!");
       for (const MCFixup &Fixup : Fixups) {
@@ -969,13 +973,9 @@ bool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layo
   MCContext &Context = Layout.getAssembler().getContext();
   uint64_t OldSize = DF.getContents().size();
   int64_t AddrDelta;
-  bool Abs;
-  if (getBackend().requiresDiffExpressionRelocations())
-    Abs = DF.getAddrDelta().evaluateAsAbsolute(AddrDelta, Layout);
-  else {
-    Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, Layout);
-    assert(Abs && "We created a line delta with an invalid expression");
-  }
+  bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, Layout);
+  assert(Abs && "We created a line delta with an invalid expression");
+  (void)Abs;
   int64_t LineDelta;
   LineDelta = DF.getLineDelta();
   SmallVectorImpl<char> &Data = DF.getContents();
@@ -983,7 +983,7 @@ bool MCAssembler::relaxDwarfLineAddr(MCAsmLayout &Layo
   raw_svector_ostream OSE(Data);
   DF.getFixups().clear();
 
-  if (Abs) {
+  if (!getBackend().requiresDiffExpressionRelocations()) {
     MCDwarfLineAddr::Encode(Context, getDWARFLinetableParams(), LineDelta,
                             AddrDelta, OSE);
   } else {
@@ -1017,10 +1017,25 @@ bool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLay
   bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, Layout);
   assert(Abs && "We created call frame with an invalid expression");
   (void) Abs;
-  SmallString<8> &Data = DF.getContents();
+  SmallVectorImpl<char> &Data = DF.getContents();
   Data.clear();
   raw_svector_ostream OSE(Data);
-  MCDwarfFrameEmitter::EncodeAdvanceLoc(Context, AddrDelta, OSE);
+  DF.getFixups().clear();
+
+  if (getBackend().requiresDiffExpressionRelocations()) {
+    uint32_t Offset;
+    uint32_t Size;
+    MCDwarfFrameEmitter::EncodeAdvanceLoc(Context, AddrDelta, OSE, &Offset,
+                                          &Size);
+    if (Size) {
+      DF.getFixups().push_back(MCFixup::create(
+          Offset, &DF.getAddrDelta(),
+          MCFixup::getKindForSizeInBits(Size /*In bits.*/, false /*isPCRel*/)));
+    }
+  } else {
+    MCDwarfFrameEmitter::EncodeAdvanceLoc(Context, AddrDelta, OSE);
+  }
+
   return OldSize != Data.size();
 }
 

Modified: head/contrib/llvm/lib/MC/MCDwarf.cpp
==============================================================================
--- head/contrib/llvm/lib/MC/MCDwarf.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/MC/MCDwarf.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -1897,26 +1897,54 @@ void MCDwarfFrameEmitter::EmitAdvanceLoc(MCObjectStrea
 }
 
 void MCDwarfFrameEmitter::EncodeAdvanceLoc(MCContext &Context,
-                                           uint64_t AddrDelta,
-                                           raw_ostream &OS) {
+                                           uint64_t AddrDelta, raw_ostream &OS,
+                                           uint32_t *Offset, uint32_t *Size) {
   // Scale the address delta by the minimum instruction length.
   AddrDelta = ScaleAddrDelta(Context, AddrDelta);
 
+  bool WithFixups = false;
+  if (Offset && Size)
+    WithFixups = true;
+
   support::endianness E =
       Context.getAsmInfo()->isLittleEndian() ? support::little : support::big;
   if (AddrDelta == 0) {
+    if (WithFixups) {
+      *Offset = 0;
+      *Size = 0;
+    }
   } else if (isUIntN(6, AddrDelta)) {
     uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
-    OS << Opcode;
+    if (WithFixups) {
+      *Offset = OS.tell();
+      *Size = 6;
+      OS << uint8_t(dwarf::DW_CFA_advance_loc);
+    } else
+      OS << Opcode;
   } else if (isUInt<8>(AddrDelta)) {
     OS << uint8_t(dwarf::DW_CFA_advance_loc1);
-    OS << uint8_t(AddrDelta);
+    if (WithFixups) {
+      *Offset = OS.tell();
+      *Size = 8;
+      OS.write_zeros(1);
+    } else
+      OS << uint8_t(AddrDelta);
   } else if (isUInt<16>(AddrDelta)) {
     OS << uint8_t(dwarf::DW_CFA_advance_loc2);
-    support::endian::write<uint16_t>(OS, AddrDelta, E);
+    if (WithFixups) {
+      *Offset = OS.tell();
+      *Size = 16;
+      OS.write_zeros(2);
+    } else
+      support::endian::write<uint16_t>(OS, AddrDelta, E);
   } else {
     assert(isUInt<32>(AddrDelta));
     OS << uint8_t(dwarf::DW_CFA_advance_loc4);
-    support::endian::write<uint32_t>(OS, AddrDelta, E);
+    if (WithFixups) {
+      *Offset = OS.tell();
+      *Size = 32;
+      OS.write_zeros(4);
+    } else
+      support::endian::write<uint32_t>(OS, AddrDelta, E);
   }
 }

Modified: head/contrib/llvm/lib/MC/MCExpr.cpp
==============================================================================
--- head/contrib/llvm/lib/MC/MCExpr.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/MC/MCExpr.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -577,6 +577,24 @@ static void AttemptToFoldSymbolOffsetDifference(
   A = B = nullptr;
 }
 
+static bool canFold(const MCAssembler *Asm, const MCSymbolRefExpr *A,
+                    const MCSymbolRefExpr *B, bool InSet) {
+  if (InSet)
+    return true;
+
+  if (!Asm->getBackend().requiresDiffExpressionRelocations())
+    return true;
+
+  const MCSymbol &CheckSym = A ? A->getSymbol() : B->getSymbol();
+  if (!CheckSym.isInSection())
+    return true;
+
+  if (!CheckSym.getSection().hasInstructions())
+    return true;
+
+  return false;
+}
+
 /// Evaluate the result of an add between (conceptually) two MCValues.
 ///
 /// This routine conceptually attempts to construct an MCValue:
@@ -617,8 +635,7 @@ EvaluateSymbolicAdd(const MCAssembler *Asm, const MCAs
   // the backend requires this to be emitted as individual relocations, unless
   // the InSet flag is set to get the current difference anyway (used for
   // example to calculate symbol sizes).
-  if (Asm &&
-      (InSet || !Asm->getBackend().requiresDiffExpressionRelocations())) {
+  if (Asm && canFold(Asm, LHS_A, LHS_B, InSet)) {
     // First, fold out any differences which are fully resolved. By
     // reassociating terms in
     //   Result = (LHS_A - LHS_B + LHS_Cst) + (RHS_A - RHS_B + RHS_Cst).

Modified: head/contrib/llvm/lib/Object/RelocationResolver.cpp
==============================================================================
--- head/contrib/llvm/lib/Object/RelocationResolver.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/Object/RelocationResolver.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -335,6 +335,8 @@ static bool supportsRISCV(uint64_t Type) {
   case ELF::R_RISCV_NONE:
   case ELF::R_RISCV_32:
   case ELF::R_RISCV_64:
+  case ELF::R_RISCV_SET6:
+  case ELF::R_RISCV_SUB6:
   case ELF::R_RISCV_ADD8:
   case ELF::R_RISCV_SUB8:
   case ELF::R_RISCV_ADD16:
@@ -358,6 +360,10 @@ static uint64_t resolveRISCV(RelocationRef R, uint64_t
     return (S + RA) & 0xFFFFFFFF;
   case ELF::R_RISCV_64:
     return S + RA;
+  case ELF::R_RISCV_SET6:
+    return (A + (S + RA)) & 0xFF;
+  case ELF::R_RISCV_SUB6:
+    return (A - (S + RA)) & 0xFF;
   case ELF::R_RISCV_ADD8:
     return (A + (S + RA)) & 0xFF;
   case ELF::R_RISCV_SUB8:

Modified: head/contrib/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
==============================================================================
--- head/contrib/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -127,6 +127,7 @@ class RISCVAsmParser : public MCTargetAsmParser {
   OperandMatchResultTy parseRegister(OperandVector &Operands,
                                      bool AllowParens = false);
   OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
+  OperandMatchResultTy parseAtomicMemOp(OperandVector &Operands);
   OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
   OperandMatchResultTy parseBareSymbol(OperandVector &Operands);
   OperandMatchResultTy parseCallSymbol(OperandVector &Operands);
@@ -575,6 +576,15 @@ struct RISCVOperand : public MCParsedAsmOperand { (pub
 
   bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); }
 
+  bool isImmZero() const {
+    if (!isImm())
+      return false;
+    int64_t Imm;
+    RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+    bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+    return IsConstantImm && (Imm == 0) && VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
   /// getStartLoc - Gets location of the first token of this operand
   SMLoc getStartLoc() const override { return StartLoc; }
   /// getEndLoc - Gets location of the last token of this operand
@@ -1296,6 +1306,73 @@ RISCVAsmParser::parseMemOpBaseReg(OperandVector &Opera
 
   getParser().Lex(); // Eat ')'
   Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
+
+  return MatchOperand_Success;
+}
+
+OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) {
+  // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand"
+  // as one of their register operands, such as `(a0)`. This just denotes that
+  // the register (in this case `a0`) contains a memory address.
+  //
+  // Normally, we would be able to parse these by putting the parens into the
+  // instruction string. However, GNU as also accepts a zero-offset memory
+  // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed
+  // with parseImmediate followed by parseMemOpBaseReg, but these instructions
+  // do not accept an immediate operand, and we do not want to add a "dummy"
+  // operand that is silently dropped.
+  //
+  // Instead, we use this custom parser. This will: allow (and discard) an
+  // offset if it is zero; require (and discard) parentheses; and add only the
+  // parsed register operand to `Operands`.
+  //
+  // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which
+  // will only print the register surrounded by parentheses (which GNU as also
+  // uses as its canonical representation for these operands).
+  std::unique_ptr<RISCVOperand> OptionalImmOp;
+
+  if (getLexer().isNot(AsmToken::LParen)) {
+    // Parse an Integer token. We do not accept arbritrary constant expressions
+    // in the offset field (because they may include parens, which complicates
+    // parsing a lot).
+    int64_t ImmVal;
+    SMLoc ImmStart = getLoc();
+    if (getParser().parseIntToken(ImmVal,
+                                  "expected '(' or optional integer offset"))
+      return MatchOperand_ParseFail;
+
+    // Create a RISCVOperand for checking later (so the error messages are
+    // nicer), but we don't add it to Operands.
+    SMLoc ImmEnd = getLoc();
+    OptionalImmOp =
+        RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()),
+                                ImmStart, ImmEnd, isRV64());
+  }
+
+  if (getLexer().isNot(AsmToken::LParen)) {
+    Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset"
+                                  : "expected '(' or optional integer offset");
+    return MatchOperand_ParseFail;
+  }
+  getParser().Lex(); // Eat '('
+
+  if (parseRegister(Operands) != MatchOperand_Success) {
+    Error(getLoc(), "expected register");
+    return MatchOperand_ParseFail;
+  }
+
+  if (getLexer().isNot(AsmToken::RParen)) {
+    Error(getLoc(), "expected ')'");
+    return MatchOperand_ParseFail;
+  }
+  getParser().Lex(); // Eat ')'
+
+  // Deferred Handling of non-zero offsets. This makes the error messages nicer.
+  if (OptionalImmOp && !OptionalImmOp->isImmZero()) {
+    Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0",
+          SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
+    return MatchOperand_ParseFail;
+  }
 
   return MatchOperand_Success;
 }

Modified: head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
==============================================================================
--- head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -33,6 +33,13 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAs
   switch ((unsigned)Fixup.getKind()) {
   default:
     break;
+  case FK_Data_1:
+  case FK_Data_2:
+  case FK_Data_4:
+  case FK_Data_8:
+    if (Target.isAbsolute())
+      return false;
+    break;
   case RISCV::fixup_riscv_got_hi20:
   case RISCV::fixup_riscv_tls_got_hi20:
   case RISCV::fixup_riscv_tls_gd_hi20:
@@ -186,6 +193,7 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup,
   case FK_Data_2:
   case FK_Data_4:
   case FK_Data_8:
+  case FK_Data_6b:
     return Value;
   case RISCV::fixup_riscv_lo12_i:
   case RISCV::fixup_riscv_pcrel_lo12_i:

Modified: head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
==============================================================================
--- head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "MCTargetDesc/RISCVFixupKinds.h"
+#include "MCTargetDesc/RISCVMCExpr.h"
 #include "MCTargetDesc/RISCVMCTargetDesc.h"
 #include "llvm/MC/MCELFObjectWriter.h"
 #include "llvm/MC/MCFixup.h"
@@ -47,6 +48,7 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext 
                                             const MCValue &Target,
                                             const MCFixup &Fixup,
                                             bool IsPCRel) const {
+  const MCExpr *Expr = Fixup.getValue();
   // Determine the type of the relocation
   unsigned Kind = Fixup.getKind();
   if (IsPCRel) {
@@ -87,6 +89,9 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext 
   default:
     llvm_unreachable("invalid fixup kind!");
   case FK_Data_4:
+    if (Expr->getKind() == MCExpr::Target &&
+        cast<RISCVMCExpr>(Expr)->getKind() == RISCVMCExpr::VK_RISCV_32_PCREL)
+      return ELF::R_RISCV_32_PCREL;
     return ELF::R_RISCV_32;
   case FK_Data_8:
     return ELF::R_RISCV_64;
@@ -98,6 +103,8 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext 
     return ELF::R_RISCV_ADD32;
   case FK_Data_Add_8:
     return ELF::R_RISCV_ADD64;
+  case FK_Data_Add_6b:
+    return ELF::R_RISCV_SET6;
   case FK_Data_Sub_1:
     return ELF::R_RISCV_SUB8;
   case FK_Data_Sub_2:
@@ -106,6 +113,8 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext 
     return ELF::R_RISCV_SUB32;
   case FK_Data_Sub_8:
     return ELF::R_RISCV_SUB64;
+  case FK_Data_Sub_6b:
+    return ELF::R_RISCV_SUB6;
   case RISCV::fixup_riscv_hi20:
     return ELF::R_RISCV_HI20;
   case RISCV::fixup_riscv_lo12_i:

Modified: head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
==============================================================================
--- head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -112,3 +112,15 @@ void RISCVInstPrinter::printFRMArg(const MCInst *MI, u
       static_cast<RISCVFPRndMode::RoundingMode>(MI->getOperand(OpNo).getImm());
   O << RISCVFPRndMode::roundingModeToString(FRMArg);
 }
+
+void RISCVInstPrinter::printAtomicMemOp(const MCInst *MI, unsigned OpNo,
+                                        const MCSubtargetInfo &STI,
+                                        raw_ostream &O) {
+  const MCOperand &MO = MI->getOperand(OpNo);
+
+  assert(MO.isReg() && "printAtomicMemOp can only print register operands");
+  O << "(";
+  printRegName(O, MO.getReg());
+  O << ")";
+  return;
+}

Modified: head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
==============================================================================
--- head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h	Thu Nov  7 19:54:08 2019	(r354469)
@@ -37,6 +37,8 @@ class RISCVInstPrinter : public MCInstPrinter { (publi
                      const MCSubtargetInfo &STI, raw_ostream &O);
   void printFRMArg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
                    raw_ostream &O);
+  void printAtomicMemOp(const MCInst *MI, unsigned OpNo,
+                        const MCSubtargetInfo &STI, raw_ostream &O);
 
   // Autogenerated by tblgen.
   void printInstruction(const MCInst *MI, const MCSubtargetInfo &STI,

Modified: head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
==============================================================================
--- head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -11,7 +11,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "RISCVMCAsmInfo.h"
+#include "MCTargetDesc/RISCVMCExpr.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/MC/MCStreamer.h"
 using namespace llvm;
 
 void RISCVMCAsmInfo::anchor() {}
@@ -24,4 +27,21 @@ RISCVMCAsmInfo::RISCVMCAsmInfo(const Triple &TT) {
   ExceptionsType = ExceptionHandling::DwarfCFI;
   Data16bitsDirective = "\t.half\t";
   Data32bitsDirective = "\t.word\t";
+}
+
+const MCExpr *RISCVMCAsmInfo::getExprForFDESymbol(const MCSymbol *Sym,
+                                                  unsigned Encoding,
+                                                  MCStreamer &Streamer) const {
+  if (!(Encoding & dwarf::DW_EH_PE_pcrel))
+    return MCAsmInfo::getExprForFDESymbol(Sym, Encoding, Streamer);
+
+  // The default symbol subtraction results in an ADD/SUB relocation pair.
+  // Processing this relocation pair is problematic when linker relaxation is
+  // enabled, so we follow binutils in using the R_RISCV_32_PCREL relocation
+  // for the FDE initial location.
+  MCContext &Ctx = Streamer.getContext();
+  const MCExpr *ME =
+      MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);
+  assert(Encoding & dwarf::DW_EH_PE_sdata4 && "Unexpected encoding");
+  return RISCVMCExpr::create(ME, RISCVMCExpr::VK_RISCV_32_PCREL, Ctx);
 }

Modified: head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h
==============================================================================
--- head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h	Thu Nov  7 19:54:08 2019	(r354469)
@@ -23,6 +23,9 @@ class RISCVMCAsmInfo : public MCAsmInfoELF {
 
 public:
   explicit RISCVMCAsmInfo(const Triple &TargetTriple);
+
+  const MCExpr *getExprForFDESymbol(const MCSymbol *Sym, unsigned Encoding,
+                                    MCStreamer &Streamer) const override;
 };
 
 } // namespace llvm

Modified: head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
==============================================================================
--- head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -266,6 +266,7 @@ unsigned RISCVMCCodeEmitter::getImmOpValue(const MCIns
     switch (RVExpr->getKind()) {
     case RISCVMCExpr::VK_RISCV_None:
     case RISCVMCExpr::VK_RISCV_Invalid:
+    case RISCVMCExpr::VK_RISCV_32_PCREL:
       llvm_unreachable("Unhandled fixup kind!");
     case RISCVMCExpr::VK_RISCV_TPREL_ADD:
       // tprel_add is only used to indicate that a relocation should be emitted

Modified: head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
==============================================================================
--- head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h	Thu Nov  7 19:54:08 2019	(r354469)
@@ -36,6 +36,7 @@ class RISCVMCExpr : public MCTargetExpr { (public)
     VK_RISCV_TLS_GD_HI,
     VK_RISCV_CALL,
     VK_RISCV_CALL_PLT,
+    VK_RISCV_32_PCREL,
     VK_RISCV_Invalid
   };
 

Modified: head/contrib/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
==============================================================================
--- head/contrib/llvm/lib/Target/RISCV/RISCVInstrInfoA.td	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/lib/Target/RISCV/RISCVInstrInfoA.td	Thu Nov  7 19:54:08 2019	(r354469)
@@ -12,14 +12,32 @@
 //===----------------------------------------------------------------------===//
 
 //===----------------------------------------------------------------------===//
+// Operand and SDNode transformation definitions.
+//===----------------------------------------------------------------------===//
+
+// A parse method for (${gpr}) or 0(${gpr}), where the 0 is be silently ignored.
+// Used for GNU as Compatibility.
+def AtomicMemOpOperand : AsmOperandClass {
+  let Name = "AtomicMemOpOperand";
+  let RenderMethod = "addRegOperands";
+  let PredicateMethod = "isReg";
+  let ParserMethod = "parseAtomicMemOp";
+}
+
+def GPRMemAtomic : RegisterOperand<GPR> {
+  let ParserMatchClass = AtomicMemOpOperand;
+  let PrintMethod = "printAtomicMemOp";
+}
+
+//===----------------------------------------------------------------------===//
 // Instruction class templates
 //===----------------------------------------------------------------------===//
 
 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
 class LR_r<bit aq, bit rl, bits<3> funct3, string opcodestr>
     : RVInstRAtomic<0b00010, aq, rl, funct3, OPC_AMO,
-                    (outs GPR:$rd), (ins GPR:$rs1),
-                    opcodestr, "$rd, (${rs1})"> {
+                    (outs GPR:$rd), (ins GPRMemAtomic:$rs1),
+                    opcodestr, "$rd, $rs1"> {
   let rs2 = 0;
 }
 
@@ -33,8 +51,8 @@ multiclass LR_r_aq_rl<bits<3> funct3, string opcodestr
 let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in
 class AMO_rr<bits<5> funct5, bit aq, bit rl, bits<3> funct3, string opcodestr>
     : RVInstRAtomic<funct5, aq, rl, funct3, OPC_AMO,
-                    (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2),
-                    opcodestr, "$rd, $rs2, (${rs1})">;
+                    (outs GPR:$rd), (ins GPRMemAtomic:$rs1, GPR:$rs2),
+                    opcodestr, "$rd, $rs2, $rs1">;
 
 multiclass AMO_rr_aq_rl<bits<5> funct5, bits<3> funct3, string opcodestr> {
   def ""     : AMO_rr<funct5, 0, 0, funct3, opcodestr>;

Modified: head/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
==============================================================================
--- head/contrib/llvm/tools/clang/lib/Basic/Targets.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/tools/clang/lib/Basic/Targets.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -363,15 +363,26 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
     return new AMDGPUTargetInfo(Triple, Opts);
 
   case llvm::Triple::riscv32:
-    // TODO: add cases for FreeBSD, NetBSD, RTEMS once tested.
-    if (os == llvm::Triple::Linux)
+    // TODO: add cases for NetBSD, RTEMS once tested.
+    switch (os) {
+    case llvm::Triple::FreeBSD:
+      return new FreeBSDTargetInfo<RISCV32TargetInfo>(Triple, Opts);
+    case llvm::Triple::Linux:
       return new LinuxTargetInfo<RISCV32TargetInfo>(Triple, Opts);
-    return new RISCV32TargetInfo(Triple, Opts);
+    default:
+      return new RISCV32TargetInfo(Triple, Opts);
+    }
+
   case llvm::Triple::riscv64:
-    // TODO: add cases for FreeBSD, NetBSD, RTEMS once tested.
-    if (os == llvm::Triple::Linux)
+    // TODO: add cases for NetBSD, RTEMS once tested.
+    switch (os) {
+    case llvm::Triple::FreeBSD:
+      return new FreeBSDTargetInfo<RISCV64TargetInfo>(Triple, Opts);
+    case llvm::Triple::Linux:
       return new LinuxTargetInfo<RISCV64TargetInfo>(Triple, Opts);
-    return new RISCV64TargetInfo(Triple, Opts);
+    default:
+      return new RISCV64TargetInfo(Triple, Opts);
+    }
 
   case llvm::Triple::sparc:
     switch (os) {

Modified: head/contrib/llvm/tools/clang/lib/Driver/ToolChains/FreeBSD.cpp
==============================================================================
--- head/contrib/llvm/tools/clang/lib/Driver/ToolChains/FreeBSD.cpp	Thu Nov  7 19:37:26 2019	(r354468)
+++ head/contrib/llvm/tools/clang/lib/Driver/ToolChains/FreeBSD.cpp	Thu Nov  7 19:54:08 2019	(r354469)
@@ -197,6 +197,14 @@ void freebsd::Linker::ConstructJob(Compilation &C, con
     else
       CmdArgs.push_back("elf64ltsmip_fbsd");
     break;
+  case llvm::Triple::riscv32:
+    CmdArgs.push_back("-m");
+    CmdArgs.push_back("elf32lriscv");
+    break;
+  case llvm::Triple::riscv64:
+    CmdArgs.push_back("-m");
+    CmdArgs.push_back("elf64lriscv");
+    break;
   default:
     break;
   }


More information about the svn-src-all mailing list