[llvm] [Xtensa] Implement Windowed Register Option. (PR #124656)

Andrei Safronov via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 30 04:57:25 PST 2025


https://github.com/andreisfr updated https://github.com/llvm/llvm-project/pull/124656

>From 930a180db5a3fb280d20f2a41af64335168e2cd8 Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Tue, 28 Jan 2025 02:28:34 +0300
Subject: [PATCH 1/3] [Xtensa] Implement Windowed Register Option.

This patch implements Xtensa ISA option "Windowed Register Option".
It implements subtarget feature, instructions descriptions and support
of these instruction in asm parser and disassembler.

This is the second version of the Windowed Register Option implementation.
Previous implementation #121118. In this variant "checkRegister"
function placed in XtensaMCTargetDesc.
---
 .../Xtensa/AsmParser/XtensaAsmParser.cpp      |  31 +++++-
 .../Disassembler/XtensaDisassembler.cpp       |  33 +++++-
 .../Xtensa/MCTargetDesc/XtensaInstPrinter.cpp |  34 ++++++
 .../Xtensa/MCTargetDesc/XtensaInstPrinter.h   |   3 +
 .../MCTargetDesc/XtensaMCCodeEmitter.cpp      |  52 +++++++++
 .../MCTargetDesc/XtensaMCTargetDesc.cpp       |  13 +++
 .../Xtensa/MCTargetDesc/XtensaMCTargetDesc.h  |   5 +
 llvm/lib/Target/Xtensa/Xtensa.td              |   7 +-
 llvm/lib/Target/Xtensa/XtensaFeatures.td      |  14 +++
 llvm/lib/Target/Xtensa/XtensaInstrInfo.td     | 101 +++++++++++++++++
 llvm/lib/Target/Xtensa/XtensaOperands.td      |  21 ++++
 llvm/lib/Target/Xtensa/XtensaRegisterInfo.td  |   6 +-
 llvm/lib/Target/Xtensa/XtensaSubtarget.h      |   7 +-
 llvm/test/MC/Disassembler/Xtensa/windowed.txt |  72 ++++++++++++
 .../Xtensa/windowed_code_density.txt          |  12 ++
 llvm/test/MC/Xtensa/windowed.s                | 105 ++++++++++++++++++
 llvm/test/MC/Xtensa/windowed_code_density.s   |  14 +++
 llvm/test/MC/Xtensa/windowed_invalid.s        |  23 ++++
 18 files changed, 544 insertions(+), 9 deletions(-)
 create mode 100644 llvm/lib/Target/Xtensa/XtensaFeatures.td
 create mode 100644 llvm/test/MC/Disassembler/Xtensa/windowed.txt
 create mode 100644 llvm/test/MC/Disassembler/Xtensa/windowed_code_density.txt
 create mode 100644 llvm/test/MC/Xtensa/windowed.s
 create mode 100644 llvm/test/MC/Xtensa/windowed_code_density.s
 create mode 100644 llvm/test/MC/Xtensa/windowed_invalid.s

diff --git a/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp b/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
index 731f9535ca251f..0c9258ecd65ecb 100644
--- a/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
+++ b/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
@@ -73,6 +73,7 @@ class XtensaAsmParser : public MCTargetAsmParser {
                                SMLoc &EndLoc) override {
     return ParseStatus::NoMatch;
   }
+
   ParseStatus parsePCRelTarget(OperandVector &Operands);
   bool parseLiteralDirective(SMLoc L);
 
@@ -89,6 +90,10 @@ class XtensaAsmParser : public MCTargetAsmParser {
       : MCTargetAsmParser(Options, STI, MII) {
     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
   }
+
+  bool hasWindowed() const {
+    return getSTI().getFeatureBits()[Xtensa::FeatureWindowed];
+  };
 };
 
 // Return true if Expr is in the range [MinValue, MaxValue].
@@ -181,6 +186,11 @@ struct XtensaOperand : public MCParsedAsmOperand {
            ((cast<MCConstantExpr>(getImm())->getValue() & 0x3) == 0);
   }
 
+  bool isentry_imm12() const {
+    return isImm(0, 32760) &&
+           ((cast<MCConstantExpr>(getImm())->getValue() % 8) == 0);
+  }
+
   bool isUimm4() const { return isImm(0, 15); }
 
   bool isUimm5() const { return isImm(0, 31); }
@@ -198,6 +208,11 @@ struct XtensaOperand : public MCParsedAsmOperand {
 
   bool isImm32n_95() const { return isImm(-32, 95); }
 
+  bool isImm64n_4n() const {
+    return isImm(-64, -4) &&
+           ((cast<MCConstantExpr>(getImm())->getValue() & 0x3) == 0);
+  }
+
   bool isB4const() const {
     if (Kind != Immediate)
       return false;
@@ -491,6 +506,12 @@ bool XtensaAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   case Match_InvalidImm32n_95:
     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
                  "expected immediate in range [-32, 95]");
+  case Match_InvalidImm64n_4n:
+    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
+                 "expected immediate in range [-64, -4]");
+  case Match_InvalidImm8n_7:
+    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
+                 "expected immediate in range [-8, 7]");
   case Match_InvalidShimm1_31:
     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
                  "expected immediate in range [1, 31]");
@@ -515,6 +536,10 @@ bool XtensaAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
                  "expected immediate in range [0, 60], first 2 bits "
                  "should be zero");
+  case Match_Invalidentry_imm12:
+    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
+                 "expected immediate in range [0, 32760], first 3 bits "
+                 "should be zero");
   }
 
   report_fatal_error("Unknown match type detected!");
