Index: llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ llvm/trunk/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -1085,11 +1085,11 @@ AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone, bool (*ConvertResult)(int64_t &) = nullptr); - OperandMatchResultTy parseOperandArrayWithPrefix( - const char *Prefix, - OperandVector &Operands, - AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone, - bool (*ConvertResult)(int64_t&) = nullptr); + OperandMatchResultTy + parseOperandArrayWithPrefix(const char *Prefix, + OperandVector &Operands, + AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone, + bool (*ConvertResult)(int64_t&) = nullptr); OperandMatchResultTy parseNamedBit(const char *Name, OperandVector &Operands, @@ -4018,12 +4018,14 @@ switch (Res) { case MatchOperand_Success: break; case MatchOperand_ParseFail: + // FIXME: use real operand location rather than the current location. Error(getLexer().getLoc(), "failed parsing operand."); while (!getLexer().is(AsmToken::EndOfStatement)) { Parser.Lex(); } return true; case MatchOperand_NoMatch: + // FIXME: use real operand location rather than the current location. Error(getLexer().getLoc(), "not a valid operand."); while (!getLexer().is(AsmToken::EndOfStatement)) { Parser.Lex(); @@ -4067,52 +4069,48 @@ return MatchOperand_Success; } -OperandMatchResultTy AMDGPUAsmParser::parseOperandArrayWithPrefix( - const char *Prefix, - OperandVector &Operands, - AMDGPUOperand::ImmTy ImmTy, - bool (*ConvertResult)(int64_t&)) { - StringRef Name = Parser.getTok().getString(); - if (!Name.equals(Prefix)) +OperandMatchResultTy +AMDGPUAsmParser::parseOperandArrayWithPrefix(const char *Prefix, + OperandVector &Operands, + AMDGPUOperand::ImmTy ImmTy, + bool (*ConvertResult)(int64_t&)) { + SMLoc S = getLoc(); + if (!trySkipId(Prefix, AsmToken::Colon)) return MatchOperand_NoMatch; - Parser.Lex(); - if (getLexer().isNot(AsmToken::Colon)) + if (!skipToken(AsmToken::LBrac, "expected a left square bracket")) return MatchOperand_ParseFail; - Parser.Lex(); - if (getLexer().isNot(AsmToken::LBrac)) - return MatchOperand_ParseFail; - Parser.Lex(); - unsigned Val = 0; - SMLoc S = Parser.getTok().getLoc(); + const unsigned MaxSize = 4; // FIXME: How to verify the number of elements matches the number of src // operands? - for (int I = 0; I < 4; ++I) { - if (I != 0) { - if (getLexer().is(AsmToken::RBrac)) - break; + for (int I = 0; ; ++I) { + int64_t Op; + SMLoc Loc = getLoc(); + if (!parseExpr(Op)) + return MatchOperand_ParseFail; - if (getLexer().isNot(AsmToken::Comma)) - return MatchOperand_ParseFail; - Parser.Lex(); + if (Op != 0 && Op != 1) { + Error(Loc, "invalid " + StringRef(Prefix) + " value."); + return MatchOperand_ParseFail; } - if (getLexer().isNot(AsmToken::Integer)) - return MatchOperand_ParseFail; + Val |= (Op << I); - int64_t Op; - if (getParser().parseAbsoluteExpression(Op)) + if (trySkipToken(AsmToken::RBrac)) + break; + + if (I + 1 == MaxSize) { + Error(getLoc(), "expected a closing square bracket"); return MatchOperand_ParseFail; + } - if (Op != 0 && Op != 1) + if (!skipToken(AsmToken::Comma, "expected a comma")) return MatchOperand_ParseFail; - Val |= (Op << I); } - Parser.Lex(); Operands.push_back(AMDGPUOperand::CreateImm(this, Val, S, ImmTy)); return MatchOperand_Success; } Index: llvm/trunk/test/MC/AMDGPU/dl-insts-err.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/dl-insts-err.s +++ llvm/trunk/test/MC/AMDGPU/dl-insts-err.s @@ -29,19 +29,19 @@ // Test invalid operands. // -// GFX906: error: failed parsing operand +// GFX906: error: invalid operand for instruction v_dot2_f32_f16 v0, v1, v2, v3 op_sel -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_f32_f16 v0, v1, v2, v3 op_sel: -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 op_sel:[ -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_f32_f16 v0, v1, v2, v3 op_sel:] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 op_sel:[] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 op_sel:[,] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 op_sel:[,0] // GFX906: error: failed parsing operand v_dot2_f32_f16 v0, v1, v2, v3 op_sel:[0,2] @@ -55,21 +55,21 @@ v_dot2_f32_f16 v0, v1, v2, v3 op_sel:[-1,0] // GFX906: error: failed parsing operand v_dot2_f32_f16 v0, v1, v2, v3 op_sel:[-1,-1] -// GFX906: error: failed parsing operand +// GFX906: error: expected a closing square bracket v_dot2_f32_f16 v0, v1, v2, v3 op_sel:[0,0,0,0,0] -// GFX906: error: failed parsing operand +// GFX906: error: invalid operand for instruction v_dot2_f32_f16 v0, v1, v2, v3 op_sel_hi -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_f32_f16 v0, v1, v2, v3 op_sel_hi: -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 op_sel_hi:[ -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_f32_f16 v0, v1, v2, v3 op_sel_hi:] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 op_sel_hi:[] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 op_sel_hi:[,] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 op_sel_hi:[,0] // GFX906: error: failed parsing operand v_dot2_f32_f16 v0, v1, v2, v3 op_sel_hi:[0,2] @@ -83,21 +83,21 @@ v_dot2_f32_f16 v0, v1, v2, v3 op_sel_hi:[-1,0] // GFX906: error: failed parsing operand v_dot2_f32_f16 v0, v1, v2, v3 op_sel_hi:[-1,-1] -// GFX906: error: failed parsing operand +// GFX906: error: expected a closing square bracket v_dot2_f32_f16 v0, v1, v2, v3 op_sel_hi:[0,0,0,0,0] -// GFX906: error: failed parsing operand +// GFX906: error: invalid operand for instruction v_dot2_f32_f16 v0, v1, v2, v3 neg_lo -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_f32_f16 v0, v1, v2, v3 neg_lo: -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 neg_lo:[ -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_f32_f16 v0, v1, v2, v3 neg_lo:] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 neg_lo:[] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 neg_lo:[,] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 neg_lo:[,0] // GFX906: error: failed parsing operand v_dot2_f32_f16 v0, v1, v2, v3 neg_lo:[0,2] @@ -111,21 +111,21 @@ v_dot2_f32_f16 v0, v1, v2, v3 neg_lo:[-1,0] // GFX906: error: failed parsing operand v_dot2_f32_f16 v0, v1, v2, v3 neg_lo:[-1,-1] -// GFX906: error: failed parsing operand +// GFX906: error: expected a closing square bracket v_dot2_f32_f16 v0, v1, v2, v3 neg_lo:[0,0,0,0,0] -// GFX906: error: failed parsing operand +// GFX906: error: invalid operand for instruction v_dot2_f32_f16 v0, v1, v2, v3 neg_hi -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_f32_f16 v0, v1, v2, v3 neg_hi: -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 neg_hi:[ -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_f32_f16 v0, v1, v2, v3 neg_hi:] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 neg_hi:[] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 neg_hi:[,] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_f32_f16 v0, v1, v2, v3 neg_hi:[,0] // GFX906: error: failed parsing operand v_dot2_f32_f16 v0, v1, v2, v3 neg_hi:[0,2] @@ -139,21 +139,21 @@ v_dot2_f32_f16 v0, v1, v2, v3 neg_hi:[-1,0] // GFX906: error: failed parsing operand v_dot2_f32_f16 v0, v1, v2, v3 neg_hi:[-1,-1] -// GFX906: error: failed parsing operand +// GFX906: error: expected a closing square bracket v_dot2_f32_f16 v0, v1, v2, v3 neg_hi:[0,0,0,0,0] -// GFX906: error: failed parsing operand +// GFX906: error: invalid operand for instruction v_dot2_i32_i16 v0, v1, v2, v3 op_sel -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_i32_i16 v0, v1, v2, v3 op_sel: -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_i32_i16 v0, v1, v2, v3 op_sel:[ -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_i32_i16 v0, v1, v2, v3 op_sel:] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_i32_i16 v0, v1, v2, v3 op_sel:[] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_i32_i16 v0, v1, v2, v3 op_sel:[,] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_i32_i16 v0, v1, v2, v3 op_sel:[,0] // GFX906: error: failed parsing operand v_dot2_i32_i16 v0, v1, v2, v3 op_sel:[0,2] @@ -167,21 +167,21 @@ v_dot2_i32_i16 v0, v1, v2, v3 op_sel:[-1,0] // GFX906: error: failed parsing operand v_dot2_i32_i16 v0, v1, v2, v3 op_sel:[-1,-1] -// GFX906: error: failed parsing operand +// GFX906: error: expected a closing square bracket v_dot2_i32_i16 v0, v1, v2, v3 op_sel:[0,0,0,0,0] -// GFX906: error: failed parsing operand +// GFX906: error: invalid operand for instruction v_dot2_i32_i16 v0, v1, v2, v3 op_sel_hi -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_i32_i16 v0, v1, v2, v3 op_sel_hi: -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_i32_i16 v0, v1, v2, v3 op_sel_hi:[ -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_i32_i16 v0, v1, v2, v3 op_sel_hi:] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_i32_i16 v0, v1, v2, v3 op_sel_hi:[] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_i32_i16 v0, v1, v2, v3 op_sel_hi:[,] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_i32_i16 v0, v1, v2, v3 op_sel_hi:[,0] // GFX906: error: failed parsing operand v_dot2_i32_i16 v0, v1, v2, v3 op_sel_hi:[0,2] @@ -195,25 +195,25 @@ v_dot2_i32_i16 v0, v1, v2, v3 op_sel_hi:[-1,0] // GFX906: error: failed parsing operand v_dot2_i32_i16 v0, v1, v2, v3 op_sel_hi:[-1,-1] -// GFX906: error: failed parsing operand +// GFX906: error: expected a closing square bracket v_dot2_i32_i16 v0, v1, v2, v3 op_sel_hi:[0,0,0,0,0] // FIXME-GFX906: error: invalid operand for instruction v_dot2_i32_i16 v0, v1, v2, v3 neg_lo:[0,0] // FIXME-GFX906: error: invalid operand for instruction v_dot2_i32_i16 v0, v1, v2, v3 neg_hi:[0,0] -// GFX906: error: failed parsing operand +// GFX906: error: invalid operand for instruction v_dot2_u32_u16 v0, v1, v2, v3 op_sel -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_u32_u16 v0, v1, v2, v3 op_sel: -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_u32_u16 v0, v1, v2, v3 op_sel:[ -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_u32_u16 v0, v1, v2, v3 op_sel:] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_u32_u16 v0, v1, v2, v3 op_sel:[] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_u32_u16 v0, v1, v2, v3 op_sel:[,] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_u32_u16 v0, v1, v2, v3 op_sel:[,0] // GFX906: error: failed parsing operand v_dot2_u32_u16 v0, v1, v2, v3 op_sel:[0,2] @@ -227,23 +227,23 @@ v_dot2_u32_u16 v0, v1, v2, v3 op_sel:[-1,0] // GFX906: error: failed parsing operand v_dot2_u32_u16 v0, v1, v2, v3 op_sel:[-1,-1] -// GFX906: error: failed parsing operand +// GFX906: error: expected a closing square bracket v_dot2_u32_u16 v0, v1, v2, v3 op_sel:[0,0,0,0,0] -// GFX906: error: failed parsing operand +// GFX906: error: invalid operand for instruction v_dot2_u32_u16 v0, v1, v2, v3 op_sel_hi -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_u32_u16 v0, v1, v2, v3 op_sel_hi: -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_u32_u16 v0, v1, v2, v3 op_sel_hi:[ -// GFX906: error: failed parsing operand +// GFX906: error: expected a left square bracket v_dot2_u32_u16 v0, v1, v2, v3 op_sel_hi:] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_u32_u16 v0, v1, v2, v3 op_sel_hi:[] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_u32_u16 v0, v1, v2, v3 op_sel_hi:[,] -// GFX906: error: failed parsing operand +// GFX906: error: unknown token in expression v_dot2_u32_u16 v0, v1, v2, v3 op_sel_hi:[,0] -// GFX906: error: failed parsing operand +// GFX906: error: invalid op_sel_hi value v_dot2_u32_u16 v0, v1, v2, v3 op_sel_hi:[0,2] // GFX906: error: failed parsing operand v_dot2_u32_u16 v0, v1, v2, v3 op_sel_hi:[2,0] @@ -255,7 +255,7 @@ v_dot2_u32_u16 v0, v1, v2, v3 op_sel_hi:[-1,0] // GFX906: error: failed parsing operand v_dot2_u32_u16 v0, v1, v2, v3 op_sel_hi:[-1,-1] -// GFX906: error: failed parsing operand +// GFX906: error: expected a closing square bracket v_dot2_u32_u16 v0, v1, v2, v3 op_sel_hi:[0,0,0,0,0] // FIXME-GFX906: error: invalid operand for instruction v_dot2_u32_u16 v0, v1, v2, v3 neg_lo:[0,0] Index: llvm/trunk/test/MC/AMDGPU/expressions-gfx9.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/expressions-gfx9.s +++ llvm/trunk/test/MC/AMDGPU/expressions-gfx9.s @@ -0,0 +1,31 @@ +// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx900 -show-encoding %s | FileCheck %s --check-prefix=GFX9 +// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx900 -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOGFX9 + +//===----------------------------------------------------------------------===// +// Relocatable expressions cannot be used with SDWA modifiers. +//===----------------------------------------------------------------------===// + +v_mov_b32_sdwa v1, sext(u) +// NOGFX9: error: expected an absolute expression + +//===----------------------------------------------------------------------===// +// Constant expressions may be used with 'sext' modifier +//===----------------------------------------------------------------------===// + +i1=1 + +v_mov_b32_sdwa v1, sext(i1-2) +// GFX9: v_mov_b32_sdwa v1, sext(-1) dst_sel:DWORD dst_unused:UNUSED_PRESERVE src0_sel:DWORD ; encoding: [0xf9,0x02,0x02,0x7e,0xc1,0x16,0x8e,0x00] + +v_mov_b32_sdwa v1, sext(-2+i1) +// GFX9: v_mov_b32_sdwa v1, sext(-1) dst_sel:DWORD dst_unused:UNUSED_PRESERVE src0_sel:DWORD ; encoding: [0xf9,0x02,0x02,0x7e,0xc1,0x16,0x8e,0x00] + +//===----------------------------------------------------------------------===// +// Constant expressions may be used with op_sel* and neg_* modifiers. +//===----------------------------------------------------------------------===// + +v_pk_add_u16 v1, v2, v3 op_sel:[2-i1,i1-1] +// GFX9: v_pk_add_u16 v1, v2, v3 op_sel:[1,0] ; encoding: [0x01,0x08,0x8a,0xd3,0x02,0x07,0x02,0x18] + +v_pk_add_u16 v1, v2, v3 neg_lo:[2-i1,i1-1] +// GFX9: v_pk_add_u16 v1, v2, v3 neg_lo:[1,0] ; encoding: [0x01,0x00,0x8a,0xd3,0x02,0x07,0x02,0x38] Index: llvm/trunk/test/MC/AMDGPU/vop3p-err.s =================================================================== --- llvm/trunk/test/MC/AMDGPU/vop3p-err.s +++ llvm/trunk/test/MC/AMDGPU/vop3p-err.s @@ -1,42 +1,54 @@ // RUN: not llvm-mc -arch=amdgcn -mcpu=gfx900 -show-encoding %s 2>&1 | FileCheck -check-prefix=GFX9 %s -// GFX9: 31: error: failed parsing operand. +// GFX9: 25: error: invalid operand for instruction v_pk_add_u16 v1, v2, v3 op_sel -// GFX9: 32: error: failed parsing operand. +// GFX9: 32: error: expected a left square bracket v_pk_add_u16 v1, v2, v3 op_sel: -// GFX9: 33: error: failed parsing operand. +// GFX9: 33: error: unknown token in expression v_pk_add_u16 v1, v2, v3 op_sel:[ -// GFX9: 33: error: failed parsing operand. +// GFX9: 33: error: unknown token in expression v_pk_add_u16 v1, v2, v3 op_sel:[] -// GFX9: 34: error: failed parsing operand. +// GFX9: 33: error: unknown token in expression v_pk_add_u16 v1, v2, v3 op_sel:[,] // XXGFX9: 34: error: failed parsing operand. // v_pk_add_u16 v1, v2, v3 op_sel:[0] -// GFX9: 35: error: failed parsing operand. +// GFX9: 35: error: expected a comma +v_pk_add_u16 v1, v2, v3 op_sel:[0 0] + +// GFX9: 35: error: unknown token in expression v_pk_add_u16 v1, v2, v3 op_sel:[0,] -// XXGFX9: 36: error: failed parsing operand. -// v_pk_add_u16 v1, v2, v3 op_sel:[,0] +// GFX9: 33: error: unknown token in expression +v_pk_add_u16 v1, v2, v3 op_sel:[,0] + +// GFX9: 42: error: expected a closing square bracket +v_max3_f16 v5, v1, v2, v3 op_sel:[1,1,1,1, + +// GFX9: 42: error: expected a closing square bracket +v_max3_f16 v5, v1, v2, v3 op_sel:[1,1,1,1[ + +// GFX9: 43: error: expected a closing square bracket +v_max3_f16 v5, v1, v2, v3 op_sel:[1,1,1,1 1 -// GFX9: 36: error: failed parsing operand. +// GFX9: 35: error: invalid op_sel value. v_pk_add_u16 v1, v2, v3 op_sel:[0,2] -// GFX9: 35: error: failed parsing operand. +// GFX9: 33: error: invalid op_sel value. v_pk_add_u16 v1, v2, v3 op_sel:[2,0] -// GFX9: 33: error: failed parsing operand. +// GFX9: 33: error: invalid op_sel value. v_pk_add_u16 v1, v2, v3 op_sel:[-1,0] -// GFX9: 35: error: failed parsing operand. +// GFX9: 35: error: invalid op_sel value. v_pk_add_u16 v1, v2, v3 op_sel:[0,-1] -// GFX9: 42: error: failed parsing operand. +// GFX9: 40: error: expected a closing square bracket v_pk_add_u16 v1, v2, v3 op_sel:[0,0,0,0,0] // XXGFX9: invalid operand for instruction