Skip to content

[Xtensa] Implement Xtensa Floating Point Option. #136086

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
46 changes: 27 additions & 19 deletions llvm/lib/Target/Xtensa/AsmParser/XtensaAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ using namespace llvm;
struct XtensaOperand;

class XtensaAsmParser : public MCTargetAsmParser {

enum XtensaRegisterType { Xtensa_Generic, Xtensa_SR, Xtensa_UR };
SMLoc getLoc() const { return getParser().getTok().getLoc(); }

XtensaTargetStreamer &getTargetStreamer() {
Expand Down Expand Up @@ -63,10 +63,10 @@ class XtensaAsmParser : public MCTargetAsmParser {

ParseStatus parseImmediate(OperandVector &Operands);
ParseStatus parseRegister(OperandVector &Operands, bool AllowParens = false,
bool SR = false);
XtensaRegisterType SR = Xtensa_Generic);
ParseStatus parseOperandWithModifier(OperandVector &Operands);
bool parseOperand(OperandVector &Operands, StringRef Mnemonic,
bool SR = false);
XtensaRegisterType SR = Xtensa_Generic);
bool ParseInstructionWithSR(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc, OperandVector &Operands);
ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
Expand Down Expand Up @@ -586,7 +586,8 @@ bool XtensaAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
}

ParseStatus XtensaAsmParser::parseRegister(OperandVector &Operands,
bool AllowParens, bool SR) {
bool AllowParens,
XtensaRegisterType RegType) {
SMLoc FirstS = getLoc();
bool HadParens = false;
AsmToken Buf[2];
Expand All @@ -596,25 +597,33 @@ ParseStatus XtensaAsmParser::parseRegister(OperandVector &Operands,
if (AllowParens && getLexer().is(AsmToken::LParen)) {
size_t ReadCount = getLexer().peekTokens(Buf);
if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
if ((Buf[0].getKind() == AsmToken::Integer) && (!SR))
if ((Buf[0].getKind() == AsmToken::Integer) &&
(RegType == Xtensa_Generic))
return ParseStatus::NoMatch;
HadParens = true;
getParser().Lex(); // Eat '('
}
}

unsigned RegNo = 0;
MCRegister RegNo = 0;

switch (getLexer().getKind()) {
default:
return ParseStatus::NoMatch;
case AsmToken::Integer:
if (!SR)
if (RegType == Xtensa_Generic)
return ParseStatus::NoMatch;
RegName = getLexer().getTok().getString();
RegNo = MatchRegisterName(RegName);
if (RegNo == 0)

// Parse case when we expect UR register code as special case,
// because SR and UR registers may have the same number
// and such situation may lead to confilct
if (RegType == Xtensa_UR) {
int64_t RegCode = getLexer().getTok().getIntVal();
RegNo = Xtensa::getUserRegister(RegCode);
} else {
RegName = getLexer().getTok().getString();
RegNo = MatchRegisterAltName(RegName);
}
break;
case AsmToken::Identifier:
RegName = getLexer().getTok().getIdentifier();
Expand Down Expand Up @@ -691,7 +700,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) {
XtensaRegisterType RegType) {
// 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);
Expand All @@ -705,7 +714,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, RegType).isSuccess())
return false;

