Home | History | Annotate | Line # | Download | only in opcodes
opc2c.c revision 1.9
      1  1.1  christos /* opc2c.c --- generate C opcode decoder code from from .opc file
      2  1.1  christos 
      3  1.9  christos    Copyright (C) 2005-2020 Free Software Foundation, Inc.
      4  1.1  christos    Contributed by Red Hat, Inc.
      5  1.1  christos 
      6  1.1  christos    This file is part of the GNU opcode library.
      7  1.1  christos 
      8  1.1  christos    This program is free software; you can redistribute it and/or modify
      9  1.1  christos    it under the terms of the GNU General Public License as published by
     10  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     11  1.1  christos    (at your option) any later version.
     12  1.1  christos 
     13  1.1  christos    This program is distributed in the hope that it will be useful,
     14  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  1.1  christos    GNU General Public License for more details.
     17  1.1  christos 
     18  1.1  christos    You should have received a copy of the GNU General Public License
     19  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     20  1.1  christos 
     21  1.1  christos 
     22  1.1  christos #include <stdio.h>
     23  1.1  christos #include <string.h>
     24  1.1  christos #include <ctype.h>
     25  1.1  christos #include <stdlib.h>
     26  1.1  christos #include <errno.h>
     27  1.1  christos #include "libiberty.h"
     28  1.1  christos 
     29  1.1  christos static char * line_buf = NULL;
     30  1.1  christos static int line_buf_size = 0;
     31  1.1  christos 
     32  1.1  christos #define LBUFINCR 100
     33  1.1  christos 
     34  1.1  christos char *
     35  1.1  christos safe_fgets (FILE * f)
     36  1.1  christos {
     37  1.1  christos   char * line_ptr;
     38  1.1  christos 
     39  1.1  christos   if (line_buf == NULL)
     40  1.1  christos     {
     41  1.1  christos       line_buf = (char *) malloc (LBUFINCR);
     42  1.1  christos       line_buf_size = LBUFINCR;
     43  1.1  christos     }
     44  1.1  christos 
     45  1.1  christos   /* Points to last byte.  */
     46  1.1  christos   line_ptr = line_buf + line_buf_size - 1;
     47  1.1  christos 
     48  1.1  christos   /* So we can see if fgets put a 0 there.  */
     49  1.1  christos   *line_ptr = 1;
     50  1.1  christos   if (fgets (line_buf, line_buf_size, f) == 0)
     51  1.1  christos     return NULL;
     52  1.1  christos 
     53  1.1  christos   /* We filled the buffer?  */
     54  1.1  christos   while (line_ptr[0] == 0 && line_ptr[-1] != '\n')
     55  1.1  christos     {
     56  1.1  christos       /* Make the buffer bigger and read more of the line.  */
     57  1.1  christos       line_buf_size += LBUFINCR;
     58  1.1  christos       line_buf = (char *) realloc (line_buf, line_buf_size);
     59  1.1  christos 
     60  1.1  christos       /* Points to last byte again.  */
     61  1.1  christos       line_ptr = line_buf + line_buf_size - 1;
     62  1.1  christos       /* So we can see if fgets put a 0 there.  */
     63  1.1  christos       *line_ptr = 1;
     64  1.1  christos 
     65  1.1  christos       if (fgets (line_buf + line_buf_size - LBUFINCR - 1, LBUFINCR + 1, f) == 0)
     66  1.1  christos 	return NULL;
     67  1.1  christos     }
     68  1.1  christos 
     69  1.1  christos   return line_buf;
     70  1.1  christos }
     71  1.1  christos 
     72  1.1  christos 
     73  1.1  christos static int errors = 0;
     74  1.1  christos 
     75  1.1  christos #define MAX_BYTES 10
     76  1.1  christos 
     77  1.1  christos typedef struct
     78  1.1  christos {
     79  1.1  christos   int varyno:16;
     80  1.1  christos   int byte:8;
     81  1.1  christos   int shift:8;
     82  1.1  christos } VaryRef;
     83  1.1  christos 
     84  1.1  christos typedef struct
     85  1.1  christos {
     86  1.1  christos   char nbytes;
     87  1.1  christos   char dbytes;
     88  1.1  christos   char id[MAX_BYTES * 8 + 1];
     89  1.1  christos   unsigned char var_start[MAX_BYTES * 8 + 1];
     90  1.1  christos   struct
     91  1.1  christos   {
     92  1.1  christos     unsigned char decodable_mask;
     93  1.1  christos     unsigned char decodable_bits;
     94  1.1  christos   } b[MAX_BYTES];
     95  1.1  christos   char * comment;
     96  1.1  christos   char * syntax;
     97  1.1  christos   int lineno;
     98  1.1  christos   int nlines;
     99  1.1  christos   char ** lines;
    100  1.1  christos   struct Indirect * last_ind;
    101  1.1  christos   int semantics_label;
    102  1.1  christos   int nvaries;
    103  1.1  christos   VaryRef * vary;
    104  1.1  christos } opcode;
    105  1.1  christos 
    106  1.1  christos int n_opcodes;
    107  1.1  christos opcode ** opcodes;
    108  1.1  christos opcode * op;
    109  1.1  christos 
    110  1.1  christos typedef struct
    111  1.1  christos {
    112  1.1  christos   char * name;
    113  1.1  christos   int nlen;
    114  1.1  christos   unsigned char mask;
    115  1.1  christos   int n_patterns;
    116  1.1  christos   unsigned char * patterns;
    117  1.1  christos } Vary;
    118  1.1  christos 
    119  1.1  christos Vary ** vary = 0;
    120  1.1  christos int n_varies = 0;
    121  1.1  christos 
    122  1.1  christos unsigned char cur_bits[MAX_BYTES + 1];
    123  1.1  christos 
    124  1.6  christos const char * orig_filename;
    125  1.1  christos 
    126  1.1  christos FILE * sim_log = NULL;
    127  1.1  christos #define lprintf if (sim_log) fprintf
    128  1.1  christos 
    129  1.1  christos opcode prefix_text, suffix_text;
    130  1.1  christos 
    131  1.1  christos typedef enum
    132  1.1  christos {
    133  1.1  christos   T_unused,
    134  1.1  christos   T_op,
    135  1.1  christos   T_indirect,
    136  1.1  christos   T_done
    137  1.1  christos } OpType;
    138  1.1  christos 
    139  1.1  christos typedef struct Indirect
    140  1.1  christos {
    141  1.1  christos   OpType type;
    142  1.1  christos   union
    143  1.1  christos   {
    144  1.1  christos     struct Indirect * ind;
    145  1.1  christos     opcode * op;
    146  1.1  christos   } u;
    147  1.1  christos } Indirect;
    148  1.1  christos 
    149  1.1  christos Indirect indirect[256];
    150  1.1  christos 
    151  1.1  christos static int
    152  1.1  christos next_varybits (int bits, opcode * op, int byte)
    153  1.1  christos {
    154  1.1  christos   int mask = op->b[byte].decodable_mask;
    155  1.1  christos   int i;
    156  1.1  christos 
    157  1.1  christos   for (i = 0; i < 8; i++)
    158  1.1  christos     if (!(mask & (1 << i)))
    159  1.1  christos       {
    160  1.1  christos 	if (bits & (1 << i))
    161  1.1  christos 	  {
    162  1.1  christos 	    bits &= ~(1 << i);
    163  1.1  christos 	  }
    164  1.1  christos 	else
    165  1.1  christos 	  {
    166  1.1  christos 	    bits |= (1 << i);
    167  1.1  christos 	    return bits;
    168  1.1  christos 	  }
    169  1.1  christos       }
    170  1.1  christos   return 0;
    171  1.1  christos }
    172  1.1  christos 
    173  1.1  christos static int
    174  1.1  christos valid_varybits (int bits, opcode * op, int byte)
    175  1.1  christos {
    176  1.1  christos   if (op->nvaries)
    177  1.1  christos     {
    178  1.1  christos       int vn;
    179  1.1  christos 
    180  1.1  christos       for (vn = 0; vn < op->nvaries; vn++)
    181  1.1  christos 	{
    182  1.1  christos 	  Vary * v;
    183  1.1  christos 	  int found = 0;
    184  1.1  christos 	  int i;
    185  1.1  christos 	  int ob;
    186  1.1  christos 
    187  1.1  christos 	  if (byte != op->vary[vn].byte)
    188  1.1  christos 	    continue;
    189  1.1  christos 	  v = vary[op->vary[vn].varyno];
    190  1.1  christos 	  ob = (bits >> op->vary[vn].shift) & v->mask;
    191  1.1  christos 	  lprintf (sim_log, "varybits: vary %s ob %x\n", v->name, ob);
    192  1.1  christos 
    193  1.1  christos 	  for (i = 0; i < v->n_patterns; i++)
    194  1.1  christos 	    if (ob == v->patterns[i])
    195  1.1  christos 	      {
    196  1.1  christos 		lprintf (sim_log, "  found at %d\n", i);
    197  1.1  christos 		found = 1;
    198  1.1  christos 		break;
    199  1.1  christos 	      }
    200  1.1  christos 	  if (!found)
    201  1.1  christos 	    return 0;
    202  1.1  christos 	}
    203  1.1  christos     }
    204  1.1  christos   return 1;
    205  1.1  christos }
    206  1.1  christos 
    207  1.1  christos char *
    208  1.1  christos prmb (int mask, int bits)
    209  1.1  christos {
    210  1.1  christos   static char buf[8][30];
    211  1.1  christos   static int bn = 0;
    212  1.1  christos   char * bp;
    213  1.1  christos 
    214  1.1  christos   bn = (bn + 1) % 8;
    215  1.1  christos   bp = buf[bn];
    216  1.1  christos   int i;
    217  1.1  christos   for (i = 0; i < 8; i++)
    218  1.1  christos     {
    219  1.1  christos       int bit = 0x80 >> i;
    220  1.1  christos 
    221  1.1  christos       if (!(mask & bit))
    222  1.1  christos 	*bp++ = '-';
    223  1.1  christos       else if (bits & bit)
    224  1.1  christos 	*bp++ = '1';
    225  1.1  christos       else
    226  1.1  christos 	*bp++ = '0';
    227  1.1  christos       if (i % 4 == 3)
    228  1.1  christos 	*bp++ = ' ';
    229  1.1  christos     }
    230  1.1  christos   *--bp = 0;
    231  1.1  christos   return buf[bn];
    232  1.1  christos }
    233  1.1  christos 
    234  1.1  christos static int
    235  1.1  christos op_cmp (const void *va, const void *vb)
    236  1.1  christos {
    237  1.1  christos   const opcode * a = *(const opcode **) va;
    238  1.1  christos   const opcode * b = *(const opcode **) vb;
    239  1.1  christos 
    240  1.1  christos   if (a->nbytes != b->nbytes)
    241  1.1  christos     return a->nbytes - b->nbytes;
    242  1.1  christos 
    243  1.1  christos   return strcmp (a->id, b->id);
    244  1.1  christos }
    245  1.1  christos 
    246  1.1  christos void
    247  1.1  christos dump_lines (opcode * op, int level, Indirect * ind)
    248  1.1  christos {
    249  1.1  christos   char * varnames[40];
    250  1.1  christos   int i, vn = 0;
    251  1.1  christos 
    252  1.1  christos   if (op->semantics_label)
    253  1.1  christos     {
    254  1.1  christos       printf ("%*sgoto op_semantics_%d;\n", level, "", op->semantics_label);
    255  1.1  christos       return;
    256  1.1  christos     }
    257  1.1  christos 
    258  1.1  christos   if (ind != op->last_ind)
    259  1.1  christos     {
    260  1.1  christos       static int labelno = 0;
    261  1.1  christos       labelno++;
    262  1.1  christos       printf ("%*sop_semantics_%d:\n", level, "", labelno);
    263  1.1  christos       op->semantics_label = labelno;
    264  1.1  christos     }
    265  1.1  christos 
    266  1.1  christos   if (op->comment)
    267  1.1  christos     {
    268  1.1  christos       level += 2;
    269  1.1  christos       printf ("%*s{\n", level, "");
    270  1.1  christos       printf ("%*s  %s\n", level, "", op->comment);
    271  1.1  christos     }
    272  1.1  christos 
    273  1.1  christos   for (i = 0; i < op->nbytes * 8;)
    274  1.1  christos     {
    275  1.1  christos       if (isalpha (op->id[i]))
    276  1.1  christos 	{
    277  1.1  christos 	  int byte = i >> 3;
    278  1.1  christos 	  int mask = 0;
    279  1.1  christos 	  int shift = 0;
    280  1.1  christos 	  char name[33];
    281  1.1  christos 	  char * np = name;
    282  1.1  christos 
    283  1.1  christos 	  while (op->id[i] && isalpha (op->id[i]))
    284  1.1  christos 	    {
    285  1.1  christos 	      mask = (mask << 1) | 1;
    286  1.1  christos 	      shift = 7 - (i & 7);
    287  1.1  christos 	      *np++ = op->id[i++];
    288  1.1  christos 	      if (op->var_start[i])
    289  1.1  christos 		break;
    290  1.1  christos 	    }
    291  1.1  christos 	  *np = 0;
    292  1.1  christos 	  varnames[vn++] = strdup (name);
    293  1.1  christos 	  printf ("#line %d \"%s\"\n", op->lineno + 1, orig_filename);
    294  1.1  christos 	  if (mask & ~0xff)
    295  1.1  christos 	    {
    296  1.1  christos 	      fprintf (stderr, "Error: variable %s spans bytes: %s\n",
    297  1.1  christos 		       name, op->comment);
    298  1.1  christos 	      errors++;
    299  1.1  christos 	    }
    300  1.1  christos 	  else if (shift && (mask != 0xff))
    301  1.1  christos 	    printf ("%*s  int %s AU = (op[%d] >> %d) & 0x%02x;\n",
    302  1.1  christos 		    level, "", name, byte, shift, mask);
    303  1.1  christos 	  else if (mask != 0xff)
    304  1.1  christos 	    printf ("%*s  int %s AU = op[%d] & 0x%02x;\n",
    305  1.1  christos 		    level, "", name, byte, mask);
    306  1.1  christos 	  else
    307  1.1  christos 	    printf ("%*s  int %s AU = op[%d];\n", level, "", name, byte);
    308  1.1  christos 	}
    309  1.1  christos       else
    310  1.1  christos 	i++;
    311  1.1  christos     }
    312  1.1  christos 
    313  1.1  christos   if (op->comment)
    314  1.1  christos     {
    315  1.1  christos       printf ("%*s  if (trace)\n", level, "");
    316  1.1  christos       printf ("%*s    {\n", level, "");
    317  1.1  christos       printf ("%*s      printf (\"\\033[33m%%s\\033[0m ", level, "");
    318  1.1  christos       for (i = 0; i < op->nbytes; i++)
    319  1.1  christos 	printf (" %%02x");
    320  1.1  christos       printf ("\\n\"");
    321  1.1  christos       printf (",\n%*s             \"%s\"", level, "", op->comment);
    322  1.1  christos       for (i = 0; i < op->nbytes; i++)
    323  1.1  christos 	{
    324  1.1  christos 	  if (i == 0)
    325  1.1  christos 	    printf (",\n%*s             op[%d]", level, "", i);
    326  1.1  christos 	  else
    327  1.1  christos 	    printf (", op[%d]", i);
    328  1.1  christos 	}
    329  1.1  christos       printf (");\n");
    330  1.1  christos       for (i = 0; i < vn; i++)
    331  1.1  christos 	printf ("%*s      printf (\"  %s = 0x%%x%s\", %s);\n", level, "",
    332  1.1  christos 		varnames[i], (i < vn - 1) ? "," : "\\n", varnames[i]);
    333  1.1  christos       printf ("%*s    }\n", level, "");
    334  1.1  christos     }
    335  1.1  christos 
    336  1.1  christos   if (op->syntax)
    337  1.1  christos     printf ("%*s  SYNTAX(\"%s\");\n", level, "", op->syntax);
    338  1.1  christos 
    339  1.1  christos   printf ("#line %d \"%s\"\n", op->lineno + 1, orig_filename);
    340  1.1  christos 
    341  1.1  christos   for (i = 0; i < op->nlines; i++)
    342  1.6  christos     if (op->lines[i][0] == '\n')
    343  1.6  christos       printf ("%s", op->lines[i]);
    344  1.6  christos     else
    345  1.6  christos       printf ("%*s%s", level, "", op->lines[i]);
    346  1.1  christos 
    347  1.1  christos   if (op->comment)
    348  1.1  christos     printf ("%*s}\n", level, "");
    349  1.1  christos }
    350  1.1  christos 
    351  1.1  christos void
    352  1.1  christos store_opcode_bits (opcode * op, int byte, Indirect * ind)
    353  1.1  christos {
    354  1.1  christos   int bits = op->b[byte].decodable_bits;
    355  1.1  christos 
    356  1.1  christos   do
    357  1.1  christos     {
    358  1.1  christos       if (!valid_varybits (bits, op, byte))
    359  1.1  christos 	continue;
    360  1.1  christos 
    361  1.1  christos       switch (ind[bits].type)
    362  1.1  christos 	{
    363  1.1  christos 	case T_unused:
    364  1.1  christos 	  if (byte == op->dbytes - 1)
    365  1.1  christos 	    {
    366  1.1  christos 	      ind[bits].type = T_op;
    367  1.1  christos 	      ind[bits].u.op = op;
    368  1.1  christos 	      op->last_ind = ind;
    369  1.1  christos 	      break;
    370  1.1  christos 	    }
    371  1.1  christos 	  else
    372  1.1  christos 	    {
    373  1.1  christos 	      int i2;
    374  1.1  christos 
    375  1.1  christos 	      ind[bits].type = T_indirect;
    376  1.1  christos 	      ind[bits].u.ind = (Indirect *) malloc (256 * sizeof (Indirect));
    377  1.1  christos 	      for (i2 = 0; i2 < 256; i2++)
    378  1.1  christos 		ind[bits].u.ind[i2].type = T_unused;
    379  1.1  christos 	      store_opcode_bits (op, byte + 1, ind[bits].u.ind);
    380  1.1  christos 	    }
    381  1.1  christos 	  break;
    382  1.1  christos 
    383  1.1  christos 	case T_indirect:
    384  1.1  christos 	  if (byte < op->dbytes - 1)
    385  1.1  christos 	    store_opcode_bits (op, byte + 1, ind[bits].u.ind);
    386  1.1  christos 	  break;
    387  1.1  christos 
    388  1.1  christos 	case T_op:
    389  1.1  christos 	  break;
    390  1.1  christos 
    391  1.1  christos 	case T_done:
    392  1.1  christos 	  break;
    393  1.1  christos 	}
    394  1.1  christos     }
    395  1.1  christos   while ((bits = next_varybits (bits, op, byte)) != 0);
    396  1.1  christos }
    397  1.1  christos 
    398  1.1  christos void
    399  1.1  christos emit_indirect (Indirect * ind, int byte)
    400  1.1  christos {
    401  1.1  christos   int unsup = 0;
    402  1.1  christos   int j, n, mask;
    403  1.1  christos 
    404  1.1  christos   mask = 0;
    405  1.1  christos   for (j = 0; j < 256; j++)
    406  1.1  christos     {
    407  1.1  christos       switch (ind[j].type)
    408  1.1  christos 	{
    409  1.1  christos 	case T_indirect:
    410  1.1  christos 	  mask = 0xff;
    411  1.1  christos 	  break;
    412  1.1  christos 	case T_op:
    413  1.1  christos 	  mask |= ind[j].u.op->b[byte].decodable_mask;
    414  1.1  christos 	  break;
    415  1.1  christos 	case T_done:
    416  1.1  christos 	case T_unused:
    417  1.1  christos 	  break;
    418  1.1  christos 	}
    419  1.1  christos     }
    420  1.1  christos 
    421  1.1  christos   printf ("%*s  GETBYTE ();\n", byte * 6, "");
    422  1.1  christos   printf ("%*s  switch (op[%d] & 0x%02x)\n", byte * 6, "", byte, mask);
    423  1.1  christos   printf ("%*s  {\n", byte * 6, "");
    424  1.1  christos 
    425  1.1  christos   for (j = 0; j < 256; j++)
    426  1.1  christos     if ((j & ~mask) == 0)
    427  1.1  christos       {
    428  1.1  christos 	switch (ind[j].type)
    429  1.1  christos 	  {
    430  1.1  christos 	  case T_done:
    431  1.1  christos 	    break;
    432  1.1  christos 	  case T_unused:
    433  1.1  christos 	    unsup = 1;
    434  1.1  christos 	    break;
    435  1.1  christos 	  case T_op:
    436  1.1  christos 	    for (n = j; n < 256; n++)
    437  1.1  christos 	      if ((n & ~mask) == 0
    438  1.1  christos 		  && ind[n].type == T_op && ind[n].u.op == ind[j].u.op)
    439  1.1  christos 		{
    440  1.1  christos 		  ind[n].type = T_done;
    441  1.1  christos 		  printf ("%*s    case 0x%02x:\n", byte * 6, "", n);
    442  1.1  christos 		}
    443  1.1  christos 	    for (n = byte; n < ind[j].u.op->nbytes - 1; n++)
    444  1.1  christos 	      printf ("%*s      GETBYTE();\n", byte * 6, "");
    445  1.1  christos 	    dump_lines (ind[j].u.op, byte * 6 + 6, ind);
    446  1.1  christos 	    printf ("%*s      break;\n", byte * 6, "");
    447  1.1  christos 	    break;
    448  1.1  christos 	  case T_indirect:
    449  1.1  christos 	    printf ("%*s    case 0x%02x:\n", byte * 6, "", j);
    450  1.1  christos 	    emit_indirect (ind[j].u.ind, byte + 1);
    451  1.1  christos 	    printf ("%*s      break;\n", byte * 6, "");
    452  1.1  christos 	    break;
    453  1.1  christos 	  }
    454  1.1  christos       }
    455  1.1  christos   if (unsup)
    456  1.1  christos     printf ("%*s    default: UNSUPPORTED(); break;\n", byte * 6, "");
    457  1.1  christos   printf ("%*s  }\n", byte * 6, "");
    458  1.1  christos }
    459  1.1  christos 
    460  1.1  christos static char *
    461  1.1  christos pv_dup (char * p, char * ep)
    462  1.1  christos {
    463  1.1  christos   int n = ep - p;
    464  1.1  christos   char *rv = (char *) malloc (n + 1);
    465  1.1  christos 
    466  1.1  christos   memcpy (rv, p, n);
    467  1.1  christos   rv[n] = 0;
    468  1.1  christos   return rv;
    469  1.1  christos }
    470  1.1  christos 
    471  1.1  christos static unsigned char
    472  1.1  christos str2mask (char * str, char * ep)
    473  1.1  christos {
    474  1.1  christos   unsigned char rv = 0;
    475  1.1  christos 
    476  1.1  christos   while (str < ep)
    477  1.1  christos     {
    478  1.1  christos       rv *= 2;
    479  1.1  christos       if (*str == '1')
    480  1.1  christos 	rv += 1;
    481  1.1  christos       str++;
    482  1.1  christos     }
    483  1.1  christos   return rv;
    484  1.1  christos }
    485  1.1  christos 
    486  1.1  christos static void
    487  1.1  christos process_vary (char * line)
    488  1.1  christos {
    489  1.1  christos   char * cp;
    490  1.1  christos   char * ep;
    491  1.1  christos   Vary * v = (Vary *) malloc (sizeof (Vary));
    492  1.1  christos 
    493  1.1  christos   n_varies++;
    494  1.1  christos   if (vary)
    495  1.1  christos     vary = (Vary **) realloc (vary, n_varies * sizeof (Vary *));
    496  1.1  christos   else
    497  1.1  christos     vary = (Vary **) malloc (n_varies * sizeof (Vary *));
    498  1.1  christos   vary[n_varies - 1] = v;
    499  1.1  christos 
    500  1.1  christos   cp = line;
    501  1.1  christos 
    502  1.1  christos   for (cp = line; isspace (*cp); cp++);
    503  1.1  christos   for (ep = cp; *ep && !isspace (*ep); ep++);
    504  1.1  christos 
    505  1.1  christos   v->name = pv_dup (cp, ep);
    506  1.1  christos   v->nlen = strlen (v->name);
    507  1.1  christos   v->mask = (1 << v->nlen) - 1;
    508  1.1  christos 
    509  1.1  christos   v->n_patterns = 0;
    510  1.1  christos   v->patterns = (unsigned char *) malloc (1);
    511  1.1  christos   while (1)
    512  1.1  christos     {
    513  1.1  christos       for (cp = ep; isspace (*cp); cp++);
    514  1.1  christos       if (!isdigit (*cp))
    515  1.1  christos 	break;
    516  1.1  christos       for (ep = cp; *ep && !isspace (*ep); ep++);
    517  1.1  christos       v->n_patterns++;
    518  1.1  christos       v->patterns = (unsigned char *) realloc (v->patterns, v->n_patterns);
    519  1.1  christos       v->patterns[v->n_patterns - 1] = str2mask (cp, ep);
    520  1.1  christos     }
    521  1.1  christos }
    522  1.1  christos 
    523  1.1  christos static int
    524  1.1  christos fieldcmp (opcode * op, int bit, char *name)
    525  1.1  christos {
    526  1.1  christos   int n = strlen (name);
    527  1.1  christos 
    528  1.1  christos   if (memcmp (op->id + bit, name, n) == 0
    529  1.1  christos       && (!isalpha (op->id[bit + n]) || op->var_start[bit + n]))
    530  1.1  christos     return 1;
    531  1.1  christos   return 0;
    532  1.1  christos }
    533  1.1  christos 
    534  1.1  christos static void
    535  1.1  christos log_indirect (Indirect * ind, int byte)
    536  1.1  christos {
    537  1.1  christos   int i, j;
    538  1.1  christos   char * last_c = 0;
    539  1.1  christos 
    540  1.1  christos   for (i = 0; i < 256; i++)
    541  1.1  christos     {
    542  1.1  christos 
    543  1.1  christos       for (j = 0; j < byte; j++)
    544  1.1  christos 	fprintf (sim_log, "%s ", prmb (255, cur_bits[j]));
    545  1.1  christos       fprintf (sim_log, "%s ", prmb (255, i));
    546  1.1  christos 
    547  1.1  christos       switch (ind[i].type)
    548  1.1  christos 	{
    549  1.1  christos 	case T_op:
    550  1.1  christos 	case T_done:
    551  1.1  christos 	  if (last_c && (ind[i].u.op->comment == last_c))
    552  1.1  christos 	    fprintf (sim_log, "''\n");
    553  1.1  christos 	  else
    554  1.1  christos 	    fprintf (sim_log, "%s\n", ind[i].u.op->comment);
    555  1.1  christos 	  last_c = ind[i].u.op->comment;
    556  1.1  christos 	  break;
    557  1.1  christos 	case T_unused:
    558  1.1  christos 	  fprintf (sim_log, "unused\n");
    559  1.1  christos 	  break;
    560  1.1  christos 	case T_indirect:
    561  1.1  christos 	  fprintf (sim_log, "indirect\n");
    562  1.1  christos 	  cur_bits[byte] = i;
    563  1.1  christos 	  log_indirect (ind[i].u.ind, byte + 1);
    564  1.1  christos 	  last_c = 0;
    565  1.1  christos 	  break;
    566  1.1  christos 	}
    567  1.1  christos     }
    568  1.1  christos }
    569  1.1  christos 
    570  1.1  christos int
    571  1.1  christos main (int argc, char ** argv)
    572  1.1  christos {
    573  1.1  christos   char * line;
    574  1.1  christos   FILE * in;
    575  1.1  christos   int lineno = 0;
    576  1.1  christos   int i;
    577  1.1  christos   VaryRef * vlist;
    578  1.1  christos   int skipping_section = 0;
    579  1.1  christos 
    580  1.1  christos   if (argc < 2)
    581  1.1  christos     {
    582  1.1  christos       fprintf (stderr, "usage: opc2c infile.opc > outfile.opc\n");
    583  1.1  christos       exit (1);
    584  1.1  christos     }
    585  1.1  christos 
    586  1.1  christos   orig_filename = lbasename (argv[1]);
    587  1.1  christos   in = fopen (argv[1], "r");
    588  1.1  christos   if (!in)
    589  1.1  christos     {
    590  1.1  christos       fprintf (stderr, "Unable to open file %s for reading: %s\n", argv[1],
    591  1.1  christos 	       xstrerror (errno));
    592  1.1  christos       exit (1);
    593  1.1  christos     }
    594  1.1  christos 
    595  1.1  christos   n_opcodes = 0;
    596  1.1  christos   opcodes = (opcode **) malloc (sizeof (opcode *));
    597  1.1  christos   op = &prefix_text;
    598  1.1  christos   op->lineno = 0;
    599  1.1  christos   while ((line = safe_fgets (in)) != 0)
    600  1.1  christos     {
    601  1.1  christos       lineno++;
    602  1.1  christos       if (strncmp (line, "/*?* ", 5) == 0)
    603  1.1  christos 	{
    604  1.1  christos 	  skipping_section = 1;
    605  1.1  christos 	  continue;
    606  1.1  christos 	}
    607  1.1  christos       if (strncmp (line, "  /** ", 6) == 0
    608  1.1  christos 	  && (isdigit (line[6]) || memcmp (line + 6, "VARY", 4) == 0))
    609  1.1  christos 	line += 2;
    610  1.1  christos       if (line[0] == '/' && line[1] == '*' && line[2] == '*')
    611  1.1  christos 	{
    612  1.1  christos 	  skipping_section = 0;
    613  1.1  christos 	  if (strncmp (line, "/** */", 6) == 0)
    614  1.1  christos 	    {
    615  1.1  christos 	      op = &suffix_text;
    616  1.1  christos 	      op->lineno = lineno;
    617  1.1  christos 	    }
    618  1.1  christos 	  else if (strncmp (line, "/** VARY ", 9) == 0)
    619  1.1  christos 	    process_vary (line + 9);
    620  1.1  christos 	  else
    621  1.1  christos 	    {
    622  1.1  christos 	      char * lp;
    623  1.1  christos 	      int i, bit, byte;
    624  1.1  christos 	      int var_start = 1;
    625  1.1  christos 
    626  1.1  christos 	      n_opcodes++;
    627  1.1  christos 	      opcodes =
    628  1.1  christos 		(opcode **) realloc (opcodes, n_opcodes * sizeof (opcode *));
    629  1.1  christos 	      op = (opcode *) malloc (sizeof (opcode));
    630  1.1  christos 	      opcodes[n_opcodes - 1] = op;
    631  1.1  christos 
    632  1.1  christos 	      op->nbytes = op->dbytes = 0;
    633  1.1  christos 	      memset (op->id, 0, sizeof (op->id));
    634  1.1  christos 	      memset (op->var_start, 0, sizeof (op->var_start));
    635  1.1  christos 	      for (i = 0; i < MAX_BYTES; i++)
    636  1.1  christos 		{
    637  1.1  christos 		  op->b[i].decodable_mask = 0;
    638  1.1  christos 		  op->b[i].decodable_bits = 0;
    639  1.1  christos 		}
    640  1.1  christos 	      op->comment = strdup (line);
    641  1.1  christos 	      op->comment[strlen (op->comment) - 1] = 0;
    642  1.1  christos 	      while (op->comment[0] && isspace (op->comment[0]))
    643  1.1  christos 		op->comment++;
    644  1.1  christos 	      op->lineno = lineno;
    645  1.1  christos 	      op->nlines = 0;
    646  1.1  christos 	      op->lines = 0;
    647  1.1  christos 	      op->last_ind = 0;
    648  1.1  christos 	      op->semantics_label = 0;
    649  1.1  christos 	      op->nvaries = 0;
    650  1.1  christos 	      op->vary = 0;
    651  1.1  christos 
    652  1.1  christos 	      i = 0;
    653  1.1  christos 	      for (lp = line + 4; *lp; lp++)
    654  1.1  christos 		{
    655  1.1  christos 		  bit = 7 - (i & 7);
    656  1.1  christos 		  byte = i >> 3;
    657  1.1  christos 
    658  1.1  christos 		  if (strncmp (lp, "*/", 2) == 0)
    659  1.1  christos 		    break;
    660  1.1  christos 		  else if ((lp[0] == ' ' && lp[1] == ' ') || (lp[0] == '\t'))
    661  1.1  christos 		    {
    662  1.1  christos 		      while (*lp == ' ' || *lp == '\t')
    663  1.1  christos 			lp ++;
    664  1.1  christos 		      op->syntax = strdup (lp);
    665  1.1  christos 		      lp = strstr (op->syntax, "*/");
    666  1.1  christos 		      if (lp)
    667  1.1  christos 			{
    668  1.1  christos 			  *lp-- = 0;
    669  1.1  christos 			  while ((*lp == ' ' || *lp == '\t')
    670  1.1  christos 				 && lp > op->syntax)
    671  1.1  christos 			    *lp-- = 0;
    672  1.1  christos 			}
    673  1.1  christos 		      break;
    674  1.1  christos 		    }
    675  1.1  christos 		  else if (*lp == ' ')
    676  1.1  christos 		    var_start = 1;
    677  1.1  christos 		  else
    678  1.1  christos 		    {
    679  1.1  christos 		      if (*lp == '0' || *lp == '1')
    680  1.1  christos 			{
    681  1.1  christos 			  op->b[byte].decodable_mask |= 1 << bit;
    682  1.1  christos 			  var_start = 1;
    683  1.1  christos 			  if (op->dbytes < byte + 1)
    684  1.1  christos 			    op->dbytes = byte + 1;
    685  1.1  christos 			}
    686  1.1  christos 		      else if (var_start)
    687  1.1  christos 			{
    688  1.1  christos 			  op->var_start[i] = 1;
    689  1.1  christos 			  var_start = 0;
    690  1.1  christos 			  if (op->dbytes < byte + 1)
    691  1.1  christos 			    op->dbytes = byte + 1;
    692  1.1  christos 			}
    693  1.1  christos 		      if (*lp == '1')
    694  1.1  christos 			op->b[byte].decodable_bits |= 1 << bit;
    695  1.1  christos 
    696  1.1  christos 		      op->nbytes = byte + 1;
    697  1.1  christos 		      op->id[i++] = *lp;
    698  1.1  christos 		    }
    699  1.1  christos 		}
    700  1.1  christos 	    }
    701  1.1  christos 	}
    702  1.1  christos       else if (!skipping_section)
    703  1.1  christos 	{
    704  1.1  christos 	  op->nlines++;
    705  1.1  christos 	  if (op->lines)
    706  1.1  christos 	    op->lines =
    707  1.1  christos 	      (char **) realloc (op->lines, op->nlines * sizeof (char *));
    708  1.1  christos 	  else
    709  1.1  christos 	    op->lines = (char **) malloc (op->nlines * sizeof (char *));
    710  1.1  christos 	  op->lines[op->nlines - 1] = strdup (line);
    711  1.1  christos 	}
    712  1.1  christos     }
    713  1.1  christos 
    714  1.1  christos   {
    715  1.1  christos     int i, j;
    716  1.1  christos     for (i = 0; i < n_varies; i++)
    717  1.1  christos       {
    718  1.1  christos 	Vary *v = vary[i];
    719  1.1  christos 	lprintf (sim_log, "V[%s] %d\n", v->name, v->nlen);
    720  1.1  christos 	for (j = 0; j < v->n_patterns; j++)
    721  1.1  christos 	  lprintf (sim_log, "  P %02x\n", v->patterns[j]);
    722  1.1  christos       }
    723  1.1  christos   }
    724  1.1  christos 
    725  1.1  christos   for (i = n_opcodes - 2; i >= 0; i--)
    726  1.1  christos     {
    727  1.1  christos       if (opcodes[i]->nlines == 0)
    728  1.1  christos 	{
    729  1.1  christos 	  opcodes[i]->nlines = opcodes[i + 1]->nlines;
    730  1.1  christos 	  opcodes[i]->lines = opcodes[i + 1]->lines;
    731  1.1  christos 	}
    732  1.1  christos     }
    733  1.1  christos 
    734  1.1  christos   for (i = 0; i < 256; i++)
    735  1.1  christos     indirect[i].type = T_unused;
    736  1.1  christos 
    737  1.1  christos   qsort (opcodes, n_opcodes, sizeof (opcodes[0]), op_cmp);
    738  1.1  christos 
    739  1.1  christos   vlist = (VaryRef *) malloc (n_varies * sizeof (VaryRef));
    740  1.1  christos 
    741  1.1  christos   for (i = 0; i < n_opcodes; i++)
    742  1.1  christos     {
    743  1.1  christos       int j, b, v;
    744  1.1  christos 
    745  1.1  christos       for (j = 0; j < opcodes[i]->nbytes; j++)
    746  1.1  christos 	lprintf (sim_log, "%s ",
    747  1.1  christos 		 prmb (opcodes[i]->b[j].decodable_mask,
    748  1.1  christos 		       opcodes[i]->b[j].decodable_bits));
    749  1.1  christos       lprintf (sim_log, " %s\n", opcodes[i]->comment);
    750  1.1  christos 
    751  1.1  christos       for (j = 0; j < opcodes[i]->nbytes; j++)
    752  1.1  christos 	{
    753  1.1  christos 	  for (b = 0; b < 8; b++)
    754  1.1  christos 	    if (isalpha (opcodes[i]->id[j * 8 + b]))
    755  1.1  christos 	      for (v = 0; v < n_varies; v++)
    756  1.1  christos 		if (fieldcmp (opcodes[i], j * 8 + b, vary[v]->name))
    757  1.1  christos 		  {
    758  1.1  christos 		    int nv = opcodes[i]->nvaries++;
    759  1.1  christos 		    if (nv)
    760  1.1  christos 		      opcodes[i]->vary =
    761  1.1  christos 			(VaryRef *) realloc (opcodes[i]->vary,
    762  1.1  christos 					     (nv + 1) * sizeof (VaryRef));
    763  1.1  christos 		    else
    764  1.1  christos 		      opcodes[i]->vary =
    765  1.1  christos 			(VaryRef *) malloc ((nv + 1) * sizeof (VaryRef));
    766  1.1  christos 
    767  1.1  christos 		    opcodes[i]->vary[nv].varyno = v;
    768  1.1  christos 		    opcodes[i]->vary[nv].byte = j;
    769  1.1  christos 		    opcodes[i]->vary[nv].shift = 8 - b - vary[v]->nlen;
    770  1.1  christos 		    lprintf (sim_log, "[vary %s shift %d]\n",
    771  1.1  christos 			     vary[v]->name, opcodes[i]->vary[nv].shift);
    772  1.1  christos 		  }
    773  1.1  christos 
    774  1.1  christos 	}
    775  1.1  christos     }
    776  1.1  christos 
    777  1.1  christos   for (i = 0; i < n_opcodes; i++)
    778  1.1  christos     {
    779  1.1  christos       int i2;
    780  1.1  christos       int bytes = opcodes[i]->dbytes;
    781  1.1  christos 
    782  1.1  christos       lprintf (sim_log, "\nmask:");
    783  1.1  christos       for (i2 = 0; i2 < opcodes[i]->nbytes; i2++)
    784  1.1  christos 	lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_mask);
    785  1.1  christos       lprintf (sim_log, "%*s%s\n", 13 - 3 * opcodes[i]->nbytes, "",
    786  1.1  christos 	       opcodes[i]->comment);
    787  1.1  christos 
    788  1.1  christos       lprintf (sim_log, "bits:");
    789  1.1  christos       for (i2 = 0; i2 < opcodes[i]->nbytes; i2++)
    790  1.1  christos 	lprintf (sim_log, " %02x", opcodes[i]->b[i2].decodable_bits);
    791  1.1  christos       lprintf (sim_log, "%*s(%s) %d byte%s\n", 13 - 3 * opcodes[i]->nbytes,
    792  1.1  christos 	       "", opcodes[i]->id, bytes, bytes == 1 ? "" : "s");
    793  1.1  christos 
    794  1.1  christos       store_opcode_bits (opcodes[i], 0, indirect);
    795  1.1  christos     }
    796  1.1  christos 
    797  1.8  christos   printf ("/* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */\n");
    798  1.8  christos 
    799  1.1  christos   dump_lines (&prefix_text, 0, 0);
    800  1.1  christos 
    801  1.1  christos   emit_indirect (indirect, 0);
    802  1.1  christos 
    803  1.1  christos   dump_lines (&suffix_text, 0, 0);
    804  1.1  christos 
    805  1.1  christos   if (sim_log)
    806  1.1  christos     log_indirect (indirect, 0);
    807  1.1  christos 
    808  1.1  christos   return errors;
    809  1.1  christos }
    810