]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - opcodes/i386-gen.c
2.41 Release sources
[thirdparty/binutils-gdb.git] / opcodes / i386-gen.c
index 112e48ebcf0b66ea6a5803df01f6ac530017c1b1..1db555d86156770917652fe16556d541e7b2fce2 100644 (file)
@@ -28,9 +28,6 @@
 
 #include "i386-opc.h"
 
-#include <libintl.h>
-#define _(String) gettext (String)
-
 /* Build-time checks are preferrable over runtime ones.  Use this construct
    in preference where possible.  */
 #define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); }))
@@ -64,13 +61,13 @@ static const dependency isa_dependencies[] =
   { "P4",
     "P3|Clflush|SSE2" },
   { "NOCONA",
-    "GENERIC64|FISTTP|SSE3|CX16" },
+    "GENERIC64|FISTTP|SSE3|MONITOR|CX16" },
   { "CORE",
-    "P4|FISTTP|SSE3|CX16" },
+    "P4|FISTTP|SSE3|MONITOR|CX16" },
   { "CORE2",
     "NOCONA|SSSE3" },
   { "COREI7",
-    "CORE2|SSE4_2|Rdtscp" },
+    "CORE2|SSE4_2|Rdtscp|LAHF_SAHF" },
   { "K6",
     "186|286|386|486|586|SYSCALL|387|MMX" },
   { "K6_2",
@@ -80,9 +77,9 @@ static const dependency isa_dependencies[] =
   { "K8",
     "ATHLON|Rdtscp|SSE2|LM" },
   { "AMDFAM10",
-    "K8|FISTTP|SSE4A|ABM" },
+    "K8|FISTTP|SSE4A|ABM|MONITOR" },
   { "BDVER1",
-    "GENERIC64|FISTTP|Rdtscp|CX16|XOP|ABM|LWP|SVME|AES|PCLMUL|PRFCHW" },
+    "GENERIC64|FISTTP|Rdtscp|MONITOR|CX16|LAHF_SAHF|XOP|ABM|LWP|SVME|AES|PCLMUL|PRFCHW" },
   { "BDVER2",
     "BDVER1|FMA|BMI|TBM|F16C" },
   { "BDVER3",
@@ -90,7 +87,7 @@ static const dependency isa_dependencies[] =
   { "BDVER4",
     "BDVER3|AVX2|Movbe|BMI2|RdRnd|MWAITX" },
   { "ZNVER1",
-    "GENERIC64|FISTTP|Rdtscp|CX16|AVX2|SSE4A|ABM|SVME|AES|PCLMUL|PRFCHW|FMA|BMI|F16C|Xsaveopt|FSGSBase|Movbe|BMI2|RdRnd|ADX|RdSeed|SMAP|SHA|XSAVEC|XSAVES|ClflushOpt|CLZERO|MWAITX" },
+    "GENERIC64|FISTTP|Rdtscp|MONITOR|CX16|LAHF_SAHF|AVX2|SSE4A|ABM|SVME|AES|PCLMUL|PRFCHW|FMA|BMI|F16C|Xsaveopt|FSGSBase|Movbe|BMI2|RdRnd|ADX|RdSeed|SMAP|SHA|XSAVEC|XSAVES|ClflushOpt|CLZERO|MWAITX" },
   { "ZNVER2",
     "ZNVER1|CLWB|RDPID|RDPRU|MCOMMIT|WBNOINVD" },
   { "ZNVER3",
@@ -98,7 +95,7 @@ static const dependency isa_dependencies[] =
   { "ZNVER4",
     "ZNVER3|AVX512F|AVX512DQ|AVX512IFMA|AVX512CD|AVX512BW|AVX512VL|AVX512_BF16|AVX512VBMI|AVX512_VBMI2|AVX512_VNNI|AVX512_BITALG|AVX512_VPOPCNTDQ|GFNI|RMPQUERY" },
   { "BTVER1",
-    "GENERIC64|FISTTP|CX16|Rdtscp|SSSE3|SSE4A|ABM|PRFCHW|CX16|Clflush|FISTTP|SVME" },
+    "GENERIC64|FISTTP|MONITOR|CX16|LAHF_SAHF|Rdtscp|SSSE3|SSE4A|ABM|PRFCHW|Clflush|FISTTP|SVME" },
   { "BTVER2",
     "BTVER1|AVX|BMI|F16C|AES|PCLMUL|Movbe|Xsaveopt|PRFCHW" },
   { "286",
@@ -167,6 +164,8 @@ static const dependency isa_dependencies[] =
     "AVX2" },
   { "AVX_NE_CONVERT",
     "AVX2" },
