ppc/svp64: setup SVP64 opcodes table
authorDmitry Selyutin <ghostmansd@gmail.com>
Sat, 18 Jun 2022 20:20:11 +0000 (23:20 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Thu, 22 Sep 2022 18:35:36 +0000 (21:35 +0300)
gas/config/tc-ppc-svp64.c
gas/config/tc-ppc.c

index f07115df3ced31e3bec3f3c500175f7bde759b48..9436c79afa678b95b74fcbdcd0ea59085737f695 100644 (file)
    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
    02110-1301, USA.  */
 
+#include <setjmp.h>
+
+struct svp64_ctx {
+  const struct svp64_desc *desc;
+};
+
+static jmp_buf svp64_exception;
+
+#define svp64_raise(...)                \
+  do {                                  \
+    as_bad (__VA_ARGS__);               \
+    longjmp (svp64_exception, 1);       \
+  } while (0)
+
+#define svp64_raise_if(COND, ...)       \
+  do {                                  \
+    if (!!(COND))                       \
+      svp64_raise (__VA_ARGS__);        \
+  } while (0)
+
+static htab_t svp64_hash;
+
+static void
+svp64_setup_records (void)
+{
+  const struct svp64_record *record;
+  const struct svp64_record *records_end;
+
+  svp64_hash = str_htab_create ();
+
+  records_end = (svp64_records + svp64_nr_records);
+  for (record = svp64_records; record < records_end; ++record)
+    {
+      const struct svp64_desc *desc = &record->desc;
+      const char *name = (record->name + (sizeof ("sv.") - 1));
+
+      if (str_hash_insert (svp64_hash, name, desc, 0) != NULL)
+        as_fatal (_("duplicate %s"), name);
+    }
+}
+
+static char *
+svp64_decode (char *str, struct svp64_ctx *svp64)
+{
+  str += (sizeof ("sv.") - 1);
+  svp64->desc = (const struct svp64_desc *) str_hash_find (svp64_hash, str);
+  if (!svp64->desc)
+    svp64_raise (_("unrecognized opcode: `%s'"), str);
+
+  return str;
+}
+
 static void
 svp64_assemble (char *str)
 {
-  as_warn (_("opcode ignored"));
+  struct svp64_ctx svp64;
+
+  if (setjmp (svp64_exception) != 0)
+    return;
+
+  memset (&svp64, 0, sizeof (svp64));
+
+  svp64_decode (str, &svp64);
+
+  as_warn (_("opcode ignored (desc=%p)"), svp64.desc);
   memcpy (str, "nop", sizeof ("nop"));
   md_assemble (str);
 }
index e7bcde73417c4c240d352413037692335fccd152..1623f4fa5d362f302de4cc43f470a2a8f42e9b8d 100644 (file)
@@ -1849,6 +1849,9 @@ ppc_setup_opcodes (void)
 
   if (bad_insn)
     abort ();
+
+  if ((ppc_cpu & PPC_OPCODE_SVP64) == PPC_OPCODE_SVP64)
+    svp64_setup_records ();
 }
 
 /* This function is called when the assembler starts up.  It is called