ppc/svp64: support svshape2 instruction
authorDmitry Selyutin <ghostmansd@gmail.com>
Sun, 28 May 2023 22:04:55 +0000 (01:04 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Tue, 14 Nov 2023 19:10:31 +0000 (22:10 +0300)
https://libre-soc.org/openpower/sv/
https://libre-soc.org/openpower/sv/remap/#svshape
https://libre-soc.org/openpower/sv/remap/#svshape2
https://libre-soc.org/openpower/isa/simplev/

gas/testsuite/gas/ppc/svshape.d
gas/testsuite/gas/ppc/svshape.s
opcodes/ppc-opc.c

index 8244741ed3374c3733175d519c6956911c8a6b53..9cfd638c3023fb9eaa82a89b6cfe7d622c7ce1c7 100644 (file)
@@ -6,8 +6,14 @@
 
 Disassembly of section \.text:
 0+ <\.text>:
-.*:    (19 00 e0 5b|5b e0 00 19)       svshape 32,1,1,0,0
-.*:    (19 00 1f 58|58 1f 00 19)       svshape 1,32,1,0,0
-.*:    (19 f8 00 58|58 00 f8 19)       svshape 1,1,32,0,0
-.*:    (99 07 00 58|58 00 07 99)       svshape 1,1,1,15,0
-.*:    (59 00 00 58|58 00 00 59)       svshape 1,1,1,0,1
+.*:\s+(19 00 e0 5b|5b e0 00 19)\s+svshape\s+32,1,1,0,0
+.*:\s+(19 00 1f 58|58 1f 00 19)\s+svshape\s+1,32,1,0,0
+.*:\s+(19 f8 00 58|58 00 f8 19)\s+svshape\s+1,1,32,0,0
+.*:\s+(99 07 00 58|58 00 07 99)\s+svshape\s+1,1,1,15,0
+.*:\s+(59 00 00 58|58 00 00 59)\s+svshape\s+1,1,1,0,1
+.*:\s+(19 04 c0 5b|5b c0 04 19)\s+svshape2\s+15,0,0,1,0,0
+.*:\s+(19 04 20 58|58 20 04 19)\s+svshape2\s+0,1,0,1,0,0
+.*:\s+(19 04 1f 58|58 1f 04 19)\s+svshape2\s+0,0,31,1,0,0
+.*:\s+(19 fc 00 58|58 00 fc 19)\s+svshape2\s+0,0,0,32,0,0
+.*:\s+(59 04 00 58|58 00 04 59)\s+svshape2\s+0,0,0,1,1,0
+.*:\s+(99 04 00 58|58 00 04 99)\s+svshape2\s+0,0,0,1,0,1
index c83373ba372e2b88b7acd1440eac059079c5c30e..39d4579a2002e26b7f83c91a4521412509369d5a 100644 (file)
@@ -3,3 +3,9 @@ svshape 1,32,1,0,0
 svshape 1,1,32,0,0
 svshape 1,1,1,15,0
 svshape 1,1,1,0,1
+svshape2 15,0,0,1,0,0
+svshape2 0,1,0,1,0,0
+svshape2 0,0,31,1,0,0
+svshape2 0,0,0,32,0,0
+svshape2 0,0,0,1,1,0
+svshape2 0,0,0,1,0,1
index 37f1aeb780caf70ebe5b2d82bab7dd9f753578ff..8afd12faff97c32fd8243c1bd81698448f9d3b1d 100644 (file)
@@ -2785,6 +2785,67 @@ extract_thds (uint64_t insn,
 
   return value;
 }
+
+static uint64_t
+insert_SVrm (uint64_t insn,
+            int64_t value,
+            ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+            const char **errmsg)
+{
+  /*
+   * 0b1000 and 0b1001 values are reserved for svshape2.
+   * svshape is SVM-form; svshape2 is SVM2-form.
+   *
+   * svshape XO:
+   *   0000-011001
+   *   0001-011001
+   *   0010-011001
+   *   0011-011001
+   *   0100-011001
+   *   0101-011001
+   *   0110-011001
+   *   0111-011001
+   *   1010-011001
+   *   1011-011001
+   *   1100-011001
+   *   1101-011001
+   *   1110-011001
+   *   1111-011001
+   *
+   * svshape2 XO:
+   *   100--011001
+   *
+   * # 1.6.35 SVM-FORM
+   * |0     |6        |11      |16    |21    |25 |26    |31  |
+   * | PO   |  SVxd   |   SVyd | SVzd | SVrm |vf |   XO      |
+   *
+   * # 1.6.35.1 SVM2-FORM
+   * |0     |6     |10|11      |16    |21 |24|25 |26    |31  |
+   * | PO   | offs |yx|   rmm  | SVd  |XO |mm|sk |   XO      |
+   */
+  if ((value == 8) || (value == 9))
+    *errmsg = _("invalid SVrm value");
+
+  return insn | ((value & 0xf) << 7);
+}
+
+static int64_t
+extract_SVrm (uint64_t insn,
+             ppc_cpu_t dialect ATTRIBUTE_UNUSED,
+             int *invalid)
+{
+  int64_t value = (insn >> 7) & 0xf;
+
+  /*
+   * We should never meet the condition below in practice.
+   * svshape2 opcode and mask should always be matched first.
+   */
+  if ((value == 8) || (value == 9))
+    *invalid = 1;
+
+  return value;
+}
+
 \f
 /* The operands table.
 
@@ -3188,6 +3249,7 @@ const struct powerpc_operand powerpc_operands[] =
 
   /* The L field in a D or X form instruction.  */
 #define L IMM20 + 1
+#define yx10 L
   { 0x1, 21, NULL, NULL, 0 },
 
   /* The optional L field in tlbie and tlbiel instructions.  */
@@ -3945,10 +4007,7 @@ const struct powerpc_operand powerpc_operands[] =
 #define yx ms
   { 0x1, 8, NULL, NULL, 0 },
 
-#define SVLcr ms + 1
-  { 0x1, 5, NULL, NULL, 0 },
-
-#define SVxd SVLcr + 1
+#define SVxd ms + 1
   { 0x1f, 21, NULL, NULL, PPC_OPERAND_NONZERO },
 
 #define SVyd SVxd + 1
@@ -3959,13 +4018,16 @@ const struct powerpc_operand powerpc_operands[] =
   { 0x1f, 11, NULL, NULL, PPC_OPERAND_NONZERO },
 
 #define SVrm SVzd + 1
-  { 0xf, 7, NULL, NULL, 0 },
+  { 0xf, 7, insert_SVrm, extract_SVrm, 0 },
 
 #define mi1 SVrm + 1
   { 0x3, 17, NULL, NULL, 0 },
 
 #define mi2 mi1 + 1
   { 0x3, 15, NULL, NULL, 0 },
+
+#define SVo mi2 + 1
+  { 0xf, 22, NULL, NULL, 0 },
 };
 
 const unsigned int num_powerpc_operands = ARRAY_SIZE (powerpc_operands);
