* dw2gencfi.c (output_cie, output_fde): Use DW_CFA_nop rather
[deliverable/binutils-gdb.git] / gas / itbl-ops.c
CommitLineData
252b5132 1/* itbl-ops.c
3438adb3 2 Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
252b5132
RH
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"
3d82a647 95#include <itbl-parse.h>
252b5132
RH
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
112int itbl_have_entries = 0;
113
114/*======================================================================*/
115/* structures for keeping itbl format entries */
116
ef99799a
KH
117struct itbl_range {
118 int sbit; /* mask starting bit position */
119 int ebit; /* mask ending bit position */
120};
121
122struct 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};
252b5132 128
252b5132
RH
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
c488923f 133 * gnu assembler and are machine specific. */
ef99799a
KH
134struct 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};
252b5132 144
252b5132
RH
145/* local data and structures */
146
147static int itbl_num_opcodes = 0;
148/* Array of entries for each processor and entry type */
ef99799a 149static struct itbl_entry *entries[e_nprocs][e_ntypes] = {
252b5132
RH
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 */
b1f1fa96
KH
157static unsigned long build_opcode (struct itbl_entry *e);
158static e_type get_type (int yytype);
159static e_processor get_processor (int yyproc);
160static struct itbl_entry **get_entries (e_processor processor,
161 e_type type);
162static struct itbl_entry *find_entry_byname (e_processor processor,
163 e_type type, char *name);
164static struct itbl_entry *find_entry_byval (e_processor processor,
165 e_type type, unsigned long val, struct itbl_range *r);
166static struct itbl_entry *alloc_entry (e_processor processor,
167 e_type type, char *name, unsigned long value);
168static unsigned long apply_range (unsigned long value, struct itbl_range r);
169static unsigned long extract_range (unsigned long value, struct itbl_range r);
170static struct itbl_field *alloc_field (e_type type, int sbit,
171 int ebit, unsigned long flags);
252b5132 172
252b5132
RH
173/*======================================================================*/
174/* Interfaces to the parser */
175
252b5132
RH
176/* Open the table and use lex and yacc to parse the entries.
177 * Return 1 for failure; 0 for success. */
178
c488923f 179int
252b5132
RH
180itbl_parse (char *insntbl)
181{
182 extern FILE *yyin;
183 extern int yyparse (void);
f740e790
NC
184
185 yyin = fopen (insntbl, FOPEN_RT);
252b5132
RH
186 if (yyin == 0)
187 {
188 printf ("Can't open processor instruction specification file \"%s\"\n",
189 insntbl);
190 return 1;
191 }
f740e790
NC
192
193 while (yyparse ())
194 ;
195
252b5132
RH
196 fclose (yyin);
197 itbl_have_entries = 1;
198 return 0;
199}
200
201/* Add a register entry */
202
203struct itbl_entry *
204itbl_add_reg (int yyprocessor, int yytype, char *regname,
205 int regnum)
206{
252b5132
RH
207 return alloc_entry (get_processor (yyprocessor), get_type (yytype), regname,
208 (unsigned long) regnum);
209}
210
211/* Add an instruction entry */
212
213struct itbl_entry *
214itbl_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
231struct itbl_field *
232itbl_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;
c488923f 238 /* Add to end of fields' list. */
252b5132
RH
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
252b5132
RH
251/*======================================================================*/
252/* Interfaces for assembler and disassembler */
253
254#ifndef STAND_ALONE
255#include "as.h"
256#include "symbols.h"
257static void append_insns_as_macros (void);
258
ef99799a
KH
259/* Initialize for gas. */
260
c488923f 261void
252b5132
RH
262itbl_init (void)
263{
264 struct itbl_entry *e, **es;
265 e_processor procn;
266 e_type type;
267
268 if (!itbl_have_entries)
ef99799a 269 return;
252b5132
RH
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
c488923f 273 we can let gas parse registers for us. */
252b5132
RH
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,
ef99799a 284 e->value, &zero_address_frag));
252b5132
RH
285 }
286 }
287 append_insns_as_macros ();
288}
289
c488923f
KH
290/* Append insns to opcodes table and increase number of opcodes
291 * Structure of opcodes table:
252b5132
RH
292 * struct itbl_opcode
293 * {
294 * const char *name;
c488923f
KH
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
252b5132
RH
299 * };
300 * examples:
301 * {"li", "t,i", 0x34000000, 0xffe00000, WR_t },
302 * {"li", "t,I", 0, (int) M_LI, INSN_MACRO },
303 */
304
305static char *form_args (struct itbl_entry *e);
c488923f 306static void
252b5132
RH
307append_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)
ef99799a 314 return;
252b5132
RH
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,
c488923f 333 we can't realloc or delete the old memory. */
252b5132
RH
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 }
47eebc20 340 if (size) /* copy preexisting opcodes table */
252b5132
RH
341 memcpy (new_opcodes, ITBL_OPCODES, size);
342
343 /* FIXME! some NUMOPCODES are calculated expressions.
c488923f 344 These need to be changed before itbls can be supported. */
252b5132
RH
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);
47eebc20 361 /* FIXME how to catch during assembly? */
252b5132
RH
362 /* mask to identify this insn */
363 o->match = apply_range (e->value, e->range);
364 o->pinfo = 0;
365
366#ifdef USE_MACROS
47eebc20 367 o->mask = id++; /* FIXME how to catch during assembly? */
252b5132
RH
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
c488923f 388 Eventually, we should also free the new opcodes table itself
252b5132
RH
389 on exit.
390 */
391}
392
393static char *
394form_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
252b5132
RH
435/* Get processor's register name from val */
436
d7ba4a77
ILT
437int
438itbl_get_reg_val (char *name, unsigned long *pval)
252b5132
RH
439{
440 e_type t;
441 e_processor p;
d7ba4a77 442
252b5132 443 for (p = e_p0; p < e_nprocs; p++)
d7ba4a77
ILT
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 }
252b5132
RH
451 return 0;
452}
453
454char *
455itbl_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
d7ba4a77
ILT
468int
469itbl_get_val (e_processor processor, e_type type, char *name,
470 unsigned long *pval)
252b5132
RH
471{
472 struct itbl_entry *r;
473 /* type depends on instruction passed */
474 r = find_entry_byname (processor, type, name);
d7ba4a77
ILT
475 if (r == NULL)
476 return 0;
477 *pval = r->value;
478 return 1;
252b5132
RH
479}
480
252b5132
RH
481/* Assemble instruction "name" with operands "s".
482 * name - name of instruction
483 * s - operands
484 * returns - long word for assembled instruction */
485
c488923f 486unsigned long
252b5132
RH
487itbl_assemble (char *name, char *s)
488{
489 unsigned long opcode;
3438adb3 490 struct itbl_entry *e = NULL;
252b5132
RH
491 struct itbl_field *f;
492 char *n;
493 int processor;
494
495 if (!name || !*name)
3b37fd66 496 return 0; /* error! must have an opcode name/expr */
252b5132
RH
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)
ef5c4bfc 506 return 0; /* opcode not in table; invalid instruction */
252b5132
RH
507 opcode = build_opcode (e);
508
509 /* parse opcode's args (if any) */
c488923f 510 for (f = e->fields; f; f = f->next) /* for each arg, ... */
252b5132
RH
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:
c488923f 552 if (*n == '0' && *(n + 1) == 'x') /* hex begins 0x... */
252b5132
RH
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
c488923f 582int
252b5132
RH
583itbl_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))
ef99799a 590 return 0; /* error */
252b5132
RH
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)
ef5c4bfc 596 return 0; /* opcode not in table; invalid instruction */
252b5132
RH
597 strcpy (s, e->name);
598
ef99799a 599 /* Parse insn's args (if any). */
c488923f 600 for (f = e->fields; f; f = f->next) /* for each arg, ... */
252b5132
RH
601 {
602 struct itbl_entry *r;
603 unsigned long value;
604
47eebc20 605 if (f == e->fields) /* First operand is preceded by tab. */
252b5132 606 strcat (s, "\t");
ef99799a 607 else /* ','s separate following operands. */
252b5132
RH
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
ef99799a 617 or '$' followed by the register number. */
252b5132
RH
618 r = find_entry_byval (e->processor, f->type, value, &f->range);
619 if (r)
620 strcat (s, r->name);
621 else
41e60a82 622 sprintf (s, "%s$%lu", s, value);
252b5132
RH
623 break;
624 case e_addr:
ef99799a
KH
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. */
252b5132 628 case e_immed:
41e60a82 629 sprintf (s, "%s0x%lx", s, value);
252b5132
RH
630 break;
631 default:
632 return 0; /* error; invalid field spec */
633 }
634 }
ef99799a 635 return 1; /* Done! */
252b5132
RH
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
c488923f 647static unsigned long
252b5132
RH
648build_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
c488923f 668static unsigned long
252b5132
RH
669apply_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
c488923f 692static unsigned long
252b5132
RH
693extract_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.
d7ba4a77 712 * delimiters are " ,()" */
252b5132
RH
713
714char *
715itbl_get_field (char **S)
716{
717 static char n[128];
41e60a82 718 char *s;
252b5132
RH
719 int len;
720
721 s = *S;
722 if (!s || !*s)
723 return 0;
d7ba4a77
ILT
724 /* FIXME: This is a weird set of delimiters. */
725 len = strcspn (s, " \t,()");
252b5132
RH
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
742static struct itbl_entry *
743find_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);
c488923f 749 for (e = *es; e; e = e->next) /* for each entry, ... */
252b5132
RH
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
763static struct itbl_entry *
764find_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);
c488923f 771 for (e = *es; e; e = e->next) /* for each entry, ... */
252b5132
RH
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 */
c488923f 781 /* if range is 0, mask val against the range of the compared entry. */
252b5132
RH
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 }
41e60a82
ILT
788 else if ((r->sbit == e->range.sbit && r->ebit == e->range.ebit)
789 || (e->range.sbit == 0 && e->range.ebit == 0))
252b5132
RH
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
c488923f 802/* Return a pointer to the list of entries for a given processor and type. */
252b5132
RH
803
804static struct itbl_entry **
805get_entries (e_processor processor, e_type type)
806{
807 return &entries[processor][type];
808}
809
c488923f 810/* Return an integral value for the processor passed from yyparse. */
252b5132 811
c488923f 812static e_processor
252b5132
RH
813get_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
c488923f 821/* Return an integral value for the entry type passed from yyparse. */
252b5132 822
c488923f 823static e_type
252b5132
RH
824get_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
252b5132
RH
846/* Allocate and initialize an entry */
847
848static struct itbl_entry *
849alloc_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
874static struct itbl_field *
875alloc_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.485709 seconds and 4 git commands to generate.