@@ -601,6 +626,10 @@ ParseStatus XtensaAsmParser::parseRegister(OperandVector &Operands,
       getLexer().UnLex(Buf[0]);
     return ParseStatus::NoMatch;
   }
+
+  if (!Xtensa::checkRegister(RegNo, getSTI().getFeatureBits()))
+    return ParseStatus::NoMatch;
+
   if (HadParens)
     Operands.push_back(XtensaOperand::createToken("(", FirstS));
   SMLoc S = getLoc();
@@ -702,7 +731,7 @@ bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
     if (RegNo == 0)
       RegNo = MatchRegisterAltName(RegName);
 
-    if (RegNo == 0)
+    if (!Xtensa::checkRegister(RegNo, getSTI().getFeatureBits()))
       return Error(NameLoc, "invalid register name");
 
     // Parse operand
diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
index c11c4b7038bdb7..f6270b4d898254 100644
--- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
+++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
@@ -73,17 +73,23 @@ static DecodeStatus DecodeARRegisterClass(MCInst &Inst, uint64_t RegNo,
   return MCDisassembler::Success;
 }
 
-static const unsigned SRDecoderTable[] = {Xtensa::SAR, 3};
+static const unsigned SRDecoderTable[] = {
+    Xtensa::SAR, 3, Xtensa::WINDOWBASE, 72, Xtensa::WINDOWSTART, 73};
 
 static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
                                           uint64_t Address,
