Skip to content

Commit 06b3708

Browse files
committed
[Xtensa] Implement SEXT, NSA, MINMAX and Loop Xtensa Options.
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.
1 parent f30c6a0 commit 06b3708

24 files changed

+442
-12
lines changed

llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ struct XtensaOperand : public MCParsedAsmOperand {
273273
return false;
274274
}
275275

276+
bool isimm7_22() const { return isImm(7, 22); }
277+
276278
/// getStartLoc - Gets location of the first token of this operand
277279
SMLoc getStartLoc() const override { return StartLoc; }
278280
/// getEndLoc - Gets location of the last token of this operand
@@ -538,6 +540,9 @@ bool XtensaAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
538540
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
539541
"expected immediate in range [0, 32760], first 3 bits "
540542
"should be zero");
543+
case Match_Invalidimm7_22:
544+
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
545+
"expected immediate in range [7, 22]");
541546
}
542547

543548
report_fatal_error("Unknown match type detected!");

llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,16 @@ static DecodeStatus decodeBranchOperand(MCInst &Inst, uint64_t Imm,
200200
return MCDisassembler::Success;
201201
}
202202

203+
static DecodeStatus decodeLoopOperand(MCInst &Inst, uint64_t Imm,
204+
int64_t Address, const void *Decoder) {
205+
206+
assert(isUInt<8>(Imm) && "Invalid immediate");
207+
if (!tryAddingSymbolicOperand(Imm + 4 + Address, true, Address, 0, 3, Inst,
208+
Decoder))
209+
Inst.addOperand(MCOperand::createImm(Imm));
210+
return MCDisassembler::Success;
211+
}
212+
203213
static DecodeStatus decodeL32ROperand(MCInst &Inst, uint64_t Imm,
204214
int64_t Address, const void *Decoder) {
205215

@@ -326,6 +336,13 @@ static DecodeStatus decodeB4constuOperand(MCInst &Inst, uint64_t Imm,
326336
return MCDisassembler::Success;
327337
}
328338

339+
static DecodeStatus decodeImm7_22Operand(MCInst &Inst, uint64_t Imm,
340+
int64_t Address, const void *Decoder) {
341+
assert(isUInt<4>(Imm) && "Invalid immediate");
342+
Inst.addOperand(MCOperand::createImm(Imm + 7));
343+
return MCDisassembler::Success;
344+
}
345+
329346
static DecodeStatus decodeMem8Operand(MCInst &Inst, uint64_t Imm,
330347
int64_t Address, const void *Decoder) {
331348
assert(isUInt<12>(Imm) && "Invalid immediate");

llvm/lib/Target/Xtensa/MCTargetDesc/XtensaAsmBackend.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ XtensaMCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
6464
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
6565
{"fixup_xtensa_l32r_16", 8, 16,
6666
MCFixupKindInfo::FKF_IsPCRel |
67-
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits}};
67+
MCFixupKindInfo::FKF_IsAlignedDownTo32Bits},
68+
{"fixup_xtensa_loop_8", 16, 8, MCFixupKindInfo::FKF_IsPCRel}};
6869

6970
if (Kind < FirstTargetFixupKind)
7071
return MCAsmBackend::getFixupKindInfo(Kind);
@@ -116,6 +117,11 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
116117
if (Value & 0x3)
117118
Ctx.reportError(Fixup.getLoc(), "fixup value must be 4-byte aligned");
118119
return (Value & 0xffffc) >> 2;
120+
case Xtensa::fixup_xtensa_loop_8:
121+
Value -= 4;
122+
if (!isUInt<8>(Value))
123+
Ctx.reportError(Fixup.getLoc(), "loop fixup value out of range");
124+
return (Value & 0xff);
119125
case Xtensa::fixup_xtensa_l32r_16:
120126
unsigned Offset = Fixup.getOffset();
121127
if (Offset & 0x3)

