aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-11-07 19:54:08 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-11-07 19:54:08 +0000
commit22a93864b8b71b79d5035e05d21e5cb617b14429 (patch)
tree2f2eab7c5c89efbe1755c4246428a3c58d38070f /contrib/llvm
parent4940bf264ab902d4b9115ceee1d19ec7cd8a8085 (diff)
downloadsrc-22a93864b8b71b79d5035e05d21e5cb617b14429.tar.gz
src-22a93864b8b71b79d5035e05d21e5cb617b14429.zip
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
Notes
Notes: svn path=/head/; revision=354469
Diffstat (limited to 'contrib/llvm')
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h2
-rw-r--r--contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h4
-rw-r--r--contrib/llvm/include/llvm/MC/MCDwarf.h3
-rw-r--r--contrib/llvm/include/llvm/MC/MCFixup.h97
-rw-r--r--contrib/llvm/include/llvm/MC/MCFragment.h16
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp26
-rw-r--r--contrib/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp20
-rw-r--r--contrib/llvm/lib/MC/MCAsmBackend.cpp5
-rw-r--r--contrib/llvm/lib/MC/MCAssembler.cpp35
-rw-r--r--contrib/llvm/lib/MC/MCDwarf.cpp40
-rw-r--r--contrib/llvm/lib/MC/MCExpr.cpp21
-rw-r--r--contrib/llvm/lib/Object/RelocationResolver.cpp6
-rw-r--r--contrib/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp77
-rw-r--r--contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp8
-rw-r--r--contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp9
-rw-r--r--contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp12
-rw-r--r--contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h2
-rw-r--r--contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp20
-rw-r--r--contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h3
-rw-r--r--contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp1
-rw-r--r--contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h1
-rw-r--r--contrib/llvm/lib/Target/RISCV/RISCVInstrInfoA.td26
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Targets.cpp23
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/ToolChains/FreeBSD.cpp8
24 files changed, 367 insertions, 98 deletions
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
index d960f4bc9b1c..afdbfbfe62f7 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
@@ -69,7 +69,7 @@ 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;
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h
index 1bba74a25d0e..68dbacfad9f2 100644
--- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h
+++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h
@@ -40,8 +40,8 @@ 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 ""; }
diff --git a/contrib/llvm/include/llvm/MC/MCDwarf.h b/contrib/llvm/include/llvm/MC/MCDwarf.h
index 1a37aafd0654..a33b4b31bb06 100644
--- a/contrib/llvm/include/llvm/MC/MCDwarf.h
+++ b/contrib/llvm/include/llvm/MC/MCDwarf.h
@@ -629,7 +629,8 @@ 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
diff --git a/contrib/llvm/include/llvm/MC/MCFixup.h b/contrib/llvm/include/llvm/MC/MCFixup.h
index accffb7f2247..c9be762d61d0 100644
--- a/contrib/llvm/include/llvm/MC/MCFixup.h
+++ b/contrib/llvm/include/llvm/MC/MCFixup.h
@@ -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,13 +132,37 @@ 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;
}
}
@@ -148,6 +175,7 @@ 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 @@ 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;
}
}
diff --git a/contrib/llvm/include/llvm/MC/MCFragment.h b/contrib/llvm/include/llvm/MC/MCFragment.h
index aadf2ce725ea..b0def566c46a 100644
--- a/contrib/llvm/include/llvm/MC/MCFragment.h
+++ b/contrib/llvm/include/llvm/MC/MCFragment.h
@@ -149,6 +149,7 @@ public:
case MCFragment::FT_CompactEncodedInst:
case MCFragment::FT_Data:
case MCFragment::FT_Dwarf:
+ case MCFragment::FT_DwarfFrame:
return true;
}
}
@@ -232,7 +233,8 @@ 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,27 +545,21 @@ public:
}
};
-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; }
-
/// @}
static bool classof(const MCFragment *F) {
diff --git a/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 5ede9bf59619..b7bb9c2347a1 100644
--- a/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -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 @@ public:
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; }
diff --git a/contrib/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/contrib/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index b3f23366f2a2..64336934d216 100644
--- a/contrib/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/contrib/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -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 *Offset,
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,
diff --git a/contrib/llvm/lib/MC/MCAsmBackend.cpp b/contrib/llvm/lib/MC/MCAsmBackend.cpp
index 9b1102cbe7d1..b800e9caee22 100644
--- a/contrib/llvm/lib/MC/MCAsmBackend.cpp
+++ b/contrib/llvm/lib/MC/MCAsmBackend.cpp
@@ -73,6 +73,7 @@ const MCFixupKindInfo &MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{"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(MCFixupKind Kind) const {
{"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];
diff --git a/contrib/llvm/lib/MC/MCAssembler.cpp b/contrib/llvm/lib/MC/MCAssembler.cpp
index c4f4d4c2870e..22a8e73e4af3 100644
--- a/contrib/llvm/lib/MC/MCAssembler.cpp
+++ b/contrib/llvm/lib/MC/MCAssembler.cpp
@@ -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 &Layout,
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 &Layout,
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(MCAsmLayout &Layout,
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();
}
diff --git a/contrib/llvm/lib/MC/MCDwarf.cpp b/contrib/llvm/lib/MC/MCDwarf.cpp
index aae6fdf90931..8456b3421bcd 100644
--- a/contrib/llvm/lib/MC/MCDwarf.cpp
+++ b/contrib/llvm/lib/MC/MCDwarf.cpp
@@ -1897,26 +1897,54 @@ void MCDwarfFrameEmitter::EmitAdvanceLoc(MCObjectStreamer &Streamer,
}
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);
}
}
diff --git a/contrib/llvm/lib/MC/MCExpr.cpp b/contrib/llvm/lib/MC/MCExpr.cpp
index ab53ed42778e..543b0661905c 100644
--- a/contrib/llvm/lib/MC/MCExpr.cpp
+++ b/contrib/llvm/lib/MC/MCExpr.cpp
@@ -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 MCAsmLayout *Layout,
// 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).
diff --git a/contrib/llvm/lib/Object/RelocationResolver.cpp b/contrib/llvm/lib/Object/RelocationResolver.cpp
index 41a0ac7fbd10..7df4f8d2b90f 100644
--- a/contrib/llvm/lib/Object/RelocationResolver.cpp
+++ b/contrib/llvm/lib/Object/RelocationResolver.cpp
@@ -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 S, uint64_t A) {
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:
diff --git a/contrib/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/contrib/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index f10f7a2b77d6..0df194d1e185 100644
--- a/contrib/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/contrib/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -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 @@ public:
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
@@ -1300,6 +1310,73 @@ RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
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;
+}
+
/// Looks at a token type and creates the relevant operand from this
/// information, adding to Operands. If operand was parsed, returns false, else
/// true.
diff --git a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index ee5f760ebcb0..61c5845cc175 100644
--- a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -33,6 +33,13 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
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, uint64_t Value,
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:
diff --git a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
index 3ccbc86d2619..169876eb7719 100644
--- a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
+++ b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
@@ -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 &Ctx,
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 &Ctx,
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 &Ctx,
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 &Ctx,
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:
diff --git a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index fe37b70811d8..d7452200e05f 100644
--- a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -112,3 +112,15 @@ void RISCVInstPrinter::printFRMArg(const MCInst *MI, unsigned OpNo,
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;
+}
diff --git a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
index 5ca1d3fa20fe..908b2de2ad3c 100644
--- a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
+++ b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
@@ -37,6 +37,8 @@ public:
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,
diff --git a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
index 983629692883..089a2def4c21 100644
--- a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
+++ b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.cpp
@@ -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() {}
@@ -25,3 +28,20 @@ RISCVMCAsmInfo::RISCVMCAsmInfo(const Triple &TT) {
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);
+}
diff --git a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h
index 043fdb7c08c0..6824baf699aa 100644
--- a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h
+++ b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCAsmInfo.h
@@ -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
diff --git a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index 0fc775f63ed4..6fd8552eeaaa 100644
--- a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -266,6 +266,7 @@ unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
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
diff --git a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
index b5a292dc1b1a..921df376f3df 100644
--- a/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
+++ b/contrib/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
@@ -36,6 +36,7 @@ public:
VK_RISCV_TLS_GD_HI,
VK_RISCV_CALL,
VK_RISCV_CALL_PLT,
+ VK_RISCV_32_PCREL,
VK_RISCV_Invalid
};
diff --git a/contrib/llvm/lib/Target/RISCV/RISCVInstrInfoA.td b/contrib/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
index b768c9347b38..1484ba9f0687 100644
--- a/contrib/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
+++ b/contrib/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
@@ -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>;
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
index a08e399e7270..63a64ed2931a 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
@@ -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) {
diff --git a/contrib/llvm/tools/clang/lib/Driver/ToolChains/FreeBSD.cpp b/contrib/llvm/tools/clang/lib/Driver/ToolChains/FreeBSD.cpp
index fb83dd54b74f..44b2230e43d4 100644
--- a/contrib/llvm/tools/clang/lib/Driver/ToolChains/FreeBSD.cpp
+++ b/contrib/llvm/tools/clang/lib/Driver/ToolChains/FreeBSD.cpp
@@ -197,6 +197,14 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
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;
}