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