@@ -4864,6 +4926,13 @@ const unsigned int num_powerpc_operands = ARRAY_SIZE (powerpc_operands);
    | (((uint64_t)(xop)) & 0x3f))
 #define SVM_MASK       SVM (0x3f, 0x3f)
 
+/* An SVM2 form instruction. */
+#define SVM2(op, xop)                          \
+  (OP (op)                                     \
+   | (((((uint64_t)(xop)) >> 6) & 0x7) << 8)   \
+   | (((uint64_t)(xop)) & 0x3f))
+#define SVM2_MASK      SVM2 (0x3f, 0x1ff)
+
 /* An SVRM form instruction. */
 #define SVRM(op, xop)                          \
   (OP (op)                                     \
@@ -6950,6 +7019,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 {"svstep",     SVL(22,19,0),   SVL_MASK,       SVP64,  PPCVLE, {RT, SVi, vf}},
 {"svstep.",    SVL(22,19,1),   SVL_MASK,       SVP64,  PPCVLE, {RT, SVi, vf}},
 
+{"svshape2",   SVM2(22,281),   SVM2_MASK,      SVP64,  PPCVLE, {SVo, yx10, rmm, SVd, sk, mm}},
 {"svshape",    SVM(22,25),     SVM_MASK,       SVP64,  PPCVLE, {SVxd, SVyd, SVzd, SVrm, vf}},
 
 {"setvl",      SVL(22,27,0),   SVL_MASK,       SVP64,  PPCVLE, {RT, RA, SVi, vf, vs, ms}},