introduce svp64 prefixing libresoc-svp64-gas lxo/WIP-svp64-gas
authorAlexandre Oliva <oliva@libre-soc.org>
Sun, 14 Mar 2021 18:34:16 +0000 (15:34 -0300)
committerAlexandre Oliva <oliva@gnu.org>
Sun, 14 Mar 2021 18:34:16 +0000 (15:34 -0300)
This (very incomplete) patch introduces svp64 prefixing support in the
GNU assembler.

The idea is to mark opcodes (in .../ppc-opc.c) that can be prefixed
with XT2 or XT3, and svp64 opcodes that aren't prefixed (setvl) with
OPC.

???  I'm not sure XT2 and XT3 are enough, though.  We might need to
know the RM-* encoding to be able to parse the prefixed opcode.
That's where I got stuck a few weeks ago.

gas/config/tc-ppc.c
include/opcode/ppc.h

index 95000fd28a9fbaec58a300c0da69d5f7e095e04b..cd0ba56ddffa728f90f2a9b1d299990b435645ad 100644 (file)
@@ -3106,12 +3106,29 @@ parse_tls_arg (char **str, const expressionS *exp, struct ppc_fixup *tls_fix)
 }
 #endif
 
+/* Parse svp64 extra operands given to the MACRO opcode starting at S,
+   then its operands, and assemble the svp64 macro.  */
+
+static void
+parse_svp64_macro (char *s, struct powerpc_macro *macro)
+{
+  as_bad (_("`sv.'-prefixed macros are not supported"));
+}
+
+/* Parse extra operands at S, and initialize SVP64_PREFIX with them.  */
+static void
+parse_svp64_operands (char **s, uint32_t *svp64_prefix, ppc_cpu_t flags)
+{
+  *svp64_prefix = (uint32_t)1 << 26;
+  /* Do nothing for now.  */
+}
+
 /* This routine is called for each instruction to be assembled.  */
 
 void
 md_assemble (char *str)
 {
-  char *s;
+  char *s, *spfx = str;
   const struct powerpc_opcode *opcode;
   uint64_t insn;
   const unsigned char *opindex_ptr;
@@ -3123,10 +3140,20 @@ md_assemble (char *str)
   int addr_mask;
   int i;
   unsigned int insn_length;
+  bfd_boolean svp64 = FALSE;
+  char opc_trailer;
+  uint32_t svp64_prefix;
+
+  if (strncmp (str, "sv.", 3) == 0)
+    {
+      svp64 = TRUE;
+      str += 3;
+    }
 
   /* Get the opcode.  */
-  for (s = str; *s != '\0' && ! ISSPACE (*s); s++)
+  for (s = str; *s != '\0' && ! ISSPACE (*s) && (!svp64 || *s != '/'); s++)
     ;
+  opc_trailer = *s;
   if (*s != '\0')
     *s++ = '\0';
 
@@ -3139,7 +3166,14 @@ md_assemble (char *str)
       macro = (const struct powerpc_macro *) str_hash_find (ppc_macro_hash,
                                                            str);
       if (macro == (const struct powerpc_macro *) NULL)
-       as_bad (_("unrecognized opcode: `%s'"), str);
+       as_bad (_("unrecognized opcode: `%s'"), spfx);
+      else if (svp64 && !(macro->flags & PPC_OPCODE_SVP64PFX))
+       as_bad (_("opcode is not `sv.'-prefixable: `%s'"), str);
+      else if (svp64)
+       {
+         *--s = opc_trailer;
+         ppc_svp64_macro (s, macro);
+       }
       else
        ppc_macro (s, macro);
 
@@ -3158,6 +3192,20 @@ md_assemble (char *str)
       return;
     }
 
+  if (svp64)
+    {
+      if (!(opcode->flags & PPC_OPCODE_SVP64PFX))
+       {
+         as_bad (_("opcode is not `sv.'-prefixable: `%s'"), str);
+         ppc_clear_labels ();
+         return;
+       }
+
+      *--s = opc_trailer;
+      parse_svp64_operands (&s, &svp64_prefix,
+                           opcode->flags & PPC_OPCODE_SVP64MSK);
+    }
+
   str = s;
   while (ISSPACE (*str))
     ++str;
index a5ee560aa17a4c80e64f41cfce8763d138fda21d..8c356b1ff4c0e82d7dd8b367cb27559707fd14dd 100644 (file)
@@ -231,6 +231,22 @@ extern const unsigned int spe2_num_opcodes;
 /* Opcode is only supported by power10 architecture.  */
 #define PPC_OPCODE_POWER10  0x400000000000ull
 
+/* Opcode is a standalone, unprefixed SVP64 opcode (e.g. setvl).  */
+#define PPC_OPCODE_SVP64OPC 0x800000000000ull
+
+/* Opcode is SVP64-prefixed, with EXTRA2 encoding.  */
+#define PPC_OPCODE_SVP64XT2 0x1000000000000ull
+
+/* Opcode is SVP64-prefixed, with EXTRA3 encoding.  */
+#define PPC_OPCODE_SVP64XT3 0x1800000000000ull
+
+/* Opcode is SVP64-prefixed, with either EXTRA encoding.  */
+#define PPC_OPCODE_SVP64PFX 0x1000000000000ull
+
+/* Opcode is SVP64-related, prefixed or standalone.  */
+#define PPC_OPCODE_SVP64MSK 0x1800000000000ull
+
+
 /* A macro to extract the major opcode from an instruction.  */
 #define PPC_OP(i) (((i) >> 26) & 0x3f)