[AMDGPU][MC] Parser cleanup and refactoring

Reviewers: artem.tamazov, arsenm

Differential Revision: https://reviews.llvm.org/D60767

llvm-svn: 359096
This commit is contained in:
Dmitry Preobrazhensky 2019-04-24 14:06:15 +00:00
parent b1b3368907
commit 47621d7c89
1 changed files with 48 additions and 93 deletions

View File

@ -178,6 +178,7 @@ public:
ImmTyHigh
};
private:
struct TokOp {
const char *Data;
unsigned Length;
@ -192,7 +193,6 @@ public:
struct RegOp {
unsigned RegNo;
bool IsForcedVOP3;
Modifiers Mods;
};
@ -203,6 +203,7 @@ public:
const MCExpr *Expr;
};
public:
bool isToken() const override {
if (Kind == Token)
return true;
@ -548,6 +549,7 @@ public:
}
unsigned getReg() const override {
assert(isRegKind());
return Reg.RegNo;
}
@ -764,12 +766,10 @@ public:
static AMDGPUOperand::Ptr CreateReg(const AMDGPUAsmParser *AsmParser,
unsigned RegNo, SMLoc S,
SMLoc E,
bool ForceVOP3) {
SMLoc E) {
auto Op = llvm::make_unique<AMDGPUOperand>(Register, AsmParser);
Op->Reg.RegNo = RegNo;
Op->Reg.Mods = Modifiers();
Op->Reg.IsForcedVOP3 = ForceVOP3;
Op->StartLoc = S;
Op->EndLoc = E;
return Op;
@ -1083,7 +1083,7 @@ public:
bool parseSP3NegModifier();
OperandMatchResultTy parseImm(OperandVector &Operands, bool HasSP3AbsModifier = false);
OperandMatchResultTy parseReg(OperandVector &Operands);
OperandMatchResultTy parseRegOrImm(OperandVector &Operands, bool AbsMod = false);
OperandMatchResultTy parseRegOrImm(OperandVector &Operands, bool HasSP3AbsMod = false);
OperandMatchResultTy parseRegOrImmWithFPInputMods(OperandVector &Operands, bool AllowImm = true);
OperandMatchResultTy parseRegOrImmWithIntInputMods(OperandVector &Operands, bool AllowImm = true);
OperandMatchResultTy parseRegWithFPInputMods(OperandVector &Operands);
@ -2000,7 +2000,7 @@ std::unique_ptr<AMDGPUOperand> AMDGPUAsmParser::parseRegister() {
return nullptr;
} else
KernelScope.usesRegister(RegKind, DwordRegIndex, RegWidth);
return AMDGPUOperand::CreateReg(this, Reg, StartLoc, EndLoc, false);
return AMDGPUOperand::CreateReg(this, Reg, StartLoc, EndLoc);
}
bool
@ -2091,7 +2091,6 @@ AMDGPUAsmParser::parseReg(OperandVector &Operands) {
if (auto R = parseRegister()) {
assert(R->isReg());
R->Reg.IsForcedVOP3 = isForcedVOP3();
Operands.push_back(std::move(R));
return MatchOperand_Success;
}
@ -2099,10 +2098,10 @@ AMDGPUAsmParser::parseReg(OperandVector &Operands) {
}
OperandMatchResultTy
AMDGPUAsmParser::parseRegOrImm(OperandVector &Operands, bool AbsMod) {
AMDGPUAsmParser::parseRegOrImm(OperandVector &Operands, bool HasSP3AbsMod) {
auto res = parseReg(Operands);
return (res == MatchOperand_NoMatch)?
parseImm(Operands, AbsMod) :
parseImm(Operands, HasSP3AbsMod) :
res;
}
@ -2148,7 +2147,9 @@ AMDGPUAsmParser::parseSP3NegModifier() {
OperandMatchResultTy
AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
bool AllowImm) {
bool Negate, Negate2 = false, Abs = false, Abs2 = false;
bool Neg, SP3Neg;
bool Abs, SP3Abs;
SMLoc Loc;
// Disable ambiguous constructs like '--1' etc. Should use neg(-1) instead.
if (isToken(AsmToken::Minus) && peekToken().is(AsmToken::Minus)) {
@ -2156,81 +2157,48 @@ AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
return MatchOperand_ParseFail;
}
Negate = parseSP3NegModifier();
SP3Neg = parseSP3NegModifier();
if (getLexer().getKind() == AsmToken::Identifier &&
Parser.getTok().getString() == "neg") {
if (Negate) {
Error(Parser.getTok().getLoc(), "expected register or immediate");
return MatchOperand_ParseFail;
}
Parser.Lex();
Negate2 = true;
if (getLexer().isNot(AsmToken::LParen)) {
Error(Parser.getTok().getLoc(), "expected left paren after neg");
return MatchOperand_ParseFail;
}
Parser.Lex();
Loc = getLoc();
Neg = trySkipId("neg");
if (Neg && SP3Neg) {
Error(Loc, "expected register or immediate");
return MatchOperand_ParseFail;
}
if (Neg && !skipToken(AsmToken::LParen, "expected left paren after neg"))
return MatchOperand_ParseFail;
if (getLexer().getKind() == AsmToken::Identifier &&
Parser.getTok().getString() == "abs") {
Parser.Lex();
Abs2 = true;
if (getLexer().isNot(AsmToken::LParen)) {
Error(Parser.getTok().getLoc(), "expected left paren after abs");
return MatchOperand_ParseFail;
}
Parser.Lex();
}
Abs = trySkipId("abs");
if (Abs && !skipToken(AsmToken::LParen, "expected left paren after abs"))
return MatchOperand_ParseFail;
if (getLexer().getKind() == AsmToken::Pipe) {
if (Abs2) {
Error(Parser.getTok().getLoc(), "expected register or immediate");
return MatchOperand_ParseFail;
}
Parser.Lex();
Abs = true;
Loc = getLoc();
SP3Abs = trySkipToken(AsmToken::Pipe);
if (Abs && SP3Abs) {
Error(Loc, "expected register or immediate");
return MatchOperand_ParseFail;
}
OperandMatchResultTy Res;
if (AllowImm) {
Res = parseRegOrImm(Operands, Abs);
Res = parseRegOrImm(Operands, SP3Abs);
} else {
Res = parseReg(Operands);
}
if (Res != MatchOperand_Success) {
return (Negate || Negate2 || Abs || Abs2)? MatchOperand_ParseFail : Res;
return (SP3Neg || Neg || SP3Abs || Abs)? MatchOperand_ParseFail : Res;
}
if (SP3Abs && !skipToken(AsmToken::Pipe, "expected vertical bar"))
return MatchOperand_ParseFail;
if (Abs && !skipToken(AsmToken::RParen, "expected closing parentheses"))
return MatchOperand_ParseFail;
if (Neg && !skipToken(AsmToken::RParen, "expected closing parentheses"))
return MatchOperand_ParseFail;
AMDGPUOperand::Modifiers Mods;
if (Abs) {
if (getLexer().getKind() != AsmToken::Pipe) {
Error(Parser.getTok().getLoc(), "expected vertical bar");
return MatchOperand_ParseFail;
}
Parser.Lex();
Mods.Abs = true;
}
if (Abs2) {
if (getLexer().isNot(AsmToken::RParen)) {
Error(Parser.getTok().getLoc(), "expected closing parentheses");
return MatchOperand_ParseFail;
}
Parser.Lex();
Mods.Abs = true;
}
if (Negate) {
Mods.Neg = true;
} else if (Negate2) {
if (getLexer().isNot(AsmToken::RParen)) {
Error(Parser.getTok().getLoc(), "expected closing parentheses");
return MatchOperand_ParseFail;
}
Parser.Lex();
Mods.Neg = true;
}
Mods.Abs = Abs || SP3Abs;
Mods.Neg = Neg || SP3Neg;
if (Mods.hasFPModifiers()) {
AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands.back());
@ -2242,18 +2210,9 @@ AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
OperandMatchResultTy
AMDGPUAsmParser::parseRegOrImmWithIntInputMods(OperandVector &Operands,
bool AllowImm) {
bool Sext = false;
if (getLexer().getKind() == AsmToken::Identifier &&
Parser.getTok().getString() == "sext") {
Parser.Lex();
Sext = true;
if (getLexer().isNot(AsmToken::LParen)) {
Error(Parser.getTok().getLoc(), "expected left paren after sext");
return MatchOperand_ParseFail;
}
Parser.Lex();
}
bool Sext = trySkipId("sext");
if (Sext && !skipToken(AsmToken::LParen, "expected left paren after sext"))
return MatchOperand_ParseFail;
OperandMatchResultTy Res;
if (AllowImm) {
@ -2265,15 +2224,11 @@ AMDGPUAsmParser::parseRegOrImmWithIntInputMods(OperandVector &Operands,
return Sext? MatchOperand_ParseFail : Res;
}
if (Sext && !skipToken(AsmToken::RParen, "expected closing parentheses"))
return MatchOperand_ParseFail;
AMDGPUOperand::Modifiers Mods;
if (Sext) {
if (getLexer().isNot(AsmToken::RParen)) {
Error(Parser.getTok().getLoc(), "expected closing parentheses");
return MatchOperand_ParseFail;
}
Parser.Lex();
Mods.Sext = true;
}
Mods.Sext = Sext;
if (Mods.hasIntModifiers()) {
AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands.back());
@ -5462,7 +5417,7 @@ void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst, const OperandVector &Operands)
} else if (Op.isInterpSlot() ||
Op.isInterpAttr() ||
Op.isAttrChan()) {
Inst.addOperand(MCOperand::createImm(Op.Imm.Val));
Inst.addOperand(MCOperand::createImm(Op.getImm()));
} else if (Op.isImmModifier()) {
OptionalIdx[Op.getImmTy()] = I;
} else {
@ -5801,7 +5756,7 @@ void AMDGPUAsmParser::cvtDPP(MCInst &Inst, const OperandVector &Operands) {
}
AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
// Add the register arguments
if (Op.isReg() && Op.Reg.RegNo == AMDGPU::VCC) {
if (Op.isReg() && Op.getReg() == AMDGPU::VCC) {
// VOP2b (v_add_u32, v_sub_u32 ...) dpp use "vcc" token.
// Skip it.
continue;
@ -5920,7 +5875,7 @@ void AMDGPUAsmParser::cvtSDWA(MCInst &Inst, const OperandVector &Operands,
for (unsigned E = Operands.size(); I != E; ++I) {
AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
if (skipVcc && !skippedVcc && Op.isReg() && Op.Reg.RegNo == AMDGPU::VCC) {
if (skipVcc && !skippedVcc && Op.isReg() && Op.getReg() == AMDGPU::VCC) {
// VOP2b (v_add_u32, v_sub_u32 ...) sdwa use "vcc" token as dst.
// Skip it if it's 2nd (e.g. v_add_i32_sdwa v1, vcc, v2, v3)
// or 4th (v_addc_u32_sdwa v1, vcc, v2, v3, vcc) operand.