s390-mkopc.c revision 99461
11573Srgrimes/* s390-mkopc.c -- Generates opcode table out of s390-opc.txt
21573Srgrimes   Copyright 2000, 2001 Free Software Foundation, Inc.
31573Srgrimes   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
41573Srgrimes
51573Srgrimes   This file is part of GDB, GAS, and the GNU binutils.
61573Srgrimes
71573Srgrimes   This program is free software; you can redistribute it and/or modify
81573Srgrimes   it under the terms of the GNU General Public License as published by
91573Srgrimes   the Free Software Foundation; either version 2 of the License, or
101573Srgrimes   (at your option) any later version.
111573Srgrimes
121573Srgrimes   This program is distributed in the hope that it will be useful,
13251672Semaste   but WITHOUT ANY WARRANTY; without even the implied warranty of
141573Srgrimes   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
151573Srgrimes   GNU General Public License for more details.
161573Srgrimes
171573Srgrimes   You should have received a copy of the GNU General Public License
181573Srgrimes   along with this program; if not, write to the Free Software
191573Srgrimes   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
201573Srgrimes   02111-1307, USA.  */
211573Srgrimes
221573Srgrimes#include <stdio.h>
231573Srgrimes#include <stdlib.h>
241573Srgrimes#include <string.h>
251573Srgrimes
261573Srgrimes/* ARCHBITS_ESA and ARCH_ESAME correspond to the bit numbers defined
271573Srgrimes   by s390_opcode_arch_val in include/opcode/s390.h:
281573Srgrimes     ARCHBITS_ESAONLY = (1<<S390_OPCODE_ESA)
291573Srgrimes     ARCHBITS_ESA     = (1<<S390_OPCODE_ESA) + (1<<S390_OPCODE_ESAME)
301573Srgrimes     ARCHBITS_ESA     = (1<<S390_OPCODE_ESAME).  */
3123662Speter#define ARCHBITS_ESAONLY 1
321573Srgrimes#define ARCHBITS_ESA     3
3392986Sobrien#define ARCHBITS_ESAME   2
3492986Sobrien
351573Srgrimesstruct op_struct
3671579Sdeischen  {
37249035Sdelphij    char  opcode[16];
38249035Sdelphij    char  mnemonic[16];
39124738Sdas    char  format[16];
401573Srgrimes    int   archbits;
4171579Sdeischen    unsigned long long sort_value;
421573Srgrimes    int   no_nibbles;
431573Srgrimes  };
441573Srgrimes
451573Srgrimesstruct op_struct *op_array;
461573Srgrimesint max_ops;
471573Srgrimesint no_ops;
481573Srgrimes
491573Srgrimesstatic void
501573SrgrimescreateTable (void)
511573Srgrimes{
521573Srgrimes  max_ops = 256;
531573Srgrimes  op_array = malloc (max_ops * sizeof (struct op_struct));
541573Srgrimes  no_ops = 0;
551573Srgrimes}
561573Srgrimes
571573Srgrimes/* `insertOpcode': insert an op_struct into sorted opcode array.  */
581573Srgrimes
59124738Sdasstatic void
601573SrgrimesinsertOpcode (char *opcode, char *mnemonic, char *format, int archbits)
611573Srgrimes{
62124738Sdas  char *str;
631573Srgrimes  unsigned long long sort_value;
641573Srgrimes  int no_nibbles;
651573Srgrimes  int ix, k;
668870Srgrimes
671573Srgrimes  while (no_ops >= max_ops)
681573Srgrimes    {
691573Srgrimes      max_ops = max_ops * 2;
701573Srgrimes      op_array = realloc (op_array, max_ops * sizeof (struct op_struct));
711573Srgrimes    }
721573Srgrimes
731573Srgrimes  sort_value = 0;
741573Srgrimes  str = opcode;
751573Srgrimes  for (ix = 0; ix < 16; ix++)
761573Srgrimes    {
771573Srgrimes      if (*str >= '0' && *str <= '9')
7892889Sobrien	sort_value = (sort_value << 4) + (*str - '0');
791573Srgrimes      else if (*str >= 'a' && *str <= 'f')
801573Srgrimes	sort_value = (sort_value << 4) + (*str - 'a' + 10);
8123662Speter      else if (*str >= 'A' && *str <= 'F')
8223662Speter	sort_value = (sort_value << 4) + (*str - 'A' + 10);
8323662Speter      else if (*str == '?')
8423662Speter	sort_value <<= 4;
8523662Speter      else
8623662Speter	break;
8723662Speter      str ++;
8823662Speter    }
8923662Speter  sort_value <<= 4*(16 - ix);
9023662Speter  no_nibbles = ix;
9123662Speter  for (ix = 0; ix < no_ops; ix++)
9223662Speter    if (sort_value > op_array[ix].sort_value)
9323662Speter      break;
9423662Speter  for (k = no_ops; k > ix; k--)
9523662Speter    op_array[k] = op_array[k-1];
9623662Speter  strcpy(op_array[ix].opcode, opcode);
9723662Speter  strcpy(op_array[ix].mnemonic, mnemonic);
9823662Speter  strcpy(op_array[ix].format, format);
9923662Speter  op_array[ix].sort_value = sort_value;
1001573Srgrimes  op_array[ix].no_nibbles = no_nibbles;
1011573Srgrimes  op_array[ix].archbits = archbits;
1021573Srgrimes  no_ops++;
1031573Srgrimes}
1041573Srgrimes
1051573Srgrimesstatic char file_header[] =
1061573Srgrimes  "/* The opcode table. This file was generated by s390-mkopc.\n\n"
1071573Srgrimes  "   The format of the opcode table is:\n\n"
1081573Srgrimes  "   NAME	     OPCODE	MASK	OPERANDS\n\n"
1091573Srgrimes  "   Name is the name of the instruction.\n"
1101573Srgrimes  "   OPCODE is the instruction opcode.\n"
1111573Srgrimes  "   MASK is the opcode mask; this is used to tell the disassembler\n"
1121573Srgrimes  "     which bits in the actual opcode must match OPCODE.\n"
1131573Srgrimes  "   OPERANDS is the list of operands.\n\n"
1141573Srgrimes  "   The disassembler reads the table in order and prints the first\n"
1151573Srgrimes  "   instruction which matches.  */\n\n"
1161573Srgrimes  "const struct s390_opcode s390_opcodes[] =\n  {\n";
1171573Srgrimes
1181573Srgrimes/* `dumpTable': write opcode table.  */
1191573Srgrimes
1201573Srgrimesstatic void
1211573SrgrimesdumpTable (void)
1221573Srgrimes{
1231573Srgrimes  char *str;
1241573Srgrimes  int  ix;
1251573Srgrimes
1261573Srgrimes  /*  Write hash table entries (slots).  */
1271573Srgrimes  printf (file_header);
1281573Srgrimes
1291573Srgrimes  for (ix = 0; ix < no_ops; ix++)
1301573Srgrimes    {
1311573Srgrimes      printf ("  { \"%s\", ", op_array[ix].mnemonic);
1321573Srgrimes      for (str = op_array[ix].opcode; *str != 0; str++)
1331573Srgrimes	if (*str == '?')
1341573Srgrimes	  *str = '0';
1351573Srgrimes      printf ("OP%i(0x%sLL), ",
1361573Srgrimes	      op_array[ix].no_nibbles*4, op_array[ix].opcode);
1371573Srgrimes      printf ("MASK_%s, INSTR_%s, ",
1381573Srgrimes	      op_array[ix].format, op_array[ix].format);
1391573Srgrimes      printf ("%i}", op_array[ix].archbits);
140118731Sache      if (ix < no_ops-1)
141110321Sache	printf (",\n");
142124738Sdas      else
143124738Sdas	printf ("\n");
1441573Srgrimes    }
1451573Srgrimes  printf ("};\n\n");
1461573Srgrimes  printf ("const int s390_num_opcodes =\n");
1471573Srgrimes  printf ("  sizeof (s390_opcodes) / sizeof (s390_opcodes[0]);\n\n");
14818832Sache}
1491573Srgrimes
1501573Srgrimesint
1511573Srgrimesmain (void)
1521573Srgrimes{
1531573Srgrimes  char currentLine[256];
1541573Srgrimes
1551573Srgrimes  createTable ();
1561573Srgrimes
1571573Srgrimes  /*  Read opcode descriptions from `stdin'.  For each mnemonic,
1581573Srgrimes      make an entry into the opcode table.  */
159124738Sdas  while (fgets (currentLine, sizeof (currentLine), stdin) != NULL)
1601573Srgrimes    {
161300953Sache      char  opcode[16];
162300953Sache      char  mnemonic[16];
163300953Sache      char  format[16];
164300953Sache      char  description[64];
165300953Sache      char  archtag[16];
166300953Sache      int   archbits;
1671573Srgrimes
1681573Srgrimes      if (currentLine[0] == '#')
1691573Srgrimes        continue;
1701573Srgrimes      memset (opcode, 0, 8);
1711573Srgrimes      if (sscanf (currentLine, "%15s %15s %15s \"%[^\"]\" %15s",
1721573Srgrimes		  opcode, mnemonic, format, description, archtag) == 5)
1731573Srgrimes	{
1741573Srgrimes	  if (strcmp (archtag, "esaonly") == 0)
1751573Srgrimes	    archbits = ARCHBITS_ESAONLY;
1761573Srgrimes	  else if (strcmp (archtag, "esa") == 0)
1771573Srgrimes	    archbits = ARCHBITS_ESA;
1781573Srgrimes	  else if (strcmp (archtag, "esame") == 0)
1791573Srgrimes	    archbits = ARCHBITS_ESAME;
1801573Srgrimes	  else
1811573Srgrimes	    archbits = 0;
1821573Srgrimes	  insertOpcode (opcode, mnemonic, format, archbits);
183124738Sdas	}
184124738Sdas      else
1851573Srgrimes        fprintf (stderr, "Couldn't scan line %s\n", currentLine);
1861573Srgrimes    }
1871573Srgrimes
1881573Srgrimes  dumpTable ();
1891573Srgrimes  return 0;
1901573Srgrimes}
1911573Srgrimes