Skip to content

Commit dd40880

Browse files
committed
[Xtensa] Implement Windowed Register Option.
This second version of the Windowed Register Option implementation. In this variant "checkRegister" function placed in XtensaMCTargetDesc.
1 parent e98b202 commit dd40880

18 files changed

+544
-9
lines changed

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

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class XtensaAsmParser : public MCTargetAsmParser {
7373
SMLoc &EndLoc) override {
7474
return ParseStatus::NoMatch;
7575
}
76+
7677
ParseStatus parsePCRelTarget(OperandVector &Operands);
7778
bool parseLiteralDirective(SMLoc L);
7879

@@ -89,6 +90,10 @@ class XtensaAsmParser : public MCTargetAsmParser {
8990
: MCTargetAsmParser(Options, STI, MII) {
9091
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
9192
}
93+
94+
bool hasWindowed() const {
95+
return getSTI().getFeatureBits()[Xtensa::FeatureWindowed];
96+
};
9297
};
9398

9499
// Return true if Expr is in the range [MinValue, MaxValue].
@@ -181,6 +186,11 @@ struct XtensaOperand : public MCParsedAsmOperand {
181186
((cast<MCConstantExpr>(getImm())->getValue() & 0x3) == 0);
182187
}
183188

189+
bool isentry_imm12() const {
190+
return isImm(0, 32760) &&
191+
((cast<MCConstantExpr>(getImm())->getValue() % 8) == 0);
192+
}
193+
184194
bool isUimm4() const { return isImm(0, 15); }
185195

186196
bool isUimm5() const { return isImm(0, 31); }
@@ -198,6 +208,11 @@ struct XtensaOperand : public MCParsedAsmOperand {
198208

199209
bool isImm32n_95() const { return isImm(-32, 95); }
200210

211+
bool isImm64n_4n() const {
212+
return isImm(-64, -4) &&
213+
((cast<MCConstantExpr>(getImm())->getValue() & 0x3) == 0);
214+
}
215+
201216
bool isB4const() const {
202217
if (Kind != Immediate)
203218
return false;
@@ -491,6 +506,12 @@ bool XtensaAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
491506
case Match_InvalidImm32n_95:
492507
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
493508
"expected immediate in range [-32, 95]");
509+
case Match_InvalidImm64n_4n:
510+
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
511+
"expected immediate in range [-64, -4]");
512+
case Match_InvalidImm8n_7:
513+
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
514+
"expected immediate in range [-8, 7]");
494515
case Match_InvalidShimm1_31:
495516
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
496517
"expected immediate in range [1, 31]");
@@ -515,6 +536,10 @@ bool XtensaAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
515536
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
516537
"expected immediate in range [0, 60], first 2 bits "
517538
"should be zero");
539+
case Match_Invalidentry_imm12:
540+
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
541+
"expected immediate in range [0, 32760], first 3 bits "
542+
"should be zero");
518543
}
519544

520545
report_fatal_error("Unknown match type detected!");
@@ -601,6 +626,10 @@ ParseStatus XtensaAsmParser::parseRegister(OperandVector &Operands,
601626
getLexer().UnLex(Buf[0]);
602627
return ParseStatus::NoMatch;
603628
}
629+
630+
if (!Xtensa::checkRegister(RegNo, getSTI().getFeatureBits()))
631+
return ParseStatus::NoMatch;
632+
604633
if (HadParens)
605634
Operands.push_back(XtensaOperand::createToken("(", FirstS));
606635
SMLoc S = getLoc();
@@ -702,7 +731,7 @@ bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
702731
if (RegNo == 0)
703732
RegNo = MatchRegisterAltName(RegName);
704733

705-
if (RegNo == 0)
734+
if (!Xtensa::checkRegister(RegNo, getSTI().getFeatureBits()))
706735
return Error(NameLoc, "invalid register name");
707736

708737
// Parse operand

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,23 @@ static DecodeStatus DecodeARRegisterClass(MCInst &Inst, uint64_t RegNo,
7373
return MCDisassembler::Success;
7474
}
7575

