Blame libcpu/i386_parse.y

Packit 032894
%{
Packit 032894
/* Parser for i386 CPU description.
Packit 032894
   Copyright (C) 2004, 2005, 2007, 2008, 2009 Red Hat, Inc.
Packit 032894
   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
Packit 032894
Packit 032894
   This file is free software; you can redistribute it and/or modify
Packit 032894
   it under the terms of either
Packit 032894
Packit 032894
     * the GNU Lesser General Public License as published by the Free
Packit 032894
       Software Foundation; either version 3 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or
Packit 032894
Packit 032894
     * the GNU General Public License as published by the Free
Packit 032894
       Software Foundation; either version 2 of the License, or (at
Packit 032894
       your option) any later version
Packit 032894
Packit 032894
   or both in parallel, as here.
Packit 032894
Packit 032894
   elfutils is distributed in the hope that it will be useful, but
Packit 032894
   WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 032894
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 032894
   General Public License for more details.
Packit 032894
Packit 032894
   You should have received copies of the GNU General Public License and
Packit 032894
   the GNU Lesser General Public License along with this program.  If
Packit 032894
   not, see <http://www.gnu.org/licenses/>.  */
Packit 032894
Packit 032894
#ifdef HAVE_CONFIG_H
Packit 032894
# include <config.h>
Packit 032894
#endif
Packit 032894
Packit 032894
#include <assert.h>
Packit 032894
#include <ctype.h>
Packit 032894
#include <errno.h>
Packit 032894
#include <inttypes.h>
Packit 032894
#include <libintl.h>
Packit 032894
#include <math.h>
Packit 032894
#include <obstack.h>
Packit 032894
#include <search.h>
Packit 032894
#include <stdbool.h>
Packit 032894
#include <stdio.h>
Packit 032894
#include <stdlib.h>
Packit 032894
#include <string.h>
Packit 032894
Packit 032894
#include <libeu.h>
Packit 032894
#include <system.h>
Packit 032894
Packit 032894
#define obstack_chunk_alloc xmalloc
Packit 032894
#define obstack_chunk_free free
Packit 032894
Packit 032894
/* The error handler.  */
Packit 032894
static void yyerror (const char *s);
Packit 032894
Packit 032894
extern int yylex (void);
Packit 032894
extern int i386_lineno;
Packit 032894
extern char *infname;
Packit 032894
Packit 032894
Packit 032894
struct known_bitfield
Packit 032894
{
Packit 032894
  char *name;
Packit 032894
  unsigned long int bits;
Packit 032894
  int tmp;
Packit 032894
};
Packit 032894
Packit 032894
Packit 032894
struct bitvalue
Packit 032894
{
Packit 032894
  enum bittype { zeroone, field, failure } type;
Packit 032894
  union
Packit 032894
  {
Packit 032894
    unsigned int value;
Packit 032894
    struct known_bitfield *field;
Packit 032894
  };
Packit 032894
  struct bitvalue *next;
Packit 032894
};
Packit 032894
Packit 032894
Packit 032894
struct argname
Packit 032894
{
Packit 032894
  enum nametype { string, nfield } type;
Packit 032894
  union
Packit 032894
  {
Packit 032894
    char *str;
Packit 032894
    struct known_bitfield *field;
Packit 032894
  };
Packit 032894
  struct argname *next;
Packit 032894
};
Packit 032894
Packit 032894
Packit 032894
struct argument
Packit 032894
{
Packit 032894
  struct argname *name;
Packit 032894
  struct argument *next;
Packit 032894
};
Packit 032894
Packit 032894
Packit 032894
struct instruction
Packit 032894
{
Packit 032894
  /* The byte encoding.  */
Packit 032894
  struct bitvalue *bytes;
Packit 032894
Packit 032894
  /* Prefix possible.  */
Packit 032894
  int repe;
Packit 032894
  int rep;
Packit 032894
Packit 032894
  /* Mnemonic.  */
Packit 032894
  char *mnemonic;
Packit 032894
Packit 032894
  /* Suffix.  */
Packit 032894
  enum { suffix_none = 0, suffix_w, suffix_w0, suffix_W, suffix_tttn,
Packit 032894
	 suffix_w1, suffix_W1, suffix_D } suffix;
Packit 032894
Packit 032894
  /* Flag set if modr/m is used.  */
Packit 032894
  int modrm;
Packit 032894
Packit 032894
  /* Operands.  */
Packit 032894
  struct operand
Packit 032894
  {
Packit 032894
    char *fct;
Packit 032894
    char *str;
Packit 032894
    int off1;
Packit 032894
    int off2;
Packit 032894
    int off3;
Packit 032894
  } operands[3];
Packit 032894
Packit 032894
  struct instruction *next;
Packit 032894
};
Packit 032894
Packit 032894
Packit 032894
struct synonym
Packit 032894
{
Packit 032894
  char *from;
Packit 032894
  char *to;
Packit 032894
};
Packit 032894
Packit 032894
Packit 032894
struct suffix
Packit 032894
{
Packit 032894
  char *name;
Packit 032894
  int idx;
Packit 032894
};
Packit 032894
Packit 032894
Packit 032894
struct argstring
Packit 032894
{
Packit 032894
  char *str;
Packit 032894
  int idx;
Packit 032894
  int off;
Packit 032894
};
Packit 032894
Packit 032894
Packit 032894
static struct known_bitfield ax_reg =
Packit 032894
  {
Packit 032894
    .name = "ax", .bits = 0, .tmp = 0
Packit 032894
  };
Packit 032894
Packit 032894
static struct known_bitfield dx_reg =
Packit 032894
  {
Packit 032894
    .name = "dx", .bits = 0, .tmp = 0
Packit 032894
  };
Packit 032894
Packit 032894
static struct known_bitfield di_reg =
Packit 032894
  {
Packit 032894
    .name = "es_di", .bits = 0, .tmp = 0
Packit 032894
  };
Packit 032894
Packit 032894
static struct known_bitfield si_reg =
Packit 032894
  {
Packit 032894
    .name = "ds_si", .bits = 0, .tmp = 0
Packit 032894
  };
Packit 032894
Packit 032894
static struct known_bitfield bx_reg =
Packit 032894
  {
Packit 032894
    .name = "ds_bx", .bits = 0, .tmp = 0
Packit 032894
  };
Packit 032894
Packit 032894
Packit 032894
static int bitfield_compare (const void *p1, const void *p2);
Packit 032894
static void new_bitfield (char *name, unsigned long int num);
Packit 032894
static void check_bits (struct bitvalue *value);
Packit 032894
static int check_duplicates (struct bitvalue *val);
Packit 032894
static int check_argsdef (struct bitvalue *bitval, struct argument *args);
Packit 032894
static int check_bitsused (struct bitvalue *bitval,
Packit 032894
			   struct known_bitfield *suffix,
Packit 032894
			   struct argument *args);
Packit 032894
static struct argname *combine (struct argname *name);
Packit 032894
static void fillin_arg (struct bitvalue *bytes, struct argname *name,
Packit 032894
			struct instruction *instr, int n);
Packit 032894
static void find_numbers (void);
Packit 032894
static int compare_syn (const void *p1, const void *p2);
Packit 032894
static int compare_suf (const void *p1, const void *p2);
Packit 032894
static void instrtable_out (void);
Packit 032894
#if 0
Packit 032894
static void create_mnemonic_table (void);
Packit 032894
#endif
Packit 032894
Packit 032894
static void *bitfields;
Packit 032894
static struct instruction *instructions;
Packit 032894
static size_t ninstructions;
Packit 032894
static void *synonyms;
Packit 032894
static void *suffixes;
Packit 032894
static int nsuffixes;
Packit 032894
static void *mnemonics;
Packit 032894
size_t nmnemonics;
Packit 032894
extern FILE *outfile;
Packit 032894
Packit 032894
/* Number of bits used mnemonics.  */
Packit 032894
#if 0
Packit 032894
static size_t best_mnemonic_bits;
Packit 032894
#endif
Packit 032894
%}
Packit 032894
Packit 032894
%union {
Packit 032894
  unsigned long int num;
Packit 032894
  char *str;
Packit 032894
  char ch;
Packit 032894
  struct known_bitfield *field;
Packit 032894
  struct bitvalue *bit;
Packit 032894
  struct argname *name;
Packit 032894
  struct argument *arg;
Packit 032894
}
Packit 032894
Packit 032894
%token kMASK
Packit 032894
%token kPREFIX
Packit 032894
%token kSUFFIX
Packit 032894
%token kSYNONYM
Packit 032894
%token <str> kID
Packit 032894
%token <num> kNUMBER
Packit 032894
%token kPERCPERC
Packit 032894
%token <str> kBITFIELD
Packit 032894
%token <ch> kCHAR
Packit 032894
%token kSPACE
Packit 032894
Packit 032894
%type <bit> bit byte bytes
Packit 032894
%type <field> bitfieldopt
Packit 032894
%type <name> argcomp arg
Packit 032894
%type <arg> args optargs
Packit 032894
Packit 032894
%defines
Packit 032894
Packit 032894
%%
Packit 032894
Packit 032894
spec:		  masks kPERCPERC '\n' instrs
Packit 032894
		    {
Packit 032894
		      if (error_message_count != 0)
Packit 032894
			error (EXIT_FAILURE, 0,
Packit 032894
			       "terminated due to previous error");
Packit 032894
Packit 032894
		      instrtable_out ();
Packit 032894
		    }