-                                          const void *Decoder) {
+                                          const MCDisassembler *Decoder) {
   if (RegNo > 255)
     return MCDisassembler::Fail;
 
   for (unsigned i = 0; i < std::size(SRDecoderTable); i += 2) {
     if (SRDecoderTable[i + 1] == RegNo) {
       unsigned Reg = SRDecoderTable[i];
+
+      if (!Xtensa::checkRegister(Reg,
+                                 Decoder->getSubtargetInfo().getFeatureBits()))
+        return MCDisassembler::Fail;
+
       Inst.addOperand(MCOperand::createReg(Reg));
       return MCDisassembler::Success;
     }
@@ -210,6 +216,29 @@ static DecodeStatus decodeImm32n_95Operand(MCInst &Inst, uint64_t Imm,
   return MCDisassembler::Success;
 }
 
+static DecodeStatus decodeImm8n_7Operand(MCInst &Inst, uint64_t Imm,
+                                         int64_t Address, const void *Decoder) {
+  assert(isUInt<4>(Imm) && "Invalid immediate");
+  Inst.addOperand(MCOperand::createImm(Imm > 7 ? Imm - 16 : Imm));
+  return MCDisassembler::Success;
+}
+
+static DecodeStatus decodeImm64n_4nOperand(MCInst &Inst, uint64_t Imm,
+                                           int64_t Address,
+                                           const void *Decoder) {
+  assert(isUInt<6>(Imm) && ((Imm & 0x3) == 0) && "Invalid immediate");
+  Inst.addOperand(MCOperand::createImm((~0x3f) | (Imm)));
+  return MCDisassembler::Success;
+}
+
+static DecodeStatus decodeEntry_Imm12OpValue(MCInst &Inst, uint64_t Imm,
+                                             int64_t Address,
+                                             const void *Decoder) {
+  assert(isUInt<15>(Imm) && ((Imm & 0x7) == 0) && "Invalid immediate");
+  Inst.addOperand(MCOperand::createImm(Imm));
+  return MCDisassembler::Success;
+}
+
 static DecodeStatus decodeShimm1_31Operand(MCInst &Inst, uint64_t Imm,
                                            int64_t Address,
                                            const void *Decoder) {
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
index df8a0854f06f41..868c7f6c0b9c3c 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
@@ -264,6 +264,28 @@ void XtensaInstPrinter::printImm32n_95_AsmOperand(const MCInst *MI, int OpNum,
     printOperand(MI, OpNum, O);
 }
 
+void XtensaInstPrinter::printImm8n_7_AsmOperand(const MCInst *MI, int OpNum,
+                                                raw_ostream &O) {
+  if (MI->getOperand(OpNum).isImm()) {
+    int64_t Value = MI->getOperand(OpNum).getImm();
+    assert((Value >= -8 && Value <= 7) &&
+           "Invalid argument, value must be in ranges <-8,7>");
+    O << Value;
+  } else
+    printOperand(MI, OpNum, O);
+}
+
+void XtensaInstPrinter::printImm64n_4n_AsmOperand(const MCInst *MI, int OpNum,
+                                                  raw_ostream &O) {
+  if (MI->getOperand(OpNum).isImm()) {
+    int64_t Value = MI->getOperand(OpNum).getImm();
+    assert((Value >= -64 && Value <= -4) & ((Value & 0x3) == 0) &&
+           "Invalid argument, value must be in ranges <-64,-4>");
+    O << Value;
+  } else
+    printOperand(MI, OpNum, O);
+}
+
 void XtensaInstPrinter::printOffset8m8_AsmOperand(const MCInst *MI, int OpNum,
                                                   raw_ostream &O) {
   if (MI->getOperand(OpNum).isImm()) {
@@ -309,6 +331,18 @@ void XtensaInstPrinter::printOffset4m32_AsmOperand(const MCInst *MI, int OpNum,
     printOperand(MI, OpNum, O);
 }
 
+void XtensaInstPrinter::printEntry_Imm12_AsmOperand(const MCInst *MI, int OpNum,
+                                                    raw_ostream &O) {
+  if (MI->getOperand(OpNum).isImm()) {
+    int64_t Value = MI->getOperand(OpNum).getImm();
+    assert((Value >= 0 && Value <= 32760) &&
+           "Invalid argument, value must be multiples of eight in range "
+           "<0,32760>");
+    O << Value;
+  } else
+    printOperand(MI, OpNum, O);
+}
+
 void XtensaInstPrinter::printB4const_AsmOperand(const MCInst *MI, int OpNum,
                                                 raw_ostream &O) {
   if (MI->getOperand(OpNum).isImm()) {
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
index e5bc67869e103d..630b4dd60108ff 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
@@ -60,10 +60,13 @@ class XtensaInstPrinter : public MCInstPrinter {
   void printImm1_16_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
   void printImm1n_15_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
   void printImm32n_95_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
+  void printImm8n_7_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
+  void printImm64n_4n_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
   void printOffset8m8_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
   void printOffset8m16_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
   void printOffset8m32_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
   void printOffset4m32_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
+  void printEntry_Imm12_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
   void printB4const_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
   void printB4constu_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
 };
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
index 51d4b8a9cc5fc5..e6cdd3d0020fc0 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
@@ -111,6 +111,18 @@ class XtensaMCCodeEmitter : public MCCodeEmitter {
                                SmallVectorImpl<MCFixup> &Fixups,
                                const MCSubtargetInfo &STI) const;
 
+  uint32_t getImm8n_7OpValue(const MCInst &MI, unsigned OpNo,
+                             SmallVectorImpl<MCFixup> &Fixups,
+                             const MCSubtargetInfo &STI) const;
+
+  uint32_t getImm64n_4nOpValue(const MCInst &MI, unsigned OpNo,
+                               SmallVectorImpl<MCFixup> &Fixups,
+                               const MCSubtargetInfo &STI) const;
+
+  uint32_t getEntry_Imm12OpValue(const MCInst &MI, unsigned OpNo,
+                                 SmallVectorImpl<MCFixup> &Fixups,
+                                 const MCSubtargetInfo &STI) const;
+
   uint32_t getShimm1_31OpValue(const MCInst &MI, unsigned OpNo,
                                SmallVectorImpl<MCFixup> &Fixups,
                                const MCSubtargetInfo &STI) const;
@@ -405,6 +417,46 @@ XtensaMCCodeEmitter::getImm32n_95OpValue(const MCInst &MI, unsigned OpNo,
   return Res;
 }
 
+uint32_t
+XtensaMCCodeEmitter::getImm8n_7OpValue(const MCInst &MI, unsigned OpNo,
+                                       SmallVectorImpl<MCFixup> &Fixups,
+                                       const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(OpNo);
+  int32_t Res = static_cast<int32_t>(MO.getImm());
+
+  assert(((Res >= -8) && (Res <= 7)) && "Unexpected operand value!");
+
+  if (Res < 0)
+    return Res + 16;
+
+  return Res;
+}
+
+uint32_t
+XtensaMCCodeEmitter::getImm64n_4nOpValue(const MCInst &MI, unsigned OpNo,
+                                         SmallVectorImpl<MCFixup> &Fixups,
+                                         const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(OpNo);
+  int32_t Res = static_cast<int32_t>(MO.getImm());
+
+  assert(((Res >= -64) && (Res <= -4) && ((Res & 0x3) == 0)) &&
+         "Unexpected operand value!");
+
+  return Res & 0x3f;
+}
+
+uint32_t
+XtensaMCCodeEmitter::getEntry_Imm12OpValue(const MCInst &MI, unsigned OpNo,
+                                           SmallVectorImpl<MCFixup> &Fixups,
+                                           const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(OpNo);
+  uint32_t res = static_cast<uint32_t>(MO.getImm());
+
+  assert(((res & 0x7) == 0) && "Unexpected operand value!");
+
+  return res;
+}
+
 uint32_t
 XtensaMCCodeEmitter::getB4constOpValue(const MCInst &MI, unsigned OpNo,
                                        SmallVectorImpl<MCFixup> &Fixups,
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
index fc23c2356825f3..37dee072e5b3dd 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
@@ -74,6 +74,19 @@ bool Xtensa::isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset) {
   return isValidAddrOffset(Scale, Offset);
 }
 
+// Verify Special Register
+bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits) {
+  switch (RegNo) {
+  case Xtensa::WINDOWBASE:
+  case Xtensa::WINDOWSTART:
+    return FeatureBits[Xtensa::FeatureWindowed];
+  case Xtensa::NoRegister:
+    return false;
+  }
+
+  return true;
+}
+
 static MCAsmInfo *createXtensaMCAsmInfo(const MCRegisterInfo &MRI,
                                         const Triple &TT,
                                         const MCTargetOptions &Options) {
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h
index 6be54867d84a73..649073b01f5c10 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h
@@ -19,12 +19,14 @@
 
 namespace llvm {
 
+class FeatureBitset;
 class MCAsmBackend;
 class MCCodeEmitter;
 class MCContext;
 class MCInstrInfo;
 class MCObjectTargetWriter;
 class MCObjectWriter;
+class MCRegister;
 class MCRegisterInfo;
 class MCSubtargetInfo;
 class MCTargetOptions;
@@ -52,6 +54,9 @@ bool isValidAddrOffset(int Scale, int64_t OffsetVal);
 
 // Check address offset for load/store instructions.
 bool isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset);
+
+// Verify if it's correct to use a special register.
+bool checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits);
 } // namespace Xtensa
 } // end namespace llvm
 
diff --git a/llvm/lib/Target/Xtensa/Xtensa.td b/llvm/lib/Target/Xtensa/Xtensa.td
index 460a15e808b3a4..2c4bacbe8282b0 100644
--- a/llvm/lib/Target/Xtensa/Xtensa.td
+++ b/llvm/lib/Target/Xtensa/Xtensa.td
@@ -17,10 +17,9 @@ include "llvm/Target/Target.td"
 //===----------------------------------------------------------------------===//
 // Subtarget Features.
 //===----------------------------------------------------------------------===//
-def FeatureDensity : SubtargetFeature<"density", "HasDensity", "true",
-                    "Enable Density instructions">;
-def HasDensity : Predicate<"Subtarget->hasDensity()">,
-                     AssemblerPredicate<(all_of FeatureDensity)>;
+
+include "XtensaFeatures.td"
+
 //===----------------------------------------------------------------------===//
 // Xtensa supported processors.
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Xtensa/XtensaFeatures.td b/llvm/lib/Target/Xtensa/XtensaFeatures.td
new file mode 100644
index 00000000000000..6f24a674ae0ce2
--- /dev/null
+++ b/llvm/lib/Target/Xtensa/XtensaFeatures.td
@@ -0,0 +1,14 @@
+//===----------------------------------------------------------------------===//
+// Xtensa subtarget features.
+//===----------------------------------------------------------------------===//
+
+// Xtensa ISA extensions (Xtensa Options).
+def FeatureDensity : SubtargetFeature<"density", "HasDensity", "true",
+                                      "Enable Density instructions">;
+def HasDensity : Predicate<"Subtarget->hasDensity()">,
+                 AssemblerPredicate<(all_of FeatureDensity)>;
+
+def FeatureWindowed : SubtargetFeature<"windowed", "HasWindowed", "true",
+                                       "Enable Xtensa Windowed Register option">;
+def HasWindowed : Predicate<"Subtarget->hasWindowed()">,
+                  AssemblerPredicate<(all_of FeatureWindowed)>;
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
index 699d0d6cf80445..5ef795a0e5287a 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
@@ -678,3 +678,104 @@ let isReturn = 1, isTerminator = 1,
     let t = 0;
   }
 }
+
+//===----------------------------------------------------------------------===//
+// Windowed instructions
+//===----------------------------------------------------------------------===//
+
+def ENTRY : BRI12_Inst<0x06, 0x3, 0x0, (outs), (ins AR:$s, entry_imm12:$imm),
+                     "entry\t$s, $imm", []>, Requires<[HasWindowed]> {
+  bits<15> imm;
+
+  let imm12{11-0} = imm{14-3};
+  let Defs = [SP];
+}
+
+let isCall = 1, Defs = [A0] in {
+  foreach i = {1,2,3} in {
+    defvar I = !mul(4, i);
+
+    def CALL#I# : CALL_Inst<0x05, (outs), (ins pcrel32call:$offset),
+                           "call"#I#"\t$offset", []>, Requires<[HasWindowed]> {
+      let n = i;
+    }
+
+    def CALLX#I# : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s),
+                             "callx"#I#"\t$s", []>, Requires<[HasWindowed]> {
+      let m = 0x3;
+      let n = i;
+      let r = 0;
+    }
+  }
+}
+
+def MOVSP : RRR_Inst<0x00, 0x00, 0x00, (outs AR:$t), (ins AR:$s),
+                    "movsp\t$t, $s", []>, Requires<[HasWindowed]> {
+  let r = 0x01;
+}
+
+let isReturn = 1, isTerminator = 1,
+    isBarrier = 1, Uses = [A0] in {
+  def RETW_N : RRRN_Inst<0x0D, (outs), (ins),
+                        "retw.n", []>, Requires<[HasWindowed, HasDensity]> {
+    let r = 0x0F;
+    let s = 0;
+    let t = 1;
+  }
+
+  def RETW : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins),
+                       "retw", []>, Requires<[HasWindowed]> {
+    let m = 0x2;
+    let n = 0x1;
+    let s = 0;
+    let r = 0;
+  }
+}
+
+def : InstAlias<"_retw", (RETW)>;
+def : InstAlias<"_retw.n", (RETW_N)>;
+
+def S32E : RRI4_Inst<0x00, 0x09, (outs), (ins AR:$t, AR:$s, imm64n_4n:$imm),
+                    "s32e\t$t, $s, $imm", []>, Requires<[HasWindowed]> {
+  bits<6> imm;
+
+  let r = imm{5-2};
+  let imm4 = 0x4;
+  let mayStore = 1;
+}
+
+def L32E : RRI4_Inst<0x00, 0x09, (outs), (ins AR:$t, AR:$s, imm64n_4n:$imm),
+                    "l32e\t$t, $s, $imm", []>, Requires<[HasWindowed]> {
+  bits<6> imm;
+
+  let r = imm{5-2};
+  let imm4 = 0x0;
+  let mayLoad = 1;
+}
+
+def RFWU : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
+                   "rfwu", []>, Requires<[HasWindowed]> {
+  bits<4> imm;
+
+  let r = 0x3;
+  let s = 0x5;
+  let t = 0x0;
+}
+
+def RFWO : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
+                   "rfwo", []>, Requires<[HasWindowed]> {
+  bits<4> imm;
+
+  let r = 0x3;
+  let s = 0x4;
+  let t = 0x0;
+}
+
+def ROTW : RRR_Inst<0x00, 0x00, 0x04, (outs), (ins imm8n_7:$imm),
+                   "rotw\t$imm", []>, Requires<[HasWindowed]> {
+  bits<4> imm;
+
+  let r = 0x8;
+  let s = 0x0;
+  let t = imm{3-0};
+}
diff --git a/llvm/lib/Target/Xtensa/XtensaOperands.td b/llvm/lib/Target/Xtensa/XtensaOperands.td
index aa72fa0a56a6f5..402e05a5c3dd1d 100644
--- a/llvm/lib/Target/Xtensa/XtensaOperands.td
+++ b/llvm/lib/Target/Xtensa/XtensaOperands.td
@@ -37,6 +37,20 @@ def imm8_sh8 : Immediate<i32, [{ return Imm >= -32768 && Imm <= 32512 && ((Imm &
   let DecoderMethod = "decodeImm8_sh8Operand";
 }
 
+// imm8n_7 predicate - Immediate in the range [-8,7]
+def Imm8n_7_AsmOperand: ImmAsmOperand<"Imm8n_7">;
+def imm8n_7: Immediate<i32, [{ return Imm >= -8 && Imm <= 7; }], "Imm8n_7_AsmOperand"> {
+  let EncoderMethod = "getImm8n_7OpValue";
+  let DecoderMethod = "decodeImm8n_7Operand";
+}
+
+// imm64n_4n predicate - Immediate in the range [-64,-4]
+def Imm64n_4n_AsmOperand: ImmAsmOperand<"Imm64n_4n">;
+def imm64n_4n: Immediate<i32, [{ return Imm >= -64 && Imm <= -4; }], "Imm64n_4n_AsmOperand"> {
+  let EncoderMethod = "getImm64n_4nOpValue";
+  let DecoderMethod = "decodeImm64n_4nOperand";
+}
+
 // imm12 predicate - Immediate in the range [-2048,2047]
 def Imm12_AsmOperand : ImmAsmOperand<"Imm12">;
 def imm12 : Immediate<i32, [{ return Imm >= -2048 && Imm <= 2047; }], "Imm12_AsmOperand"> {
@@ -117,6 +131,13 @@ def offset4m32 : Immediate<i32,
     [{ return Imm >= 0 && Imm <= 60 && (Imm & 0x3 == 0); }],
     "Offset4m32_AsmOperand">;
 
+// entry_imm12 predicate - Immediate in the range [0,32760], ENTRY parameter
+def Entry_Imm12_AsmOperand: ImmAsmOperand<"entry_imm12">;
+def entry_imm12: Immediate<i32, [{ return Imm >= 0 && Imm <= 32760 && (Imm % 8 == 0); }], "Entry_Imm12_AsmOperand"> {
+  let EncoderMethod = "getEntry_Imm12OpValue";
+  let DecoderMethod = "decodeEntry_Imm12OpValue";
+}
+
 // b4const predicate - Branch Immediate 4-bit signed operand
 def B4const_AsmOperand: ImmAsmOperand<"B4const">;
 def b4const: Immediate<i32,
diff --git a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
index 5c07386b060cd9..09087edc86712d 100644
--- a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
@@ -75,4 +75,8 @@ class SRReg<bits<8> num, string n, list<string> alt = []> : XtensaReg<n> {
 // Shift Amount Register
 def SAR : SRReg<3, "sar", ["SAR","3"]>;
 
-def SR :  RegisterClass<"Xtensa", [i32], 32, (add SAR)>;
+// Windowed Register Option registers
+def WINDOWBASE : SRReg<72, "windowbase", ["WINDOWBASE", "72"]>;
+def WINDOWSTART : SRReg<73, "windowstart", ["WINDOWSTART", "73"]>;
+
+def SR :  RegisterClass<"Xtensa", [i32], 32, (add SAR, WINDOWBASE, WINDOWSTART)>;
diff --git a/llvm/lib/Target/Xtensa/XtensaSubtarget.h b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
index 948dcbc5278eaa..dddc0f7ef605d7 100644
--- a/llvm/lib/Target/Xtensa/XtensaSubtarget.h
+++ b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
@@ -36,9 +36,12 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
   SelectionDAGTargetInfo TSInfo;
   XtensaFrameLowering FrameLowering;
 
-  // Enabled Xtensa Density extension
+  // Enabled Xtensa Density Option
   bool HasDensity;
 
+  // Enabled Xtensa Windowed Register Option
+  bool HasWindowed;
+
   XtensaSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS);
 
 public:
@@ -64,6 +67,8 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
 
   bool hasDensity() const { return HasDensity; }
 
+  bool hasWindowed() const { return HasWindowed; }
+
   // Automatically generated by tblgen.
   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
 };
diff --git a/llvm/test/MC/Disassembler/Xtensa/windowed.txt b/llvm/test/MC/Disassembler/Xtensa/windowed.txt
new file mode 100644
index 00000000000000..69f588efd73de6
--- /dev/null
+++ b/llvm/test/MC/Disassembler/Xtensa/windowed.txt
@@ -0,0 +1,72 @@
+# RUN: llvm-mc -triple=xtensa -mattr=+windowed -disassemble %s | FileCheck -check-prefixes=CHECK-WINDOWED %s
+# RUN: not llvm-mc -triple=xtensa -disassemble %s 2>&1 | FileCheck --implicit-check-not=warning: -check-prefixes=CHECK-CORE %s
+
+#------------------------------------------------------------------------------
+# Verify that binary code is correctly disassembled with
+# windowed register option enabled. Also verify that dissasembling without
+# windowed register option generates warnings.
+#------------------------------------------------------------------------------
+
+[0x36,0x03,0x01]
+# CHECK-WINDOWED: entry a3, 128
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x30,0x14,0x00]
+# CHECK-WINDOWED: movsp a3, a4
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x15,0x10,0x00]
+# CHECK-WINDOWED: call4 . +260
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x25,0x10,0x00]
+# CHECK-WINDOWED: call8 . +260
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x35,0x10,0x00]
+# CHECK-WINDOWED: call12 . +260
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0xd0,0x03,0x00]
+# CHECK-WINDOWED: callx4 a3
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0xe0,0x03,0x00]
+# CHECK-WINDOWED: callx8 a3
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0xf0,0x03,0x00]
+# CHECK-WINDOWED: callx12 a3
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x90,0x00,0x00]
+# CHECK-WINDOWED: retw
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x20,0x80,0x40]
+# CHECK-WINDOWED: rotw 2
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x30,0xd4,0x09]
+# CHECK-WINDOWED: l32e a3, a4, -12
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x30,0xd4,0x49]
+# CHECK-WINDOWED: s32e a3, a4, -12
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x00,0x34,0x00]
+# CHECK-WINDOWED: rfwo
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x00,0x35,0x00]
+# CHECK-WINDOWED: rfwu
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x30,0x48,0x61]
+# CHECK-WINDOWED: xsr a3, windowbase
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+
+[0x30,0x49,0x61]
+# CHECK-WINDOWED: xsr a3, windowstart
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
diff --git a/llvm/test/MC/Disassembler/Xtensa/windowed_code_density.txt b/llvm/test/MC/Disassembler/Xtensa/windowed_code_density.txt
new file mode 100644
index 00000000000000..1b8c87e643f5d3
--- /dev/null
+++ b/llvm/test/MC/Disassembler/Xtensa/windowed_code_density.txt
@@ -0,0 +1,12 @@
+# RUN: llvm-mc -triple=xtensa -mattr=+windowed,+density -disassemble %s | FileCheck -check-prefixes=CHECK-WINDOWED-DENSITY %s
+# RUN: not llvm-mc -triple=xtensa -disassemble %s 2>&1 | FileCheck --implicit-check-not=warning: -check-prefixes=CHECK-CORE %s
+
+#------------------------------------------------------------------------------
+# Verify that binary code is correctly disassembled with windowed register
+# and code density options enabled. Also verify that
+# dissasembling without these options generates warnings.
+#------------------------------------------------------------------------------
+
+[0x1d,0xf0]
+# CHECK-WINDOWED-DENSITY: retw.n
+# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
diff --git a/llvm/test/MC/Xtensa/windowed.s b/llvm/test/MC/Xtensa/windowed.s
new file mode 100644
index 00000000000000..3376469e3085b8
--- /dev/null
+++ b/llvm/test/MC/Xtensa/windowed.s
@@ -0,0 +1,105 @@
+# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+windowed \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+
+.align	4
+LBL0:
+
+# Instruction format BRI12
+# CHECK-INST: entry a3, 128
+# CHECK: encoding: [0x36,0x03,0x01]
+entry a3, 128
+
+# Instruction format RRR
+# CHECK-INST: movsp a3, a4
+# CHECK: encoding: [0x30,0x14,0x00]
+movsp a3, a4
+
+# Instruction format CALL
+# CHECK-INST: call4	LBL0
+# CHECK: encoding: [0bAA010101,A,A]
+call4 LBL0
+
+# Instruction format CALL
+# CHECK-INST: call8 LBL0
+# CHECK: encoding: [0bAA100101,A,A]
+call8 LBL0
+
+# Instruction format CALL
+# CHECK-INST: call12 LBL0
+# CHECK: encoding: [0bAA110101,A,A]
+call12 LBL0
+
+# Instruction format CALLX
+# CHECK-INST: callx4 a3
+# CHECK: encoding: [0xd0,0x03,0x00]
+callx4 a3
+
+# Instruction format CALLX
+# CHECK-INST: callx8 a3
+# CHECK: encoding: [0xe0,0x03,0x00]
+callx8 a3
+
+# Instruction format CALLX
+# CHECK-INST: callx12 a3
+# CHECK: encoding: [0xf0,0x03,0x00]
+callx12 a3
+
+# Instruction format CALLX
+# CHECK-INST: retw
+# CHECK: encoding: [0x90,0x00,0x00]
+retw
+
+# Instruction format CALLX
+# CHECK-INST: retw
+# CHECK: encoding: [0x90,0x00,0x00]
+_retw
+
+# Instruction format RRR
+# CHECK-INST: rotw 2
+# CHECK: encoding: [0x20,0x80,0x40]
+rotw 2
+
+# Instruction format RRI4
+# CHECK-INST: l32e a3, a4, -12
+# CHECK: encoding: [0x30,0xd4,0x09]
+l32e a3, a4, -12
+
+# Instruction format RRI4
+# CHECK-INST: s32e a3, a4, -12
+# CHECK: encoding: [0x30,0xd4,0x49]
+s32e a3, a4, -12
+
+# Instruction format RRR
+# CHECK-INST: rfwo
+# CHECK: encoding: [0x00,0x34,0x00]
+rfwo
+
+# Instruction format RRR
+# CHECK-INST: rfwu
+# CHECK: encoding: [0x00,0x35,0x00]
+rfwu
+
+# Instruction format RSR
+# CHECK-INST: xsr a3, windowbase
+# CHECK: # encoding: [0x30,0x48,0x61]
+xsr a3, windowbase
+
+# CHECK-INST: xsr a3, windowbase
+# CHECK: # encoding: [0x30,0x48,0x61]
+xsr.windowbase a3
+
+# CHECK-INST: xsr a3, windowbase
+# CHECK: # encoding: [0x30,0x48,0x61]
+xsr a3, 72
+
+# CHECK-INST: xsr a3, windowstart
+# CHECK: # encoding: [0x30,0x49,0x61]
+xsr a3, windowstart
+
+# CHECK-INST: xsr a3, windowstart
+# CHECK: # encoding: [0x30,0x49,0x61]
+xsr.windowstart a3
+
+# CHECK-INST: xsr a3, windowstart
+# CHECK: # encoding: [0x30,0x49,0x61]
+xsr a3, 73
diff --git a/llvm/test/MC/Xtensa/windowed_code_density.s b/llvm/test/MC/Xtensa/windowed_code_density.s
new file mode 100644
index 00000000000000..e532657466fba5
--- /dev/null
+++ b/llvm/test/MC/Xtensa/windowed_code_density.s
@@ -0,0 +1,14 @@
+# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+windowed,+density \
+# RUN:     | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+
+.align	4
+
+# Instruction format RRRN
+# CHECK-INST: retw.n
+# CHECK: encoding: [0x1d,0xf0]
+retw.n
+
+# Instruction format RRRN
+# CHECK-INST: retw.n
+# CHECK: encoding: [0x1d,0xf0]
+_retw.n
diff --git a/llvm/test/MC/Xtensa/windowed_invalid.s b/llvm/test/MC/Xtensa/windowed_invalid.s
new file mode 100644
index 00000000000000..d2d59e11576052
--- /dev/null
+++ b/llvm/test/MC/Xtensa/windowed_invalid.s
@@ -0,0 +1,23 @@
+# RUN: not llvm-mc -triple xtensa --mattr=+windowed %s 2>&1 | FileCheck %s
+
+# Out of range immediates
+
+# entry_imm12
+entry a3, -1
+# CHECK: :[[#@LINE-1]]:11: error: expected immediate in range [0, 32760], first 3 bits should be zero
+
+# entry_imm12
+entry a3, 32764
+# CHECK: :[[#@LINE-1]]:11: error: expected immediate in range [0, 32760], first 3 bits should be zero
+
+# entry_imm12
+entry a3, 4
+# CHECK: :[[#@LINE-1]]:11: error: expected immediate in range [0, 32760], first 3 bits should be zero
+
+# imm8n_7
+rotw 100
+# CHECK: :[[#@LINE-1]]:6: error: expected immediate in range [-8, 7]
+
+# imm64n_4n
+l32e a3, a4, -100
+# CHECK: :[[#@LINE-1]]:14: error: expected immediate in range [-64, -4]

