1/* itbl-ops.c
2   Copyright (C) 1997-2017 Free Software Foundation, Inc.
3
4   This file is part of GAS, the GNU Assembler.
5
6   GAS is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3, or (at your option)
9   any later version.
10
11   GAS is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with GAS; see the file COPYING.  If not, write to the Free
18   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19   02110-1301, USA.  */
20
21/*======================================================================*/
22/*
23 * Herein lies the support for dynamic specification of processor
24 * instructions and registers.  Mnemonics, values, and formats for each
25 * instruction and register are specified in an ascii file consisting of
26 * table entries.  The grammar for the table is defined in the document
27 * "Processor instruction table specification".
28 *
29 * Instructions use the gnu assembler syntax, with the addition of
30 * allowing mnemonics for register.
31 * Eg. "func $2,reg3,0x100,symbol ; comment"
32 * 	func - opcode name
33 * 	$n - register n
34 * 	reg3 - mnemonic for processor's register defined in table
35 * 	0xddd..d - immediate value
36 * 	symbol - address of label or external symbol
37 *
38 * First, itbl_parse reads in the table of register and instruction
39 * names and formats, and builds a list of entries for each
40 * processor/type combination.  lex and yacc are used to parse
41 * the entries in the table and call functions defined here to
42 * add each entry to our list.
43 *
44 * Then, when assembling or disassembling, these functions are called to
45 * 1) get information on a processor's registers and
46 * 2) assemble/disassemble an instruction.
47 * To assemble(disassemble) an instruction, the function
48 * itbl_assemble(itbl_disassemble) is called to search the list of
49 * instruction entries, and if a match is found, uses the format
50 * described in the instruction entry structure to complete the action.
51 *
52 * Eg. Suppose we have a Mips coprocessor "cop3" with data register "d2"
53 * and we want to define function "pig" which takes two operands.
54 *
55 * Given the table entries:
56 * 	"p3 insn pig 0x1:24-21 dreg:20-16 immed:15-0"
57 * 	"p3 dreg d2 0x2"
58 * and that the instruction encoding for coprocessor pz has encoding:
59 * 	#define MIPS_ENCODE_COP_NUM(z) ((0x21|(z<<1))<<25)
60 * 	#define ITBL_ENCODE_PNUM(pnum) MIPS_ENCODE_COP_NUM(pnum)
61 *
62 * a structure to describe the instruction might look something like:
63 *      struct itbl_entry = {
64 *      e_processor processor = e_p3
65 *      e_type type = e_insn
66 *      char *name = "pig"
67 *      uint value = 0x1
68 *      uint flags = 0
69 *      struct itbl_range range = 24-21
70 *      struct itbl_field *field = {
71 *              e_type type = e_dreg
72 *              struct itbl_range range = 20-16
73 *              struct itbl_field *next = {
74 *                      e_type type = e_immed
75 *                      struct itbl_range range = 15-0
76 *                      struct itbl_field *next = 0
77 *                      };
78 *              };
79 *      struct itbl_entry *next = 0
80 *      };
81 *
82 * And the assembler instructions:
83 * 	"pig d2,0x100"
84 * 	"pig $2,0x100"
85 *
86 * would both assemble to the hex value:
87 * 	"0x4e220100"
88 *
89 */
90
91#include "as.h"
92#include "itbl-ops.h"
93#include <itbl-parse.h>
94
95/* #define DEBUG */
96
97#ifdef DEBUG
98#include <assert.h>
99#define ASSERT(x) gas_assert (x)
100#define DBG(x) printf x
101#else
102#define ASSERT(x)
103#define DBG(x)
104#endif
105
106#ifndef min
107#define min(a,b) (a<b?a:b)
108#endif
109
110int itbl_have_entries = 0;
111
112/*======================================================================*/
113/* structures for keeping itbl format entries */
114
115struct itbl_range {
116  int sbit;			/* mask starting bit position */
117  int ebit;			/* mask ending bit position */
118};
119
120struct itbl_field {
121  e_type type;			/* dreg/creg/greg/immed/symb */
122  struct itbl_range range;	/* field's bitfield range within instruction */
123  unsigned long flags;		/* field flags */
124  struct itbl_field *next;	/* next field in list */
125};
126
127/* These structures define the instructions and registers for a processor.
128 * If the type is an instruction, the structure defines the format of an
129 * instruction where the fields are the list of operands.
130 * The flags field below uses the same values as those defined in the
131 * gnu assembler and are machine specific.  */
132struct itbl_entry {
133  e_processor processor;	/* processor number */
134  e_type type;			/* dreg/creg/greg/insn */
135  char *name;			/* mnemionic name for insn/register */
136  unsigned long value;		/* opcode/instruction mask/register number */
137  unsigned long flags;		/* effects of the instruction */
138  struct itbl_range range;	/* bit range within instruction for value */
139  struct itbl_field *fields;	/* list of operand definitions (if any) */
140  struct itbl_entry *next;	/* next entry */
141};
142
143/* local data and structures */
144
145static int itbl_num_opcodes = 0;
146/* Array of entries for each processor and entry type */
147static struct itbl_entry *entries[e_nprocs][e_ntypes];
148
149/* local prototypes */
150static unsigned long build_opcode (struct itbl_entry *e);
151static e_type get_type (int yytype);
152static e_processor get_processor (int yyproc);
153static struct itbl_entry **get_entries (e_processor processor,
154					e_type type);
155static struct itbl_entry *find_entry_byname (e_processor processor,
156					e_type type, char *name);
157static struct itbl_entry *find_entry_byval (e_processor processor,
158			e_type type, unsigned long val, struct itbl_range *r);
159static struct itbl_entry *alloc_entry (e_processor processor,
160		e_type type, char *name, unsigned long value);
161static unsigned long apply_range (unsigned long value, struct itbl_range r);
162static unsigned long extract_range (unsigned long value, struct itbl_range r);
163static struct itbl_field *alloc_field (e_type type, int sbit,
164					int ebit, unsigned long flags);
165
166/*======================================================================*/
167/* Interfaces to the parser */
168
169/* Open the table and use lex and yacc to parse the entries.
170 * Return 1 for failure; 0 for success.  */
171
172int
173itbl_parse (char *insntbl)
174{
175  extern FILE *yyin;
176  extern int yyparse (void);
177
178  yyin = fopen (insntbl, FOPEN_RT);
179  if (yyin == 0)
180    {
181      printf ("Can't open processor instruction specification file \"%s\"\n",
182	      insntbl);
183      return 1;
184    }
185
186  while (yyparse ())
187    ;
188
189  fclose (yyin);
190  itbl_have_entries = 1;
191  return 0;
192}
193
194/* Add a register entry */
195
196struct itbl_entry *
197itbl_add_reg (int yyprocessor, int yytype, char *regname,
198	      int regnum)
199{
200  return alloc_entry (get_processor (yyprocessor), get_type (yytype), regname,
201		      (unsigned long) regnum);
202}
203
204/* Add an instruction entry */
205
206struct itbl_entry *
207itbl_add_insn (int yyprocessor, char *name, unsigned long value,
208	       int sbit, int ebit, unsigned long flags)
209{
210  struct itbl_entry *e;
211  e = alloc_entry (get_processor (yyprocessor), e_insn, name, value);
212  if (e)
213    {
214      e->range.sbit = sbit;
215      e->range.ebit = ebit;
216      e->flags = flags;
217      itbl_num_opcodes++;
218    }
219  return e;
220}
221
222/* Add an operand to an instruction entry */
223
224struct itbl_field *
225itbl_add_operand (struct itbl_entry *e, int yytype, int sbit,
226		  int ebit, unsigned long flags)
227{
228  struct itbl_field *f, **last_f;
229  if (!e)
230    return 0;
231  /* Add to end of fields' list.  */
232  f = alloc_field (get_type (yytype), sbit, ebit, flags);
233  if (f)
234    {
235      last_f = &e->fields;
236      while (*last_f)
237	last_f = &(*last_f)->next;
238      *last_f = f;
239      f->next = 0;
240    }
241  return f;
242}
243
244/*======================================================================*/
245/* Interfaces for assembler and disassembler */
246
247#ifndef STAND_ALONE
248static void append_insns_as_macros (void);
249
250/* Initialize for gas.  */
251
252void
253itbl_init (void)
254{
255  struct itbl_entry *e, **es;
256  e_processor procn;
257  e_type type;
258
259  if (!itbl_have_entries)
260    return;
261
262  /* Since register names don't have a prefix, put them in the symbol table so
263     they can't be used as symbols.  This simplifies argument parsing as
264     we can let gas parse registers for us.  */
265  /* Use symbol_create instead of symbol_new so we don't try to
266     output registers into the object file's symbol table.  */
267
268  for (type = e_regtype0; type < e_nregtypes; type++)
269    for (procn = e_p0; procn < e_nprocs; procn++)
270      {
271	es = get_entries (procn, type);
272	for (e = *es; e; e = e->next)
273	  {
274	    symbol_table_insert (symbol_create (e->name, reg_section,
275						e->value, &zero_address_frag));
276	  }
277      }
278  append_insns_as_macros ();
279}
280
281/* Append insns to opcodes table and increase number of opcodes
282 * Structure of opcodes table:
283 * struct itbl_opcode
284 * {
285 *   const char *name;
286 *   const char *args; 		- string describing the arguments.
287 *   unsigned long match; 	- opcode, or ISA level if pinfo=INSN_MACRO
288 *   unsigned long mask; 	- opcode mask, or macro id if pinfo=INSN_MACRO
289 *   unsigned long pinfo; 	- insn flags, or INSN_MACRO
290 * };
291 * examples:
292 *	{"li",      "t,i",  0x34000000, 0xffe00000, WR_t    },
293 *	{"li",      "t,I",  0,    (int) M_LI,   INSN_MACRO  },
294 */
295
296static char *form_args (struct itbl_entry *e);
297static void
298append_insns_as_macros (void)
299{
300  struct ITBL_OPCODE_STRUCT *new_opcodes, *o;
301  struct itbl_entry *e, **es;
302  int n, size, new_num_opcodes;
303#ifdef USE_MACROS
304  int id;
305#endif
306
307  if (!itbl_have_entries)
308    return;
309
310  if (!itbl_num_opcodes)	/* no new instructions to add! */
311    {
312      return;
313    }
314  DBG (("previous num_opcodes=%d\n", ITBL_NUM_OPCODES));
315
316  new_num_opcodes = ITBL_NUM_OPCODES + itbl_num_opcodes;
317  ASSERT (new_num_opcodes >= itbl_num_opcodes);
318
319  size = sizeof (struct ITBL_OPCODE_STRUCT) * ITBL_NUM_OPCODES;
320  ASSERT (size >= 0);
321  DBG (("I get=%d\n", size / sizeof (ITBL_OPCODES[0])));
322
323  /* FIXME since ITBL_OPCODES culd be a static table,
324		we can't realloc or delete the old memory.  */
325  new_opcodes = XNEWVEC (struct ITBL_OPCODE_STRUCT, new_num_opcodes);
326  if (!new_opcodes)
327    {
328      printf (_("Unable to allocate memory for new instructions\n"));
329      return;
330    }
331  if (size)			/* copy preexisting opcodes table */
332    memcpy (new_opcodes, ITBL_OPCODES, size);
333
334  /* FIXME! some NUMOPCODES are calculated expressions.
335		These need to be changed before itbls can be supported.  */
336
337#ifdef USE_MACROS
338  id = ITBL_NUM_MACROS;		/* begin the next macro id after the last */
339#endif
340  o = &new_opcodes[ITBL_NUM_OPCODES];	/* append macro to opcodes list */
341  for (n = e_p0; n < e_nprocs; n++)
342    {
343      es = get_entries (n, e_insn);
344      for (e = *es; e; e = e->next)
345	{
346	  /* name,    args,   mask,       match,  pinfo
347		 * {"li",      "t,i",  0x34000000, 0xffe00000, WR_t    },
348		 * {"li",      "t,I",  0,    (int) M_LI,   INSN_MACRO  },
349		 * Construct args from itbl_fields.
350		*/
351	  o->name = e->name;
352	  o->args = strdup (form_args (e));
353	  o->mask = apply_range (e->value, e->range);
354	  /* FIXME how to catch during assembly? */
355	  /* mask to identify this insn */
356	  o->match = apply_range (e->value, e->range);
357	  o->pinfo = 0;
358
359#ifdef USE_MACROS
360	  o->mask = id++;	/* FIXME how to catch during assembly? */
361	  o->match = 0;		/* for macros, the insn_isa number */
362	  o->pinfo = INSN_MACRO;
363#endif
364
365	  /* Don't add instructions which caused an error */
366	  if (o->args)
367	    o++;
368	  else
369	    new_num_opcodes--;
370	}
371    }
372  ITBL_OPCODES = new_opcodes;
373  ITBL_NUM_OPCODES = new_num_opcodes;
374
375  /* FIXME
376		At this point, we can free the entries, as they should have
377		been added to the assembler's tables.
378		Don't free name though, since name is being used by the new
379		opcodes table.
380
381		Eventually, we should also free the new opcodes table itself
382		on exit.
383	*/
384}
385
386static char *
387form_args (struct itbl_entry *e)
388{
389  static char s[31];
390  char c = 0, *p = s;
391  struct itbl_field *f;
392
393  ASSERT (e);
394  for (f = e->fields; f; f = f->next)
395    {
396      switch (f->type)
397	{
398	case e_dreg:
399	  c = 'd';
400	  break;
401	case e_creg:
402	  c = 't';
403	  break;
404	case e_greg:
405	  c = 's';
406	  break;
407	case e_immed:
408	  c = 'i';
409	  break;
410	case e_addr:
411	  c = 'a';
412	  break;
413	default:
414	  c = 0;		/* ignore; unknown field type */
415	}
416      if (c)
417	{
418	  if (p != s)
419	    *p++ = ',';
420	  *p++ = c;
421	}
422    }
423  *p = 0;
424  return s;
425}
426#endif /* !STAND_ALONE */
427
428/* Get processor's register name from val */
429
430int
431itbl_get_reg_val (char *name, unsigned long *pval)
432{
433  e_type t;
434  e_processor p;
435
436  for (p = e_p0; p < e_nprocs; p++)
437    {
438      for (t = e_regtype0; t < e_nregtypes; t++)
439	{
440	  if (itbl_get_val (p, t, name, pval))
441	    return 1;
442	}
443    }
444  return 0;
445}
446
447char *
448itbl_get_name (e_processor processor, e_type type, unsigned long val)
449{
450  struct itbl_entry *r;
451  /* type depends on instruction passed */
452  r = find_entry_byval (processor, type, val, 0);
453  if (r)
454    return r->name;
455  else
456    return 0;			/* error; invalid operand */
457}
458
459/* Get processor's register value from name */
460
461int
462itbl_get_val (e_processor processor, e_type type, char *name,
463	      unsigned long *pval)
464{
465  struct itbl_entry *r;
466  /* type depends on instruction passed */
467  r = find_entry_byname (processor, type, name);
468  if (r == NULL)
469    return 0;
470  *pval = r->value;
471  return 1;
472}
473
474/* Assemble instruction "name" with operands "s".
475 * name - name of instruction
476 * s - operands
477 * returns - long word for assembled instruction */
478
479unsigned long
480itbl_assemble (char *name, char *s)
481{
482  unsigned long opcode;
483  struct itbl_entry *e = NULL;
484  struct itbl_field *f;
485  char *n;
486  int processor;
487
488  if (!name || !*name)
489    return 0;			/* error!  must have an opcode name/expr */
490
491  /* find entry in list of instructions for all processors */
492  for (processor = 0; processor < e_nprocs; processor++)
493    {
494      e = find_entry_byname (processor, e_insn, name);
495      if (e)
496	break;
497    }
498  if (!e)
499    return 0;			/* opcode not in table; invalid instruction */
500  opcode = build_opcode (e);
501
502  /* parse opcode's args (if any) */
503  for (f = e->fields; f; f = f->next)	/* for each arg, ...  */
504    {
505      struct itbl_entry *r;
506      unsigned long value;
507      if (!s || !*s)
508	return 0;		/* error - not enough operands */
509      n = itbl_get_field (&s);
510      /* n should be in form $n or 0xhhh (are symbol names valid?? */
511      switch (f->type)
512	{
513	case e_dreg:
514	case e_creg:
515	case e_greg:
516	  /* Accept either a string name
517			 * or '$' followed by the register number */
518	  if (*n == '$')
519	    {
520	      n++;
521	      value = strtol (n, 0, 10);
522	      /* FIXME! could have "0l"... then what?? */
523	      if (value == 0 && *n != '0')
524		return 0;	/* error; invalid operand */
525	    }
526	  else
527	    {
528	      r = find_entry_byname (e->processor, f->type, n);
529	      if (r)
530		value = r->value;
531	      else
532		return 0;	/* error; invalid operand */
533	    }
534	  break;
535	case e_addr:
536	  /* use assembler's symbol table to find symbol */
537	  /* FIXME!! Do we need this?
538				if so, what about relocs??
539				my_getExpression (&imm_expr, s);
540				return 0;	/-* error; invalid operand *-/
541				break;
542			*/
543	  /* If not a symbol, fallthru to IMMED */
544	case e_immed:
545	  if (*n == '0' && *(n + 1) == 'x')	/* hex begins 0x...  */
546	    {
547	      n += 2;
548	      value = strtol (n, 0, 16);
549	      /* FIXME! could have "0xl"... then what?? */
550	    }
551	  else
552	    {
553	      value = strtol (n, 0, 10);
554	      /* FIXME! could have "0l"... then what?? */
555	      if (value == 0 && *n != '0')
556		return 0;	/* error; invalid operand */
557	    }
558	  break;
559	default:
560	  return 0;		/* error; invalid field spec */
561	}
562      opcode |= apply_range (value, f->range);
563    }
564  if (s && *s)
565    return 0;			/* error - too many operands */
566  return opcode;		/* done! */
567}
568
569/* Disassemble instruction "insn".
570 * insn - instruction
571 * s - buffer to hold disassembled instruction
572 * returns - 1 if succeeded; 0 if failed
573 */
574
575int
576itbl_disassemble (char *s, unsigned long insn)
577{
578  e_processor processor;
579  struct itbl_entry *e;
580  struct itbl_field *f;
581
582  if (!ITBL_IS_INSN (insn))
583    return 0;			/* error */
584  processor = get_processor (ITBL_DECODE_PNUM (insn));
585
586  /* find entry in list */
587  e = find_entry_byval (processor, e_insn, insn, 0);
588  if (!e)
589    return 0;			/* opcode not in table; invalid instruction */
590  strcpy (s, e->name);
591
592  /* Parse insn's args (if any).  */
593  for (f = e->fields; f; f = f->next)	/* for each arg, ...  */
594    {
595      struct itbl_entry *r;
596      unsigned long value;
597      char s_value[20];
598
599      if (f == e->fields)	/* First operand is preceded by tab.  */
600	strcat (s, "\t");
601      else			/* ','s separate following operands.  */
602	strcat (s, ",");
603      value = extract_range (insn, f->range);
604      /* n should be in form $n or 0xhhh (are symbol names valid?? */
605      switch (f->type)
606	{
607	case e_dreg:
608	case e_creg:
609	case e_greg:
610	  /* Accept either a string name
611	     or '$' followed by the register number.  */
612	  r = find_entry_byval (e->processor, f->type, value, &f->range);
613	  if (r)
614	    strcat (s, r->name);
615	  else
616	    {
617	      sprintf (s_value, "$%lu", value);
618	      strcat (s, s_value);
619	    }
620	  break;
621	case e_addr:
622	  /* Use assembler's symbol table to find symbol.  */
623	  /* FIXME!! Do we need this?  If so, what about relocs??  */
624	  /* If not a symbol, fall through to IMMED.  */
625	case e_immed:
626	  sprintf (s_value, "0x%lx", value);
627	  strcat (s, s_value);
628	  break;
629	default:
630	  return 0;		/* error; invalid field spec */
631	}
632    }
633  return 1;			/* Done!  */
634}
635
636/*======================================================================*/
637/*
638 * Local functions for manipulating private structures containing
639 * the names and format for the new instructions and registers
640 * for each processor.
641 */
642
643/* Calculate instruction's opcode and function values from entry */
644
645static unsigned long
646build_opcode (struct itbl_entry *e)
647{
648  unsigned long opcode;
649
650  opcode = apply_range (e->value, e->range);
651  opcode |= ITBL_ENCODE_PNUM (e->processor);
652  return opcode;
653}
654
655/* Calculate absolute value given the relative value and bit position range
656 * within the instruction.
657 * The range is inclusive where 0 is least significant bit.
658 * A range of { 24, 20 } will have a mask of
659 * bit   3           2            1
660 * pos: 1098 7654 3210 9876 5432 1098 7654 3210
661 * bin: 0000 0001 1111 0000 0000 0000 0000 0000
662 * hex:    0    1    f    0    0    0    0    0
663 * mask: 0x01f00000.
664 */
665
666static unsigned long
667apply_range (unsigned long rval, struct itbl_range r)
668{
669  unsigned long mask;
670  unsigned long aval;
671  int len = MAX_BITPOS - r.sbit;
672
673  ASSERT (r.sbit >= r.ebit);
674  ASSERT (MAX_BITPOS >= r.sbit);
675  ASSERT (r.ebit >= 0);
676
677  /* create mask by truncating 1s by shifting */
678  mask = 0xffffffff << len;
679  mask = mask >> len;
680  mask = mask >> r.ebit;
681  mask = mask << r.ebit;
682
683  aval = (rval << r.ebit) & mask;
684  return aval;
685}
686
687/* Calculate relative value given the absolute value and bit position range
688 * within the instruction.  */
689
690static unsigned long
691extract_range (unsigned long aval, struct itbl_range r)
692{
693  unsigned long mask;
694  unsigned long rval;
695  int len = MAX_BITPOS - r.sbit;
696
697  /* create mask by truncating 1s by shifting */
698  mask = 0xffffffff << len;
699  mask = mask >> len;
700  mask = mask >> r.ebit;
701  mask = mask << r.ebit;
702
703  rval = (aval & mask) >> r.ebit;
704  return rval;
705}
706
707/* Extract processor's assembly instruction field name from s;
708 * forms are "n args" "n,args" or "n" */
709/* Return next argument from string pointer "s" and advance s.
710 * delimiters are " ,()" */
711
712char *
713itbl_get_field (char **S)
714{
715  static char n[128];
716  char *s;
717  int len;
718
719  s = *S;
720  if (!s || !*s)
721    return 0;
722  /* FIXME: This is a weird set of delimiters.  */
723  len = strcspn (s, " \t,()");
724  ASSERT (128 > len + 1);
725  strncpy (n, s, len);
726  n[len] = 0;
727  if (s[len] == '\0')
728    s = 0;			/* no more args */
729  else
730    s += len + 1;		/* advance to next arg */
731
732  *S = s;
733  return n;
734}
735
736/* Search entries for a given processor and type
737 * to find one matching the name "n".
738 * Return a pointer to the entry */
739
740static struct itbl_entry *
741find_entry_byname (e_processor processor,
742		   e_type type, char *n)
743{
744  struct itbl_entry *e, **es;
745
746  es = get_entries (processor, type);
747  for (e = *es; e; e = e->next)	/* for each entry, ...  */
748    {
749      if (!strcmp (e->name, n))
750	return e;
751    }
752  return 0;
753}
754
755/* Search entries for a given processor and type
756 * to find one matching the value "val" for the range "r".
757 * Return a pointer to the entry.
758 * This function is used for disassembling fields of an instruction.
759 */
760
761static struct itbl_entry *
762find_entry_byval (e_processor processor, e_type type,
763		  unsigned long val, struct itbl_range *r)
764{
765  struct itbl_entry *e, **es;
766  unsigned long eval;
767
768  es = get_entries (processor, type);
769  for (e = *es; e; e = e->next)	/* for each entry, ...  */
770    {
771      if (processor != e->processor)
772	continue;
773      /* For insns, we might not know the range of the opcode,
774	 * so a range of 0 will allow this routine to match against
775	 * the range of the entry to be compared with.
776	 * This could cause ambiguities.
777	 * For operands, we get an extracted value and a range.
778	 */
779      /* if range is 0, mask val against the range of the compared entry.  */
780      if (r == 0)		/* if no range passed, must be whole 32-bits
781			 * so create 32-bit value from entry's range */
782	{
783	  eval = apply_range (e->value, e->range);
784	  val &= apply_range (0xffffffff, e->range);
785	}
786      else if ((r->sbit == e->range.sbit && r->ebit == e->range.ebit)
787	       || (e->range.sbit == 0 && e->range.ebit == 0))
788	{
789	  eval = apply_range (e->value, *r);
790	  val = apply_range (val, *r);
791	}
792      else
793	continue;
794      if (val == eval)
795	return e;
796    }
797  return 0;
798}
799
800/* Return a pointer to the list of entries for a given processor and type.  */
801
802static struct itbl_entry **
803get_entries (e_processor processor, e_type type)
804{
805  return &entries[processor][type];
806}
807
808/* Return an integral value for the processor passed from yyparse.  */
809
810static e_processor
811get_processor (int yyproc)
812{
813  /* translate from yacc's processor to enum */
814  if (yyproc >= e_p0 && yyproc < e_nprocs)
815    return (e_processor) yyproc;
816  return e_invproc;		/* error; invalid processor */
817}
818
819/* Return an integral value for the entry type passed from yyparse.  */
820
821static e_type
822get_type (int yytype)
823{
824  switch (yytype)
825    {
826      /* translate from yacc's type to enum */
827    case INSN:
828      return e_insn;
829    case DREG:
830      return e_dreg;
831    case CREG:
832      return e_creg;
833    case GREG:
834      return e_greg;
835    case ADDR:
836      return e_addr;
837    case IMMED:
838      return e_immed;
839    default:
840      return e_invtype;		/* error; invalid type */
841    }
842}
843
844/* Allocate and initialize an entry */
845
846static struct itbl_entry *
847alloc_entry (e_processor processor, e_type type,
848	     char *name, unsigned long value)
849{
850  struct itbl_entry *e, **es;
851  if (!name)
852    return 0;
853  e = XNEW (struct itbl_entry);
854  if (e)
855    {
856      memset (e, 0, sizeof (struct itbl_entry));
857      e->name = xstrdup (name);
858      e->processor = processor;
859      e->type = type;
860      e->value = value;
861      es = get_entries (e->processor, e->type);
862      e->next = *es;
863      *es = e;
864    }
865  return e;
866}
867
868/* Allocate and initialize an entry's field */
869
870static struct itbl_field *
871alloc_field (e_type type, int sbit, int ebit,
872	     unsigned long flags)
873{
874  struct itbl_field *f;
875  f = XNEW (struct itbl_field);
876  if (f)
877    {
878      memset (f, 0, sizeof (struct itbl_field));
879      f->type = type;
880      f->range.sbit = sbit;
881      f->range.ebit = ebit;
882      f->flags = flags;
883    }
884  return f;
885}
886