[llvm] [M68k] implement -mxgot (PR #119803)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 17 10:29:03 PDT 2025
https://github.com/knickish updated https://github.com/llvm/llvm-project/pull/119803
>From 34dab26af80540ada11457e870ade40df765e1ba Mon Sep 17 00:00:00 2001
From: kirk <knickish at gmail.com>
Date: Wed, 11 Dec 2024 19:42:43 +0000
Subject: [PATCH] [M68k] implement -mxgot
---
llvm/lib/Target/M68k/M68k.td | 3 ++
llvm/lib/Target/M68k/M68kInstrInfo.cpp | 27 ++++++++++++--
llvm/lib/Target/M68k/M68kSubtarget.cpp | 10 +++--
llvm/lib/Target/M68k/M68kSubtarget.h | 4 ++
llvm/test/CodeGen/M68k/xgot.ll | 51 ++++++++++++++++++++++++++
5 files changed, 88 insertions(+), 7 deletions(-)
create mode 100644 llvm/test/CodeGen/M68k/xgot.ll
diff --git a/llvm/lib/Target/M68k/M68k.td b/llvm/lib/Target/M68k/M68k.td
index dab66d1022955..7fd48d6a7c46d 100644
--- a/llvm/lib/Target/M68k/M68k.td
+++ b/llvm/lib/Target/M68k/M68k.td
@@ -65,6 +65,9 @@ foreach i = {0-7} in
SubtargetFeature<"reserve-d"#i, "UserReservedRegister[M68k::D"#i#"]",
"true", "Reserve D"#i#" register">;
+def FeatureXGOT
+ : SubtargetFeature<"xgot", "UseXGOT", "true", "Assume 32-bit GOT">;
+
//===----------------------------------------------------------------------===//
// M68k processors supported.
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/M68k/M68kInstrInfo.cpp b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
index 21e9319aaf0b3..4f200d8d8bee3 100644
--- a/llvm/lib/Target/M68k/M68kInstrInfo.cpp
+++ b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
@@ -933,6 +933,7 @@ struct M68kGlobalBaseReg : public MachineFunctionPass {
bool runOnMachineFunction(MachineFunction &MF) override {
const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();
M68kMachineFunctionInfo *MxFI = MF.getInfo<M68kMachineFunctionInfo>();
+ MachineRegisterInfo &RegInfo = MF.getRegInfo();
unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();
@@ -946,9 +947,29 @@ struct M68kGlobalBaseReg : public MachineFunctionPass {
DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
const M68kInstrInfo *TII = STI.getInstrInfo();
- // Generate lea (__GLOBAL_OFFSET_TABLE_,%PC), %A5
- BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32q), GlobalBaseReg)
- .addExternalSymbol("_GLOBAL_OFFSET_TABLE_", M68kII::MO_GOTPCREL);
+ if (STI.useXGOT()) {
+ // Generate the following, as PC relative addressing is limited to i16
+ // offset
+ // lea (0,%PC), %A5
+ // lea _GLOBAL_OFFSET_TABLE_, %AX
+ // suba.l %AX, %A5
+ // where %AX can be any other assigned address register.
+ // This should allow programs in a >16bit PC state to still use GOTPCREL
+ // addressing.
+ Register LoadPC = RegInfo.createVirtualRegister(&M68k::AR32_NOSPRegClass);
+ Register LoadGOT =
+ RegInfo.createVirtualRegister(&M68k::AR32_NOSPRegClass);
+ BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32q), LoadPC).addImm(0);
+ BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32b), LoadGOT)
+ .addExternalSymbol("_GLOBAL_OFFSET_TABLE_");
+ BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::SUB32ar), GlobalBaseReg)
+ .addReg(LoadGOT)
+ .addReg(LoadPC);
+ } else {
+ // Generate lea (__GLOBAL_OFFSET_TABLE_,%PC), %A5
+ BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32q), GlobalBaseReg)
+ .addExternalSymbol("_GLOBAL_OFFSET_TABLE_", M68kII::MO_GOTPCREL);
+ }
return true;
}
diff --git a/llvm/lib/Target/M68k/M68kSubtarget.cpp b/llvm/lib/Target/M68k/M68kSubtarget.cpp
index 59d865ff1f4a9..8525a8d77457b 100644
--- a/llvm/lib/Target/M68k/M68kSubtarget.cpp
+++ b/llvm/lib/Target/M68k/M68kSubtarget.cpp
@@ -24,6 +24,7 @@
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
@@ -49,10 +50,11 @@ void M68kSubtarget::anchor() {}
M68kSubtarget::M68kSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
const M68kTargetMachine &TM)
- : M68kGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), TM(TM),
- InstrInfo(initializeSubtargetDependencies(CPU, TT, FS, TM)),
- FrameLowering(*this, this->getStackAlignment()), TLInfo(TM, *this),
- TargetTriple(TT) {
+ : M68kGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
+ UseXGOT(this->useXGOT()), TM(TM), InstrInfo(initializeSubtargetDependencies(CPU, TT, FS, TM)),
+ FrameLowering(*this, this->getStackAlignment()),
+ TLInfo(TM, *this), TargetTriple(TT),
+ TSInfo() {
TSInfo = std::make_unique<M68kSelectionDAGInfo>();
CallLoweringInfo.reset(new M68kCallLowering(*getTargetLowering()));
diff --git a/llvm/lib/Target/M68k/M68kSubtarget.h b/llvm/lib/Target/M68k/M68kSubtarget.h
index 16ca7d2e6d0fd..6ac1341d1bb71 100644
--- a/llvm/lib/Target/M68k/M68kSubtarget.h
+++ b/llvm/lib/Target/M68k/M68kSubtarget.h
@@ -50,6 +50,8 @@ class M68kSubtarget : public M68kGenSubtargetInfo {
enum SubtargetEnum { M00, M10, M20, M30, M40, M60 };
SubtargetEnum SubtargetKind = M00;
+ bool UseXGOT = false;
+
enum FPKindEnum { M881, M882 };
std::optional<FPKindEnum> FPUKind;
@@ -98,6 +100,8 @@ class M68kSubtarget : public M68kGenSubtargetInfo {
bool useSmallSection() const { return UseSmallSection; }
+ bool useXGOT() const { return UseXGOT; }
+
const Triple &getTargetTriple() const { return TargetTriple; }
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
diff --git a/llvm/test/CodeGen/M68k/xgot.ll b/llvm/test/CodeGen/M68k/xgot.ll
new file mode 100644
index 0000000000000..afe3bb2d164d9
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/xgot.ll
@@ -0,0 +1,51 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -mtriple=m68k --show-mc-encoding -mattr=+xgot -relocation-model=pic -code-model=large < %s | FileCheck %s
+
+ at VBRTag = external global [2147483647 x i8]
+
+define i1 @folded_offset(i32 %conv29) {
+; CHECK-LABEL: folded_offset:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: lea (0,%pc), %a0 ; encoding: [0x41,0xfa,0x00,0x00]
+; CHECK-NEXT: lea _GLOBAL_OFFSET_TABLE_, %a1 ; encoding: [0x43,0xf9,A,A,A,A]
+; CHECK-NEXT: ; fixup A - offset: 2, value: _GLOBAL_OFFSET_TABLE_, kind: FK_Data_4
+; CHECK-NEXT: suba.l %a0, %a1 ; encoding: [0x93,0xc8]
+; CHECK-NEXT: move.l #VBRTag at GOTOFF, %d0 ; encoding: [0x20,0x3c,A,A,A,A]
+; CHECK-NEXT: ; fixup A - offset: 2, value: VBRTag at GOTOFF, kind: FK_Data_4
+; CHECK-NEXT: move.b (1,%a1,%d0), %d0 ; encoding: [0x10,0x31,0x08,0x01]
+; CHECK-NEXT: ext.w %d0 ; encoding: [0x48,0x80]
+; CHECK-NEXT: ext.l %d0 ; encoding: [0x48,0xc0]
+; CHECK-NEXT: sub.l (4,%sp), %d0 ; encoding: [0x90,0xaf,0x00,0x04]
+; CHECK-NEXT: seq %d0 ; encoding: [0x57,0xc0]
+; CHECK-NEXT: rts ; encoding: [0x4e,0x75]
+entry:
+ %0 = load i8, ptr getelementptr inbounds ([2147483647 x i8], ptr @VBRTag, i32 0, i32 1), align 1
+ %conv30 = sext i8 %0 to i32
+ %cmp31.not = icmp eq i32 %conv30, %conv29
+ ret i1 %cmp31.not
+}
+
+define i1 @non_folded_offset(i32 %conv29) {
+; CHECK-LABEL: non_folded_offset:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %entry
+; CHECK-NEXT: lea (0,%pc), %a0 ; encoding: [0x41,0xfa,0x00,0x00]
+; CHECK-NEXT: lea _GLOBAL_OFFSET_TABLE_, %a1 ; encoding: [0x43,0xf9,A,A,A,A]
+; CHECK-NEXT: ; fixup A - offset: 2, value: _GLOBAL_OFFSET_TABLE_, kind: FK_Data_4
+; CHECK-NEXT: suba.l %a0, %a1 ; encoding: [0x93,0xc8]
+; CHECK-NEXT: move.l #2147483645, %d0 ; encoding: [0x20,0x3c,0x7f,0xff,0xff,0xfd]
+; CHECK-NEXT: adda.l #VBRTag at GOTOFF, %a1 ; encoding: [0xd3,0xfc,A,A,A,A]
+; CHECK-NEXT: ; fixup A - offset: 2, value: VBRTag at GOTOFF, kind: FK_Data_4
+; CHECK-NEXT: move.b (0,%a1,%d0), %d0 ; encoding: [0x10,0x31,0x08,0x00]
+; CHECK-NEXT: ext.w %d0 ; encoding: [0x48,0x80]
+; CHECK-NEXT: ext.l %d0 ; encoding: [0x48,0xc0]
+; CHECK-NEXT: sub.l (4,%sp), %d0 ; encoding: [0x90,0xaf,0x00,0x04]
+; CHECK-NEXT: seq %d0 ; encoding: [0x57,0xc0]
+; CHECK-NEXT: rts ; encoding: [0x4e,0x75]
+entry:
+ %0 = load i8, ptr getelementptr inbounds ([2147483647 x i8], ptr @VBRTag, i32 0, i32 2147483645), align 1
+ %conv30 = sext i8 %0 to i32
+ %cmp31.not = icmp eq i32 %conv30, %conv29
+ ret i1 %cmp31.not
+}
More information about the llvm-commits
mailing list