>From 50eef7607f75c346bced26f921acd13121176480 Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Thu, 30 Jan 2025 03:00:42 +0300
Subject: [PATCH 2/3] [Xtensa] Fix tests comments.

---
 llvm/test/MC/Disassembler/Xtensa/windowed.txt | 67 +++++++++----------
 .../Xtensa/windowed_code_density.txt          | 11 ++-
 llvm/test/MC/Xtensa/windowed_invalid.s        | 24 +++++--
 3 files changed, 56 insertions(+), 46 deletions(-)

diff --git a/llvm/test/MC/Disassembler/Xtensa/windowed.txt b/llvm/test/MC/Disassembler/Xtensa/windowed.txt
index 69f588efd73de6..34c51dd32b6be7 100644
--- a/llvm/test/MC/Disassembler/Xtensa/windowed.txt
+++ b/llvm/test/MC/Disassembler/Xtensa/windowed.txt
@@ -1,72 +1,71 @@
+# NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
 # RUN: llvm-mc -triple=xtensa -mattr=+windowed -disassemble %s | FileCheck -check-prefixes=CHECK-WINDOWED %s
 # RUN: not llvm-mc -triple=xtensa -disassemble %s 2>&1 | FileCheck --implicit-check-not=warning: -check-prefixes=CHECK-CORE %s
 
