Back to index

cell-binutils  2.17cvs20070401
s390-mkopc.c
Go to the documentation of this file.
00001 /* s390-mkopc.c -- Generates opcode table out of s390-opc.txt
00002    Copyright 2000, 2001, 2003 Free Software Foundation, Inc.
00003    Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
00004 
00005    This file is part of GDB, GAS, and the GNU binutils.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
00020    02110-1301, USA.  */
00021 
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 
00026 /* Taken from opcodes/s390.h */
00027 enum s390_opcode_mode_val
00028   {
00029     S390_OPCODE_ESA = 0,
00030     S390_OPCODE_ZARCH
00031   };
00032 
00033 enum s390_opcode_cpu_val
00034   {
00035     S390_OPCODE_G5 = 0,
00036     S390_OPCODE_G6,
00037     S390_OPCODE_Z900,
00038     S390_OPCODE_Z990,
00039     S390_OPCODE_Z9_109,
00040     S390_OPCODE_Z9_EC
00041   };
00042 
00043 struct op_struct
00044   {
00045     char  opcode[16];
00046     char  mnemonic[16];
00047     char  format[16];
00048     int   mode_bits;
00049     int   min_cpu;
00050     
00051     unsigned long long sort_value;
00052     int   no_nibbles;
00053   };
00054 
00055 struct op_struct *op_array;
00056 int max_ops;
00057 int no_ops;
00058 
00059 static void
00060 createTable (void)
00061 {
00062   max_ops = 256;
00063   op_array = malloc (max_ops * sizeof (struct op_struct));
00064   no_ops = 0;
00065 }
00066 
00067 /* `insertOpcode': insert an op_struct into sorted opcode array.  */
00068 
00069 static void
00070 insertOpcode (char *opcode, char *mnemonic, char *format,
00071              int min_cpu, int mode_bits)
00072 {
00073   char *str;
00074   unsigned long long sort_value;
00075   int no_nibbles;
00076   int ix, k;
00077 
00078   while (no_ops >= max_ops)
00079     {
00080       max_ops = max_ops * 2;
00081       op_array = realloc (op_array, max_ops * sizeof (struct op_struct));
00082     }
00083 
00084   sort_value = 0;
00085   str = opcode;
00086   for (ix = 0; ix < 16; ix++)
00087     {
00088       if (*str >= '0' && *str <= '9')
00089        sort_value = (sort_value << 4) + (*str - '0');
00090       else if (*str >= 'a' && *str <= 'f')
00091        sort_value = (sort_value << 4) + (*str - 'a' + 10);
00092       else if (*str >= 'A' && *str <= 'F')
00093        sort_value = (sort_value << 4) + (*str - 'A' + 10);
00094       else if (*str == '?')
00095        sort_value <<= 4;
00096       else
00097        break;
00098       str ++;
00099     }
00100   sort_value <<= 4*(16 - ix);
00101   sort_value += (min_cpu << 8) + mode_bits;
00102   no_nibbles = ix;
00103   for (ix = 0; ix < no_ops; ix++)
00104     if (sort_value > op_array[ix].sort_value)
00105       break;
00106   for (k = no_ops; k > ix; k--)
00107     op_array[k] = op_array[k-1];
00108   strcpy(op_array[ix].opcode, opcode);
00109   strcpy(op_array[ix].mnemonic, mnemonic);
00110   strcpy(op_array[ix].format, format);
00111   op_array[ix].sort_value = sort_value;
00112   op_array[ix].no_nibbles = no_nibbles;
00113   op_array[ix].min_cpu = min_cpu;
00114   op_array[ix].mode_bits = mode_bits;
00115   no_ops++;
00116 }
00117 
00118 static char file_header[] =
00119   "/* The opcode table. This file was generated by s390-mkopc.\n\n"
00120   "   The format of the opcode table is:\n\n"
00121   "   NAME         OPCODE   MASK   OPERANDS\n\n"
00122   "   Name is the name of the instruction.\n"
00123   "   OPCODE is the instruction opcode.\n"
00124   "   MASK is the opcode mask; this is used to tell the disassembler\n"
00125   "     which bits in the actual opcode must match OPCODE.\n"
00126   "   OPERANDS is the list of operands.\n\n"
00127   "   The disassembler reads the table in order and prints the first\n"
00128   "   instruction which matches.  */\n\n"
00129   "const struct s390_opcode s390_opcodes[] =\n  {\n";
00130 
00131 /* `dumpTable': write opcode table.  */
00132 
00133 static void
00134 dumpTable (void)
00135 {
00136   char *str;
00137   int  ix;
00138 
00139   /*  Write hash table entries (slots).  */
00140   printf (file_header);
00141 
00142   for (ix = 0; ix < no_ops; ix++)
00143     {
00144       printf ("  { \"%s\", ", op_array[ix].mnemonic);
00145       for (str = op_array[ix].opcode; *str != 0; str++)
00146        if (*str == '?')
00147          *str = '0';
00148       printf ("OP%i(0x%sLL), ", 
00149              op_array[ix].no_nibbles*4, op_array[ix].opcode);
00150       printf ("MASK_%s, INSTR_%s, ",
00151              op_array[ix].format, op_array[ix].format);
00152       printf ("%i, ", op_array[ix].mode_bits);
00153       printf ("%i}", op_array[ix].min_cpu);
00154       if (ix < no_ops-1)
00155        printf (",\n");
00156       else
00157        printf ("\n");
00158     }
00159   printf ("};\n\n");
00160   printf ("const int s390_num_opcodes =\n");
00161   printf ("  sizeof (s390_opcodes) / sizeof (s390_opcodes[0]);\n\n");
00162 }
00163 
00164 int
00165 main (void)
00166 {
00167   char currentLine[256];
00168   
00169   createTable ();
00170 
00171   /*  Read opcode descriptions from `stdin'.  For each mnemonic,
00172       make an entry into the opcode table.  */
00173   while (fgets (currentLine, sizeof (currentLine), stdin) != NULL)
00174     {
00175       char  opcode[16];
00176       char  mnemonic[16];
00177       char  format[16];
00178       char  description[64];
00179       char  cpu_string[16];
00180       char  modes_string[16];
00181       int   min_cpu;
00182       int   mode_bits;
00183       char  *str;
00184 
00185       if (currentLine[0] == '#')
00186         continue;
00187       memset (opcode, 0, 8);
00188       if (sscanf (currentLine, "%15s %15s %15s \"%[^\"]\" %15s %15s",
00189                 opcode, mnemonic, format, description,
00190                 cpu_string, modes_string) == 6)
00191        {
00192          if (strcmp (cpu_string, "g5") == 0)
00193            min_cpu = S390_OPCODE_G5;
00194          else if (strcmp (cpu_string, "g6") == 0)
00195            min_cpu = S390_OPCODE_G6;
00196          else if (strcmp (cpu_string, "z900") == 0)
00197            min_cpu = S390_OPCODE_Z900;
00198          else if (strcmp (cpu_string, "z990") == 0)
00199            min_cpu = S390_OPCODE_Z990;
00200          else if (strcmp (cpu_string, "z9-109") == 0)
00201            min_cpu = S390_OPCODE_Z9_109;
00202          else if (strcmp (cpu_string, "z9-ec") == 0)
00203            min_cpu = S390_OPCODE_Z9_EC;
00204          else {
00205            fprintf (stderr, "Couldn't parse cpu string %s\n", cpu_string);
00206            exit (1);
00207          }
00208 
00209          str = modes_string;
00210          mode_bits = 0;
00211          do {
00212            if (strncmp (str, "esa", 3) == 0
00213               && (str[3] == 0 || str[3] == ',')) {
00214              mode_bits |= 1 << S390_OPCODE_ESA;
00215              str += 3;
00216            } else if (strncmp (str, "zarch", 5) == 0
00217                      && (str[5] == 0 || str[5] == ',')) {
00218              mode_bits |= 1 << S390_OPCODE_ZARCH;
00219              str += 5;
00220            } else {
00221              fprintf (stderr, "Couldn't parse modes string %s\n",
00222                      modes_string);
00223              exit (1);
00224            }
00225            if (*str == ',')
00226              str++;
00227          } while (*str != 0);
00228          insertOpcode (opcode, mnemonic, format, min_cpu, mode_bits);
00229        }
00230       else
00231         fprintf (stderr, "Couldn't scan line %s\n", currentLine);
00232     }
00233 
00234   dumpTable ();
00235   return 0;
00236 }