llvm/lib/Target/Xtensa/MCTargetDesc/XtensaFixupKinds.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ enum FixupKind {
2222
fixup_xtensa_jump_18,
2323
fixup_xtensa_call_18,
2424
fixup_xtensa_l32r_16,
25+
fixup_xtensa_loop_8,
2526
fixup_xtensa_invalid,
2627
LastTargetFixupKind,
2728
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind

llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,21 @@ void XtensaInstPrinter::printBranchTarget(const MCInst *MI, int OpNum,
105105
llvm_unreachable("Invalid operand");
106106
}
107107

108+
void XtensaInstPrinter::printLoopTarget(const MCInst *MI, int OpNum,
109+
raw_ostream &OS) {
110+
const MCOperand &MC = MI->getOperand(OpNum);
111+
if (MI->getOperand(OpNum).isImm()) {
112+
int64_t Val = MC.getImm() + 4;
113+
OS << ". ";
114+
if (Val > 0)
115+
OS << '+';
116+
OS << Val;
117+
} else if (MC.isExpr())
118+
MC.getExpr()->print(OS, &MAI, true);
119+
else
120+
llvm_unreachable("Invalid operand");
121+
}
122+
108123
void XtensaInstPrinter::printJumpTarget(const MCInst *MI, int OpNum,
109124
raw_ostream &OS) {
110125
const MCOperand &MC = MI->getOperand(OpNum);
@@ -404,3 +419,14 @@ void XtensaInstPrinter::printB4constu_AsmOperand(const MCInst *MI, int OpNum,
404419
} else
405420
printOperand(MI, OpNum, O);
406421
}
422+
423+
void XtensaInstPrinter::printImm7_22_AsmOperand(const MCInst *MI, int OpNum,
424+
raw_ostream &O) {
425+
if (MI->getOperand(OpNum).isImm()) {
426+
int64_t Value = MI->getOperand(OpNum).getImm();
427+
assert((Value >= 7 && Value <= 22) &&
428+
"Invalid argument, value must be in range <7,22>");
429+
O << Value;
430+
} else
431+
printOperand(MI, OpNum, O);
432+
}

llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class XtensaInstPrinter : public MCInstPrinter {
4646
void printOperand(const MCInst *MI, int OpNum, raw_ostream &O);
4747
void printMemOperand(const MCInst *MI, int OpNUm, raw_ostream &O);
4848
void printBranchTarget(const MCInst *MI, int OpNum, raw_ostream &O);
49+
void printLoopTarget(const MCInst *MI, int OpNum, raw_ostream &O);
4950
void printJumpTarget(const MCInst *MI, int OpNum, raw_ostream &O);
5051
void printCallOperand(const MCInst *MI, int OpNum, raw_ostream &O);
5152
void printL32RTarget(const MCInst *MI, int OpNum, raw_ostream &O);
@@ -69,6 +70,7 @@ class XtensaInstPrinter : public MCInstPrinter {
6970
void printEntry_Imm12_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
7071
void printB4const_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
7172
void printB4constu_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
73+
void printImm7_22_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
7274
};
7375
} // end namespace llvm
7476

llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ class XtensaMCCodeEmitter : public MCCodeEmitter {
6767
SmallVectorImpl<MCFixup> &Fixups,
6868
const MCSubtargetInfo &STI) const;
6969

70+
uint32_t getLoopTargetEncoding(const MCInst &MI, unsigned int OpNum,
71+
SmallVectorImpl<MCFixup> &Fixups,
72+
const MCSubtargetInfo &STI) const;
73+
7074
uint32_t getCallEncoding(const MCInst &MI, unsigned int OpNum,
7175
SmallVectorImpl<MCFixup> &Fixups,
7276
const MCSubtargetInfo &STI) const;
@@ -134,6 +138,10 @@ class XtensaMCCodeEmitter : public MCCodeEmitter {
134138
uint32_t getB4constuOpValue(const MCInst &MI, unsigned OpNo,
135139
SmallVectorImpl<MCFixup> &Fixups,
136140
const MCSubtargetInfo &STI) const;
141+
142+
uint32_t getImm7_22OpValue(const MCInst &MI, unsigned OpNo,
143+
SmallVectorImpl<MCFixup> &Fixups,
144+
const MCSubtargetInfo &STI) const;
137145
};
138146
} // namespace
139147

@@ -220,6 +228,23 @@ uint32_t XtensaMCCodeEmitter::getBranchTargetEncoding(
220228
}
221229
}
222230

