Skip to content

Commit 74e804c

Browse files
committed
Emit CSECT/CATTR
This adds the logic to emit the CSECT and CATTR assembler instructions.
1 parent 5d522fd commit 74e804c

File tree

10 files changed

+175
-38
lines changed

10 files changed

+175
-38
lines changed

llvm/include/llvm/MC/MCSectionGOFF.h

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,34 +42,23 @@ class MCSectionGOFF final : public MCSection {
4242
// generate an error in this case.
4343
unsigned RequiresNonZeroLength : 1;
4444

45+
// Set to true if the section definition was already emitted.
46+
mutable unsigned Emitted : 1;
47+
4548
friend class MCContext;
49+
friend class MCSymbolGOFF;
4650
MCSectionGOFF(StringRef Name, SectionKind K, GOFF::ESDSymbolType SymbolType,
4751
GOFF::SDAttr SDAttributes, GOFF::EDAttr EDAttributes,
4852
GOFF::PRAttr PRAttributes, MCSectionGOFF *Parent = nullptr)
4953
: MCSection(SV_GOFF, Name, K.isText(), /*IsVirtual=*/false, nullptr),
5054
Parent(Parent), SDAttributes(SDAttributes), EDAttributes(EDAttributes),
51-
PRAttributes(PRAttributes), SymbolType(SymbolType) {}
55+
PRAttributes(PRAttributes), SymbolType(SymbolType),
56+
RequiresNonZeroLength(0), Emitted(0) {}
5257

5358
public:
5459
void printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
5560
raw_ostream &OS,
56-
uint32_t Subsection) const override {
57-
switch (SymbolType) {
58-
case GOFF::ESD_ST_SectionDefinition:
59-
OS << Name << " CSECT\n";
60-
break;
61-
case GOFF::ESD_ST_ElementDefinition:
62-
getParent()->printSwitchToSection(MAI, T, OS, Subsection);
63-
OS << Name << " CATTR\n";
64-
break;
65-
case GOFF::ESD_ST_PartReference:
66-
getParent()->printSwitchToSection(MAI, T, OS, Subsection);
67-
OS << Name << " XATTR\n";
68-
break;
69-
default:
70-
llvm_unreachable("Wrong section type");
71-
}
72-
}
61+
uint32_t Subsection) const override;
7362

7463
bool useCodeAlign() const override { return false; }
7564

@@ -100,7 +89,6 @@ class MCSectionGOFF final : public MCSection {
10089
return PRAttributes;
10190
}
10291

103-
void setRequiresNonZeroLength() { RequiresNonZeroLength = true; }
10492
bool requiresNonZeroLength() const { return RequiresNonZeroLength; }
10593

10694
void setName(StringRef SectionName) { Name = SectionName; }

