1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[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
This commit is contained in:
Anirudh Prasad 2021-07-27 11:26:00 -04:00
parent 23f3f90569
commit 2b967460b4
14 changed files with 176 additions and 4 deletions

View File

@ -284,6 +284,17 @@ public:
const TargetMachine &TM) const override; const TargetMachine &TM) const override;
}; };
class TargetLoweringObjectFileGOFF : public TargetLoweringObjectFile {
public:
TargetLoweringObjectFileGOFF();
~TargetLoweringObjectFileGOFF() override = default;
MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
const TargetMachine &TM) const override;
MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
const TargetMachine &TM) const override;
};
} // end namespace llvm } // end namespace llvm
#endif // LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H #endif // LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H

View File

@ -52,6 +52,7 @@ namespace llvm {
class MCSection; class MCSection;
class MCSectionCOFF; class MCSectionCOFF;
class MCSectionELF; class MCSectionELF;
class MCSectionGOFF;
class MCSectionMachO; class MCSectionMachO;
class MCSectionWasm; class MCSectionWasm;
class MCSectionXCOFF; class MCSectionXCOFF;
@ -74,7 +75,7 @@ namespace llvm {
using DiagHandlerTy = using DiagHandlerTy =
std::function<void(const SMDiagnostic &, bool, const SourceMgr &, std::function<void(const SMDiagnostic &, bool, const SourceMgr &,
std::vector<const MDNode *> &)>; std::vector<const MDNode *> &)>;
enum Environment { IsMachO, IsELF, IsCOFF, IsWasm, IsXCOFF }; enum Environment { IsMachO, IsELF, IsGOFF, IsCOFF, IsWasm, IsXCOFF };
private: private:
Environment Env; Environment Env;
@ -114,6 +115,7 @@ namespace llvm {
SpecificBumpPtrAllocator<MCSectionCOFF> COFFAllocator; SpecificBumpPtrAllocator<MCSectionCOFF> COFFAllocator;
SpecificBumpPtrAllocator<MCSectionELF> ELFAllocator; SpecificBumpPtrAllocator<MCSectionELF> ELFAllocator;
SpecificBumpPtrAllocator<MCSectionMachO> MachOAllocator; SpecificBumpPtrAllocator<MCSectionMachO> MachOAllocator;
SpecificBumpPtrAllocator<MCSectionGOFF> GOFFAllocator;
SpecificBumpPtrAllocator<MCSectionWasm> WasmAllocator; SpecificBumpPtrAllocator<MCSectionWasm> WasmAllocator;
SpecificBumpPtrAllocator<MCSectionXCOFF> XCOFFAllocator; SpecificBumpPtrAllocator<MCSectionXCOFF> XCOFFAllocator;
SpecificBumpPtrAllocator<MCInst> MCInstAllocator; SpecificBumpPtrAllocator<MCInst> MCInstAllocator;
@ -323,6 +325,7 @@ namespace llvm {
StringMap<MCSectionMachO *> MachOUniquingMap; StringMap<MCSectionMachO *> MachOUniquingMap;
std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap; std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap;
std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap; std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap;
std::map<std::string, MCSectionGOFF *> GOFFUniquingMap;
std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap; std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap;
std::map<XCOFFSectionKey, MCSectionXCOFF *> XCOFFUniquingMap; std::map<XCOFFSectionKey, MCSectionXCOFF *> XCOFFUniquingMap;
StringMap<bool> RelSecNames; StringMap<bool> RelSecNames;
@ -595,6 +598,8 @@ namespace llvm {
unsigned Flags, unsigned Flags,
unsigned EntrySize); unsigned EntrySize);
MCSectionGOFF *getGOFFSection(StringRef Section, SectionKind Kind);
MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
SectionKind Kind, StringRef COMDATSymName, SectionKind Kind, StringRef COMDATSymName,
int Selection, int Selection,

View File

@ -426,6 +426,7 @@ private:
void initMachOMCObjectFileInfo(const Triple &T); void initMachOMCObjectFileInfo(const Triple &T);
void initELFMCObjectFileInfo(const Triple &T, bool Large); void initELFMCObjectFileInfo(const Triple &T, bool Large);
void initGOFFMCObjectFileInfo(const Triple &T);
void initCOFFMCObjectFileInfo(const Triple &T); void initCOFFMCObjectFileInfo(const Triple &T);
void initWasmMCObjectFileInfo(const Triple &T); void initWasmMCObjectFileInfo(const Triple &T);
void initXCOFFMCObjectFileInfo(const Triple &T); void initXCOFFMCObjectFileInfo(const Triple &T);

View File

@ -40,7 +40,14 @@ class MCSection {
public: public:
static constexpr unsigned NonUniqueID = ~0U; static constexpr unsigned NonUniqueID = ~0U;
enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO, SV_Wasm, SV_XCOFF }; enum SectionVariant {
SV_COFF = 0,
SV_ELF,
SV_GOFF,
SV_MachO,
SV_Wasm,
SV_XCOFF
};
/// Express the state of bundle locked groups while emitting code. /// Express the state of bundle locked groups while emitting code.
enum BundleLockStateType { enum BundleLockStateType {

View File

@ -0,0 +1,46 @@
//===-- llvm/MC/MCSectionGOFF.h - GOFF Machine Code Sections ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file declares the MCSectionGOFF class, which contains all of the
/// necessary machine code sections for the GOFF file format.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSECTIONGOFF_H
#define LLVM_MC_MCSECTIONGOFF_H
#include "llvm/MC/MCSection.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
class MCExpr;
class MCSectionGOFF final : public MCSection {
private:
friend class MCContext;
MCSectionGOFF(StringRef Name, SectionKind K)
: MCSection(SV_GOFF, Name, K, nullptr) {}
public:
void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
raw_ostream &OS,
const MCExpr *Subsection) const override {
OS << "\t.section\t\"" << getName() << "\"\n";
}
bool UseCodeAlign() const override { return false; }
bool isVirtualSection() const override { return false; }
static bool classof(const MCSection *S) { return S->getVariant() == SV_GOFF; }
};
} // end namespace llvm
#endif

View File

@ -46,6 +46,7 @@ protected:
SymbolKindUnset, SymbolKindUnset,
SymbolKindCOFF, SymbolKindCOFF,
SymbolKindELF, SymbolKindELF,
SymbolKindGOFF,
SymbolKindMachO, SymbolKindMachO,
SymbolKindWasm, SymbolKindWasm,
SymbolKindXCOFF, SymbolKindXCOFF,
@ -276,6 +277,8 @@ public:
bool isCOFF() const { return Kind == SymbolKindCOFF; } bool isCOFF() const { return Kind == SymbolKindCOFF; }
bool isGOFF() const { return Kind == SymbolKindGOFF; }
bool isMachO() const { return Kind == SymbolKindMachO; } bool isMachO() const { return Kind == SymbolKindMachO; }
bool isWasm() const { return Kind == SymbolKindWasm; } bool isWasm() const { return Kind == SymbolKindWasm; }

View File

@ -0,0 +1,28 @@
//===-- llvm/MC/MCSymbolGOFF.h - GOFF Machine Code Symbols ------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains the MCSymbolGOFF class
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCSYMBOLGOFF_H
#define LLVM_MC_MCSYMBOLGOFF_H
#include "llvm/MC/MCSymbol.h"
namespace llvm {
class MCSymbolGOFF : public MCSymbol {
public:
MCSymbolGOFF(const StringMapEntry<bool> *Name, bool IsTemporary)
: MCSymbol(SymbolKindGOFF, Name, IsTemporary) {}
static bool classof(const MCSymbol *S) { return S->isGOFF(); }
};
} // end namespace llvm
#endif

View File

@ -48,6 +48,7 @@
#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionGOFF.h"
#include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSectionWasm.h" #include "llvm/MC/MCSectionWasm.h"
#include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCSectionXCOFF.h"
@ -2521,3 +2522,24 @@ MCSection *TargetLoweringObjectFileXCOFF::getSectionForTOCEntry(
TM.getCodeModel() == CodeModel::Large ? XCOFF::XMC_TE : XCOFF::XMC_TC, TM.getCodeModel() == CodeModel::Large ? XCOFF::XMC_TE : XCOFF::XMC_TC,
XCOFF::XTY_SD)); XCOFF::XTY_SD));
} }
//===----------------------------------------------------------------------===//
// GOFF
//===----------------------------------------------------------------------===//
TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF()
: TargetLoweringObjectFile() {}
MCSection *TargetLoweringObjectFileGOFF::getExplicitSectionGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
return SelectSectionForGlobal(GO, Kind, TM);
}
MCSection *TargetLoweringObjectFileGOFF::SelectSectionForGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
auto *Symbol = TM.getSymbol(GO);
if (Kind.isBSS())
return getContext().getGOFFSection(Symbol->getName(),
SectionKind::getBSS());
return getContext().getObjectFileInfo()->getTextSection();
}

