Skip to content

Commit 4154ada

Browse files
authored
[Xtensa] Implement Xtensa Floating Point Option. (#136086)
Implement Xtensa FP Option instructions and lowering of the base FP operations with tests. Implement UR registers parsing. Fix loading from constant pool callee, basic block, globaladdress and jumptable addresses. Also fixed potential memory leakage when several similar XtensaConstantPoolValue objects are created Fix lowering i32 immediate.
1 parent 8f01edf commit 4154ada

26 files changed

+2204
-241
lines changed

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

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ using namespace llvm;
3535
struct XtensaOperand;
3636

3737
class XtensaAsmParser : public MCTargetAsmParser {
38+
const MCRegisterInfo &MRI;
3839

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

4143
XtensaTargetStreamer &getTargetStreamer() {
@@ -64,11 +66,12 @@ class XtensaAsmParser : public MCTargetAsmParser {
6466
ParseStatus parseImmediate(OperandVector &Operands);
6567
ParseStatus
6668
parseRegister(OperandVector &Operands, bool AllowParens = false,
67-
bool SR = false,
69+
XtensaRegisterType SR = Xtensa_Generic,
6870
Xtensa::RegisterAccessType RAType = Xtensa::REGISTER_EXCHANGE);
6971
ParseStatus parseOperandWithModifier(OperandVector &Operands);
7072
bool
71-
parseOperand(OperandVector &Operands, StringRef Mnemonic, bool SR = false,
73+
parseOperand(OperandVector &Operands, StringRef Mnemonic,
74+
XtensaRegisterType SR = Xtensa_Generic,
7275
Xtensa::RegisterAccessType RAType = Xtensa::REGISTER_EXCHANGE);
7376
bool ParseInstructionWithSR(ParseInstructionInfo &Info, StringRef Name,
7477
SMLoc NameLoc, OperandVector &Operands);
@@ -90,7 +93,8 @@ class XtensaAsmParser : public MCTargetAsmParser {
9093

9194
XtensaAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
9295
const MCInstrInfo &MII, const MCTargetOptions &Options)
93-
: MCTargetAsmParser(Options, STI, MII) {
96+
: MCTargetAsmParser(Options, STI, MII),
97+
MRI(*Parser.getContext().getRegisterInfo()) {
9498
setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
9599
}
96100

@@ -583,7 +587,8 @@ bool XtensaAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
583587
}
584588

585589
ParseStatus XtensaAsmParser::parseRegister(OperandVector &Operands,
586-
bool AllowParens, bool SR,
590+
bool AllowParens,
591+
XtensaRegisterType RegType,
587592
Xtensa::RegisterAccessType RAType) {
588593
SMLoc FirstS = getLoc();
589594
bool HadParens = false;
@@ -594,25 +599,32 @@ ParseStatus XtensaAsmParser::parseRegister(OperandVector &Operands,
594599
if (AllowParens && getLexer().is(AsmToken::LParen)) {
595600
size_t ReadCount = getLexer().peekTokens(Buf);
596601
if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
597-
if ((Buf[0].getKind() == AsmToken::Integer) && (!SR))
602+
if (Buf[0].getKind() == AsmToken::Integer && RegType == Xtensa_Generic)
598603
return ParseStatus::NoMatch;
599604
HadParens = true;
600605
getParser().Lex(); // Eat '('
601606
}
602607
}
603608

604-
unsigned RegNo = 0;
609+
MCRegister RegNo = 0;
605610

606611
switch (getLexer().getKind()) {
607612
default:
608613
return ParseStatus::NoMatch;
609614
case AsmToken::Integer:
610-
if (!SR)
615+
if (RegType == Xtensa_Generic)
611616
return ParseStatus::NoMatch;
612-
RegName = getLexer().getTok().getString();
613-
RegNo = MatchRegisterName(RegName);
614-
if (RegNo == 0)
617+
618+
// Parse case when we expect UR register code as special case,
619+
// because SR and UR registers may have the same number
620+
// and such situation may lead to confilct
621+
if (RegType == Xtensa_UR) {
622+
int64_t RegCode = getLexer().getTok().getIntVal();
623+
RegNo = Xtensa::getUserRegister(RegCode, MRI);
624+
} else {
625+
RegName = getLexer().getTok().getString();
615626
RegNo = MatchRegisterAltName(RegName);
627+
}
616628
break;
617629
case AsmToken::Identifier:
618630
RegName = getLexer().getTok().getIdentifier();
@@ -689,7 +701,8 @@ ParseStatus XtensaAsmParser::parseOperandWithModifier(OperandVector &Operands) {
689701
/// from this information, adding to Operands.
690702
/// If operand was parsed, returns false, else true.
691703
bool XtensaAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic,
692-
bool SR, Xtensa::RegisterAccessType RAType) {
704+
XtensaRegisterType RegType,
705+
Xtensa::RegisterAccessType RAType) {
693706
// Check if the current operand has a custom associated parser, if so, try to
694707
// custom parse the operand, or fallback to the general approach.
695708
ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);
@@ -703,7 +716,7 @@ bool XtensaAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic,
703716
return true;
704717

705718
// Attempt to parse token as register
706-
if (parseRegister(Operands, true, SR, RAType).isSuccess())
719+
if (parseRegister(Operands, true, RegType, RAType).isSuccess())
707720
return false;
708721

709722
// Attempt to parse token as an immediate
@@ -722,11 +735,9 @@ bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
722735
: (Name[0] == 'r' ? Xtensa::REGISTER_READ
723736
: Xtensa::REGISTER_EXCHANGE);
724737

725-
if ((Name.starts_with("wsr.") || Name.starts_with("rsr.") ||
726-
Name.starts_with("xsr.")) &&
727-
(Name.size() > 4)) {
728-
// Parse case when instruction name is concatenated with SR register
729-
// name, like "wsr.sar a1"
738+
if ((Name.size() > 4) && Name[3] == '.') {
739+
// Parse case when instruction name is concatenated with SR/UR register
740+
// name, like "wsr.sar a1" or "wur.fcr a1"
730741

731742
// First operand is token for instruction
732743
Operands.push_back(XtensaOperand::createToken(Name.take_front(3), NameLoc));
@@ -762,7 +773,8 @@ bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
762773
}
763774

764775
// Parse second operand
765-
if (parseOperand(Operands, Name, true, RAType))
776+
if (parseOperand(Operands, Name, Name[1] == 's' ? Xtensa_SR : Xtensa_UR,
777+
RAType))
766778
return true;
767779
}
768780

@@ -780,7 +792,8 @@ bool XtensaAsmParser::parseInstruction(ParseInstructionInfo &Info,
780792
StringRef Name, SMLoc NameLoc,
781793
OperandVector &Operands) {
782794
if (Name.starts_with("wsr") || Name.starts_with("rsr") ||
783-
Name.starts_with("xsr")) {
795+
Name.starts_with("xsr") || Name.starts_with("rur") ||
796+
Name.starts_with("wur")) {
784797
return ParseInstructionWithSR(Info, Name, NameLoc, Operands);
785798
}
786799

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

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

76-
static const MCPhysReg MRDecoderTable[] = {Xtensa::M0, Xtensa::M1, Xtensa::M2,
77-
Xtensa::M3};
78-
7976
static DecodeStatus DecodeMRRegisterClass(MCInst &Inst, uint64_t RegNo,
8077
uint64_t Address,
8178
const void *Decoder) {
82-
if (RegNo >= std::size(MRDecoderTable))
79+
if (RegNo > 3)
8380
return MCDisassembler::Fail;
8481

85-
MCPhysReg Reg = MRDecoderTable[RegNo];
82+
MCPhysReg Reg = Xtensa::M0 + RegNo;
8683
Inst.addOperand(MCOperand::createReg(Reg));
8784
return MCDisassembler::Success;
8885
}
8986

90-
static const MCPhysReg MR01DecoderTable[] = {Xtensa::M0, Xtensa::M1};
91-
9287
static DecodeStatus DecodeMR01RegisterClass(MCInst &Inst, uint64_t RegNo,
9388
uint64_t Address,
9489
const void *Decoder) {
95-
if (RegNo > 2)
90+
if (RegNo > 1)
9691
return MCDisassembler::Fail;
9792

98-
MCPhysReg Reg = MR01DecoderTable[RegNo];
93+
MCPhysReg Reg = Xtensa::M0 + RegNo;
9994
Inst.addOperand(MCOperand::createReg(Reg));
10095
return MCDisassembler::Success;
10196
}
10297

103-
static const MCPhysReg MR23DecoderTable[] = {Xtensa::M2, Xtensa::M3};
104-
10598
static DecodeStatus DecodeMR23RegisterClass(MCInst &Inst, uint64_t RegNo,
10699
uint64_t Address,
107100
const void *Decoder) {
108-
if (RegNo != 0 && RegNo != 1)
101+
if (RegNo > 1)
102+
return MCDisassembler::Fail;
103+
104+
MCPhysReg Reg = Xtensa::M2 + RegNo;
105+
Inst.addOperand(MCOperand::createReg(Reg));
106+
return MCDisassembler::Success;
107+
}
108+
109+
static DecodeStatus DecodeFPRRegisterClass(MCInst &Inst, uint64_t RegNo,
110+
uint64_t Address,
111+
const void *Decoder) {
112+
if (RegNo > 15)
113+
return MCDisassembler::Fail;
114+
115+
MCPhysReg Reg = Xtensa::F0 + RegNo;
116+
Inst.addOperand(MCOperand::createReg(Reg));
117+
return MCDisassembler::Success;
118+
}
119+
120+
static DecodeStatus DecodeURRegisterClass(MCInst &Inst, uint64_t RegNo,
121+
uint64_t Address,
122+
const MCDisassembler *Decoder) {
123+
if (RegNo > 255)
124+
return MCDisassembler::Fail;
125+
126+
Xtensa::RegisterAccessType RAType = Inst.getOpcode() == Xtensa::WUR
127+
? Xtensa::REGISTER_WRITE
128+
: Xtensa::REGISTER_READ;
129+
130+
const XtensaDisassembler *Dis =
131+
static_cast<const XtensaDisassembler *>(Decoder);
132+
const MCRegisterInfo *MRI = Dis->getContext().getRegisterInfo();
133+
MCPhysReg Reg = Xtensa::getUserRegister(RegNo, *MRI);
134+
if (!Xtensa::checkRegister(Reg, Decoder->getSubtargetInfo().getFeatureBits(),
135+
RAType))
109136
return MCDisassembler::Fail;
110137

111-
MCPhysReg Reg = MR23DecoderTable[RegNo];
112138
Inst.addOperand(MCOperand::createReg(Reg));
113139
return MCDisassembler::Success;
114140
}
@@ -187,18 +213,13 @@ static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
187213
return MCDisassembler::Fail;
188214
}
189215

190-
const MCPhysReg BRDecoderTable[] = {
191-
Xtensa::B0, Xtensa::B1, Xtensa::B2, Xtensa::B3, Xtensa::B4, Xtensa::B5,
192-
Xtensa::B6, Xtensa::B7, Xtensa::B8, Xtensa::B9, Xtensa::B10, Xtensa::B11,
193-
Xtensa::B12, Xtensa::B13, Xtensa::B14, Xtensa::B15};
194-
195216
static DecodeStatus DecodeBRRegisterClass(MCInst &Inst, uint64_t RegNo,
196217
uint64_t Address,
197218
const void *Decoder) {
198-
if (RegNo >= std::size(BRDecoderTable))
219+
if (RegNo > 15)
199220
return MCDisassembler::Fail;
200221

201-
MCPhysReg Reg = BRDecoderTable[RegNo];
222+
MCPhysReg Reg = Xtensa::B0 + RegNo;
202223
Inst.addOperand(MCOperand::createReg(Reg));
203224
return MCDisassembler::Success;
204225
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,11 @@ XtensaMCCodeEmitter::getMemRegEncoding(const MCInst &MI, unsigned OpNo,
307307
case Xtensa::L32I:
308308
case Xtensa::S32I_N:
309309
case Xtensa::L32I_N:
310+
case Xtensa::SSI:
311+
case Xtensa::SSIP:
312+
case Xtensa::LSI:
313+
case Xtensa::LSIP:
314+
310315
if (Res & 0x3) {
311316
report_fatal_error("Unexpected operand value!");
312317
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits,
188188
return RAType == Xtensa::REGISTER_READ && FeatureBits[Xtensa::FeaturePRID];
189189
case Xtensa::VECBASE:
190190
return FeatureBits[Xtensa::FeatureRelocatableVector];
191+
case Xtensa::FCR:
192+
case Xtensa::FSR:
193+
return FeatureBits[FeatureSingleFloat];
191194
case Xtensa::WINDOWBASE:
192195
case Xtensa::WINDOWSTART:
193196
return FeatureBits[Xtensa::FeatureWindowed];
@@ -198,6 +201,16 @@ bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits,
198201
return true;
199202
}
200203

204+
// Get Xtensa User Register by encoding value.
205+
MCRegister Xtensa::getUserRegister(unsigned Code, const MCRegisterInfo &MRI) {
206+
if (MRI.getEncodingValue(Xtensa::FCR) == Code) {
207+
return Xtensa::FCR;
208+
} else if (MRI.getEncodingValue(Xtensa::FSR) == Code) {
209+
return Xtensa::FSR;
210+
}
211+
return Xtensa::NoRegister;
212+
}
213+
201214
static MCAsmInfo *createXtensaMCAsmInfo(const MCRegisterInfo &MRI,
202215
const Triple &TT,
203216
const MCTargetOptions &Options) {

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ enum RegisterAccessType {
6464
// Verify if it's correct to use a special register.
6565
bool checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits,
6666
RegisterAccessType RA);
67+
68+
// Get Xtensa User Register by register encoding value.
69+
MCRegister getUserRegister(unsigned Code, const MCRegisterInfo &MRI);
6770
} // namespace Xtensa
6871
} // end namespace llvm
6972

llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,25 @@ void XtensaAsmPrinter::emitInstruction(const MachineInstr *MI) {
6262

6363
void XtensaAsmPrinter::emitMachineConstantPoolValue(
6464
MachineConstantPoolValue *MCPV) {
65-
XtensaConstantPoolValue *ACPV = static_cast<XtensaConstantPoolValue *>(MCPV);
65+
XtensaConstantPoolValue *XtensaCPV =
66+
static_cast<XtensaConstantPoolValue *>(MCPV);
6667
MCSymbol *MCSym;
6768

68-
if (ACPV->isBlockAddress()) {
69+
if (XtensaCPV->isBlockAddress()) {
6970
const BlockAddress *BA =
70-
cast<XtensaConstantPoolConstant>(ACPV)->getBlockAddress();
71+
cast<XtensaConstantPoolConstant>(XtensaCPV)->getBlockAddress();
7172
MCSym = GetBlockAddressSymbol(BA);
72-
} else if (ACPV->isMachineBasicBlock()) {
73-
const MachineBasicBlock *MBB = cast<XtensaConstantPoolMBB>(ACPV)->getMBB();
73+
} else if (XtensaCPV->isMachineBasicBlock()) {
74+
const MachineBasicBlock *MBB =
75+
cast<XtensaConstantPoolMBB>(XtensaCPV)->getMBB();
7476
MCSym = MBB->getSymbol();
75-
} else if (ACPV->isJumpTable()) {
76-
unsigned Idx = cast<XtensaConstantPoolJumpTable>(ACPV)->getIndex();
77+
} else if (XtensaCPV->isJumpTable()) {
78+
unsigned Idx = cast<XtensaConstantPoolJumpTable>(XtensaCPV)->getIndex();
7779
MCSym = this->GetJTISymbol(Idx, false);
7880
} else {
79-
assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
80-
XtensaConstantPoolSymbol *XtensaSym = cast<XtensaConstantPoolSymbol>(ACPV);
81+
assert(XtensaCPV->isExtSymbol() && "unrecognized constant pool value");
82+
XtensaConstantPoolSymbol *XtensaSym =
83+
cast<XtensaConstantPoolSymbol>(XtensaCPV);
8184
const char *SymName = XtensaSym->getSymbol();
8285

8386
if (XtensaSym->isPrivateLinkage()) {
@@ -89,14 +92,14 @@ void XtensaAsmPrinter::emitMachineConstantPoolValue(
8992
}
9093
}
9194

92-
MCSymbol *LblSym = GetCPISymbol(ACPV->getLabelId());
95+
MCSymbol *LblSym = GetCPISymbol(XtensaCPV->getLabelId());
9396
auto *TS =
9497
static_cast<XtensaTargetStreamer *>(OutStreamer->getTargetStreamer());
95-
auto Spec = getModifierSpecifier(ACPV->getModifier());
98+
auto Spec = getModifierSpecifier(XtensaCPV->getModifier());
9699

97-
if (ACPV->getModifier() != XtensaCP::no_modifier) {
100+
if (XtensaCPV->getModifier() != XtensaCP::no_modifier) {
98101
std::string SymName(MCSym->getName());
99-
StringRef Modifier = ACPV->getModifierText();
102+
StringRef Modifier = XtensaCPV->getModifierText();
100103
SymName += Modifier;
101104
MCSym = OutContext.getOrCreateSymbol(SymName);
102105
}
@@ -108,9 +111,9 @@ void XtensaAsmPrinter::emitMachineConstantPoolValue(
108111
void XtensaAsmPrinter::emitMachineConstantPoolEntry(
109112
const MachineConstantPoolEntry &CPE, int i) {
110113
if (CPE.isMachineConstantPoolEntry()) {
111-
XtensaConstantPoolValue *ACPV =
114+
XtensaConstantPoolValue *XtensaCPV =
112115
static_cast<XtensaConstantPoolValue *>(CPE.Val.MachineCPVal);
113-
ACPV->setLabelId(i);
116+
XtensaCPV->setLabelId(i);
114117
emitMachineConstantPoolValue(CPE.Val.MachineCPVal);
115118
} else {
116119
MCSymbol *LblSym = GetCPISymbol(i);

llvm/lib/Target/Xtensa/XtensaCallingConv.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
def RetCC_Xtensa : CallingConv<[
1616
// First two return values go in a2, a3, a4, a5
1717
CCIfType<[i32], CCAssignToReg<[A2, A3, A4, A5]>>,
18+
CCIfType<[f32], CCAssignToReg<[A2, A3, A4, A5]>>,
1819
CCIfType<[i64], CCAssignToRegWithShadow<[A2, A4], [A3, A5]>>
1920
]>;
2021

llvm/lib/Target/Xtensa/XtensaFeatures.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ def FeatureDensity : SubtargetFeature<"density", "HasDensity", "true",
88
def HasDensity : Predicate<"Subtarget->hasDensity()">,
99
AssemblerPredicate<(all_of FeatureDensity)>;
1010

11+
def FeatureSingleFloat : SubtargetFeature<"fp", "HasSingleFloat", "true",
12+
"Enable Xtensa Single FP instructions">;
13+
def HasSingleFloat : Predicate<"Subtarget->hasSingleFloat()">,
14+
AssemblerPredicate<(all_of FeatureSingleFloat)>;
15+
1116
def FeatureWindowed : SubtargetFeature<"windowed", "HasWindowed", "true",
1217
"Enable Xtensa Windowed Register option">;
1318
def HasWindowed : Predicate<"Subtarget->hasWindowed()">,

0 commit comments

Comments
 (0)