Home | History | Annotate | Line # | Download | only in opcodes
s390-mkopc.c revision 1.12
      1   1.1  christos /* s390-mkopc.c -- Generates opcode table out of s390-opc.txt
      2  1.11  christos    Copyright (C) 2000-2024 Free Software Foundation, Inc.
      3   1.1  christos    Contributed by Martin Schwidefsky (schwidefsky (at) de.ibm.com).
      4   1.1  christos 
      5   1.1  christos    This file is part of the GNU opcodes library.
      6   1.1  christos 
      7   1.1  christos    This library is free software; you can redistribute it and/or modify
      8   1.1  christos    it under the terms of the GNU General Public License as published by
      9   1.1  christos    the Free Software Foundation; either version 3, or (at your option)
     10   1.1  christos    any later version.
     11   1.1  christos 
     12   1.1  christos    It is distributed in the hope that it will be useful, but WITHOUT
     13   1.1  christos    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     14   1.1  christos    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     15   1.1  christos    License for more details.
     16   1.1  christos 
     17   1.1  christos    You should have received a copy of the GNU General Public License
     18   1.1  christos    along with this file; see the file COPYING.  If not, write to the
     19   1.1  christos    Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
     20   1.1  christos    MA 02110-1301, USA.  */
     21   1.1  christos 
     22   1.1  christos #include <stdio.h>
     23   1.1  christos #include <stdlib.h>
     24  1.11  christos #include <stdarg.h>
     25   1.1  christos #include <string.h>
     26   1.5  christos #include "opcode/s390.h"
     27   1.1  christos 
     28  1.11  christos #define STRINGIFY(x) _STRINGIFY(x)
     29  1.11  christos #define _STRINGIFY(x) #x
     30  1.11  christos 
     31  1.11  christos /* Length of strings without terminating '\0' character.  */
     32  1.11  christos #define MAX_OPCODE_LEN 15
     33  1.11  christos #define MAX_MNEMONIC_LEN 15
     34  1.11  christos #define MAX_FORMAT_LEN 15
     35  1.11  christos #define MAX_DESCRIPTION_LEN 127
     36  1.11  christos 
     37  1.11  christos #define MAX_CPU_LEN 15
     38  1.11  christos #define MAX_MODES_LEN 15
     39  1.11  christos #define MAX_FLAGS_LEN 79
     40  1.11  christos 
     41  1.11  christos /* Return code.  */
     42  1.11  christos int return_code = EXIT_SUCCESS;
     43  1.11  christos 
     44  1.11  christos /* Helper to print an error message and set the return code.  */
     45  1.11  christos static void __attribute__ ((format (printf, 1, 2)))
     46  1.11  christos print_error (const char *fmt, ...)
     47  1.11  christos {
     48  1.11  christos   va_list ap;
     49  1.11  christos 
     50  1.11  christos   va_start(ap, fmt);
     51  1.11  christos   fprintf(stderr, "Error: ");
     52  1.11  christos   vfprintf(stderr, fmt, ap);
     53  1.11  christos   va_end(ap);
     54  1.11  christos 
     55  1.11  christos   return_code = EXIT_FAILURE;
     56  1.11  christos }
     57  1.11  christos 
     58   1.1  christos struct op_struct
     59   1.1  christos   {
     60  1.11  christos     char  opcode[MAX_OPCODE_LEN + 1];
     61  1.11  christos     char  mnemonic[MAX_MNEMONIC_LEN + 1];
     62  1.11  christos     char  format[MAX_FORMAT_LEN + 1];
     63   1.1  christos     int   mode_bits;
     64   1.1  christos     int   min_cpu;
     65   1.5  christos     int   flags;
     66  1.11  christos     char  description[MAX_DESCRIPTION_LEN + 1];
     67   1.1  christos 
     68   1.1  christos     unsigned long long sort_value;
     69   1.1  christos     int   no_nibbles;
     70   1.1  christos   };
     71   1.1  christos 
     72   1.1  christos struct op_struct *op_array;
     73   1.1  christos int max_ops;
     74   1.1  christos int no_ops;
     75   1.1  christos 
     76   1.1  christos static void
     77   1.1  christos createTable (void)
     78   1.1  christos {
     79   1.1  christos   max_ops = 256;
     80   1.1  christos   op_array = malloc (max_ops * sizeof (struct op_struct));
     81   1.1  christos   no_ops = 0;
     82   1.1  christos }
     83   1.1  christos 
     84   1.1  christos /* `insertOpcode': insert an op_struct into sorted opcode array.  */
     85   1.1  christos 
     86   1.1  christos static void
     87   1.1  christos insertOpcode (char *opcode, char *mnemonic, char *format,
     88  1.11  christos 	      int min_cpu, int mode_bits, int flags, char* description)
     89   1.1  christos {
     90   1.1  christos   char *str;
     91   1.1  christos   unsigned long long sort_value;
     92   1.1  christos   int no_nibbles;
     93   1.1  christos   int ix, k;
     94   1.1  christos 
     95   1.1  christos   while (no_ops >= max_ops)
     96   1.1  christos     {
     97   1.1  christos       max_ops = max_ops * 2;
     98   1.1  christos       op_array = realloc (op_array, max_ops * sizeof (struct op_struct));
     99   1.1  christos     }
    100   1.1  christos 
    101   1.1  christos   sort_value = 0;
    102   1.1  christos   str = opcode;
    103   1.1  christos   for (ix = 0; ix < 16; ix++)
    104   1.1  christos     {
    105   1.1  christos       if (*str >= '0' && *str <= '9')
    106   1.1  christos 	sort_value = (sort_value << 4) + (*str - '0');
    107   1.1  christos       else if (*str >= 'a' && *str <= 'f')
    108   1.1  christos 	sort_value = (sort_value << 4) + (*str - 'a' + 10);
    109   1.1  christos       else if (*str >= 'A' && *str <= 'F')
    110   1.1  christos 	sort_value = (sort_value << 4) + (*str - 'A' + 10);
    111   1.1  christos       else if (*str == '?')
    112   1.1  christos 	sort_value <<= 4;
    113   1.1  christos       else
    114   1.1  christos 	break;
    115   1.1  christos       str ++;
    116   1.1  christos     }
    117   1.1  christos   sort_value <<= 4*(16 - ix);
    118   1.1  christos   sort_value += (min_cpu << 8) + mode_bits;
    119   1.1  christos   no_nibbles = ix;
    120   1.1  christos   for (ix = 0; ix < no_ops; ix++)
    121   1.1  christos     if (sort_value > op_array[ix].sort_value)
    122   1.1  christos       break;
    123   1.1  christos   for (k = no_ops; k > ix; k--)
    124   1.1  christos     op_array[k] = op_array[k-1];
    125  1.11  christos   strncpy (op_array[ix].opcode, opcode, MAX_OPCODE_LEN);
    126  1.11  christos   op_array[ix].opcode[MAX_OPCODE_LEN] = '\0';
    127  1.11  christos   strncpy (op_array[ix].mnemonic, mnemonic, MAX_MNEMONIC_LEN);
    128  1.11  christos   op_array[ix].mnemonic[MAX_MNEMONIC_LEN] = '\0';
    129  1.11  christos   strncpy (op_array[ix].format, format, MAX_FORMAT_LEN);
    130  1.11  christos   op_array[ix].format[MAX_FORMAT_LEN] = '\0';
    131   1.1  christos   op_array[ix].sort_value = sort_value;
    132   1.1  christos   op_array[ix].no_nibbles = no_nibbles;
    133   1.1  christos   op_array[ix].min_cpu = min_cpu;
    134   1.1  christos   op_array[ix].mode_bits = mode_bits;
    135   1.5  christos   op_array[ix].flags = flags;
    136  1.11  christos   strncpy (op_array[ix].description, description, MAX_DESCRIPTION_LEN);
    137  1.11  christos   op_array[ix].description[MAX_DESCRIPTION_LEN] = '\0';
    138   1.1  christos   no_ops++;
    139   1.1  christos }
    140   1.1  christos 
    141   1.1  christos struct s390_cond_ext_format
    142   1.1  christos {
    143   1.1  christos   char nibble;
    144   1.1  christos   char extension[4];
    145  1.11  christos   char *description_suffix;
    146  1.11  christos 
    147   1.1  christos };
    148   1.1  christos 
    149   1.1  christos /* The mnemonic extensions for conditional jumps used to replace
    150   1.1  christos    the '*' tag.  */
    151   1.1  christos #define NUM_COND_EXTENSIONS 20
    152   1.1  christos const struct s390_cond_ext_format s390_cond_extensions[NUM_COND_EXTENSIONS] =
    153  1.11  christos { { '1', "o", "on overflow / if ones" },	/* jump on overflow / if ones */
    154  1.11  christos   { '2', "h", "on A high" },			/* jump on A high */
    155  1.11  christos   { '2', "p", "on plus" },			/* jump on plus */
    156  1.11  christos   { '3', "nle", "on not low or equal" },	/* jump on not low or equal */
    157  1.11  christos   { '4', "l", "on A low" },			/* jump on A low */
    158  1.11  christos   { '4', "m", "on minus / if mixed" },		/* jump on minus / if mixed */
    159  1.11  christos   { '5', "nhe", "on not high or equal" },	/* jump on not high or equal */
    160  1.11  christos   { '6', "lh", "on low or high" },		/* jump on low or high */
    161  1.11  christos   { '7', "ne", "on A not equal B" },		/* jump on A not equal B */
    162  1.11  christos   { '7', "nz", "on not zero / if not zeros" },	/* jump on not zero / if not zeros */
    163  1.11  christos   { '8', "e", "on A equal B" },			/* jump on A equal B */
    164  1.11  christos   { '8', "z", "on zero / if zeros" },		/* jump on zero / if zeros */
    165  1.11  christos   { '9', "nlh", "on not low or high" },		/* jump on not low or high */
    166  1.11  christos   { 'a', "he", "on high or equal" },		/* jump on high or equal */
    167  1.11  christos   { 'b', "nl", "on A not low" },		/* jump on A not low */
    168  1.11  christos   { 'b', "nm", "on not minus / if not mixed" },	/* jump on not minus / if not mixed */
    169  1.11  christos   { 'c', "le", "on low or equal" },		/* jump on low or equal */
    170  1.11  christos   { 'd', "nh", "on A not high" },		/* jump on A not high */
    171  1.11  christos   { 'd', "np", "on not plus" },			/* jump on not plus */
    172  1.11  christos   { 'e', "no", "on not overflow / if not ones" },/* jump on not overflow / if not ones */
    173   1.1  christos };
    174   1.1  christos 
    175   1.1  christos /* The mnemonic extensions for conditional branches used to replace
    176   1.1  christos    the '$' tag.  */
    177   1.1  christos #define NUM_CRB_EXTENSIONS 12
    178   1.1  christos const struct s390_cond_ext_format s390_crb_extensions[NUM_CRB_EXTENSIONS] =
    179  1.11  christos { { '2', "h", "on A high" },			/* jump on A high */
    180  1.11  christos   { '2', "nle", "on not low or equal" },	/* jump on not low or equal */
    181  1.11  christos   { '4', "l", "on A low" },			/* jump on A low */
    182  1.11  christos   { '4', "nhe", "on not high or equal" },	/* jump on not high or equal */
    183  1.11  christos   { '6', "ne", "on A not equal B" },		/* jump on A not equal B */
    184  1.11  christos   { '6', "lh", "on low or high" },		/* jump on low or high */
    185  1.11  christos   { '8', "e", "on A equal B" },			/* jump on A equal B */
    186  1.11  christos   { '8', "nlh", "on not low or high" },		/* jump on not low or high */
    187  1.11  christos   { 'a', "nl", "on A not low" },		/* jump on A not low */
    188  1.11  christos   { 'a', "he", "on high or equal" },		/* jump on high or equal */
    189  1.11  christos   { 'c', "nh", "on A not high" },		/* jump on A not high */
    190  1.11  christos   { 'c', "le", "on low or equal" },		/* jump on low or equal */
    191   1.1  christos };
    192   1.1  christos 
    193   1.1  christos /* As with insertOpcode instructions are added to the sorted opcode
    194   1.1  christos    array.  Additionally mnemonics containing the '*<number>' tag are
    195   1.1  christos    expanded to the set of conditional instructions described by
    196   1.1  christos    s390_cond_extensions with the tag replaced by the respective
    197   1.1  christos    mnemonic extensions.  */
    198   1.1  christos 
    199   1.1  christos static void
    200   1.1  christos insertExpandedMnemonic (char *opcode, char *mnemonic, char *format,
    201  1.11  christos 			int min_cpu, int mode_bits, int flags, char *description)
    202   1.1  christos {
    203   1.1  christos   char *tag;
    204  1.11  christos   char prefix[MAX_MNEMONIC_LEN + 1];
    205  1.11  christos   char suffix[MAX_MNEMONIC_LEN + 1];
    206  1.11  christos   char number[MAX_MNEMONIC_LEN + 1];
    207   1.1  christos   int mask_start, i = 0, tag_found = 0, reading_number = 0;
    208   1.1  christos   int number_p = 0, suffix_p = 0, prefix_p = 0;
    209   1.1  christos   const struct s390_cond_ext_format *ext_table;
    210   1.1  christos   int ext_table_length;
    211   1.1  christos 
    212   1.1  christos   if (!(tag = strpbrk (mnemonic, "*$")))
    213   1.1  christos     {
    214  1.11  christos       insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits, flags, description);
    215   1.1  christos       return;
    216   1.1  christos     }
    217   1.1  christos 
    218   1.1  christos   while (mnemonic[i] != '\0')
    219   1.1  christos     {
    220   1.1  christos       if (mnemonic[i] == *tag)
    221   1.1  christos 	{
    222   1.1  christos 	  if (tag_found)
    223   1.1  christos 	    goto malformed_mnemonic;
    224   1.1  christos 
    225   1.1  christos 	  tag_found = 1;
    226   1.1  christos 	  reading_number = 1;
    227   1.1  christos 	}
    228   1.1  christos       else
    229   1.1  christos 	switch (mnemonic[i])
    230   1.1  christos 	  {
    231   1.1  christos 	  case '0': case '1': case '2': case '3': case '4':
    232   1.1  christos 	  case '5': case '6': case '7': case '8': case '9':
    233   1.1  christos 	    if (!tag_found || !reading_number)
    234   1.1  christos 	      goto malformed_mnemonic;
    235   1.1  christos 
    236   1.1  christos 	    number[number_p++] = mnemonic[i];
    237   1.1  christos 	    break;
    238   1.1  christos 
    239   1.1  christos 	  default:
    240   1.1  christos 	    if (reading_number)
    241   1.1  christos 	      {
    242   1.1  christos 		if (!number_p)
    243   1.1  christos 		  goto malformed_mnemonic;
    244   1.1  christos 		else
    245   1.1  christos 		  reading_number = 0;
    246   1.1  christos 	      }
    247   1.1  christos 
    248   1.1  christos 	    if (tag_found)
    249   1.1  christos 	      suffix[suffix_p++] = mnemonic[i];
    250   1.1  christos 	    else
    251   1.1  christos 	      prefix[prefix_p++] = mnemonic[i];
    252   1.1  christos 	  }
    253   1.1  christos       i++;
    254   1.1  christos     }
    255   1.1  christos 
    256   1.1  christos   prefix[prefix_p] = '\0';
    257   1.1  christos   suffix[suffix_p] = '\0';
    258   1.1  christos   number[number_p] = '\0';
    259   1.1  christos 
    260   1.1  christos   if (sscanf (number, "%d", &mask_start) != 1)
    261   1.1  christos     goto malformed_mnemonic;
    262   1.1  christos 
    263   1.1  christos   if (mask_start & 3)
    264   1.1  christos     {
    265  1.11  christos       print_error ("Mnemonic \"%s\": Conditional mask not at nibble boundary\n", mnemonic);
    266   1.1  christos       return;
    267   1.1  christos     }
    268   1.1  christos 
    269   1.1  christos   mask_start >>= 2;
    270   1.1  christos 
    271   1.1  christos   switch (*tag)
    272   1.1  christos     {
    273   1.1  christos     case '*':
    274   1.1  christos       ext_table = s390_cond_extensions;
    275   1.1  christos       ext_table_length = NUM_COND_EXTENSIONS;
    276   1.1  christos       break;
    277   1.1  christos     case '$':
    278   1.1  christos       ext_table = s390_crb_extensions;
    279   1.1  christos       ext_table_length = NUM_CRB_EXTENSIONS;
    280   1.1  christos       break;
    281   1.9  christos     default:
    282   1.9  christos       abort ();			/* Should be unreachable.  */
    283   1.1  christos     }
    284   1.1  christos 
    285   1.1  christos   for (i = 0; i < ext_table_length; i++)
    286   1.1  christos     {
    287  1.11  christos       char new_mnemonic[MAX_MNEMONIC_LEN + 1];
    288  1.11  christos       char new_description[MAX_DESCRIPTION_LEN + 1];
    289   1.1  christos 
    290   1.1  christos       opcode[mask_start] = ext_table[i].nibble;
    291  1.11  christos 
    292  1.11  christos       if (snprintf (new_mnemonic, sizeof (new_mnemonic), "%s%s%s", prefix,
    293  1.11  christos 		    ext_table[i].extension, suffix) >= sizeof (new_mnemonic))
    294  1.11  christos 	{
    295  1.11  christos 	  print_error ("Mnemonic: \"%s\": Concatenated mnemonic exceeds max. length\n", mnemonic);
    296  1.11  christos 	  return;
    297  1.11  christos 	}
    298  1.11  christos 
    299  1.11  christos       if (snprintf (new_description, sizeof (new_description), "%s %s", description,
    300  1.11  christos 		    ext_table[i].description_suffix) >= sizeof (new_description))
    301  1.11  christos 	{
    302  1.11  christos 	  print_error ("Mnemonic \"%s\": Concatenated description exceeds max. length\n", mnemonic);
    303  1.11  christos 	  return;
    304  1.11  christos 	}
    305  1.11  christos 
    306  1.11  christos       insertOpcode (opcode, new_mnemonic, format, min_cpu, mode_bits, flags, new_description);
    307   1.1  christos     }
    308   1.1  christos   return;
    309   1.1  christos 
    310   1.1  christos  malformed_mnemonic:
    311  1.11  christos   print_error ("Malformed mnemonic: %s\n", mnemonic);
    312   1.1  christos }
    313   1.1  christos 
    314   1.1  christos static const char file_header[] =
    315   1.1  christos   "/* The opcode table. This file was generated by s390-mkopc.\n\n"
    316   1.1  christos   "   The format of the opcode table is:\n\n"
    317   1.1  christos   "   NAME	     OPCODE	MASK	OPERANDS\n\n"
    318   1.1  christos   "   Name is the name of the instruction.\n"
    319   1.1  christos   "   OPCODE is the instruction opcode.\n"
    320   1.1  christos   "   MASK is the opcode mask; this is used to tell the disassembler\n"
    321   1.1  christos   "     which bits in the actual opcode must match OPCODE.\n"
    322   1.1  christos   "   OPERANDS is the list of operands.\n\n"
    323   1.1  christos   "   The disassembler reads the table in order and prints the first\n"
    324   1.5  christos   "   instruction which matches.\n"
    325   1.5  christos   "   MODE_BITS - zarch or esa\n"
    326   1.5  christos   "   MIN_CPU - number of the min cpu level required\n"
    327  1.11  christos   "   FLAGS - instruction flags.\n"
    328  1.11  christos   "   DESCRIPTION - description of the instruction.  */\n\n"
    329   1.1  christos   "const struct s390_opcode s390_opcodes[] =\n  {\n";
    330   1.1  christos 
    331   1.1  christos /* `dumpTable': write opcode table.  */
    332   1.1  christos 
    333   1.1  christos static void
    334   1.1  christos dumpTable (void)
    335   1.1  christos {
    336   1.1  christos   char *str;
    337   1.1  christos   int  ix;
    338   1.1  christos 
    339   1.1  christos   /*  Write hash table entries (slots).  */
    340   1.1  christos   printf ("%s", file_header);
    341   1.1  christos 
    342   1.1  christos   for (ix = 0; ix < no_ops; ix++)
    343   1.1  christos     {
    344   1.1  christos       printf ("  { \"%s\", ", op_array[ix].mnemonic);
    345   1.1  christos       for (str = op_array[ix].opcode; *str != 0; str++)
    346   1.1  christos 	if (*str == '?')
    347   1.1  christos 	  *str = '0';
    348   1.1  christos       printf ("OP%i(0x%sLL), ",
    349   1.1  christos 	      op_array[ix].no_nibbles*4, op_array[ix].opcode);
    350   1.1  christos       printf ("MASK_%s, INSTR_%s, ",
    351   1.1  christos 	      op_array[ix].format, op_array[ix].format);
    352   1.1  christos       printf ("%i, ", op_array[ix].mode_bits);
    353   1.5  christos       printf ("%i, ", op_array[ix].min_cpu);
    354  1.11  christos       printf ("%i, ", op_array[ix].flags);
    355  1.11  christos       printf ("\"%s\" }", op_array[ix].description);
    356   1.1  christos       if (ix < no_ops-1)
    357   1.1  christos 	printf (",\n");
    358   1.1  christos       else
    359   1.1  christos 	printf ("\n");
    360   1.1  christos     }
    361   1.1  christos   printf ("};\n\n");
    362   1.1  christos   printf ("const int s390_num_opcodes =\n");
    363   1.1  christos   printf ("  sizeof (s390_opcodes) / sizeof (s390_opcodes[0]);\n\n");
    364   1.1  christos }
    365   1.1  christos 
    366   1.1  christos int
    367   1.1  christos main (void)
    368   1.1  christos {
    369   1.1  christos   char currentLine[256];
    370   1.1  christos 
    371   1.1  christos   createTable ();
    372   1.1  christos 
    373   1.1  christos   /*  Read opcode descriptions from `stdin'.  For each mnemonic,
    374   1.1  christos       make an entry into the opcode table.  */
    375   1.1  christos   while (fgets (currentLine, sizeof (currentLine), stdin) != NULL)
    376   1.1  christos     {
    377  1.11  christos       char  opcode[MAX_OPCODE_LEN + 1];
    378  1.11  christos       char  mnemonic[MAX_MNEMONIC_LEN + 1];
    379  1.11  christos       char  format[MAX_FORMAT_LEN + 1];
    380  1.11  christos       char  description[MAX_DESCRIPTION_LEN + 1];
    381  1.11  christos       char  cpu_string[MAX_CPU_LEN + 1];
    382  1.11  christos       char  modes_string[MAX_MODES_LEN + 1];
    383  1.11  christos       char  flags_string[MAX_FLAGS_LEN + 1];
    384   1.1  christos       int   min_cpu;
    385   1.1  christos       int   mode_bits;
    386   1.5  christos       int   flag_bits;
    387   1.5  christos       int   num_matched;
    388   1.1  christos       char  *str;
    389   1.1  christos 
    390   1.1  christos       if (currentLine[0] == '#' || currentLine[0] == '\n')
    391   1.7  christos 	continue;
    392  1.11  christos       memset (opcode, '\0', sizeof(opcode));
    393  1.11  christos       num_matched = sscanf (currentLine,
    394  1.11  christos 			    "%" STRINGIFY (MAX_OPCODE_LEN) "s "
    395  1.11  christos 			    "%" STRINGIFY (MAX_MNEMONIC_LEN) "s "
    396  1.11  christos 			    "%" STRINGIFY (MAX_FORMAT_LEN) "s "
    397  1.11  christos 			    "\"%" STRINGIFY (MAX_DESCRIPTION_LEN) "[^\"]\" "
    398  1.11  christos 			    "%" STRINGIFY (MAX_CPU_LEN) "s "
    399  1.11  christos 			    "%" STRINGIFY (MAX_MODES_LEN) "s "
    400  1.11  christos 			    "%" STRINGIFY (MAX_FLAGS_LEN) "[^\n]",
    401  1.11  christos 			    opcode, mnemonic, format, description,
    402  1.11  christos 			    cpu_string, modes_string, flags_string);
    403   1.5  christos       if (num_matched != 6 && num_matched != 7)
    404   1.1  christos 	{
    405  1.11  christos 	  print_error ("Couldn't scan line %s\n", currentLine);
    406  1.11  christos 	  exit (EXIT_FAILURE);
    407   1.5  christos 	}
    408   1.5  christos 
    409   1.7  christos       if (strcmp (cpu_string, "g5") == 0
    410   1.7  christos 	  || strcmp (cpu_string, "arch3") == 0)
    411   1.5  christos 	min_cpu = S390_OPCODE_G5;
    412   1.5  christos       else if (strcmp (cpu_string, "g6") == 0)
    413   1.5  christos 	min_cpu = S390_OPCODE_G6;
    414   1.7  christos       else if (strcmp (cpu_string, "z900") == 0
    415   1.7  christos 	       || strcmp (cpu_string, "arch5") == 0)
    416   1.5  christos 	min_cpu = S390_OPCODE_Z900;
    417   1.7  christos       else if (strcmp (cpu_string, "z990") == 0
    418   1.7  christos 	       || strcmp (cpu_string, "arch6") == 0)
    419   1.5  christos 	min_cpu = S390_OPCODE_Z990;
    420   1.5  christos       else if (strcmp (cpu_string, "z9-109") == 0)
    421   1.5  christos 	min_cpu = S390_OPCODE_Z9_109;
    422   1.7  christos       else if (strcmp (cpu_string, "z9-ec") == 0
    423   1.7  christos 	       || strcmp (cpu_string, "arch7") == 0)
    424   1.5  christos 	min_cpu = S390_OPCODE_Z9_EC;
    425   1.7  christos       else if (strcmp (cpu_string, "z10") == 0
    426   1.7  christos 	       || strcmp (cpu_string, "arch8") == 0)
    427   1.5  christos 	min_cpu = S390_OPCODE_Z10;
    428   1.7  christos       else if (strcmp (cpu_string, "z196") == 0
    429   1.7  christos 	       || strcmp (cpu_string, "arch9") == 0)
    430   1.5  christos 	min_cpu = S390_OPCODE_Z196;
    431   1.7  christos       else if (strcmp (cpu_string, "zEC12") == 0
    432   1.7  christos 	       || strcmp (cpu_string, "arch10") == 0)
    433   1.5  christos 	min_cpu = S390_OPCODE_ZEC12;
    434   1.7  christos       else if (strcmp (cpu_string, "z13") == 0
    435   1.7  christos 	       || strcmp (cpu_string, "arch11") == 0)
    436   1.5  christos 	min_cpu = S390_OPCODE_Z13;
    437   1.8  christos       else if (strcmp (cpu_string, "z14") == 0
    438   1.8  christos 	       || strcmp (cpu_string, "arch12") == 0)
    439   1.7  christos 	min_cpu = S390_OPCODE_ARCH12;
    440   1.9  christos       else if (strcmp (cpu_string, "z15") == 0
    441   1.9  christos 	       || strcmp (cpu_string, "arch13") == 0)
    442   1.8  christos 	min_cpu = S390_OPCODE_ARCH13;
    443  1.10  christos       else if (strcmp (cpu_string, "z16") == 0
    444  1.10  christos 	       || strcmp (cpu_string, "arch14") == 0)
    445  1.10  christos 	min_cpu = S390_OPCODE_ARCH14;
    446  1.12  christos       else if (strcmp (cpu_string, "arch15") == 0)
    447  1.12  christos 	min_cpu = S390_OPCODE_ARCH15;
    448   1.5  christos       else {
    449  1.11  christos 	print_error ("Mnemonic \"%s\": Couldn't parse CPU string: %s\n",
    450  1.11  christos 		     mnemonic, cpu_string);
    451  1.11  christos 	goto continue_loop;
    452   1.5  christos       }
    453   1.5  christos 
    454   1.5  christos       str = modes_string;
    455   1.5  christos       mode_bits = 0;
    456   1.5  christos       do {
    457   1.5  christos 	if (strncmp (str, "esa", 3) == 0
    458   1.5  christos 	    && (str[3] == 0 || str[3] == ',')) {
    459   1.5  christos 	  mode_bits |= 1 << S390_OPCODE_ESA;
    460   1.5  christos 	  str += 3;
    461   1.5  christos 	} else if (strncmp (str, "zarch", 5) == 0
    462   1.5  christos 		   && (str[5] == 0 || str[5] == ',')) {
    463   1.5  christos 	  mode_bits |= 1 << S390_OPCODE_ZARCH;
    464   1.5  christos 	  str += 5;
    465   1.5  christos 	} else {
    466  1.11  christos 	  print_error ("Mnemonic \"%s\": Couldn't parse modes string: %s\n",
    467  1.11  christos 		       mnemonic, modes_string);
    468  1.11  christos 	  goto continue_loop;
    469   1.5  christos 	}
    470   1.5  christos 	if (*str == ',')
    471   1.5  christos 	  str++;
    472   1.5  christos       } while (*str != 0);
    473   1.5  christos 
    474   1.5  christos       flag_bits = 0;
    475   1.1  christos 
    476   1.5  christos       if (num_matched == 7)
    477   1.5  christos 	{
    478   1.5  christos 	  str = flags_string;
    479   1.1  christos 	  do {
    480   1.5  christos 	    if (strncmp (str, "optparm", 7) == 0
    481   1.5  christos 		&& (str[7] == 0 || str[7] == ',')) {
    482   1.5  christos 	      flag_bits |= S390_INSTR_FLAG_OPTPARM;
    483   1.5  christos 	      str += 7;
    484   1.8  christos 	    } else if (strncmp (str, "optparm2", 8) == 0
    485   1.8  christos 		       && (str[8] == 0 || str[8] == ',')) {
    486   1.8  christos 	      flag_bits |= S390_INSTR_FLAG_OPTPARM2;
    487   1.8  christos 	      str += 8;
    488   1.6  christos 	    } else if (strncmp (str, "htm", 3) == 0
    489   1.8  christos 		       && (str[3] == 0 || str[3] == ',')) {
    490   1.6  christos 	      flag_bits |= S390_INSTR_FLAG_HTM;
    491   1.6  christos 	      str += 3;
    492   1.6  christos 	    } else if (strncmp (str, "vx", 2) == 0
    493   1.8  christos 		       && (str[2] == 0 || str[2] == ',')) {
    494   1.6  christos 	      flag_bits |= S390_INSTR_FLAG_VX;
    495   1.6  christos 	      str += 2;
    496  1.11  christos 	    } else if (strncmp (str, "jump", 4) == 0
    497  1.11  christos 		&& (str[4] == 0 || str[4] == ',')) {
    498  1.11  christos 	      flag_bits |= S390_INSTR_FLAGS_CLASS_JUMP;
    499  1.11  christos 	      str += 4;
    500  1.11  christos 	    } else if (strncmp (str, "condjump", 8) == 0
    501  1.11  christos 		&& (str[8] == 0 || str[8] == ',')) {
    502  1.11  christos 	      flag_bits |= S390_INSTR_FLAGS_CLASS_CONDJUMP;
    503  1.11  christos 	      str += 8;
    504  1.11  christos 	    } else if (strncmp (str, "jumpsr", 6) == 0
    505  1.11  christos 		&& (str[6] == 0 || str[6] == ',')) {
    506  1.11  christos 	      flag_bits |= S390_INSTR_FLAGS_CLASS_JUMPSR;
    507  1.11  christos 	      str += 6;
    508   1.1  christos 	    } else {
    509  1.11  christos 	      print_error ("Mnemonic \"%s\": Couldn't parse flags string: %s\n",
    510  1.11  christos 			   mnemonic, flags_string);
    511  1.11  christos 	      goto continue_loop;
    512   1.1  christos 	    }
    513   1.1  christos 	    if (*str == ',')
    514   1.1  christos 	      str++;
    515   1.1  christos 	  } while (*str != 0);
    516   1.1  christos 	}
    517  1.11  christos       insertExpandedMnemonic (opcode, mnemonic, format, min_cpu, mode_bits, flag_bits, description);
    518  1.11  christos 
    519  1.11  christos  continue_loop:
    520  1.11  christos       ;
    521   1.1  christos     }
    522   1.1  christos 
    523   1.1  christos   dumpTable ();
    524  1.11  christos   return return_code;
    525   1.1  christos }
    526