231+
uint32_t
232+
XtensaMCCodeEmitter::getLoopTargetEncoding(const MCInst &MI, unsigned int OpNum,
233+
SmallVectorImpl<MCFixup> &Fixups,
234+
const MCSubtargetInfo &STI) const {
235+
const MCOperand &MO = MI.getOperand(OpNum);
236+
if (MO.isImm())
237+
return static_cast<uint32_t>(MO.getImm());
238+
239+
assert((MO.isExpr()) && "Unexpected operand value!");
240+
241+
const MCExpr *Expr = MO.getExpr();
242+
243+
Fixups.push_back(MCFixup::create(
244+
0, Expr, MCFixupKind(Xtensa::fixup_xtensa_loop_8), MI.getLoc()));
245+
return 0;
246+
}
247+
223248
uint32_t
224249
XtensaMCCodeEmitter::getCallEncoding(const MCInst &MI, unsigned int OpNum,
225250
SmallVectorImpl<MCFixup> &Fixups,
@@ -554,4 +579,17 @@ XtensaMCCodeEmitter::getB4constuOpValue(const MCInst &MI, unsigned OpNo,
554579

555580
return Res;
556581
}
582+
583+
uint32_t
584+
XtensaMCCodeEmitter::getImm7_22OpValue(const MCInst &MI, unsigned OpNo,
585+
SmallVectorImpl<MCFixup> &Fixups,
586+
const MCSubtargetInfo &STI) const {
587+
const MCOperand &MO = MI.getOperand(OpNo);
588+
uint32_t res = static_cast<uint32_t>(MO.getImm());
589+
590+
res -= 7;
591+
assert(((res & 0xf) == res) && "Unexpected operand value!");
592+
593+
return res;
594+
}
557595
#include "XtensaGenMCCodeEmitter.inc"

llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits) {
7979
switch (RegNo) {
8080
case Xtensa::BREG:
8181
return FeatureBits[Xtensa::FeatureBoolean];
82+
case Xtensa::LBEG:
83+
case Xtensa::LEND:
84+
case Xtensa::LCOUNT:
85+
return FeatureBits[Xtensa::FeatureLoop];
8286
case Xtensa::WINDOWBASE:
8387
case Xtensa::WINDOWSTART:
8488
return FeatureBits[Xtensa::FeatureWindowed];

llvm/lib/Target/Xtensa/XtensaFeatures.td

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,28 @@ def FeatureBoolean : SubtargetFeature<"bool", "HasBoolean", "true",
2222
"Enable Xtensa Boolean extension">;
2323
def HasBoolean : Predicate<"Subtarget->hasBoolean()">,
2424
AssemblerPredicate<(all_of FeatureBoolean)>;
25+
26+
def FeatureLoop : SubtargetFeature<"loop", "HasLoop", "true",
27+
"Enable Xtensa Loop extension">;
28+
def HasLoop : Predicate<"Subtarget->hasLoop()">,
29+
AssemblerPredicate<(all_of FeatureLoop)>;
30+
31+
def FeatureSEXT : SubtargetFeature<"sext", "HasSEXT", "true",
32+
"Enable Xtensa Sign Extend option">;
33+
def HasSEXT : Predicate<"Subtarget->hasSEXT()">,
34+
AssemblerPredicate<(all_of FeatureSEXT)>;
35+
36+
def FeatureCLAMPS : SubtargetFeature<"clamps", "HasCLAMPS", "true",
37+
"Enable Xtensa CLAMPS option">;
38+
def HasCLAMPS : Predicate<"Subtarget->hasCLAMPS()">,
39+
AssemblerPredicate<(all_of FeatureCLAMPS)>;
40+
41+
def FeatureNSA : SubtargetFeature<"nsa", "HasNSA", "true",
42+
"Enable Xtensa NSA option">;
43+
def HasNSA : Predicate<"Subtarget->hasNSA()">,
44+
AssemblerPredicate<(all_of FeatureNSA)>;
45+
46+
def FeatureMINMAX : SubtargetFeature<"minmax", "HasMINMAX", "true",
47+
"Enable Xtensa MINMAX option">;
48+
def HasMINMAX : Predicate<"Subtarget->hasMINMAX()">,
49+
AssemblerPredicate<(all_of FeatureMINMAX)>;

llvm/lib/Target/Xtensa/XtensaISelLowering.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
7575
setBooleanContents(ZeroOrOneBooleanContent);
7676

7777
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
78-
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand);
79-
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
78+
setOperationAction(ISD::SIGN_EXTEND_INREG, {MVT::i8, MVT::i16},
79+
Subtarget.hasSEXT() ? Legal : Expand);
8080

8181
setOperationAction(ISD::BITCAST, MVT::i32, Expand);
8282
setOperationAction(ISD::BITCAST, MVT::f32, Expand);
@@ -141,6 +141,9 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
141141
setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
142142
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
143143

144+
setOperationAction({ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX}, MVT::i32,
145+
Subtarget.hasMINMAX() ? Legal : Expand);
146+
144147
// Implement custom stack allocations
145148
setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom);
146149
// Implement custom stack save and restore

0 commit comments

Comments
 (0)