179 lines · cpp
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-exception6//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 supported34 AscizDirective = nullptr; // not supported35 CharacterLiteralSyntax = ACLS_SingleQuotePrefix;36 37 // Use .vbyte for data definition to avoid directives that apply an implicit38 // 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, and52 // 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, or58 // 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(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("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("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 "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("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("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 print132 // 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 csect141 // 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 are150 // eligible for .bss/.tbss csect, getKind().isThreadBSS() is used to151 // cover TLS common and zero-initialized local symbols since linkage type152 // (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 commons157 // and zero-initialized TLS data. The '.comm' and '.lcomm' directives of the158 // variable will create the needed csect.159 return;160 }161 162 // Zero-initialized TLS data with weak or external linkage are not eligible to163 // 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("0x%" PRIx32, *Sec.getDwarfSubtypeFlags())172 << '\n';173 OS << Sec.getName() << ':' << '\n';174 return;175 }176 177 report_fatal_error("Printing for this SectionKind is unimplemented.");178}179