-#------------------------------------------------------------------------------
-# Verify that binary code is correctly disassembled with
-# windowed register option enabled. Also verify that dissasembling without
-# windowed register option generates warnings.
-#------------------------------------------------------------------------------
+## Verify that binary code is correctly disassembled with
+## windowed register option enabled. Also verify that dissasembling without
+## windowed register option generates warnings.
 
 [0x36,0x03,0x01]
-# CHECK-WINDOWED: entry a3, 128
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-WINDOWED: entry	a3, 128
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x30,0x14,0x00]
-# CHECK-WINDOWED: movsp a3, a4
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-WINDOWED: movsp	a3, a4
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x15,0x10,0x00]
-# CHECK-WINDOWED: call4 . +260
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-WINDOWED: call4	. +260
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x25,0x10,0x00]
-# CHECK-WINDOWED: call8 . +260
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-WINDOWED: call8	. +260
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x35,0x10,0x00]
-# CHECK-WINDOWED: call12 . +260
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-WINDOWED: call12	. +260
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0xd0,0x03,0x00]
-# CHECK-WINDOWED: callx4 a3
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-WINDOWED: callx4	a3
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0xe0,0x03,0x00]
-# CHECK-WINDOWED: callx8 a3
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-WINDOWED: callx8	a3
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0xf0,0x03,0x00]
-# CHECK-WINDOWED: callx12 a3
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-WINDOWED: callx12	a3
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x90,0x00,0x00]
 # CHECK-WINDOWED: retw
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x20,0x80,0x40]
-# CHECK-WINDOWED: rotw 2
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-WINDOWED: rotw	2
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x30,0xd4,0x09]
-# CHECK-WINDOWED: l32e a3, a4, -12
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-WINDOWED: l32e	a3, a4, -12
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x30,0xd4,0x49]
-# CHECK-WINDOWED: s32e a3, a4, -12
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-WINDOWED: s32e	a3, a4, -12
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x00,0x34,0x00]
 # CHECK-WINDOWED: rfwo
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x00,0x35,0x00]
 # CHECK-WINDOWED: rfwu
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x30,0x48,0x61]
-# CHECK-WINDOWED: xsr a3, windowbase
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-WINDOWED: xsr	a3, windowbase
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
 
 [0x30,0x49,0x61]
