diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 101 |
1 files changed, 61 insertions, 40 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index 5c10d6307c76..780b22b4fbe6 100644 --- a/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -68,6 +68,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Process.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Threading.h" #include "llvm/Target/TargetMachine.h" #include "llvm/TargetParser/Triple.h" #include "llvm/Transforms/Utils/ModuleUtils.h" @@ -316,7 +317,7 @@ void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, // Linux assembler (Others?) does not take register mnemonics. // FIXME - What about special registers used in mfspr/mtspr? - O << PPCRegisterInfo::stripRegisterPrefix(RegName); + O << PPC::stripRegisterPrefix(RegName); return; } case MachineOperand::MO_Immediate: @@ -376,13 +377,13 @@ bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, // This operand uses VSX numbering. // If the operand is a VMX register, convert it to a VSX register. Register Reg = MI->getOperand(OpNo).getReg(); - if (PPCInstrInfo::isVRRegister(Reg)) + if (PPC::isVRRegister(Reg)) Reg = PPC::VSX32 + (Reg - PPC::V0); - else if (PPCInstrInfo::isVFRegister(Reg)) + else if (PPC::isVFRegister(Reg)) Reg = PPC::VSX32 + (Reg - PPC::VF0); const char *RegName; RegName = PPCInstPrinter::getRegisterName(Reg); - RegName = PPCRegisterInfo::stripRegisterPrefix(RegName); + RegName = PPC::stripRegisterPrefix(RegName); O << RegName; return false; } @@ -632,7 +633,6 @@ void PPCAsmPrinter::EmitAIXTlsCallHelper(const MachineInstr *MI) { const MCExpr *TlsRef = MCSymbolRefExpr::create(TlsCall, MCSymbolRefExpr::VK_None, OutContext); EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BLA).addExpr(TlsRef)); - return; } /// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a @@ -715,25 +715,11 @@ static MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO, } } -static bool hasTLSFlag(const MachineOperand &MO) { - unsigned Flags = MO.getTargetFlags(); - if (Flags & PPCII::MO_TLSGD_FLAG || Flags & PPCII::MO_TPREL_FLAG || - Flags & PPCII::MO_TLSLD_FLAG || Flags & PPCII::MO_TLSGDM_FLAG) - return true; - - if (Flags == PPCII::MO_TPREL_LO || Flags == PPCII::MO_TPREL_HA || - Flags == PPCII::MO_DTPREL_LO || Flags == PPCII::MO_TLSLD_LO || - Flags == PPCII::MO_TLS) - return true; - - return false; -} - static PPCAsmPrinter::TOCEntryType getTOCEntryTypeForMO(const MachineOperand &MO) { // Use the target flags to determine if this MO is Thread Local. // If we don't do this it comes out as Global. - if (hasTLSFlag(MO)) + if (PPCInstrInfo::hasTLSFlag(MO.getTargetFlags())) return PPCAsmPrinter::TOCType_ThreadLocal; switch (MO.getType()) { @@ -827,24 +813,27 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) { return Expr; }; auto GetVKForMO = [&](const MachineOperand &MO) { - // For TLS local-exec accesses on AIX, we have one TOC entry for the symbol - // (with the variable offset), which is differentiated by MO_TPREL_FLAG. - if (MO.getTargetFlags() & PPCII::MO_TPREL_FLAG) { - // TODO: Update the query and the comment above to add a check for initial - // exec when this TLS model is supported on AIX in the future, as both - // local-exec and initial-exec can use MO_TPREL_FLAG. + // For TLS initial-exec and local-exec accesses on AIX, we have one TOC + // entry for the symbol (with the variable offset), which is differentiated + // by MO_TPREL_FLAG. + unsigned Flag = MO.getTargetFlags(); + if (Flag == PPCII::MO_TPREL_FLAG || + Flag == PPCII::MO_GOT_TPREL_PCREL_FLAG || + Flag == PPCII::MO_TPREL_PCREL_FLAG) { assert(MO.isGlobal() && "Only expecting a global MachineOperand here!\n"); TLSModel::Model Model = TM.getTLSModel(MO.getGlobal()); if (Model == TLSModel::LocalExec) return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE; - llvm_unreachable("Only expecting local-exec accesses!"); + if (Model == TLSModel::InitialExec) + return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE; + llvm_unreachable("Only expecting local-exec or initial-exec accesses!"); } // For GD TLS access on AIX, we have two TOC entries for the symbol (one for // the variable offset and the other for the region handle). They are // differentiated by MO_TLSGD_FLAG and MO_TLSGDM_FLAG. - if (MO.getTargetFlags() & PPCII::MO_TLSGDM_FLAG) + if (Flag == PPCII::MO_TLSGDM_FLAG) return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM; - if (MO.getTargetFlags() & PPCII::MO_TLSGD_FLAG) + if (Flag == PPCII::MO_TLSGD_FLAG || Flag == PPCII::MO_GOT_TLSGD_PCREL_FLAG) return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD; return MCSymbolRefExpr::VariantKind::VK_None; }; @@ -1534,6 +1523,24 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) { EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::EnforceIEIO)); return; } + case PPC::ADDI8: { + // The faster non-TOC-based local-exec sequence is represented by `addi` + // with an immediate operand having the MO_TPREL_FLAG. Such an instruction + // does not otherwise arise. + unsigned Flag = MI->getOperand(2).getTargetFlags(); + if (Flag == PPCII::MO_TPREL_FLAG || + Flag == PPCII::MO_GOT_TPREL_PCREL_FLAG || + Flag == PPCII::MO_TPREL_PCREL_FLAG) { + assert( + Subtarget->hasAIXSmallLocalExecTLS() && + "addi with thread-pointer only expected with local-exec small TLS"); + LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); + TmpInst.setOpcode(PPC::LA8); + EmitToStreamer(*OutStreamer, TmpInst); + return; + } + break; + } } LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); @@ -2512,7 +2519,7 @@ void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { } void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable *GV) { - assert(!GV->getName().startswith("llvm.") && + assert(!GV->getName().starts_with("llvm.") && "Unhandled intrinsic global variable."); if (GV->hasComdat()) @@ -2759,14 +2766,18 @@ bool PPCAIXAsmPrinter::doInitialization(Module &M) { // 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. + else { + // Use threadId, Pid, and current time as the unique module id when we + // cannot generate one based on a module's strong external symbols. + auto CurTime = + std::chrono::duration_cast<std::chrono::nanoseconds>( + std::chrono::steady_clock::now().time_since_epoch()) + .count(); FormatIndicatorAndUniqueModId = - "clangPidTime_" + llvm::itostr(sys::Process::getProcessId()) + - "_" + llvm::itostr(time(nullptr)); + "clangPidTidTime_" + llvm::itostr(sys::Process::getProcessId()) + + "_" + llvm::itostr(llvm::get_threadid()) + "_" + + llvm::itostr(CurTime); + } } emitSpecialLLVMGlobal(&G); @@ -2781,11 +2792,21 @@ bool PPCAIXAsmPrinter::doInitialization(Module &M) { // Construct an aliasing list for each GlobalObject. for (const auto &Alias : M.aliases()) { - const GlobalObject *Base = Alias.getAliaseeObject(); - if (!Base) + const GlobalObject *Aliasee = Alias.getAliaseeObject(); + if (!Aliasee) report_fatal_error( "alias without a base object is not yet supported on AIX"); - GOAliasMap[Base].push_back(&Alias); + + if (Aliasee->hasCommonLinkage()) { + report_fatal_error("Aliases to common variables are not allowed on AIX:" + "\n\tAlias attribute for " + + Alias.getGlobalIdentifier() + + " is invalid because " + Aliasee->getName() + + " is common.", + false); + } + + GOAliasMap[Aliasee].push_back(&Alias); } return Result; |
