diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -1330,6 +1330,7 @@ private: struct OperandInfoTy { + SMLoc Loc; int64_t Id; bool IsSymbolic = false; bool IsDefined = false; @@ -1340,14 +1341,14 @@ bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &Op, OperandInfoTy &Stream); bool validateSendMsg(const OperandInfoTy &Msg, const OperandInfoTy &Op, - const OperandInfoTy &Stream, - const SMLoc Loc); + const OperandInfoTy &Stream); - bool parseHwregBody(OperandInfoTy &HwReg, int64_t &Offset, int64_t &Width); + bool parseHwregBody(OperandInfoTy &HwReg, + OperandInfoTy &Offset, + OperandInfoTy &Width); bool validateHwreg(const OperandInfoTy &HwReg, - const int64_t Offset, - const int64_t Width, - const SMLoc Loc); + const OperandInfoTy &Offset, + const OperandInfoTy &Width); OperandMatchResultTy parseExpTgtImpl(StringRef Str, uint8_t &Val); SMLoc getFlatOffsetLoc(const OperandVector &Operands) const; @@ -5582,11 +5583,12 @@ bool AMDGPUAsmParser::parseHwregBody(OperandInfoTy &HwReg, - int64_t &Offset, - int64_t &Width) { + OperandInfoTy &Offset, + OperandInfoTy &Width) { using namespace llvm::AMDGPU::Hwreg; // The register may be specified by name or using a numeric code + HwReg.Loc = getLoc(); if (isToken(AsmToken::Identifier) && (HwReg.Id = getHwregId(getTokenStr())) >= 0) { HwReg.IsSymbolic = true; @@ -5599,33 +5601,45 @@ return true; // parse optional params - return - skipToken(AsmToken::Comma, "expected a comma or a closing parenthesis") && - parseExpr(Offset) && - skipToken(AsmToken::Comma, "expected a comma") && - parseExpr(Width) && - skipToken(AsmToken::RParen, "expected a closing parenthesis"); + if (!skipToken(AsmToken::Comma, "expected a comma or a closing parenthesis")) + return false; + + Offset.Loc = getLoc(); + if (!parseExpr(Offset.Id)) + return false; + + if (!skipToken(AsmToken::Comma, "expected a comma")) + return false; + + Width.Loc = getLoc(); + return parseExpr(Width.Id) && + skipToken(AsmToken::RParen, "expected a closing parenthesis"); } bool AMDGPUAsmParser::validateHwreg(const OperandInfoTy &HwReg, - const int64_t Offset, - const int64_t Width, - const SMLoc Loc) { + const OperandInfoTy &Offset, + const OperandInfoTy &Width) { using namespace llvm::AMDGPU::Hwreg; if (HwReg.IsSymbolic && !isValidHwreg(HwReg.Id, getSTI())) { - Error(Loc, "specified hardware register is not supported on this GPU"); + Error(HwReg.Loc, + "specified hardware register is not supported on this GPU"); return false; - } else if (!isValidHwreg(HwReg.Id)) { - Error(Loc, "invalid code of hardware register: only 6-bit values are legal"); + } + if (!isValidHwreg(HwReg.Id)) { + Error(HwReg.Loc, + "invalid code of hardware register: only 6-bit values are legal"); return false; - } else if (!isValidHwregOffset(Offset)) { - Error(Loc, "invalid bit offset: only 5-bit values are legal"); + } + if (!isValidHwregOffset(Offset.Id)) { + Error(Offset.Loc, "invalid bit offset: only 5-bit values are legal"); return false; - } else if (!isValidHwregWidth(Width)) { - Error(Loc, "invalid bitfield width: only values from 1 to 32 are legal"); + } + if (!isValidHwregWidth(Width.Id)) { + Error(Width.Loc, + "invalid bitfield width: only values from 1 to 32 are legal"); return false; } return true; @@ -5640,11 +5654,11 @@ if (trySkipId("hwreg", AsmToken::LParen)) { OperandInfoTy HwReg(ID_UNKNOWN_); - int64_t Offset = OFFSET_DEFAULT_; - int64_t Width = WIDTH_DEFAULT_; + OperandInfoTy Offset(OFFSET_DEFAULT_); + OperandInfoTy Width(WIDTH_DEFAULT_); if (parseHwregBody(HwReg, Offset, Width) && - validateHwreg(HwReg, Offset, Width, Loc)) { - ImmVal = encodeHwreg(HwReg.Id, Offset, Width); + validateHwreg(HwReg, Offset, Width)) { + ImmVal = encodeHwreg(HwReg.Id, Offset.Id, Width.Id); } else { return MatchOperand_ParseFail; } @@ -5675,6 +5689,7 @@ OperandInfoTy &Stream) { using namespace llvm::AMDGPU::SendMsg; + Msg.Loc = getLoc(); if (isToken(AsmToken::Identifier) && (Msg.Id = getMsgId(getTokenStr())) >= 0) { Msg.IsSymbolic = true; lex(); // skip message name @@ -5684,6 +5699,7 @@ if (trySkipToken(AsmToken::Comma)) { Op.IsDefined = true; + Op.Loc = getLoc(); if (isToken(AsmToken::Identifier) && (Op.Id = getMsgOpId(Msg.Id, getTokenStr())) >= 0) { lex(); // skip operation name @@ -5693,6 +5709,7 @@ if (trySkipToken(AsmToken::Comma)) { Stream.IsDefined = true; + Stream.Loc = getLoc(); if (!parseExpr(Stream.Id)) return false; } @@ -5704,8 +5721,7 @@ bool AMDGPUAsmParser::validateSendMsg(const OperandInfoTy &Msg, const OperandInfoTy &Op, - const OperandInfoTy &Stream, - const SMLoc S) { + const OperandInfoTy &Stream) { using namespace llvm::AMDGPU::SendMsg; // Validation strictness depends on whether message is specified @@ -5714,21 +5730,27 @@ bool Strict = Msg.IsSymbolic; if (!isValidMsgId(Msg.Id, getSTI(), Strict)) { - Error(S, "invalid message id"); + Error(Msg.Loc, "invalid message id"); return false; - } else if (Strict && (msgRequiresOp(Msg.Id) != Op.IsDefined)) { - Error(S, Op.IsDefined ? - "message does not support operations" : - "missing message operation"); + } + if (Strict && (msgRequiresOp(Msg.Id) != Op.IsDefined)) { + if (Op.IsDefined) { + Error(Op.Loc, "message does not support operations"); + } else { + Error(Msg.Loc, "missing message operation"); + } return false; - } else if (!isValidMsgOp(Msg.Id, Op.Id, Strict)) { - Error(S, "invalid operation id"); + } + if (!isValidMsgOp(Msg.Id, Op.Id, Strict)) { + Error(Op.Loc, "invalid operation id"); return false; - } else if (Strict && !msgSupportsStream(Msg.Id, Op.Id) && Stream.IsDefined) { - Error(S, "message operation does not support streams"); + } + if (Strict && !msgSupportsStream(Msg.Id, Op.Id) && Stream.IsDefined) { + Error(Stream.Loc, "message operation does not support streams"); return false; - } else if (!isValidMsgStream(Msg.Id, Op.Id, Stream.Id, Strict)) { - Error(S, "invalid message stream id"); + } + if (!isValidMsgStream(Msg.Id, Op.Id, Stream.Id, Strict)) { + Error(Stream.Loc, "invalid message stream id"); return false; } return true; @@ -5746,7 +5768,7 @@ OperandInfoTy Op(OP_NONE_); OperandInfoTy Stream(STREAM_ID_NONE_); if (parseSendMsgBody(Msg, Op, Stream) && - validateSendMsg(Msg, Op, Stream, Loc)) { + validateSendMsg(Msg, Op, Stream)) { ImmVal = encodeMsg(Msg.Id, Op.Id, Stream.Id); } else { return MatchOperand_ParseFail; diff --git a/llvm/test/MC/AMDGPU/gfx10_err_pos.s b/llvm/test/MC/AMDGPU/gfx10_err_pos.s --- a/llvm/test/MC/AMDGPU/gfx10_err_pos.s +++ b/llvm/test/MC/AMDGPU/gfx10_err_pos.s @@ -485,7 +485,7 @@ s_getreg_b32 s2, hwreg(3,32,32) // CHECK: error: invalid bit offset: only 5-bit values are legal // CHECK-NEXT:{{^}}s_getreg_b32 s2, hwreg(3,32,32) -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // invalid bitfield width: only values from 1 to 32 are legal @@ -493,7 +493,7 @@ s_setreg_b32 hwreg(3,0,33), s2 // CHECK: error: invalid bitfield width: only values from 1 to 32 are legal // CHECK-NEXT:{{^}}s_setreg_b32 hwreg(3,0,33), s2 -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // invalid code of hardware register: only 6-bit values are legal @@ -501,7 +501,7 @@ s_setreg_b32 hwreg(0x40), s2 // CHECK: error: invalid code of hardware register: only 6-bit values are legal // CHECK-NEXT:{{^}}s_setreg_b32 hwreg(0x40), s2 -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // invalid counter name x @@ -567,7 +567,7 @@ s_sendmsg sendmsg(-1) // CHECK: error: invalid message id // CHECK-NEXT:{{^}}s_sendmsg sendmsg(-1) -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // invalid message stream id @@ -575,12 +575,12 @@ s_sendmsg sendmsg(2, 2, 4) // CHECK: error: invalid message stream id // CHECK-NEXT:{{^}}s_sendmsg sendmsg(2, 2, 4) -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 4) // CHECK: error: invalid message stream id // CHECK-NEXT:{{^}}s_sendmsg sendmsg(MSG_GS, GS_OP_CUT, 4) -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // invalid mul value. @@ -648,7 +648,7 @@ s_sendmsg sendmsg(15, -1) // CHECK: error: invalid operation id // CHECK-NEXT:{{^}}s_sendmsg sendmsg(15, -1) -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // invalid or unsupported register size @@ -717,7 +717,7 @@ s_sendmsg sendmsg(MSG_GS_ALLOC_REQ, 0) // CHECK: error: message does not support operations // CHECK-NEXT:{{^}}s_sendmsg sendmsg(MSG_GS_ALLOC_REQ, 0) -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // message operation does not support streams @@ -725,7 +725,7 @@ s_sendmsg sendmsg(MSG_GS_DONE, GS_OP_NOP, 0) // CHECK: error: message operation does not support streams // CHECK-NEXT:{{^}}s_sendmsg sendmsg(MSG_GS_DONE, GS_OP_NOP, 0) -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // missing message operation @@ -733,7 +733,7 @@ s_sendmsg sendmsg(MSG_SYSMSG) // CHECK: error: missing message operation // CHECK-NEXT:{{^}}s_sendmsg sendmsg(MSG_SYSMSG) -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // missing register index @@ -874,7 +874,7 @@ s_getreg_b32 s2, hwreg(HW_REG_SHADER_CYCLES) // CHECK: error: specified hardware register is not supported on this GPU // CHECK-NEXT:{{^}}s_getreg_b32 s2, hwreg(HW_REG_SHADER_CYCLES) -// CHECK-NEXT:{{^}} ^ +// CHECK-NEXT:{{^}} ^ //============================================================================== // too few operands for instruction