Index: llvm/lib/Target/Xtensa/XtensaAsmPrinter.h =================================================================== --- llvm/lib/Target/Xtensa/XtensaAsmPrinter.h +++ llvm/lib/Target/Xtensa/XtensaAsmPrinter.h @@ -37,6 +37,8 @@ // Override AsmPrinter. StringRef getPassName() const override { return "Xtensa Assembly Printer"; } void emitInstruction(const MachineInstr *MI) override; + void emitConstantPool() override; + void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override; }; } // end namespace llvm Index: llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp =================================================================== --- llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp +++ llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp @@ -15,6 +15,7 @@ #include "XtensaAsmPrinter.h" #include "TargetInfo/XtensaTargetInfo.h" +#include "XtensaConstantPoolValue.h" #include "XtensaMCInstLower.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" @@ -28,6 +29,17 @@ using namespace llvm; +static MCSymbolRefExpr::VariantKind +getModifierVariantKind(XtensaCP::XtensaCPModifier Modifier) { + switch (Modifier) { + case XtensaCP::no_modifier: + return MCSymbolRefExpr::VK_None; + case XtensaCP::TPOFF: + return MCSymbolRefExpr::VK_TPOFF; + } + llvm_unreachable("Invalid XtensaCPModifier!"); +} + void XtensaAsmPrinter::emitInstruction(const MachineInstr *MI) { XtensaMCInstLower Lower(MF->getContext(), *this); MCInst LoweredMI; @@ -35,6 +47,164 @@ EmitToStreamer(*OutStreamer, LoweredMI); } +/// EmitConstantPool - Print to the current output stream assembly +/// representations of the constants in the constant pool MCP. This is +/// used to print out constants which have been "spilled to memory" by +/// the code generator. +void XtensaAsmPrinter::emitConstantPool() { + const Function &F = MF->getFunction(); + const MachineConstantPool *MCP = MF->getConstantPool(); + const std::vector &CP = MCP->getConstants(); + if (CP.empty()) + return; + + for (unsigned i = 0, e = CP.size(); i != e; ++i) { + const MachineConstantPoolEntry &CPE = CP[i]; + + if (i == 0) { + if (OutStreamer->hasRawTextSupport()) { + OutStreamer->switchSection( + getObjFileLowering().SectionForGlobal(&F, TM)); + OutStreamer->emitRawText(StringRef("\t.literal_position\n")); + } else { + MCSectionELF *CS = + (MCSectionELF *)getObjFileLowering().SectionForGlobal(&F, TM); + std::string CSectionName = CS->getName().str(); + std::size_t Pos = CSectionName.find(".text"); + std::string SectionName; + if (Pos != std::string::npos) { + if (Pos > 0) + SectionName = CSectionName.substr(0, Pos + 5); + else + SectionName = ""; + SectionName += ".literal"; + SectionName += CSectionName.substr(Pos + 5); + } else { + SectionName = CSectionName; + SectionName += ".literal"; + } + + MCSectionELF *S = + OutContext.getELFSection(SectionName, ELF::SHT_PROGBITS, + ELF::SHF_EXECINSTR | ELF::SHF_ALLOC); + S->setAlignment(Align(4)); + OutStreamer->switchSection(S); + } + } + + if (CPE.isMachineConstantPoolEntry()) { + XtensaConstantPoolValue *ACPV = + static_cast(CPE.Val.MachineCPVal); + ACPV->setLabelId(i); + emitMachineConstantPoolValue(CPE.Val.MachineCPVal); + } else { + MCSymbol *LblSym = GetCPISymbol(i); + // TODO find a better way to check whether we emit data to .s file + if (OutStreamer->hasRawTextSupport()) { + std::string str("\t.literal "); + str += LblSym->getName(); + str += ", "; + const Constant *C = CPE.Val.ConstVal; + + Type *Ty = C->getType(); + if (const auto *CFP = dyn_cast(C)) { + str += toString(CFP->getValueAPF().bitcastToAPInt(), 10, true); + } else if (const auto *CI = dyn_cast(C)) { + str += toString(CI->getValue(), 10, true); + } else if (isa(Ty)) { + const MCExpr *ME = lowerConstant(C); + const MCSymbolRefExpr &SRE = cast(*ME); + const MCSymbol &Sym = SRE.getSymbol(); + str += Sym.getName(); + } else { + unsigned NumElements; + if (isa(Ty)) + NumElements = (cast(Ty))->getNumElements(); + else + NumElements = Ty->getArrayNumElements(); + + for (unsigned I = 0; I < NumElements; I++) { + const Constant *CAE = C->getAggregateElement(I); + if (I > 0) + str += ", "; + if (const auto *CFP = dyn_cast(CAE)) { + str += toString(CFP->getValueAPF().bitcastToAPInt(), 10, true); + } else if (const auto *CI = dyn_cast(CAE)) { + str += toString(CI->getValue(), 10, true); + } + } + } + + OutStreamer->emitRawText(StringRef(str)); + } else { + OutStreamer->emitLabel(LblSym); + emitGlobalConstant(getDataLayout(), CPE.Val.ConstVal); + } + } + } +} + +void XtensaAsmPrinter::emitMachineConstantPoolValue( + MachineConstantPoolValue *MCPV) { + XtensaConstantPoolValue *ACPV = static_cast(MCPV); + + MCSymbol *MCSym; + if (ACPV->isBlockAddress()) { + const BlockAddress *BA = + cast(ACPV)->getBlockAddress(); + MCSym = GetBlockAddressSymbol(BA); + } else if (ACPV->isGlobalValue()) { + const GlobalValue *GV = cast(ACPV)->getGV(); + // TODO some modifiers + MCSym = getSymbol(GV); + } else if (ACPV->isMachineBasicBlock()) { + const MachineBasicBlock *MBB = cast(ACPV)->getMBB(); + MCSym = MBB->getSymbol(); + } else if (ACPV->isJumpTable()) { + unsigned idx = cast(ACPV)->getIndex(); + MCSym = this->GetJTISymbol(idx, false); + } else { + assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); + XtensaConstantPoolSymbol *XtensaSym = cast(ACPV); + const char *Sym = XtensaSym->getSymbol(); + // TODO it's a trick to distinguish static references and generated rodata + // references Some clear method required + { + std::string SymName(Sym); + if (XtensaSym->isPrivateLinkage()) + SymName = ".L" + SymName; + MCSym = GetExternalSymbolSymbol(StringRef(SymName)); + } + } + + MCSymbol *LblSym = GetCPISymbol(ACPV->getLabelId()); + // TODO find a better way to check whether we emit data to .s file + if (OutStreamer->hasRawTextSupport()) { + std::string SymName("\t.literal "); + SymName += LblSym->getName(); + SymName += ", "; + SymName += MCSym->getName(); + + StringRef Modifier = ACPV->getModifierText(); + SymName += Modifier; + + OutStreamer->emitRawText(StringRef(SymName)); + } else { + MCSymbolRefExpr::VariantKind VK = + getModifierVariantKind(ACPV->getModifier()); + + if (ACPV->getModifier() != XtensaCP::no_modifier) { + std::string SymName(MCSym->getName()); + MCSym = GetExternalSymbolSymbol(StringRef(SymName)); + } + + const MCExpr *Expr = MCSymbolRefExpr::create(MCSym, VK, OutContext); + uint64_t Size = getDataLayout().getTypeAllocSize(ACPV->getType()); + OutStreamer->emitLabel(LblSym); + OutStreamer->emitValue(Expr, Size); + } +} + // Force static initialization. extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmPrinter() { RegisterAsmPrinter A(getTheXtensaTarget());