diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp --- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -635,18 +635,18 @@ { "ssf", SystemZ::InsnSSF, 4, { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } }, { "vri", SystemZ::InsnVRI, 6, - { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } }, + { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } }, { "vrr", SystemZ::InsnVRR, 7, - { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_U4Imm, + { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_VR128, MCK_U4Imm, MCK_U4Imm, MCK_U4Imm } }, { "vrs", SystemZ::InsnVRS, 5, - { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12, MCK_U4Imm } }, + { MCK_U48Imm, MCK_AnyReg, MCK_VR128, MCK_BDAddr64Disp12, MCK_U4Imm } }, { "vrv", SystemZ::InsnVRV, 4, - { MCK_U48Imm, MCK_AnyReg, MCK_BDVAddr64Disp12, MCK_U4Imm } }, + { MCK_U48Imm, MCK_VR128, MCK_BDVAddr64Disp12, MCK_U4Imm } }, { "vrx", SystemZ::InsnVRX, 4, - { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12, MCK_U4Imm } }, + { MCK_U48Imm, MCK_VR128, MCK_BDXAddr64Disp12, MCK_U4Imm } }, { "vsi", SystemZ::InsnVSI, 4, - { MCK_U48Imm, MCK_AnyReg, MCK_BDAddr64Disp12, MCK_U8Imm } } + { MCK_U48Imm, MCK_VR128, MCK_BDAddr64Disp12, MCK_U8Imm } } }; static void printMCExpr(const MCExpr *E, raw_ostream &OS) { @@ -851,10 +851,11 @@ // Parse any type of register (including integers) and add it to Operands. OperandMatchResultTy SystemZAsmParser::parseAnyRegister(OperandVector &Operands) { + SMLoc StartLoc = Parser.getTok().getLoc(); + // Handle integer values. if (Parser.getTok().is(AsmToken::Integer)) { const MCExpr *Register; - SMLoc StartLoc = Parser.getTok().getLoc(); if (Parser.parseExpression(Register)) return MatchOperand_ParseFail; @@ -876,6 +877,11 @@ if (parseRegister(Reg)) return MatchOperand_ParseFail; + if (Reg.Num > 15) { + Error(StartLoc, "invalid register"); + return MatchOperand_ParseFail; + } + // Map to the correct register kind. RegisterKind Kind; unsigned RegNo; @@ -1208,6 +1214,8 @@ OperandMatchResultTy ResTy; if (Kind == MCK_AnyReg) ResTy = parseAnyReg(Operands); + else if (Kind == MCK_VR128) + ResTy = parseVR128(Operands); else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20) ResTy = parseBDXAddr64(Operands); else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20) diff --git a/llvm/test/MC/SystemZ/directive-insn-vector.s b/llvm/test/MC/SystemZ/directive-insn-vector.s --- a/llvm/test/MC/SystemZ/directive-insn-vector.s +++ b/llvm/test/MC/SystemZ/directive-insn-vector.s @@ -25,3 +25,5 @@ #CHECK: e6 0c 20 0c 01 35 vlrl %v16, 12(%r2), 12 .insn vsi,0xe60000000035,%v16,12(%r2),12 +#CHECK: e7 01 00 00 0c 56 vlr %v16, %v17 + .insn vrr,0xe70000000056,16,17,0,0,0,0 diff --git a/llvm/test/MC/SystemZ/regs-bad.s b/llvm/test/MC/SystemZ/regs-bad.s --- a/llvm/test/MC/SystemZ/regs-bad.s +++ b/llvm/test/MC/SystemZ/regs-bad.s @@ -217,6 +217,13 @@ lxr %f0,16 lxr %f0,0(%r1) +# Test that a high (>=16) vector register is not accepted in a non-vector +# operand. +# +#CHECK: error: invalid register +#CHECK: .insn rr,0x1800,%v16,%v0 +.insn rr,0x1800,%v16,%v0 + # Test access register operands # #CHECK: error: invalid operand for instruction