[VE] Add VBRD/VMV instructions
authorKazushi (Jam) Marukawa <marukawa@nec.com>
Sun, 18 Oct 2020 09:47:45 +0000 (18:47 +0900)
committerKazushi (Jam) Marukawa <marukawa@nec.com>
Mon, 19 Oct 2020 09:33:54 +0000 (18:33 +0900)
Add VBRD/VMV vector instructions.  In order to do that, also support
VM512 registers and RV instruction format in MC layer.  Also add
regression tests for new instructions.

Reviewed By: simoll

Differential Revision: https://reviews.llvm.org/D89641

llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp
llvm/lib/Target/VE/VEInstrFormats.td
llvm/lib/Target/VE/VEInstrVec.td
llvm/test/MC/VE/VBRD.s [new file with mode: 0644]
llvm/test/MC/VE/VMV.s [new file with mode: 0644]

index 73228f9..fc13b8e 100644 (file)
@@ -125,6 +125,9 @@ static const MCPhysReg F128Regs[32] = {
     VE::Q16, VE::Q17, VE::Q18, VE::Q19, VE::Q20, VE::Q21, VE::Q22, VE::Q23,
     VE::Q24, VE::Q25, VE::Q26, VE::Q27, VE::Q28, VE::Q29, VE::Q30, VE::Q31};
 
+static const MCPhysReg VM512Regs[8] = {VE::VMP0, VE::VMP1, VE::VMP2, VE::VMP3,
+                                       VE::VMP4, VE::VMP5, VE::VMP6, VE::VMP7};
+
 static const MCPhysReg MISCRegs[31] = {
     VE::USRCC,      VE::PSW,        VE::SAR,        VE::NoRegister,
     VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::PMMR,
@@ -648,6 +651,15 @@ public:
     return true;
   }
 
+  static bool MorphToVM512Reg(VEOperand &Op) {
+    unsigned Reg = Op.getReg();
+    unsigned regIdx = Reg - VE::VM0;
+    if (regIdx % 2 || regIdx > 15)
+      return false;
+    Op.Reg.RegNum = VM512Regs[regIdx / 2];
+    return true;
+  }
+
   static bool MorphToMISCReg(VEOperand &Op) {
     const auto *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm());
     if (!ConstExpr)
@@ -1462,6 +1474,10 @@ unsigned VEAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
     if (Op.isReg() && VEOperand::MorphToF128Reg(Op))
       return MCTargetAsmParser::Match_Success;
     break;
+  case MCK_VM512:
+    if (Op.isReg() && VEOperand::MorphToVM512Reg(Op))
+      return MCTargetAsmParser::Match_Success;
+    break;
   case MCK_MISC:
     if (Op.isImm() && VEOperand::MorphToMISCReg(Op))
       return MCTargetAsmParser::Match_Success;
index 399a24d..f43c975 100644 (file)
@@ -237,8 +237,43 @@ class RVM<bits<8>opVal, dag outs, dag ins, string asmstr,
 
 //-----------------------------------------------------------------------------
 // Section 5.7 RV Type
+//
+// RV type is for vector instructions.
 //-----------------------------------------------------------------------------
 
