1//===- MC/MCAsmInfoXCOFF.cpp - XCOFF asm properties ------------ *- 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#include "llvm/MC/MCAsmInfoXCOFF.h"
10#include "llvm/ADT/StringExtras.h"
11#include "llvm/MC/MCAsmInfo.h"
12#include "llvm/MC/MCSectionXCOFF.h"
13#include "llvm/Support/CommandLine.h"
14#include "llvm/Support/Format.h"
15#include "llvm/Support/raw_ostream.h"
16
17using namespace llvm;
18
19namespace llvm {
20extern cl::opt<cl::boolOrDefault> UseLEB128Directives;
21}
22
23MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
24 IsAIX = true;
25 IsLittleEndian = false;
26
27 PrivateGlobalPrefix = "L..";
28 PrivateLabelPrefix = "L..";
29 SupportsQuotedNames = false;
30 if (UseLEB128Directives == cl::BOU_UNSET)
31 HasLEB128Directives = false;
32 ZeroDirective = "\t.space\t";
33 AsciiDirective = nullptr; // not supported
34 AscizDirective = nullptr; // not supported
35 CharacterLiteralSyntax = ACLS_SingleQuotePrefix;
36
37 // Use .vbyte for data definition to avoid directives that apply an implicit
38 // alignment.
39 Data16bitsDirective = "\t.vbyte\t2, ";
40 Data32bitsDirective = "\t.vbyte\t4, ";
41
42 COMMDirectiveAlignmentIsInBytes = false;
43 LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
44 HasDotTypeDotSizeDirective = false;
45 ParseInlineAsmUsingAsmParser = true;
46
47 ExceptionsType = ExceptionHandling::AIX;
48}
49
50bool MCAsmInfoXCOFF::isAcceptableChar(char C) const {
51 // QualName is allowed for a MCSymbolXCOFF, and
52 // QualName contains '[' and ']'.
53 if (C == '[' || C == ']')
54 return true;
55
56 // For AIX assembler, symbols may consist of numeric digits,
57 // underscores, periods, uppercase or lowercase letters, or
58 // any combination of these.
59 return isAlnum(C) || C == '_' || C == '.';
60}
61
62bool MCAsmInfoXCOFF::useCodeAlign(const MCSection &Sec) const {
63 return static_cast<const MCSectionXCOFF &>(Sec).getKind().isText();
64}
65
66MCSectionXCOFF::~MCSectionXCOFF() = default;
67
68void MCSectionXCOFF::printCsectDirective(raw_ostream &OS) const {
69 OS << "\t.csect " << QualName->getName() << "," << Log2(A: getAlign()) << '\n';
70}
71
72void MCAsmInfoXCOFF::printSwitchToSection(const MCSection &Section, uint32_t,
73 const Triple &T,
74 raw_ostream &OS) const {
75 auto &Sec = static_cast<const MCSectionXCOFF &>(Section);
76 if (Sec.getKind().isText()) {
77 if (Sec.getMappingClass() != XCOFF::XMC_PR)
78 report_fatal_error(reason: "Unhandled storage-mapping class for .text csect");
79
80 Sec.printCsectDirective(OS);
81 return;
82 }
83
84 if (Sec.getKind().isReadOnly()) {
85 if (Sec.getMappingClass() != XCOFF::XMC_RO &&
86 Sec.getMappingClass() != XCOFF::XMC_TD)
87 report_fatal_error(reason: "Unhandled storage-mapping class for .rodata csect.");
88 Sec.printCsectDirective(OS);
89 return;
90 }
91
92 if (Sec.getKind().isReadOnlyWithRel()) {
93 if (Sec.getMappingClass() != XCOFF::XMC_RW &&
94 Sec.getMappingClass() != XCOFF::XMC_RO &&
95 Sec.getMappingClass() != XCOFF::XMC_TD)
96 report_fatal_error(
97 reason: "Unexepected storage-mapping class for ReadOnlyWithRel kind");
98 Sec.printCsectDirective(OS);
99 return;
100 }
101
102 // Initialized TLS data.
103 if (Sec.getKind().isThreadData()) {
104 // We only expect XMC_TL here for initialized TLS data.
105 if (Sec.getMappingClass() != XCOFF::XMC_TL)
106 report_fatal_error(reason: "Unhandled storage-mapping class for .tdata csect.");
107 Sec.printCsectDirective(OS);
108 return;
109 }
110
111 if (Sec.getKind().isData()) {
112 switch (Sec.getMappingClass()) {
113 case XCOFF::XMC_RW:
114 case XCOFF::XMC_DS:
115 case XCOFF::XMC_TD:
116 Sec.printCsectDirective(OS);
117 break;
118 case XCOFF::XMC_TC:
119 case XCOFF::XMC_TE:
120 break;
121 case XCOFF::XMC_TC0:
122 OS << "\t.toc\n";
123 break;
124 default:
125 report_fatal_error(reason: "Unhandled storage-mapping class for .data csect.");
126 }
127 return;
128 }
129
130 if (Sec.isCsect() && Sec.getMappingClass() == XCOFF::XMC_TD) {
131 // Common csect type (uninitialized storage) does not have to print
132 // csect directive for section switching unless it is local.
133 if (Sec.getKind().isCommon() && !Sec.getKind().isBSSLocal())
134 return;
135
136 assert(Sec.getKind().isBSS() && "Unexpected section kind for toc-data");
137 Sec.printCsectDirective(OS);
138 return;
139 }
140 // Common csect type (uninitialized storage) does not have to print csect
141 // directive for section switching.
142 if (Sec.isCsect() && Sec.getCSectType() == XCOFF::XTY_CM) {
143 assert((Sec.getMappingClass() == XCOFF::XMC_RW ||
144 Sec.getMappingClass() == XCOFF::XMC_BS ||
145 Sec.getMappingClass() == XCOFF::XMC_UL) &&
146 "Generated a storage-mapping class for a common/bss/tbss csect we "
147 "don't "
148 "understand how to switch to.");
149 // Common symbols and local zero-initialized symbols for TLS and Non-TLS are
150 // eligible for .bss/.tbss csect, getKind().isThreadBSS() is used to
151 // cover TLS common and zero-initialized local symbols since linkage type
152 // (in the GlobalVariable) is not accessible in this class.
153 assert((Sec.getKind().isBSSLocal() || Sec.getKind().isCommon() ||
154 Sec.getKind().isThreadBSS()) &&
155 "wrong symbol type for .bss/.tbss csect");
156 // Don't have to print a directive for switching to section for commons
157 // and zero-initialized TLS data. The '.comm' and '.lcomm' directives of the
158 // variable will create the needed csect.
159 return;
160 }
161
162 // Zero-initialized TLS data with weak or external linkage are not eligible to
163 // be put into common csect.
164 if (Sec.getKind().isThreadBSS()) {
165 Sec.printCsectDirective(OS);
166 return;
167 }
168
169 // XCOFF debug sections.
170 if (Sec.getKind().isMetadata() && Sec.isDwarfSect()) {
171 OS << "\n\t.dwsect " << format(Fmt: "0x%" PRIx32, Vals: *Sec.getDwarfSubtypeFlags())
172 << '\n';
173 OS << Sec.getName() << ':' << '\n';
174 return;
175 }
176
177 report_fatal_error(reason: "Printing for this SectionKind is unimplemented.");
178}
179