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