Skip to content

Commit 68f73c1

Browse files
committed
[RISCV][MC] Use a custom ParserMethod for the bare_symbol operand type
This allows the hard-coded shouldForceImmediate logic to be removed because the generated MatchOperandParserImpl makes use of the current context (i.e. the current mnemonic) to determine parsing behaviour, and so won't first try to parse a register before parsing a symbol name. No functional change is intended. gas accepts immediate arguments for call, tail and lla. This patch doesn't address this discrepancy. Differential Revision: https://reviews.llvm.org/D51733 llvm-svn: 342488
1 parent 7d0e18d commit 68f73c1

File tree

2 files changed

+36
-33
lines changed

2 files changed

+36
-33
lines changed

llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,9 @@ class RISCVAsmParser : public MCTargetAsmParser {
9191
bool AllowParens = false);
9292
OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
9393
OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
94+
OperandMatchResultTy parseBareSymbol(OperandVector &Operands);
9495

95-
bool parseOperand(OperandVector &Operands, bool ForceImmediate);
96+
bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
9697

9798
bool parseDirectiveOption();
9899

@@ -966,6 +967,24 @@ RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
966967
return MatchOperand_Success;
967968
}
968969

970+
OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
971+
SMLoc S = getLoc();
972+
SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
973+
const MCExpr *Res;
974+
975+
if (getLexer().getKind() != AsmToken::Identifier)
976+
return MatchOperand_NoMatch;
977+
978+
StringRef Identifier;
979+
if (getParser().parseIdentifier(Identifier))
980+
return MatchOperand_ParseFail;
981+
982+
MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
983+
Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
984+
Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
985+
return MatchOperand_Success;
986+
}
987+
969988
OperandMatchResultTy
970989
RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
971990
if (getLexer().isNot(AsmToken::LParen)) {
@@ -994,13 +1013,19 @@ RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
9941013

9951014
/// Looks at a token type and creates the relevant operand from this
9961015
/// information, adding to Operands. If operand was parsed, returns false, else
997-
/// true. If ForceImmediate is true, no attempt will be made to parse the
998-
/// operand as a register, which is needed for pseudoinstructions such as
999-
/// call.
1000-
bool RISCVAsmParser::parseOperand(OperandVector &Operands,
1001-
bool ForceImmediate) {
1002-
// Attempt to parse token as register, unless ForceImmediate.
1003-
if (!ForceImmediate && parseRegister(Operands, true) == MatchOperand_Success)
1016+
/// true.
1017+
bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1018+
// Check if the current operand has a custom associated parser, if so, try to
1019+
// custom parse the operand, or fallback to the general approach.
1020+
OperandMatchResultTy Result =
1021+
MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
1022+
if (Result == MatchOperand_Success)
1023+
return false;
1024+
if (Result == MatchOperand_ParseFail)
1025+
return true;
1026+
1027+
// Attempt to parse token as a register.
1028+
if (parseRegister(Operands, true) == MatchOperand_Success)
10041029
return false;
10051030

10061031
// Attempt to parse token as an immediate
@@ -1016,26 +1041,6 @@ bool RISCVAsmParser::parseOperand(OperandVector &Operands,
10161041
return true;
10171042
}
10181043

1019-
/// Return true if the operand at the OperandIdx for opcode Name should be
1020-
/// 'forced' to be parsed as an immediate. This is required for
1021-
/// pseudoinstructions such as tail or call, which allow bare symbols to be used
1022-
/// that could clash with register names.
1023-
static bool shouldForceImediateOperand(StringRef Name, unsigned OperandIdx) {
1024-
// FIXME: This may not scale so perhaps we want to use a data-driven approach
1025-
// instead.
1026-
switch (OperandIdx) {
1027-
case 0:
1028-
// call imm
1029-
// tail imm
1030-
return Name == "tail" || Name == "call";
1031-
case 1:
1032-
// lla rdest, imm
1033-
return Name == "lla";
1034-
default:
1035-
return false;
1036-
}
1037-
}
1038-
10391044
bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
10401045
StringRef Name, SMLoc NameLoc,
10411046
OperandVector &Operands) {
@@ -1047,7 +1052,7 @@ bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
10471052
return false;
10481053

10491054
// Parse first operand
1050-
if (parseOperand(Operands, shouldForceImediateOperand(Name, 0)))
1055+
if (parseOperand(Operands, Name))
10511056
return true;
10521057

10531058
// Parse until end of statement, consuming commas between operands
@@ -1057,7 +1062,7 @@ bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
10571062
getLexer().Lex();
10581063

10591064
// Parse next operand
1060-
if (parseOperand(Operands, shouldForceImediateOperand(Name, OperandIdx)))
1065+
if (parseOperand(Operands, Name))
10611066
return true;
10621067

10631068
++OperandIdx;

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,12 @@ def BareSymbol : AsmOperandClass {
178178
let Name = "BareSymbol";
179179
let RenderMethod = "addImmOperands";
180180
let DiagnosticType = "InvalidBareSymbol";
181+
let ParserMethod = "parseBareSymbol";
181182
}
182183

183184
// A bare symbol.
184185
def bare_symbol : Operand<XLenVT> {
185186
let ParserMatchClass = BareSymbol;
186-
let MCOperandPredicate = [{
187-
return MCOp.isBareSymbolRef();
188-
}];
189187
}
190188

191189
// A parameterized register class alternative to i32imm/i64imm from Target.td.

0 commit comments

Comments
 (0)