76-
static const unsigned SRDecoderTable[] = {Xtensa::SAR, 3};
76+
static const unsigned SRDecoderTable[] = {
77+
Xtensa::SAR, 3, Xtensa::WINDOWBASE, 72, Xtensa::WINDOWSTART, 73};
7778

7879
static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
7980
uint64_t Address,
80-
const void *Decoder) {
81+
const MCDisassembler *Decoder) {
8182
if (RegNo > 255)
8283
return MCDisassembler::Fail;
8384

8485
for (unsigned i = 0; i < std::size(SRDecoderTable); i += 2) {
8586
if (SRDecoderTable[i + 1] == RegNo) {
8687
unsigned Reg = SRDecoderTable[i];
88+
89+
if (!Xtensa::checkRegister(Reg,
90+
Decoder->getSubtargetInfo().getFeatureBits()))
91+
return MCDisassembler::Fail;
92+
8793
Inst.addOperand(MCOperand::createReg(Reg));
8894
return MCDisassembler::Success;
8995
}
@@ -210,6 +216,29 @@ static DecodeStatus decodeImm32n_95Operand(MCInst &Inst, uint64_t Imm,
210216
return MCDisassembler::Success;
211217
}
212218

219+
static DecodeStatus decodeImm8n_7Operand(MCInst &Inst, uint64_t Imm,
220+
int64_t Address, const void *Decoder) {
221+
assert(isUInt<4>(Imm) && "Invalid immediate");
222+
Inst.addOperand(MCOperand::createImm(Imm > 7 ? Imm - 16 : Imm));
223+
return MCDisassembler::Success;
224+
}
225+
226+
static DecodeStatus decodeImm64n_4nOperand(MCInst &Inst, uint64_t Imm,
227+
int64_t Address,
228+
const void *Decoder) {
229+
assert(isUInt<6>(Imm) && ((Imm & 0x3) == 0) && "Invalid immediate");
230+
Inst.addOperand(MCOperand::createImm((~0x3f) | (Imm)));
231+
return MCDisassembler::Success;
232+
}
233+
234+
static DecodeStatus decodeEntry_Imm12OpValue(MCInst &Inst, uint64_t Imm,
235+
int64_t Address,
236+
const void *Decoder) {
237+
assert(isUInt<15>(Imm) && ((Imm & 0x7) == 0) && "Invalid immediate");
238+
Inst.addOperand(MCOperand::createImm(Imm));
239+
return MCDisassembler::Success;
240+
}
241+
213242
static DecodeStatus decodeShimm1_31Operand(MCInst &Inst, uint64_t Imm,
214243
int64_t Address,
215244
const void *Decoder) {

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,28 @@ void XtensaInstPrinter::printImm32n_95_AsmOperand(const MCInst *MI, int OpNum,
264264
printOperand(MI, OpNum, O);
265265
}
266266

267+
void XtensaInstPrinter::printImm8n_7_AsmOperand(const MCInst *MI, int OpNum,
268+
raw_ostream &O) {
269+
if (MI->getOperand(OpNum).isImm()) {
270+
int64_t Value = MI->getOperand(OpNum).getImm();
271+
assert((Value >= -8 && Value <= 7) &&
272+
"Invalid argument, value must be in ranges <-8,7>");
273+
O << Value;
274+
} else
275+
printOperand(MI, OpNum, O);
276+
}
277+
278+
void XtensaInstPrinter::printImm64n_4n_AsmOperand(const MCInst *MI, int OpNum,
279+
raw_ostream &O) {
280+
if (MI->getOperand(OpNum).isImm()) {
281+
int64_t Value = MI->getOperand(OpNum).getImm();
282+
assert((Value >= -64 && Value <= -4) & ((Value & 0x3) == 0) &&
283+
"Invalid argument, value must be in ranges <-64,-4>");
284+
O << Value;
285+
} else
286+
printOperand(MI, OpNum, O);
287+
}
288+
267289
void XtensaInstPrinter::printOffset8m8_AsmOperand(const MCInst *MI, int OpNum,
268290
raw_ostream &O) {
269291
if (MI->getOperand(OpNum).isImm()) {
@@ -309,6 +331,18 @@ void XtensaInstPrinter::printOffset4m32_AsmOperand(const MCInst *MI, int OpNum,
309331
printOperand(MI, OpNum, O);
310332
}
311333

334+
void XtensaInstPrinter::printEntry_Imm12_AsmOperand(const MCInst *MI, int OpNum,
335+
raw_ostream &O) {
336+
if (MI->getOperand(OpNum).isImm()) {
337+
int64_t Value = MI->getOperand(OpNum).getImm();
338+
assert((Value >= 0 && Value <= 32760) &&
339+
"Invalid argument, value must be multiples of eight in range "
340+
"<0,32760>");
341+
O << Value;
342+
} else
343+
printOperand(MI, OpNum, O);
344+
}
345+
312346
void XtensaInstPrinter::printB4const_AsmOperand(const MCInst *MI, int OpNum,
313347
raw_ostream &O) {
314348
if (MI->getOperand(OpNum).isImm()) {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,13 @@ class XtensaInstPrinter : public MCInstPrinter {
6060
void printImm1_16_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
6161
void printImm1n_15_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
6262
void printImm32n_95_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
63+
void printImm8n_7_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
64+
void printImm64n_4n_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
6365
void printOffset8m8_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
6466
void printOffset8m16_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
6567
void printOffset8m32_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
6668
void printOffset4m32_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
69+
void printEntry_Imm12_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
6770
void printB4const_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
6871
void printB4constu_AsmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
6972
};

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

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,18 @@ class XtensaMCCodeEmitter : public MCCodeEmitter {
111111
SmallVectorImpl<MCFixup> &Fixups,
112112
const MCSubtargetInfo &STI) const;
113113

114+
uint32_t getImm8n_7OpValue(const MCInst &MI, unsigned OpNo,
115+
SmallVectorImpl<MCFixup> &Fixups,
116+
const MCSubtargetInfo &STI) const;
117+
118+
uint32_t getImm64n_4nOpValue(const MCInst &MI, unsigned OpNo,
119+
SmallVectorImpl<MCFixup> &Fixups,
120+
const MCSubtargetInfo &STI) const;
121+
122+
uint32_t getEntry_Imm12OpValue(const MCInst &MI, unsigned OpNo,
123+
SmallVectorImpl<MCFixup> &Fixups,
124+
const MCSubtargetInfo &STI) const;
125+
114126
uint32_t getShimm1_31OpValue(const MCInst &MI, unsigned OpNo,
115127
SmallVectorImpl<MCFixup> &Fixups,
116128
const MCSubtargetInfo &STI) const;
@@ -405,6 +417,46 @@ XtensaMCCodeEmitter::getImm32n_95OpValue(const MCInst &MI, unsigned OpNo,
405417
return Res;
406418
}
407419

420+
uint32_t
421+
XtensaMCCodeEmitter::getImm8n_7OpValue(const MCInst &MI, unsigned OpNo,
422+
SmallVectorImpl<MCFixup> &Fixups,
423+
const MCSubtargetInfo &STI) const {
424+
const MCOperand &MO = MI.getOperand(OpNo);
425+
int32_t Res = static_cast<int32_t>(MO.getImm());
426+
427+
assert(((Res >= -8) && (Res <= 7)) && "Unexpected operand value!");
428+
429+
if (Res < 0)
430+
return Res + 16;
431+
432+
return Res;
433+
}
434+
435+
uint32_t
436+
XtensaMCCodeEmitter::getImm64n_4nOpValue(const MCInst &MI, unsigned OpNo,
437+
SmallVectorImpl<MCFixup> &Fixups,
438+
const MCSubtargetInfo &STI) const {
439+
const MCOperand &MO = MI.getOperand(OpNo);
440+
int32_t Res = static_cast<int32_t>(MO.getImm());
441+
442+
assert(((Res >= -64) && (Res <= -4) && ((Res & 0x3) == 0)) &&
443+
"Unexpected operand value!");
444+
445+
return Res & 0x3f;
446+
}
447+
448+
uint32_t
449+
XtensaMCCodeEmitter::getEntry_Imm12OpValue(const MCInst &MI, unsigned OpNo,
450+
SmallVectorImpl<MCFixup> &Fixups,
451+
const MCSubtargetInfo &STI) const {
452+
const MCOperand &MO = MI.getOperand(OpNo);
453+
uint32_t res = static_cast<uint32_t>(MO.getImm());
454+
455+
assert(((res & 0x7) == 0) && "Unexpected operand value!");
456+
457+
return res;
458+
}
459+
408460
uint32_t
409461
XtensaMCCodeEmitter::getB4constOpValue(const MCInst &MI, unsigned OpNo,
410462
SmallVectorImpl<MCFixup> &Fixups,

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,19 @@ bool Xtensa::isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset) {
7474
return isValidAddrOffset(Scale, Offset);
7575
}
7676

77+
// Verify Special Register
78+
bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits) {
79+
switch (RegNo) {
80+
case Xtensa::WINDOWBASE:
81+
case Xtensa::WINDOWSTART:
82+
return FeatureBits[Xtensa::FeatureWindowed];
83+
case Xtensa::NoRegister:
84+
return false;
85+
}
86+
87+
return true;
88+
}
89+
7790
static MCAsmInfo *createXtensaMCAsmInfo(const MCRegisterInfo &MRI,
7891
const Triple &TT,
7992
const MCTargetOptions &Options) {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919

2020
namespace llvm {
2121

22+
class FeatureBitset;
2223
class MCAsmBackend;
2324
class MCCodeEmitter;
2425
class MCContext;
2526
class MCInstrInfo;
2627
class MCObjectTargetWriter;
2728
class MCObjectWriter;
29+
class MCRegister;
2830
class MCRegisterInfo;
2931
class MCSubtargetInfo;
3032
class MCTargetOptions;
@@ -52,6 +54,9 @@ bool isValidAddrOffset(int Scale, int64_t OffsetVal);
5254

5355
// Check address offset for load/store instructions.
5456
bool isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset);
57+
58+
// Verify if it's correct to use a special register.
59+
bool checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits);
5560
} // namespace Xtensa
5661
} // end namespace llvm
5762

llvm/lib/Target/Xtensa/Xtensa.td

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@ include "llvm/Target/Target.td"
1717
//===----------------------------------------------------------------------===//
1818
// Subtarget Features.
1919
//===----------------------------------------------------------------------===//
20-
def FeatureDensity : SubtargetFeature<"density", "HasDensity", "true",
21-
"Enable Density instructions">;
22-
def HasDensity : Predicate<"Subtarget->hasDensity()">,
23-
AssemblerPredicate<(all_of FeatureDensity)>;
20+
21+
include "XtensaFeatures.td"
22+
2423
//===----------------------------------------------------------------------===//
2524
// Xtensa supported processors.
2625
//===----------------------------------------------------------------------===//
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//===----------------------------------------------------------------------===//
2+
// Xtensa subtarget features.
3+
//===----------------------------------------------------------------------===//
4+
5+
// Xtensa ISA extensions (Xtensa Options).
6+
def FeatureDensity : SubtargetFeature<"density", "HasDensity", "true",
7+
"Enable Density instructions">;
8+
def HasDensity : Predicate<"Subtarget->hasDensity()">,
9+
AssemblerPredicate<(all_of FeatureDensity)>;
10+
11+
def FeatureWindowed : SubtargetFeature<"windowed", "HasWindowed", "true",
12+
"Enable Xtensa Windowed Register option">;
13+
def HasWindowed : Predicate<"Subtarget->hasWindowed()">,
14+
AssemblerPredicate<(all_of FeatureWindowed)>;

0 commit comments

Comments
 (0)