diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -52,6 +52,7 @@ class MCSection; class MCSectionCOFF; class MCSectionELF; + class MCSectionGOFF; class MCSectionMachO; class MCSectionWasm; class MCSectionXCOFF; @@ -74,7 +75,7 @@ using DiagHandlerTy = std::function &)>; - enum Environment { IsMachO, IsELF, IsCOFF, IsWasm, IsXCOFF }; + enum Environment { IsMachO, IsELF, IsGOFF, IsCOFF, IsWasm, IsXCOFF }; private: Environment Env; @@ -114,6 +115,7 @@ SpecificBumpPtrAllocator COFFAllocator; SpecificBumpPtrAllocator ELFAllocator; SpecificBumpPtrAllocator MachOAllocator; + SpecificBumpPtrAllocator GOFFAllocator; SpecificBumpPtrAllocator WasmAllocator; SpecificBumpPtrAllocator XCOFFAllocator; SpecificBumpPtrAllocator MCInstAllocator; @@ -268,6 +270,16 @@ } }; + struct GOFFSectionKey { + std::string SectionName; + + GOFFSectionKey(StringRef SectionName) : SectionName(SectionName) {} + + bool operator<(const GOFFSectionKey &Other) const { + return SectionName < Other.SectionName; + } + }; + struct WasmSectionKey { std::string SectionName; StringRef GroupName; @@ -323,6 +335,7 @@ StringMap MachOUniquingMap; std::map ELFUniquingMap; std::map COFFUniquingMap; + std::map GOFFUniquingMap; std::map WasmUniquingMap; std::map XCOFFUniquingMap; StringMap RelSecNames; @@ -595,6 +608,8 @@ unsigned Flags, unsigned EntrySize); + MCSectionGOFF *getGOFFSection(StringRef Section, SectionKind Kind); + MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, SectionKind Kind, StringRef COMDATSymName, int Selection, diff --git a/llvm/include/llvm/MC/MCObjectFileInfo.h b/llvm/include/llvm/MC/MCObjectFileInfo.h --- a/llvm/include/llvm/MC/MCObjectFileInfo.h +++ b/llvm/include/llvm/MC/MCObjectFileInfo.h @@ -426,6 +426,7 @@ void initMachOMCObjectFileInfo(const Triple &T); void initELFMCObjectFileInfo(const Triple &T, bool Large); + void initGOFFMCObjectFileInfo(const Triple &T); void initCOFFMCObjectFileInfo(const Triple &T); void initWasmMCObjectFileInfo(const Triple &T); void initXCOFFMCObjectFileInfo(const Triple &T); diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h --- a/llvm/include/llvm/MC/MCSection.h +++ b/llvm/include/llvm/MC/MCSection.h @@ -40,7 +40,14 @@ public: 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. enum BundleLockStateType { diff --git a/llvm/include/llvm/MC/MCSectionGOFF.h b/llvm/include/llvm/MC/MCSectionGOFF.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/MC/MCSectionGOFF.h @@ -0,0 +1,48 @@ +//===-- 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: + virtual ~MCSectionGOFF() {} + + 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 diff --git a/llvm/include/llvm/MC/MCSymbol.h b/llvm/include/llvm/MC/MCSymbol.h --- a/llvm/include/llvm/MC/MCSymbol.h +++ b/llvm/include/llvm/MC/MCSymbol.h @@ -46,6 +46,7 @@ SymbolKindUnset, SymbolKindCOFF, SymbolKindELF, + SymbolKindGOFF, SymbolKindMachO, SymbolKindWasm, SymbolKindXCOFF, @@ -276,6 +277,8 @@ bool isCOFF() const { return Kind == SymbolKindCOFF; } + bool isGOFF() const { return Kind == SymbolKindGOFF; } + bool isMachO() const { return Kind == SymbolKindMachO; } bool isWasm() const { return Kind == SymbolKindWasm; } diff --git a/llvm/include/llvm/MC/MCSymbolGOFF.h b/llvm/include/llvm/MC/MCSymbolGOFF.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/MC/MCSymbolGOFF.h @@ -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 *Name, bool IsTemporary) + : MCSymbol(SymbolKindGOFF, Name, IsTemporary) {} + static bool classof(const MCSymbol *S) { return S->isGOFF(); } +}; +} // end namespace llvm + +#endif diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp --- a/llvm/lib/MC/MCContext.cpp +++ b/llvm/lib/MC/MCContext.cpp @@ -25,6 +25,7 @@ #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCSectionGOFF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionWasm.h" #include "llvm/MC/MCSectionXCOFF.h" @@ -32,6 +33,7 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbolCOFF.h" #include "llvm/MC/MCSymbolELF.h" +#include "llvm/MC/MCSymbolGOFF.h" #include "llvm/MC/MCSymbolMachO.h" #include "llvm/MC/MCSymbolWasm.h" #include "llvm/MC/MCSymbolXCOFF.h" @@ -99,7 +101,7 @@ Env = IsXCOFF; break; case Triple::GOFF: - report_fatal_error("Cannot initialize MC for GOFF object file format"); + Env = IsGOFF; break; case Triple::UnknownObjectFormat: report_fatal_error("Cannot initialize MC for unknown object file format."); @@ -231,6 +233,8 @@ return new (Name, *this) MCSymbolCOFF(Name, IsTemporary); case MCContext::IsELF: return new (Name, *this) MCSymbolELF(Name, IsTemporary); + case MCContext::IsGOFF: + return new (Name, *this) MCSymbolGOFF(Name, IsTemporary); case MCContext::IsMachO: return new (Name, *this) MCSymbolMachO(Name, IsTemporary); case MCContext::IsWasm: @@ -610,6 +614,23 @@ return (I != ELFEntrySizeMap.end()) ? Optional(I->second) : None; } +MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind) { + // Do the lookup. If we have a hit, return it. + auto IterBool = GOFFUniquingMap.insert( + std::make_pair(GOFFSectionKey{Section.str()}, nullptr)); + auto &Entry = *IterBool.first; + if (!IterBool.second) + return Entry.second; + + // Otherwise, return a new section. + StringRef CachedName = Entry.first.SectionName; + MCSectionGOFF *Result = + new (GOFFAllocator.Allocate()) MCSectionGOFF(CachedName, Kind); + Entry.second = Result; + + return Result; +} + MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, unsigned Characteristics, SectionKind Kind, diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -17,6 +17,7 @@ #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSectionCOFF.h" #include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCSectionGOFF.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCSectionWasm.h" #include "llvm/MC/MCSectionXCOFF.h" @@ -504,6 +505,11 @@ 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) { EHFrameSection = Ctx->getCOFFSection(".eh_frame", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | @@ -995,6 +1001,9 @@ case MCContext::IsELF: initELFMCObjectFileInfo(TheTriple, LargeCodeModel); break; + case MCContext::IsGOFF: + initGOFFMCObjectFileInfo(TheTriple); + break; case MCContext::IsWasm: initWasmMCObjectFileInfo(TheTriple); break; diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -782,6 +782,8 @@ case MCContext::IsELF: PlatformParser.reset(createELFAsmParser()); break; + case MCContext::IsGOFF: + report_fatal_error("GOFFAsmParser support not implemented yet"); case MCContext::IsWasm: PlatformParser.reset(createWasmAsmParser()); break; diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -6369,6 +6369,7 @@ case MCContext::IsWasm: CurrentFormat = WASM; break; + case MCContext::IsGOFF: case MCContext::IsXCOFF: llvm_unreachable("unexpected object format"); break; diff --git a/llvm/test/CodeGen/SystemZ/zos-simple-test.ll b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/zos-simple-test.ll @@ -0,0 +1,10 @@ +; 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 + +define signext i32 @main() { +; CHECK-LABEL: main: +; CHECK: lghi 3, 0 +entry: + ret i32 0 +}