Skip to content

Commit 34dab26

Browse files
committed
[M68k] implement -mxgot
1 parent 1f5047e commit 34dab26

File tree

5 files changed

+88
-7
lines changed

5 files changed

+88
-7
lines changed

llvm/lib/Target/M68k/M68k.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ foreach i = {0-7} in
6565
SubtargetFeature<"reserve-d"#i, "UserReservedRegister[M68k::D"#i#"]",
6666
"true", "Reserve D"#i#" register">;
6767

68+
def FeatureXGOT
69+
: SubtargetFeature<"xgot", "UseXGOT", "true", "Assume 32-bit GOT">;
70+
6871
//===----------------------------------------------------------------------===//
6972
// M68k processors supported.
7073
//===----------------------------------------------------------------------===//

llvm/lib/Target/M68k/M68kInstrInfo.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ struct M68kGlobalBaseReg : public MachineFunctionPass {
933933
bool runOnMachineFunction(MachineFunction &MF) override {
934934
const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();
935935
M68kMachineFunctionInfo *MxFI = MF.getInfo<M68kMachineFunctionInfo>();
936+
MachineRegisterInfo &RegInfo = MF.getRegInfo();
936937

937938
unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();
938939

@@ -946,9 +947,29 @@ struct M68kGlobalBaseReg : public MachineFunctionPass {
946947
DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
947948
const M68kInstrInfo *TII = STI.getInstrInfo();
948949

949-
// Generate lea (__GLOBAL_OFFSET_TABLE_,%PC), %A5
950-
BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32q), GlobalBaseReg)
951-
.addExternalSymbol("_GLOBAL_OFFSET_TABLE_", M68kII::MO_GOTPCREL);
950+
if (STI.useXGOT()) {
951+
// Generate the following, as PC relative addressing is limited to i16
952+
// offset
953+
// lea (0,%PC), %A5
954+
// lea _GLOBAL_OFFSET_TABLE_, %AX
955+
// suba.l %AX, %A5
956+
// where %AX can be any other assigned address register.
957+
// This should allow programs in a >16bit PC state to still use GOTPCREL
958+
// addressing.
959+
Register LoadPC = RegInfo.createVirtualRegister(&M68k::AR32_NOSPRegClass);
960+
Register LoadGOT =
961+
RegInfo.createVirtualRegister(&M68k::AR32_NOSPRegClass);
962+
BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32q), LoadPC).addImm(0);
963+
BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32b), LoadGOT)
964+
.addExternalSymbol("_GLOBAL_OFFSET_TABLE_");
965+
BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::SUB32ar), GlobalBaseReg)
966+
.addReg(LoadGOT)
967+
.addReg(LoadPC);
968+
} else {
969+
// Generate lea (__GLOBAL_OFFSET_TABLE_,%PC), %A5
970+
BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32q), GlobalBaseReg)
971+
.addExternalSymbol("_GLOBAL_OFFSET_TABLE_", M68kII::MO_GOTPCREL);
972+
}
952973

953974
return true;
954975
}

llvm/lib/Target/M68k/M68kSubtarget.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/IR/Attributes.h"
2525
#include "llvm/IR/Function.h"
2626
#include "llvm/MC/TargetRegistry.h"
27+
#include "llvm/Support/CodeGen.h"
2728
#include "llvm/Support/CommandLine.h"
2829
#include "llvm/Support/ErrorHandling.h"
2930

@@ -49,10 +50,11 @@ void M68kSubtarget::anchor() {}
4950

