aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
}