diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:39 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:39 +0300 |
commit | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch) | |
tree | 64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/libs/llvm12/lib/Target/PowerPC/PPCAsmPrinter.cpp | |
parent | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff) | |
download | ydb-e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/Target/PowerPC/PPCAsmPrinter.cpp')
-rw-r--r-- | contrib/libs/llvm12/lib/Target/PowerPC/PPCAsmPrinter.cpp | 1226 |
1 files changed, 613 insertions, 613 deletions
diff --git a/contrib/libs/llvm12/lib/Target/PowerPC/PPCAsmPrinter.cpp b/contrib/libs/llvm12/lib/Target/PowerPC/PPCAsmPrinter.cpp index f6e59a2718..6257709731 100644 --- a/contrib/libs/llvm12/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/contrib/libs/llvm12/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -27,7 +27,7 @@ #include "PPCTargetStreamer.h" #include "TargetInfo/PowerPCTargetInfo.h" #include "llvm/ADT/MapVector.h" -#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" @@ -47,7 +47,7 @@ #include "llvm/IR/Module.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" -#include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstBuilder.h" @@ -62,11 +62,11 @@ #include "llvm/Support/CodeGen.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/Process.h" +#include "llvm/Support/Process.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Transforms/Utils/ModuleUtils.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" #include <algorithm> #include <cassert> #include <cstdint> @@ -74,7 +74,7 @@ #include <new> using namespace llvm; -using namespace llvm::XCOFF; +using namespace llvm::XCOFF; #define DEBUG_TYPE "asmprinter" @@ -150,22 +150,22 @@ public: class PPCAIXAsmPrinter : public PPCAsmPrinter { private: - /// Symbols lowered from ExternalSymbolSDNodes, we will need to emit extern - /// linkage for them in AIX. - SmallPtrSet<MCSymbol *, 8> ExtSymSDNodeSymbols; - - /// A format indicator and unique trailing identifier to form part of the - /// sinit/sterm function names. - std::string FormatIndicatorAndUniqueModId; - + /// Symbols lowered from ExternalSymbolSDNodes, we will need to emit extern + /// linkage for them in AIX. + SmallPtrSet<MCSymbol *, 8> ExtSymSDNodeSymbols; + + /// A format indicator and unique trailing identifier to form part of the + /// sinit/sterm function names. + std::string FormatIndicatorAndUniqueModId; + static void ValidateGV(const GlobalVariable *GV); - // Record a list of GlobalAlias associated with a GlobalObject. - // This is used for AIX's extra-label-at-definition aliasing strategy. - DenseMap<const GlobalObject *, SmallVector<const GlobalAlias *, 1>> - GOAliasMap; + // Record a list of GlobalAlias associated with a GlobalObject. + // This is used for AIX's extra-label-at-definition aliasing strategy. + DenseMap<const GlobalObject *, SmallVector<const GlobalAlias *, 1>> + GOAliasMap; + + void emitTracebackTable(); - void emitTracebackTable(); - public: PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) : PPCAsmPrinter(TM, std::move(Streamer)) { @@ -178,28 +178,28 @@ public: bool doInitialization(Module &M) override; - void emitXXStructorList(const DataLayout &DL, const Constant *List, - bool IsCtor) override; - + void emitXXStructorList(const DataLayout &DL, const Constant *List, + bool IsCtor) override; + void SetupMachineFunction(MachineFunction &MF) override; void emitGlobalVariable(const GlobalVariable *GV) override; void emitFunctionDescriptor() override; - void emitFunctionEntryLabel() override; - - void emitFunctionBodyEnd() override; - + void emitFunctionEntryLabel() override; + + void emitFunctionBodyEnd() override; + void emitEndOfAsmFile(Module &) override; void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const override; - - void emitInstruction(const MachineInstr *MI) override; - - bool doFinalization(Module &M) override; - - void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override; + + void emitInstruction(const MachineInstr *MI) override; + + bool doFinalization(Module &M) override; + + void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override; }; } // end anonymous namespace @@ -321,12 +321,12 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, O << "0, "; printOperand(MI, OpNo, O); return false; - case 'I': - // Write 'i' if an integer constant, otherwise nothing. Used to print - // addi vs add, etc. - if (MI->getOperand(OpNo).isImm()) - O << "i"; - return false; + case 'I': + // Write 'i' if an integer constant, otherwise nothing. Used to print + // addi vs add, etc. + if (MI->getOperand(OpNo).isImm()) + O << "i"; + return false; case 'U': // Print 'u' for update form. case 'X': // Print 'x' for indexed form. // FIXME: Currently for PowerPC memory operands are always loaded @@ -499,14 +499,14 @@ void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI, StringRef Name = "__tls_get_addr"; MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(Name); MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None; - unsigned Opcode = PPC::BL8_NOP_TLS; - - assert(MI->getNumOperands() >= 3 && "Expecting at least 3 operands from MI"); - if (MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG || - MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG) { - Kind = MCSymbolRefExpr::VK_PPC_NOTOC; - Opcode = PPC::BL8_NOTOC_TLS; - } + unsigned Opcode = PPC::BL8_NOP_TLS; + + assert(MI->getNumOperands() >= 3 && "Expecting at least 3 operands from MI"); + if (MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG || + MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG) { + Kind = MCSymbolRefExpr::VK_PPC_NOTOC; + Opcode = PPC::BL8_NOTOC_TLS; + } const Module *M = MF->getFunction().getParent(); assert(MI->getOperand(0).isReg() && @@ -534,10 +534,10 @@ void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI, MCSymbol *MOSymbol = getSymbol(GValue); const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, VK, OutContext); EmitToStreamer(*OutStreamer, - MCInstBuilder(Subtarget->isPPC64() ? Opcode - : (unsigned)PPC::BL_TLS) - .addExpr(TlsRef) - .addExpr(SymVar)); + MCInstBuilder(Subtarget->isPPC64() ? Opcode + : (unsigned)PPC::BL_TLS) + .addExpr(TlsRef) + .addExpr(SymVar)); } /// Map a machine operand for a TOC pseudo-machine instruction to its @@ -591,38 +591,38 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) { } } #endif - - auto getTOCRelocAdjustedExprForXCOFF = [this](const MCExpr *Expr, - ptrdiff_t OriginalOffset) { - // Apply an offset to the TOC-based expression such that the adjusted - // notional offset from the TOC base (to be encoded into the instruction's D - // or DS field) is the signed 16-bit truncation of the original notional - // offset from the TOC base. - // This is consistent with the treatment used both by XL C/C++ and - // by AIX ld -r. - ptrdiff_t Adjustment = - OriginalOffset - llvm::SignExtend32<16>(OriginalOffset); - return MCBinaryExpr::createAdd( - Expr, MCConstantExpr::create(-Adjustment, OutContext), OutContext); - }; - - auto getTOCEntryLoadingExprForXCOFF = - [IsPPC64, getTOCRelocAdjustedExprForXCOFF, - this](const MCSymbol *MOSymbol, const MCExpr *Expr) -> const MCExpr * { - const unsigned EntryByteSize = IsPPC64 ? 8 : 4; - const auto TOCEntryIter = TOC.find(MOSymbol); - assert(TOCEntryIter != TOC.end() && - "Could not find the TOC entry for this symbol."); - const ptrdiff_t EntryDistanceFromTOCBase = - (TOCEntryIter - TOC.begin()) * EntryByteSize; - constexpr int16_t PositiveTOCRange = INT16_MAX; - - if (EntryDistanceFromTOCBase > PositiveTOCRange) - return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase); - - return Expr; - }; - + + auto getTOCRelocAdjustedExprForXCOFF = [this](const MCExpr *Expr, + ptrdiff_t OriginalOffset) { + // Apply an offset to the TOC-based expression such that the adjusted + // notional offset from the TOC base (to be encoded into the instruction's D + // or DS field) is the signed 16-bit truncation of the original notional + // offset from the TOC base. + // This is consistent with the treatment used both by XL C/C++ and + // by AIX ld -r. + ptrdiff_t Adjustment = + OriginalOffset - llvm::SignExtend32<16>(OriginalOffset); + return MCBinaryExpr::createAdd( + Expr, MCConstantExpr::create(-Adjustment, OutContext), OutContext); + }; + + auto getTOCEntryLoadingExprForXCOFF = + [IsPPC64, getTOCRelocAdjustedExprForXCOFF, + this](const MCSymbol *MOSymbol, const MCExpr *Expr) -> const MCExpr * { + const unsigned EntryByteSize = IsPPC64 ? 8 : 4; + const auto TOCEntryIter = TOC.find(MOSymbol); + assert(TOCEntryIter != TOC.end() && + "Could not find the TOC entry for this symbol."); + const ptrdiff_t EntryDistanceFromTOCBase = + (TOCEntryIter - TOC.begin()) * EntryByteSize; + constexpr int16_t PositiveTOCRange = INT16_MAX; + + if (EntryDistanceFromTOCBase > PositiveTOCRange) + return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase); + + return Expr; + }; + // Lower multi-instruction pseudo operations. switch (MI->getOpcode()) { default: break; @@ -769,7 +769,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) { assert( TM.getCodeModel() == CodeModel::Small && "This pseudo should only be selected for 32-bit small code model."); - Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp); + Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp); TmpInst.getOperand(1) = MCOperand::createExpr(Exp); EmitToStreamer(*OutStreamer, TmpInst); return; @@ -798,20 +798,20 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) { assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && "Invalid operand!"); - // Map the operand to its corresponding MCSymbol. - const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this); - + // Map the operand to its corresponding MCSymbol. + const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this); + // Map the machine operand to its corresponding MCSymbol, then map the // global address operand to be a reference to the TOC entry we will // synthesize later. - MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); + MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol); const MCSymbolRefExpr::VariantKind VK = IsAIX ? MCSymbolRefExpr::VK_None : MCSymbolRefExpr::VK_PPC_TOC; const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry, VK, OutContext); - TmpInst.getOperand(1) = MCOperand::createExpr( - IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp) : Exp); + TmpInst.getOperand(1) = MCOperand::createExpr( + IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp) : Exp); EmitToStreamer(*OutStreamer, TmpInst); return; } @@ -1087,7 +1087,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) { case PPC::GETtlsADDR: // Transform: %x3 = GETtlsADDR %x3, @sym // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd) - case PPC::GETtlsADDRPCREL: + case PPC::GETtlsADDRPCREL: case PPC::GETtlsADDR32: { // Transform: %r3 = GETtlsADDR32 %r3, @sym // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT @@ -1133,7 +1133,7 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) { case PPC::GETtlsldADDR: // Transform: %x3 = GETtlsldADDR %x3, @sym // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld) - case PPC::GETtlsldADDRPCREL: + case PPC::GETtlsldADDRPCREL: case PPC::GETtlsldADDR32: { // Transform: %r3 = GETtlsldADDR32 %r3, @sym // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT @@ -1160,21 +1160,21 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) { .addExpr(SymDtprel)); return; } - case PPC::PADDIdtprel: { - // Transform: %rd = PADDIdtprel %rs, @sym - // Into: %rd = PADDI8 %rs, sym@dtprel - const MachineOperand &MO = MI->getOperand(2); - const GlobalValue *GValue = MO.getGlobal(); - MCSymbol *MOSymbol = getSymbol(GValue); - const MCExpr *SymDtprel = MCSymbolRefExpr::create( - MOSymbol, MCSymbolRefExpr::VK_DTPREL, OutContext); - EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::PADDI8) - .addReg(MI->getOperand(0).getReg()) - .addReg(MI->getOperand(1).getReg()) - .addExpr(SymDtprel)); - return; - } - + case PPC::PADDIdtprel: { + // Transform: %rd = PADDIdtprel %rs, @sym + // Into: %rd = PADDI8 %rs, sym@dtprel + const MachineOperand &MO = MI->getOperand(2); + const GlobalValue *GValue = MO.getGlobal(); + MCSymbol *MOSymbol = getSymbol(GValue); + const MCExpr *SymDtprel = MCSymbolRefExpr::create( + MOSymbol, MCSymbolRefExpr::VK_DTPREL, OutContext); + EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::PADDI8) + .addReg(MI->getOperand(0).getReg()) + .addReg(MI->getOperand(1).getReg()) + .addExpr(SymDtprel)); + return; + } + case PPC::ADDIdtprelL: // Transform: %xd = ADDIdtprelL %xs, @sym // Into: %xd = ADDI8 %xs, sym@dtprel@l @@ -1711,19 +1711,19 @@ void PPCAIXAsmPrinter::emitLinkage(const GlobalValue *GV, assert(LinkageAttr != MCSA_Invalid && "LinkageAttr should not MCSA_Invalid."); MCSymbolAttr VisibilityAttr = MCSA_Invalid; - if (!TM.getIgnoreXCOFFVisibility()) { - switch (GV->getVisibility()) { + if (!TM.getIgnoreXCOFFVisibility()) { + switch (GV->getVisibility()) { - // TODO: "exported" and "internal" Visibility needs to go here. - case GlobalValue::DefaultVisibility: - break; - case GlobalValue::HiddenVisibility: - VisibilityAttr = MAI->getHiddenVisibilityAttr(); - break; - case GlobalValue::ProtectedVisibility: - VisibilityAttr = MAI->getProtectedVisibilityAttr(); - break; - } + // TODO: "exported" and "internal" Visibility needs to go here. + case GlobalValue::DefaultVisibility: + break; + case GlobalValue::HiddenVisibility: + VisibilityAttr = MAI->getHiddenVisibilityAttr(); + break; + case GlobalValue::ProtectedVisibility: + VisibilityAttr = MAI->getProtectedVisibilityAttr(); + break; + } } OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr, @@ -1742,284 +1742,284 @@ void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) { return AsmPrinter::SetupMachineFunction(MF); } -void PPCAIXAsmPrinter::emitFunctionBodyEnd() { - - if (!TM.getXCOFFTracebackTable()) - return; - - emitTracebackTable(); -} - -void PPCAIXAsmPrinter::emitTracebackTable() { - - // Create a symbol for the end of function. - MCSymbol *FuncEnd = createTempSymbol(MF->getName()); - OutStreamer->emitLabel(FuncEnd); - - OutStreamer->AddComment("Traceback table begin"); - // Begin with a fullword of zero. - OutStreamer->emitIntValueInHexWithPadding(0, 4 /*size*/); - - SmallString<128> CommentString; - raw_svector_ostream CommentOS(CommentString); - - auto EmitComment = [&]() { - OutStreamer->AddComment(CommentOS.str()); - CommentString.clear(); - }; - - auto EmitCommentAndValue = [&](uint64_t Value, int Size) { - EmitComment(); - OutStreamer->emitIntValueInHexWithPadding(Value, Size); - }; - - unsigned int Version = 0; - CommentOS << "Version = " << Version; - EmitCommentAndValue(Version, 1); - - // There is a lack of information in the IR to assist with determining the - // source language. AIX exception handling mechanism would only search for - // personality routine and LSDA area when such language supports exception - // handling. So to be conservatively correct and allow runtime to do its job, - // we need to set it to C++ for now. - TracebackTable::LanguageID LanguageIdentifier = - TracebackTable::CPlusPlus; // C++ - - CommentOS << "Language = " - << getNameForTracebackTableLanguageId(LanguageIdentifier); - EmitCommentAndValue(LanguageIdentifier, 1); - - // This is only populated for the third and fourth bytes. - uint32_t FirstHalfOfMandatoryField = 0; - - // Emit the 3rd byte of the mandatory field. - - // We always set traceback offset bit to true. - FirstHalfOfMandatoryField |= TracebackTable::HasTraceBackTableOffsetMask; - - const PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>(); - const MachineRegisterInfo &MRI = MF->getRegInfo(); - - // Check the function uses floating-point processor instructions or not - for (unsigned Reg = PPC::F0; Reg <= PPC::F31; ++Reg) { - if (MRI.isPhysRegUsed(Reg)) { - FirstHalfOfMandatoryField |= TracebackTable::IsFloatingPointPresentMask; - break; - } - } - -#define GENBOOLCOMMENT(Prefix, V, Field) \ - CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \ - << #Field - -#define GENVALUECOMMENT(PrefixAndName, V, Field) \ - CommentOS << (PrefixAndName) << " = " \ - << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \ - (TracebackTable::Field##Shift)) - - GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsGlobaLinkage); - GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue); - EmitComment(); - - GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasTraceBackTableOffset); - GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsInternalProcedure); - EmitComment(); - - GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasControlledStorage); - GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsTOCless); - EmitComment(); - - GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsFloatingPointPresent); - EmitComment(); - GENBOOLCOMMENT("", FirstHalfOfMandatoryField, - IsFloatingPointOperationLogOrAbortEnabled); - EmitComment(); - - OutStreamer->emitIntValueInHexWithPadding( - (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1); - - // Set the 4th byte of the mandatory field. - FirstHalfOfMandatoryField |= TracebackTable::IsFunctionNamePresentMask; - - static_assert(XCOFF::AllocRegNo == 31, "Unexpected register usage!"); - if (MRI.isPhysRegUsed(Subtarget->isPPC64() ? PPC::X31 : PPC::R31)) - FirstHalfOfMandatoryField |= TracebackTable::IsAllocaUsedMask; - - const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs(); - if (!MustSaveCRs.empty()) - FirstHalfOfMandatoryField |= TracebackTable::IsCRSavedMask; - - if (FI->mustSaveLR()) - FirstHalfOfMandatoryField |= TracebackTable::IsLRSavedMask; - - GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsInterruptHandler); - GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsFunctionNamePresent); - GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsAllocaUsed); - EmitComment(); - GENVALUECOMMENT("OnConditionDirective", FirstHalfOfMandatoryField, - OnConditionDirective); - GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsCRSaved); - GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsLRSaved); - EmitComment(); - OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff), - 1); - - // Set the 5th byte of mandatory field. - uint32_t SecondHalfOfMandatoryField = 0; - - // Always store back chain. - SecondHalfOfMandatoryField |= TracebackTable::IsBackChainStoredMask; - - uint32_t FPRSaved = 0; - for (unsigned Reg = PPC::F14; Reg <= PPC::F31; ++Reg) { - if (MRI.isPhysRegModified(Reg)) { - FPRSaved = PPC::F31 - Reg + 1; - break; - } - } - SecondHalfOfMandatoryField |= (FPRSaved << TracebackTable::FPRSavedShift) & - TracebackTable::FPRSavedMask; - GENBOOLCOMMENT("", SecondHalfOfMandatoryField, IsBackChainStored); - GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, IsFixup); - GENVALUECOMMENT(", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved); - EmitComment(); - OutStreamer->emitIntValueInHexWithPadding( - (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1); - - // Set the 6th byte of mandatory field. - bool ShouldEmitEHBlock = TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF); - if (ShouldEmitEHBlock) - SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask; - - uint32_t GPRSaved = 0; - - // X13 is reserved under 64-bit environment. - unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13; - unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31; - - for (unsigned Reg = GPRBegin; Reg <= GPREnd; ++Reg) { - if (MRI.isPhysRegModified(Reg)) { - GPRSaved = GPREnd - Reg + 1; - break; - } - } - - SecondHalfOfMandatoryField |= (GPRSaved << TracebackTable::GPRSavedShift) & - TracebackTable::GPRSavedMask; - - GENBOOLCOMMENT("", SecondHalfOfMandatoryField, HasVectorInfo); - GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasExtensionTable); - GENVALUECOMMENT(", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved); - EmitComment(); - OutStreamer->emitIntValueInHexWithPadding( - (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1); - - // Set the 7th byte of mandatory field. - uint32_t NumberOfFixedPara = FI->getFixedParamNum(); - SecondHalfOfMandatoryField |= - (NumberOfFixedPara << TracebackTable::NumberOfFixedParmsShift) & - TracebackTable::NumberOfFixedParmsMask; - GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField, - NumberOfFixedParms); - EmitComment(); - OutStreamer->emitIntValueInHexWithPadding( - (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1); - - // Set the 8th byte of mandatory field. - - // Always set parameter on stack. - SecondHalfOfMandatoryField |= TracebackTable::HasParmsOnStackMask; - - uint32_t NumberOfFPPara = FI->getFloatingPointParamNum(); - SecondHalfOfMandatoryField |= - (NumberOfFPPara << TracebackTable::NumberOfFloatingPointParmsShift) & - TracebackTable::NumberOfFloatingPointParmsMask; - - GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField, - NumberOfFloatingPointParms); - GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasParmsOnStack); - EmitComment(); - OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff, - 1); - - // Generate the optional fields of traceback table. - - // Parameter type. - if (NumberOfFixedPara || NumberOfFPPara) { - assert((SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) == - 0 && - "VectorInfo has not been implemented."); - uint32_t ParaType = FI->getParameterType(); - CommentOS << "Parameter type = " - << XCOFF::parseParmsType(ParaType, - NumberOfFixedPara + NumberOfFPPara); - EmitComment(); - OutStreamer->emitIntValueInHexWithPadding(ParaType, sizeof(ParaType)); - } - - // Traceback table offset. - OutStreamer->AddComment("Function size"); - if (FirstHalfOfMandatoryField & TracebackTable::HasTraceBackTableOffsetMask) { - MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol( - &(MF->getFunction()), TM); - OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4); - } - - // Since we unset the Int_Handler. - if (FirstHalfOfMandatoryField & TracebackTable::IsInterruptHandlerMask) - report_fatal_error("Hand_Mask not implement yet"); - - if (FirstHalfOfMandatoryField & TracebackTable::HasControlledStorageMask) - report_fatal_error("Ctl_Info not implement yet"); - - if (FirstHalfOfMandatoryField & TracebackTable::IsFunctionNamePresentMask) { - StringRef Name = MF->getName().substr(0, INT16_MAX); - int16_t NameLength = Name.size(); - CommentOS << "Function name len = " - << static_cast<unsigned int>(NameLength); - EmitCommentAndValue(NameLength, 2); - OutStreamer->AddComment("Function Name"); - OutStreamer->emitBytes(Name); - } - - if (FirstHalfOfMandatoryField & TracebackTable::IsAllocaUsedMask) { - uint8_t AllocReg = XCOFF::AllocRegNo; - OutStreamer->AddComment("AllocaUsed"); - OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg)); - } - - uint8_t ExtensionTableFlag = 0; - if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) { - if (ShouldEmitEHBlock) - ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO; - - CommentOS << "ExtensionTableFlag = " - << getExtendedTBTableFlagString(ExtensionTableFlag); - EmitCommentAndValue(ExtensionTableFlag, sizeof(ExtensionTableFlag)); - } - - if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) { - auto &Ctx = OutStreamer->getContext(); - MCSymbol *EHInfoSym = - TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(MF); - MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym); - const MCSymbol *TOCBaseSym = - cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection()) - ->getQualNameSymbol(); - const MCExpr *Exp = - MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx), - MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx); - - const DataLayout &DL = getDataLayout(); - OutStreamer->emitValueToAlignment(4); - OutStreamer->AddComment("EHInfo Table"); - OutStreamer->emitValue(Exp, DL.getPointerSize()); - } - -#undef GENBOOLCOMMENT -#undef GENVALUECOMMENT -} - +void PPCAIXAsmPrinter::emitFunctionBodyEnd() { + + if (!TM.getXCOFFTracebackTable()) + return; + + emitTracebackTable(); +} + +void PPCAIXAsmPrinter::emitTracebackTable() { + + // Create a symbol for the end of function. + MCSymbol *FuncEnd = createTempSymbol(MF->getName()); + OutStreamer->emitLabel(FuncEnd); + + OutStreamer->AddComment("Traceback table begin"); + // Begin with a fullword of zero. + OutStreamer->emitIntValueInHexWithPadding(0, 4 /*size*/); + + SmallString<128> CommentString; + raw_svector_ostream CommentOS(CommentString); + + auto EmitComment = [&]() { + OutStreamer->AddComment(CommentOS.str()); + CommentString.clear(); + }; + + auto EmitCommentAndValue = [&](uint64_t Value, int Size) { + EmitComment(); + OutStreamer->emitIntValueInHexWithPadding(Value, Size); + }; + + unsigned int Version = 0; + CommentOS << "Version = " << Version; + EmitCommentAndValue(Version, 1); + + // There is a lack of information in the IR to assist with determining the + // source language. AIX exception handling mechanism would only search for + // personality routine and LSDA area when such language supports exception + // handling. So to be conservatively correct and allow runtime to do its job, + // we need to set it to C++ for now. + TracebackTable::LanguageID LanguageIdentifier = + TracebackTable::CPlusPlus; // C++ + + CommentOS << "Language = " + << getNameForTracebackTableLanguageId(LanguageIdentifier); + EmitCommentAndValue(LanguageIdentifier, 1); + + // This is only populated for the third and fourth bytes. + uint32_t FirstHalfOfMandatoryField = 0; + + // Emit the 3rd byte of the mandatory field. + + // We always set traceback offset bit to true. + FirstHalfOfMandatoryField |= TracebackTable::HasTraceBackTableOffsetMask; + + const PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>(); + const MachineRegisterInfo &MRI = MF->getRegInfo(); + + // Check the function uses floating-point processor instructions or not + for (unsigned Reg = PPC::F0; Reg <= PPC::F31; ++Reg) { + if (MRI.isPhysRegUsed(Reg)) { + FirstHalfOfMandatoryField |= TracebackTable::IsFloatingPointPresentMask; + break; + } + } + +#define GENBOOLCOMMENT(Prefix, V, Field) \ + CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \ + << #Field + +#define GENVALUECOMMENT(PrefixAndName, V, Field) \ + CommentOS << (PrefixAndName) << " = " \ + << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \ + (TracebackTable::Field##Shift)) + + GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsGlobaLinkage); + GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue); + EmitComment(); + + GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasTraceBackTableOffset); + GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsInternalProcedure); + EmitComment(); + + GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasControlledStorage); + GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsTOCless); + EmitComment(); + + GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsFloatingPointPresent); + EmitComment(); + GENBOOLCOMMENT("", FirstHalfOfMandatoryField, + IsFloatingPointOperationLogOrAbortEnabled); + EmitComment(); + + OutStreamer->emitIntValueInHexWithPadding( + (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1); + + // Set the 4th byte of the mandatory field. + FirstHalfOfMandatoryField |= TracebackTable::IsFunctionNamePresentMask; + + static_assert(XCOFF::AllocRegNo == 31, "Unexpected register usage!"); + if (MRI.isPhysRegUsed(Subtarget->isPPC64() ? PPC::X31 : PPC::R31)) + FirstHalfOfMandatoryField |= TracebackTable::IsAllocaUsedMask; + + const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs(); + if (!MustSaveCRs.empty()) + FirstHalfOfMandatoryField |= TracebackTable::IsCRSavedMask; + + if (FI->mustSaveLR()) + FirstHalfOfMandatoryField |= TracebackTable::IsLRSavedMask; + + GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsInterruptHandler); + GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsFunctionNamePresent); + GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsAllocaUsed); + EmitComment(); + GENVALUECOMMENT("OnConditionDirective", FirstHalfOfMandatoryField, + OnConditionDirective); + GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsCRSaved); + GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsLRSaved); + EmitComment(); + OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff), + 1); + + // Set the 5th byte of mandatory field. + uint32_t SecondHalfOfMandatoryField = 0; + + // Always store back chain. + SecondHalfOfMandatoryField |= TracebackTable::IsBackChainStoredMask; + + uint32_t FPRSaved = 0; + for (unsigned Reg = PPC::F14; Reg <= PPC::F31; ++Reg) { + if (MRI.isPhysRegModified(Reg)) { + FPRSaved = PPC::F31 - Reg + 1; + break; + } + } + SecondHalfOfMandatoryField |= (FPRSaved << TracebackTable::FPRSavedShift) & + TracebackTable::FPRSavedMask; + GENBOOLCOMMENT("", SecondHalfOfMandatoryField, IsBackChainStored); + GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, IsFixup); + GENVALUECOMMENT(", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved); + EmitComment(); + OutStreamer->emitIntValueInHexWithPadding( + (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1); + + // Set the 6th byte of mandatory field. + bool ShouldEmitEHBlock = TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF); + if (ShouldEmitEHBlock) + SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask; + + uint32_t GPRSaved = 0; + + // X13 is reserved under 64-bit environment. + unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13; + unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31; + + for (unsigned Reg = GPRBegin; Reg <= GPREnd; ++Reg) { + if (MRI.isPhysRegModified(Reg)) { + GPRSaved = GPREnd - Reg + 1; + break; + } + } + + SecondHalfOfMandatoryField |= (GPRSaved << TracebackTable::GPRSavedShift) & + TracebackTable::GPRSavedMask; + + GENBOOLCOMMENT("", SecondHalfOfMandatoryField, HasVectorInfo); + GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasExtensionTable); + GENVALUECOMMENT(", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved); + EmitComment(); + OutStreamer->emitIntValueInHexWithPadding( + (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1); + + // Set the 7th byte of mandatory field. + uint32_t NumberOfFixedPara = FI->getFixedParamNum(); + SecondHalfOfMandatoryField |= + (NumberOfFixedPara << TracebackTable::NumberOfFixedParmsShift) & + TracebackTable::NumberOfFixedParmsMask; + GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField, + NumberOfFixedParms); + EmitComment(); + OutStreamer->emitIntValueInHexWithPadding( + (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1); + + // Set the 8th byte of mandatory field. + + // Always set parameter on stack. + SecondHalfOfMandatoryField |= TracebackTable::HasParmsOnStackMask; + + uint32_t NumberOfFPPara = FI->getFloatingPointParamNum(); + SecondHalfOfMandatoryField |= + (NumberOfFPPara << TracebackTable::NumberOfFloatingPointParmsShift) & + TracebackTable::NumberOfFloatingPointParmsMask; + + GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField, + NumberOfFloatingPointParms); + GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasParmsOnStack); + EmitComment(); + OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff, + 1); + + // Generate the optional fields of traceback table. + + // Parameter type. + if (NumberOfFixedPara || NumberOfFPPara) { + assert((SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) == + 0 && + "VectorInfo has not been implemented."); + uint32_t ParaType = FI->getParameterType(); + CommentOS << "Parameter type = " + << XCOFF::parseParmsType(ParaType, + NumberOfFixedPara + NumberOfFPPara); + EmitComment(); + OutStreamer->emitIntValueInHexWithPadding(ParaType, sizeof(ParaType)); + } + + // Traceback table offset. + OutStreamer->AddComment("Function size"); + if (FirstHalfOfMandatoryField & TracebackTable::HasTraceBackTableOffsetMask) { + MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol( + &(MF->getFunction()), TM); + OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4); + } + + // Since we unset the Int_Handler. + if (FirstHalfOfMandatoryField & TracebackTable::IsInterruptHandlerMask) + report_fatal_error("Hand_Mask not implement yet"); + + if (FirstHalfOfMandatoryField & TracebackTable::HasControlledStorageMask) + report_fatal_error("Ctl_Info not implement yet"); + + if (FirstHalfOfMandatoryField & TracebackTable::IsFunctionNamePresentMask) { + StringRef Name = MF->getName().substr(0, INT16_MAX); + int16_t NameLength = Name.size(); + CommentOS << "Function name len = " + << static_cast<unsigned int>(NameLength); + EmitCommentAndValue(NameLength, 2); + OutStreamer->AddComment("Function Name"); + OutStreamer->emitBytes(Name); + } + + if (FirstHalfOfMandatoryField & TracebackTable::IsAllocaUsedMask) { + uint8_t AllocReg = XCOFF::AllocRegNo; + OutStreamer->AddComment("AllocaUsed"); + OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg)); + } + + uint8_t ExtensionTableFlag = 0; + if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) { + if (ShouldEmitEHBlock) + ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO; + + CommentOS << "ExtensionTableFlag = " + << getExtendedTBTableFlagString(ExtensionTableFlag); + EmitCommentAndValue(ExtensionTableFlag, sizeof(ExtensionTableFlag)); + } + + if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) { + auto &Ctx = OutStreamer->getContext(); + MCSymbol *EHInfoSym = + TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(MF); + MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym); + const MCSymbol *TOCBaseSym = + cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection()) + ->getQualNameSymbol(); + const MCExpr *Exp = + MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx), + MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx); + + const DataLayout &DL = getDataLayout(); + OutStreamer->emitValueToAlignment(4); + OutStreamer->AddComment("EHInfo Table"); + OutStreamer->emitValue(Exp, DL.getPointerSize()); + } + +#undef GENBOOLCOMMENT +#undef GENVALUECOMMENT +} + void PPCAIXAsmPrinter::ValidateGV(const GlobalVariable *GV) { // Early error checking limiting what is supported. if (GV->isThreadLocal()) @@ -2029,18 +2029,18 @@ void PPCAIXAsmPrinter::ValidateGV(const GlobalVariable *GV) { report_fatal_error("COMDAT not yet supported by AIX."); } -static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable *GV) { - return GV->hasAppendingLinkage() && - StringSwitch<bool>(GV->getName()) - // TODO: Linker could still eliminate the GV if we just skip - // handling llvm.used array. Skipping them for now until we or the - // AIX OS team come up with a good solution. - .Case("llvm.used", true) - // It's correct to just skip llvm.compiler.used array here. - .Case("llvm.compiler.used", true) - .Default(false); -} - +static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable *GV) { + return GV->hasAppendingLinkage() && + StringSwitch<bool>(GV->getName()) + // TODO: Linker could still eliminate the GV if we just skip + // handling llvm.used array. Skipping them for now until we or the + // AIX OS team come up with a good solution. + .Case("llvm.used", true) + // It's correct to just skip llvm.compiler.used array here. + .Case("llvm.compiler.used", true) + .Default(false); +} + static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV) { return StringSwitch<bool>(GV->getName()) .Cases("llvm.global_ctors", "llvm.global_dtors", true) @@ -2048,12 +2048,12 @@ static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV) { } void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { - // Special LLVM global arrays have been handled at the initialization. - if (isSpecialLLVMGlobalArrayToSkip(GV) || isSpecialLLVMGlobalArrayForStaticInit(GV)) - return; - - assert(!GV->getName().startswith("llvm.") && - "Unhandled intrinsic global variable."); + // Special LLVM global arrays have been handled at the initialization. + if (isSpecialLLVMGlobalArrayToSkip(GV) || isSpecialLLVMGlobalArrayForStaticInit(GV)) + return; + + assert(!GV->getName().startswith("llvm.") && + "Unhandled intrinsic global variable."); ValidateGV(GV); MCSymbolXCOFF *GVSym = cast<MCSymbolXCOFF>(getSymbol(GV)); @@ -2080,12 +2080,12 @@ void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { if (GVKind.isCommon() || GVKind.isBSSLocal()) { Align Alignment = GV->getAlign().getValueOr(DL.getPreferredAlign(GV)); uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType()); - GVSym->setStorageClass( - TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV)); + GVSym->setStorageClass( + TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV)); if (GVKind.isBSSLocal()) OutStreamer->emitXCOFFLocalCommonSymbol( - OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()), Size, + OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()), Size, GVSym, Alignment.value()); else OutStreamer->emitCommonSymbol(GVSym, Size, Alignment.value()); @@ -2095,18 +2095,18 @@ void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { MCSymbol *EmittedInitSym = GVSym; emitLinkage(GV, EmittedInitSym); emitAlignment(getGVAlignment(GV, DL), GV); - - // When -fdata-sections is enabled, every GlobalVariable will - // be put into its own csect; therefore, label is not necessary here. - if (!TM.getDataSections() || GV->hasSection()) { - OutStreamer->emitLabel(EmittedInitSym); - } - - // Emit aliasing label for global variable. - llvm::for_each(GOAliasMap[GV], [this](const GlobalAlias *Alias) { - OutStreamer->emitLabel(getSymbol(Alias)); - }); - + + // When -fdata-sections is enabled, every GlobalVariable will + // be put into its own csect; therefore, label is not necessary here. + if (!TM.getDataSections() || GV->hasSection()) { + OutStreamer->emitLabel(EmittedInitSym); + } + + // Emit aliasing label for global variable. + llvm::for_each(GOAliasMap[GV], [this](const GlobalAlias *Alias) { + OutStreamer->emitLabel(getSymbol(Alias)); + }); + emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer()); } @@ -2118,13 +2118,13 @@ void PPCAIXAsmPrinter::emitFunctionDescriptor() { // Emit function descriptor. OutStreamer->SwitchSection( cast<MCSymbolXCOFF>(CurrentFnDescSym)->getRepresentedCsect()); - - // Emit aliasing label for function descriptor csect. - llvm::for_each(GOAliasMap[&MF->getFunction()], - [this](const GlobalAlias *Alias) { - OutStreamer->emitLabel(getSymbol(Alias)); - }); - + + // Emit aliasing label for function descriptor csect. + llvm::for_each(GOAliasMap[&MF->getFunction()], + [this](const GlobalAlias *Alias) { + OutStreamer->emitLabel(getSymbol(Alias)); + }); + // Emit function entry point address. OutStreamer->emitValue(MCSymbolRefExpr::create(CurrentFnSym, OutContext), PointerSize); @@ -2140,20 +2140,20 @@ void PPCAIXAsmPrinter::emitFunctionDescriptor() { OutStreamer->SwitchSection(Current.first, Current.second); } -void PPCAIXAsmPrinter::emitFunctionEntryLabel() { - // It's not necessary to emit the label when we have individual - // function in its own csect. - if (!TM.getFunctionSections()) - PPCAsmPrinter::emitFunctionEntryLabel(); - - // Emit aliasing label for function entry point label. - llvm::for_each( - GOAliasMap[&MF->getFunction()], [this](const GlobalAlias *Alias) { - OutStreamer->emitLabel( - getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM)); - }); -} - +void PPCAIXAsmPrinter::emitFunctionEntryLabel() { + // It's not necessary to emit the label when we have individual + // function in its own csect. + if (!TM.getFunctionSections()) + PPCAsmPrinter::emitFunctionEntryLabel(); + + // Emit aliasing label for function entry point label. + llvm::for_each( + GOAliasMap[&MF->getFunction()], [this](const GlobalAlias *Alias) { + OutStreamer->emitLabel( + getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM)); + }); +} + void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) { // If there are no functions in this module, we will never need to reference // the TOC base. @@ -2169,7 +2169,7 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) { for (auto &I : TOC) { // Setup the csect for the current TC entry. MCSectionXCOFF *TCEntry = cast<MCSectionXCOFF>( - getObjFileLowering().getSectionForTOCEntry(I.first, TM)); + getObjFileLowering().getSectionForTOCEntry(I.first, TM)); OutStreamer->SwitchSection(TCEntry); OutStreamer->emitLabel(I.second); @@ -2198,174 +2198,174 @@ bool PPCAIXAsmPrinter::doInitialization(Module &M) { // We need to know, up front, the alignment of csects for the assembly path, // because once a .csect directive gets emitted, we could not change the // alignment value on it. - for (const auto &G : M.globals()) { - if (isSpecialLLVMGlobalArrayToSkip(&G)) - continue; - - if (isSpecialLLVMGlobalArrayForStaticInit(&G)) { - // Generate a format indicator and a unique module id to be a part of - // the sinit and sterm function names. - if (FormatIndicatorAndUniqueModId.empty()) { - std::string UniqueModuleId = getUniqueModuleId(&M); - if (UniqueModuleId != "") - // TODO: Use source file full path to generate the unique module id - // and add a format indicator as a part of function name in case we - // will support more than one format. - FormatIndicatorAndUniqueModId = "clang_" + UniqueModuleId.substr(1); - else - // Use the Pid and current time as the unique module id when we cannot - // generate one based on a module's strong external symbols. - // FIXME: Adjust the comment accordingly after we use source file full - // path instead. - FormatIndicatorAndUniqueModId = - "clangPidTime_" + llvm::itostr(sys::Process::getProcessId()) + - "_" + llvm::itostr(time(nullptr)); - } - - emitSpecialLLVMGlobal(&G); - continue; - } - + for (const auto &G : M.globals()) { + if (isSpecialLLVMGlobalArrayToSkip(&G)) + continue; + + if (isSpecialLLVMGlobalArrayForStaticInit(&G)) { + // Generate a format indicator and a unique module id to be a part of + // the sinit and sterm function names. + if (FormatIndicatorAndUniqueModId.empty()) { + std::string UniqueModuleId = getUniqueModuleId(&M); + if (UniqueModuleId != "") + // TODO: Use source file full path to generate the unique module id + // and add a format indicator as a part of function name in case we + // will support more than one format. + FormatIndicatorAndUniqueModId = "clang_" + UniqueModuleId.substr(1); + else + // Use the Pid and current time as the unique module id when we cannot + // generate one based on a module's strong external symbols. + // FIXME: Adjust the comment accordingly after we use source file full + // path instead. + FormatIndicatorAndUniqueModId = + "clangPidTime_" + llvm::itostr(sys::Process::getProcessId()) + + "_" + llvm::itostr(time(nullptr)); + } + + emitSpecialLLVMGlobal(&G); + continue; + } + setCsectAlignment(&G); - } + } for (const auto &F : M) setCsectAlignment(&F); - // Construct an aliasing list for each GlobalObject. - for (const auto &Alias : M.aliases()) { - const GlobalObject *Base = Alias.getBaseObject(); - if (!Base) - report_fatal_error( - "alias without a base object is not yet supported on AIX"); - GOAliasMap[Base].push_back(&Alias); - } - + // Construct an aliasing list for each GlobalObject. + for (const auto &Alias : M.aliases()) { + const GlobalObject *Base = Alias.getBaseObject(); + if (!Base) + report_fatal_error( + "alias without a base object is not yet supported on AIX"); + GOAliasMap[Base].push_back(&Alias); + } + return Result; } -void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) { - switch (MI->getOpcode()) { - default: - break; - case PPC::BL8: - case PPC::BL: - case PPC::BL8_NOP: - case PPC::BL_NOP: { - const MachineOperand &MO = MI->getOperand(0); - if (MO.isSymbol()) { - MCSymbolXCOFF *S = - cast<MCSymbolXCOFF>(OutContext.getOrCreateSymbol(MO.getSymbolName())); - ExtSymSDNodeSymbols.insert(S); - } - } break; - case PPC::BL_TLS: - case PPC::BL8_TLS: - case PPC::BL8_TLS_: - case PPC::BL8_NOP_TLS: - report_fatal_error("TLS call not yet implemented"); - case PPC::TAILB: - case PPC::TAILB8: - case PPC::TAILBA: - case PPC::TAILBA8: - case PPC::TAILBCTR: - case PPC::TAILBCTR8: - if (MI->getOperand(0).isSymbol()) - report_fatal_error("Tail call for extern symbol not yet supported."); - break; - } - return PPCAsmPrinter::emitInstruction(MI); -} - -bool PPCAIXAsmPrinter::doFinalization(Module &M) { - for (MCSymbol *Sym : ExtSymSDNodeSymbols) - OutStreamer->emitSymbolAttribute(Sym, MCSA_Extern); - return PPCAsmPrinter::doFinalization(M); -} - -static unsigned mapToSinitPriority(int P) { - if (P < 0 || P > 65535) - report_fatal_error("invalid init priority"); - - if (P <= 20) - return P; - - if (P < 81) - return 20 + (P - 20) * 16; - - if (P <= 1124) - return 1004 + (P - 81); - - if (P < 64512) - return 2047 + (P - 1124) * 33878; - - return 2147482625u + (P - 64512); -} - -static std::string convertToSinitPriority(int Priority) { - // This helper function converts clang init priority to values used in sinit - // and sterm functions. - // - // The conversion strategies are: - // We map the reserved clang/gnu priority range [0, 100] into the sinit/sterm - // reserved priority range [0, 1023] by - // - directly mapping the first 21 and the last 20 elements of the ranges - // - linear interpolating the intermediate values with a step size of 16. - // - // We map the non reserved clang/gnu priority range of [101, 65535] into the - // sinit/sterm priority range [1024, 2147483648] by: - // - directly mapping the first and the last 1024 elements of the ranges - // - linear interpolating the intermediate values with a step size of 33878. - unsigned int P = mapToSinitPriority(Priority); - - std::string PrioritySuffix; - llvm::raw_string_ostream os(PrioritySuffix); - os << llvm::format_hex_no_prefix(P, 8); - os.flush(); - return PrioritySuffix; -} - -void PPCAIXAsmPrinter::emitXXStructorList(const DataLayout &DL, - const Constant *List, bool IsCtor) { - SmallVector<Structor, 8> Structors; - preprocessXXStructorList(DL, List, Structors); - if (Structors.empty()) - return; - - unsigned Index = 0; - for (Structor &S : Structors) { - if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func)) - S.Func = CE->getOperand(0); - - llvm::GlobalAlias::create( - GlobalValue::ExternalLinkage, - (IsCtor ? llvm::Twine("__sinit") : llvm::Twine("__sterm")) + - llvm::Twine(convertToSinitPriority(S.Priority)) + - llvm::Twine("_", FormatIndicatorAndUniqueModId) + - llvm::Twine("_", llvm::utostr(Index++)), - cast<Function>(S.Func)); - } -} - -void PPCAIXAsmPrinter::emitTTypeReference(const GlobalValue *GV, - unsigned Encoding) { - if (GV) { - MCSymbol *TypeInfoSym = TM.getSymbol(GV); - MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym); - const MCSymbol *TOCBaseSym = - cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection()) - ->getQualNameSymbol(); - auto &Ctx = OutStreamer->getContext(); - const MCExpr *Exp = - MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx), - MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx); - OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding)); - } else - OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding)); -} - -// Return a pass that prints the PPC assembly code for a MachineFunction to the -// given output stream. +void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) { + switch (MI->getOpcode()) { + default: + break; + case PPC::BL8: + case PPC::BL: + case PPC::BL8_NOP: + case PPC::BL_NOP: { + const MachineOperand &MO = MI->getOperand(0); + if (MO.isSymbol()) { + MCSymbolXCOFF *S = + cast<MCSymbolXCOFF>(OutContext.getOrCreateSymbol(MO.getSymbolName())); + ExtSymSDNodeSymbols.insert(S); + } + } break; + case PPC::BL_TLS: + case PPC::BL8_TLS: + case PPC::BL8_TLS_: + case PPC::BL8_NOP_TLS: + report_fatal_error("TLS call not yet implemented"); + case PPC::TAILB: + case PPC::TAILB8: + case PPC::TAILBA: + case PPC::TAILBA8: + case PPC::TAILBCTR: + case PPC::TAILBCTR8: + if (MI->getOperand(0).isSymbol()) + report_fatal_error("Tail call for extern symbol not yet supported."); + break; + } + return PPCAsmPrinter::emitInstruction(MI); +} + +bool PPCAIXAsmPrinter::doFinalization(Module &M) { + for (MCSymbol *Sym : ExtSymSDNodeSymbols) + OutStreamer->emitSymbolAttribute(Sym, MCSA_Extern); + return PPCAsmPrinter::doFinalization(M); +} + +static unsigned mapToSinitPriority(int P) { + if (P < 0 || P > 65535) + report_fatal_error("invalid init priority"); + + if (P <= 20) + return P; + + if (P < 81) + return 20 + (P - 20) * 16; + + if (P <= 1124) + return 1004 + (P - 81); + + if (P < 64512) + return 2047 + (P - 1124) * 33878; + + return 2147482625u + (P - 64512); +} + +static std::string convertToSinitPriority(int Priority) { + // This helper function converts clang init priority to values used in sinit + // and sterm functions. + // + // The conversion strategies are: + // We map the reserved clang/gnu priority range [0, 100] into the sinit/sterm + // reserved priority range [0, 1023] by + // - directly mapping the first 21 and the last 20 elements of the ranges + // - linear interpolating the intermediate values with a step size of 16. + // + // We map the non reserved clang/gnu priority range of [101, 65535] into the + // sinit/sterm priority range [1024, 2147483648] by: + // - directly mapping the first and the last 1024 elements of the ranges + // - linear interpolating the intermediate values with a step size of 33878. + unsigned int P = mapToSinitPriority(Priority); + + std::string PrioritySuffix; + llvm::raw_string_ostream os(PrioritySuffix); + os << llvm::format_hex_no_prefix(P, 8); + os.flush(); + return PrioritySuffix; +} + +void PPCAIXAsmPrinter::emitXXStructorList(const DataLayout &DL, + const Constant *List, bool IsCtor) { + SmallVector<Structor, 8> Structors; + preprocessXXStructorList(DL, List, Structors); + if (Structors.empty()) + return; + + unsigned Index = 0; + for (Structor &S : Structors) { + if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func)) + S.Func = CE->getOperand(0); + + llvm::GlobalAlias::create( + GlobalValue::ExternalLinkage, + (IsCtor ? llvm::Twine("__sinit") : llvm::Twine("__sterm")) + + llvm::Twine(convertToSinitPriority(S.Priority)) + + llvm::Twine("_", FormatIndicatorAndUniqueModId) + + llvm::Twine("_", llvm::utostr(Index++)), + cast<Function>(S.Func)); + } +} + +void PPCAIXAsmPrinter::emitTTypeReference(const GlobalValue *GV, + unsigned Encoding) { + if (GV) { + MCSymbol *TypeInfoSym = TM.getSymbol(GV); + MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym); + const MCSymbol *TOCBaseSym = + cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection()) + ->getQualNameSymbol(); + auto &Ctx = OutStreamer->getContext(); + const MCExpr *Exp = + MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx), + MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx); + OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding)); + } else + OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding)); +} + +// Return a pass that prints the PPC assembly code for a MachineFunction to the +// given output stream. static AsmPrinter * createPPCAsmPrinterPass(TargetMachine &tm, std::unique_ptr<MCStreamer> &&Streamer) { @@ -2379,8 +2379,8 @@ createPPCAsmPrinterPass(TargetMachine &tm, extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() { TargetRegistry::RegisterAsmPrinter(getThePPC32Target(), createPPCAsmPrinterPass); - TargetRegistry::RegisterAsmPrinter(getThePPC32LETarget(), - createPPCAsmPrinterPass); + TargetRegistry::RegisterAsmPrinter(getThePPC32LETarget(), + createPPCAsmPrinterPass); TargetRegistry::RegisterAsmPrinter(getThePPC64Target(), createPPCAsmPrinterPass); TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(), |