llvm/include/llvm/MC/MCSymbolGOFF.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ class MCSymbolGOFF : public MCSymbol {
4242
GOFF::LDAttr getLDAttributes() const { return LDAttributes; }
4343
bool hasLDAttributes() const { return getFlags() & SF_LD; }
4444

45-
void setADA(MCSectionGOFF *AssociatedDataArea) { ADA = AssociatedDataArea; }
45+
void setADA(MCSectionGOFF *AssociatedDataArea) {
46+
ADA = AssociatedDataArea;
47+
AssociatedDataArea->RequiresNonZeroLength = true;
48+
}
4649
MCSectionGOFF *getADA() const { return ADA; }
4750

4851
static bool classof(const MCSymbol *S) { return S->isGOFF(); }

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2765,14 +2765,15 @@ TargetLoweringObjectFileGOFF::TargetLoweringObjectFileGOFF() = default;
27652765
void TargetLoweringObjectFileGOFF::getModuleMetadata(Module &M) {
27662766
// Construct the default names for the root SD and the ADA PR symbol.
27672767
StringRef FileName = sys::path::stem(M.getSourceFileName());
2768+
if (FileName.size() > 1 && FileName.starts_with('<') &&
2769+
FileName.ends_with('>'))
2770+
FileName = FileName.substr(1, FileName.size() - 2);
27682771
DefaultRootSDName = Twine(FileName).concat("#C").str();
27692772
DefaultADAPRName = Twine(FileName).concat("#S").str();
27702773
MCSectionGOFF *RootSD = static_cast<MCSectionGOFF *>(RootSDSection);
27712774
MCSectionGOFF *ADAPR = static_cast<MCSectionGOFF *>(ADASection);
27722775
RootSD->setName(DefaultRootSDName);
27732776
ADAPR->setName(DefaultADAPRName);
2774-
// The length of the ADA needs to be adjusted in case it is 0.
2775-
ADAPR->setRequiresNonZeroLength();
27762777
// Initialize the label for the text section.
27772778
MCSymbolGOFF *TextLD = static_cast<MCSymbolGOFF *>(
27782779
getContext().getOrCreateSymbol(RootSD->getName()));

llvm/lib/MC/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ add_llvm_component_library(LLVMMC
4646
MCSectionCOFF.cpp
4747
MCSectionDXContainer.cpp
4848
MCSectionELF.cpp
49+
MCSectionGOFF.cpp
4950
MCSectionMachO.cpp
5051
MCSectionWasm.cpp
5152
MCSectionXCOFF.cpp

llvm/lib/MC/MCSectionGOFF.cpp

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
//===- MCSectionGOFF.cpp - GOFF Code Section Representation ---------------===//
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+
#include "llvm/MC/MCSectionGOFF.h"
10+
#include "llvm/BinaryFormat/GOFF.h"
11+
#include "llvm/Support/raw_ostream.h"
12+
13+
using namespace llvm;
14+
15+
namespace {
16+
void emitRMode(raw_ostream &OS, GOFF::ESDRmode Rmode, bool UseParenthesis) {
17+
if (Rmode != GOFF::ESD_RMODE_None) {
18+
OS << "RMODE" << (UseParenthesis ? '(' : ' ');
19+
switch (Rmode) {
20+
case GOFF::ESD_RMODE_24:
21+
OS << "24";
22+
break;
23+
case GOFF::ESD_RMODE_31:
24+
OS << "31";
25+
break;
26+
case GOFF::ESD_RMODE_64:
27+
OS << "64";
28+
break;
29+
case GOFF::ESD_RMODE_None:
30+
break;
31+
}
32+
if (UseParenthesis)
33+
OS << ')';
34+
}
35+
}
36+
37+
void emitCATTR(raw_ostream &OS, StringRef Name, StringRef ParentName,
38+
bool EmitAmodeAndRmode, GOFF::ESDAmode Amode,
39+
GOFF::ESDRmode Rmode, GOFF::ESDAlignment Alignment,
40+
GOFF::ESDLoadingBehavior LoadBehavior,
41+
GOFF::ESDExecutable Executable, bool IsReadOnly,
42+
StringRef PartName) {
43+
if (EmitAmodeAndRmode && Amode != GOFF::ESD_AMODE_None) {
44+
OS << ParentName << " AMODE ";
45+
switch (Amode) {
46+
case GOFF::ESD_AMODE_24:
47+
OS << "24";
48+
break;
49+
case GOFF::ESD_AMODE_31:
50+
OS << "31";
51+
break;
52+
case GOFF::ESD_AMODE_ANY:
53+
OS << "ANY";
54+
break;
55+
case GOFF::ESD_AMODE_64:
56+
OS << "64";
57+
break;
58+
case GOFF::ESD_AMODE_MIN:
59+
OS << "ANY64";
60+
break;
61+
case GOFF::ESD_AMODE_None:
62+
break;
63+
}
64+
OS << "\n";
65+
}
66+
if (EmitAmodeAndRmode && Rmode != GOFF::ESD_RMODE_None) {
67+
OS << ParentName << ' ';
68+
emitRMode(OS, Rmode, /*UseParenthesis=*/false);
69+
OS << "\n";
70+
}
71+
OS << Name << " CATTR ";
72+
OS << "ALIGN(" << static_cast<unsigned>(Alignment) << ")";
73+
switch (LoadBehavior) {
74+
case GOFF::ESD_LB_Deferred:
75+
OS << ",DEFLOAD";
76+
break;
77+
case GOFF::ESD_LB_NoLoad:
78+
OS << ",NOLOAD";
79+
break;
80+
default:
81+
break;
82+
}
83+
switch (Executable) {
84+
case GOFF::ESD_EXE_CODE:
85+
OS << ",EXECUTABLE";
86+
break;
87+
case GOFF::ESD_EXE_DATA:
88+
OS << ",NOTEXECUTABLE";
89+
break;
90+
default:
91+
break;
92+
}
93+
if (IsReadOnly)
94+
OS << ",READONLY";
95+
if (Rmode != GOFF::ESD_RMODE_None) {
96+
OS << ',';
97+
emitRMode(OS, Rmode, /*UseParenthesis=*/true);
98+
}
99+
if (!PartName.empty())
100+
OS << ",PART(" << PartName << ")";
101+
OS << '\n';
102+
}
103+
} // namespace
104+
105+
void MCSectionGOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
106+
raw_ostream &OS,
107+
uint32_t Subsection) const {
108+
switch (SymbolType) {
109+
case GOFF::ESD_ST_SectionDefinition: {
110+
OS << Name << " CSECT\n";
111+
Emitted = true;
112+
break;
113+
}
114+
case GOFF::ESD_ST_ElementDefinition: {
115+
bool ParentEmitted = getParent()->Emitted;
116+
getParent()->printSwitchToSection(MAI, T, OS, Subsection);
117+
if (!Emitted) {
118+
emitCATTR(OS, Name, getParent()->getName(), !ParentEmitted,
119+
EDAttributes.Amode, EDAttributes.Rmode, EDAttributes.Alignment,
120+
EDAttributes.LoadBehavior, EDAttributes.Executable,
121+
EDAttributes.IsReadOnly, StringRef());
122+
Emitted = true;
123+
} else
124+
OS << Name << " CATTR ,\n";
125+
break;
126+
}
127+
case GOFF::ESD_ST_PartReference: {
128+
MCSectionGOFF *ED = getParent();
129+
bool SDEmitted = ED->getParent()->Emitted;
130+
ED->getParent()->printSwitchToSection(MAI, T, OS, Subsection);
131+
if (!Emitted) {
132+
emitCATTR(OS, ED->getName(), ED->getParent()->getName(), !SDEmitted,
133+
PRAttributes.Amode, getParent()->EDAttributes.Rmode,
134+
PRAttributes.Alignment, getParent()->EDAttributes.LoadBehavior,
135+
PRAttributes.Executable, PRAttributes.IsReadOnly, Name);
136+
ED->Emitted = true;
137+
Emitted = true;
138+
} else
139+
OS << ED->getName() << " CATTR ,\n";
140+
break;
141+
}
142+
default:
143+
llvm_unreachable("Wrong section type");
144+
}
145+
}

llvm/test/CodeGen/SystemZ/zos-ada-relocations.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,8 @@ entry:
5555

5656
declare signext i32 @callout(i32 signext)
5757

58-
; CHECK: #C CSECT
59-
; CHECK: C_WSA64 CATTR
60-
; CHECK: #S XATTR
58+
; CHECK: stdin#C CSECT
59+
; CHECK: C_WSA64 CATTR ALIGN(4),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(stdin#S)
6160
; CHECK: .set L#DoFunc@indirect0, DoFunc
6261
; CHECK: .indirect_symbol L#DoFunc@indirect0
6362
; CHECK: .quad V(L#DoFunc@indirect0) * Offset 0 pointer to function descriptor DoFunc

llvm/test/CodeGen/SystemZ/zos-intrinsics.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@ declare double @llvm.sin.f64(double)
3030
declare fp128 @llvm.exp2.f128(fp128)
3131

3232
; Check the calls in the ADA.
33-
; CHECK: #C CSECT
34-
; CHECK: C_WSA64 CATTR
35-
; CHECK: #S XATTR
33+
; CHECK: stdin#C CSECT
34+
; CHECK: C_WSA64 CATTR ALIGN(4),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(stdin#S)
3635

3736
; Check that there is no call to sqrt.
3837
; CHECK-NOT: .quad R(@@WSQT@B)

llvm/test/CodeGen/SystemZ/zos-landingpad.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ lpad:
3737
; CHECK: Personality routine
3838
; CHECK: LSDA location
3939
; Check that the exception table is emitted into .lsda section.
40-
; CHECK: <stdin>#C CSECT
41-
; CHECK: C_WSA64 CATTR
42-
; CHECK: .gcc_exception_table.test1 XATTR
40+
; CHECK: stdin#C CSECT
41+
; CHECK: C_WSA64 CATTR ALIGN(2),DEFLOAD,RMODE(64),PART(.gcc_exception_table.test1)
4342
; CHECK: GCC_except_table0:

llvm/test/CodeGen/SystemZ/zos-simple-test.ll

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
@a = global i32 0, align 4
66

77
define signext i32 @main() {
8-
; CHECK: <stdin>#C CSECT
9-
; CHECK: C_CODE64 CATTR
8+
; CHECK: stdin#C CSECT
9+
; CHECK: stdin#C AMODE 64
10+
; CHECK: stdin#C RMODE 64
11+
; CHECK: C_CODE64 CATTR ALIGN(3),EXECUTABLE,READONLY,RMODE(64)
1012
; CHECK: main:
11-
; CHECK: <stdin>#C CSECT
12-
; CHECK: C_WSA64 CATTR
13-
; CHECK: a XATTR
13+
; CHECK: stdin#C CSECT
14+
; CHECK: C_WSA64 CATTR ALIGN(4),DEFLOAD,NOTEXECUTABLE,RMODE(64),PART(a)
15+
; CHECK: a:
1416
entry:
1517
ret i32 0
1618
}

llvm/test/MC/GOFF/ppa1.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
; CHECK: * Bit 1: 1 = Leaf function
1313
; CHECK: * Bit 2: 0 = Does not use alloca
1414
; CHECK: L#func_end0:
15-
; CHECK: <stdin>#C CSECT
16-
; CHECK: C_CODE64 CATTR
15+
; CHECK: stdin#C CSECT
16+
; CHECK: C_CODE64 CATTR ,
1717
; CHECK: L#PPA1_void_test_0: * PPA1
1818
; CHECK: .byte 2 * Version
1919
; CHECK: .byte 206 * LE Signature X'CE'

0 commit comments

Comments
 (0)