Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class XtensaAsmParser : public MCTargetAsmParser {
SMLoc &EndLoc) override {
return ParseStatus::NoMatch;
}
bool checkRegister(MCRegister RegNo);
ParseStatus parsePCRelTarget(OperandVector &Operands);
bool parseLiteralDirective(SMLoc L);

Expand All @@ -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].
Expand Down Expand Up @@ -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); }
Expand All @@ -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;
Expand Down Expand Up @@ -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]");
Expand All @@ -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!");
Expand Down Expand Up @@ -601,6 +626,10 @@ ParseStatus XtensaAsmParser::parseRegister(OperandVector &Operands,
getLexer().UnLex(Buf[0]);
return ParseStatus::NoMatch;
}

if (!checkRegister(RegNo))
return ParseStatus::NoMatch;

if (HadParens)
Operands.push_back(XtensaOperand::createToken("(", FirstS));
SMLoc S = getLoc();
Expand Down Expand Up @@ -702,7 +731,7 @@ bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
if (RegNo == 0)
RegNo = MatchRegisterAltName(RegName);

if (RegNo == 0)
if (!checkRegister(RegNo))
return Error(NameLoc, "invalid register name");

// Parse operand
Expand Down Expand Up @@ -826,6 +855,22 @@ ParseStatus XtensaAsmParser::parseDirective(AsmToken DirectiveID) {
return ParseStatus::NoMatch;
}

// Verify Special Register
bool XtensaAsmParser::checkRegister(MCRegister RegNo) {
bool Res = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be rewritten with a simpler expression without any conditional assign and break

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rewrote the function code.


switch (RegNo) {
case Xtensa::WINDOWBASE:
case Xtensa::WINDOWSTART:
Res = hasWindowed();
break;
case Xtensa::NoRegister:
Res = false;
}

return Res;
}

// Force static initialization.
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmParser() {
RegisterMCAsmParser<XtensaAsmParser> X(getTheXtensaTarget());
Expand Down
50 changes: 49 additions & 1 deletion llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,42 @@ static DecodeStatus DecodeARRegisterClass(MCInst &Inst, uint64_t RegNo,
return MCDisassembler::Success;
}

static const unsigned SRDecoderTable[] = {Xtensa::SAR, 3};
// Verify SR
bool CheckRegister(unsigned RegNo, MCSubtargetInfo STI) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, also this is the same function? Also should start with lowercase, and not pass MCSubtargetInfo by value

Copy link
Contributor Author

@andreisfr andreisfr Jan 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rewrote the function code and name. This function is almost the same as "checkRegister" in asm parser. I plan to make version asm parser more complex (then disassembler version) in future commits (probably it will require additional arguments). Am I understand correctly that your suggestion is to create single variant of this function in XtensaUtils.*?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arsenm , I placed "checkRegister" function to the "XtensaUtils.cpp" in new commit. Could you please take a look?

bool Res = true;

switch (RegNo) {
case Xtensa::WINDOWBASE:
case Xtensa::WINDOWSTART:
Res = STI.getFeatureBits()[Xtensa::FeatureWindowed];
break;
default:
Res = false;
break;
}

return Res;
}

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 llvm::MCSubtargetInfo STI =
((const MCDisassembler *)Decoder)->getSubtargetInfo();

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 (!CheckRegister(Reg, STI))
return MCDisassembler::Fail;

Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
Expand Down Expand Up @@ -210,6 +235,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) {
Expand Down
34 changes: 34 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down Expand Up @@ -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()) {
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
Expand Down
52 changes: 52 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 3 additions & 4 deletions llvm/lib/Target/Xtensa/Xtensa.td
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//===----------------------------------------------------------------------===//
Expand Down
14 changes: 14 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaFeatures.td
Original file line number Diff line number Diff line change
@@ -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)>;
Loading
Loading