1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[AMDGPU][MC] Refactored parsing of dpp ctrl

Summary of changes:
- simplified code to improve maintainability;
- replaced lex() with higher level parser functions;
- improved errors handling.

Reviewers: rampitec

Differential Revision: https://reviews.llvm.org/D94777
This commit is contained in:
Dmitry Preobrazhensky 2021-01-18 15:16:46 +03:00
parent 7d7c35ebbc
commit 3788b3b798
3 changed files with 179 additions and 103 deletions

View File

@ -1485,6 +1485,9 @@ public:
OperandMatchResultTy parseDim(OperandVector &Operands);
OperandMatchResultTy parseDPP8(OperandVector &Operands);
OperandMatchResultTy parseDPPCtrl(OperandVector &Operands);
bool isSupportedDPPCtrl(StringRef Ctrl, const OperandVector &Operands);
int64_t parseDPPCtrlSel(StringRef Ctrl);
int64_t parseDPPCtrlPerm();
AMDGPUOperand::Ptr defaultRowMask() const;
AMDGPUOperand::Ptr defaultBankMask() const;
AMDGPUOperand::Ptr defaultBoundCtrl() const;
@ -4952,7 +4955,7 @@ bool AMDGPUAsmParser::ParseInstruction(ParseInstructionInfo &Info,
Error(getLoc(), Msg);
}
while (!trySkipToken(AsmToken::EndOfStatement)) {
Parser.Lex();
lex();
}
return true;
}
@ -7227,7 +7230,7 @@ OperandMatchResultTy AMDGPUAsmParser::parseDim(OperandVector &Operands) {
if (isToken(AsmToken::Integer)) {
SMLoc Loc = getToken().getEndLoc();
Token = std::string(getTokenStr());
Parser.Lex();
lex();
if (getLoc() != Loc)
return MatchOperand_ParseFail;
}
@ -7243,7 +7246,7 @@ OperandMatchResultTy AMDGPUAsmParser::parseDim(OperandVector &Operands) {
if (!DimInfo)
return MatchOperand_ParseFail;
Parser.Lex();
lex();
Operands.push_back(AMDGPUOperand::CreateImm(this, DimInfo->Encoding, S,
AMDGPUOperand::ImmTyDim));
@ -7287,116 +7290,138 @@ OperandMatchResultTy AMDGPUAsmParser::parseDPP8(OperandVector &Operands) {
return MatchOperand_Success;
}
bool
AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
const OperandVector &Operands) {
if (Ctrl == "row_share" ||
Ctrl == "row_xmask")
return isGFX10Plus();
if (Ctrl == "wave_shl" ||
Ctrl == "wave_shr" ||
Ctrl == "wave_rol" ||
Ctrl == "wave_ror" ||
Ctrl == "row_bcast")
return isVI() || isGFX9();
return Ctrl == "row_mirror" ||
Ctrl == "row_half_mirror" ||
Ctrl == "quad_perm" ||
Ctrl == "row_shl" ||
Ctrl == "row_shr" ||
Ctrl == "row_ror";
}
int64_t
AMDGPUAsmParser::parseDPPCtrlPerm() {
// quad_perm:[%d,%d,%d,%d]
if (!skipToken(AsmToken::LBrac, "expected an opening square bracket"))
return -1;
int64_t Val = 0;
for (int i = 0; i < 4; ++i) {
if (i > 0 && !skipToken(AsmToken::Comma, "expected a comma"))
return -1;
int64_t Temp;
SMLoc Loc = getLoc();
if (getParser().parseAbsoluteExpression(Temp))
return -1;
if (Temp < 0 || Temp > 3) {
Error(Loc, "expected a 2-bit value");
return -1;
}
Val += (Temp << i * 2);
}
if (!skipToken(AsmToken::RBrac, "expected a closing square bracket"))
return -1;
return Val;
}
int64_t
AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
using namespace AMDGPU::DPP;
// sel:%d
int64_t Val;
SMLoc Loc = getLoc();
if (getParser().parseAbsoluteExpression(Val))
return -1;
struct DppCtrlCheck {
int64_t Ctrl;
int Lo;
int Hi;
};
DppCtrlCheck Check = StringSwitch<DppCtrlCheck>(Ctrl)
.Case("wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
.Case("wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
.Case("wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
.Case("wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
.Case("row_shl", {DppCtrl::ROW_SHL0, 1, 15})
.Case("row_shr", {DppCtrl::ROW_SHR0, 1, 15})
.Case("row_ror", {DppCtrl::ROW_ROR0, 1, 15})
.Case("row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
.Case("row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
.Default({-1});
bool Valid;
if (Check.Ctrl == -1) {
Valid = (Ctrl == "row_bcast" && (Val == 15 || Val == 31));
Val = (Val == 15)? DppCtrl::BCAST15 : DppCtrl::BCAST31;
} else {
Valid = Check.Lo <= Val && Val <= Check.Hi;
Val = (Check.Lo == Check.Hi) ? Check.Ctrl : (Check.Ctrl | Val);
}
if (!Valid) {
Error(Loc, Twine("invalid ", Ctrl) + Twine(" value"));
return -1;
}
return Val;
}
OperandMatchResultTy
AMDGPUAsmParser::parseDPPCtrl(OperandVector &Operands) {
using namespace AMDGPU::DPP;
SMLoc S = getLoc();
StringRef Prefix;
int64_t Int;
if (isToken(AsmToken::Identifier)) {
Prefix = getTokenStr();
} else {
if (!isToken(AsmToken::Identifier) ||
!isSupportedDPPCtrl(getTokenStr(), Operands))
return MatchOperand_NoMatch;
}
if (Prefix == "row_mirror") {
Int = DppCtrl::ROW_MIRROR;
Parser.Lex();
} else if (Prefix == "row_half_mirror") {
Int = DppCtrl::ROW_HALF_MIRROR;
Parser.Lex();
SMLoc S = getLoc();
int64_t Val = -1;
StringRef Ctrl;
parseId(Ctrl);
if (Ctrl == "row_mirror") {
Val = DppCtrl::ROW_MIRROR;
} else if (Ctrl == "row_half_mirror") {
Val = DppCtrl::ROW_HALF_MIRROR;
} else {
// Check to prevent parseDPPCtrlOps from eating invalid tokens
if (Prefix != "quad_perm"
&& Prefix != "row_shl"
&& Prefix != "row_shr"
&& Prefix != "row_ror"
&& Prefix != "wave_shl"
&& Prefix != "wave_rol"
&& Prefix != "wave_shr"
&& Prefix != "wave_ror"
&& Prefix != "row_bcast"
&& Prefix != "row_share"
&& Prefix != "row_xmask") {
return MatchOperand_NoMatch;
}
if (!isGFX10Plus() && (Prefix == "row_share" || Prefix == "row_xmask"))
return MatchOperand_NoMatch;
if (!isVI() && !isGFX9() &&
(Prefix == "wave_shl" || Prefix == "wave_shr" ||
Prefix == "wave_rol" || Prefix == "wave_ror" ||
Prefix == "row_bcast"))
return MatchOperand_NoMatch;
Parser.Lex();
if (!isToken(AsmToken::Colon))
return MatchOperand_ParseFail;
if (Prefix == "quad_perm") {
// quad_perm:[%d,%d,%d,%d]
Parser.Lex();
if (!trySkipToken(AsmToken::LBrac))
return MatchOperand_ParseFail;
if (getParser().parseAbsoluteExpression(Int) || !(0 <= Int && Int <=3))
return MatchOperand_ParseFail;
for (int i = 0; i < 3; ++i) {
if (!trySkipToken(AsmToken::Comma))
return MatchOperand_ParseFail;
int64_t Temp;
if (getParser().parseAbsoluteExpression(Temp) || !(0 <= Temp && Temp <=3))
return MatchOperand_ParseFail;
const int shift = i*2 + 2;
Int += (Temp << shift);
}
if (!trySkipToken(AsmToken::RBrac))
return MatchOperand_ParseFail;
} else {
// sel:%d
Parser.Lex();
if (getParser().parseAbsoluteExpression(Int))
return MatchOperand_ParseFail;
if (Prefix == "row_shl" && 1 <= Int && Int <= 15) {
Int |= DppCtrl::ROW_SHL0;
} else if (Prefix == "row_shr" && 1 <= Int && Int <= 15) {
Int |= DppCtrl::ROW_SHR0;
} else if (Prefix == "row_ror" && 1 <= Int && Int <= 15) {
Int |= DppCtrl::ROW_ROR0;
} else if (Prefix == "wave_shl" && 1 == Int) {
Int = DppCtrl::WAVE_SHL1;
} else if (Prefix == "wave_rol" && 1 == Int) {
Int = DppCtrl::WAVE_ROL1;
} else if (Prefix == "wave_shr" && 1 == Int) {
Int = DppCtrl::WAVE_SHR1;
} else if (Prefix == "wave_ror" && 1 == Int) {
Int = DppCtrl::WAVE_ROR1;
} else if (Prefix == "row_bcast") {
if (Int == 15) {
Int = DppCtrl::BCAST15;
} else if (Int == 31) {
Int = DppCtrl::BCAST31;
} else {
return MatchOperand_ParseFail;
}
} else if (Prefix == "row_share" && 0 <= Int && Int <= 15) {
Int |= DppCtrl::ROW_SHARE_FIRST;
} else if (Prefix == "row_xmask" && 0 <= Int && Int <= 15) {
Int |= DppCtrl::ROW_XMASK_FIRST;
if (skipToken(AsmToken::Colon, "expected a colon")) {
if (Ctrl == "quad_perm") {
Val = parseDPPCtrlPerm();
} else {
return MatchOperand_ParseFail;
Val = parseDPPCtrlSel(Ctrl);
}
}
}
Operands.push_back(AMDGPUOperand::CreateImm(this, Int, S, AMDGPUOperand::ImmTyDppCtrl));
if (Val == -1)
return MatchOperand_ParseFail;
Operands.push_back(
AMDGPUOperand::CreateImm(this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
return MatchOperand_Success;
}

View File

@ -115,6 +115,19 @@ s_atomic_swap s5, s[2:3], 0x1FFFFF
// CHECK-NEXT:{{^}}s_atomic_swap s5, s[2:3], 0x1FFFFF
// CHECK-NEXT:{{^}} ^
//==============================================================================
// expected a 2-bit value
v_mov_b32_dpp v5, v1 quad_perm:[3,2,1,4] row_mask:0x0 bank_mask:0x0
// CHECK: error: expected a 2-bit value
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 quad_perm:[3,2,1,4] row_mask:0x0 bank_mask:0x0
// CHECK-NEXT:{{^}} ^
v_mov_b32_dpp v5, v1 quad_perm:[3,-1,1,3] row_mask:0x0 bank_mask:0x0
// CHECK: error: expected a 2-bit value
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 quad_perm:[3,-1,1,3] row_mask:0x0 bank_mask:0x0
// CHECK-NEXT:{{^}} ^
//==============================================================================
// expected a 3-bit value
@ -210,6 +223,11 @@ v_mov_b32_dpp v5, v1 dpp8:[0,1,2,3,4,5,6,7)
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 dpp8:[0,1,2,3,4,5,6,7)
// CHECK-NEXT:{{^}} ^
v_mov_b32_dpp v5, v1 quad_perm:[3,2,1,0) row_mask:0x0 bank_mask:0x0
// CHECK: error: expected a closing square bracket
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 quad_perm:[3,2,1,0) row_mask:0x0 bank_mask:0x0
// CHECK-NEXT:{{^}} ^
//==============================================================================
// expected a colon
@ -251,6 +269,11 @@ v_mov_b32_dpp v5, v1 dpp8:[0,1,2,3,4,5,6]
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 dpp8:[0,1,2,3,4,5,6]
// CHECK-NEXT:{{^}} ^
v_mov_b32_dpp v5, v1 quad_perm:[3,2] row_mask:0x0 bank_mask:0x0
// CHECK: error: expected a comma
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 quad_perm:[3,2] row_mask:0x0 bank_mask:0x0
// CHECK-NEXT:{{^}} ^
//==============================================================================
// expected a comma or a closing parenthesis
@ -379,6 +402,16 @@ v_mov_b32_dpp v5, v1 dpp8:[0,1,2,x,4,5,6,7]
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 dpp8:[0,1,2,x,4,5,6,7]
// CHECK-NEXT:{{^}} ^
v_mov_b32_dpp v5, v1 quad_perm:[3,x,1,0] row_mask:0x0 bank_mask:0x0
// CHECK: error: expected absolute expression
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 quad_perm:[3,x,1,0] row_mask:0x0 bank_mask:0x0
// CHECK-NEXT:{{^}} ^
v_mov_b32_dpp v5, v1 row_share:x row_mask:0x0 bank_mask:0x0
// CHECK: error: expected absolute expression
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 row_share:x row_mask:0x0 bank_mask:0x0
// CHECK-NEXT:{{^}} ^
//==============================================================================
// expected a message name or an absolute expression
@ -458,6 +491,11 @@ v_mov_b32_dpp v5, v1 dpp8:(0,1,2,3,4,5,6,7)
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 dpp8:(0,1,2,3,4,5,6,7)
// CHECK-NEXT:{{^}} ^
v_mov_b32_dpp v5, v1 quad_perm:(3,2,1,0) row_mask:0x0 bank_mask:0x0
// CHECK: error: expected an opening square bracket
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 quad_perm:(3,2,1,0) row_mask:0x0 bank_mask:0x0
// CHECK-NEXT:{{^}} ^
//==============================================================================
// expected an operation name or an absolute expression
@ -800,6 +838,19 @@ s_mov_b64 s[10:11], [x0,s1]
// CHECK-NEXT:{{^}}s_mov_b64 s[10:11], [x0,s1]
// CHECK-NEXT:{{^}} ^
//==============================================================================
// invalid row_share value
v_mov_b32_dpp v5, v1 row_share:16 row_mask:0x0 bank_mask:0x0
// CHECK: error: invalid row_share value
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 row_share:16 row_mask:0x0 bank_mask:0x0
// CHECK-NEXT:{{^}} ^
v_mov_b32_dpp v5, v1 row_share:-1 row_mask:0x0 bank_mask:0x0
// CHECK: error: invalid row_share value
// CHECK-NEXT:{{^}}v_mov_b32_dpp v5, v1 row_share:-1 row_mask:0x0 bank_mask:0x0
// CHECK-NEXT:{{^}} ^
//==============================================================================
// invalid syntax, expected 'neg' modifier

View File

@ -4,9 +4,9 @@
// RUN: not llvm-mc -arch=amdgcn -mcpu=bonaire %s 2>&1 | FileCheck %s --check-prefix=NOSICI --implicit-check-not=error:
// NOSICI: error: not a valid operand.
// NOVI: error: failed parsing operand
// NOVI: error: invalid row_bcast value
v_mov_b32 v0, v0 row_bcast:0
// NOSICI: error: not a valid operand.
// NOVI: error: failed parsing operand
// NOVI: error: invalid row_bcast value
v_mov_b32 v0, v0 row_bcast:13