View File

@ -25,6 +25,7 @@
#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionGOFF.h"
#include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSectionWasm.h" #include "llvm/MC/MCSectionWasm.h"
#include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCSectionXCOFF.h"
@ -32,6 +33,7 @@
#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolCOFF.h" #include "llvm/MC/MCSymbolCOFF.h"
#include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCSymbolGOFF.h"
#include "llvm/MC/MCSymbolMachO.h" #include "llvm/MC/MCSymbolMachO.h"
#include "llvm/MC/MCSymbolWasm.h" #include "llvm/MC/MCSymbolWasm.h"
#include "llvm/MC/MCSymbolXCOFF.h" #include "llvm/MC/MCSymbolXCOFF.h"
@ -99,7 +101,7 @@ MCContext::MCContext(const Triple &TheTriple, const MCAsmInfo *mai,
Env = IsXCOFF; Env = IsXCOFF;
break; break;
case Triple::GOFF: case Triple::GOFF:
report_fatal_error("Cannot initialize MC for GOFF object file format"); Env = IsGOFF;
break; break;
case Triple::UnknownObjectFormat: case Triple::UnknownObjectFormat:
report_fatal_error("Cannot initialize MC for unknown object file format."); report_fatal_error("Cannot initialize MC for unknown object file format.");
@ -133,6 +135,7 @@ void MCContext::reset() {
// Call the destructors so the fragments are freed // Call the destructors so the fragments are freed
COFFAllocator.DestroyAll(); COFFAllocator.DestroyAll();
ELFAllocator.DestroyAll(); ELFAllocator.DestroyAll();
GOFFAllocator.DestroyAll();
MachOAllocator.DestroyAll(); MachOAllocator.DestroyAll();
XCOFFAllocator.DestroyAll(); XCOFFAllocator.DestroyAll();
MCInstAllocator.DestroyAll(); MCInstAllocator.DestroyAll();
@ -156,6 +159,7 @@ void MCContext::reset() {
MachOUniquingMap.clear(); MachOUniquingMap.clear();
ELFUniquingMap.clear(); ELFUniquingMap.clear();
GOFFUniquingMap.clear();
COFFUniquingMap.clear(); COFFUniquingMap.clear();
WasmUniquingMap.clear(); WasmUniquingMap.clear();
XCOFFUniquingMap.clear(); XCOFFUniquingMap.clear();
@ -231,6 +235,8 @@ MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name,
return new (Name, *this) MCSymbolCOFF(Name, IsTemporary); return new (Name, *this) MCSymbolCOFF(Name, IsTemporary);
case MCContext::IsELF: case MCContext::IsELF:
return new (Name, *this) MCSymbolELF(Name, IsTemporary); return new (Name, *this) MCSymbolELF(Name, IsTemporary);
case MCContext::IsGOFF:
return new (Name, *this) MCSymbolGOFF(Name, IsTemporary);
case MCContext::IsMachO: case MCContext::IsMachO:
return new (Name, *this) MCSymbolMachO(Name, IsTemporary); return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
case MCContext::IsWasm: case MCContext::IsWasm:
@ -610,6 +616,15 @@ Optional<unsigned> MCContext::getELFUniqueIDForEntsize(StringRef SectionName,
return (I != ELFEntrySizeMap.end()) ? Optional<unsigned>(I->second) : None; return (I != ELFEntrySizeMap.end()) ? Optional<unsigned>(I->second) : None;
} }
MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind) {
// Do the lookup. If we don't have a hit, return a new section.
auto &GOFFSection = GOFFUniquingMap[Section.str()];
if (!GOFFSection)
GOFFSection = new (GOFFAllocator.Allocate()) MCSectionGOFF(Section, Kind);
return GOFFSection;
}
MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
unsigned Characteristics, unsigned Characteristics,
SectionKind Kind, SectionKind Kind,

View File

@ -17,6 +17,7 @@
#include "llvm/MC/MCSection.h" #include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionGOFF.h"
#include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSectionWasm.h" #include "llvm/MC/MCSectionWasm.h"
#include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCSectionXCOFF.h"
@ -504,6 +505,11 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
Ctx->getELFSection(".pseudo_probe_desc", DebugSecType, 0); Ctx->getELFSection(".pseudo_probe_desc", DebugSecType, 0);
} }
void MCObjectFileInfo::initGOFFMCObjectFileInfo(const Triple &T) {
TextSection = Ctx->getGOFFSection(".text", SectionKind::getText());
BSSSection = Ctx->getGOFFSection(".bss", SectionKind::getBSS());
}
void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) { void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
EHFrameSection = EHFrameSection =
Ctx->getCOFFSection(".eh_frame", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | Ctx->getCOFFSection(".eh_frame", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@ -995,6 +1001,9 @@ void MCObjectFileInfo::initMCObjectFileInfo(MCContext &MCCtx, bool PIC,
case MCContext::IsELF: case MCContext::IsELF:
initELFMCObjectFileInfo(TheTriple, LargeCodeModel); initELFMCObjectFileInfo(TheTriple, LargeCodeModel);
break; break;
case MCContext::IsGOFF:
initGOFFMCObjectFileInfo(TheTriple);
break;
case MCContext::IsWasm: case MCContext::IsWasm:
initWasmMCObjectFileInfo(TheTriple); initWasmMCObjectFileInfo(TheTriple);
break; break;

View File

@ -782,6 +782,8 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
case MCContext::IsELF: case MCContext::IsELF:
PlatformParser.reset(createELFAsmParser()); PlatformParser.reset(createELFAsmParser());
break; break;
case MCContext::IsGOFF:
report_fatal_error("GOFFAsmParser support not implemented yet");
case MCContext::IsWasm: case MCContext::IsWasm:
PlatformParser.reset(createWasmAsmParser()); PlatformParser.reset(createWasmAsmParser());
break; break;

View File

@ -6369,6 +6369,7 @@ bool ARMAsmParser::parsePrefix(ARMMCExpr::VariantKind &RefKind) {
case MCContext::IsWasm: case MCContext::IsWasm:
CurrentFormat = WASM; CurrentFormat = WASM;
break; break;
case MCContext::IsGOFF:
case MCContext::IsXCOFF: case MCContext::IsXCOFF:
llvm_unreachable("unexpected object format"); llvm_unreachable("unexpected object format");
break; break;

View File

@ -97,6 +97,15 @@ static std::string computeDataLayout(const Triple &TT, StringRef CPU,
return Ret; return Ret;
} }
static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
if (TT.isOSzOS())
return std::make_unique<TargetLoweringObjectFileGOFF>();
// Note: Some times run with -triple s390x-unknown.
// In this case, default to ELF unless z/OS specifically provided.
return std::make_unique<TargetLoweringObjectFileELF>();
}
static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
// Static code is suitable for use in a dynamic executable; there is no // Static code is suitable for use in a dynamic executable; there is no
// separate DynamicNoPIC model. // separate DynamicNoPIC model.
@ -160,7 +169,7 @@ SystemZTargetMachine::SystemZTargetMachine(const Target &T, const Triple &TT,
getEffectiveRelocModel(RM), getEffectiveRelocModel(RM),
getEffectiveSystemZCodeModel(CM, getEffectiveRelocModel(RM), JIT), getEffectiveSystemZCodeModel(CM, getEffectiveRelocModel(RM), JIT),
OL), OL),
TLOF(std::make_unique<TargetLoweringObjectFileELF>()) { TLOF(createTLOF(getTargetTriple())) {
initAsmInfo(); initAsmInfo();
} }

View File

@ -0,0 +1,13 @@
; A simple, barebones test to check whether assembly can be emitted
; for the z/OS target
; RUN: llc < %s -mtriple=s390x-ibm-zos | FileCheck %s
@a = global i32 0, align 4
define signext i32 @main() {
; CHECK: .section ".text"
; CHECK: main:
; CHECK: .section "a"
entry:
ret i32 0
}