-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[AVR] Backport #118015 and #121498 #125081
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-mc @llvm/pr-subscribers-backend-arm Author: Patryk Wychowaniec (Patryk27) ChangesThis pull request backports #118015 and #121498 to 19.x, so that the fixes can be pulled to rustc. Not sure if backports warrant an extra review - especially since there were no major changes in here, just a small conflict somewhere in AVRAsmBackend.cpp IIRC - but just in case: cc @benshi001. Patch is 359.05 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/125081.diff 26 Files Affected:
diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index 3f88ac02cd92ac..74ce676170d93c 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -94,6 +94,7 @@ class MCAsmBackend {
virtual bool shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
+ const uint64_t Value,
const MCSubtargetInfo *STI) {
return false;
}
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index c3da4bb5cc363c..c0465ab3c992ca 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -231,7 +231,7 @@ bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
// Let the backend force a relocation if needed.
if (IsResolved &&
- getBackend().shouldForceRelocation(*this, Fixup, Target, STI)) {
+ getBackend().shouldForceRelocation(*this, Fixup, Target, Value, STI)) {
IsResolved = false;
WasForced = true;
}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
index be34a649e1c4bf..196bfbdfe5cb09 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
@@ -100,7 +100,7 @@ class AArch64AsmBackend : public MCAsmBackend {
unsigned getFixupKindContainereSizeInBytes(unsigned Kind) const;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;
};
@@ -512,6 +512,7 @@ bool AArch64AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
+ const uint64_t,
const MCSubtargetInfo *STI) {
unsigned Kind = Fixup.getKind();
if (Kind >= FirstLiteralRelocationKind)
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
index c2d2ca0f90f930..2908107d9bb801 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
@@ -53,7 +53,7 @@ class AMDGPUAsmBackend : public MCAsmBackend {
std::optional<MCFixupKind> getFixupKind(StringRef Name) const override;
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, uint64_t Value,
const MCSubtargetInfo *STI) override;
};
@@ -191,7 +191,7 @@ const MCFixupKindInfo &AMDGPUAsmBackend::getFixupKindInfo(
bool AMDGPUAsmBackend::shouldForceRelocation(const MCAssembler &,
const MCFixup &Fixup,
- const MCValue &,
+ const MCValue &, const uint64_t,
const MCSubtargetInfo *STI) {
return Fixup.getKind() >= FirstLiteralRelocationKind;
}
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 994b43f1abb49a..562c20ac6f0a26 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -909,7 +909,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
bool ARMAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, const uint64_t,
const MCSubtargetInfo *STI) {
const MCSymbolRefExpr *A = Target.getSymA();
const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
index f33cd8b7c2425a..2932e68cd98e56 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
@@ -36,7 +36,7 @@ class ARMAsmBackend : public MCAsmBackend {
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;
unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup,
diff --git a/llvm/lib/Target/AVR/AVRDevices.td b/llvm/lib/Target/AVR/AVRDevices.td
index 5eca92ab4b6c58..56147bb473bc4b 100644
--- a/llvm/lib/Target/AVR/AVRDevices.td
+++ b/llvm/lib/Target/AVR/AVRDevices.td
@@ -60,6 +60,18 @@ def FeatureSmallStack
"The device has an 8-bit "
"stack pointer">;
+// The device potentially requires emitting rjmp that wraps across the flash
+// boundary.
+//
+// We enable this for devices that have exactly 8 kB of flash memory and don't
+// support the `jmp` instruction - with this feature enabled, we try to convert
+// out-of-bounds relative jumps into in-bounds by wrapping the offset, e.g.
+// `rjmp +5000` becomes `rjmp -3192`.
+def FeatureWrappingRjmp
+ : SubtargetFeature<"wrappingrjmp", "HasWrappingRjmp", "true",
+ "The device potentially requires emitting rjmp that "
+ "wraps across the flash boundary">;
+
// The device supports the 16-bit GPR pair MOVW instruction.
def FeatureMOVW : SubtargetFeature<"movw", "HasMOVW", "true",
"The device supports the 16-bit MOVW "
@@ -274,11 +286,11 @@ def : Device<"at86rf401", FamilyAVR2, ELFArchAVR25, [FeatureMOVW, FeatureLPMX]>;
def : Device<"at90s4414", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>;
def : Device<"at90s4433", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>;
def : Device<"at90s4434", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>;
-def : Device<"at90s8515", FamilyAVR2, ELFArchAVR2>;
-def : Device<"at90c8534", FamilyAVR2, ELFArchAVR2>;
-def : Device<"at90s8535", FamilyAVR2, ELFArchAVR2>;
-def : Device<"ata5272", FamilyAVR25, ELFArchAVR25>;
-def : Device<"ata6616c", FamilyAVR25, ELFArchAVR25>;
+def : Device<"at90s8515", FamilyAVR2, ELFArchAVR2, [FeatureWrappingRjmp]>;
+def : Device<"at90c8534", FamilyAVR2, ELFArchAVR2, [FeatureWrappingRjmp]>;
+def : Device<"at90s8535", FamilyAVR2, ELFArchAVR2, [FeatureWrappingRjmp]>;
+def : Device<"ata5272", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"ata6616c", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"attiny13", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny13a", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny2313", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
@@ -288,24 +300,24 @@ def : Device<"attiny24a", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny4313", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny44", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny44a", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny84", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny84a", FamilyAVR25, ELFArchAVR25>;
+def : Device<"attiny84", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny84a", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"attiny25", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny45", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny85", FamilyAVR25, ELFArchAVR25>;
+def : Device<"attiny85", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"attiny261", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny261a", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny441", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny461", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny461a", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny841", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny861", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny861a", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny87", FamilyAVR25, ELFArchAVR25>;
+def : Device<"attiny841", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny861", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny861a", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny87", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"attiny43u", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny48", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny88", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny828", FamilyAVR25, ELFArchAVR25>;
+def : Device<"attiny88", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny828", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"at43usb355", FamilyAVR3, ELFArchAVR3>;
def : Device<"at76c711", FamilyAVR3, ELFArchAVR3>;
def : Device<"atmega103", FamilyAVR31, ELFArchAVR31>;
@@ -321,11 +333,11 @@ def : Device<"atmega16u2", FamilyAVR35, ELFArchAVR35>;
def : Device<"atmega32u2", FamilyAVR35, ELFArchAVR35>;
def : Device<"attiny1634", FamilyAVR35, ELFArchAVR35>;
def : Device<"atmega8", FamilyAVR2, ELFArchAVR4,
- [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
+ [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, FeatureWrappingRjmp]>;
def : Device<"ata6289", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega8a", FamilyAVR2, ELFArchAVR4,
- [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
-def : Device<"ata6285", FamilyAVR4, ELFArchAVR4>;
+ [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, FeatureWrappingRjmp]>;
+def : Device<"ata6285", FamilyAVR4, ELFArchAVR4, [FeatureWrappingRjmp]>;
def : Device<"ata6286", FamilyAVR4, ELFArchAVR4>;
def : Device<"ata6612c", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega48", FamilyAVR4, ELFArchAVR4>;
@@ -339,9 +351,9 @@ def : Device<"atmega88p", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega88pa", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega88pb", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega8515", FamilyAVR2, ELFArchAVR4,
- [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
+ [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, FeatureWrappingRjmp]>;
def : Device<"atmega8535", FamilyAVR2, ELFArchAVR4,
- [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
+ [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, FeatureWrappingRjmp]>;
def : Device<"atmega8hva", FamilyAVR4, ELFArchAVR4>;
def : Device<"at90pwm1", FamilyAVR4, ELFArchAVR4>;
def : Device<"at90pwm2", FamilyAVR4, ELFArchAVR4>;
diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
index c0bc1276967bf0..80c53c74ec6fd2 100644
--- a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
+++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
@@ -28,36 +28,13 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-// FIXME: we should be doing checks to make sure asm operands
-// are not out of bounds.
-
namespace adjust {
using namespace llvm;
-static void signed_width(unsigned Width, uint64_t Value,
- std::string Description, const MCFixup &Fixup,
- MCContext *Ctx = nullptr) {
- if (!isIntN(Width, Value)) {
- std::string Diagnostic = "out of range " + Description;
-
- int64_t Min = minIntN(Width);
- int64_t Max = maxIntN(Width);
-
- Diagnostic += " (expected an integer in the range " + std::to_string(Min) +
- " to " + std::to_string(Max) + ")";
-
- if (Ctx) {
- Ctx->reportError(Fixup.getLoc(), Diagnostic);
- } else {
- llvm_unreachable(Diagnostic.c_str());
- }
- }
-}
-
static void unsigned_width(unsigned Width, uint64_t Value,
std::string Description, const MCFixup &Fixup,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
if (!isUIntN(Width, Value)) {
std::string Diagnostic = "out of range " + Description;
@@ -66,17 +43,13 @@ static void unsigned_width(unsigned Width, uint64_t Value,
Diagnostic +=
" (expected an integer in the range 0 to " + std::to_string(Max) + ")";
- if (Ctx) {
- Ctx->reportError(Fixup.getLoc(), Diagnostic);
- } else {
- llvm_unreachable(Diagnostic.c_str());
- }
+ Ctx->reportError(Fixup.getLoc(), Diagnostic);
}
}
/// Adjusts the value of a branch target before fixup application.
static void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
// We have one extra bit of precision because the value is rightshifted by
// one.
unsigned_width(Size + 1, Value, std::string("branch target"), Fixup, Ctx);
@@ -86,17 +59,37 @@ static void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
}
/// Adjusts the value of a relative branch target before fixup application.
-static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
- uint64_t &Value, MCContext *Ctx = nullptr) {
+static bool adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
+ uint64_t &Value, const MCSubtargetInfo *STI) {
// Jumps are relative to the current instruction.
Value -= 2;
// We have one extra bit of precision because the value is rightshifted by
// one.
- signed_width(Size + 1, Value, std::string("branch target"), Fixup, Ctx);
+ Size += 1;
+
+ assert(STI && "STI can not be NULL");
+
+ if (!isIntN(Size, Value) && STI->hasFeature(AVR::FeatureWrappingRjmp)) {
+ const int32_t FlashSize = 0x2000;
+ int32_t SignedValue = Value;
+
+ uint64_t WrappedValue = SignedValue > 0 ? (uint64_t)(Value - FlashSize)
+ : (uint64_t)(FlashSize + Value);
+
+ if (isIntN(Size, WrappedValue)) {
+ Value = WrappedValue;
+ }
+ }
+
+ if (!isIntN(Size, Value)) {
+ return false;
+ }
// Rightshifts the value by one.
AVR::fixups::adjustBranchTarget(Value);
+
+ return true;
}
/// 22-bit absolute fixup.
@@ -106,7 +99,7 @@ static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
///
/// Offset of 0 (so the result is left shifted by 3 bits before application).
static void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
adjustBranch(Size, Fixup, Value, Ctx);
auto top = Value & (0xf00000 << 6); // the top four bits
@@ -122,8 +115,10 @@ static void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
/// 0000 00kk kkkk k000
/// Offset of 0 (so the result is left shifted by 3 bits before application).
static void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
- adjustRelativeBranch(Size, Fixup, Value, Ctx);
+ MCContext *Ctx) {
+ if (!adjustRelativeBranch(Size, Fixup, Value, Ctx->getSubtargetInfo())) {
+ llvm_unreachable("should've been emitted as a relocation");
+ }
// Because the value may be negative, we must mask out the sign bits
Value &= 0x7f;
@@ -136,8 +131,10 @@ static void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
/// 0000 kkkk kkkk kkkk
/// Offset of 0 (so the result isn't left-shifted before application).
static void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
- adjustRelativeBranch(Size, Fixup, Value, Ctx);
+ MCContext *Ctx) {
+ if (!adjustRelativeBranch(Size, Fixup, Value, Ctx->getSubtargetInfo())) {
+ llvm_unreachable("should've been emitted as a relocation");
+ }
// Because the value may be negative, we must mask out the sign bits
Value &= 0xfff;
@@ -148,8 +145,7 @@ static void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
///
/// Resolves to:
/// 10q0 qq10 0000 1qqq
-static void fixup_6(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+static void fixup_6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
Value = ((Value & 0x20) << 8) | ((Value & 0x18) << 7) | (Value & 0x07);
@@ -161,7 +157,7 @@ static void fixup_6(const MCFixup &Fixup, uint64_t &Value,
/// Resolves to:
/// 0000 0000 kk00 kkkk
static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
Value = ((Value & 0x30) << 2) | (Value & 0x0f);
@@ -171,8 +167,7 @@ static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
///
/// Resolves to:
/// 0000 0000 AAAA A000
-static void fixup_port5(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+static void fixup_port5(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
unsigned_width(5, Value, std::string("port number"), Fixup, Ctx);
Value &= 0x1f;
@@ -180,12 +175,11 @@ static void fixup_port5(const MCFixup &Fixup, uint64_t &Value,
Value <<= 3;
}
-/// 6-bit port number fixup on the `IN` family of instructions.
+/// 6-bit port number fixup on the IN family of instructions.
///
/// Resolves to:
/// 1011 0AAd dddd AAAA
-static void fixup_port6(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+static void fixup_port6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
unsigned_width(6, Value, std::string("port number"), Fixup, Ctx);
Value = ((Value & 0x30) << 5) | (Value & 0x0f);
@@ -196,7 +190,7 @@ static void fixup_port6(const MCFixup &Fixup, uint64_t &Value,
/// Resolves to:
/// 1010 ikkk dddd kkkk
static void fixup_lds_sts_16(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
unsigned_width(7, Value, std::string("immediate"), Fixup, Ctx);
Value = ((Value & 0x70) << 8) | (Value & 0x0f);
}
@@ -214,7 +208,7 @@ namespace ldi {
/// 0000 KKKK 0000 KKKK
/// Offset of 0 (so the result isn't left-shifted before application).
static void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
uint64_t upper = Value & 0xf0;
uint64_t lower = Value & 0x0f;
@@ -224,25 +218,25 @@ static void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
static void neg(uint64_t &Value) { Value *= -1; }
static void lo8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
Value &= 0xff;
ldi::fixup(Size, Fixup, Value, Ctx);
}
static void hi8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
Value = (Value & 0xff00) >> 8;
ldi::fixup(Size, Fixup, Value, Ctx);
}
static void hh8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
Value = (Value & 0xff0000) >> 16;
ldi::fixup(Size, Fixup, Value, Ctx);
}
static...
[truncated]
|
@llvm/pr-subscribers-backend-powerpc Author: Patryk Wychowaniec (Patryk27) ChangesThis pull request backports #118015 and #121498 to 19.x, so that the fixes can be pulled to rustc. Not sure if backports warrant an extra review - especially since there were no major changes in here, just a small conflict somewhere in AVRAsmBackend.cpp IIRC - but just in case: cc @benshi001. Patch is 359.05 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/125081.diff 26 Files Affected:
diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index 3f88ac02cd92ac..74ce676170d93c 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -94,6 +94,7 @@ class MCAsmBackend {
virtual bool shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
+ const uint64_t Value,
const MCSubtargetInfo *STI) {
return false;
}
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index c3da4bb5cc363c..c0465ab3c992ca 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -231,7 +231,7 @@ bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
// Let the backend force a relocation if needed.
if (IsResolved &&
- getBackend().shouldForceRelocation(*this, Fixup, Target, STI)) {
+ getBackend().shouldForceRelocation(*this, Fixup, Target, Value, STI)) {
IsResolved = false;
WasForced = true;
}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
index be34a649e1c4bf..196bfbdfe5cb09 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
@@ -100,7 +100,7 @@ class AArch64AsmBackend : public MCAsmBackend {
unsigned getFixupKindContainereSizeInBytes(unsigned Kind) const;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;
};
@@ -512,6 +512,7 @@ bool AArch64AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
+ const uint64_t,
const MCSubtargetInfo *STI) {
unsigned Kind = Fixup.getKind();
if (Kind >= FirstLiteralRelocationKind)
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
index c2d2ca0f90f930..2908107d9bb801 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
@@ -53,7 +53,7 @@ class AMDGPUAsmBackend : public MCAsmBackend {
std::optional<MCFixupKind> getFixupKind(StringRef Name) const override;
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, uint64_t Value,
const MCSubtargetInfo *STI) override;
};
@@ -191,7 +191,7 @@ const MCFixupKindInfo &AMDGPUAsmBackend::getFixupKindInfo(
bool AMDGPUAsmBackend::shouldForceRelocation(const MCAssembler &,
const MCFixup &Fixup,
- const MCValue &,
+ const MCValue &, const uint64_t,
const MCSubtargetInfo *STI) {
return Fixup.getKind() >= FirstLiteralRelocationKind;
}
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 994b43f1abb49a..562c20ac6f0a26 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -909,7 +909,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
bool ARMAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, const uint64_t,
const MCSubtargetInfo *STI) {
const MCSymbolRefExpr *A = Target.getSymA();
const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
index f33cd8b7c2425a..2932e68cd98e56 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
@@ -36,7 +36,7 @@ class ARMAsmBackend : public MCAsmBackend {
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;
unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup,
diff --git a/llvm/lib/Target/AVR/AVRDevices.td b/llvm/lib/Target/AVR/AVRDevices.td
index 5eca92ab4b6c58..56147bb473bc4b 100644
--- a/llvm/lib/Target/AVR/AVRDevices.td
+++ b/llvm/lib/Target/AVR/AVRDevices.td
@@ -60,6 +60,18 @@ def FeatureSmallStack
"The device has an 8-bit "
"stack pointer">;
+// The device potentially requires emitting rjmp that wraps across the flash
+// boundary.
+//
+// We enable this for devices that have exactly 8 kB of flash memory and don't
+// support the `jmp` instruction - with this feature enabled, we try to convert
+// out-of-bounds relative jumps into in-bounds by wrapping the offset, e.g.
+// `rjmp +5000` becomes `rjmp -3192`.
+def FeatureWrappingRjmp
+ : SubtargetFeature<"wrappingrjmp", "HasWrappingRjmp", "true",
+ "The device potentially requires emitting rjmp that "
+ "wraps across the flash boundary">;
+
// The device supports the 16-bit GPR pair MOVW instruction.
def FeatureMOVW : SubtargetFeature<"movw", "HasMOVW", "true",
"The device supports the 16-bit MOVW "
@@ -274,11 +286,11 @@ def : Device<"at86rf401", FamilyAVR2, ELFArchAVR25, [FeatureMOVW, FeatureLPMX]>;
def : Device<"at90s4414", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>;
def : Device<"at90s4433", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>;
def : Device<"at90s4434", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>;
-def : Device<"at90s8515", FamilyAVR2, ELFArchAVR2>;
-def : Device<"at90c8534", FamilyAVR2, ELFArchAVR2>;
-def : Device<"at90s8535", FamilyAVR2, ELFArchAVR2>;
-def : Device<"ata5272", FamilyAVR25, ELFArchAVR25>;
-def : Device<"ata6616c", FamilyAVR25, ELFArchAVR25>;
+def : Device<"at90s8515", FamilyAVR2, ELFArchAVR2, [FeatureWrappingRjmp]>;
+def : Device<"at90c8534", FamilyAVR2, ELFArchAVR2, [FeatureWrappingRjmp]>;
+def : Device<"at90s8535", FamilyAVR2, ELFArchAVR2, [FeatureWrappingRjmp]>;
+def : Device<"ata5272", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"ata6616c", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"attiny13", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny13a", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny2313", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
@@ -288,24 +300,24 @@ def : Device<"attiny24a", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny4313", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny44", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny44a", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny84", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny84a", FamilyAVR25, ELFArchAVR25>;
+def : Device<"attiny84", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny84a", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"attiny25", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny45", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny85", FamilyAVR25, ELFArchAVR25>;
+def : Device<"attiny85", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"attiny261", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny261a", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny441", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny461", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny461a", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny841", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny861", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny861a", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny87", FamilyAVR25, ELFArchAVR25>;
+def : Device<"attiny841", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny861", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny861a", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny87", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"attiny43u", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny48", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny88", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny828", FamilyAVR25, ELFArchAVR25>;
+def : Device<"attiny88", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny828", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"at43usb355", FamilyAVR3, ELFArchAVR3>;
def : Device<"at76c711", FamilyAVR3, ELFArchAVR3>;
def : Device<"atmega103", FamilyAVR31, ELFArchAVR31>;
@@ -321,11 +333,11 @@ def : Device<"atmega16u2", FamilyAVR35, ELFArchAVR35>;
def : Device<"atmega32u2", FamilyAVR35, ELFArchAVR35>;
def : Device<"attiny1634", FamilyAVR35, ELFArchAVR35>;
def : Device<"atmega8", FamilyAVR2, ELFArchAVR4,
- [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
+ [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, FeatureWrappingRjmp]>;
def : Device<"ata6289", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega8a", FamilyAVR2, ELFArchAVR4,
- [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
-def : Device<"ata6285", FamilyAVR4, ELFArchAVR4>;
+ [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, FeatureWrappingRjmp]>;
+def : Device<"ata6285", FamilyAVR4, ELFArchAVR4, [FeatureWrappingRjmp]>;
def : Device<"ata6286", FamilyAVR4, ELFArchAVR4>;
def : Device<"ata6612c", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega48", FamilyAVR4, ELFArchAVR4>;
@@ -339,9 +351,9 @@ def : Device<"atmega88p", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega88pa", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega88pb", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega8515", FamilyAVR2, ELFArchAVR4,
- [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
+ [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, FeatureWrappingRjmp]>;
def : Device<"atmega8535", FamilyAVR2, ELFArchAVR4,
- [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
+ [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, FeatureWrappingRjmp]>;
def : Device<"atmega8hva", FamilyAVR4, ELFArchAVR4>;
def : Device<"at90pwm1", FamilyAVR4, ELFArchAVR4>;
def : Device<"at90pwm2", FamilyAVR4, ELFArchAVR4>;
diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
index c0bc1276967bf0..80c53c74ec6fd2 100644
--- a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
+++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
@@ -28,36 +28,13 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-// FIXME: we should be doing checks to make sure asm operands
-// are not out of bounds.
-
namespace adjust {
using namespace llvm;
-static void signed_width(unsigned Width, uint64_t Value,
- std::string Description, const MCFixup &Fixup,
- MCContext *Ctx = nullptr) {
- if (!isIntN(Width, Value)) {
- std::string Diagnostic = "out of range " + Description;
-
- int64_t Min = minIntN(Width);
- int64_t Max = maxIntN(Width);
-
- Diagnostic += " (expected an integer in the range " + std::to_string(Min) +
- " to " + std::to_string(Max) + ")";
-
- if (Ctx) {
- Ctx->reportError(Fixup.getLoc(), Diagnostic);
- } else {
- llvm_unreachable(Diagnostic.c_str());
- }
- }
-}
-
static void unsigned_width(unsigned Width, uint64_t Value,
std::string Description, const MCFixup &Fixup,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
if (!isUIntN(Width, Value)) {
std::string Diagnostic = "out of range " + Description;
@@ -66,17 +43,13 @@ static void unsigned_width(unsigned Width, uint64_t Value,
Diagnostic +=
" (expected an integer in the range 0 to " + std::to_string(Max) + ")";
- if (Ctx) {
- Ctx->reportError(Fixup.getLoc(), Diagnostic);
- } else {
- llvm_unreachable(Diagnostic.c_str());
- }
+ Ctx->reportError(Fixup.getLoc(), Diagnostic);
}
}
/// Adjusts the value of a branch target before fixup application.
static void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
// We have one extra bit of precision because the value is rightshifted by
// one.
unsigned_width(Size + 1, Value, std::string("branch target"), Fixup, Ctx);
@@ -86,17 +59,37 @@ static void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
}
/// Adjusts the value of a relative branch target before fixup application.
-static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
- uint64_t &Value, MCContext *Ctx = nullptr) {
+static bool adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
+ uint64_t &Value, const MCSubtargetInfo *STI) {
// Jumps are relative to the current instruction.
Value -= 2;
// We have one extra bit of precision because the value is rightshifted by
// one.
- signed_width(Size + 1, Value, std::string("branch target"), Fixup, Ctx);
+ Size += 1;
+
+ assert(STI && "STI can not be NULL");
+
+ if (!isIntN(Size, Value) && STI->hasFeature(AVR::FeatureWrappingRjmp)) {
+ const int32_t FlashSize = 0x2000;
+ int32_t SignedValue = Value;
+
+ uint64_t WrappedValue = SignedValue > 0 ? (uint64_t)(Value - FlashSize)
+ : (uint64_t)(FlashSize + Value);
+
+ if (isIntN(Size, WrappedValue)) {
+ Value = WrappedValue;
+ }
+ }
+
+ if (!isIntN(Size, Value)) {
+ return false;
+ }
// Rightshifts the value by one.
AVR::fixups::adjustBranchTarget(Value);
+
+ return true;
}
/// 22-bit absolute fixup.
@@ -106,7 +99,7 @@ static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
///
/// Offset of 0 (so the result is left shifted by 3 bits before application).
static void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
adjustBranch(Size, Fixup, Value, Ctx);
auto top = Value & (0xf00000 << 6); // the top four bits
@@ -122,8 +115,10 @@ static void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
/// 0000 00kk kkkk k000
/// Offset of 0 (so the result is left shifted by 3 bits before application).
static void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
- adjustRelativeBranch(Size, Fixup, Value, Ctx);
+ MCContext *Ctx) {
+ if (!adjustRelativeBranch(Size, Fixup, Value, Ctx->getSubtargetInfo())) {
+ llvm_unreachable("should've been emitted as a relocation");
+ }
// Because the value may be negative, we must mask out the sign bits
Value &= 0x7f;
@@ -136,8 +131,10 @@ static void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
/// 0000 kkkk kkkk kkkk
/// Offset of 0 (so the result isn't left-shifted before application).
static void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
- adjustRelativeBranch(Size, Fixup, Value, Ctx);
+ MCContext *Ctx) {
+ if (!adjustRelativeBranch(Size, Fixup, Value, Ctx->getSubtargetInfo())) {
+ llvm_unreachable("should've been emitted as a relocation");
+ }
// Because the value may be negative, we must mask out the sign bits
Value &= 0xfff;
@@ -148,8 +145,7 @@ static void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
///
/// Resolves to:
/// 10q0 qq10 0000 1qqq
-static void fixup_6(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+static void fixup_6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
Value = ((Value & 0x20) << 8) | ((Value & 0x18) << 7) | (Value & 0x07);
@@ -161,7 +157,7 @@ static void fixup_6(const MCFixup &Fixup, uint64_t &Value,
/// Resolves to:
/// 0000 0000 kk00 kkkk
static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
Value = ((Value & 0x30) << 2) | (Value & 0x0f);
@@ -171,8 +167,7 @@ static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
///
/// Resolves to:
/// 0000 0000 AAAA A000
-static void fixup_port5(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+static void fixup_port5(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
unsigned_width(5, Value, std::string("port number"), Fixup, Ctx);
Value &= 0x1f;
@@ -180,12 +175,11 @@ static void fixup_port5(const MCFixup &Fixup, uint64_t &Value,
Value <<= 3;
}
-/// 6-bit port number fixup on the `IN` family of instructions.
+/// 6-bit port number fixup on the IN family of instructions.
///
/// Resolves to:
/// 1011 0AAd dddd AAAA
-static void fixup_port6(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+static void fixup_port6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
unsigned_width(6, Value, std::string("port number"), Fixup, Ctx);
Value = ((Value & 0x30) << 5) | (Value & 0x0f);
@@ -196,7 +190,7 @@ static void fixup_port6(const MCFixup &Fixup, uint64_t &Value,
/// Resolves to:
/// 1010 ikkk dddd kkkk
static void fixup_lds_sts_16(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
unsigned_width(7, Value, std::string("immediate"), Fixup, Ctx);
Value = ((Value & 0x70) << 8) | (Value & 0x0f);
}
@@ -214,7 +208,7 @@ namespace ldi {
/// 0000 KKKK 0000 KKKK
/// Offset of 0 (so the result isn't left-shifted before application).
static void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
uint64_t upper = Value & 0xf0;
uint64_t lower = Value & 0x0f;
@@ -224,25 +218,25 @@ static void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
static void neg(uint64_t &Value) { Value *= -1; }
static void lo8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
Value &= 0xff;
ldi::fixup(Size, Fixup, Value, Ctx);
}
static void hi8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
Value = (Value & 0xff00) >> 8;
ldi::fixup(Size, Fixup, Value, Ctx);
}
static void hh8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
Value = (Value & 0xff0000) >> 16;
ldi::fixup(Size, Fixup, Value, Ctx);
}
static...
[truncated]
|
@llvm/pr-subscribers-backend-aarch64 Author: Patryk Wychowaniec (Patryk27) ChangesThis pull request backports #118015 and #121498 to 19.x, so that the fixes can be pulled to rustc. Not sure if backports warrant an extra review - especially since there were no major changes in here, just a small conflict somewhere in AVRAsmBackend.cpp IIRC - but just in case: cc @benshi001. Patch is 359.05 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/125081.diff 26 Files Affected:
diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index 3f88ac02cd92ac..74ce676170d93c 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -94,6 +94,7 @@ class MCAsmBackend {
virtual bool shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
+ const uint64_t Value,
const MCSubtargetInfo *STI) {
return false;
}
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index c3da4bb5cc363c..c0465ab3c992ca 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -231,7 +231,7 @@ bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
// Let the backend force a relocation if needed.
if (IsResolved &&
- getBackend().shouldForceRelocation(*this, Fixup, Target, STI)) {
+ getBackend().shouldForceRelocation(*this, Fixup, Target, Value, STI)) {
IsResolved = false;
WasForced = true;
}
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
index be34a649e1c4bf..196bfbdfe5cb09 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
@@ -100,7 +100,7 @@ class AArch64AsmBackend : public MCAsmBackend {
unsigned getFixupKindContainereSizeInBytes(unsigned Kind) const;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;
};
@@ -512,6 +512,7 @@ bool AArch64AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
+ const uint64_t,
const MCSubtargetInfo *STI) {
unsigned Kind = Fixup.getKind();
if (Kind >= FirstLiteralRelocationKind)
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
index c2d2ca0f90f930..2908107d9bb801 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp
@@ -53,7 +53,7 @@ class AMDGPUAsmBackend : public MCAsmBackend {
std::optional<MCFixupKind> getFixupKind(StringRef Name) const override;
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, uint64_t Value,
const MCSubtargetInfo *STI) override;
};
@@ -191,7 +191,7 @@ const MCFixupKindInfo &AMDGPUAsmBackend::getFixupKindInfo(
bool AMDGPUAsmBackend::shouldForceRelocation(const MCAssembler &,
const MCFixup &Fixup,
- const MCValue &,
+ const MCValue &, const uint64_t,
const MCSubtargetInfo *STI) {
return Fixup.getKind() >= FirstLiteralRelocationKind;
}
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 994b43f1abb49a..562c20ac6f0a26 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -909,7 +909,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
bool ARMAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, const uint64_t,
const MCSubtargetInfo *STI) {
const MCSymbolRefExpr *A = Target.getSymA();
const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
index f33cd8b7c2425a..2932e68cd98e56 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h
@@ -36,7 +36,7 @@ class ARMAsmBackend : public MCAsmBackend {
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
- const MCValue &Target,
+ const MCValue &Target, const uint64_t Value,
const MCSubtargetInfo *STI) override;
unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup,
diff --git a/llvm/lib/Target/AVR/AVRDevices.td b/llvm/lib/Target/AVR/AVRDevices.td
index 5eca92ab4b6c58..56147bb473bc4b 100644
--- a/llvm/lib/Target/AVR/AVRDevices.td
+++ b/llvm/lib/Target/AVR/AVRDevices.td
@@ -60,6 +60,18 @@ def FeatureSmallStack
"The device has an 8-bit "
"stack pointer">;
+// The device potentially requires emitting rjmp that wraps across the flash
+// boundary.
+//
+// We enable this for devices that have exactly 8 kB of flash memory and don't
+// support the `jmp` instruction - with this feature enabled, we try to convert
+// out-of-bounds relative jumps into in-bounds by wrapping the offset, e.g.
+// `rjmp +5000` becomes `rjmp -3192`.
+def FeatureWrappingRjmp
+ : SubtargetFeature<"wrappingrjmp", "HasWrappingRjmp", "true",
+ "The device potentially requires emitting rjmp that "
+ "wraps across the flash boundary">;
+
// The device supports the 16-bit GPR pair MOVW instruction.
def FeatureMOVW : SubtargetFeature<"movw", "HasMOVW", "true",
"The device supports the 16-bit MOVW "
@@ -274,11 +286,11 @@ def : Device<"at86rf401", FamilyAVR2, ELFArchAVR25, [FeatureMOVW, FeatureLPMX]>;
def : Device<"at90s4414", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>;
def : Device<"at90s4433", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>;
def : Device<"at90s4434", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>;
-def : Device<"at90s8515", FamilyAVR2, ELFArchAVR2>;
-def : Device<"at90c8534", FamilyAVR2, ELFArchAVR2>;
-def : Device<"at90s8535", FamilyAVR2, ELFArchAVR2>;
-def : Device<"ata5272", FamilyAVR25, ELFArchAVR25>;
-def : Device<"ata6616c", FamilyAVR25, ELFArchAVR25>;
+def : Device<"at90s8515", FamilyAVR2, ELFArchAVR2, [FeatureWrappingRjmp]>;
+def : Device<"at90c8534", FamilyAVR2, ELFArchAVR2, [FeatureWrappingRjmp]>;
+def : Device<"at90s8535", FamilyAVR2, ELFArchAVR2, [FeatureWrappingRjmp]>;
+def : Device<"ata5272", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"ata6616c", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"attiny13", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny13a", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny2313", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
@@ -288,24 +300,24 @@ def : Device<"attiny24a", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny4313", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny44", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny44a", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny84", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny84a", FamilyAVR25, ELFArchAVR25>;
+def : Device<"attiny84", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny84a", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"attiny25", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny45", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny85", FamilyAVR25, ELFArchAVR25>;
+def : Device<"attiny85", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"attiny261", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny261a", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>;
def : Device<"attiny441", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny461", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny461a", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny841", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny861", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny861a", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny87", FamilyAVR25, ELFArchAVR25>;
+def : Device<"attiny841", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny861", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny861a", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny87", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"attiny43u", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny48", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny88", FamilyAVR25, ELFArchAVR25>;
-def : Device<"attiny828", FamilyAVR25, ELFArchAVR25>;
+def : Device<"attiny88", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
+def : Device<"attiny828", FamilyAVR25, ELFArchAVR25, [FeatureWrappingRjmp]>;
def : Device<"at43usb355", FamilyAVR3, ELFArchAVR3>;
def : Device<"at76c711", FamilyAVR3, ELFArchAVR3>;
def : Device<"atmega103", FamilyAVR31, ELFArchAVR31>;
@@ -321,11 +333,11 @@ def : Device<"atmega16u2", FamilyAVR35, ELFArchAVR35>;
def : Device<"atmega32u2", FamilyAVR35, ELFArchAVR35>;
def : Device<"attiny1634", FamilyAVR35, ELFArchAVR35>;
def : Device<"atmega8", FamilyAVR2, ELFArchAVR4,
- [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
+ [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, FeatureWrappingRjmp]>;
def : Device<"ata6289", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega8a", FamilyAVR2, ELFArchAVR4,
- [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
-def : Device<"ata6285", FamilyAVR4, ELFArchAVR4>;
+ [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, FeatureWrappingRjmp]>;
+def : Device<"ata6285", FamilyAVR4, ELFArchAVR4, [FeatureWrappingRjmp]>;
def : Device<"ata6286", FamilyAVR4, ELFArchAVR4>;
def : Device<"ata6612c", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega48", FamilyAVR4, ELFArchAVR4>;
@@ -339,9 +351,9 @@ def : Device<"atmega88p", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega88pa", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega88pb", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega8515", FamilyAVR2, ELFArchAVR4,
- [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
+ [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, FeatureWrappingRjmp]>;
def : Device<"atmega8535", FamilyAVR2, ELFArchAVR4,
- [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
+ [FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, FeatureWrappingRjmp]>;
def : Device<"atmega8hva", FamilyAVR4, ELFArchAVR4>;
def : Device<"at90pwm1", FamilyAVR4, ELFArchAVR4>;
def : Device<"at90pwm2", FamilyAVR4, ELFArchAVR4>;
diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
index c0bc1276967bf0..80c53c74ec6fd2 100644
--- a/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
+++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
@@ -28,36 +28,13 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-// FIXME: we should be doing checks to make sure asm operands
-// are not out of bounds.
-
namespace adjust {
using namespace llvm;
-static void signed_width(unsigned Width, uint64_t Value,
- std::string Description, const MCFixup &Fixup,
- MCContext *Ctx = nullptr) {
- if (!isIntN(Width, Value)) {
- std::string Diagnostic = "out of range " + Description;
-
- int64_t Min = minIntN(Width);
- int64_t Max = maxIntN(Width);
-
- Diagnostic += " (expected an integer in the range " + std::to_string(Min) +
- " to " + std::to_string(Max) + ")";
-
- if (Ctx) {
- Ctx->reportError(Fixup.getLoc(), Diagnostic);
- } else {
- llvm_unreachable(Diagnostic.c_str());
- }
- }
-}
-
static void unsigned_width(unsigned Width, uint64_t Value,
std::string Description, const MCFixup &Fixup,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
if (!isUIntN(Width, Value)) {
std::string Diagnostic = "out of range " + Description;
@@ -66,17 +43,13 @@ static void unsigned_width(unsigned Width, uint64_t Value,
Diagnostic +=
" (expected an integer in the range 0 to " + std::to_string(Max) + ")";
- if (Ctx) {
- Ctx->reportError(Fixup.getLoc(), Diagnostic);
- } else {
- llvm_unreachable(Diagnostic.c_str());
- }
+ Ctx->reportError(Fixup.getLoc(), Diagnostic);
}
}
/// Adjusts the value of a branch target before fixup application.
static void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
// We have one extra bit of precision because the value is rightshifted by
// one.
unsigned_width(Size + 1, Value, std::string("branch target"), Fixup, Ctx);
@@ -86,17 +59,37 @@ static void adjustBranch(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
}
/// Adjusts the value of a relative branch target before fixup application.
-static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
- uint64_t &Value, MCContext *Ctx = nullptr) {
+static bool adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
+ uint64_t &Value, const MCSubtargetInfo *STI) {
// Jumps are relative to the current instruction.
Value -= 2;
// We have one extra bit of precision because the value is rightshifted by
// one.
- signed_width(Size + 1, Value, std::string("branch target"), Fixup, Ctx);
+ Size += 1;
+
+ assert(STI && "STI can not be NULL");
+
+ if (!isIntN(Size, Value) && STI->hasFeature(AVR::FeatureWrappingRjmp)) {
+ const int32_t FlashSize = 0x2000;
+ int32_t SignedValue = Value;
+
+ uint64_t WrappedValue = SignedValue > 0 ? (uint64_t)(Value - FlashSize)
+ : (uint64_t)(FlashSize + Value);
+
+ if (isIntN(Size, WrappedValue)) {
+ Value = WrappedValue;
+ }
+ }
+
+ if (!isIntN(Size, Value)) {
+ return false;
+ }
// Rightshifts the value by one.
AVR::fixups::adjustBranchTarget(Value);
+
+ return true;
}
/// 22-bit absolute fixup.
@@ -106,7 +99,7 @@ static void adjustRelativeBranch(unsigned Size, const MCFixup &Fixup,
///
/// Offset of 0 (so the result is left shifted by 3 bits before application).
static void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
adjustBranch(Size, Fixup, Value, Ctx);
auto top = Value & (0xf00000 << 6); // the top four bits
@@ -122,8 +115,10 @@ static void fixup_call(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
/// 0000 00kk kkkk k000
/// Offset of 0 (so the result is left shifted by 3 bits before application).
static void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
- adjustRelativeBranch(Size, Fixup, Value, Ctx);
+ MCContext *Ctx) {
+ if (!adjustRelativeBranch(Size, Fixup, Value, Ctx->getSubtargetInfo())) {
+ llvm_unreachable("should've been emitted as a relocation");
+ }
// Because the value may be negative, we must mask out the sign bits
Value &= 0x7f;
@@ -136,8 +131,10 @@ static void fixup_7_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
/// 0000 kkkk kkkk kkkk
/// Offset of 0 (so the result isn't left-shifted before application).
static void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
- adjustRelativeBranch(Size, Fixup, Value, Ctx);
+ MCContext *Ctx) {
+ if (!adjustRelativeBranch(Size, Fixup, Value, Ctx->getSubtargetInfo())) {
+ llvm_unreachable("should've been emitted as a relocation");
+ }
// Because the value may be negative, we must mask out the sign bits
Value &= 0xfff;
@@ -148,8 +145,7 @@ static void fixup_13_pcrel(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
///
/// Resolves to:
/// 10q0 qq10 0000 1qqq
-static void fixup_6(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+static void fixup_6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
Value = ((Value & 0x20) << 8) | ((Value & 0x18) << 7) | (Value & 0x07);
@@ -161,7 +157,7 @@ static void fixup_6(const MCFixup &Fixup, uint64_t &Value,
/// Resolves to:
/// 0000 0000 kk00 kkkk
static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
unsigned_width(6, Value, std::string("immediate"), Fixup, Ctx);
Value = ((Value & 0x30) << 2) | (Value & 0x0f);
@@ -171,8 +167,7 @@ static void fixup_6_adiw(const MCFixup &Fixup, uint64_t &Value,
///
/// Resolves to:
/// 0000 0000 AAAA A000
-static void fixup_port5(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+static void fixup_port5(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
unsigned_width(5, Value, std::string("port number"), Fixup, Ctx);
Value &= 0x1f;
@@ -180,12 +175,11 @@ static void fixup_port5(const MCFixup &Fixup, uint64_t &Value,
Value <<= 3;
}
-/// 6-bit port number fixup on the `IN` family of instructions.
+/// 6-bit port number fixup on the IN family of instructions.
///
/// Resolves to:
/// 1011 0AAd dddd AAAA
-static void fixup_port6(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+static void fixup_port6(const MCFixup &Fixup, uint64_t &Value, MCContext *Ctx) {
unsigned_width(6, Value, std::string("port number"), Fixup, Ctx);
Value = ((Value & 0x30) << 5) | (Value & 0x0f);
@@ -196,7 +190,7 @@ static void fixup_port6(const MCFixup &Fixup, uint64_t &Value,
/// Resolves to:
/// 1010 ikkk dddd kkkk
static void fixup_lds_sts_16(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
unsigned_width(7, Value, std::string("immediate"), Fixup, Ctx);
Value = ((Value & 0x70) << 8) | (Value & 0x0f);
}
@@ -214,7 +208,7 @@ namespace ldi {
/// 0000 KKKK 0000 KKKK
/// Offset of 0 (so the result isn't left-shifted before application).
static void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
uint64_t upper = Value & 0xf0;
uint64_t lower = Value & 0x0f;
@@ -224,25 +218,25 @@ static void fixup(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
static void neg(uint64_t &Value) { Value *= -1; }
static void lo8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
Value &= 0xff;
ldi::fixup(Size, Fixup, Value, Ctx);
}
static void hi8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
Value = (Value & 0xff00) >> 8;
ldi::fixup(Size, Fixup, Value, Ctx);
}
static void hh8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) {
+ MCContext *Ctx) {
Value = (Value & 0xff0000) >> 16;
ldi::fixup(Size, Fixup, Value, Ctx);
}
static...
[truncated]
|
FWIW, the issue this addresses is a hard blocker for building even basic AVR programs with Zig as well, so definitely +1 for a backport from our side. |
It's not possible to backport this in this form, because the changes to shouldForceRelocation are ABI-breaking.
The LLVM 20 upgrade in Rust is already in progress, so this is not necessary. |
Huh, interesting - out of curiosity, why do they break the ABI if those jumps are local to functions? |
Ah sorry, I meant that they break the ABI of libLLVM.so by adding an additional parameter to an exported function, not the ABI of the generated code. |
Ah, that tracks! Is there a timeline for getting rustc to LLVM 20? Also, @alexrp - is Zig planning on upgrading soon as well? If not, I can try to prepare a different backport, one that doesn't require modifying |
The situation on our end is that Zig 0.14.0 will release on February 17th with LLVM 19. (We're not planning on upgrading to 20 until 0.15.0.) So if an LLVM patch release can happen before the 17th, then a backport would definitely be appreciated, if possible. |
I see, I’ll do my best, then! Let’s keep this pull request open and I’ll report back. |
4a542f5
to
8b036c2
Compare
Alright, backported! I changed the logic from As for testing, I compiled rustc with these changes and ran https://github.com/Patryk27/avr-tester's testsuite - all's green. cc @benshi001 |
Not sure what's the next step (can't merge it myself here :-P) - cc @nikic? |
We've decided to wait for beta branch before merging the LLVM 20 upgrade, so the target is Feb 14.
As the LLVM 20 release cycle has started, there are no plans for further LLVM 19 releases. |
Ah, I see - so the only remaining option is for Zig to apply the patch on its own side, it seems. |
Closin', since there's nothing more to do on the LLVM's side here, considering the backport won't be merged. If someone downstream would like to apply this patch and has follow-up questions, feel free to reopen. |
This pull request backports #118015 and #121498 to 19.x, so that the fixes can be pulled to rustc.
Not sure if backports warrant an extra review - especially since there were no major changes in here, just a small conflict somewhere in AVRAsmBackend.cpp IIRC - but just in case: cc @benshi001.
Edit: I changed the approach, see #125081 (comment).