mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
f8a477d8bf
Summary: This patch implements the backend implementation of adding global variables directly to the table of contents (TOC), rather than adding the address of the variable to the TOC. Currently, this patch will look for the "toc-data" attribute on symbols in the IR, and then add those symbols to the TOC. ATM, this is implemented for 32 bit AIX. Reviewers: sfertile Differential Revision: https://reviews.llvm.org/D101178
124 lines
4.1 KiB
C++
124 lines
4.1 KiB
C++
//===- lib/MC/MCSectionXCOFF.cpp - XCOFF Code Section Representation ------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/MC/MCSectionXCOFF.h"
|
|
#include "llvm/MC/MCAsmInfo.h"
|
|
#include "llvm/MC/MCExpr.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/Format.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
using namespace llvm;
|
|
|
|
MCSectionXCOFF::~MCSectionXCOFF() = default;
|
|
|
|
void MCSectionXCOFF::printCsectDirective(raw_ostream &OS) const {
|
|
OS << "\t.csect " << QualName->getName() << "," << Log2_32(getAlignment())
|
|
<< '\n';
|
|
}
|
|
|
|
void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
|
|
raw_ostream &OS,
|
|
const MCExpr *Subsection) const {
|
|
if (getKind().isText()) {
|
|
if (getMappingClass() != XCOFF::XMC_PR)
|
|
report_fatal_error("Unhandled storage-mapping class for .text csect");
|
|
|
|
printCsectDirective(OS);
|
|
return;
|
|
}
|
|
|
|
if (getKind().isReadOnly()) {
|
|
if (getMappingClass() != XCOFF::XMC_RO)
|
|
report_fatal_error("Unhandled storage-mapping class for .rodata csect.");
|
|
printCsectDirective(OS);
|
|
return;
|
|
}
|
|
|
|
// Initialized TLS data.
|
|
if (getKind().isThreadData()) {
|
|
// We only expect XMC_TL here for initialized TLS data.
|
|
if (getMappingClass() != XCOFF::XMC_TL)
|
|
report_fatal_error("Unhandled storage-mapping class for .tdata csect.");
|
|
printCsectDirective(OS);
|
|
return;
|
|
}
|
|
|
|
if (getKind().isData()) {
|
|
switch (getMappingClass()) {
|
|
case XCOFF::XMC_RW:
|
|
case XCOFF::XMC_DS:
|
|
case XCOFF::XMC_TD:
|
|
printCsectDirective(OS);
|
|
break;
|
|
case XCOFF::XMC_TC:
|
|
case XCOFF::XMC_TE:
|
|
break;
|
|
case XCOFF::XMC_TC0:
|
|
OS << "\t.toc\n";
|
|
break;
|
|
default:
|
|
report_fatal_error(
|
|
"Unhandled storage-mapping class for .data csect.");
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (isCsect() && getMappingClass() == XCOFF::XMC_TD) {
|
|
assert((getKind().isBSSExtern() || getKind().isBSSLocal()) &&
|
|
"Unexepected section kind for toc-data");
|
|
printCsectDirective(OS);
|
|
return;
|
|
}
|
|
// Common csect type (uninitialized storage) does not have to print csect
|
|
// directive for section switching.
|
|
if (isCsect() && getCSectType() == XCOFF::XTY_CM) {
|
|
assert((getMappingClass() == XCOFF::XMC_RW ||
|
|
getMappingClass() == XCOFF::XMC_BS ||
|
|
getMappingClass() == XCOFF::XMC_UL) &&
|
|
"Generated a storage-mapping class for a common/bss/tbss csect we "
|
|
"don't "
|
|
"understand how to switch to.");
|
|
// Common symbols and local zero-initialized symbols for TLS and Non-TLS are
|
|
// eligible for .bss/.tbss csect, getKind().isThreadBSS() is used to cover
|
|
// TLS common and zero-initialized local symbols since linkage type (in the
|
|
// GlobalVariable) is not accessible in this class.
|
|
assert((getKind().isBSSLocal() || getKind().isCommon() ||
|
|
getKind().isThreadBSS()) &&
|
|
"wrong symbol type for .bss/.tbss csect");
|
|
// Don't have to print a directive for switching to section for commons and
|
|
// zero-initialized TLS data. The '.comm' and '.lcomm' directives of the
|
|
// variable will create the needed csect.
|
|
return;
|
|
}
|
|
|
|
// Zero-initialized TLS data with weak or external linkage are not eligible to
|
|
// be put into common csect.
|
|
if (getKind().isThreadBSS()) {
|
|
printCsectDirective(OS);
|
|
return;
|
|
}
|
|
|
|
// XCOFF debug sections.
|
|
if (getKind().isMetadata() && isDwarfSect()) {
|
|
OS << "\n\t.dwsect "
|
|
<< format("0x%" PRIx32, getDwarfSubtypeFlags().getValue()) << '\n';
|
|
OS << MAI.getPrivateLabelPrefix() << getName() << ':' << '\n';
|
|
return;
|
|
}
|
|
|
|
report_fatal_error("Printing for this SectionKind is unimplemented.");
|
|
}
|
|
|
|
bool MCSectionXCOFF::UseCodeAlign() const { return getKind().isText(); }
|
|
|
|
bool MCSectionXCOFF::isVirtualSection() const {
|
|
assert(isCsect() && "Only csect section can be virtual!");
|
|
return XCOFF::XTY_CM == CsectProp->Type;
|
|
}
|