ppc/svp64: setup SVP64 opcodes table
authorDmitry Selyutin <ghostmansd@gmail.com>
Tue, 11 Apr 2023 18:27:24 +0000 (21:27 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Wed, 26 Apr 2023 16:35:08 +0000 (19: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 b762706c95b8d4afb5434504655fa540e2a8168a..d62e671ac525f97050b33698909cf29886650265 100644 (file)
@@ -1867,6 +1867,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