mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
Enable assembly output of local commons for AIX
Summary: This patch enable assembly output of local commons for AIX using .lcomm directives. Adds a EmitXCOFFLocalCommonSymbol to MCStreamer so we can emit the AIX version of .lcomm assembly directives which include a csect name. Handle the case of BSS locals in PPCAIXAsmPrinter by using EmitXCOFFLocalCommonSymbol. Adds a test for generating .lcomm on AIX Targets. Reviewers: cebowleratibm, hubert.reinterpretcast, Xiangling_L, jasonliu, sfertile Reviewed By: sfertile Subscribers: wuzish, nemanjai, hiraditya, kbarton, MaskRay, jsji, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D64825 llvm-svn: 368306
This commit is contained in:
parent
b937fefeae
commit
fb66d80ccb
@ -537,6 +537,15 @@ public:
|
||||
/// \param Symbol - Symbol the image relative relocation should point to.
|
||||
virtual void EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset);
|
||||
|
||||
/// Emits an lcomm directive with XCOFF csect information.
|
||||
///
|
||||
/// \param Symbol - The symbol we are emiting.
|
||||
/// \param Size - The size of the block of storage.
|
||||
/// \param ByteAlignment - The alignment of the symbol in bytes. Must be a power
|
||||
/// of 2.
|
||||
virtual void EmitXCOFFLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||
unsigned ByteAlignment);
|
||||
|
||||
/// Emit an ELF .size directive.
|
||||
///
|
||||
/// This corresponds to an assembler statement such as:
|
||||
|
@ -26,6 +26,8 @@ public:
|
||||
uint64_t Size = 0, unsigned ByteAlignment = 0,
|
||||
SMLoc Loc = SMLoc()) override;
|
||||
void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
|
||||
void EmitXCOFFLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||
unsigned ByteAlign) override;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -1836,11 +1836,12 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(
|
||||
|
||||
// Common symbols go into a csect with matching name which will get mapped
|
||||
// into the .bss section.
|
||||
if (Kind.isCommon()) {
|
||||
if (Kind.isBSSLocal() || Kind.isCommon()) {
|
||||
SmallString<128> Name;
|
||||
getNameWithPrefix(Name, GO, TM);
|
||||
return getContext().getXCOFFSection(Name, XCOFF::XMC_RW, XCOFF::XTY_CM,
|
||||
Kind, /* BeginSymbolName */ nullptr);
|
||||
return getContext().getXCOFFSection(
|
||||
Name, Kind.isBSSLocal() ? XCOFF::XMC_BS : XCOFF::XMC_RW, XCOFF::XTY_CM,
|
||||
Kind, /* BeginSymbolName */ nullptr);
|
||||
}
|
||||
|
||||
if (Kind.isText())
|
||||
|
@ -16,4 +16,5 @@ MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
|
||||
IsLittleEndian = false;
|
||||
HasDotTypeDotSizeDirective = false;
|
||||
COMMDirectiveAlignmentIsInBytes = false;
|
||||
LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
|
||||
}
|
||||
|
@ -162,6 +162,8 @@ public:
|
||||
void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
|
||||
void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
|
||||
void EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override;
|
||||
void EmitXCOFFLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||
unsigned ByteAlign) override;
|
||||
void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
|
||||
void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||
unsigned ByteAlignment) override;
|
||||
@ -757,6 +759,24 @@ void MCAsmStreamer::EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
// We need an XCOFF specific version of this directive as the AIX syntax
|
||||
// requires a QualName argument identifying the csect name and storage mapping
|
||||
// class to appear before the alignment if we are specifying it.
|
||||
void MCAsmStreamer::EmitXCOFFLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||
unsigned ByteAlignment) {
|
||||
assert(MAI->getLCOMMDirectiveAlignmentType() == LCOMM::Log2Alignment &&
|
||||
"We only support writing log base-2 alignment format with XCOFF");
|
||||
assert(isPowerOf2_32(ByteAlignment) && "alignment must be a power of 2");
|
||||
|
||||
OS << "\t.lcomm\t";
|
||||
Symbol->print(OS, MAI);
|
||||
OS << ',' << Size;
|
||||
OS << ',' << Symbol->getName();
|
||||
OS << ',' << Log2_32(ByteAlignment);
|
||||
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
|
||||
assert(MAI->hasDotTypeDotSizeDirective());
|
||||
OS << "\t.size\t";
|
||||
|
@ -28,9 +28,11 @@ void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
|
||||
return;
|
||||
}
|
||||
|
||||
if (getKind().isCommon()) {
|
||||
if (getMappingClass() != XCOFF::XMC_RW)
|
||||
llvm_unreachable("Unsupported storage-mapping class for common csect");
|
||||
if (getKind().isBSSLocal() || getKind().isCommon()) {
|
||||
if (getMappingClass() != XCOFF::XMC_RW &&
|
||||
getMappingClass() != XCOFF::XMC_BS)
|
||||
llvm_unreachable("Generated a storage-mapping class for a common/bss "
|
||||
"csect we don't understand how to switch to.");
|
||||
if (getCSectType() != XCOFF::XTY_CM)
|
||||
llvm_unreachable("wrong csect type for .bss csect");
|
||||
// Don't have to print a directive for switching to section for commons.
|
||||
|
@ -1055,6 +1055,10 @@ void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
|
||||
void MCStreamer::EmitCOFFSymbolType(int Type) {
|
||||
llvm_unreachable("this directive only supported on COFF targets");
|
||||
}
|
||||
void MCStreamer::EmitXCOFFLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||
unsigned ByteAlign) {
|
||||
llvm_unreachable("this directive only supported on XCOFF targets");
|
||||
}
|
||||
void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
|
||||
void MCStreamer::emitELFSymverDirective(StringRef AliasName,
|
||||
const MCSymbol *Aliasee) {}
|
||||
|
@ -57,3 +57,8 @@ MCStreamer *llvm::createXCOFFStreamer(MCContext &Context,
|
||||
S->getAssembler().setRelaxAll(true);
|
||||
return S;
|
||||
}
|
||||
|
||||
void MCXCOFFStreamer::EmitXCOFFLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||
unsigned ByteAlign) {
|
||||
llvm_unreachable("Not implemented yet.");
|
||||
}
|
@ -1659,7 +1659,7 @@ void PPCAIXAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
|
||||
report_fatal_error("COMDAT not yet supported by AIX.");
|
||||
|
||||
SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
|
||||
if (!GVKind.isCommon())
|
||||
if (!GVKind.isCommon() && !GVKind.isBSSLocal())
|
||||
report_fatal_error("Only common variables are supported on AIX for now.");
|
||||
|
||||
// Create the containing csect and switch to it.
|
||||
@ -1673,7 +1673,11 @@ void PPCAIXAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
|
||||
unsigned Align =
|
||||
GV->getAlignment() ? GV->getAlignment() : DL.getPreferredAlignment(GV);
|
||||
uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType());
|
||||
OutStreamer->EmitCommonSymbol(XSym, Size, Align);
|
||||
|
||||
if (GVKind.isBSSLocal())
|
||||
OutStreamer->EmitXCOFFLocalCommonSymbol(XSym, Size, Align);
|
||||
else
|
||||
OutStreamer->EmitCommonSymbol(XSym, Size, Align);
|
||||
}
|
||||
|
||||
/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
|
||||
|
10
test/CodeGen/PowerPC/aix-xcoff-lcomm.ll
Normal file
10
test/CodeGen/PowerPC/aix-xcoff-lcomm.ll
Normal file
@ -0,0 +1,10 @@
|
||||
; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s
|
||||
; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s
|
||||
|
||||
@a = internal global i32 0, align 4
|
||||
@b = internal global i64 0, align 8
|
||||
@c = internal global i16 0, align 2
|
||||
|
||||
; CHECK: .lcomm a,4,a,2
|
||||
; CHECK-NEXT: .lcomm b,8,b,3
|
||||
; CHECK-NEXT: .lcomm c,2,c,1
|
Loading…
Reference in New Issue
Block a user