+  { "FRED",
+    "LKGS" },
   { "AVX512F",
     "AVX2" },
   { "AVX512CD",
@@ -243,6 +242,8 @@ static const dependency isa_dependencies[] =
     "AMX_TILE" },
   { "AMX_FP16",
     "AMX_TILE" },
+  { "AMX_COMPLEX",
+    "AMX_TILE" },
   { "KL",
     "SSE2" },
   { "WIDEKL",
@@ -316,6 +317,7 @@ static bitfield cpu_flags[] =
   BITFIELD (LM),
   BITFIELD (Movbe),
   BITFIELD (CX16),
+  BITFIELD (LAHF_SAHF),
   BITFIELD (EPT),
   BITFIELD (Rdtscp),
   BITFIELD (FSGSBase),
@@ -324,6 +326,7 @@ static bitfield cpu_flags[] =
   BITFIELD (BMI2),
   BITFIELD (LZCNT),
   BITFIELD (POPCNT),
+  BITFIELD (MONITOR),
   BITFIELD (HLE),
   BITFIELD (RTM),
   BITFIELD (INVPCID),
@@ -361,6 +364,8 @@ static bitfield cpu_flags[] =
   BITFIELD (MSRLIST),
   BITFIELD (AVX_NE_CONVERT),
   BITFIELD (RAO_INT),
+  BITFIELD (FRED),
+  BITFIELD (LKGS),
   BITFIELD (MWAITX),
   BITFIELD (CLZERO),
   BITFIELD (OSPKE),
@@ -379,6 +384,7 @@ static bitfield cpu_flags[] =
   BITFIELD (AMX_INT8),
   BITFIELD (AMX_BF16),
   BITFIELD (AMX_FP16),
+  BITFIELD (AMX_COMPLEX),
   BITFIELD (AMX_TILE),
   BITFIELD (MOVDIRI),
   BITFIELD (MOVDIR64B),
@@ -433,9 +439,7 @@ static bitfield opcode_modifiers[] =
   BITFIELD (Vex),
   BITFIELD (VexVVVV),
   BITFIELD (VexW),
-  BITFIELD (OpcodeSpace),
   BITFIELD (OpcodePrefix),
-  BITFIELD (VexSources),
   BITFIELD (SIB),
   BITFIELD (SSE2AVX),
   BITFIELD (EVex),
@@ -557,7 +561,7 @@ fail (const char *message, ...)
   va_list args;
 
   va_start (args, message);
-  fprintf (stderr, _("%s: error: "), program_name);
+  fprintf (stderr, "%s: error: ", program_name);
   vfprintf (stderr, message, args);
   va_end (args);
   xexit (1);
@@ -683,9 +687,9 @@ set_bitfield (char *f, bitfield *array, int value,
     }
 
   if (lineno != -1)
-    fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
+    fail ("%s: %d: unknown bitfield: %s\n", filename, lineno, f);
   else
-    fail (_("unknown bitfield: %s\n"), f);
+    fail ("unknown bitfield: %s\n", f);
 }
 
 static void
@@ -752,7 +756,7 @@ add_isa_dependencies (bitfield *flags, const char *f, int value,
       }
 
   if (!is_isa)
-    fail (_("unknown bitfield: %s\n"), f);
+    fail ("unknown bitfield: %s\n", f);
 }
 
 static void
@@ -817,7 +821,7 @@ process_i386_cpu_flag (FILE *table, char *flag,
          last -= 1;
          next = flag + 2;
          if (*last != ')')
-           fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
+           fail ("%s: %d: missing `)' in bitfield: %s\n", filename,
                  lineno, flag);
          *last = '\0';
        }
@@ -917,7 +921,7 @@ get_element_size (char **opnd, int lineno)
   while (full != NULL && strstr(full, "BaseIndex") == NULL)
     full = *++opnd;
   if (full == NULL)
-    fail (_("%s: %d: no memory operand\n"), filename, lineno);
+    fail ("%s: %d: no memory operand\n", filename, lineno);
 
   op = xstrdup (full);
   last = op + strlen (op);
@@ -953,17 +957,31 @@ get_element_size (char **opnd, int lineno)
   free (op);
 
   if (elem_size == INT_MAX)
