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