diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/CodeGen/AsmPrinter.h | 5 | ||||
| -rw-r--r-- | llvm/include/llvm/MC/MCAsmInfo.h | 8 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/MC/MCAsmInfoXCOFF.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 10 | ||||
| -rw-r--r-- | llvm/lib/MC/MCObjectFileInfo.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/MC/MCSectionXCOFF.cpp | 10 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 37 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll | 57 | 
10 files changed, 130 insertions, 13 deletions
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h index 78188ed0eff..7ca0e508416 100644 --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -635,6 +635,11 @@ public:    /// supported by the target.    void EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const; +  /// Return the alignment in log2 form for the specified \p GV. +  static unsigned getGVAlignmentLog2(const GlobalValue *GV, +                                     const DataLayout &DL, +                                     unsigned InBits = 0); +  private:    /// Private state for PrintSpecial()    // Assign a unique ID to this machine instruction. diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h index 971e9354da8..95c5662835a 100644 --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -165,6 +165,10 @@ protected:    /// instead.    bool UseDataRegionDirectives = false; +  /// True if .align is to be used for alignment. Only power-of-two +  /// alignment is supported. +  bool UseDotAlignForAlignment = false; +    //===--- Data Emission Directives -------------------------------------===//    /// This should be set to the directive used to get some number of zero bytes @@ -520,6 +524,10 @@ public:      return UseDataRegionDirectives;    } +  bool useDotAlignForAlignment() const { +    return UseDotAlignForAlignment; +  } +    const char *getZeroDirective() const { return ZeroDirective; }    const char *getAsciiDirective() const { return AsciiDirective; }    const char *getAscizDirective() const { return AscizDirective; } diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 8530174bb6c..220c4758956 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -162,8 +162,9 @@ static gcp_map_type &getGCMap(void *&P) {  /// getGVAlignmentLog2 - Return the alignment to use for the specified global  /// value in log2 form.  This rounds up to the preferred alignment if possible  /// and legal. -static unsigned getGVAlignmentLog2(const GlobalValue *GV, const DataLayout &DL, -                                   unsigned InBits = 0) { +unsigned AsmPrinter::getGVAlignmentLog2(const GlobalValue *GV, +                                        const DataLayout &DL, +                                        unsigned InBits) {    unsigned NumBits = 0;    if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))      NumBits = DL.getPreferredAlignmentLog(GVar); diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 1505c9d5e15..653f30a12a2 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1849,6 +1849,9 @@ MCSection *TargetLoweringObjectFileXCOFF::SelectSectionForGlobal(    if (Kind.isText())      return TextSection; +  if (Kind.isData()) +    return DataSection; +    report_fatal_error("XCOFF other section types not yet implemented.");  } diff --git a/llvm/lib/MC/MCAsmInfoXCOFF.cpp b/llvm/lib/MC/MCAsmInfoXCOFF.cpp index 92dc505c0a1..13939f6a65f 100644 --- a/llvm/lib/MC/MCAsmInfoXCOFF.cpp +++ b/llvm/lib/MC/MCAsmInfoXCOFF.cpp @@ -17,4 +17,8 @@ MCAsmInfoXCOFF::MCAsmInfoXCOFF() {    HasDotTypeDotSizeDirective = false;    COMMDirectiveAlignmentIsInBytes = false;    LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment; +  UseDotAlignForAlignment = true; +  AsciiDirective = nullptr; // not supported +  AscizDirective = nullptr; // not supported +  Data64bitsDirective = "\t.llong\t";  } diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index e20ba2f96e3..e37bc4a4d70 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -1119,6 +1119,16 @@ void MCAsmStreamer::emitFill(const MCExpr &NumValues, int64_t Size,  void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,                                           unsigned ValueSize,                                           unsigned MaxBytesToEmit) { +  if (MAI->useDotAlignForAlignment()) { +    if (!isPowerOf2_32(ByteAlignment)) +      report_fatal_error("Only power-of-two alignments are supported " +                         "with .align."); +    OS << "\t.align\t"; +    OS << Log2_32(ByteAlignment); +    EmitEOL(); +    return; +  } +    // Some assemblers don't support non-power of two alignments, so we always    // emit alignments as a power of two if possible.    if (isPowerOf2_32(ByteAlignment)) { diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index d59453aa1ca..861e5013b6b 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -770,6 +770,10 @@ void MCObjectFileInfo::initXCOFFMCObjectFileInfo(const Triple &T) {    TextSection = Ctx->getXCOFFSection(        ".text", XCOFF::StorageMappingClass::XMC_PR, XCOFF::XTY_SD,        XCOFF::C_HIDEXT, SectionKind::getText()); + +  DataSection = Ctx->getXCOFFSection( +      ".data", XCOFF::StorageMappingClass::XMC_RW, XCOFF::XTY_SD, +      XCOFF::C_HIDEXT, SectionKind::getData());  }  void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC, diff --git a/llvm/lib/MC/MCSectionXCOFF.cpp b/llvm/lib/MC/MCSectionXCOFF.cpp index d00a435b625..db277521db2 100644 --- a/llvm/lib/MC/MCSectionXCOFF.cpp +++ b/llvm/lib/MC/MCSectionXCOFF.cpp @@ -28,6 +28,16 @@ void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,      return;    } +  if (getKind().isData()) { +    assert(getMappingClass() == XCOFF::XMC_RW && +           "Unhandled storage-mapping class for data section."); + +    OS << "\t.csect " << getSectionName() << "[" +       << "RW" +       << "]" << '\n'; +    return; +  } +    if (getKind().isBSSLocal() || getKind().isCommon()) {      assert((getMappingClass() == XCOFF::XMC_RW ||              getMappingClass() == XCOFF::XMC_BS) && diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index 8d23238e615..b1d988db839 100644 --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -1659,8 +1659,9 @@ void PPCAIXAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {      report_fatal_error("COMDAT not yet supported by AIX.");    SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM); -  if (!GVKind.isCommon() && !GVKind.isBSSLocal()) -    report_fatal_error("Only common variables are supported on AIX for now."); +  if (!GVKind.isCommon() && !GVKind.isBSSLocal() && !GVKind.isData()) +    report_fatal_error("Encountered a global variable kind that is " +                       "not supported yet.");    // Create the containing csect and switch to it.    MCSectionXCOFF *CSect = cast<MCSectionXCOFF>( @@ -1668,20 +1669,34 @@ void PPCAIXAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {    OutStreamer->SwitchSection(CSect);    // Create the symbol, set its storage class, and emit it. -  MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(getSymbol(GV)); -  XSym->setStorageClass( +  MCSymbolXCOFF *GVSym = cast<MCSymbolXCOFF>(getSymbol(GV)); +  GVSym->setStorageClass(        TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV)); -  XSym->setContainingCsect(CSect); +  GVSym->setContainingCsect(CSect);    const DataLayout &DL = GV->getParent()->getDataLayout(); -  unsigned Align = + +  // Handle common symbols. +  if (GVKind.isCommon() || GVKind.isBSSLocal()) { +    unsigned Align =        GV->getAlignment() ? GV->getAlignment() : DL.getPreferredAlignment(GV); -  uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType()); +    uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType()); + +    if (GVKind.isBSSLocal()) +      OutStreamer->EmitXCOFFLocalCommonSymbol(GVSym, Size, Align); +    else +      OutStreamer->EmitCommonSymbol(GVSym, Size, Align); +    return; +  } + +  // Get the alignment in the log2 form. +  const unsigned AlignLog = getGVAlignmentLog2(GV, DL); -  if (GVKind.isBSSLocal()) -    OutStreamer->EmitXCOFFLocalCommonSymbol(XSym, Size, Align); -  else -    OutStreamer->EmitCommonSymbol(XSym, Size, Align); +  MCSymbol *EmittedInitSym = GVSym; +  EmitLinkage(GV, EmittedInitSym); +  EmitAlignment(AlignLog, GV); +  OutStreamer->EmitLabel(EmittedInitSym); +  EmitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());  }  /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll new file mode 100644 index 00000000000..fa1b70d1830 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll @@ -0,0 +1,57 @@ +; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s +; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s + +@ivar = local_unnamed_addr global i32 35, align 4 +@llvar = local_unnamed_addr global i64 36, align 8 +@svar = local_unnamed_addr global i16 37, align 2 +@fvar = local_unnamed_addr global float 8.000000e+02, align 4 +@dvar = local_unnamed_addr global double 9.000000e+02, align 8 +@over_aligned = local_unnamed_addr global double 9.000000e+02, align 32 +@charr = local_unnamed_addr global [4 x i8] c"abcd", align 1 +@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 + +; CHECK:      .csect .data[RW] +; CHECK-NEXT: .globl  ivar +; CHECK-NEXT: .align  2 +; CHECK-NEXT: ivar: +; CHECK-NEXT: .long   35 + +; CHECK:      .globl  llvar +; CHECK-NEXT: .align  3 +; CHECK-NEXT: llvar: +; CHECK-NEXT: .llong  36 + +; CHECK:      .globl  svar +; CHECK-NEXT: .align  1 +; CHECK-NEXT: svar: +; CHECK-NEXT: .short  37 + +; CHECK:      .globl  fvar +; CHECK-NEXT: .align  2 +; CHECK-NEXT: fvar: +; CHECK-NEXT: .long   1145569280 + +; CHECK:      .globl  dvar +; CHECK-NEXT: .align  3 +; CHECK-NEXT: dvar: +; CHECK-NEXT: .llong  4651127699538968576 + +; CHECK:      .globl  over_aligned +; CHECK-NEXT: .align  5 +; CHECK-NEXT: over_aligned: +; CHECK-NEXT: .llong  4651127699538968576 + +; CHECK:      .globl  charr +; CHECK-NEXT: charr: +; CHECK-NEXT: .byte   97 +; CHECK-NEXT: .byte   98 +; CHECK-NEXT: .byte   99 +; CHECK-NEXT: .byte   100 + +; CHECK:      .globl  dblarr +; CHECK-NEXT: .align  3 +; CHECK-NEXT: dblarr: +; CHECK-NEXT: .llong  4607182418800017408 +; CHECK-NEXT: .llong  4611686018427387904 +; CHECK-NEXT: .llong  4613937818241073152 +; CHECK-NEXT: .llong  4616189618054758400  | 