// Attempt to parse token as an immediate
Expand All @@ -719,11 +728,9 @@ bool XtensaAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic,
bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
StringRef Name, SMLoc NameLoc,
OperandVector &Operands) {
if ((Name.starts_with("wsr.") || Name.starts_with("rsr.") ||
Name.starts_with("xsr.")) &&
(Name.size() > 4)) {
// Parse case when instruction name is concatenated with SR register
// name, like "wsr.sar a1"
if ((Name.size() > 4) && Name[3] == '.') {
// Parse case when instruction name is concatenated with SR/UR register
// name, like "wsr.sar a1" or "wur.fcr a1"

// First operand is token for instruction
Operands.push_back(XtensaOperand::createToken(Name.take_front(3), NameLoc));
Expand Down Expand Up @@ -759,7 +766,7 @@ bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
}

// Parse second operand
if (parseOperand(Operands, Name, true))
if (parseOperand(Operands, Name, Name[1] == 's' ? Xtensa_SR : Xtensa_UR))
return true;
}

Expand All @@ -777,7 +784,8 @@ bool XtensaAsmParser::parseInstruction(ParseInstructionInfo &Info,
StringRef Name, SMLoc NameLoc,
OperandVector &Operands) {
if (Name.starts_with("wsr") || Name.starts_with("rsr") ||
Name.starts_with("xsr")) {
Name.starts_with("xsr") || Name.starts_with("rur") ||
Name.starts_with("wur")) {
return ParseInstructionWithSR(Info, Name, NameLoc, Operands);
}

Expand Down
30 changes: 30 additions & 0 deletions llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,36 @@ static DecodeStatus DecodeMR23RegisterClass(MCInst &Inst, uint64_t RegNo,
return MCDisassembler::Success;
}

static const MCPhysReg FPRDecoderTable[] = {
Xtensa::F0, Xtensa::F1, Xtensa::F2, Xtensa::F3, Xtensa::F4, Xtensa::F5,
Xtensa::F6, Xtensa::F7, Xtensa::F8, Xtensa::F9, Xtensa::F10, Xtensa::F11,
Xtensa::F12, Xtensa::F13, Xtensa::F14, Xtensa::F15};

static DecodeStatus DecodeFPRRegisterClass(MCInst &Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder) {
if (RegNo >= std::size(FPRDecoderTable))
return MCDisassembler::Fail;

MCPhysReg Reg = FPRDecoderTable[RegNo];
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}

static DecodeStatus DecodeURRegisterClass(MCInst &Inst, uint64_t RegNo,
uint64_t Address,
const MCDisassembler *Decoder) {
if (RegNo > 255)
return MCDisassembler::Fail;

MCPhysReg Reg = Xtensa::getUserRegister(RegNo);
if (!Xtensa::checkRegister(Reg, Decoder->getSubtargetInfo().getFeatureBits()))
return MCDisassembler::Fail;

Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}

const MCPhysReg SRDecoderTable[] = {
Xtensa::SAR, 3, Xtensa::ACCLO, 16, Xtensa::ACCHI, 17,
Xtensa::M0, 32, Xtensa::M1, 33, Xtensa::M2, 34,
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,11 @@ XtensaMCCodeEmitter::getMemRegEncoding(const MCInst &MI, unsigned OpNo,
case Xtensa::L32I:
case Xtensa::S32I_N:
case Xtensa::L32I_N:
case Xtensa::SSI:
case Xtensa::SSIP:
case Xtensa::LSI:
case Xtensa::LSIP:

if (Res & 0x3) {
report_fatal_error("Unexpected operand value!");
}
Expand Down
14 changes: 14 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits) {
case Xtensa::LEND:
case Xtensa::LCOUNT:
return FeatureBits[Xtensa::FeatureLoop];
case Xtensa::FCR:
case Xtensa::FSR:
return FeatureBits[FeatureSingleFloat];
case Xtensa::WINDOWBASE:
case Xtensa::WINDOWSTART:
return FeatureBits[Xtensa::FeatureWindowed];
Expand All @@ -93,6 +96,17 @@ bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits) {
return true;
}

// Get Xtensa User Register by encoding value.
MCRegister Xtensa::getUserRegister(unsigned Code) {
switch (Code) {
case 232:
return Xtensa::FCR;
case 233:
return Xtensa::FSR;
}
return Xtensa::NoRegister;
}

static MCAsmInfo *createXtensaMCAsmInfo(const MCRegisterInfo &MRI,
const Triple &TT,
const MCTargetOptions &Options) {
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ bool isValidAddrOffsetForOpcode(unsigned Opcode, int64_t Offset);

// Verify if it's correct to use a special register.
bool checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits);

// Get Xtensa User Register by register encoding value.
MCRegister getUserRegister(unsigned Code);
} // namespace Xtensa
} // end namespace llvm

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/Xtensa/XtensaCallingConv.td
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
def RetCC_Xtensa : CallingConv<[
// First two return values go in a2, a3, a4, a5
CCIfType<[i32], CCAssignToReg<[A2, A3, A4, A5]>>,
CCIfType<[f32], CCAssignToReg<[A2, A3, A4, A5]>>,
CCIfType<[i64], CCAssignToRegWithShadow<[A2, A4], [A3, A5]>>
]>;

Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/Xtensa/XtensaFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ def FeatureDensity : SubtargetFeature<"density", "HasDensity", "true",
def HasDensity : Predicate<"Subtarget->hasDensity()">,
AssemblerPredicate<(all_of FeatureDensity)>;

def FeatureSingleFloat : SubtargetFeature<"fp", "HasSingleFloat", "true",
"Enable Xtensa Single FP instructions">;
def HasSingleFloat : Predicate<"Subtarget->hasSingleFloat()">,
AssemblerPredicate<(all_of FeatureSingleFloat)>;

def FeatureWindowed : SubtargetFeature<"windowed", "HasWindowed", "true",
"Enable Xtensa Windowed Register option">;
def HasWindowed : Predicate<"Subtarget->hasWindowed()">,
Expand Down
Loading