Skip to content

Commit a8cfa4b

Browse files
committed
[SystemZ][z/OS] Initial code to generate assembly files on z/OS
- This patch consists of the bare basic code needed in order to generate some assembly for the z/OS target. - Only the .text and the .bss sections are added for now. - The relevant MCSectionGOFF/Symbol interfaces have been added. This enables us to print out the GOFF machine code sections. - This patch enables us to add simple lit tests wherever possible, and contribute to the testing coverage for the z/OS target - Further improvements and additions will be made in future patches. Reviewed By: tmatheson Differential Revision: https://reviews.llvm.org/D106380
1 parent 8ee5759 commit a8cfa4b

File tree

14 files changed

+176
-4
lines changed

14 files changed

+176
-4
lines changed

llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,17 @@ class TargetLoweringObjectFileXCOFF : public TargetLoweringObjectFile {
284284
const TargetMachine &TM) const override;
285285
};
286286

287+
class TargetLoweringObjectFileGOFF : public TargetLoweringObjectFile {
288+
public:
289+
TargetLoweringObjectFileGOFF();
290+
~TargetLoweringObjectFileGOFF() override = default;
291+
292+
MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
293+
const TargetMachine &TM) const override;
294+
MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
295+
const TargetMachine &TM) const override;
296+
};
297+
287298
} // end namespace llvm
288299

289300
#endif // LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H

