[llvm] [Xtensa] Implement base CallConvention. (PR #83280)

Sergei Barannikov via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 23 17:04:26 PDT 2024


================
@@ -25,12 +29,193 @@
 
 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;
+  }
+  report_fatal_error("Invalid XtensaCPModifier!");
+}
+
 void XtensaAsmPrinter::emitInstruction(const MachineInstr *MI) {
   MCInst LoweredMI;
   lowerToMCInst(MI, LoweredMI);
   EmitToStreamer(*OutStreamer, LoweredMI);
 }
 
+void XtensaAsmPrinter::emitMachineConstantPoolValue(
+    MachineConstantPoolValue *MCPV) {
+  XtensaConstantPoolValue *ACPV = static_cast<XtensaConstantPoolValue *>(MCPV);
+  MCSymbol *MCSym;
+
+  assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
+
+  XtensaConstantPoolSymbol *XtensaSym = cast<XtensaConstantPoolSymbol>(ACPV);
+  const char *Sym = XtensaSym->getSymbol();
+  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()) {
+    SmallString<60> Str;
+    raw_svector_ostream LiteralStr(Str);
+    LiteralStr << "\t.literal " << LblSym->getName() << ", "
+               << MCSym->getName();
+
+    StringRef Modifier = ACPV->getModifierText();
+    LiteralStr << Modifier;
+
+    OutStreamer->emitRawText(StringRef(LiteralStr.str()));
+  } 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->emitCodeAlignment(
+        Align(4), OutStreamer->getContext().getSubtargetInfo());
+    OutStreamer->emitLabel(LblSym);
+    OutStreamer->emitValue(Expr, Size);
+  }
+}
+
+void XtensaAsmPrinter::emitMachineConstantPoolEntry(
+    const MachineConstantPoolEntry &CPE, int i) {
+  if (CPE.isMachineConstantPoolEntry()) {
+    XtensaConstantPoolValue *ACPV =
+        static_cast<XtensaConstantPoolValue *>(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()) {
+      SmallString<60> Str;
+      raw_svector_ostream LiteralStr(Str);
+      LiteralStr << "\t.literal " << LblSym->getName() << ", ";
+
+      const Constant *C = CPE.Val.ConstVal;
+
+      if (const auto *CFP = dyn_cast<ConstantFP>(C)) {
+        LiteralStr << toString(CFP->getValueAPF().bitcastToAPInt(), 10, true);
+      } else if (const auto *CI = dyn_cast<ConstantInt>(C)) {
+        LiteralStr << toString(CI->getValue(), 10, true);
+      } else {
+        report_fatal_error(
+            "This constant type is not supported yet in constantpool");
+      }
+
+      OutStreamer->emitRawText(StringRef(LiteralStr.str()));
+    } else {
+      OutStreamer->emitCodeAlignment(
+          Align(4), OutStreamer->getContext().getSubtargetInfo());
+      OutStreamer->emitLabel(LblSym);
+      emitGlobalConstant(getDataLayout(), CPE.Val.ConstVal);
+    }
+  }
+}
+
+// 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<MachineConstantPoolEntry> &CP = MCP->getConstants();
+  if (CP.empty())
+    return;
+
+  if (OutStreamer->hasRawTextSupport()) {
+    OutStreamer->switchSection(getObjFileLowering().SectionForGlobal(&F, TM));
+    OutStreamer->emitRawText(StringRef("\t.literal_position\n"));
+  } else {
+    MCSectionELF *CS =
+        (MCSectionELF *)getObjFileLowering().SectionForGlobal(&F, TM);
+    StringRef CSectionName = CS->getName();
+    std::size_t Pos = CSectionName.find(".text");
+    std::string SectionName;
+    if (Pos != std::string::npos) {
+      SectionName = CSectionName.substr(0, Pos);
+
+      if (Pos > 0)
+        SectionName += ".text";
+
+      CSectionName = CSectionName.drop_front(Pos);
+      CSectionName.consume_front(".text");
+
+      SectionName += ".literal";
+      SectionName += CSectionName;
+    } 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);
+  }
+
+  int CPIdx = 0;
+  for (const MachineConstantPoolEntry &CPE : CP) {
+    emitMachineConstantPoolEntry(CPE, CPIdx++);
+  }
+}
+
+MCSymbol *
+XtensaAsmPrinter::GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
+  // Create a symbol for the name.
+  return GetCPISymbol(MO.getIndex());
+}
+
+MCOperand
+XtensaAsmPrinter::LowerSymbolOperand(const MachineOperand &MO,
+                                     MachineOperand::MachineOperandType MOTy,
+                                     unsigned Offset) const {
----------------
s-barannikov wrote:

It looks like Offset is always zero.

https://github.com/llvm/llvm-project/pull/83280


More information about the llvm-commits mailing list