ppc/svp64: setup SVP64 opcodes table
authorDmitry Selyutin <ghostmansd@gmail.com>
Sun, 28 May 2023 22:04:56 +0000 (01:04 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Tue, 14 Nov 2023 19:53:34 +0000 (22:53 +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 5386d2ed87133b95b8ece4b1cc57c70ce2bd6f54..19a852f3aab7163ebed4910279aae44eb16d0f09 100644 (file)
@@ -1871,6 +1871,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