llvm/include/llvm/MC/MCContext.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ namespace llvm {
5252
class MCSection;
5353
class MCSectionCOFF;
5454
class MCSectionELF;
55+
class MCSectionGOFF;
5556
class MCSectionMachO;
5657
class MCSectionWasm;
5758
class MCSectionXCOFF;
@@ -74,7 +75,7 @@ namespace llvm {
7475
using DiagHandlerTy =
7576
std::function<void(const SMDiagnostic &, bool, const SourceMgr &,
7677
std::vector<const MDNode *> &)>;
77-
enum Environment { IsMachO, IsELF, IsCOFF, IsWasm, IsXCOFF };
78+
enum Environment { IsMachO, IsELF, IsGOFF, IsCOFF, IsWasm, IsXCOFF };
7879

7980
private:
8081
Environment Env;
@@ -114,6 +115,7 @@ namespace llvm {
114115
SpecificBumpPtrAllocator<MCSectionCOFF> COFFAllocator;
115116
SpecificBumpPtrAllocator<MCSectionELF> ELFAllocator;
116117
SpecificBumpPtrAllocator<MCSectionMachO> MachOAllocator;
118+
SpecificBumpPtrAllocator<MCSectionGOFF> GOFFAllocator;
117119
SpecificBumpPtrAllocator<MCSectionWasm> WasmAllocator;
118120
SpecificBumpPtrAllocator<MCSectionXCOFF> XCOFFAllocator;
119121
SpecificBumpPtrAllocator<MCInst> MCInstAllocator;
@@ -323,6 +325,7 @@ namespace llvm {
323325
StringMap<MCSectionMachO *> MachOUniquingMap;
324326
std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap;
325327
std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
328+
std::map<std::string, MCSectionGOFF *> GOFFUniquingMap;
326329
std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
327330
std::map<XCOFFSectionKey, MCSectionXCOFF *> XCOFFUniquingMap;
328331
StringMap<bool> RelSecNames;
@@ -595,6 +598,8 @@ namespace llvm {
595598
unsigned Flags,
596599
unsigned EntrySize);
597600

601+
MCSectionGOFF *getGOFFSection(StringRef Section, SectionKind Kind);
602+
598603
MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
599604
SectionKind Kind, StringRef COMDATSymName,
600605
int Selection,

llvm/include/llvm/MC/MCObjectFileInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ class MCObjectFileInfo {
426426

427427
void initMachOMCObjectFileInfo(const Triple &T);
428428
void initELFMCObjectFileInfo(const Triple &T, bool Large);
429+
void initGOFFMCObjectFileInfo(const Triple &T);
429430
void initCOFFMCObjectFileInfo(const Triple &T);
430431
void initWasmMCObjectFileInfo(const Triple &T);
431432
void initXCOFFMCObjectFileInfo(const Triple &T);

llvm/include/llvm/MC/MCSection.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,14 @@ class MCSection {
4040
public:
4141
static constexpr unsigned NonUniqueID = ~0U;
4242

43-
enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO, SV_Wasm, SV_XCOFF };
43+
enum SectionVariant {
44+
SV_COFF = 0,
45+
SV_ELF,
46+
SV_GOFF,
47+
SV_MachO,
48+
SV_Wasm,
49+
SV_XCOFF
50+
};
4451

4552
/// Express the state of bundle locked groups while emitting code.
4653
enum BundleLockStateType {

llvm/include/llvm/MC/MCSectionGOFF.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===-- llvm/MC/MCSectionGOFF.h - GOFF Machine Code Sections ----*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
///
9+
/// \file
10+
/// This file declares the MCSectionGOFF class, which contains all of the
11+
/// necessary machine code sections for the GOFF file format.
12+
///
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef LLVM_MC_MCSECTIONGOFF_H
16+
#define LLVM_MC_MCSECTIONGOFF_H
17+
18+
#include "llvm/MC/MCSection.h"
19+
#include "llvm/Support/raw_ostream.h"
20+
21+
namespace llvm {
22+
23+
class MCExpr;
24+
25+
class MCSectionGOFF final : public MCSection {
26+
private:
27+
friend class MCContext;
28+
MCSectionGOFF(StringRef Name, SectionKind K)
29+
: MCSection(SV_GOFF, Name, K, nullptr) {}
30+
31+
public:
32+
void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
33+
raw_ostream &OS,
34+
const MCExpr *Subsection) const override {
35+
OS << "\t.section\t\"" << getName() << "\"\n";
36+
}
37+
38+
bool UseCodeAlign() const override { return false; }
39+
40+
bool isVirtualSection() const override { return false; }
41+
42+
static bool classof(const MCSection *S) { return S->getVariant() == SV_GOFF; }
43+
};
44+
} // end namespace llvm
45+
46+
#endif

llvm/include/llvm/MC/MCSymbol.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class MCSymbol {
4646
SymbolKindUnset,
4747
SymbolKindCOFF,
4848
SymbolKindELF,
49+
SymbolKindGOFF,
4950
SymbolKindMachO,
5051
SymbolKindWasm,
5152
SymbolKindXCOFF,
@@ -276,6 +277,8 @@ class MCSymbol {
276277

277278
bool isCOFF() const { return Kind == SymbolKindCOFF; }
278279

280+
bool isGOFF() const { return Kind == SymbolKindGOFF; }
281+
279282
bool isMachO() const { return Kind == SymbolKindMachO; }
280283

281284
bool isWasm() const { return Kind == SymbolKindWasm; }

llvm/include/llvm/MC/MCSymbolGOFF.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===-- llvm/MC/MCSymbolGOFF.h - GOFF Machine Code Symbols ------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
///
9+
/// \file
10+
/// This file contains the MCSymbolGOFF class
11+
///
12+
//===----------------------------------------------------------------------===//
13+
#ifndef LLVM_MC_MCSYMBOLGOFF_H
14+
#define LLVM_MC_MCSYMBOLGOFF_H
15+
16+
#include "llvm/MC/MCSymbol.h"
17+
18+
namespace llvm {
19+
20+
class MCSymbolGOFF : public MCSymbol {
21+
public:
22+
MCSymbolGOFF(const StringMapEntry<bool> *Name, bool IsTemporary)
23+
: MCSymbol(SymbolKindGOFF, Name, IsTemporary) {}
24+
static bool classof(const MCSymbol *S) { return S->isGOFF(); }
25+
};
26+
} // end namespace llvm
27+
28+
#endif

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "llvm/MC/MCExpr.h"
4949
#include "llvm/MC/MCSectionCOFF.h"
5050
#include "llvm/MC/MCSectionELF.h"
51+
#include "llvm/MC/MCSectionGOFF.h"
5152
#include "llvm/MC/MCSectionMachO.h"
5253
#include "llvm/MC/MCSectionWasm.h"
5354
#include "llvm/MC/MCSectionXCOFF.h"
@@ -2521,3 +2522,24 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForTOCEntry(
25212522
TM.getCodeModel() == CodeModel::Large ? XCOFF::XMC_TE : XCOFF::XMC_TC,
25222523
XCOFF::XTY_SD));
25232524
}
2525+
2526+
//===----------------------------------------------------------------------===//
2527+
// GOFF
2528+
//===----------------------------------------------------------------------===//
2529+
TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF()
2530+
: TargetLoweringObjectFile() {}
2531+
2532+
MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal(
2533+
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
2534+
return SelectSectionForGlobal(GO, Kind, TM);
2535+
}
2536+
2537+
MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
2538+
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
2539+
auto *Symbol = TM.getSymbol(GO);
2540+
if (Kind.isBSS())
2541+
return getContext().getGOFFSection(Symbol->getName(),
2542+
SectionKind::getBSS());
2543+
2544+
return getContext().getObjectFileInfo()->getTextSection();
2545+
}

llvm/lib/MC/MCContext.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@
2525
#include "llvm/MC/MCObjectFileInfo.h"
2626
#include "llvm/MC/MCSectionCOFF.h"
2727
#include "llvm/MC/MCSectionELF.h"
28+
#include "llvm/MC/MCSectionGOFF.h"
2829
#include "llvm/MC/MCSectionMachO.h"
2930
#include "llvm/MC/MCSectionWasm.h"
3031
#include "llvm/MC/MCSectionXCOFF.h"
3132
#include "llvm/MC/MCStreamer.h"
3233
#include "llvm/MC/MCSymbol.h"
3334
#include "llvm/MC/MCSymbolCOFF.h"
3435
#include "llvm/MC/MCSymbolELF.h"
36+
#include "llvm/MC/MCSymbolGOFF.h"
3537
#include "llvm/MC/MCSymbolMachO.h"
3638
#include "llvm/MC/MCSymbolWasm.h"
3739
#include "llvm/MC/MCSymbolXCOFF.h"
@@ -99,7 +101,7 @@ MCContext::MCContext(const Triple &TheTriple, const MCAsmInfo *mai,
99101
Env = IsXCOFF;
100102
break;
101103
case Triple::GOFF:
102-
report_fatal_error("Cannot initialize MC for GOFF object file format");
104+
Env = IsGOFF;
103105
break;
104106
case Triple::UnknownObjectFormat:
105107
report_fatal_error("Cannot initialize MC for unknown object file format.");
@@ -133,6 +135,7 @@ void MCContext::reset() {
133135
// Call the destructors so the fragments are freed
134136
COFFAllocator.DestroyAll();
135137
ELFAllocator.DestroyAll();
138+
GOFFAllocator.DestroyAll();
136139
MachOAllocator.DestroyAll();
137140
XCOFFAllocator.DestroyAll();
138141
MCInstAllocator.DestroyAll();
@@ -156,6 +159,7 @@ void MCContext::reset() {
156159

157160
MachOUniquingMap.clear();
158161
ELFUniquingMap.clear();
162+
GOFFUniquingMap.clear();
159163
COFFUniquingMap.clear();
160164
WasmUniquingMap.clear();
161165
XCOFFUniquingMap.clear();
@@ -231,6 +235,8 @@ MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name,
231235
return new (Name, *this) MCSymbolCOFF(Name, IsTemporary);
232236
case MCContext::IsELF:
233237
return new (Name, *this) MCSymbolELF(Name, IsTemporary);
238+
case MCContext::IsGOFF:
239+
return new (Name, *this) MCSymbolGOFF(Name, IsTemporary);
234240
case MCContext::IsMachO:
235241
return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
236242
case MCContext::IsWasm:
@@ -610,6 +616,15 @@ Optional<unsigned> MCContext::getELFUniqueIDForEntsize(StringRef SectionName,
610616
return (I != ELFEntrySizeMap.end()) ? Optional<unsigned>(I->second) : None;
611617
}
612618

619+
MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind) {
620+
// Do the lookup. If we don't have a hit, return a new section.
621+
auto &GOFFSection = GOFFUniquingMap[Section.str()];
622+
if (!GOFFSection)
623+
GOFFSection = new (GOFFAllocator.Allocate()) MCSectionGOFF(Section, Kind);
624+
625+
return GOFFSection;
626+
}
627+
613628
MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
614629
unsigned Characteristics,
615630
SectionKind Kind,

llvm/lib/MC/MCObjectFileInfo.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/MC/MCSection.h"
1818
#include "llvm/MC/MCSectionCOFF.h"
1919
#include "llvm/MC/MCSectionELF.h"
20+
#include "llvm/MC/MCSectionGOFF.h"
2021
#include "llvm/MC/MCSectionMachO.h"
2122
#include "llvm/MC/MCSectionWasm.h"
2223
#include "llvm/MC/MCSectionXCOFF.h"
@@ -504,6 +505,11 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
504505
Ctx->getELFSection(".pseudo_probe_desc", DebugSecType, 0);
505506
}
506507

508+
void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
509+
TextSection = Ctx->getGOFFSection(".text", SectionKind::getText());
510+
BSSSection = Ctx->getGOFFSection(".bss", SectionKind::getBSS());
511+
}
512+
507513
void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
508514
EHFrameSection =
509515
Ctx->getCOFFSection(".eh_frame", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -995,6 +1001,9 @@ void MCObjectFileInfo::initMCObjectFileInfo(MCContext &MCCtx, bool PIC,
9951001
case MCContext::IsELF:
9961002
initELFMCObjectFileInfo(TheTriple, LargeCodeModel);
9971003
break;
1004+
case MCContext::IsGOFF:
1005+
initGOFFMCObjectFileInfo(TheTriple);
1006+
break;
9981007
case MCContext::IsWasm:
9991008
initWasmMCObjectFileInfo(TheTriple);
10001009
break;

llvm/lib/MC/MCParser/AsmParser.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,8 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
782782
case MCContext::IsELF:
783783
PlatformParser.reset(createELFAsmParser());
784784
break;
785+
case MCContext::IsGOFF:
786+
report_fatal_error("GOFFAsmParser support not implemented yet");
785787
case MCContext::IsWasm:
786788
PlatformParser.reset(createWasmAsmParser());
787789
break;

llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6369,6 +6369,7 @@ bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
63696369
case MCContext::IsWasm:
63706370
CurrentFormat = WASM;
63716371
break;
6372+
case MCContext::IsGOFF:
63726373
case MCContext::IsXCOFF:
63736374
llvm_unreachable("unexpected object format");
63746375
break;

llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,15 @@ static std::string computeDataLayout(const Triple &TT, StringRef CPU,
9797
return Ret;
9898
}
9999

100+
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
101+
if (TT.isOSzOS())
102+
return std::make_unique<TargetLoweringObjectFileGOFF>();
103+
104+
// Note: Some times run with -triple s390x-unknown.
105+
// In this case, default to ELF unless z/OS specifically provided.
106+
return std::make_unique<TargetLoweringObjectFileELF>();
107+
}
108+
100109
static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
101110
// Static code is suitable for use in a dynamic executable; there is no
102111
// separate DynamicNoPIC model.
@@ -160,7 +169,7 @@ SystemZTargetMachine::SystemZTargetMachine(const Target &T, const Triple &TT,
160169
getEffectiveRelocModel(RM),
161170
getEffectiveSystemZCodeModel(CM, getEffectiveRelocModel(RM), JIT),
162171
OL),
163-
TLOF(std::make_unique<TargetLoweringObjectFileELF>()) {
172+
TLOF(createTLOF(getTargetTriple())) {
164173
initAsmInfo();
165174
}
166175

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; A simple, barebones test to check whether assembly can be emitted
2+
; for the z/OS target
3+
; RUN: llc < %s -mtriple=s390x-ibm-zos | FileCheck %s
4+
5+
@a = global i32 0, align 4
6+
7+
define signext i32 @main() {
8+
; CHECK: .section ".text"
9+
; CHECK: main:
10+
; CHECK: .section "a"
11+
entry:
12+
ret i32 0
13+
}

0 commit comments

Comments
 (0)