Index: llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp =================================================================== --- llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ 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) Index: llvm/lib/Target/SystemZ/SystemZRegisterInfo.td =================================================================== --- llvm/lib/Target/SystemZ/SystemZRegisterInfo.td +++ llvm/lib/Target/SystemZ/SystemZRegisterInfo.td @@ -120,13 +120,12 @@ // of a GR128. defm ADDR128 : SystemZRegClass<"ADDR128", [untyped], 128, (sub GR128Bit, R0Q)>; -// Any type register. Used for .insn directives when we don't know what the -// register types could be. -defm AnyReg : SystemZRegClass<"AnyReg", - [i64, f64, v8i8, v4i16, v2i32, v2f32], 64, +// Any type register. Used for .insn directives when we don't know what the register +// types could be. +defm AnyReg : SystemZRegClass<"AnyReg", [i64, f64], 64, (add (sequence "R%uD", 0, 15), - (sequence "F%uD", 0, 15), - (sequence "V%u", 0, 15)), 0/*allocatable*/>; + (sequence "F%uD", 0, 15)), 0/*allocatable*/>; + //===----------------------------------------------------------------------===// // Floating-point registers Index: llvm/test/MC/SystemZ/directive-insn-vector.s =================================================================== --- llvm/test/MC/SystemZ/directive-insn-vector.s +++ 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 Index: llvm/test/MC/SystemZ/regs-bad.s =================================================================== --- llvm/test/MC/SystemZ/regs-bad.s +++ 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