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 @@ -565,7 +565,7 @@ StringRef Format; uint64_t Opcode; int32_t NumOperands; - MatchClassKind OperandKinds[5]; + MatchClassKind OperandKinds[7]; }; // For equal_range comparison. @@ -633,7 +633,20 @@ { "sse", SystemZ::InsnSSE, 3, { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } }, { "ssf", SystemZ::InsnSSF, 4, - { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } } + { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } }, + { "vri", SystemZ::InsnVRI, 6, + { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } }, + { "vrr", SystemZ::InsnVRR, 7, + { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_U4Imm, + MCK_U4Imm } }, + { "vrs", SystemZ::InsnVRS, 5, + { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12, MCK_U4Imm } }, + { "vrv", SystemZ::InsnVRV, 4, + { MCK_U48Imm, MCK_AnyReg, MCK_BDVAddr64Disp12, MCK_U4Imm } }, + { "vrx", SystemZ::InsnVRX, 4, + { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12, MCK_U4Imm } }, + { "vsi", SystemZ::InsnVSI, 4, + { MCK_U48Imm, MCK_AnyReg, MCK_BDAddr64Disp12, MCK_U8Imm } } }; static void printMCExpr(const MCExpr *E, raw_ostream &OS) { @@ -1199,6 +1212,8 @@ ResTy = parseBDXAddr64(Operands); else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20) ResTy = parseBDAddr64(Operands); + else if (Kind == MCK_BDVAddr64Disp12) + ResTy = parseBDVAddr64(Operands); else if (Kind == MCK_PCRel32) ResTy = parsePCRel32(Operands); else if (Kind == MCK_PCRel16) @@ -1243,6 +1258,8 @@ ZOperand.addBDAddrOperands(Inst, 2); else if (ZOperand.isMem(BDXMem)) ZOperand.addBDXAddrOperands(Inst, 3); + else if (ZOperand.isMem(BDVMem)) + ZOperand.addBDVAddrOperands(Inst, 3); else if (ZOperand.isImm()) ZOperand.addImmOperands(Inst, 1); else diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td --- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td @@ -1764,6 +1764,55 @@ let Inst{35-32} = enc{35-32}; } +class DirectiveInsnVRI pattern> + : InstVRIe<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnVRR pattern> + : InstVRRc<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnVRS pattern> + : InstVRSc<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnVRV pattern> + : InstVRV<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnVRX pattern> + : InstVRX<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnVSI pattern> + : InstVSI<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + + //===----------------------------------------------------------------------===// // Variants of instructions with condition mask //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td @@ -2246,6 +2246,31 @@ (ins imm64zx48:$enc, bdaddr12only:$BD1, bdaddr12only:$BD2, AnyReg:$R3), ".insn ssf,$enc,$BD1,$BD2,$R3", []>; + def InsnVRI : DirectiveInsnVRI<(outs), + (ins imm64zx48:$enc, VR128:$V1, VR128:$V2, + imm32zx12:$I3, imm32zx4:$M4, imm32zx4:$M5), + ".insn vri,$enc,$V1,$V2,$I3,$M4,$M5", []>; + def InsnVRR : DirectiveInsnVRR<(outs), + (ins imm64zx48:$enc, VR128:$V1, VR128:$V2, + VR128:$V3, imm32zx4:$M4, imm32zx4:$M5, + imm32zx4:$M6), + ".insn vrr,$enc,$V1,$V2,$V3,$M4,$M5,$M6", []>; + def InsnVRS : DirectiveInsnVRS<(outs), + (ins imm64zx48:$enc, AnyReg:$R1, VR128:$V3, + bdaddr12only:$BD2, imm32zx4:$M4), + ".insn vrs,$enc,$BD2,$M4", []>; + def InsnVRV : DirectiveInsnVRV<(outs), + (ins imm64zx48:$enc, VR128:$V1, + bdvaddr12only:$VBD2, imm32zx4:$M3), + ".insn vrv,$enc,$V1,$VBD2,$M3", []>; + def InsnVRX : DirectiveInsnVRX<(outs), + (ins imm64zx48:$enc, VR128:$V1, + bdxaddr12only:$XBD2, imm32zx4:$M3), + ".insn vrx,$enc,$V1,$XBD2,$M3", []>; + def InsnVSI : DirectiveInsnVSI<(outs), + (ins imm64zx48:$enc, VR128:$V1, + bdaddr12only:$BD2, imm32zx8:$I3), + ".insn vsi,$enc,$V1,$BD2,$I3", []>; } //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/SystemZ/directive-insn-vector.s b/llvm/test/MC/SystemZ/directive-insn-vector.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/SystemZ/directive-insn-vector.s @@ -0,0 +1,27 @@ +# RUN: llvm-mc -triple s390x-linux-gnu -filetype=obj %s | \ +# RUN: llvm-objdump --mcpu=z14 -d - | FileCheck %s + +# Test the .insn directive for vector instructions. + +#CHECK: e7 23 2f ff 10 13 vgef %v2, 4095(%v3,%r2), 1 + .insn vrv,0xe70000000013,%v2,4095(%v3,%r2),1 + +#CHECK: e7 56 ff f1 20 4a vftci %v5, %v6, 4095, 2, 1 + .insn vri,0xe7000000004a,%v5,%v6,4095,2,1 + +#CHECK: e7 20 2f ff 30 06 vl %v2, 4095(%r2), 3 + .insn vrx,0xe70000000006,%v2,4095(%r2),3 + +#CHECK: e7 16 00 01 00 21 vlgvb %r1, %v6, 1 + .insn vrs,0xe70000003021,%r1,%v6,1(%r0),0 +#CHECK: e7 16 00 00 30 21 vlgvg %r1, %v6, 0 + .insn vrs,0xe70000003021,%r1,%v6,0(%r0),3 + +#CHECK: e7 37 00 00 00 56 vlr %v3, %v7 + .insn vrr,0xe70000000056,%v3,%v7,0,0,0,0 +#CHECK: e7 37 60 18 30 eb wfchdbs %f3, %f7, %f6 + .insn vrr,0xe700000000eb,%v3,%v7,%v6,3,8,1 + +#CHECK: e6 0c 20 0c 01 35 vlrl %v16, 12(%r2), 12 + .insn vsi,0xe60000000035,%v16,12(%r2),12 +