Packit 032894
		;
Packit 032894
Packit 032894
masks:		  masks '\n' mask
Packit 032894
		| mask
Packit 032894
		;
Packit 032894
Packit 032894
mask:		  kMASK kBITFIELD kNUMBER
Packit 032894
		    { new_bitfield ($2, $3); }
Packit 032894
		| kPREFIX kBITFIELD
Packit 032894
		    { new_bitfield ($2, -1); }
Packit 032894
		| kSUFFIX kBITFIELD
Packit 032894
		    { new_bitfield ($2, -2); }
Packit 032894
		| kSYNONYM kBITFIELD kBITFIELD
Packit 032894
		    {
Packit 032894
		      struct synonym *newp = xmalloc (sizeof (*newp));
Packit 032894
		      newp->from = $2;
Packit 032894
		      newp->to = $3;
Packit 032894
		      if (tfind (newp, &synonyms, compare_syn) != NULL)
Packit 032894
			error (0, 0,
Packit 032894
			       "%d: duplicate definition for synonym '%s'",
Packit 032894
			       i386_lineno, $2);
Packit 032894
		      else if (tsearch ( newp, &synonyms, compare_syn) == NULL)
Packit 032894
			error (EXIT_FAILURE, 0, "tsearch");
Packit 032894
		    }
Packit 032894
		|
Packit 032894
		;
Packit 032894
Packit 032894
instrs:		  instrs '\n' instr
Packit 032894
		| instr
Packit 032894
		;
Packit 032894
Packit 032894
instr:		  bytes ':' bitfieldopt kID bitfieldopt optargs
Packit 032894
		    {
Packit 032894
		      if ($3 != NULL && strcmp ($3->name, "RE") != 0
Packit 032894
			  && strcmp ($3->name, "R") != 0)
Packit 032894
			{
Packit 032894
			  error (0, 0, "%d: only 'R' and 'RE' prefix allowed",
Packit 032894
				 i386_lineno - 1);
Packit 032894
			}
Packit 032894
		      if (check_duplicates ($1) == 0
Packit 032894
			  && check_argsdef ($1, $6) == 0
Packit 032894
			  && check_bitsused ($1, $5, $6) == 0)
Packit 032894
			{
Packit 032894
			  struct instruction *newp = xcalloc (sizeof (*newp),
Packit 032894
							      1);
Packit 032894
			  if ($3 != NULL)
Packit 032894
			    {
Packit 032894
			      if (strcmp ($3->name, "RE") == 0)
Packit 032894
				newp->repe = 1;
Packit 032894
			      else if (strcmp ($3->name, "R") == 0)
Packit 032894
				newp->rep = 1;
Packit 032894
			    }
Packit 032894
Packit 032894
			  newp->bytes = $1;
Packit 032894
			  newp->mnemonic = $4;
Packit 032894
			  if (newp->mnemonic != (void *) -1l
Packit 032894
			      && tfind ($4, &mnemonics,
Packit 032894
					(int (*)(const void *, const void *)) strcmp) == NULL)
Packit 032894
			    {
Packit 032894
			      if (tsearch ($4, &mnemonics,
Packit 032894
					   (int (*)(const void *, const void *)) strcmp) == NULL)
Packit 032894
				error (EXIT_FAILURE, errno, "tsearch");
Packit 032894
			      ++nmnemonics;
Packit 032894
			    }
Packit 032894
Packit 032894
			  if ($5 != NULL)
Packit 032894
			    {
Packit 032894
			      if (strcmp ($5->name, "w") == 0)
Packit 032894
				newp->suffix = suffix_w;
Packit 032894
			      else if (strcmp ($5->name, "w0") == 0)
Packit 032894
				newp->suffix = suffix_w0;
Packit 032894
			      else if (strcmp ($5->name, "tttn") == 0)
Packit 032894
				newp->suffix = suffix_tttn;
Packit 032894
			      else if (strcmp ($5->name, "w1") == 0)
Packit 032894
				newp->suffix = suffix_w1;
Packit 032894
			      else if (strcmp ($5->name, "W") == 0)
Packit 032894
				newp->suffix = suffix_W;
Packit 032894
			      else if (strcmp ($5->name, "W1") == 0)
Packit 032894
				newp->suffix = suffix_W1;
Packit 032894
			      else if (strcmp ($5->name, "D") == 0)
Packit 032894
				newp->suffix = suffix_D;
Packit 032894
			      else
Packit 032894
				error (EXIT_FAILURE, 0,
Packit 032894
				       "%s: %d: unknown suffix '%s'",
Packit 032894
				       infname, i386_lineno - 1, $5->name);
Packit 032894
Packit 032894
			      struct suffix search = { .name = $5->name };
Packit 032894
			      if (tfind (&search, &suffixes, compare_suf)
Packit 032894
				  == NULL)
Packit 032894
				{
Packit 032894
				  struct suffix *ns = xmalloc (sizeof (*ns));
Packit 032894
				  ns->name = $5->name;
Packit 032894
				  ns->idx = ++nsuffixes;
Packit 032894
				  if (tsearch (ns, &suffixes, compare_suf)
Packit 032894
				      == NULL)
Packit 032894
				    error (EXIT_FAILURE, errno, "tsearch");
Packit 032894
				}
Packit 032894
			    }
Packit 032894
Packit 032894
			  struct argument *args = $6;
Packit 032894
			  int n = 0;
Packit 032894
			  while (args != NULL)
Packit 032894
			    {
Packit 032894
			      fillin_arg ($1, args->name, newp, n);
Packit 032894
Packit 032894
			      args = args->next;
Packit 032894
			      ++n;
Packit 032894
			    }
Packit 032894
Packit 032894
			  newp->next = instructions;
Packit 032894
			  instructions = newp;
Packit 032894
			  ++ninstructions;
Packit 032894
			}
Packit 032894
		    }
Packit 032894
		|
Packit 032894
		;
Packit 032894
Packit 032894
bitfieldopt:	  kBITFIELD
Packit 032894
		    {
Packit 032894
		      struct known_bitfield search;
Packit 032894
		      search.name = $1;
Packit 032894
		      struct known_bitfield **res;
Packit 032894
		      res = tfind (&search, &bitfields, bitfield_compare);
Packit 032894
		      if (res == NULL)
Packit 032894
			{
Packit 032894
			  error (0, 0, "%d: unknown bitfield '%s'",
Packit 032894
				 i386_lineno, search.name);
Packit 032894
			  $$ = NULL;
Packit 032894
			}
Packit 032894
		      else
Packit 032894
			$$ = *res;
Packit 032894
		    }
Packit 032894
		|
Packit 032894
		    { $$ = NULL; }
Packit 032894
		;
Packit 032894
Packit 032894
bytes:		  bytes ',' byte
Packit 032894
		    {
Packit 032894
		      check_bits ($3);
Packit 032894
Packit 032894
		      struct bitvalue *runp = $1;
Packit 032894
		      while (runp->next != NULL)
Packit 032894
			runp = runp->next;
Packit 032894
		      runp->next = $3;
Packit 032894
		      $$ = $1;
Packit 032894
		    }
Packit 032894
		| byte
Packit 032894
		    {
Packit 032894
		      check_bits ($1);
Packit 032894
		      $$ = $1;
Packit 032894
		    }
Packit 032894
		;
Packit 032894
Packit 032894
byte:		  byte bit
Packit 032894
		    {
Packit 032894
		      struct bitvalue *runp = $1;
Packit 032894
		      while (runp->next != NULL)
Packit 032894
			runp = runp->next;
Packit 032894
		      runp->next = $2;
Packit 032894
		      $$ = $1;
Packit 032894
		    }
Packit 032894
		| bit
Packit 032894
		    { $$ = $1; }
Packit 032894
		;
Packit 032894
Packit 032894
bit:		  '0'
Packit 032894
		    {
Packit 032894
		      $$ = xmalloc (sizeof (struct bitvalue));
Packit 032894
		      $$->type = zeroone;
Packit 032894
		      $$->value = 0;
Packit 032894
		      $$->next = NULL;
Packit 032894
		    }
Packit 032894
		| '1'
Packit 032894
		    {
Packit 032894
		      $$ = xmalloc (sizeof (struct bitvalue));
Packit 032894
		      $$->type = zeroone;
Packit 032894
		      $$->value = 1;
Packit 032894
		      $$->next = NULL;
Packit 032894
		    }
Packit 032894
		| kBITFIELD
Packit 032894
		    {
Packit 032894
		      $$ = xmalloc (sizeof (struct bitvalue));
Packit 032894
		      struct known_bitfield search;
Packit 032894
		      search.name = $1;
Packit 032894
		      struct known_bitfield **res;
Packit 032894
		      res = tfind (&search, &bitfields, bitfield_compare);
Packit 032894
		      if (res == NULL)
Packit 032894
			{
Packit 032894
			  error (0, 0, "%d: unknown bitfield '%s'",
Packit 032894
				 i386_lineno, search.name);
Packit 032894
			  $$->type = failure;
Packit 032894
			}
Packit 032894
		      else
Packit 032894
			{
Packit 032894
			  $$->type = field;
Packit 032894
			  $$->field = *res;
Packit 032894
			}
Packit 032894
		      $$->next = NULL;
Packit 032894
		    }