-    fail (_("%s: %d: unknown element size: %s\n"), filename, lineno, full);
+    fail ("%s: %d: unknown element size: %s\n", filename, lineno, full);
 
   return elem_size;
 }
 
 static void
 process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
-                             unsigned int prefix, char **opnd, int lineno)
+                             unsigned int prefix, const char *extension_opcode,
+                             char **opnd, int lineno)
 {
   char *str, *next, *last;
   bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
+  static const char *const spaces[] = {
+#define SPACE(n) [SPACE_##n] = #n
+    SPACE(BASE),
+    SPACE(0F),
+    SPACE(0F38),
+    SPACE(0F3A),
+    SPACE(EVEXMAP5),
+    SPACE(EVEXMAP6),
+    SPACE(XOP08),
+    SPACE(XOP09),
+    SPACE(XOP0A),
+#undef SPACE
+  };
 
   active_isstring = 0;
 
@@ -981,6 +999,34 @@ process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
          if (str)
            {
              int val = 1;
+
+             if (strncmp(str, "OpcodeSpace", 11) == 0)
+               {
+                 char *end;
+
+                 if (str[11] != '=')
+                   fail ("%s:%d: Missing value for `OpcodeSpace'\n",
+                         filename, lineno);
+
+                 val = strtol (str + 12, &end, 0);
+                 if (*end)
+                   fail ("%s:%d: Bogus value `%s' for `OpcodeSpace'\n",
+                         filename, lineno, end);
+
+                 if (space)
+                   {
+                     if (val != space)
+                       fail ("%s:%d: Conflicting opcode space specifications\n",
+                             filename, lineno);
+                     fprintf (stderr,
+                              "%s:%d: Warning: redundant opcode space specification\n",
+                              filename, lineno);
+                   }
+
+                 space = val;
+                 continue;
+               }
+
              if (strcasecmp(str, "Broadcast") == 0)
                val = get_element_size (opnd, lineno) + BYTE_BROADCAST;
              else if (strcasecmp(str, "Disp8MemShift") == 0)
@@ -1005,29 +1051,16 @@ process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
            }
        }
 
-      if (space)
-       {
-         if (!modifiers[OpcodeSpace].value)
-           modifiers[OpcodeSpace].value = space;
-         else if (modifiers[OpcodeSpace].value != space)
-           fail (_("%s:%d: Conflicting opcode space specifications\n"),
-                 filename, lineno);
-         else
-           fprintf (stderr,
-                    _("%s:%d: Warning: redundant opcode space specification\n"),
-                    filename, lineno);
-       }
-
       if (prefix)
        {
          if (!modifiers[OpcodePrefix].value)
            modifiers[OpcodePrefix].value = prefix;
          else if (modifiers[OpcodePrefix].value != prefix)
-           fail (_("%s:%d: Conflicting prefix specifications\n"),
+           fail ("%s:%d: Conflicting prefix specifications\n",
                  filename, lineno);
          else
            fprintf (stderr,
-                    _("%s:%d: Warning: redundant prefix specification\n"),
+                    "%s:%d: Warning: redundant prefix specification\n",
                     filename, lineno);
        }
 
@@ -1041,6 +1074,13 @@ process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
                 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
                 filename, lineno);
     }
+
+  if (space >= ARRAY_SIZE (spaces) || !spaces[space])
+    fail ("%s:%d: Unknown opcode space %u\n", filename, lineno, space);
+
+  fprintf (table, " SPACE_%s, %s,\n",
+          spaces[space], extension_opcode ? extension_opcode : "None");
+
   output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
 }
 
@@ -1250,23 +1290,22 @@ output_i386_opcode (FILE *table, const char *name, char *str,
        }
 
       if (space != SPACE_0F && --length == 1)
-       fail (_("%s:%d: %s: unrecognized opcode encoding space\n"),
+       fail ("%s:%d: %s: unrecognized opcode encoding space\n",
              filename, lineno, name);
       opcode &= (1ULL << (8 * --length)) - 1;
     }
 
   if (length > 2)