-# CHECK-WINDOWED: xsr a3, windowstart
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-WINDOWED: xsr	a3, windowstart
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
diff --git a/llvm/test/MC/Disassembler/Xtensa/windowed_code_density.txt b/llvm/test/MC/Disassembler/Xtensa/windowed_code_density.txt
index 1b8c87e643f5d3..69d7d424d96826 100644
--- a/llvm/test/MC/Disassembler/Xtensa/windowed_code_density.txt
+++ b/llvm/test/MC/Disassembler/Xtensa/windowed_code_density.txt
@@ -1,12 +1,11 @@
+# NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
 # RUN: llvm-mc -triple=xtensa -mattr=+windowed,+density -disassemble %s | FileCheck -check-prefixes=CHECK-WINDOWED-DENSITY %s
 # RUN: not llvm-mc -triple=xtensa -disassemble %s 2>&1 | FileCheck --implicit-check-not=warning: -check-prefixes=CHECK-CORE %s
 
-#------------------------------------------------------------------------------
-# Verify that binary code is correctly disassembled with windowed register
-# and code density options enabled. Also verify that
-# dissasembling without these options generates warnings.
-#------------------------------------------------------------------------------
+## Verify that binary code is correctly disassembled with windowed register
+## and code density options enabled. Also verify that
+## dissasembling without these options generates warnings.
 
 [0x1d,0xf0]
 # CHECK-WINDOWED-DENSITY: retw.n
