llvm.org GIT mirror llvm / 325fca6
[PowerPC][AIX] Adds support for writing the .data section in assembly files Summary: Adds support for generating the .data section in assembly files for global variables with a non-zero initialization. The support for writing the .data section in XCOFF object files will be added in a follow-on patch. Any relocations are not included in this patch. Reviewers: hubert.reinterpretcast, sfertile, jasonliu, daltenty, Xiangling_L Reviewed by: hubert.reinterpretcast Subscribers: nemanjai, hiraditya, kbarton, MaskRay, jsji, wuzish, shchenz, DiggerLin, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D66154 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369869 91177308-0d34-0410-b5e6-96231b3b80d8 Xing Xue 21 days ago
10 changed file(s) with 131 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
634634 /// supported by the target.
635635 void EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const;
636636
637 /// Return the alignment in log2 form for the specified \p GV.
638 static unsigned getGVAlignmentLog2(const GlobalValue *GV,
639 const DataLayout &DL,
640 unsigned InBits = 0);
641
637642 private:
638643 /// Private state for PrintSpecial()
639644 // Assign a unique ID to this machine instruction.
163163 /// ".data_region/.end_data_region" directives. If false, use "$d/$a" labels
164164 /// instead.
165165 bool UseDataRegionDirectives = false;
166
167 /// True if .align is to be used for alignment. Only power-of-two
168 /// alignment is supported.
169 bool UseDotAlignForAlignment = false;
166170
167171 //===--- Data Emission Directives -------------------------------------===//
168172
519523 return UseDataRegionDirectives;
520524 }
521525
526 bool useDotAlignForAlignment() const {
527 return UseDotAlignForAlignment;
528 }
529
522530 const char *getZeroDirective() const { return ZeroDirective; }
523531 const char *getAsciiDirective() const { return AsciiDirective; }
524532 const char *getAscizDirective() const { return AscizDirective; }
161161 /// getGVAlignmentLog2 - Return the alignment to use for the specified global
162162 /// value in log2 form. This rounds up to the preferred alignment if possible
163163 /// and legal.
164 static unsigned getGVAlignmentLog2(const GlobalValue *GV, const DataLayout &DL,
165 unsigned InBits = 0) {
164 unsigned AsmPrinter::getGVAlignmentLog2(const GlobalValue *GV,
165 const DataLayout &DL,
166 unsigned InBits) {
166167 unsigned NumBits = 0;
167168 if (const GlobalVariable *GVar = dyn_cast(GV))
168169 NumBits = DL.getPreferredAlignmentLog(GVar);
18481848 if (Kind.isText())
18491849 return TextSection;
18501850
1851 if (Kind.isData())
1852 return DataSection;
1853
18511854 report_fatal_error("XCOFF other section types not yet implemented.");
18521855 }
18531856
1616 HasDotTypeDotSizeDirective = false;
1717 COMMDirectiveAlignmentIsInBytes = false;
1818 LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
19 UseDotAlignForAlignment = true;
20 AsciiDirective = nullptr; // not supported
21 AscizDirective = nullptr; // not supported
22 Data64bitsDirective = "\t.llong\t";
1923 }
11181118 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
11191119 unsigned ValueSize,
11201120 unsigned MaxBytesToEmit) {
1121 if (MAI->useDotAlignForAlignment()) {
1122 if (!isPowerOf2_32(ByteAlignment))
1123 report_fatal_error("Only power-of-two alignments are supported "
1124 "with .align.");
1125 OS << "\t.align\t";
1126 OS << Log2_32(ByteAlignment);
1127 EmitEOL();
1128 return;
1129 }
1130
11211131 // Some assemblers don't support non-power of two alignments, so we always
11221132 // emit alignments as a power of two if possible.
11231133 if (isPowerOf2_32(ByteAlignment)) {
769769 TextSection = Ctx->getXCOFFSection(
770770 ".text", XCOFF::StorageMappingClass::XMC_PR, XCOFF::XTY_SD,
771771 XCOFF::C_HIDEXT, SectionKind::getText());
772
773 DataSection = Ctx->getXCOFFSection(
774 ".data", XCOFF::StorageMappingClass::XMC_RW, XCOFF::XTY_SD,
775 XCOFF::C_HIDEXT, SectionKind::getData());
772776 }
773777
774778 void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,
2727 return;
2828 }
2929
30 if (getKind().isData()) {
31 assert(getMappingClass() == XCOFF::XMC_RW &&
32 "Unhandled storage-mapping class for data section.");
33
34 OS << "\t.csect " << getSectionName() << "["
35 << "RW"
36 << "]" << '\n';
37 return;
38 }
39
3040 if (getKind().isBSSLocal() || getKind().isCommon()) {
3141 assert((getMappingClass() == XCOFF::XMC_RW ||
3242 getMappingClass() == XCOFF::XMC_BS) &&
16581658 report_fatal_error("COMDAT not yet supported by AIX.");
16591659
16601660 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
1661 if (!GVKind.isCommon() && !GVKind.isBSSLocal())
1662 report_fatal_error("Only common variables are supported on AIX for now.");
1661 if (!GVKind.isCommon() && !GVKind.isBSSLocal() && !GVKind.isData())
1662 report_fatal_error("Encountered a global variable kind that is "
1663 "not supported yet.");
16631664
16641665 // Create the containing csect and switch to it.
16651666 MCSectionXCOFF *CSect = cast(
16671668 OutStreamer->SwitchSection(CSect);
16681669
16691670 // Create the symbol, set its storage class, and emit it.
1670 MCSymbolXCOFF *XSym = cast(getSymbol(GV));
1671 XSym->setStorageClass(
1671 MCSymbolXCOFF *GVSym = cast(getSymbol(GV));
1672 GVSym->setStorageClass(
16721673 TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV));
1673 XSym->setContainingCsect(CSect);
1674 GVSym->setContainingCsect(CSect);
16741675
16751676 const DataLayout &DL = GV->getParent()->getDataLayout();
1676 unsigned Align =
1677
1678 // Handle common symbols.
1679 if (GVKind.isCommon() || GVKind.isBSSLocal()) {
1680 unsigned Align =
16771681 GV->getAlignment() ? GV->getAlignment() : DL.getPreferredAlignment(GV);
1678 uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType());
1679
1680 if (GVKind.isBSSLocal())
1681 OutStreamer->EmitXCOFFLocalCommonSymbol(XSym, Size, Align);
1682 else
1683 OutStreamer->EmitCommonSymbol(XSym, Size, Align);
1682 uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType());
1683
1684 if (GVKind.isBSSLocal())
1685 OutStreamer->EmitXCOFFLocalCommonSymbol(GVSym, Size, Align);
1686 else
1687 OutStreamer->EmitCommonSymbol(GVSym, Size, Align);
1688 return;
1689 }
1690
1691 // Get the alignment in the log2 form.
1692 const unsigned AlignLog = getGVAlignmentLog2(GV, DL);
1693
1694 MCSymbol *EmittedInitSym = GVSym;
1695 EmitLinkage(GV, EmittedInitSym);
1696 EmitAlignment(AlignLog, GV);
1697 OutStreamer->EmitLabel(EmittedInitSym);
1698 EmitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());
16841699 }
16851700
16861701 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
0 ; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s
1 ; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s
2
3 @ivar = local_unnamed_addr global i32 35, align 4
4 @llvar = local_unnamed_addr global i64 36, align 8
5 @svar = local_unnamed_addr global i16 37, align 2
6 @fvar = local_unnamed_addr global float 8.000000e+02, align 4
7 @dvar = local_unnamed_addr global double 9.000000e+02, align 8
8 @over_aligned = local_unnamed_addr global double 9.000000e+02, align 32
9 @charr = local_unnamed_addr global [4 x i8] c"abcd", align 1
10 @dblarr = local_unnamed_addr global [4 x double] [double 1.000000e+00, double 2.000000e+00, double 3.000000e+00, double 4.000000e+00], align 8
11
12 ; CHECK: .csect .data[RW]
13 ; CHECK-NEXT: .globl ivar
14 ; CHECK-NEXT: .align 2
15 ; CHECK-NEXT: ivar:
16 ; CHECK-NEXT: .long 35
17
18 ; CHECK: .globl llvar
19 ; CHECK-NEXT: .align 3
20 ; CHECK-NEXT: llvar:
21 ; CHECK-NEXT: .llong 36
22
23 ; CHECK: .globl svar
24 ; CHECK-NEXT: .align 1
25 ; CHECK-NEXT: svar:
26 ; CHECK-NEXT: .short 37
27
28 ; CHECK: .globl fvar
29 ; CHECK-NEXT: .align 2
30 ; CHECK-NEXT: fvar:
31 ; CHECK-NEXT: .long 1145569280
32
33 ; CHECK: .globl dvar
34 ; CHECK-NEXT: .align 3
35 ; CHECK-NEXT: dvar:
36 ; CHECK-NEXT: .llong 4651127699538968576
37
38 ; CHECK: .globl over_aligned
39 ; CHECK-NEXT: .align 5
40 ; CHECK-NEXT: over_aligned:
41 ; CHECK-NEXT: .llong 4651127699538968576
42
43 ; CHECK: .globl charr
44 ; CHECK-NEXT: charr:
45 ; CHECK-NEXT: .byte 97
46 ; CHECK-NEXT: .byte 98
47 ; CHECK-NEXT: .byte 99
48 ; CHECK-NEXT: .byte 100
49
50 ; CHECK: .globl dblarr
51 ; CHECK-NEXT: .align 3
52 ; CHECK-NEXT: dblarr:
53 ; CHECK-NEXT: .llong 4607182418800017408
54 ; CHECK-NEXT: .llong 4611686018427387904
55 ; CHECK-NEXT: .llong 4613937818241073152
56 ; CHECK-NEXT: .llong 4616189618054758400