Packit 032894
		;
Packit 032894
Packit 032894
optargs:	  kSPACE args
Packit 032894
		    { $$ = $2; }
Packit 032894
		|
Packit 032894
		    { $$ = NULL; }
Packit 032894
		;
Packit 032894
Packit 032894
args:		  args ',' arg
Packit 032894
		    {
Packit 032894
		      struct argument *runp = $1;
Packit 032894
		      while (runp->next != NULL)
Packit 032894
			runp = runp->next;
Packit 032894
		      runp->next = xmalloc (sizeof (struct argument));
Packit 032894
		      runp->next->name = combine ($3);
Packit 032894
		      runp->next->next = NULL;
Packit 032894
		      $$ = $1;
Packit 032894
		    }
Packit 032894
		| arg
Packit 032894
		    {
Packit 032894
		      $$ = xmalloc (sizeof (struct argument));
Packit 032894
		      $$->name = combine ($1);
Packit 032894
		      $$->next = NULL;
Packit 032894
		    }
Packit 032894
		;
Packit 032894
Packit 032894
arg:		  arg argcomp
Packit 032894
		    {
Packit 032894
		      struct argname *runp = $1;
Packit 032894
		      while (runp->next != NULL)
Packit 032894
			runp = runp->next;
Packit 032894
		      runp->next = $2;
Packit 032894
		      $$ = $1;
Packit 032894
		    }
Packit 032894
		| argcomp
Packit 032894
		    { $$ = $1; }
Packit 032894
		;
Packit 032894
argcomp:	  kBITFIELD
Packit 032894
		    {
Packit 032894
		      $$ = xmalloc (sizeof (struct argname));
Packit 032894
		      $$->type = nfield;
Packit 032894
		      $$->next = NULL;
Packit 032894
Packit 032894
		      struct known_bitfield search;
Packit 032894
		      search.name = $1;
Packit 032894
		      struct known_bitfield **res;
Packit 032894
		      res = tfind (&search, &bitfields, bitfield_compare);
Packit 032894
		      if (res == NULL)
Packit 032894
			{
Packit 032894
			  if (strcmp ($1, "ax") == 0)
Packit 032894
			    $$->field = &ax_reg;
Packit 032894
			  else if (strcmp ($1, "dx") == 0)
Packit 032894
			    $$->field = &dx_reg;
Packit 032894
			  else if (strcmp ($1, "es_di") == 0)
Packit 032894
			    $$->field = &di_reg;
Packit 032894
			  else if (strcmp ($1, "ds_si") == 0)
Packit 032894
			    $$->field = &si_reg;
Packit 032894
			  else if (strcmp ($1, "ds_bx") == 0)
Packit 032894
			    $$->field = &bx_reg;
Packit 032894
			  else
Packit 032894
			    {
Packit 032894
			      error (0, 0, "%d: unknown bitfield '%s'",
Packit 032894
				     i386_lineno, search.name);
Packit 032894
			      $$->field = NULL;
Packit 032894
			    }
Packit 032894
			}
Packit 032894
		      else
Packit 032894
			$$->field = *res;
Packit 032894
		    }
Packit 032894
		| kCHAR
Packit 032894
		    {
Packit 032894
		      $$ = xmalloc (sizeof (struct argname));
Packit 032894
		      $$->type = string;
Packit 032894
		      $$->next = NULL;
Packit 032894
		      $$->str = xmalloc (2);
Packit 032894
		      $$->str[0] = $1;
Packit 032894
		      $$->str[1] = '\0';
Packit 032894
		    }
Packit 032894
		| kID
Packit 032894
		    {
Packit 032894
		      $$ = xmalloc (sizeof (struct argname));
Packit 032894
		      $$->type = string;
Packit 032894
		      $$->next = NULL;
Packit 032894
		      $$->str = $1;
Packit 032894
		    }
Packit 032894
		| ':'
Packit 032894
		    {
Packit 032894
		      $$ = xmalloc (sizeof (struct argname));
Packit 032894
		      $$->type = string;
Packit 032894
		      $$->next = NULL;
Packit 032894
		      $$->str = xmalloc (2);
Packit 032894
		      $$->str[0] = ':';
Packit 032894
		      $$->str[1] = '\0';
Packit 032894
		    }
Packit 032894
		;
