[llvm] [Xtensa] Initial support of the ALU operations and ConstantPool (PR #78548)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 17 23:51:31 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mc

Author: Andrei Safronov (andreisfr)

<details>
<summary>Changes</summary>

This PR provides implementation of the basic codegen infra such as TargetFrameLowering, CallingConv, TargetLowering, SelectionDAGISe. Initial ConstantPool support has also been implemented.

The PR contains five commits that were originally published on Phabricator (third patch is approved), each commit depends on previous commits, and together these patches provide support for more complex IR tests. Patches have been updated based on reviewers comments from Phabricator and slightly refactored.

Migrated from:
https://reviews.llvm.org/D145658
https://reviews.llvm.org/D145660
https://reviews.llvm.org/D145661 (this Differential is approved in Phabricator)
https://reviews.llvm.org/D145662
https://reviews.llvm.org/D145663

---

Patch is 117.73 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/78548.diff


42 Files Affected:

- (modified) llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp (+134-1) 
- (modified) llvm/lib/Target/Xtensa/CMakeLists.txt (+13) 
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt (+1) 
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp (+1-1) 
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp (+4-4) 
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp (+3-3) 
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.cpp (+1-1) 
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp (+24-2) 
- (added) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.cpp (+87) 
- (added) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.h (+46) 
- (added) llvm/lib/Target/Xtensa/Xtensa.h (+30) 
- (modified) llvm/lib/Target/Xtensa/Xtensa.td (+6) 
- (added) llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp (+183) 
- (added) llvm/lib/Target/Xtensa/XtensaAsmPrinter.h (+46) 
- (added) llvm/lib/Target/Xtensa/XtensaCallingConv.td (+30) 
- (added) llvm/lib/Target/Xtensa/XtensaConstantPoolValue.cpp (+210) 
- (added) llvm/lib/Target/Xtensa/XtensaConstantPoolValue.h (+267) 
- (added) llvm/lib/Target/Xtensa/XtensaFrameLowering.cpp (+44) 
- (added) llvm/lib/Target/Xtensa/XtensaFrameLowering.h (+34) 
- (added) llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp (+130) 
- (added) llvm/lib/Target/Xtensa/XtensaISelLowering.cpp (+429) 
- (added) llvm/lib/Target/Xtensa/XtensaISelLowering.h (+76) 
- (added) llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp (+96) 
- (added) llvm/lib/Target/Xtensa/XtensaInstrInfo.h (+62) 
- (modified) llvm/lib/Target/Xtensa/XtensaInstrInfo.td (+10-1) 
- (added) llvm/lib/Target/Xtensa/XtensaMCInstLower.cpp (+110) 
- (added) llvm/lib/Target/Xtensa/XtensaMCInstLower.h (+50) 
- (modified) llvm/lib/Target/Xtensa/XtensaOperands.td (+1-1) 
- (added) llvm/lib/Target/Xtensa/XtensaOperators.td (+23) 
- (added) llvm/lib/Target/Xtensa/XtensaRegisterInfo.cpp (+118) 
- (added) llvm/lib/Target/Xtensa/XtensaRegisterInfo.h (+60) 
- (added) llvm/lib/Target/Xtensa/XtensaSubtarget.cpp (+46) 
- (added) llvm/lib/Target/Xtensa/XtensaSubtarget.h (+72) 
- (modified) llvm/lib/Target/Xtensa/XtensaTargetMachine.cpp (+28-2) 
- (modified) llvm/lib/Target/Xtensa/XtensaTargetMachine.h (+6) 
- (added) llvm/lib/Target/Xtensa/XtensaUtils.cpp (+60) 
- (added) llvm/lib/Target/Xtensa/XtensaUtils.h (+27) 
- (added) llvm/test/CodeGen/Xtensa/alu.ll (+158) 
- (added) llvm/test/CodeGen/Xtensa/constantpool.ll (+80) 
- (added) llvm/test/CodeGen/Xtensa/stack-access.ll (+36) 
- (modified) llvm/test/MC/Xtensa/Core/invalid.s (-4) 
- (added) llvm/test/MC/Xtensa/directive-literal.s (+42) 


``````````diff
diff --git a/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp b/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
index 3f808298527f8fc..9fd05ee96a9290d 100644
--- a/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
+++ b/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
@@ -8,7 +8,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "MCTargetDesc/XtensaMCExpr.h"
 #include "MCTargetDesc/XtensaMCTargetDesc.h"
+#include "MCTargetDesc/XtensaTargetStreamer.h"
 #include "TargetInfo/XtensaTargetInfo.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -22,6 +24,7 @@
 #include "llvm/MC/MCRegisterInfo.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/TargetRegistry.h"
 #include "llvm/Support/Casting.h"
 
@@ -35,6 +38,12 @@ class XtensaAsmParser : public MCTargetAsmParser {
 
   SMLoc getLoc() const { return getParser().getTok().getLoc(); }
 
+  XtensaTargetStreamer &getTargetStreamer() {
+    MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
+    return static_cast<XtensaTargetStreamer &>(TS);
+  }
+
+  bool ParseDirective(AsmToken DirectiveID) override;
   bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                         SMLoc NameLoc, OperandVector &Operands) override;
@@ -45,6 +54,9 @@ class XtensaAsmParser : public MCTargetAsmParser {
   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
                                       unsigned Kind) override;
 
+  bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+                          const MCSubtargetInfo *STI);
+
 // Auto-generated instruction matching functions
 #define GET_ASSEMBLER_HEADER
 #include "XtensaGenAsmMatcher.inc"
