[llvm] [Xtensa] Implement Xtensa Interrupt/Exception/Debug Options. (PR #143820)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 11 18:01:15 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mc
Author: Andrei Safronov (andreisfr)
<details>
<summary>Changes</summary>
Implement Xtensa Interrupt. HighInterrupts, Exception, Debug Options. Also implement small Xtensa Options like PRID, Coprocessor and Timers.
---
Patch is 54.63 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/143820.diff
24 Files Affected:
- (modified) llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp (+19-10)
- (modified) llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp (+47-9)
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp (+88-1)
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h (+8-1)
- (modified) llvm/lib/Target/Xtensa/XtensaFeatures.td (+40)
- (modified) llvm/lib/Target/Xtensa/XtensaInstrInfo.td (+115)
- (modified) llvm/lib/Target/Xtensa/XtensaRegisterInfo.td (+113-2)
- (modified) llvm/lib/Target/Xtensa/XtensaSubtarget.h (+9)
- (added) llvm/test/MC/Disassembler/Xtensa/coprocessor.txt (+10)
- (added) llvm/test/MC/Disassembler/Xtensa/debug.txt (+62)
- (added) llvm/test/MC/Disassembler/Xtensa/exception.txt (+42)
- (added) llvm/test/MC/Disassembler/Xtensa/highinterrupts.txt (+82)
- (added) llvm/test/MC/Disassembler/Xtensa/interrupt.txt (+26)
- (added) llvm/test/MC/Disassembler/Xtensa/prid.txt (+10)
- (added) llvm/test/MC/Disassembler/Xtensa/timer.txt (+22)
- (modified) llvm/test/MC/Xtensa/Core/processor-control.s (+5)
- (added) llvm/test/MC/Xtensa/coprocessor.s (+20)
- (added) llvm/test/MC/Xtensa/debug-invalid.s (+9)
- (added) llvm/test/MC/Xtensa/debug.s (+190)
- (added) llvm/test/MC/Xtensa/exception.s (+100)
- (added) llvm/test/MC/Xtensa/highinterrupts.s (+280)
- (added) llvm/test/MC/Xtensa/interrupt.s (+60)
- (added) llvm/test/MC/Xtensa/prid.s (+20)
- (added) llvm/test/MC/Xtensa/timer.s (+65)
``````````diff
diff --git a/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp b/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
index e0bbbc79b201b..b9be5e26d1fd5 100644
--- a/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
+++ b/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
@@ -62,11 +62,14 @@ class XtensaAsmParser : public MCTargetAsmParser {
#include "XtensaGenAsmMatcher.inc"
ParseStatus parseImmediate(OperandVector &Operands);
- ParseStatus parseRegister(OperandVector &Operands, bool AllowParens = false,
- bool SR = false);
+ ParseStatus
+ parseRegister(OperandVector &Operands, bool AllowParens = false,
+ bool SR = false,
+ Xtensa::RegisterAccessType RAType = Xtensa::REGISTER_EXCHANGE);
ParseStatus parseOperandWithModifier(OperandVector &Operands);
- bool parseOperand(OperandVector &Operands, StringRef Mnemonic,
- bool SR = false);
+ bool
+ parseOperand(OperandVector &Operands, StringRef Mnemonic, bool SR = false,
+ Xtensa::RegisterAccessType RAType = Xtensa::REGISTER_EXCHANGE);
bool ParseInstructionWithSR(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc, OperandVector &Operands);
ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
@@ -586,7 +589,8 @@ bool XtensaAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
}
ParseStatus XtensaAsmParser::parseRegister(OperandVector &Operands,
- bool AllowParens, bool SR) {
+ bool AllowParens, bool SR,
+ Xtensa::RegisterAccessType RAType) {
SMLoc FirstS = getLoc();
bool HadParens = false;
AsmToken Buf[2];
@@ -630,7 +634,7 @@ ParseStatus XtensaAsmParser::parseRegister(OperandVector &Operands,
return ParseStatus::NoMatch;
}
- if (!Xtensa::checkRegister(RegNo, getSTI().getFeatureBits()))
+ if (!Xtensa::checkRegister(RegNo, getSTI().getFeatureBits(), RAType))
return ParseStatus::NoMatch;
if (HadParens)
@@ -691,7 +695,7 @@ ParseStatus XtensaAsmParser::parseOperandWithModifier(OperandVector &Operands) {
/// from this information, adding to Operands.
/// If operand was parsed, returns false, else true.
bool XtensaAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic,
- bool SR) {
+ bool SR, Xtensa::RegisterAccessType RAType) {
// Check if the current operand has a custom associated parser, if so, try to
// custom parse the operand, or fallback to the general approach.
ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);
@@ -705,7 +709,7 @@ bool XtensaAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic,
return true;
// Attempt to parse token as register
- if (parseRegister(Operands, true, SR).isSuccess())
+ if (parseRegister(Operands, true, SR, RAType).isSuccess())
return false;
// Attempt to parse token as an immediate
@@ -719,6 +723,11 @@ bool XtensaAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic,
bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
StringRef Name, SMLoc NameLoc,
OperandVector &Operands) {
+ Xtensa::RegisterAccessType RAType =
+ Name[0] == 'w' ? Xtensa::REGISTER_WRITE
+ : (Name[0] == 'r' ? Xtensa::REGISTER_READ
+ : Xtensa::REGISTER_EXCHANGE);
+
if ((Name.starts_with("wsr.") || Name.starts_with("rsr.") ||
Name.starts_with("xsr.")) &&
(Name.size() > 4)) {
@@ -734,7 +743,7 @@ bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
if (RegNo == 0)
RegNo = MatchRegisterAltName(RegName);
- if (!Xtensa::checkRegister(RegNo, getSTI().getFeatureBits()))
+ if (!Xtensa::checkRegister(RegNo, getSTI().getFeatureBits(), RAType))
return Error(NameLoc, "invalid register name");
// Parse operand
@@ -759,7 +768,7 @@ bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
}
// Parse second operand
- if (parseOperand(Operands, Name, true))
+ if (parseOperand(Operands, Name, true, RAType))
return true;
}
diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
index dbd34964db074..fd4aafec07f9a 100644
--- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
+++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
@@ -119,13 +119,39 @@ struct DecodeRegister {
};
const DecodeRegister SRDecoderTable[] = {
- {Xtensa::LBEG, 0}, {Xtensa::LEND, 1}, {Xtensa::LCOUNT, 2},
- {Xtensa::SAR, 3}, {Xtensa::BREG, 4}, {Xtensa::SAR, 3},
- {Xtensa::LITBASE, 5}, {Xtensa::ACCLO, 16}, {Xtensa::ACCHI, 17},
- {Xtensa::M0, 32}, {Xtensa::M1, 33}, {Xtensa::M2, 34},
- {Xtensa::M3, 35}, {Xtensa::WINDOWBASE, 72}, {Xtensa::WINDOWSTART, 73},
- {Xtensa::MEMCTL, 97}, {Xtensa::VECBASE, 231}, {Xtensa::MISC0, 244},
- {Xtensa::MISC1, 245}, {Xtensa::MISC2, 246}, {Xtensa::MISC3, 247}};
+ {Xtensa::LBEG, 0}, {Xtensa::LEND, 1},
+ {Xtensa::LCOUNT, 2}, {Xtensa::SAR, 3},
+ {Xtensa::BREG, 4}, {Xtensa::LITBASE, 5},
+ {Xtensa::ACCLO, 16}, {Xtensa::ACCHI, 17},
+ {Xtensa::M0, 32}, {Xtensa::M1, 33},
+ {Xtensa::M2, 34}, {Xtensa::M3, 35},
+ {Xtensa::WINDOWBASE, 72}, {Xtensa::WINDOWSTART, 73},
+ {Xtensa::IBREAKENABLE, 96}, {Xtensa::MEMCTL, 97},
+ {Xtensa::DDR, 104}, {Xtensa::IBREAKA0, 128},
+ {Xtensa::IBREAKA1, 129}, {Xtensa::DBREAKA0, 144},
+ {Xtensa::DBREAKA1, 145}, {Xtensa::DBREAKC0, 160},
+ {Xtensa::DBREAKC1, 161}, {Xtensa::CONFIGID0, 176},
+ {Xtensa::EPC1, 177}, {Xtensa::EPC2, 178},
+ {Xtensa::EPC3, 179}, {Xtensa::EPC4, 180},
+ {Xtensa::EPC5, 181}, {Xtensa::EPC6, 182},
+ {Xtensa::EPC7, 183}, {Xtensa::DEPC, 192},
+ {Xtensa::EPS2, 194}, {Xtensa::EPS3, 195},
+ {Xtensa::EPS4, 196}, {Xtensa::EPS5, 197},
+ {Xtensa::EPS6, 198}, {Xtensa::EPS7, 199},
+ {Xtensa::CONFIGID1, 208}, {Xtensa::EXCSAVE1, 209},
+ {Xtensa::EXCSAVE2, 210}, {Xtensa::EXCSAVE3, 211},
+ {Xtensa::EXCSAVE4, 212}, {Xtensa::EXCSAVE5, 213},
+ {Xtensa::EXCSAVE6, 214}, {Xtensa::EXCSAVE7, 215},
+ {Xtensa::CPENABLE, 224}, {Xtensa::INTERRUPT, 226},
+ {Xtensa::INTCLEAR, 227}, {Xtensa::INTENABLE, 228},
+ {Xtensa::PS, 230}, {Xtensa::VECBASE, 231},
+ {Xtensa::EXCCAUSE, 232}, {Xtensa::DEBUGCAUSE, 233},
+ {Xtensa::CCOUNT, 234}, {Xtensa::PRID, 235},
+ {Xtensa::ICOUNT, 236}, {Xtensa::ICOUNTLEVEL, 237},
+ {Xtensa::EXCVADDR, 238}, {Xtensa::CCOMPARE0, 240},
+ {Xtensa::CCOMPARE1, 241}, {Xtensa::CCOMPARE2, 242},
+ {Xtensa::MISC0, 244}, {Xtensa::MISC1, 245},
+ {Xtensa::MISC2, 246}, {Xtensa::MISC3, 247}};
static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
uint64_t Address,
@@ -133,12 +159,24 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
if (RegNo > 255)
return MCDisassembler::Fail;
+ Xtensa::RegisterAccessType RAType =
+ Inst.getOpcode() == Xtensa::WSR
+ ? Xtensa::REGISTER_WRITE
+ : (Inst.getOpcode() == Xtensa::RSR ? Xtensa::REGISTER_READ
+ : Xtensa::REGISTER_EXCHANGE);
+
for (unsigned i = 0; i < std::size(SRDecoderTable); i++) {
if (SRDecoderTable[i].RegNo == RegNo) {
MCPhysReg Reg = SRDecoderTable[i].Reg;
- if (!Xtensa::checkRegister(Reg,
- Decoder->getSubtargetInfo().getFeatureBits()))
+ // Handle special case. The INTERRUPT/INTSET registers use the same
+ // encoding, but INTERRUPT used for read and INTSET for write.
+ if ((Reg == Xtensa::INTERRUPT) && (RAType == Xtensa::REGISTER_WRITE)) {
+ Reg = Xtensa::INTSET;
+ }
+
+ if (!Xtensa::checkRegister(
+ Reg, Decoder->getSubtargetInfo().getFeatureBits(), RAType))
return MCDisassembler::Fail;
Inst.addOperand(MCOperand::createReg(Reg));
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
index 63fed46ac411f..f48c6225827b0 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
@@ -75,10 +75,95 @@ bool Xtensa::isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset) {
}
// Verify Special Register
-bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits) {
+bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits,
+ RegisterAccessType RAType) {
switch (RegNo) {
case Xtensa::BREG:
return FeatureBits[Xtensa::FeatureBoolean];
+ case Xtensa::CCOUNT:
+ case Xtensa::CCOMPARE0:
+ if (FeatureBits[Xtensa::FeatureTimers1])
+ return true;
+ LLVM_FALLTHROUGH;
+ case Xtensa::CCOMPARE1:
+ if (FeatureBits[Xtensa::FeatureTimers2])
+ return true;
+ LLVM_FALLTHROUGH;
+ case Xtensa::CCOMPARE2:
+ if (FeatureBits[Xtensa::FeatureTimers3])
+ return true;
+ return false;
+ case Xtensa::CONFIGID0:
+ return RAType != Xtensa::REGISTER_EXCHANGE;
+ case Xtensa::CONFIGID1:
+ return RAType == Xtensa::REGISTER_READ;
+ case Xtensa::CPENABLE:
+ return FeatureBits[Xtensa::FeatureCoprocessor];
+ case Xtensa::DEBUGCAUSE:
+ return RAType == Xtensa::REGISTER_READ && FeatureBits[Xtensa::FeatureDebug];
+ case Xtensa::DEPC:
+ case Xtensa::EPC1:
+ case Xtensa::EXCCAUSE:
+ case Xtensa::EXCSAVE1:
+ case Xtensa::EXCVADDR:
+ return FeatureBits[Xtensa::FeatureException];
+ LLVM_FALLTHROUGH;
+ case Xtensa::EPC2:
+ case Xtensa::EPS2:
+ case Xtensa::EXCSAVE2:
+ if (FeatureBits[Xtensa::FeatureHighPriInterrupts])
+ return true;
+ LLVM_FALLTHROUGH;
+ case Xtensa::EPC3:
+ case Xtensa::EPS3:
+ case Xtensa::EXCSAVE3:
+ if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel3])
+ return true;
+ LLVM_FALLTHROUGH;
+ case Xtensa::EPC4:
+ case Xtensa::EPS4:
+ case Xtensa::EXCSAVE4:
+ if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel4])
+ return true;
+ LLVM_FALLTHROUGH;
+ case Xtensa::EPC5:
+ case Xtensa::EPS5:
+ case Xtensa::EXCSAVE5:
+ if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel5])
+ return true;
+ LLVM_FALLTHROUGH;
+ case Xtensa::EPC6:
+ case Xtensa::EPS6:
+ case Xtensa::EXCSAVE6:
+ if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel6])
+ return true;
+ LLVM_FALLTHROUGH;
+ case Xtensa::EPC7:
+ case Xtensa::EPS7:
+ case Xtensa::EXCSAVE7:
+ if (FeatureBits[Xtensa::FeatureHighPriInterruptsLevel7])
+ return true;
+ return false;
+ case Xtensa::INTENABLE:
+ return FeatureBits[Xtensa::FeatureInterrupt];
+ case Xtensa::INTERRUPT:
+ return RAType == Xtensa::REGISTER_READ &&
+ FeatureBits[Xtensa::FeatureInterrupt];
+ case Xtensa::INTSET:
+ case Xtensa::INTCLEAR:
+ return RAType == Xtensa::REGISTER_WRITE &&
+ FeatureBits[Xtensa::FeatureInterrupt];
+ case Xtensa::ICOUNT:
+ case Xtensa::ICOUNTLEVEL:
+ case Xtensa::IBREAKENABLE:
+ case Xtensa::DDR:
+ case Xtensa::IBREAKA0:
+ case Xtensa::IBREAKA1:
+ case Xtensa::DBREAKA0:
+ case Xtensa::DBREAKA1:
+ case Xtensa::DBREAKC0:
+ case Xtensa::DBREAKC1:
+ return FeatureBits[Xtensa::FeatureDebug];
case Xtensa::LBEG:
case Xtensa::LEND:
case Xtensa::LCOUNT:
@@ -99,6 +184,8 @@ bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits) {
case Xtensa::MISC2:
case Xtensa::MISC3:
return FeatureBits[Xtensa::FeatureMiscSR];
+ case Xtensa::PRID:
+ return RAType == Xtensa::REGISTER_READ && FeatureBits[Xtensa::FeaturePRID];
case Xtensa::VECBASE:
return FeatureBits[Xtensa::FeatureRelocatableVector];
case Xtensa::WINDOWBASE:
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h
index cedc57a14f142..ec91f656bdcbd 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h
@@ -55,8 +55,15 @@ bool isValidAddrOffset(int Scale, int64_t OffsetVal);
// Check address offset for load/store instructions.
bool isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset);
+enum RegisterAccessType {
+ REGISTER_WRITE = 1,
+ REGISTER_READ = 2,
+ REGISTER_EXCHANGE = 3
+};
+
// Verify if it's correct to use a special register.
-bool checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits);
+bool checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits,
+ RegisterAccessType RA);
} // namespace Xtensa
} // end namespace llvm
diff --git a/llvm/lib/Target/Xtensa/XtensaFeatures.td b/llvm/lib/Target/Xtensa/XtensaFeatures.td
index 55977277daf8e..1dd03283e9313 100644
--- a/llvm/lib/Target/Xtensa/XtensaFeatures.td
+++ b/llvm/lib/Target/Xtensa/XtensaFeatures.td
@@ -92,3 +92,43 @@ def FeatureDataCache : SubtargetFeature<"dcache", "HasDataCache", "true",
"Enable Xtensa Data Cache option">;
def HasDataCache : Predicate<"Subtarget->hasDataCache()">,
AssemblerPredicate<(all_of FeatureDataCache)>;
+
+// Xtensa Interrupts Options.
+def FeatureHighPriInterrupts : SubtargetFeature<"highpriinterrupts",
+ "HasHighPriInterrupts", "true",
+ "Enable Xtensa HighPriInterrupts option">;
+def HasHighPriInterrupts : Predicate<"Subtarget->hasHighPriInterrupts()">,
+ AssemblerPredicate<(all_of FeatureHighPriInterrupts)>;
+
+foreach i = {3-7} in
+ def FeatureHighPriInterruptsLevel#i : SubtargetFeature<"highpriinterrupts-level"#i,
+ "HasHighPriInterruptsLevel"#i#"", "true", "Enable Xtensa HighPriInterrupts Level"#i, [FeatureHighPriInterrupts]>;
+
+def FeatureInterrupt : SubtargetFeature<"interrupt", "HasInterrupt", "true",
+ "Enable Xtensa Interrupt option">;
+def HasInterrupt : Predicate<"Subtarget->hasInterrupt()">,
+ AssemblerPredicate<(all_of FeatureInterrupt)>;
+
+def FeatureException : SubtargetFeature<"exception", "HasException", "true",
+ "Enable Xtensa Exception option">;
+def HasException : Predicate<"Subtarget->hasException()">,
+ AssemblerPredicate<(all_of FeatureException)>;
+
+def FeatureDebug : SubtargetFeature<"debug", "HasDebug", "true",
+ "Enable Xtensa Debug option">;
+def HasDebug : Predicate<"Subtarget->hasDebug()">,
+ AssemblerPredicate<(all_of FeatureDebug)>;
+
+foreach i = {1-3} in
+ def FeatureTimers#i : SubtargetFeature<"timers"#i,
+ "HasTimers"#i#"", "true", "Enable Xtensa Timers "#i>;
+
+def FeaturePRID : SubtargetFeature<"prid", "HasPRID", "true",
+ "Enable Xtensa Processor ID option">;
+def HasPRID : Predicate<"Subtarget->hasPRID()">,
+ AssemblerPredicate<(all_of FeaturePRID)>;
+
+def FeatureCoprocessor : SubtargetFeature<"coprocessor", "HasCoprocessor", "true",
+ "Enable Xtensa Coprocessor option">;
+def HasCoprocessor : Predicate<"Subtarget->hasCoprocessor()">,
+ AssemblerPredicate<(all_of FeatureCoprocessor)>;
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
index 9a9424f916996..7e9fcd7058c20 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
@@ -499,6 +499,18 @@ def EXTW : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
let hasSideEffects = 1;
}
+//===----------------------------------------------------------------------===//
+// Illegal instructions
+//===----------------------------------------------------------------------===//
+
+def ILL : CALLX_Inst<0x00, 0x00, 0x00, (outs), (ins),
+ "ill", []> {
+ let m = 0x0;
+ let n = 0x0;
+ let r = 0;
+ let s = 0;
+}
+
//===----------------------------------------------------------------------===//
// Processor control instructions
//===----------------------------------------------------------------------===//
@@ -1044,6 +1056,109 @@ let Predicates = [HasRegionProtection] in {
}
}
+//===----------------------------------------------------------------------===//
+// Debug instructions
+//===----------------------------------------------------------------------===//
+
+let isBarrier = 1, isTerminator = 1 in {
+ def BREAK : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins uimm4:$s, uimm4:$t),
+ "break\t$s, $t", []>, Requires<[HasDebug]> {
+ let r = 0x04;
+ }
+
+ def BREAK_N : RRRN_Inst<0x0C, (outs), (ins uimm4:$imm),
+ "break.n\t$imm", []>, Requires<[HasDensity, HasDebug]> {
+ bits<4> imm;
+
+ let r = 0xf;
+ let s = imm;
+ let t = 0x2;
+ }
+}
+
+def : InstAlias<"_break.n\t$imm", (BREAK_N uimm4:$imm)>;
+
+def : Pat<(trap), (BREAK (i32 1), (i32 15))>;
+
+// Load instruction
+def LDDR32P : RRR_Inst<0x00, 0x00, 0x00, (outs AR:$s), (ins),
+ "lddr32.p\t$s", []>, Requires<[HasDebug]> {
+ let r = 0x7;
+ let t = 0xe;
+ let mayLoad = 1;
+}
+
+// Store instruction
+def SDDR32P : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins AR:$s),
+ "sddr32.p\t$s", []>, Requires<[HasDebug]> {
+ let r = 0x7;
+ let t = 0xf;
+ let mayStore = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// Exception feature instructions
+//===----------------------------------------------------------------------===//
+
+def EXCW : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
+ "excw", []>, Requires<[HasException]> {
+ let r = 0x2;
+ let s = 0x0;
+ let t = 0x8;
+}
+
+def RFDE : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
+ "rfde", []>, Requires<[HasException]> {
+ let r = 0x3;
+ let s = 0x2;
+ let t = 0x0;
+}
+
+
+def RFE : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
+ "rfe", []>, Requires<[HasException]> {
+ let r = 0x3;
+ let s = 0x0;
+ let t = 0x0;
+}
+
+def SYSCALL : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins),
+ "syscall", []>, Requires<[HasException]> {
+ let r = 0x5;
+ let s = 0x0;
+ let t = 0x0;
+}
+
+//===----------------------------------------------------------------------===//
+// Interrupt feature instructions
+//===----------------------------------------------------------------------===//
+
+def RSIL : RRR_Inst<0x00, 0x00, 0x00, (outs AR:$t), (ins uimm4:$imm),
+ "rsil\t$t, $imm", []>, Requires<[HasInterrupt]> {
+ bits<4> imm;
+
+ let r = 0x6;
+ let s = imm{3-0};
+}
+
+def WAITI : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins uimm4:$imm),
+ "waiti\t$imm", []>, Requires<[HasInterrupt]> {
+ bits<4> imm;
+
+ let r = 0x7;
+ let s = imm{3-0};
+ let t = 0;
+}
+
+def RFI : RRR_Inst<0x00, 0x00, 0x00, (outs), (ins uimm4:$imm),
+ "rfi\t$imm", []>, Requires<[HasHighPriInterrupts]> {
+ bits<4> imm;
+
+ let r = 0x3;
+ let s = imm{3-0};
+ let t = 0x1;
+}
+
//===----------------------------------------------------------------------===//
// DSP Instructions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
index c54e2556ba11f..1f5ea077cb777 100644
--- a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
@@ -91,9 +91,111 @@ def LITBASE : SRReg<5, "litbase", ["LITBASE", "5"]>;
def WINDOWBASE : SRReg<72, "windowbase", ["WINDOWBASE", "72"]>;
def WINDOWSTART : SRReg<73, "windowstart", ["WINDOWSTART", "73"]>;
+// Instuction breakpoint enable register
+def IBREAKENABLE : SRReg<96, "ibreakenabl...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/143820
More information about the llvm-commits
mailing list