Packit 032894
Packit 032894
%%
Packit 032894
Packit 032894
static void
Packit 032894
yyerror (const char *s)
Packit 032894
{
Packit 032894
  error (0, 0, gettext ("while reading i386 CPU description: %s at line %d"),
Packit 032894
         gettext (s), i386_lineno);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static int
Packit 032894
bitfield_compare (const void *p1, const void *p2)
Packit 032894
{
Packit 032894
  struct known_bitfield *f1 = (struct known_bitfield *) p1;
Packit 032894
  struct known_bitfield *f2 = (struct known_bitfield *) p2;
Packit 032894
Packit 032894
  return strcmp (f1->name, f2->name);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static void
Packit 032894
new_bitfield (char *name, unsigned long int num)
Packit 032894
{
Packit 032894
  struct known_bitfield *newp = xmalloc (sizeof (struct known_bitfield));
Packit 032894
  newp->name = name;
Packit 032894
  newp->bits = num;
Packit 032894
  newp->tmp = 0;
Packit 032894
Packit 032894
  if (tfind (newp, &bitfields, bitfield_compare) != NULL)
Packit 032894
    {
Packit 032894
      error (0, 0, "%d: duplicated definition of bitfield '%s'",
Packit 032894
	     i386_lineno, name);
Packit 032894
      free (name);
Packit Service 35cfd5
      free (newp);
Packit 032894
      return;
Packit 032894
    }
Packit 032894
Packit 032894
  if (tsearch (newp, &bitfields, bitfield_compare) == NULL)
Packit 032894
    error (EXIT_FAILURE, errno, "%d: cannot insert new bitfield '%s'",
Packit 032894
	   i386_lineno, name);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
/* Check that the number of bits is a multiple of 8.  */
Packit 032894
static void
Packit 032894
check_bits (struct bitvalue *val)
Packit 032894
{
Packit 032894
  struct bitvalue *runp = val;
Packit 032894
  unsigned int total = 0;
Packit 032894
Packit 032894
  while (runp != NULL)
Packit 032894
    {
Packit 032894
      if (runp->type == zeroone)
Packit 032894
	++total;
Packit 032894
      else if (runp->field == NULL)
Packit 032894
	/* No sense doing anything, the field is not known.  */
Packit 032894
	return;
Packit 032894
      else
Packit 032894
	total += runp->field->bits;
Packit 032894
Packit 032894
      runp = runp->next;
Packit 032894
    }
Packit 032894
Packit 032894
  if (total % 8 != 0)
Packit 032894
    {
Packit 032894
      struct obstack os;
Packit 032894
      obstack_init (&os);
Packit 032894
Packit 032894
      while (val != NULL)
Packit 032894
	{
Packit 032894
	  if (val->type == zeroone)
Packit 032894
	    obstack_printf (&os, "%u", val->value);
Packit 032894
	  else
Packit 032894
	    obstack_printf (&os, "{%s}", val->field->name);
Packit 032894
	  val = val->next;
Packit 032894
	}
Packit 032894
      obstack_1grow (&os, '\0');
Packit 032894
Packit 032894
      error (0, 0, "%d: field '%s' not a multiple of 8 bits in size",
Packit 032894
	     i386_lineno, (char *) obstack_finish (&os);;
Packit 032894
Packit 032894
      obstack_free (&os, NULL);
Packit 032894
    }
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static int
Packit 032894
check_duplicates (struct bitvalue *val)
Packit 032894
{
Packit 032894
  static int testcnt;
Packit 032894
  ++testcnt;
Packit 032894
Packit 032894
  int result = 0;
Packit 032894
  while (val != NULL)
Packit 032894
    {
Packit 032894
      if (val->type == field && val->field != NULL)
Packit 032894
	{
Packit 032894
	  if (val->field->tmp == testcnt)
Packit 032894
	    {
Packit 032894
	      error (0, 0, "%d: bitfield '%s' used more than once",
Packit 032894
		     i386_lineno - 1, val->field->name);
Packit 032894
	      result = 1;
Packit 032894
	    }
Packit 032894
	  val->field->tmp = testcnt;
Packit 032894
	}
Packit 032894
Packit 032894
      val = val->next;
Packit 032894
    }
Packit 032894
Packit 032894
  return result;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static int
Packit 032894
check_argsdef (struct bitvalue *bitval, struct argument *args)
Packit 032894
{
Packit 032894
  int result = 0;
Packit 032894
Packit 032894
  while (args != NULL)
Packit 032894
    {
Packit 032894
      for (struct argname *name = args->name; name != NULL; name = name->next)
Packit 032894
	if (name->type == nfield && name->field != NULL
Packit 032894
	    && name->field != &ax_reg && name->field != &dx_reg
Packit 032894
	    && name->field != &di_reg && name->field != &si_reg
Packit 032894
	    && name->field != &bx_reg)
Packit 032894
	  {
Packit 032894
	    struct bitvalue *runp = bitval;
Packit 032894
Packit 032894
	    while (runp != NULL)
Packit 032894
	      if (runp->type == field && runp->field == name->field)
Packit 032894
		break;
Packit 032894
	      else
Packit 032894
		runp = runp->next;
Packit 032894
Packit 032894
	    if (runp == NULL)
Packit 032894
	      {
Packit 032894
		error (0, 0, "%d: unknown bitfield '%s' used in output format",
Packit 032894
		       i386_lineno - 1, name->field->name);
Packit 032894
		result = 1;
Packit 032894
	      }
Packit 032894
	  }
Packit 032894
Packit 032894
      args = args->next;
Packit 032894
    }
Packit 032894
Packit 032894
  return result;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static int
Packit 032894
check_bitsused (struct bitvalue *bitval, struct known_bitfield *suffix,
Packit 032894
		struct argument *args)
Packit 032894
{
Packit 032894
  int result = 0;
Packit 032894
Packit 032894
  while (bitval != NULL)
Packit 032894
    {
Packit 032894
      if (bitval->type == field && bitval->field != NULL
Packit 032894
	  && bitval->field != suffix
Packit 032894
	  /* {w} is handled special.  */
Packit 032894
	  && strcmp (bitval->field->name, "w") != 0)
Packit 032894
	{
Packit 032894
	  struct argument *runp;
Packit 032894
	  for (runp = args; runp != NULL; runp = runp->next)
Packit 032894
	    {
Packit 032894
	      struct argname *name = runp->name;
Packit 032894
Packit 032894
	      while (name != NULL)
Packit 032894
		if (name->type == nfield && name->field == bitval->field)
Packit 032894
		  break;
Packit 032894
		else
Packit 032894
		  name = name->next;
Packit 032894
Packit 032894
	      if (name != NULL)
Packit 032894
		break;
Packit 032894
	    }
Packit 032894
Packit 032894
#if 0
Packit 032894
	  if (runp == NULL)
Packit 032894
	    {
Packit 032894
	      error (0, 0, "%d: bitfield '%s' not used",
Packit 032894
		     i386_lineno - 1, bitval->field->name);
Packit 032894
	      result = 1;
Packit 032894
	    }
Packit 032894
#endif
Packit 032894
	}
Packit 032894
Packit 032894
      bitval = bitval->next;
Packit 032894
    }
Packit 032894
Packit 032894
  return result;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static struct argname *
Packit 032894
combine (struct argname *name)
Packit 032894
{
Packit 032894
  struct argname *last_str = NULL;
Packit 032894
  for (struct argname *runp = name; runp != NULL; runp = runp->next)
Packit 032894
    {
Packit 032894
      if (runp->type == string)
Packit 032894
	{
Packit 032894
	  if (last_str == NULL)
Packit 032894
	    last_str = runp;
Packit 032894
	  else
Packit 032894
	    {
Packit 032894
	      last_str->str = xrealloc (last_str->str,
Packit 032894
					strlen (last_str->str)
Packit 032894
					+ strlen (runp->str) + 1);
Packit 032894
	      strcat (last_str->str, runp->str);
Packit 032894
	      last_str->next = runp->next;
Packit 032894
	    }
Packit 032894
	}
Packit 032894
      else
Packit 032894
	last_str = NULL;
Packit 032894
    }
Packit 032894
  return name;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
#define obstack_grow_str(ob, str) obstack_grow (ob, str, strlen (str))
Packit 032894
Packit 032894
Packit 032894
static void
Packit 032894
fillin_arg (struct bitvalue *bytes, struct argname *name,
Packit 032894
	    struct instruction *instr, int n)
Packit 032894
{
Packit 032894
  static struct obstack ob;
Packit 032894
  static int initialized;
Packit 032894
  if (! initialized)
Packit 032894
    {
Packit 032894
      initialized = 1;
Packit 032894
      obstack_init (&ob;;
Packit 032894
    }
Packit 032894
Packit 032894
  struct argname *runp = name;
Packit 032894
  int cnt = 0;
Packit 032894
  while (runp != NULL)
Packit 032894
    {
Packit 032894
      /* We ignore strings in the function name.  */
Packit 032894
      if (runp->type == string)
Packit 032894
	{
Packit 032894
	  if (instr->operands[n].str != NULL)
Packit 032894
	    error (EXIT_FAILURE, 0,
Packit 032894
		   "%d: cannot have more than one string parameter",
Packit 032894
		   i386_lineno - 1);
Packit 032894
Packit 032894
	  instr->operands[n].str = runp->str;
Packit 032894
	}
Packit 032894
      else
Packit 032894
	{
Packit 032894
	  assert (runp->type == nfield);
Packit 032894
Packit 032894
	  /* Construct the function name.  */
Packit 032894
	  if (cnt++ > 0)
Packit 032894
	    obstack_1grow (&ob, '$');
Packit 032894
Packit 032894
	  if (runp->field == NULL)
Packit 032894
	    /* Add some string which contains invalid characters.  */
Packit 032894
	    obstack_grow_str (&ob, "!!!INVALID!!!");
Packit 032894
	  else
Packit 032894
	    {
Packit 032894
	      char *fieldname = runp->field->name;
Packit 032894
Packit 032894
	      struct synonym search = { .from = fieldname };
Packit 032894
Packit 032894
	      struct synonym **res = tfind (&search, &synonyms, compare_syn);
Packit 032894
	      if (res != NULL)
Packit 032894
		fieldname = (*res)->to;
Packit 032894
Packit 032894
	      obstack_grow_str (&ob, fieldname);
Packit 032894
	    }
Packit 032894
Packit 032894
	  /* Now compute the bit offset of the field.  */
Packit 032894
	  struct bitvalue *b = bytes;
Packit 032894
	  int bitoff = 0;
Packit 032894
	  if (runp->field != NULL)
Packit 032894
	    while (b != NULL)
Packit 032894
	      {
Packit 032894
		if (b->type == field && b->field != NULL)
Packit 032894
		  {
Packit 032894
		    if (strcmp (b->field->name, runp->field->name) == 0)
Packit 032894
		      break;
Packit 032894
		    bitoff += b->field->bits;
Packit 032894
		  }
Packit 032894
		else
Packit 032894
		  ++bitoff;
Packit 032894
Packit 032894
		b = b->next;
Packit 032894
	      }
Packit 032894
	  if (instr->operands[n].off1 == 0)
Packit 032894
	    instr->operands[n].off1 = bitoff;
Packit 032894
	  else if (instr->operands[n].off2 == 0)
Packit 032894
	    instr->operands[n].off2 = bitoff;
Packit 032894
	  else if (instr->operands[n].off3 == 0)
Packit 032894
	    instr->operands[n].off3 = bitoff;
Packit 032894
	  else
Packit 032894
	    error (EXIT_FAILURE, 0,
Packit 032894
		   "%d: cannot have more than three fields in parameter",
Packit 032894
		   i386_lineno - 1);
Packit 032894
Packit 032894
	  if  (runp->field != NULL
Packit 032894
	       && strncasecmp (runp->field->name, "mod", 3) == 0)
Packit 032894
	    instr->modrm = 1;
Packit 032894
	}
Packit 032894
Packit 032894
      runp = runp->next;
Packit 032894
    }
Packit 032894
  if (obstack_object_size (&ob) == 0)
Packit 032894
    obstack_grow_str (&ob, "string");
Packit 032894
  obstack_1grow (&ob, '\0');
Packit 032894
  char *fct = obstack_finish (&ob;;
Packit 032894
Packit 032894
  instr->operands[n].fct = fct;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
#if 0
Packit 032894
static void
Packit 032894
nameout (const void *nodep, VISIT value, int level)
Packit 032894
{
Packit 032894
  if (value == leaf || value == postorder)
Packit 032894
    printf ("  %s\n", *(const char **) nodep);
Packit 032894
}
Packit 032894
#endif
Packit 032894
Packit 032894
Packit 032894
static int
Packit 032894
compare_argstring (const void *p1, const void *p2)
Packit 032894
{
Packit 032894
  const struct argstring *a1 = (const struct argstring *) p1;
Packit 032894
  const struct argstring *a2 = (const struct argstring *) p2;
Packit 032894
Packit 032894
  return strcmp (a1->str, a2->str);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static int maxoff[3][3];
Packit 032894
static int minoff[3][3] = { { 1000, 1000, 1000 },
Packit 032894
			    { 1000, 1000, 1000 },
Packit 032894
			    { 1000, 1000, 1000 } };
Packit 032894
static int nbitoff[3][3];
Packit 032894
static void *fct_names[3];
Packit 032894
static int nbitfct[3];
Packit 032894
static int nbitsuf;
Packit 032894
static void *strs[3];
Packit 032894
static int nbitstr[3];
Packit 032894
static int total_bits = 2;	// Already counted the rep/repe bits.
Packit 032894
Packit 032894
static void
Packit 032894
find_numbers (void)
Packit 032894
{
Packit 032894
  int nfct_names[3] = { 0, 0, 0 };
Packit 032894
  int nstrs[3] = { 0, 0, 0 };
Packit 032894
Packit 032894
  /* We reverse the order of the instruction list while processing it.
Packit 032894
     Later phases need it in the order in which the input file has
Packit 032894
     them.  */
Packit 032894
  struct instruction *reversed = NULL;
Packit 032894
Packit 032894
  struct instruction *runp = instructions;
Packit 032894
  while (runp != NULL)
Packit 032894
    {
Packit 032894
      for (int i = 0; i < 3; ++i)
Packit 032894
	if (runp->operands[i].fct != NULL)
Packit 032894
	  {
Packit 032894
	    struct argstring search = { .str = runp->operands[i].fct };
Packit 032894
	    if (tfind (&search, &fct_names[i], compare_argstring) == NULL)
Packit 032894
	      {
Packit 032894
		struct argstring *newp = xmalloc (sizeof (*newp));
Packit 032894
		newp->str = runp->operands[i].fct;
Packit 032894
		newp->idx = 0;
Packit 032894
		if (tsearch (newp, &fct_names[i], compare_argstring) == NULL)
Packit 032894
		  error (EXIT_FAILURE, errno, "tsearch");
Packit 032894
		++nfct_names[i];
Packit 032894
	      }
Packit 032894
Packit 032894
	    if (runp->operands[i].str != NULL)
Packit 032894
	      {
Packit 032894
		search.str = runp->operands[i].str;
Packit 032894
		if (tfind (&search, &strs[i], compare_argstring) == NULL)
Packit 032894
		  {
Packit 032894
		    struct argstring *newp = xmalloc (sizeof (*newp));
Packit 032894
		    newp->str = runp->operands[i].str;
Packit 032894
		    newp->idx = 0;
Packit 032894
		    if (tsearch (newp, &strs[i], compare_argstring) == NULL)
Packit 032894
		      error (EXIT_FAILURE, errno, "tsearch");
Packit 032894
		    ++nstrs[i];
Packit 032894
		  }
Packit 032894
	      }
Packit 032894
Packit 032894
	    maxoff[i][0] = MAX (maxoff[i][0], runp->operands[i].off1);
Packit 032894
	    maxoff[i][1] = MAX (maxoff[i][1], runp->operands[i].off2);
Packit 032894
	    maxoff[i][2] = MAX (maxoff[i][2], runp->operands[i].off3);
Packit 032894
Packit 032894
	    if (runp->operands[i].off1 > 0)
Packit 032894
	      minoff[i][0] = MIN (minoff[i][0], runp->operands[i].off1);
Packit 032894
	    if (runp->operands[i].off2 > 0)
Packit 032894
	      minoff[i][1] = MIN (minoff[i][1], runp->operands[i].off2);
Packit 032894
	    if (runp->operands[i].off3 > 0)
Packit 032894
	      minoff[i][2] = MIN (minoff[i][2], runp->operands[i].off3);
Packit 032894
	  }
Packit 032894
Packit 032894
      struct instruction *old = runp;
Packit 032894
      runp = runp->next;
Packit 032894
Packit 032894
      old->next = reversed;
Packit 032894
      reversed = old;
Packit 032894
    }
Packit 032894
  instructions = reversed;
Packit 032894
Packit 032894
  int d;
Packit 032894
  int c;
Packit 032894
  for (int i = 0; i < 3; ++i)
Packit 032894
    {
Packit 032894
      // printf ("min1 = %d, min2 = %d, min3 = %d\n", minoff[i][0], minoff[i][1], minoff[i][2]);
Packit 032894
      // printf ("max1 = %d, max2 = %d, max3 = %d\n", maxoff[i][0], maxoff[i][1], maxoff[i][2]);
Packit 032894
Packit 032894
      if (minoff[i][0] == 1000)
Packit 032894
	nbitoff[i][0] = 0;
Packit 032894
      else
Packit 032894
	{
Packit 032894
	  nbitoff[i][0] = 1;
Packit 032894
	  d = maxoff[i][0] - minoff[i][0];
Packit 032894
	  c = 1;
Packit 032894
	  while (c < d)
Packit 032894
	    {
Packit 032894
	      ++nbitoff[i][0];
Packit 032894
	      c *= 2;
Packit 032894
	    }
Packit 032894
	  total_bits += nbitoff[i][0];
Packit 032894
	}
Packit 032894
Packit 032894
      if (minoff[i][1] == 1000)
Packit 032894
	nbitoff[i][1] = 0;
Packit 032894
      else
Packit 032894
	{
Packit 032894
	  nbitoff[i][1] = 1;
Packit 032894
	  d = maxoff[i][1] - minoff[i][1];
Packit 032894
	  c = 1;
Packit 032894
	  while (c < d)
Packit 032894
	    {
Packit 032894
	      ++nbitoff[i][1];
Packit 032894
	      c *= 2;
Packit 032894
	    }
Packit 032894
	  total_bits += nbitoff[i][1];
Packit 032894
	}
Packit 032894
Packit 032894
      if (minoff[i][2] == 1000)
Packit 032894
	nbitoff[i][2] = 0;
Packit 032894
      else
Packit 032894
	{
Packit 032894
	  nbitoff[i][2] = 1;
Packit 032894
	  d = maxoff[i][2] - minoff[i][2];
Packit 032894
	  c = 1;
Packit 032894
	  while (c < d)
Packit 032894
	    {
Packit 032894
	      ++nbitoff[i][2];
Packit 032894
	      c *= 2;
Packit 032894
	    }
Packit 032894
	  total_bits += nbitoff[i][2];
Packit 032894
	}
Packit 032894
      // printf ("off1 = %d, off2 = %d, off3 = %d\n", nbitoff[i][0], nbitoff[i][1], nbitoff[i][2]);
Packit 032894
Packit 032894
      nbitfct[i] = 1;
Packit 032894
      d = nfct_names[i];
Packit 032894
      c = 1;
Packit 032894
      while (c < d)
Packit 032894
	{
Packit 032894
	  ++nbitfct[i];
Packit 032894
	  c *= 2;
Packit 032894
	}
Packit 032894
      total_bits += nbitfct[i];
Packit 032894
      // printf ("%d fct[%d], %d bits\n", nfct_names[i], i, nbitfct[i]);
Packit 032894
Packit 032894
      if (nstrs[i] != 0)
Packit 032894
	{
Packit 032894
	  nbitstr[i] = 1;
Packit 032894
	  d = nstrs[i];
Packit 032894
	  c = 1;
Packit 032894
	  while (c < d)
Packit 032894
	    {
Packit 032894
	      ++nbitstr[i];
Packit 032894
	      c *= 2;
Packit 032894
	    }
Packit 032894
	  total_bits += nbitstr[i];
Packit 032894
	}
Packit 032894
Packit 032894
      // twalk (fct_names[i], nameout);
Packit 032894
    }
Packit 032894
Packit 032894
  nbitsuf = 0;
Packit 032894
  d = nsuffixes;
Packit 032894
  c = 1;
Packit 032894
  while (c < d)
Packit 032894
    {
Packit 032894
      ++nbitsuf;
Packit 032894
      c *= 2;
Packit 032894
    }
Packit 032894
  total_bits += nbitsuf;
Packit 032894
  // printf ("%d suffixes, %d bits\n", nsuffixes, nbitsuf);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static int
Packit 032894
compare_syn (const void *p1, const void *p2)
Packit 032894
{
Packit 032894
  const struct synonym *s1 = (const struct synonym *) p1;
Packit 032894
  const struct synonym *s2 = (const struct synonym *) p2;
Packit 032894
Packit 032894
  return strcmp (s1->from, s2->from);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static int
Packit 032894
compare_suf (const void *p1, const void *p2)
Packit 032894
{
Packit 032894
  const struct suffix *s1 = (const struct suffix *) p1;
Packit 032894
  const struct suffix *s2 = (const struct suffix *) p2;
Packit 032894
Packit 032894
  return strcmp (s1->name, s2->name);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static int count_op_str;
Packit 032894
static int off_op_str;
Packit 032894
static void
Packit 032894
print_op_str (const void *nodep, VISIT value,
Packit 032894
	      int level __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  if (value == leaf || value == postorder)
Packit 032894
    {
Packit 032894
      const char *str = (*(struct argstring **) nodep)->str;
Packit 032894
      fprintf (outfile, "%s\n  \"%s",
Packit 032894
	       count_op_str == 0 ? "" : "\\0\"", str);
Packit 032894
      (*(struct argstring **) nodep)->idx = ++count_op_str;
Packit 032894
      (*(struct argstring **) nodep)->off = off_op_str;
Packit 032894
      off_op_str += strlen (str) + 1;
Packit 032894
    }
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static void
Packit 032894
print_op_str_idx (const void *nodep, VISIT value,
Packit 032894
		  int level __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  if (value == leaf || value == postorder)
Packit 032894
    printf ("  %d,\n", (*(struct argstring **) nodep)->off);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static void
Packit 032894
print_op_fct (const void *nodep, VISIT value,
Packit 032894
	      int level __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  if (value == leaf || value == postorder)
Packit 032894
    {
Packit 032894
      fprintf (outfile, "  FCT_%s,\n", (*(struct argstring **) nodep)->str);
Packit 032894
      (*(struct argstring **) nodep)->idx = ++count_op_str;
Packit 032894
    }
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
#if NMNES < 2
Packit 032894
# error "bogus NMNES value"
Packit 032894
#endif
Packit 032894
Packit 032894
static void
Packit 032894
instrtable_out (void)
Packit 032894
{
Packit 032894
  find_numbers ();
Packit 032894
Packit 032894
#if 0
Packit 032894
  create_mnemonic_table ();
Packit 032894
Packit 032894
  fprintf (outfile, "#define MNEMONIC_BITS %zu\n", best_mnemonic_bits);
Packit 032894
#else
Packit 032894
  fprintf (outfile, "#define MNEMONIC_BITS %ld\n",
Packit 032894
	   lrint (ceil (log2 (NMNES))));
Packit 032894
#endif
Packit 032894
  fprintf (outfile, "#define SUFFIX_BITS %d\n", nbitsuf);
Packit 032894
  for (int i = 0; i < 3; ++i)
Packit 032894
    {
Packit 032894
      fprintf (outfile, "#define FCT%d_BITS %d\n", i + 1, nbitfct[i]);
Packit 032894
      if (nbitstr[i] != 0)
Packit 032894
	fprintf (outfile, "#define STR%d_BITS %d\n", i + 1, nbitstr[i]);
Packit 032894
      fprintf (outfile, "#define OFF%d_1_BITS %d\n", i + 1, nbitoff[i][0]);
Packit 032894
      fprintf (outfile, "#define OFF%d_1_BIAS %d\n", i + 1, minoff[i][0]);
Packit 032894
      if (nbitoff[i][1] != 0)
Packit 032894
	{
Packit 032894
	  fprintf (outfile, "#define OFF%d_2_BITS %d\n", i + 1, nbitoff[i][1]);
Packit 032894
	  fprintf (outfile, "#define OFF%d_2_BIAS %d\n", i + 1, minoff[i][1]);
Packit 032894
	}
Packit 032894
      if (nbitoff[i][2] != 0)
Packit 032894
	{
Packit 032894
	  fprintf (outfile, "#define OFF%d_3_BITS %d\n", i + 1, nbitoff[i][2]);
Packit 032894
	  fprintf (outfile, "#define OFF%d_3_BIAS %d\n", i + 1, minoff[i][2]);
Packit 032894
	}
Packit 032894
    }
Packit 032894
Packit 032894
  fputs ("\n#include <i386_data.h>\n\n", outfile);
Packit 032894
Packit 032894
Packit 032894
#define APPEND(a, b) APPEND_ (a, b)
Packit 032894
#define APPEND_(a, b) a##b
Packit 032894
#define EMIT_SUFFIX(suf) \
Packit 032894
  fprintf (outfile, "#define suffix_%s %d\n", #suf, APPEND (suffix_, suf))
Packit 032894
  EMIT_SUFFIX (none);
Packit 032894
  EMIT_SUFFIX (w);
Packit 032894
  EMIT_SUFFIX (w0);
Packit 032894
  EMIT_SUFFIX (W);
Packit 032894
  EMIT_SUFFIX (tttn);
Packit 032894
  EMIT_SUFFIX (D);
Packit 032894
  EMIT_SUFFIX (w1);
Packit 032894
  EMIT_SUFFIX (W1);
Packit 032894
Packit 032894
  fputc_unlocked ('\n', outfile);
Packit 032894
Packit 032894
  for (int i = 0; i < 3; ++i)
Packit 032894
    {
Packit 032894
      /* Functions.  */
Packit 032894
      count_op_str = 0;
Packit 032894
      fprintf (outfile, "static const opfct_t op%d_fct[] =\n{\n  NULL,\n",
Packit 032894
	       i + 1);
Packit 032894
      twalk (fct_names[i], print_op_fct);
Packit 032894
      fputs ("};\n", outfile);
Packit 032894
Packit 032894
      /* The operand strings.  */
Packit 032894
      if (nbitstr[i] != 0)
Packit 032894
	{
Packit 032894
	  count_op_str = 0;
Packit 032894
	  off_op_str = 0;
Packit 032894
	  fprintf (outfile, "static const char op%d_str[] =", i + 1);
Packit 032894
	  twalk (strs[i], print_op_str);
Packit 032894
	  fputs ("\";\n", outfile);
Packit 032894
Packit 032894
	  fprintf (outfile, "static const uint8_t op%d_str_idx[] = {\n",
Packit 032894
		   i + 1);
Packit 032894
	  twalk (strs[i], print_op_str_idx);
Packit 032894
	  fputs ("};\n", outfile);
Packit 032894
	}
Packit 032894
    }
Packit 032894
Packit 032894
Packit 032894
  fputs ("static const struct instr_enc instrtab[] =\n{\n", outfile);
Packit 032894
  struct instruction *instr;
Packit 032894
  for (instr = instructions; instr != NULL; instr = instr->next)
Packit 032894
    {
Packit 032894
      fputs ("  {", outfile);
Packit 032894
      if (instr->mnemonic == (void *) -1l)
Packit 032894
	fputs (" .mnemonic = MNE_INVALID,", outfile);
Packit 032894
      else
Packit 032894
	fprintf (outfile, " .mnemonic = MNE_%s,", instr->mnemonic);
Packit 032894
      fprintf (outfile, " .rep = %d,", instr->rep);
Packit 032894
      fprintf (outfile, " .repe = %d,", instr->repe);
Packit 032894
      fprintf (outfile, " .suffix = %d,", instr->suffix);
Packit 032894
      fprintf (outfile, " .modrm = %d,", instr->modrm);
Packit 032894
Packit 032894
      for (int i = 0; i < 3; ++i)
Packit 032894
	{
Packit 032894
	  int idx = 0;
Packit 032894
	  if (instr->operands[i].fct != NULL)
Packit 032894
	    {
Packit 032894
	      struct argstring search = { .str = instr->operands[i].fct };
Packit 032894
	      struct argstring **res = tfind (&search, &fct_names[i],
Packit 032894
					      compare_argstring);
Packit 032894
	      assert (res != NULL);
Packit 032894
	      idx = (*res)->idx;
Packit 032894
	    }
Packit 032894
	  fprintf (outfile, " .fct%d = %d,", i + 1, idx);
Packit 032894
Packit 032894
	  idx = 0;
Packit 032894
	  if (instr->operands[i].str != NULL)
Packit 032894
	    {
Packit 032894
	      struct argstring search = { .str = instr->operands[i].str };
Packit 032894
	      struct argstring **res = tfind (&search, &strs[i],
Packit 032894
					      compare_argstring);
Packit 032894
	      assert (res != NULL);
Packit 032894
	      idx = (*res)->idx;
Packit 032894
	    }
Packit 032894
	  if (nbitstr[i] != 0)
Packit 032894
	    fprintf (outfile, " .str%d = %d,", i + 1, idx);
Packit 032894
Packit 032894
	  fprintf (outfile, " .off%d_1 = %d,", i + 1,
Packit 032894
		   MAX (0, instr->operands[i].off1 - minoff[i][0]));
Packit 032894
Packit 032894
	  if (nbitoff[i][1] != 0)
Packit 032894
	    fprintf (outfile, " .off%d_2 = %d,", i + 1,
Packit 032894
		     MAX (0, instr->operands[i].off2 - minoff[i][1]));
Packit 032894
Packit 032894
	  if (nbitoff[i][2] != 0)
Packit 032894
	    fprintf (outfile, " .off%d_3 = %d,", i + 1,
Packit 032894
		     MAX (0, instr->operands[i].off3 - minoff[i][2]));
Packit 032894
	}
Packit 032894
Packit 032894
      fputs (" },\n", outfile);
Packit 032894
    }
Packit 032894
  fputs ("};\n", outfile);
Packit 032894
Packit 032894
  fputs ("static const uint8_t match_data[] =\n{\n", outfile);
Packit 032894
  size_t cnt = 0;
Packit 032894
  for (instr = instructions; instr != NULL; instr = instr->next, ++cnt)
Packit 032894
    {
Packit 032894
      /* First count the number of bytes.  */
Packit 032894
      size_t totalbits = 0;
Packit 032894
      size_t zerobits = 0;
Packit 032894
      bool leading_p = true;
Packit 032894
      size_t leadingbits = 0;
Packit 032894
      struct bitvalue *b = instr->bytes;
Packit 032894
      while (b != NULL)
Packit 032894
	{
Packit 032894
	  if (b->type == zeroone)
Packit 032894
	    {
Packit 032894
	      ++totalbits;
Packit 032894
	      zerobits = 0;
Packit 032894
	      if (leading_p)
Packit 032894
		++leadingbits;
Packit 032894
	    }
Packit 032894
	  else
Packit 032894
	    {
Packit 032894
	      totalbits += b->field->bits;
Packit 032894
	      /* We must always count the mod/rm byte.  */
Packit 032894
	      if (strncasecmp (b->field->name, "mod", 3) == 0)
Packit 032894
		zerobits = 0;
Packit 032894
	      else
Packit 032894
		zerobits += b->field->bits;
Packit 032894
	      leading_p = false;
Packit 032894
	    }
Packit 032894
	  b = b->next;
Packit 032894
	}
Packit 032894
      size_t nbytes = (totalbits - zerobits + 7) / 8;
Packit 032894
      assert (nbytes > 0);
Packit 032894
      size_t leadingbytes = leadingbits / 8;
Packit 032894
Packit 032894
      fprintf (outfile, "  %#zx,", nbytes | (leadingbytes << 4));
Packit 032894
Packit 032894
      /* Now create the mask and byte values.  */
Packit 032894
      uint8_t byte = 0;
Packit 032894
      uint8_t mask = 0;
Packit 032894
      int nbits = 0;
Packit 032894
      b = instr->bytes;
Packit 032894
      while (b != NULL)
Packit 032894
	{
Packit 032894
	  if (b->type == zeroone)
Packit 032894
	    {
Packit 032894
	      byte = (byte << 1) | b->value;
Packit 032894
	      mask = (mask << 1) | 1;
Packit 032894
	      if (++nbits == 8)
Packit 032894
		{
Packit 032894
		  if (leadingbytes > 0)
Packit 032894
		    {
Packit 032894
		      assert (mask == 0xff);
Packit 032894
		      fprintf (outfile, " %#" PRIx8 ",", byte);
Packit 032894
		      --leadingbytes;
Packit 032894
		    }
Packit 032894
		  else
Packit 032894
		    fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",",
Packit 032894
			     mask, byte);
Packit 032894
		  byte = mask = nbits = 0;
Packit 032894
		  if (--nbytes == 0)
Packit 032894
		    break;
Packit 032894
		}
Packit 032894
	    }
Packit 032894
	  else
Packit 032894
	    {
Packit 032894
	      assert (leadingbytes == 0);
Packit 032894
Packit 032894
	      unsigned long int remaining = b->field->bits;
Packit 032894
	      while (nbits + remaining > 8)
Packit 032894
		{
Packit 032894
		  fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",",
Packit 032894
			   mask << (8 - nbits), byte << (8 - nbits));
Packit 032894
		  remaining = nbits + remaining - 8;
Packit 032894
		  byte = mask = nbits = 0;
Packit 032894
		  if (--nbytes == 0)
Packit 032894
		    break;
Packit 032894
		}
Packit 032894
	      byte <<= remaining;
Packit 032894
	      mask <<= remaining;
Packit 032894
	      nbits += remaining;
Packit 032894
	      if (nbits == 8)
Packit 032894
		{
Packit 032894
		  fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",", mask, byte);
Packit 032894
		  byte = mask = nbits = 0;
Packit 032894
		  if (--nbytes == 0)
Packit 032894
		    break;
Packit 032894
		}
Packit 032894
	    }
Packit 032894
	  b = b->next;
Packit 032894
	}
Packit 032894
Packit 032894
      fputc_unlocked ('\n', outfile);
Packit 032894
    }
Packit 032894
  fputs ("};\n", outfile);
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
#if 0
Packit 032894
static size_t mnemonic_maxlen;
Packit 032894
static size_t mnemonic_minlen;
Packit 032894
static size_t
Packit 032894
which_chars (const char *str[], size_t nstr)
Packit 032894
{
Packit 032894
  char used_char[256];
Packit 032894
  memset (used_char, '\0', sizeof (used_char));
Packit 032894
  mnemonic_maxlen = 0;
Packit 032894
  mnemonic_minlen = 10000;
Packit 032894
  for (size_t cnt = 0; cnt < nstr; ++cnt)
Packit 032894
    {
Packit 032894
      const unsigned char *cp = (const unsigned char *) str[cnt];
Packit 032894
      mnemonic_maxlen = MAX (mnemonic_maxlen, strlen ((char *) cp));
Packit 032894
      mnemonic_minlen = MIN (mnemonic_minlen, strlen ((char *) cp));
Packit 032894
      do
Packit 032894
        used_char[*cp++] = 1;
Packit 032894
      while (*cp != '\0');
Packit 032894
    }
Packit 032894
  size_t nused_char = 0;
Packit 032894
  for (size_t cnt = 0; cnt < 256; ++cnt)
Packit 032894
    if (used_char[cnt] != 0)
Packit 032894
      ++nused_char;
Packit 032894
  return nused_char;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static const char **mnemonic_strs;
Packit 032894
static size_t nmnemonic_strs;
Packit 032894
static void
Packit 032894
add_mnemonics (const void *nodep, VISIT value,
Packit 032894
	       int level __attribute__ ((unused)))
Packit 032894
{
Packit 032894
  if (value == leaf || value == postorder)
Packit 032894
    mnemonic_strs[nmnemonic_strs++] = *(const char **) nodep;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
struct charfreq
Packit 032894
{
Packit 032894
  char ch;
Packit 032894
  int freq;
Packit 032894
};
Packit 032894
static struct charfreq pfxfreq[256];
Packit 032894
static struct charfreq sfxfreq[256];
Packit 032894
Packit 032894
Packit 032894
static int
Packit 032894
compare_freq (const void *p1, const void *p2)
Packit 032894
{
Packit 032894
  const struct charfreq *c1 = (const struct charfreq *) p1;
Packit 032894
  const struct charfreq *c2 = (const struct charfreq *) p2;
Packit 032894
Packit 032894
  if (c1->freq > c2->freq)
Packit 032894
    return -1;
Packit 032894
  if (c1->freq < c2->freq)
Packit 032894
    return 1;
Packit 032894
  return 0;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static size_t
Packit 032894
compute_pfxfreq (const char *str[], size_t nstr)
Packit 032894
{
Packit 032894
  memset (pfxfreq, '\0', sizeof (pfxfreq));
Packit 032894
Packit 032894
  for (size_t i = 0; i < nstr; ++i)
Packit 032894
    pfxfreq[i].ch = i;
Packit 032894
Packit 032894
  for (size_t i = 0; i < nstr; ++i)
Packit 032894
    ++pfxfreq[*((const unsigned char *) str[i])].freq;
Packit 032894
Packit 032894
  qsort (pfxfreq, 256, sizeof (struct charfreq), compare_freq);
Packit 032894
Packit 032894
  size_t n = 0;
Packit 032894
  while (n < 256 && pfxfreq[n].freq != 0)
Packit 032894
    ++n;
Packit 032894
  return n;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
struct strsnlen
Packit 032894
{
Packit 032894
  const char *str;
Packit 032894
  size_t len;
Packit 032894
};
Packit 032894
Packit 032894
static size_t
Packit 032894
compute_sfxfreq (size_t nstr, struct strsnlen *strsnlen)
Packit 032894
{
Packit 032894
  memset (sfxfreq, '\0', sizeof (sfxfreq));
Packit 032894
Packit 032894
  for (size_t i = 0; i < nstr; ++i)
Packit 032894
    sfxfreq[i].ch = i;
Packit 032894
Packit 032894
  for (size_t i = 0; i < nstr; ++i)
Packit 032894
    ++sfxfreq[((const unsigned char *) strchrnul (strsnlen[i].str, '\0'))[-1]].freq;
Packit 032894
Packit 032894
  qsort (sfxfreq, 256, sizeof (struct charfreq), compare_freq);
Packit 032894
Packit 032894
  size_t n = 0;
Packit 032894
  while (n < 256 && sfxfreq[n].freq != 0)
Packit 032894
    ++n;
Packit 032894
  return n;
Packit 032894
}
Packit 032894
Packit 032894
Packit 032894
static void
Packit 032894
create_mnemonic_table (void)
Packit 032894
{
Packit 032894
  mnemonic_strs = xmalloc (nmnemonics * sizeof (char *));
Packit 032894
Packit 032894
  twalk (mnemonics, add_mnemonics);
Packit 032894
Packit 032894
  (void) which_chars (mnemonic_strs, nmnemonic_strs);
Packit 032894
Packit 032894
  size_t best_so_far = 100000000;
Packit 032894
  char *best_prefix = NULL;
Packit 032894
  char *best_suffix = NULL;
Packit 032894
  char *best_table = NULL;
Packit 032894
  size_t best_table_size = 0;
Packit 032894
  size_t best_table_bits = 0;
Packit 032894
  size_t best_prefix_bits = 0;
Packit 032894
Packit 032894
  /* We can precompute the prefix characters.  */
Packit 032894
  size_t npfx_char = compute_pfxfreq (mnemonic_strs, nmnemonic_strs);
Packit 032894
Packit 032894
  /* Compute best size for string representation including explicit NUL.  */
Packit 032894
  for (size_t pfxbits = 0; (1u << pfxbits) < 2 * npfx_char; ++pfxbits)
Packit 032894
    {
Packit 032894
      char prefix[1 << pfxbits];
Packit 032894
      size_t i;
Packit 032894
      for (i = 0; i < (1u << pfxbits) - 1; ++i)
Packit 032894
	prefix[i] = pfxfreq[i].ch;
Packit 032894
      prefix[i] = '\0';
Packit 032894
Packit 032894
      struct strsnlen strsnlen[nmnemonic_strs];
Packit 032894
Packit 032894
      for (i = 0; i < nmnemonic_strs; ++i)
Packit 032894
	{
Packit 032894
	  if (strchr (prefix, *mnemonic_strs[i]) != NULL)
Packit 032894
	    strsnlen[i].str = mnemonic_strs[i] + 1;
Packit 032894
	  else
Packit 032894
	    strsnlen[i].str = mnemonic_strs[i];
Packit 032894
	  strsnlen[i].len = strlen (strsnlen[i].str);
Packit 032894
	}
Packit 032894
Packit 032894
      /* With the prefixes gone, try to combine strings.  */
Packit 032894
      size_t nstrsnlen = 1;
Packit 032894
      for (i = 1; i < nmnemonic_strs; ++i)
Packit 032894
	{
Packit 032894
	  size_t j;
Packit 032894
	  for (j = 0; j < nstrsnlen; ++j)
Packit 032894
	    if (strsnlen[i].len > strsnlen[j].len
Packit 032894
		&& strcmp (strsnlen[j].str,
Packit 032894
			   strsnlen[i].str + (strsnlen[i].len
Packit 032894
					      - strsnlen[j].len)) == 0)
Packit 032894
	      {
Packit 032894
		strsnlen[j] = strsnlen[i];
Packit 032894
		break;
Packit 032894
	      }
Packit 032894
	    else if (strsnlen[i].len < strsnlen[j].len
Packit 032894
		     && strcmp (strsnlen[i].str,
Packit 032894
				strsnlen[j].str + (strsnlen[j].len
Packit 032894
						   - strsnlen[i].len)) == 0)
Packit 032894
	      break;
Packit 032894
;
Packit 032894
	  if (j == nstrsnlen)
Packit 032894
	      strsnlen[nstrsnlen++] = strsnlen[i];
Packit 032894
	}
Packit 032894
Packit 032894
      size_t nsfx_char = compute_sfxfreq (nstrsnlen, strsnlen);
Packit 032894
Packit 032894
      for (size_t sfxbits = 0; (1u << sfxbits) < 2 * nsfx_char; ++sfxbits)
Packit 032894
	{
Packit 032894
	  char suffix[1 << sfxbits];
Packit 032894
Packit 032894
	  for (i = 0; i < (1u << sfxbits) - 1; ++i)
Packit 032894
	    suffix[i] = sfxfreq[i].ch;
Packit 032894
	  suffix[i] = '\0';
Packit 032894
Packit 032894
	  size_t newlen[nstrsnlen];
Packit 032894
Packit 032894
	  for (i = 0; i < nstrsnlen; ++i)
Packit 032894
	    if (strchr (suffix, strsnlen[i].str[strsnlen[i].len - 1]) != NULL)
Packit 032894
	      newlen[i] = strsnlen[i].len - 1;
Packit 032894
	    else
Packit 032894
	      newlen[i] = strsnlen[i].len;
Packit 032894
Packit 032894
	  char charused[256];
Packit 032894
	  memset (charused, '\0', sizeof (charused));
Packit 032894
	  size_t ncharused = 0;
Packit 032894
Packit 032894
	  const char *tablestr[nstrsnlen];
Packit 032894
	  size_t ntablestr = 1;
Packit 032894
	  tablestr[0] = strsnlen[0].str;
Packit 032894
	  size_t table = newlen[0] + 1;
Packit 032894
	  for (i = 1; i < nstrsnlen; ++i)
Packit 032894
	    {
Packit 032894
	      size_t j;
Packit 032894
	      for (j = 0; j < ntablestr; ++j)
Packit 032894
		if (newlen[i] > newlen[j]
Packit 032894
		    && memcmp (tablestr[j],
Packit 032894
			       strsnlen[i].str + (newlen[i] - newlen[j]),
Packit 032894
			       newlen[j]) == 0)
Packit 032894
		  {
Packit 032894
		    table += newlen[i] - newlen[j];
Packit 032894
		    tablestr[j] = strsnlen[i].str;
Packit 032894
		    newlen[j] = newlen[i];
Packit 032894
		    break;
Packit 032894
		  }
Packit 032894
		else if (newlen[i] < newlen[j]
Packit 032894
		     && memcmp (strsnlen[i].str,
Packit 032894
				tablestr[j] + (newlen[j] - newlen[i]),
Packit 032894
				newlen[i]) == 0)
Packit 032894
		  break;
Packit 032894
Packit 032894
	      if (j == ntablestr)
Packit 032894
		{
Packit 032894
		  table += newlen[i] + 1;
Packit 032894
		  tablestr[ntablestr] = strsnlen[i].str;
Packit 032894
		  newlen[ntablestr] = newlen[i];
Packit 032894
Packit 032894
		  ++ntablestr;
Packit 032894
		}
Packit 032894
Packit 032894
	      for (size_t x = 0; x < newlen[j]; ++x)
Packit 032894
		if (charused[((const unsigned char *) tablestr[j])[x]]++ == 0)
Packit 032894
		  ++ncharused;
Packit 032894
	    }
Packit 032894
Packit 032894
	  size_t ncharused_bits = 0;
Packit 032894
	  i = 1;
Packit 032894
	  while (i < ncharused)
Packit 032894
	    {
Packit 032894
	      i *= 2;
Packit 032894
	      ++ncharused_bits;
Packit 032894
	    }
Packit 032894
Packit 032894
	  size_t table_bits = 0;
Packit 032894
	  i = 1;
Packit 032894
	  while (i < table)
Packit 032894
	    {
Packit 032894
	      i *= 2;
Packit 032894
	      ++table_bits;
Packit 032894
	    }
Packit 032894
Packit 032894
	  size_t mnemonic_bits = table_bits + pfxbits + sfxbits;
Packit 032894
	  size_t new_total = (((table + 7) / 8) * ncharused_bits + ncharused
Packit 032894
			      + (pfxbits == 0 ? 0 : (1 << pfxbits) - 1)
Packit 032894
			      + (sfxbits == 0 ? 0 : (1 << sfxbits) - 1)
Packit 032894
			      + (((total_bits + mnemonic_bits + 7) / 8)
Packit 032894
				 * ninstructions));
Packit 032894
Packit 032894
	  if (new_total < best_so_far)
Packit 032894
	    {
Packit 032894
	      best_so_far = new_total;
Packit 032894
	      best_mnemonic_bits = mnemonic_bits;
Packit 032894
Packit 032894
	      free (best_suffix);
Packit 032894
	      best_suffix = xstrdup (suffix);
Packit 032894
Packit 032894
	      free (best_prefix);
Packit 032894
	      best_prefix = xstrdup (prefix);
Packit 032894
	      best_prefix_bits = pfxbits;
Packit 032894
Packit 032894
	      best_table_size = table;
Packit 032894
	      best_table_bits = table_bits;
Packit 032894
	      char *cp = best_table = xrealloc (best_table, table);
Packit 032894
	      for (i = 0; i < ntablestr; ++i)
Packit 032894
		{
Packit 032894
		  assert (cp + newlen[i] + 1 <= best_table + table);
Packit 032894
		  cp = mempcpy (cp, tablestr[i], newlen[i]);
Packit 032894
		  *cp++ = '\0';
Packit 032894
		}
Packit 032894
	      assert (cp == best_table + table);
Packit 032894
	    }
Packit 032894
	}
Packit 032894
    }
Packit 032894
Packit 032894
  fputs ("static const char mnemonic_table[] =\n\"", outfile);
Packit 032894
  for (size_t i = 0; i < best_table_size; ++i)
Packit 032894
    {
Packit 032894
      if (((i + 1) % 60) == 0)
Packit 032894
	fputs ("\"\n\"", outfile);
Packit 032894
      if (!isascii (best_table[i]) || !isprint (best_table[i]))
Packit 032894
	fprintf (outfile, "\\%03o", best_table[i]);
Packit 032894
      else
Packit 032894
	fputc (best_table[i], outfile);
Packit 032894
    }
Packit 032894
  fputs ("\";\n", outfile);
Packit 032894
Packit 032894
  if (best_prefix[0] != '\0')
Packit 032894
    fprintf (outfile,
Packit 032894
	     "static const char prefix[%zu] = \"%s\";\n"
Packit 032894
	     "#define PREFIXCHAR_BITS %zu\n",
Packit 032894
	     strlen (best_prefix), best_prefix, best_prefix_bits);
Packit 032894
  else
Packit 032894
    fputs ("#define NO_PREFIX\n", outfile);
Packit 032894
Packit 032894
  if (best_suffix[0] != '\0')
Packit 032894
    fprintf (outfile, "static const char suffix[%zu] = \"%s\";\n",
Packit 032894
	     strlen (best_suffix), best_suffix);
Packit 032894
  else
Packit 032894
    fputs ("#define NO_SUFFIX\n", outfile);
Packit 032894
Packit 032894
  for (size_t i = 0; i < nmnemonic_strs; ++i)
Packit 032894
    {
Packit 032894
      const char *mne = mnemonic_strs[i];
Packit 032894
Packit 032894
      size_t pfxval = 0;
Packit 032894
      char *cp = strchr (best_prefix, *mne);
Packit 032894
      if (cp != NULL)
Packit 032894
	{
Packit 032894
	  pfxval = 1 + (cp - best_prefix);
Packit 032894
	  ++mne;
Packit 032894
	}
Packit 032894
Packit 032894
      size_t l = strlen (mne);
Packit 032894
Packit 032894
      size_t sfxval = 0;
Packit 032894
      cp = strchr (best_suffix, mne[l - 1]);
Packit 032894
      if (cp != NULL)
Packit 032894
	{
Packit 032894
	  sfxval = 1 + (cp - best_suffix);
Packit 032894
	  --l;
Packit 032894
	}
Packit 032894
Packit 032894
      char *off = memmem (best_table, best_table_size, mne, l);
Packit 032894
      while (off[l] != '\0')
Packit 032894
	{
Packit 032894
	  off = memmem (off + 1, best_table_size, mne, l);
Packit 032894
	  assert (off != NULL);
Packit 032894
	}
Packit 032894
Packit 032894
      fprintf (outfile, "#define MNE_%s %#zx\n",
Packit 032894
	       mnemonic_strs[i],
Packit 032894
	       (off - best_table)
Packit 032894
	       + ((pfxval + (sfxval << best_prefix_bits)) << best_table_bits));
Packit 032894
    }
Packit 032894
}
Packit 032894
#endif