-# CHECK-CORE: [[#@LINE-2]]:2: warning: invalid instruction encoding
+# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
diff --git a/llvm/test/MC/Xtensa/windowed_invalid.s b/llvm/test/MC/Xtensa/windowed_invalid.s
index d2d59e11576052..958363093dd8e1 100644
--- a/llvm/test/MC/Xtensa/windowed_invalid.s
+++ b/llvm/test/MC/Xtensa/windowed_invalid.s
@@ -1,23 +1,35 @@
+// NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
 # RUN: not llvm-mc -triple xtensa --mattr=+windowed %s 2>&1 | FileCheck %s
 
-# Out of range immediates
+## Out of range immediates
+
 
 # entry_imm12
+
+
 entry a3, -1
-# CHECK: :[[#@LINE-1]]:11: error: expected immediate in range [0, 32760], first 3 bits should be zero
+// CHECK: :[[@LINE-1]]:11: error: expected immediate in range [0, 32760], first 3 bits should be zero
 
 # entry_imm12
+
+
 entry a3, 32764
-# CHECK: :[[#@LINE-1]]:11: error: expected immediate in range [0, 32760], first 3 bits should be zero
+// CHECK: :[[@LINE-1]]:11: error: expected immediate in range [0, 32760], first 3 bits should be zero
 
 # entry_imm12