@@ -62,6 +74,7 @@ class XtensaAsmParser : public MCTargetAsmParser {
     return ParseStatus::NoMatch;
   }
   ParseStatus parsePCRelTarget(OperandVector &Operands);
+  bool parseLiteralDirective(SMLoc L);
 
 public:
   enum XtensaMatchResultTy {
@@ -148,7 +161,13 @@ struct XtensaOperand : public MCParsedAsmOperand {
 
   bool isImm12() const { return isImm(-2048, 2047); }
 
-  bool isImm12m() const { return isImm(-2048, 2047); }
+  // Convert MOVI to literal load, when immediate is not in range (-2048, 2047)
+  bool isImm12m() const {
+    if (Kind == Immediate)
+      return true;
+
+    return false;
+  }
 
   bool isOffset4m32() const {
     return isImm(0, 60) &&
@@ -348,6 +367,67 @@ static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
   return Loc;
 }
 
+bool XtensaAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
+                                         MCStreamer &Out,
+                                         const MCSubtargetInfo *STI) {
+  Inst.setLoc(IDLoc);
+  const unsigned Opcode = Inst.getOpcode();
+  switch (Opcode) {
+  case Xtensa::L32R: {
+    const MCSymbolRefExpr *OpExpr =
+        (const MCSymbolRefExpr *)Inst.getOperand(1).getExpr();
+    XtensaMCExpr::VariantKind Kind = XtensaMCExpr::VK_Xtensa_None;
+    const MCExpr *NewOpExpr = XtensaMCExpr::create(OpExpr, Kind, getContext());
+    Inst.getOperand(1).setExpr(NewOpExpr);
+  } break;
+  case Xtensa::MOVI: {
+    XtensaTargetStreamer &TS = this->getTargetStreamer();
+
+    // Expand MOVI operand
+    if (!Inst.getOperand(1).isExpr()) {
+      uint64_t ImmOp64 = Inst.getOperand(1).getImm();
+      int32_t Imm = ImmOp64;
+      if ((Imm < -2048) || (Imm > 2047)) {
+        XtensaTargetStreamer &TS = this->getTargetStreamer();
+        MCInst TmpInst;
+        TmpInst.setLoc(IDLoc);
+        TmpInst.setOpcode(Xtensa::L32R);
+        const MCExpr *Value = MCConstantExpr::create(ImmOp64, getContext());
+        MCSymbol *Sym = getContext().createTempSymbol();
+        const MCExpr *Expr = MCSymbolRefExpr::create(
+            Sym, MCSymbolRefExpr::VK_None, getContext());
+        const MCExpr *OpExpr = XtensaMCExpr::create(
+            Expr, XtensaMCExpr::VK_Xtensa_None, getContext());
+        TmpInst.addOperand(Inst.getOperand(0));
+        MCOperand Op1 = MCOperand::createExpr(OpExpr);
+        TmpInst.addOperand(Op1);
+        TS.emitLiteral(Sym, Value, IDLoc);
+        Inst = TmpInst;
+      }
+    } else {
+      MCInst TmpInst;
+      TmpInst.setLoc(IDLoc);
+      TmpInst.setOpcode(Xtensa::L32R);
+      const MCExpr *Value = Inst.getOperand(1).getExpr();
+      MCSymbol *Sym = getContext().createTempSymbol();
+      const MCExpr *Expr =
+          MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
+      const MCExpr *OpExpr = XtensaMCExpr::create(
+          Expr, XtensaMCExpr::VK_Xtensa_None, getContext());
+      TmpInst.addOperand(Inst.getOperand(0));
+      MCOperand Op1 = MCOperand::createExpr(OpExpr);
+      TmpInst.addOperand(Op1);
+      Inst = TmpInst;
+      TS.emitLiteral(Sym, Value, IDLoc);
+    }
+  } break;
+  default:
+    break;
+  }
+
+  return true;
+}
+
 bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                                               OperandVector &Operands,
                                               MCStreamer &Out,
@@ -361,6 +441,7 @@ bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   default:
     break;
   case Match_Success:
+    processInstruction(Inst, IDLoc, Out, STI);
     Inst.setLoc(IDLoc);
     Out.emitInstruction(Inst, getSTI());
     return false;
@@ -686,6 +767,58 @@ bool XtensaAsmParser::ParseInstruction(ParseInstructionInfo &Info,
   return false;
 }
 
+bool XtensaAsmParser::parseLiteralDirective(SMLoc L) {
+  MCAsmParser &Parser = getParser();
+  MCSymbol *Sym;
+  const MCExpr *Value;
+  SMLoc LiteralLoc = getLexer().getLoc();
+  XtensaTargetStreamer &TS = this->getTargetStreamer();
+
+  if (Parser.parseExpression(Value))
+    return true;
+
+  const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Value);
+  if (!SE)
+    return Error(LiteralLoc, "literal label must be a symbol");
+  else {
+    Sym = getContext().getOrCreateSymbol(SE->getSymbol().getName());
+  }
+
+  if (Parser.parseToken(AsmToken::Comma, "expected comma"))
+    return true;
+
+  SMLoc OpcodeLoc = getLexer().getLoc();
+  if (parseOptionalToken(AsmToken::EndOfStatement))
+    return Error(OpcodeLoc, "expected value");
+
+  if (Parser.parseExpression(Value))
+    return true;
+
+  TS.emitLiteral(Sym, Value, LiteralLoc);
+
+  return false;
+}
+
+bool XtensaAsmParser::ParseDirective(AsmToken DirectiveID) {
+  StringRef IDVal = DirectiveID.getString();
+  SMLoc Loc = getLexer().getLoc();
+
+  if (IDVal == ".literal_position") {
+    XtensaTargetStreamer &TS = this->getTargetStreamer();
+    TS.emitLiteralPosition();
+    Lex();
+    return false;
+  }
+
+  if (IDVal == ".literal") {
+    parseLiteralDirective(Loc);
+    Lex();
+    return false;
+  }
+
+  return true;
+}
+
 // Force static initialization.
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmParser() {
   RegisterMCAsmParser<XtensaAsmParser> X(getTheXtensaTarget());
diff --git a/llvm/lib/Target/Xtensa/CMakeLists.txt b/llvm/lib/Target/Xtensa/CMakeLists.txt
index 7192f7392072b31..f0abf3e550a124e 100644
--- a/llvm/lib/Target/Xtensa/CMakeLists.txt
+++ b/llvm/lib/Target/Xtensa/CMakeLists.txt
@@ -4,6 +4,8 @@ set(LLVM_TARGET_DEFINITIONS Xtensa.td)
 
 tablegen(LLVM XtensaGenAsmMatcher.inc -gen-asm-matcher)
 tablegen(LLVM XtensaGenAsmWriter.inc -gen-asm-writer)
+tablegen(LLVM XtensaGenCallingConv.inc -gen-callingconv)
+tablegen(LLVM XtensaGenDAGISel.inc -gen-dag-isel)
 tablegen(LLVM XtensaGenDisassemblerTables.inc -gen-disassembler)
 tablegen(LLVM XtensaGenInstrInfo.inc -gen-instr-info)
 tablegen(LLVM XtensaGenMCCodeEmitter.inc -gen-emitter)
@@ -13,13 +15,24 @@ tablegen(LLVM XtensaGenSubtargetInfo.inc -gen-subtarget)
 add_public_tablegen_target(XtensaCommonTableGen)
 
 add_llvm_target(XtensaCodeGen
+  XtensaAsmPrinter.cpp
+  XtensaConstantPoolValue.cpp
+  XtensaFrameLowering.cpp
+  XtensaInstrInfo.cpp
+  XtensaISelDAGToDAG.cpp
+  XtensaISelLowering.cpp
+  XtensaMCInstLower.cpp
+  XtensaRegisterInfo.cpp
+  XtensaSubtarget.cpp
   XtensaTargetMachine.cpp
+  XtensaUtils.cpp
 
   LINK_COMPONENTS
   AsmPrinter
   CodeGen
   Core
   MC
+  SelectionDAG
   Support
   Target
   XtensaDesc
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
index 6841b44f9d569cd..dc12863394c7ad0 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/CMakeLists.txt
@@ -6,6 +6,7 @@ add_llvm_component_library(LLVMXtensaDesc
   XtensaMCCodeEmitter.cpp
   XtensaMCExpr.cpp
   XtensaMCTargetDesc.cpp
+  XtensaTargetStreamer.cpp
 
   LINK_COMPONENTS
   MC
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
index db4484bb57c1ad7..c87e2187b73d4e6 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
@@ -84,7 +84,7 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
   unsigned Kind = Fixup.getKind();
   switch (Kind) {
   default:
-    llvm_unreachable("Unknown fixup kind!");
+    report_fatal_error("Unknown fixup kind!");
   case FK_Data_1:
   case FK_Data_2:
   case FK_Data_4:
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
index fe1dc0e2e483e72..f234d5e900a472a 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
@@ -102,7 +102,7 @@ void XtensaInstPrinter::printBranchTarget(const MCInst *MI, int OpNum,
   } else if (MC.isExpr())
     MC.getExpr()->print(OS, &MAI, true);
   else
-    llvm_unreachable("Invalid operand");
+    report_fatal_error("Invalid operand");
 }
 
 void XtensaInstPrinter::printJumpTarget(const MCInst *MI, int OpNum,
@@ -117,7 +117,7 @@ void XtensaInstPrinter::printJumpTarget(const MCInst *MI, int OpNum,
   } else if (MC.isExpr())
     MC.getExpr()->print(OS, &MAI, true);
   else
-    llvm_unreachable("Invalid operand");
+    report_fatal_error("Invalid operand");
   ;
 }
 
@@ -133,7 +133,7 @@ void XtensaInstPrinter::printCallOperand(const MCInst *MI, int OpNum,
   } else if (MC.isExpr())
     MC.getExpr()->print(OS, &MAI, true);
   else
-    llvm_unreachable("Invalid operand");
+    report_fatal_error("Invalid operand");
 }
 
 void XtensaInstPrinter::printL32RTarget(const MCInst *MI, int OpNum,
@@ -151,7 +151,7 @@ void XtensaInstPrinter::printL32RTarget(const MCInst *MI, int OpNum,
   } else if (MC.isExpr())
     MC.getExpr()->print(O, &MAI, true);
   else
-    llvm_unreachable("Invalid operand");
+    report_fatal_error("Invalid operand");
 }
 
 void XtensaInstPrinter::printImm8_AsmOperand(const MCInst *MI, int OpNum,
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
index 1afdbb38f9571a2..c6941499cba192d 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
@@ -203,7 +203,7 @@ XtensaMCCodeEmitter::getCallEncoding(const MCInst &MI, unsigned int OpNum,
   if (MO.isImm()) {
     int32_t Res = MO.getImm();
     if (Res & 0x3) {
-      llvm_unreachable("Unexpected operand value!");
+      report_fatal_error("Unexpected operand value!");
     }
     Res >>= 2;
     return Res;
@@ -396,7 +396,7 @@ XtensaMCCodeEmitter::getB4constOpValue(const MCInst &MI, unsigned OpNo,
     Res = 15;
     break;
   default:
-    llvm_unreachable("Unexpected operand value!");
+    report_fatal_error("Unexpected operand value!");
   }
 
   return Res;
@@ -446,7 +446,7 @@ XtensaMCCodeEmitter::getB4constuOpValue(const MCInst &MI, unsigned OpNo,
     Res = 15;
     break;
   default:
-    llvm_unreachable("Unexpected operand value!");
+    report_fatal_error("Unexpected operand value!");
   }
 
   return Res;
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.cpp
index cafd8b7e2978202..2d0db1aae0645b3 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCExpr.cpp
@@ -58,6 +58,6 @@ XtensaMCExpr::VariantKind XtensaMCExpr::getVariantKindForName(StringRef name) {
 StringRef XtensaMCExpr::getVariantKindName(VariantKind Kind) {
   switch (Kind) {
   default:
-    llvm_unreachable("Invalid ELF symbol kind");
+    report_fatal_error("Invalid ELF symbol kind");
   }
 }
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
index 48674d15bdfbe27..8914ebf658cc434 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
@@ -10,6 +10,7 @@
 #include "XtensaMCTargetDesc.h"
 #include "XtensaInstPrinter.h"
 #include "XtensaMCAsmInfo.h"
+#include "XtensaTargetStreamer.h"
 #include "TargetInfo/XtensaTargetInfo.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/MC/MCAsmInfo.h"
@@ -63,16 +64,29 @@ createXtensaMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
   return createXtensaMCSubtargetInfoImpl(TT, CPU, CPU, FS);
 }
 
+static MCTargetStreamer *
+createXtensaAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS,
+                              MCInstPrinter *InstPrint, bool isVerboseAsm) {
+  return new XtensaTargetAsmStreamer(S, OS);
+}
+
+static MCTargetStreamer *
+createXtensaObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
+  return new XtensaTargetELFStreamer(S);
+}
+
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTargetMC() {
   // Register the MCAsmInfo.
-  TargetRegistry::RegisterMCAsmInfo(getTheXtensaTarget(), createXtensaMCAsmInfo);
+  TargetRegistry::RegisterMCAsmInfo(getTheXtensaTarget(),
+                                    createXtensaMCAsmInfo);
 
   // Register the MCCodeEmitter.
   TargetRegistry::RegisterMCCodeEmitter(getTheXtensaTarget(),
                                         createXtensaMCCodeEmitter);
 
   // Register the MCInstrInfo.
-  TargetRegistry::RegisterMCInstrInfo(getTheXtensaTarget(), createXtensaMCInstrInfo);
+  TargetRegistry::RegisterMCInstrInfo(getTheXtensaTarget(),
+                                      createXtensaMCInstrInfo);
 
   // Register the MCInstPrinter.
   TargetRegistry::RegisterMCInstPrinter(getTheXtensaTarget(),
@@ -89,4 +103,12 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaTargetMC() {
   // Register the MCAsmBackend.
   TargetRegistry::RegisterMCAsmBackend(getTheXtensaTarget(),
                                        createXtensaMCAsmBackend);
+
+  // Register the asm target streamer.
+  TargetRegistry::RegisterAsmTargetStreamer(getTheXtensaTarget(),
+                                            createXtensaAsmTargetStreamer);
+
+  // Register the ELF target streamer.
+  TargetRegistry::RegisterObjectTargetStreamer(
+      getTheXtensaTarget(), createXtensaObjectTargetStreamer);
 }
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.cpp
new file mode 100644
index 000000000000000..4163e64de48f091
--- /dev/null
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.cpp
@@ -0,0 +1,87 @@
+//===-- XtensaTargetStreamer.cpp - Xtensa Target Streamer Methods ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides Xtensa specific target streamer methods.
+//
+//===----------------------------------------------------------------------===//
+
+#include "XtensaTargetStreamer.h"
+#include "XtensaInstPrinter.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCSectionELF.h"
+#include "llvm/Support/FormattedStream.h"
+
+using namespace llvm;
+
+XtensaTargetStreamer::XtensaTargetStreamer(MCStreamer &S)
+    : MCTargetStreamer(S) {}
+
+XtensaTargetAsmStreamer::XtensaTargetAsmStreamer(MCStreamer &S,
+                                                 formatted_raw_ostream &OS)
+    : XtensaTargetStreamer(S), OS(OS) {}
+
+void XtensaTargetAsmStreamer::emitLiteral(MCSymbol *LblSym, const MCExpr *Value,
+                                          SMLoc L) {
+  const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
+
+  OS << "\t.literal\t";
+  LblSym->print(OS, MAI);
+  OS << ", ";
+  Value->print(OS, MAI);
+  OS << '\n';
+}
+
+void XtensaTargetAsmStreamer::emitLiteralPosition() {
+  OS << "\t.literal_position\n";
+}
+
+XtensaTargetELFStreamer::XtensaTargetELFStreamer(MCStreamer &S)
+    : XtensaTargetStreamer(S) {}
+
+static std::string getLiteralSectionName(std::string CSectionName) {
+  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";
+  }
+  return SectionName;
+}
+
+void XtensaTargetELFStreamer::emitLiteral(MCSymbol *LblSym, const MCExpr *Value,
+                                          SMLoc L) {
+  MCContext &Context = getStreamer().getContext();
+  MCStreamer &OutStreamer = getStreamer();
+  MCSectionELF *CS = (MCSectionELF *)OutStreamer.getCurrentSectionOnly();
+  std::string SectionName = getLiteralSectionName(CS->getName().str());
+
+  MCSection *ConstSection = Context.getELFSection(
+      SectionName, ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC);
+
+  OutStreamer.pushSection();
+  OutStreamer.switchSection(ConstSection);
+  OutStreamer.emitLabel(LblSym, L);
+  OutStreamer.emitValue(Value, 4, L);
+  OutStreamer.popSection();
+}
+
+MCELFStreamer &XtensaTargetELFStreamer::getStreamer() {
+  return static_cast<MCELFStreamer &>(Streamer);
+}
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.h b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.h
new file mode 100644
index 000000000000000..a7d8b6dd9c792b5
--- /dev/null
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.h
@@ -0,0 +1,46 @@
+//===-- XtensaTargetStreamer.h - Xtensa Target Streamer --------*- C++ -*--===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_XTENSA_XTENSATARGETSTREAMER_H
+#define LLVM_LIB_TARGET_XTENSA_XTENSATARGETSTREAMER_H
+
+#include "llvm/MC/MCELFStreamer.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/Support/SMLoc.h"
+
+namespace llvm {
+class formatted_raw_ostream;
+
+class XtensaTargetStreamer : public MCTargetStreamer {
+public:
+  XtensaTargetStreamer(MCStreamer &S);
+  virtual void emitLiteral(MCSymbol *LblSym, const MCExpr *Value, SMLoc L) = 0;
+  virtual void emitLiteralPosition() = 0;
+};
+
+class XtensaTargetAsmStreamer : public XtensaTargetStreamer {
+  formatted_raw_ostream &OS;
+
+public:
+  XtensaTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
+  void emitLiteral(MCSymbol *LblSym, const MCExpr *Value, SMLoc L) override;
+  void emitLiteralPosition() override;
+};
+
+class XtensaTargetELFStreamer : public XtensaTargetStreamer {
+public:
+  XtensaTargetELFStreamer(MCStreamer &S);
+  MCELFStreamer &getStreamer();
+  void emitLiteral(MCSymbol *LblSym, const MCExpr *Value, SMLoc L) override;
+  void emitLiteralPosition() override {}
+};
+} // end namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/Xtensa/Xtensa.h b/llvm/lib/Target/Xtensa/Xtensa.h
new file mode...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list