-    fail (_("%s:%d: %s: residual opcode (0x%0*llx) too large\n"),
+    fail ("%s:%d: %s: residual opcode (0x%0*llx) too large\n",
          filename, lineno, name, 2 * length, opcode);
 
   ident = mkident (name);
-  fprintf (table, "  { MN_%s, 0x%0*llx%s, %lu, %s,\n",
-          ident, 2 * (int)length, opcode, end, i,
-          extension_opcode ? extension_opcode : "None");
+  fprintf (table, "  { MN_%s, 0x%0*llx%s, %u,",
+          ident, 2 * (int)length, opcode, end, i);
   free (ident);
 
   process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
-                               operand_types, lineno);
+                               extension_opcode, operand_types, lineno);
 
   process_i386_cpu_flag (table, cpu_flags, NULL, ",", "    ", lineno, CpuMax);
 
@@ -1293,10 +1332,13 @@ output_i386_opcode (FILE *table, const char *name, char *str,
 
 struct opcode_hash_entry
 {
-  struct opcode_hash_entry *next;
-  char *name;
-  char *opcode;
-  int lineno;
+  const char *name;
+  struct opcode_entry
+  {
+    struct opcode_entry *next;
+    char *opcode;
+    int lineno;
+  } entry;
 };
 
 /* Calculate the hash value of an opcode hash entry P.  */
@@ -1432,7 +1474,8 @@ expand_templates (char *name, const char *str, htab_t opcode_hash_table,
 {
   static unsigned int idx, opcode_array_size;
   struct opcode_hash_entry **opcode_array = *opcode_array_p;
-  struct opcode_hash_entry **hash_slot, **entry;
+  struct opcode_hash_entry **hash_slot;
+  struct opcode_entry *entry;
   char *ptr1 = strchr(name, '<'), *ptr2;
 
   if (ptr1 == NULL)
@@ -1458,26 +1501,25 @@ expand_templates (char *name, const char *str, htab_t opcode_hash_table,
 
          opcode_array[idx] = (struct opcode_hash_entry *)
            xmalloc (sizeof (struct opcode_hash_entry));
-         opcode_array[idx]->next = NULL;
          opcode_array[idx]->name = xstrdup (name);
-         opcode_array[idx]->opcode = xstrdup (str);
-         opcode_array[idx]->lineno = lineno;
          *hash_slot = opcode_array[idx];
+         entry = &opcode_array[idx]->entry;
          idx++;
        }
       else
        {
          /* Append it to the existing one.  */
-         entry = hash_slot;
-         while ((*entry) != NULL)
-           entry = &(*entry)->next;
-         *entry = (struct opcode_hash_entry *)
-           xmalloc (sizeof (struct opcode_hash_entry));
-         (*entry)->next = NULL;
-         (*entry)->name = (*hash_slot)->name;
-         (*entry)->opcode = xstrdup (str);
-         (*entry)->lineno = lineno;
+         struct opcode_entry **entryp = &(*hash_slot)->entry.next;
+
+         while (*entryp != NULL)
+           entryp = &(*entryp)->next;
+         entry = (struct opcode_entry *)xmalloc (sizeof (struct opcode_entry));
+         *entryp = entry;
        }
+
+      entry->next = NULL;
+      entry->opcode = xstrdup (str);
+      entry->lineno = lineno;
     }
   else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
     fail ("%s: %d: missing '>'\n", filename, lineno);
@@ -1599,7 +1641,7 @@ process_i386_opcodes (FILE *table)
   char buf[2048];
   unsigned int i, j, nr, offs;
   size_t l;
-  char *str, *p, *last, *name;
+  char *str, *p, *last;
   htab_t opcode_hash_table;
   struct opcode_hash_entry **opcode_array = NULL;
   int lineno = 0, marker = 0;
@@ -1619,6 +1661,8 @@ process_i386_opcodes (FILE *table)
   /* Put everything on opcode array.  */
   while (!feof (fp))
     {
+      char *name;
+
       if (fgets (buf, sizeof (buf), fp) == NULL)
        break;
 
@@ -1643,7 +1687,7 @@ process_i386_opcodes (FILE *table)
          if (!j || buf[j - 1] != '+')
            break;
          if (j >= sizeof (buf) - 1)
-           fail (_("%s: %d: (continued) line too long\n"), filename, lineno);
+           fail ("%s: %d: (continued) line too long\n", filename, lineno);
 
          if (fgets (buf + j - 1, sizeof (buf) - j + 1, fp) == NULL)
            {
@@ -1700,11 +1744,11 @@ process_i386_opcodes (FILE *table)
   /* Process opcode array.  */
   for (j = 0; j < i; j++)
     {
-      struct opcode_hash_entry *next;
+      const char *name = opcode_array[j]->name;
+      struct opcode_entry *next;
 
-      for (next = opcode_array[j]; next; next = next->next)
+      for (next = &opcode_array[j]->entry; next; next = next->next)
        {
-         name = next->name;
          str = next->opcode;
          lineno = next->lineno;
          last = str + strlen (str);
@@ -1723,7 +1767,7 @@ process_i386_opcodes (FILE *table)
 
   for (nr = j = 0; j < i; j++)
     {
-      struct opcode_hash_entry *next = opcode_array[j];
+      struct opcode_entry *next = &opcode_array[j]->entry;
 
       do
        {
@@ -1741,7 +1785,7 @@ process_i386_opcodes (FILE *table)
 
   fp = fopen ("i386-mnem.h", "w");
   if (fp == NULL)
-    fail (_("can't create i386-mnem.h, errno = %s\n"),
+    fail ("can't create i386-mnem.h, errno = %s\n",
          xstrerror (errno));
 
   process_copyright (fp);
@@ -1753,10 +1797,10 @@ process_i386_opcodes (FILE *table)
   str = NULL;
   for (l = strlen (opcode_array[offs = j = 0]->name); j < i; j++)
     {
+      const char *name = opcode_array[j]->name;
       const char *next = NULL;
       size_t l1 = j + 1 < i ? strlen(next = opcode_array[j + 1]->name) : 0;
 
-      name = opcode_array[j]->name;
       if (str == NULL)
        str = mkident (name);
       if (l < l1 && !strcmp(name, next + l1 - l))
@@ -1777,6 +1821,9 @@ process_i386_opcodes (FILE *table)
       l = l1;
     }
 
+  fprintf (table, "  \"\\0\"\".insn\"\n");
+  fprintf (fp, "#define MN__insn %#x\n", offs + 1);
+
   fprintf (table, ";\n");
 
   fclose (fp);
@@ -1795,7 +1842,7 @@ process_i386_registers (FILE *table)
   filename = "i386-reg.tbl";
   fp = fopen (filename, "r");
   if (fp == NULL)
-    fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
+    fail ("can't find i386-reg.tbl for reading, errno = %s\n",
          xstrerror (errno));
 
   fprintf (table, "\n/* i386 register table.  */\n\n");
@@ -1872,7 +1919,7 @@ process_i386_initializers (void)
   FILE *fp = fopen ("i386-init.h", "w");
 
   if (fp == NULL)
-    fail (_("can't create i386-init.h, errno = %s\n"),
+    fail ("can't create i386-init.h, errno = %s\n",
          xstrerror (errno));
 
   process_copyright (fp);
@@ -1987,7 +2034,7 @@ main (int argc, char **argv)
 
   if (srcdir != NULL)
     if (chdir (srcdir) != 0)
-      fail (_("unable to change directory to \"%s\", errno = %s\n"),
+      fail ("unable to change directory to \"%s\", errno = %s\n",
            srcdir, xstrerror (errno));
 
   /* cpu_flags isn't sorted by position.  */
@@ -2001,16 +2048,16 @@ main (int argc, char **argv)
   static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
 
   if ((cpumax - 1) != CpuMax)
-    fail (_("CpuMax != %d!\n"), cpumax);
+    fail ("CpuMax != %d!\n", cpumax);
 #else
   static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
 
   if (cpumax != CpuMax)
-    fail (_("CpuMax != %d!\n"), cpumax);
+    fail ("CpuMax != %d!\n", cpumax);
 
   c = CpuNumOfBits - CpuMax - 1;
   if (c)
-    fail (_("%d unused bits in i386_cpu_flags.\n"), c);
+    fail ("%d unused bits in i386_cpu_flags.\n", c);
 #endif
 
   static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
@@ -2025,7 +2072,7 @@ main (int argc, char **argv)
 
   c = OTNumOfBits - OTNum;
   if (c)
-    fail (_("%d unused bits in i386_operand_type.\n"), c);
+    fail ("%d unused bits in i386_operand_type.\n", c);
 #endif
 
   qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
@@ -2039,7 +2086,7 @@ main (int argc, char **argv)
 
   table = fopen ("i386-tbl.h", "w");
   if (table == NULL)
-    fail (_("can't create i386-tbl.h, errno = %s\n"),
+    fail ("can't create i386-tbl.h, errno = %s\n",
          xstrerror (errno));
 
   process_copyright (table);