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