5051
M68kSubtarget::M68kSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
5152
const M68kTargetMachine &TM)
52-
: M68kGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), TM(TM),
53-
InstrInfo(initializeSubtargetDependencies(CPU, TT, FS, TM)),
54-
FrameLowering(*this, this->getStackAlignment()), TLInfo(TM, *this),
55-
TargetTriple(TT) {
53+
: M68kGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
54+
UseXGOT(this->useXGOT()), TM(TM), InstrInfo(initializeSubtargetDependencies(CPU, TT, FS, TM)),
55+
FrameLowering(*this, this->getStackAlignment()),
56+
TLInfo(TM, *this), TargetTriple(TT),
57+
TSInfo() {
5658
TSInfo = std::make_unique<M68kSelectionDAGInfo>();
5759

5860
CallLoweringInfo.reset(new M68kCallLowering(*getTargetLowering()));

llvm/lib/Target/M68k/M68kSubtarget.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class M68kSubtarget : public M68kGenSubtargetInfo {
5050
enum SubtargetEnum { M00, M10, M20, M30, M40, M60 };
5151
SubtargetEnum SubtargetKind = M00;
5252

53+
bool UseXGOT = false;
54+
5355
enum FPKindEnum { M881, M882 };
5456
std::optional<FPKindEnum> FPUKind;
5557

@@ -98,6 +100,8 @@ class M68kSubtarget : public M68kGenSubtargetInfo {
98100

99101
bool useSmallSection() const { return UseSmallSection; }
100102

103+
bool useXGOT() const { return UseXGOT; }
104+
101105
const Triple &getTargetTriple() const { return TargetTriple; }
102106

103107
bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }

llvm/test/CodeGen/M68k/xgot.ll

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2+
; RUN: llc -mtriple=m68k --show-mc-encoding -mattr=+xgot -relocation-model=pic -code-model=large < %s | FileCheck %s
3+
4+
@VBRTag = external global [2147483647 x i8]
5+
6+
define i1 @folded_offset(i32 %conv29) {
7+
; CHECK-LABEL: folded_offset:
8+
; CHECK: .cfi_startproc
9+
; CHECK-NEXT: ; %bb.0: ; %entry
10+
; CHECK-NEXT: lea (0,%pc), %a0 ; encoding: [0x41,0xfa,0x00,0x00]
11+
; CHECK-NEXT: lea _GLOBAL_OFFSET_TABLE_, %a1 ; encoding: [0x43,0xf9,A,A,A,A]
12+
; CHECK-NEXT: ; fixup A - offset: 2, value: _GLOBAL_OFFSET_TABLE_, kind: FK_Data_4
13+
; CHECK-NEXT: suba.l %a0, %a1 ; encoding: [0x93,0xc8]
14+
; CHECK-NEXT: move.l #VBRTag@GOTOFF, %d0 ; encoding: [0x20,0x3c,A,A,A,A]
15+
; CHECK-NEXT: ; fixup A - offset: 2, value: VBRTag@GOTOFF, kind: FK_Data_4
16+
; CHECK-NEXT: move.b (1,%a1,%d0), %d0 ; encoding: [0x10,0x31,0x08,0x01]
17+
; CHECK-NEXT: ext.w %d0 ; encoding: [0x48,0x80]
18+
; CHECK-NEXT: ext.l %d0 ; encoding: [0x48,0xc0]
19+
; CHECK-NEXT: sub.l (4,%sp), %d0 ; encoding: [0x90,0xaf,0x00,0x04]
20+
; CHECK-NEXT: seq %d0 ; encoding: [0x57,0xc0]
21+
; CHECK-NEXT: rts ; encoding: [0x4e,0x75]
22+
entry:
23+
%0 = load i8, ptr getelementptr inbounds ([2147483647 x i8], ptr @VBRTag, i32 0, i32 1), align 1
24+
%conv30 = sext i8 %0 to i32
25+
%cmp31.not = icmp eq i32 %conv30, %conv29
26+
ret i1 %cmp31.not
27+
}
28+
29+
define i1 @non_folded_offset(i32 %conv29) {
30+
; CHECK-LABEL: non_folded_offset:
31+
; CHECK: .cfi_startproc
32+
; CHECK-NEXT: ; %bb.0: ; %entry
33+
; CHECK-NEXT: lea (0,%pc), %a0 ; encoding: [0x41,0xfa,0x00,0x00]
34+
; CHECK-NEXT: lea _GLOBAL_OFFSET_TABLE_, %a1 ; encoding: [0x43,0xf9,A,A,A,A]
35+
; CHECK-NEXT: ; fixup A - offset: 2, value: _GLOBAL_OFFSET_TABLE_, kind: FK_Data_4
36+
; CHECK-NEXT: suba.l %a0, %a1 ; encoding: [0x93,0xc8]
37+
; CHECK-NEXT: move.l #2147483645, %d0 ; encoding: [0x20,0x3c,0x7f,0xff,0xff,0xfd]
38+
; CHECK-NEXT: adda.l #VBRTag@GOTOFF, %a1 ; encoding: [0xd3,0xfc,A,A,A,A]
39+
; CHECK-NEXT: ; fixup A - offset: 2, value: VBRTag@GOTOFF, kind: FK_Data_4
40+
; CHECK-NEXT: move.b (0,%a1,%d0), %d0 ; encoding: [0x10,0x31,0x08,0x00]
41+
; CHECK-NEXT: ext.w %d0 ; encoding: [0x48,0x80]
42+
; CHECK-NEXT: ext.l %d0 ; encoding: [0x48,0xc0]
43+
; CHECK-NEXT: sub.l (4,%sp), %d0 ; encoding: [0x90,0xaf,0x00,0x04]
44+
; CHECK-NEXT: seq %d0 ; encoding: [0x57,0xc0]
45+
; CHECK-NEXT: rts ; encoding: [0x4e,0x75]
46+
entry:
47+
%0 = load i8, ptr getelementptr inbounds ([2147483647 x i8], ptr @VBRTag, i32 0, i32 2147483645), align 1
48+
%conv30 = sext i8 %0 to i32
49+
%cmp31.not = icmp eq i32 %conv30, %conv29
50+
ret i1 %cmp31.not
51+
}

0 commit comments

Comments
 (0)