+class RV<bits<8>opVal, dag outs, dag ins, string asmstr, list<dag> pattern = []>
+   : InstVE<outs, ins, asmstr, pattern> {
+  bits<1>  cx = 0;
+  bits<1>  cx2 = 0;
+  bits<1>  cs = 0;
+  bits<1>  cs2 = 0;
+  bits<4>  m = 0;
+  bits<1>  cy = 1;
+  bits<7>  sy;
+  bits<1>  cz = 0;
+  bits<7>  sz = 0;
+  bits<8>  vx = 0;
+  bits<8>  vy = 0;
+  bits<8>  vz = 0;
+  bits<8>  vw = 0;
+  let op = opVal;
+  let Inst{55} = cx;
+  let Inst{54} = cx2;
+  let Inst{53} = cs;
+  let Inst{52} = cs2;
+  let Inst{51-48} = m;
+  let Inst{47} = cy;
+  let Inst{46-40} = sy;
+  let Inst{39} = cz;
+  let Inst{38-32} = sz;
+  let Inst{31-24} = vx;
+  let Inst{23-16} = vy;
+  let Inst{15-8} = vz;
+  let Inst{7-0} = vw;
+
+  let VE_Vector = 1;
+}
+
 // Pseudo instructions.
 class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern = []>
    : InstVE<outs, ins, asmstr, pattern> {
index dd04ece..8e2db99 100644 (file)
@@ -352,3 +352,84 @@ multiclass SVMm<string opcStr, bits<8>opc, RegisterClass RCM> {
               opcStr#" $sx, $vz, $sy">;
 }
 defm SVM : SVMm<"svm", 0xa7, VM>;
+
+// Section 8.9.24 - VBRD (Vector Broadcast)
+let vx = ?, hasSideEffects = 0, Uses = [VL] in
+multiclass VBRDbm<string opcStr, string argStr, bits<8>opc, RegisterClass RC,
+                  dag dag_in, string disEnc = ""> {
+  let DisableEncoding = disEnc in
+  def "" : RV<opc, (outs RC:$vx), dag_in,
+              !strconcat(opcStr, " $vx, ", argStr)>;
+  let Constraints = "$vx = $base", DisableEncoding = disEnc#"$base",
+      isCodeGenOnly = 1 in
+  def _v : RV<opc, (outs RC:$vx), !con(dag_in, (ins RC:$base)),
+              !strconcat(opcStr, " $vx, ", argStr)>;
+}
+multiclass VBRDlm<string opcStr, string argStr, bits<8>opc, RegisterClass RC,
+                  dag dag_in> {
+  defm "" : VBRDbm<opcStr, argStr, opc, RC, dag_in>;
+  let isCodeGenOnly = 1, VE_VLInUse = 1 in {
+    defm l : VBRDbm<opcStr, argStr, opc, RC, !con(dag_in, (ins I32:$vl)),
+                   "$vl,">;
+    defm L : VBRDbm<opcStr, argStr, opc, RC, !con(dag_in, (ins VLS:$vl)),
+                   "$vl,">;
+  }
+}
+multiclass VBRDmm<string opcStr, string argStr, bits<8>opc, RegisterClass RC,
+                  RegisterClass RCM, dag dag_in> {
+  defm "" : VBRDlm<opcStr, argStr, opc, RC, dag_in>;
+  let m = ?, VE_VLWithMask = 1 in
+  defm m : VBRDlm<opcStr, argStr#", $m", opc, RC, !con(dag_in, (ins RCM:$m))>;
+}
+let VE_VLIndex = 2 in
+multiclass VBRDm<string opcStr, bits<8>opc, RegisterClass VRC, RegisterClass RC,
+                 RegisterClass RCM> {
+  defm r : VBRDmm<opcStr, "$sy", opc, VRC, RCM, (ins RC:$sy)>;
+  let cy = 0 in
+  defm i : VBRDmm<opcStr, "$sy", opc, VRC, RCM, (ins simm7:$sy)>;
+}
+let cx = 0, cx2 = 0 in
+defm VBRD : VBRDm<"vbrd", 0x8c, V64, I64, VM>;
+let cx = 0, cx2 = 1 in
+defm VBRDL : VBRDm<"vbrdl", 0x8c, V64, I32, VM>;
+let cx = 1, cx2 = 0 in
+defm VBRDU : VBRDm<"vbrdu", 0x8c, V64, F32, VM>;
+let cx = 1, cx2 = 1 in
+defm PVBRD : VBRDm<"pvbrd", 0x8c, V64, I64, VM512>;
+
+// Section 8.9.25 - VMV (Vector Move)
+let vx = ?, vz = ?, hasSideEffects = 0, Uses = [VL] in
+multiclass VMVbm<string opcStr, string argStr, bits<8>opc, RegisterClass RC,
+                 dag dag_in, string disEnc = ""> {
+  let DisableEncoding = disEnc in
+  def "" : RV<opc, (outs RC:$vx), dag_in,
+              !strconcat(opcStr, " $vx, ", argStr)>;
+  let Constraints = "$vx = $base", DisableEncoding = disEnc#"$base",
+      isCodeGenOnly = 1 in
+  def _v : RV<opc, (outs RC:$vx), !con(dag_in, (ins RC:$base)),
+              !strconcat(opcStr, " $vx, ", argStr)>;
+}
+multiclass VMVlm<string opcStr, string argStr, bits<8>opc, RegisterClass RC,
+                 dag dag_in> {
+  defm "" : VMVbm<opcStr, argStr, opc, RC, dag_in>;
+  let isCodeGenOnly = 1, VE_VLInUse = 1 in {
+    defm l : VMVbm<opcStr, argStr, opc, RC, !con(dag_in, (ins I32:$vl)),
+                   "$vl,">;
+    defm L : VMVbm<opcStr, argStr, opc, RC, !con(dag_in, (ins VLS:$vl)),
+                   "$vl,">;
+  }
+}
+multiclass VMVmm<string opcStr, bits<8>opc, RegisterClass RC,
+                 RegisterClass RCM, dag dag_in> {
+  defm "" : VMVlm<opcStr, "$sy, $vz", opc, RC, dag_in>;
+  let m = ?, VE_VLWithMask = 1 in
+  defm m : VMVlm<opcStr, "$sy, $vz, $m", opc, RC, !con(dag_in, (ins RCM:$m))>;
+}
+let VE_VLIndex = 3 in
+multiclass VMVm<string opcStr, bits<8>opc, RegisterClass RC,
+                RegisterClass RCM> {
+  defm rv : VMVmm<opcStr, opc, RC, RCM, (ins I64:$sy, RC:$vz)>;
+  let cy = 0 in
+  defm iv : VMVmm<opcStr, opc, RC, RCM, (ins uimm7:$sy, RC:$vz)>;
+}
+defm VMV : VMVm<"vmv", 0x9c, V64, VM>;
diff --git a/llvm/test/MC/VE/VBRD.s b/llvm/test/MC/VE/VBRD.s
new file mode 100644 (file)
index 0000000..ab3bba2
--- /dev/null
@@ -0,0 +1,52 @@
+# RUN: llvm-mc -triple=ve --show-encoding < %s \
+# RUN:     | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=ve -filetype=obj < %s | llvm-objdump -d - \
+# RUN:     | FileCheck %s --check-prefixes=CHECK-INST
+
+# CHECK-INST: vbrd %v11, 23
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x0b,0x00,0x17,0x00,0x8c]
+vbrd %v11, 23
+
+# CHECK-INST: vbrd %v11, %s12, %vm15
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x0b,0x00,0x8c,0x0f,0x8c]
+vbrd %v11, %s12, %vm15
+
+# CHECK-INST: vbrd %vix, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0xff,0x00,0x96,0x00,0x8c]
+vbrd %vix, %s22, %vm0
+
+# CHECK-INST: vbrdl %v11, 23
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x0b,0x00,0x17,0x40,0x8c]
+vbrdl %v11, 23
+
+# CHECK-INST: vbrdl %v11, %s12, %vm15
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x0b,0x00,0x8c,0x4f,0x8c]
+vbrdl %v11, %s12, %vm15
+
+# CHECK-INST: vbrdl %vix, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0xff,0x00,0x96,0x40,0x8c]
+vbrdl %vix, %s22, %vm0
+
+# CHECK-INST: vbrdu %v11, 23
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x0b,0x00,0x17,0x80,0x8c]
+vbrdu %v11, 23
+
+# CHECK-INST: vbrdu %v11, %s12, %vm15
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x0b,0x00,0x8c,0x8f,0x8c]
+vbrdu %v11, %s12, %vm15
+
+# CHECK-INST: vbrdu %vix, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0xff,0x00,0x96,0x80,0x8c]
+vbrdu %vix, %s22, %vm0
+
+# CHECK-INST: pvbrd %v11, 23
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x0b,0x00,0x17,0xc0,0x8c]
+pvbrd %v11, 23
+
+# CHECK-INST: pvbrd %v11, %s12, %vm14
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0x0b,0x00,0x8c,0xce,0x8c]
+pvbrd %v11, %s12, %vm14
+
+# CHECK-INST: pvbrd %vix, %s22
+# CHECK-ENCODING: encoding: [0x00,0x00,0x00,0xff,0x00,0x96,0xc0,0x8c]
+pvbrd %vix, %s22, %vm0
diff --git a/llvm/test/MC/VE/VMV.s b/llvm/test/MC/VE/VMV.s
new file mode 100644 (file)
index 0000000..3e67c04
--- /dev/null
@@ -0,0 +1,16 @@
+# RUN: llvm-mc -triple=ve --show-encoding < %s \
+# RUN:     | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+# RUN: llvm-mc -triple=ve -filetype=obj < %s | llvm-objdump -d - \
+# RUN:     | FileCheck %s --check-prefixes=CHECK-INST
+
+# CHECK-INST: vmv %v11, 23, %v11
+# CHECK-ENCODING: encoding: [0x00,0x0b,0x00,0x0b,0x00,0x17,0x00,0x9c]
+vmv %v11, 23, %v11
+
+# CHECK-INST: vmv %v11, %s12, %vix, %vm15
+# CHECK-ENCODING: encoding: [0x00,0xff,0x00,0x0b,0x00,0x8c,0x0f,0x9c]
+vmv %v11, %s12, %vix, %vm15
+
+# CHECK-INST: vmv %vix, 127, %v63
+# CHECK-ENCODING: encoding: [0x00,0x3f,0x00,0xff,0x00,0x7f,0x00,0x9c]
+vmv %vix, 127, %v63, %vm0