[llvm] [Xtensa] Implement SEXT, NSA, MINMAX and Loop Xtensa Options. (PR #133818)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 31 16:03:13 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mc
Author: Andrei Safronov (andreisfr)
<details>
<summary>Changes</summary>
Implement basic support of the several simple Xtensa Options with 1-4 instructions for each option. The Sign Extend Option (SEXT). The NSA Option. The Minimum/Maximum Integer 32-bit Option and Loop Option.
---
Patch is 28.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/133818.diff
24 Files Affected:
- (modified) llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp (+5)
- (modified) llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp (+17)
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp (+7-1)
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaFixupKinds.h (+1)
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp (+26)
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h (+2)
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp (+38)
- (modified) llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp (+4)
- (modified) llvm/lib/Target/Xtensa/XtensaFeatures.td (+25)
- (modified) llvm/lib/Target/Xtensa/XtensaISelLowering.cpp (+5-2)
- (modified) llvm/lib/Target/Xtensa/XtensaInstrInfo.td (+88)
- (modified) llvm/lib/Target/Xtensa/XtensaOperands.td (+15)
- (modified) llvm/lib/Target/Xtensa/XtensaRegisterInfo.td (+7-2)
- (modified) llvm/lib/Target/Xtensa/XtensaSubtarget.h (+10)
- (added) llvm/test/CodeGen/Xtensa/minmax.ll (+52)
- (added) llvm/test/CodeGen/Xtensa/sext.ll (+23)
- (modified) llvm/test/MC/Xtensa/Relocations/fixups-diagnostics.s (+3-1)
- (modified) llvm/test/MC/Xtensa/Relocations/fixups.s (+12-4)
- (modified) llvm/test/MC/Xtensa/Relocations/relocations.s (+11-2)
- (added) llvm/test/MC/Xtensa/loop.s (+35)
- (added) llvm/test/MC/Xtensa/minmax.s (+24)
- (added) llvm/test/MC/Xtensa/nsau.s (+14)
- (added) llvm/test/MC/Xtensa/sext.s (+9)
- (added) llvm/test/MC/Xtensa/sext_invalid.s (+9)
``````````diff
diff --git a/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp b/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
index 19160a599c27c..30c9ee34ade1c 100644
--- a/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
+++ b/llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
@@ -273,6 +273,8 @@ struct XtensaOperand : public MCParsedAsmOperand {
return false;
}
+ bool isimm7_22() const { return isImm(7, 22); }
+
/// getStartLoc - Gets location of the first token of this operand
SMLoc getStartLoc() const override { return StartLoc; }
/// getEndLoc - Gets location of the last token of this operand
@@ -538,6 +540,9 @@ bool XtensaAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
"expected immediate in range [0, 32760], first 3 bits "
"should be zero");
+ case Match_Invalidimm7_22:
+ return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
+ "expected immediate in range [7, 22]");
}
report_fatal_error("Unknown match type detected!");
diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
index b949b893953fe..2c34755551b28 100644
--- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
+++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
@@ -200,6 +200,16 @@ static DecodeStatus decodeBranchOperand(MCInst &Inst, uint64_t Imm,
return MCDisassembler::Success;
}
+static DecodeStatus decodeLoopOperand(MCInst &Inst, uint64_t Imm,
+ int64_t Address, const void *Decoder) {
+
+ assert(isUInt<8>(Imm) && "Invalid immediate");
+ if (!tryAddingSymbolicOperand(Imm + 4 + Address, true, Address, 0, 3, Inst,
+ Decoder))
+ Inst.addOperand(MCOperand::createImm(Imm));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus decodeL32ROperand(MCInst &Inst, uint64_t Imm,
int64_t Address, const void *Decoder) {
@@ -326,6 +336,13 @@ static DecodeStatus decodeB4constuOperand(MCInst &Inst, uint64_t Imm,
return MCDisassembler::Success;
}
+static DecodeStatus decodeImm7_22Operand(MCInst &Inst, uint64_t Imm,
+ int64_t Address, const void *Decoder) {
+ assert(isUInt<4>(Imm) && "Invalid immediate");
+ Inst.addOperand(MCOperand::createImm(Imm + 7));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus decodeMem8Operand(MCInst &Inst, uint64_t Imm,
int64_t Address, const void *Decoder) {
assert(isUInt<12>(Imm) && "Invalid immediate");
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
index 1396eb45801af..ba2744d5facb5 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp
@@ -64,7 +64,8 @@ XtensaMCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
{"fixup_xtensa_l32r_16", 8, 16,
MCFixupKindInfo::FKF_IsPCRel |
- MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}};
+ MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
+ {"fixup_xtensa_loop_8", 16, 8, MCFixupKindInfo::FKF_IsPCRel}};
if (Kind < FirstTargetFixupKind)
return MCAsmBackend::getFixupKindInfo(Kind);
@@ -116,6 +117,11 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
if (Value & 0x3)
Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned");
return (Value & 0xffffc) >> 2;
+ case Xtensa::fixup_xtensa_loop_8:
+ Value -= 4;
+ if (!isUInt<8>(Value))
+ Ctx.reportError(Fixup.getLoc(), "loop fixup value out of range");
+ return (Value & 0xff);
case Xtensa::fixup_xtensa_l32r_16:
unsigned Offset = Fixup.getOffset();
if (Offset & 0x3)
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaFixupKinds.h b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaFixupKinds.h
index 57b114e709a8a..f6b1e58adf073 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaFixupKinds.h
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaFixupKinds.h
@@ -22,6 +22,7 @@ enum FixupKind {
fixup_xtensa_jump_18,
fixup_xtensa_call_18,
fixup_xtensa_l32r_16,
+ fixup_xtensa_loop_8,
fixup_xtensa_invalid,
LastTargetFixupKind,
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
index da7e9098f7544..bb013d5ac5681 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
@@ -105,6 +105,21 @@ void XtensaInstPrinter::printBranchTarget(const MCInst *MI, int OpNum,
llvm_unreachable("Invalid operand");
}
+void XtensaInstPrinter::printLoopTarget(const MCInst *MI, int OpNum,
+ raw_ostream &OS) {
+ const MCOperand &MC = MI->getOperand(OpNum);
+ if (MI->getOperand(OpNum).isImm()) {
+ int64_t Val = MC.getImm() + 4;
+ OS << ". ";
+ if (Val > 0)
+ OS << '+';
+ OS << Val;
+ } else if (MC.isExpr())
+ MC.getExpr()->print(OS, &MAI, true);
+ else
+ llvm_unreachable("Invalid operand");
+}
+
void XtensaInstPrinter::printJumpTarget(const MCInst *MI, int OpNum,
raw_ostream &OS) {
const MCOperand &MC = MI->getOperand(OpNum);
@@ -404,3 +419,14 @@ void XtensaInstPrinter::printB4constu_AsmOperand(const MCInst *MI, int OpNum,
} else
printOperand(MI, OpNum, O);
}
+
+void XtensaInstPrinter::printImm7_22_AsmOperand(const MCInst *MI, int OpNum,
+ raw_ostream &O) {
+ if (MI->getOperand(OpNum).isImm()) {
+ int64_t Value = MI->getOperand(OpNum).getImm();
+ assert((Value >= 7 && Value <= 22) &&
+ "Invalid argument, value must be in range <7,22>");
+ O << Value;
+ } else
+ printOperand(MI, OpNum, O);
+}
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
index 630b4dd60108f..34d72dfa1c69a 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
@@ -46,6 +46,7 @@ class XtensaInstPrinter : public MCInstPrinter {
void printOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printMemOperand(const MCInst *MI, int OpNUm, raw_ostream &O);
void printBranchTarget(const MCInst *MI, int OpNum, raw_ostream &O);
+ void printLoopTarget(const MCInst *MI, int OpNum, raw_ostream &O);
void printJumpTarget(const MCInst *MI, int OpNum, raw_ostream &O);
void printCallOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printL32RTarget(const MCInst *MI, int OpNum, raw_ostream &O);
@@ -69,6 +70,7 @@ class XtensaInstPrinter : public MCInstPrinter {
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);
+ void printImm7_22_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
};
} // end namespace llvm
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
index e6cdd3d0020fc..8231a8a9a44d4 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
@@ -67,6 +67,10 @@ class XtensaMCCodeEmitter : public MCCodeEmitter {
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ uint32_t getLoopTargetEncoding(const MCInst &MI, unsigned int OpNum,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
uint32_t getCallEncoding(const MCInst &MI, unsigned int OpNum,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
@@ -134,6 +138,10 @@ class XtensaMCCodeEmitter : public MCCodeEmitter {
uint32_t getB4constuOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+
+ uint32_t getImm7_22OpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
};
} // namespace
@@ -220,6 +228,23 @@ uint32_t XtensaMCCodeEmitter::getBranchTargetEncoding(
}
}
+uint32_t
+XtensaMCCodeEmitter::getLoopTargetEncoding(const MCInst &MI, unsigned int OpNum,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ const MCOperand &MO = MI.getOperand(OpNum);
+ if (MO.isImm())
+ return static_cast<uint32_t>(MO.getImm());
+
+ assert((MO.isExpr()) && "Unexpected operand value!");
+
+ const MCExpr *Expr = MO.getExpr();
+
+ Fixups.push_back(MCFixup::create(
+ 0, Expr, MCFixupKind(Xtensa::fixup_xtensa_loop_8), MI.getLoc()));
+ return 0;
+}
+
uint32_t
XtensaMCCodeEmitter::getCallEncoding(const MCInst &MI, unsigned int OpNum,
SmallVectorImpl<MCFixup> &Fixups,
@@ -554,4 +579,17 @@ XtensaMCCodeEmitter::getB4constuOpValue(const MCInst &MI, unsigned OpNo,
return Res;
}
+
+uint32_t
+XtensaMCCodeEmitter::getImm7_22OpValue(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());
+
+ res -= 7;
+ assert(((res & 0xf) == res) && "Unexpected operand value!");
+
+ return res;
+}
#include "XtensaGenMCCodeEmitter.inc"
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
index adaa9a71a905c..792faf811aca9 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
@@ -79,6 +79,10 @@ bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits) {
switch (RegNo) {
case Xtensa::BREG:
return FeatureBits[Xtensa::FeatureBoolean];
+ case Xtensa::LBEG:
+ case Xtensa::LEND:
+ case Xtensa::LCOUNT:
+ return FeatureBits[Xtensa::FeatureLoop];
case Xtensa::WINDOWBASE:
case Xtensa::WINDOWSTART:
return FeatureBits[Xtensa::FeatureWindowed];
diff --git a/llvm/lib/Target/Xtensa/XtensaFeatures.td b/llvm/lib/Target/Xtensa/XtensaFeatures.td
index 184828cd253f3..8b2d351dae386 100644
--- a/llvm/lib/Target/Xtensa/XtensaFeatures.td
+++ b/llvm/lib/Target/Xtensa/XtensaFeatures.td
@@ -22,3 +22,28 @@ def FeatureBoolean : SubtargetFeature<"bool", "HasBoolean", "true",
"Enable Xtensa Boolean extension">;
def HasBoolean : Predicate<"Subtarget->hasBoolean()">,
AssemblerPredicate<(all_of FeatureBoolean)>;
+
+def FeatureLoop : SubtargetFeature<"loop", "HasLoop", "true",
+ "Enable Xtensa Loop extension">;
+def HasLoop : Predicate<"Subtarget->hasLoop()">,
+ AssemblerPredicate<(all_of FeatureLoop)>;
+
+def FeatureSEXT : SubtargetFeature<"sext", "HasSEXT", "true",
+ "Enable Xtensa Sign Extend option">;
+def HasSEXT : Predicate<"Subtarget->hasSEXT()">,
+ AssemblerPredicate<(all_of FeatureSEXT)>;
+
+def FeatureCLAMPS : SubtargetFeature<"clamps", "HasCLAMPS", "true",
+ "Enable Xtensa CLAMPS option">;
+def HasCLAMPS : Predicate<"Subtarget->hasCLAMPS()">,
+ AssemblerPredicate<(all_of FeatureCLAMPS)>;
+
+def FeatureNSA : SubtargetFeature<"nsa", "HasNSA", "true",
+ "Enable Xtensa NSA option">;
+def HasNSA : Predicate<"Subtarget->hasNSA()">,
+ AssemblerPredicate<(all_of FeatureNSA)>;
+
+def FeatureMINMAX : SubtargetFeature<"minmax", "HasMINMAX", "true",
+ "Enable Xtensa MINMAX option">;
+def HasMINMAX : Predicate<"Subtarget->hasMINMAX()">,
+ AssemblerPredicate<(all_of FeatureMINMAX)>;
diff --git a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
index d4ee2ca72ad38..9ba87cf6d5878 100644
--- a/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaISelLowering.cpp
@@ -75,8 +75,8 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
setBooleanContents(ZeroOrOneBooleanContent);
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
- setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand);
- setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
+ setOperationAction(ISD::SIGN_EXTEND_INREG, {MVT::i8, MVT::i16},
+ Subtarget.hasSEXT() ? Legal : Expand);
setOperationAction(ISD::BITCAST, MVT::i32, Expand);
setOperationAction(ISD::BITCAST, MVT::f32, Expand);
@@ -141,6 +141,9 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
+ setOperationAction({ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX}, MVT::i32,
+ Subtarget.hasMINMAX() ? Legal : Expand);
+
// Implement custom stack allocations
setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom);
// Implement custom stack save and restore
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
index 2de19f62e14c5..9734e914db335 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
@@ -868,6 +868,94 @@ let Constraints = "$dr = $r, at earlyclobber $dr" in {
"movt\t$r, $s, $t", []>, Requires<[HasBoolean]>;
}
+//===----------------------------------------------------------------------===//
+// SEXT Instruction
+//===----------------------------------------------------------------------===//
+
+def SEXT : RRR_Inst<0x00, 0x03, 0x02, (outs AR:$r), (ins AR:$s, imm7_22:$imm),
+ "sext\t$r, $s, $imm", []>, Requires<[HasSEXT]> {
+ bits<4> imm;
+
+ let t = imm;
+}
+
+def : Pat<(i32 (sext_inreg AR:$s, i8)), (SEXT AR:$s, (i32 7))>;
+def : Pat<(i32 (sext_inreg AR:$s, i16)), (SEXT AR:$s, (i32 15))>;
+
+//===----------------------------------------------------------------------===//
+// CLAMPS Instruction
+//===----------------------------------------------------------------------===//
+
+def CLAMPS : RRR_Inst<0x00, 0x03, 0x03, (outs AR:$r), (ins AR:$s, imm7_22:$imm),
+ "clamps\t$r, $s, $imm", []>, Requires<[HasCLAMPS]> {
+ bits<4> imm;
+
+ let t = imm;
+}
+
+//===----------------------------------------------------------------------===//
+// NSA Instructions
+//===----------------------------------------------------------------------===//
+
+def NSA : RRR_Inst<0x00, 0x00, 0x04, (outs AR:$t), (ins AR:$s),
+ "nsa\t$t, $s", []>, Requires<[HasNSA]> {
+ let r = 0xE;
+}
+
+def NSAU : RRR_Inst<0x00, 0x00, 0x04, (outs AR:$t), (ins AR:$s),
+ "nsau\t$t, $s",
+ [(set AR:$t, (ctlz AR:$s))]>, Requires<[HasNSA]> {
+ let r = 0xF;
+}
+
+//===----------------------------------------------------------------------===//
+// MINMAX Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasMINMAX] in {
+ def MIN : ArithLogic_RRR<0x04, 0x03, "min", smin, 1>;
+ def MAX : ArithLogic_RRR<0x05, 0x03, "max", smax, 1>;
+ def MINU : ArithLogic_RRR<0x06, 0x03, "minu", umin, 1>;
+ def MAXU : ArithLogic_RRR<0x07, 0x03, "maxu", umax, 1>;
+}
+
+//===----------------------------------------------------------------------===//
+// Loop Instructions
+//===----------------------------------------------------------------------===//
+
+def LOOP : RRI8_Inst<0x06, (outs), (ins AR:$s, ltarget:$target),
+ "loop\t$s, $target", []>, Requires<[HasLoop]> {
+ bits<8> target;
+
+ let r = 0x08;
+ let t = 0x07;
+ let imm8 = target;
+}
+
+def : InstAlias<"_loop\t$s, $target", (LOOP AR:$s, ltarget:$target)>;
+
+def LOOPGTZ : RRI8_Inst<0x06, (outs), (ins AR:$s, ltarget:$target),
+ "loopgtz\t$s, $target", []>, Requires<[HasLoop]> {
+ bits<8> target;
+
+ let r = 0x0A;
+ let t = 0x07;
+ let imm8 = target;
+}
+
+def : InstAlias<"_loopgtz\t$s, $target", (LOOPGTZ AR:$s, ltarget:$target)>;
+
+def LOOPNEZ : RRI8_Inst<0x06, (outs), (ins AR:$s, ltarget:$target),
+ "loopnez\t$s, $target", []>, Requires<[HasLoop]> {
+ bits<8> target;
+
+ let r = 0x09;
+ let t = 0x07;
+ let imm8 = target;
+}
+
+def : InstAlias<"_loopnez\t$s, $target", (LOOPNEZ AR:$s, ltarget:$target)>;
+
//===----------------------------------------------------------------------===//
// DSP Instructions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Xtensa/XtensaOperands.td b/llvm/lib/Target/Xtensa/XtensaOperands.td
index 402e05a5c3dd1..6f893c56378e5 100644
--- a/llvm/lib/Target/Xtensa/XtensaOperands.td
+++ b/llvm/lib/Target/Xtensa/XtensaOperands.td
@@ -167,6 +167,14 @@ def b4constu: Immediate<i32,
let EncoderMethod = "getB4constuOpValue";
let DecoderMethod = "decodeB4constuOperand";
}
+
+// imm7_22 predicate - Immediate in the range [7,22] for sign extend and clamps
+def Imm7_22_AsmOperand: ImmAsmOperand<"imm7_22">;
+def imm7_22: Immediate<i32, [{ return Imm >= 7 && Imm <= 22; }], "Imm7_22_AsmOperand"> {
+ let EncoderMethod = "getImm7_22OpValue";
+ let DecoderMethod = "decodeImm7_22Operand";
+}
+
//===----------------------------------------------------------------------===//
// Memory address operands
//===----------------------------------------------------------------------===//
@@ -230,6 +238,13 @@ def jumptarget : Operand<OtherVT> {
let ParserMatchClass = XtensaPCRelTargetAsmOperand;
}
+def ltarget : Operand<OtherVT> {
+ let PrintMethod = "printLoopTarget";
+ let EncoderMethod = "getLoopTargetEncoding";
+ let DecoderMethod = "decodeLoopOperand";
+ let ParserMatchClass = XtensaPCRelTargetAsmOperand;
+}
+
def L32Rtarget : Operand<i32> {
let PrintMethod = "printL32RTarget";
let EncoderMethod = "getL32RTargetEncoding";
diff --git a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
index 2934018318406..2a40431adc7f0 100644
--- a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
@@ -73,6 +73,11 @@ class SRReg<bits<8> num, string n, list<string> alt = []> : XtensaReg<n> {
let AltNames = alt;
}
+// Loop Option Registers
+def LBEG : SRReg<0, "lbeg", ["LBEG", "0"]>;
+def LEND : SRReg<1, "lend", ["LEND", "1"]>;
+def LCOUNT : SRReg<2, "lcount", ["LCOUNT", "2"]>;
+
// Shift Amount Register
def SAR : SRReg<3, "sar", ["SAR","3"]>;
@@ -95,8 +100,8 @@ def MR01 : RegisterClass<"Xtensa", [i32], 32, (add M0, M1)>;
def MR23 : RegisterClass<"Xtensa", [i32], 32, (add M2, M3)>;
def MR : RegisterClass<"Xtensa", [i32], 32, (add MR01, MR23)>;
-def SR : RegisterClass<"Xtensa", [i32], 32, (add SAR, BREG, MR,
- WINDOWBASE, WINDOWSTART)>;
+def SR : RegisterClass<"Xtensa", [i32], 32, (add
+ LBEG, LEND, LCOUNT, SAR, BREG, MR, WINDOWBASE, WINDOWSTART)>;
//===----------------------------------------------------------------------===//
// Boolean registers
diff --git a/llvm/lib/Target/Xtensa/XtensaSubtarget.h b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
index 05c0c07e93a96..cb7ff30ea1846 100644
--- a/llvm/lib/Target/Xtensa/XtensaSubtarget.h
+++ b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
@@ -72,6 +72,16 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
bool ha...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/133818
More information about the llvm-commits
mailing list