+
+
 entry a3, 4
-# CHECK: :[[#@LINE-1]]:11: error: expected immediate in range [0, 32760], first 3 bits should be zero
+// CHECK: :[[@LINE-1]]:11: error: expected immediate in range [0, 32760], first 3 bits should be zero
 
 # imm8n_7
+
+
 rotw 100
-# CHECK: :[[#@LINE-1]]:6: error: expected immediate in range [-8, 7]
+// CHECK: :[[@LINE-1]]:6: error: expected immediate in range [-8, 7]
 
 # imm64n_4n
+
+
 l32e a3, a4, -100
-# CHECK: :[[#@LINE-1]]:14: error: expected immediate in range [-64, -4]
+// CHECK: :[[@LINE-1]]:14: error: expected immediate in range [-64, -4]

>From 5c2e13dae837e120437e26c663ede792b85fc3d4 Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Thu, 30 Jan 2025 13:26:06 +0300
Subject: [PATCH 3/3] [Xtensa] Minor fixes in disassembler.

---
 llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
index f6270b4d898254..7ad8a87ed599ae 100644
--- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
+++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
@@ -57,7 +57,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaDisassembler() {
                                          createXtensaDisassembler);
 }
 
-static const unsigned ARDecoderTable[] = {
+const unsigned ARDecoderTable[] = {
     Xtensa::A0,  Xtensa::SP,  Xtensa::A2,  Xtensa::A3, Xtensa::A4,  Xtensa::A5,
     Xtensa::A6,  Xtensa::A7,  Xtensa::A8,  Xtensa::A9, Xtensa::A10, Xtensa::A11,
     Xtensa::A12, Xtensa::A13, Xtensa::A14, Xtensa::A15};
@@ -73,7 +73,7 @@ static DecodeStatus DecodeARRegisterClass(MCInst &Inst, uint64_t RegNo,
   return MCDisassembler::Success;
 }
 
-static const unsigned SRDecoderTable[] = {
+const unsigned SRDecoderTable[] = {
     Xtensa::SAR, 3, Xtensa::WINDOWBASE, 72, Xtensa::WINDOWSTART, 73};
 
 static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,



More information about the llvm-commits mailing list