OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [itbl-ops.c] - Blame information for rev 241

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 147 khays
/* itbl-ops.c
2
   Copyright 1997, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007,
3
   2009, 2010  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 3, 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) gas_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
 
111
int itbl_have_entries = 0;
112
 
113
/*======================================================================*/
114
/* structures for keeping itbl format entries */
115
 
116
struct itbl_range {
117
  int sbit;                     /* mask starting bit position */
118
  int ebit;                     /* mask ending bit position */
119
};
120
 
121
struct 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.  */
133
struct 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
 
146
static int itbl_num_opcodes = 0;
147
/* Array of entries for each processor and entry type */
148
static struct itbl_entry *entries[e_nprocs][e_ntypes];
149
 
150
/* local prototypes */
151
static unsigned long build_opcode (struct itbl_entry *e);
152
static e_type get_type (int yytype);
153
static e_processor get_processor (int yyproc);
154
static struct itbl_entry **get_entries (e_processor processor,
155
                                        e_type type);
156
static struct itbl_entry *find_entry_byname (e_processor processor,
157
                                        e_type type, char *name);
158
static struct itbl_entry *find_entry_byval (e_processor processor,
159
                        e_type type, unsigned long val, struct itbl_range *r);
160
static struct itbl_entry *alloc_entry (e_processor processor,
161
                e_type type, char *name, unsigned long value);
162
static unsigned long apply_range (unsigned long value, struct itbl_range r);
163
static unsigned long extract_range (unsigned long value, struct itbl_range r);
164
static 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
 
173
int
174
itbl_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
 
197
struct itbl_entry *
198
itbl_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
 
207
struct itbl_entry *
208
itbl_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
 
225
struct itbl_field *
226
itbl_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
249
static void append_insns_as_macros (void);
250
 
251
/* Initialize for gas.  */
252
 
253
void
254
itbl_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
 
297
static char *form_args (struct itbl_entry *e);
298
static void
299
append_insns_as_macros (void)
300
{
301
  struct ITBL_OPCODE_STRUCT *new_opcodes, *o;
302
  struct itbl_entry *e, **es;
303
  int n, size, new_size, new_num_opcodes;
304
#ifdef USE_MACROS
305
  int id;
306
#endif
307
 
308
  if (!itbl_have_entries)
309
    return;
310
 
311
  if (!itbl_num_opcodes)        /* no new instructions to add! */
312
    {
313
      return;
314
    }
315
  DBG (("previous num_opcodes=%d\n", ITBL_NUM_OPCODES));
316
 
317
  new_num_opcodes = ITBL_NUM_OPCODES + itbl_num_opcodes;
318
  ASSERT (new_num_opcodes >= itbl_num_opcodes);
319
 
320
  size = sizeof (struct ITBL_OPCODE_STRUCT) * ITBL_NUM_OPCODES;
321
  ASSERT (size >= 0);
322
  DBG (("I get=%d\n", size / sizeof (ITBL_OPCODES[0])));
323
 
324
  new_size = sizeof (struct ITBL_OPCODE_STRUCT) * new_num_opcodes;
325
  ASSERT (new_size > size);
326
 
327
  /* FIXME since ITBL_OPCODES culd be a static table,
328
                we can't realloc or delete the old memory.  */
329
  new_opcodes = (struct ITBL_OPCODE_STRUCT *) malloc (new_size);
330
  if (!new_opcodes)
331
    {
332
      printf (_("Unable to allocate memory for new instructions\n"));
333
      return;
334
    }
335
  if (size)                     /* copy preexisting opcodes table */
336
    memcpy (new_opcodes, ITBL_OPCODES, size);
337
 
338
  /* FIXME! some NUMOPCODES are calculated expressions.
339
                These need to be changed before itbls can be supported.  */
340
 
341
#ifdef USE_MACROS
342
  id = ITBL_NUM_MACROS;         /* begin the next macro id after the last */
343
#endif
344
  o = &new_opcodes[ITBL_NUM_OPCODES];   /* append macro to opcodes list */
345
  for (n = e_p0; n < e_nprocs; n++)
346
    {
347
      es = get_entries (n, e_insn);
348
      for (e = *es; e; e = e->next)
349
        {
350
          /* name,    args,   mask,       match,  pinfo
351
                 * {"li",      "t,i",  0x34000000, 0xffe00000, WR_t    },
352
                 * {"li",      "t,I",  0,    (int) M_LI,   INSN_MACRO  },
353
                 * Construct args from itbl_fields.
354
                */
355
          o->name = e->name;
356
          o->args = strdup (form_args (e));
357
          o->mask = apply_range (e->value, e->range);
358
          /* FIXME how to catch during assembly? */
359
          /* mask to identify this insn */
360
          o->match = apply_range (e->value, e->range);
361
          o->pinfo = 0;
362
 
363
#ifdef USE_MACROS
364
          o->mask = id++;       /* FIXME how to catch during assembly? */
365
          o->match = 0;          /* for macros, the insn_isa number */
366
          o->pinfo = INSN_MACRO;
367
#endif
368
 
369
          /* Don't add instructions which caused an error */
370
          if (o->args)
371
            o++;
372
          else
373
            new_num_opcodes--;
374
        }
375
    }
376
  ITBL_OPCODES = new_opcodes;
377
  ITBL_NUM_OPCODES = new_num_opcodes;
378
 
379
  /* FIXME
380
                At this point, we can free the entries, as they should have
381
                been added to the assembler's tables.
382
                Don't free name though, since name is being used by the new
383
                opcodes table.
384
 
385
                Eventually, we should also free the new opcodes table itself
386
                on exit.
387
        */
388
}
389
 
390
static char *
391
form_args (struct itbl_entry *e)
392
{
393
  static char s[31];
394
  char c = 0, *p = s;
395
  struct itbl_field *f;
396
 
397
  ASSERT (e);
398
  for (f = e->fields; f; f = f->next)
399
    {
400
      switch (f->type)
401
        {
402
        case e_dreg:
403
          c = 'd';
404
          break;
405
        case e_creg:
406
          c = 't';
407
          break;
408
        case e_greg:
409
          c = 's';
410
          break;
411
        case e_immed:
412
          c = 'i';
413
          break;
414
        case e_addr:
415
          c = 'a';
416
          break;
417
        default:
418
          c = 0;         /* ignore; unknown field type */
419
        }
420
      if (c)
421
        {
422
          if (p != s)
423
            *p++ = ',';
424
          *p++ = c;
425
        }
426
    }
427
  *p = 0;
428
  return s;
429
}
430
#endif /* !STAND_ALONE */
431
 
432
/* Get processor's register name from val */
433
 
434
int
435
itbl_get_reg_val (char *name, unsigned long *pval)
436
{
437
  e_type t;
438
  e_processor p;
439
 
440
  for (p = e_p0; p < e_nprocs; p++)
441
    {
442
      for (t = e_regtype0; t < e_nregtypes; t++)
443
        {
444
          if (itbl_get_val (p, t, name, pval))
445
            return 1;
446
        }
447
    }
448
  return 0;
449
}
450
 
451
char *
452
itbl_get_name (e_processor processor, e_type type, unsigned long val)
453
{
454
  struct itbl_entry *r;
455
  /* type depends on instruction passed */
456
  r = find_entry_byval (processor, type, val, 0);
457
  if (r)
458
    return r->name;
459
  else
460
    return 0;                    /* error; invalid operand */
461
}
462
 
463
/* Get processor's register value from name */
464
 
465
int
466
itbl_get_val (e_processor processor, e_type type, char *name,
467
              unsigned long *pval)
468
{
469
  struct itbl_entry *r;
470
  /* type depends on instruction passed */
471
  r = find_entry_byname (processor, type, name);
472
  if (r == NULL)
473
    return 0;
474
  *pval = r->value;
475
  return 1;
476
}
477
 
478
/* Assemble instruction "name" with operands "s".
479
 * name - name of instruction
480
 * s - operands
481
 * returns - long word for assembled instruction */
482
 
483
unsigned long
484
itbl_assemble (char *name, char *s)
485
{
486
  unsigned long opcode;
487
  struct itbl_entry *e = NULL;
488
  struct itbl_field *f;
489
  char *n;
490
  int processor;
491
 
492
  if (!name || !*name)
493
    return 0;                    /* error!  must have an opcode name/expr */
494
 
495
  /* find entry in list of instructions for all processors */
496
  for (processor = 0; processor < e_nprocs; processor++)
497
    {
498
      e = find_entry_byname (processor, e_insn, name);
499
      if (e)
500
        break;
501
    }
502
  if (!e)
503
    return 0;                    /* opcode not in table; invalid instruction */
504
  opcode = build_opcode (e);
505
 
506
  /* parse opcode's args (if any) */
507
  for (f = e->fields; f; f = f->next)   /* for each arg, ...  */
508
    {
509
      struct itbl_entry *r;
510
      unsigned long value;
511
      if (!s || !*s)
512
        return 0;                /* error - not enough operands */
513
      n = itbl_get_field (&s);
514
      /* n should be in form $n or 0xhhh (are symbol names valid?? */
515
      switch (f->type)
516
        {
517
        case e_dreg:
518
        case e_creg:
519
        case e_greg:
520
          /* Accept either a string name
521
                         * or '$' followed by the register number */
522
          if (*n == '$')
523
            {
524
              n++;
525
              value = strtol (n, 0, 10);
526
              /* FIXME! could have "0l"... then what?? */
527
              if (value == 0 && *n != '0')
528
                return 0;        /* error; invalid operand */
529
            }
530
          else
531
            {
532
              r = find_entry_byname (e->processor, f->type, n);
533
              if (r)
534
                value = r->value;
535
              else
536
                return 0;        /* error; invalid operand */
537
            }
538
          break;
539
        case e_addr:
540
          /* use assembler's symbol table to find symbol */
541
          /* FIXME!! Do we need this?
542
                                if so, what about relocs??
543
                                my_getExpression (&imm_expr, s);
544
                                return 0;       /-* error; invalid operand *-/
545
                                break;
546
                        */
547
          /* If not a symbol, fall thru to IMMED */
548
        case e_immed:
549
          if (*n == '0' && *(n + 1) == 'x')     /* hex begins 0x...  */
550
            {
551
              n += 2;
552
              value = strtol (n, 0, 16);
553
              /* FIXME! could have "0xl"... then what?? */
554
            }
555
          else
556
            {
557
              value = strtol (n, 0, 10);
558
              /* FIXME! could have "0l"... then what?? */
559
              if (value == 0 && *n != '0')
560
                return 0;        /* error; invalid operand */
561
            }
562
          break;
563
        default:
564
          return 0;              /* error; invalid field spec */
565
        }
566
      opcode |= apply_range (value, f->range);
567
    }
568
  if (s && *s)
569
    return 0;                    /* error - too many operands */
570
  return opcode;                /* done! */
571
}
572
 
573
/* Disassemble instruction "insn".
574
 * insn - instruction
575
 * s - buffer to hold disassembled instruction
576
 * returns - 1 if succeeded; 0 if failed
577
 */
578
 
579
int
580
itbl_disassemble (char *s, unsigned long insn)
581
{
582
  e_processor processor;
583
  struct itbl_entry *e;
584
  struct itbl_field *f;
585
 
586
  if (!ITBL_IS_INSN (insn))
587
    return 0;                    /* error */
588
  processor = get_processor (ITBL_DECODE_PNUM (insn));
589
 
590
  /* find entry in list */
591
  e = find_entry_byval (processor, e_insn, insn, 0);
592
  if (!e)
593
    return 0;                    /* opcode not in table; invalid instruction */
594
  strcpy (s, e->name);
595
 
596
  /* Parse insn's args (if any).  */
597
  for (f = e->fields; f; f = f->next)   /* for each arg, ...  */
598
    {
599
      struct itbl_entry *r;
600
      unsigned long value;
601
      char s_value[20];
602
 
603
      if (f == e->fields)       /* First operand is preceded by tab.  */
604
        strcat (s, "\t");
605
      else                      /* ','s separate following operands.  */
606
        strcat (s, ",");
607
      value = extract_range (insn, f->range);
608
      /* n should be in form $n or 0xhhh (are symbol names valid?? */
609
      switch (f->type)
610
        {
611
        case e_dreg:
612
        case e_creg:
613
        case e_greg:
614
          /* Accept either a string name
615
             or '$' followed by the register number.  */
616
          r = find_entry_byval (e->processor, f->type, value, &f->range);
617
          if (r)
618
            strcat (s, r->name);
619
          else
620
            {
621
              sprintf (s_value, "$%lu", value);
622
              strcat (s, s_value);
623
            }
624
          break;
625
        case e_addr:
626
          /* Use assembler's symbol table to find symbol.  */
627
          /* FIXME!! Do we need this?  If so, what about relocs??  */
628
          /* If not a symbol, fall through to IMMED.  */
629
        case e_immed:
630
          sprintf (s_value, "0x%lx", value);
631
          strcat (s, s_value);
632
          break;
633
        default:
634
          return 0;              /* error; invalid field spec */
635
        }
636
    }
637
  return 1;                     /* Done!  */
638
}
639
 
640
/*======================================================================*/
641
/*
642
 * Local functions for manipulating private structures containing
643
 * the names and format for the new instructions and registers
644
 * for each processor.
645
 */
646
 
647
/* Calculate instruction's opcode and function values from entry */
648
 
649
static unsigned long
650
build_opcode (struct itbl_entry *e)
651
{
652
  unsigned long opcode;
653
 
654
  opcode = apply_range (e->value, e->range);
655
  opcode |= ITBL_ENCODE_PNUM (e->processor);
656
  return opcode;
657
}
658
 
659
/* Calculate absolute value given the relative value and bit position range
660
 * within the instruction.
661
 * The range is inclusive where 0 is least significant bit.
662
 * A range of { 24, 20 } will have a mask of
663
 * bit   3           2            1
664
 * pos: 1098 7654 3210 9876 5432 1098 7654 3210
665
 * bin: 0000 0001 1111 0000 0000 0000 0000 0000
666
 * hex:    0    1    f    0    0    0    0    0
667
 * mask: 0x01f00000.
668
 */
669
 
670
static unsigned long
671
apply_range (unsigned long rval, struct itbl_range r)
672
{
673
  unsigned long mask;
674
  unsigned long aval;
675
  int len = MAX_BITPOS - r.sbit;
676
 
677
  ASSERT (r.sbit >= r.ebit);
678
  ASSERT (MAX_BITPOS >= r.sbit);
679
  ASSERT (r.ebit >= 0);
680
 
681
  /* create mask by truncating 1s by shifting */
682
  mask = 0xffffffff << len;
683
  mask = mask >> len;
684
  mask = mask >> r.ebit;
685
  mask = mask << r.ebit;
686
 
687
  aval = (rval << r.ebit) & mask;
688
  return aval;
689
}
690
 
691
/* Calculate relative value given the absolute value and bit position range
692
 * within the instruction.  */
693
 
694
static unsigned long
695
extract_range (unsigned long aval, struct itbl_range r)
696
{
697
  unsigned long mask;
698
  unsigned long rval;
699
  int len = MAX_BITPOS - r.sbit;
700
 
701
  /* create mask by truncating 1s by shifting */
702
  mask = 0xffffffff << len;
703
  mask = mask >> len;
704
  mask = mask >> r.ebit;
705
  mask = mask << r.ebit;
706
 
707
  rval = (aval & mask) >> r.ebit;
708
  return rval;
709
}
710
 
711
/* Extract processor's assembly instruction field name from s;
712
 * forms are "n args" "n,args" or "n" */
713
/* Return next argument from string pointer "s" and advance s.
714
 * delimiters are " ,()" */
715
 
716
char *
717
itbl_get_field (char **S)
718
{
719
  static char n[128];
720
  char *s;
721
  int len;
722
 
723
  s = *S;
724
  if (!s || !*s)
725
    return 0;
726
  /* FIXME: This is a weird set of delimiters.  */
727
  len = strcspn (s, " \t,()");
728
  ASSERT (128 > len + 1);
729
  strncpy (n, s, len);
730
  n[len] = 0;
731
  if (s[len] == '\0')
732
    s = 0;                       /* no more args */
733
  else
734
    s += len + 1;               /* advance to next arg */
735
 
736
  *S = s;
737
  return n;
738
}
739
 
740
/* Search entries for a given processor and type
741
 * to find one matching the name "n".
742
 * Return a pointer to the entry */
743
 
744
static struct itbl_entry *
745
find_entry_byname (e_processor processor,
746
                   e_type type, char *n)
747
{
748
  struct itbl_entry *e, **es;
749
 
750
  es = get_entries (processor, type);
751
  for (e = *es; e; e = e->next) /* for each entry, ...  */
752
    {
753
      if (!strcmp (e->name, n))
754
        return e;
755
    }
756
  return 0;
757
}
758
 
759
/* Search entries for a given processor and type
760
 * to find one matching the value "val" for the range "r".
761
 * Return a pointer to the entry.
762
 * This function is used for disassembling fields of an instruction.
763
 */
764
 
765
static struct itbl_entry *
766
find_entry_byval (e_processor processor, e_type type,
767
                  unsigned long val, struct itbl_range *r)
768
{
769
  struct itbl_entry *e, **es;
770
  unsigned long eval;
771
 
772
  es = get_entries (processor, type);
773
  for (e = *es; e; e = e->next) /* for each entry, ...  */
774
    {
775
      if (processor != e->processor)
776
        continue;
777
      /* For insns, we might not know the range of the opcode,
778
         * so a range of 0 will allow this routine to match against
779
         * the range of the entry to be compared with.
780
         * This could cause ambiguities.
781
         * For operands, we get an extracted value and a range.
782
         */
783
      /* if range is 0, mask val against the range of the compared entry.  */
784
      if (r == 0)                /* if no range passed, must be whole 32-bits
785
                         * so create 32-bit value from entry's range */
786
        {
787
          eval = apply_range (e->value, e->range);
788
          val &= apply_range (0xffffffff, e->range);
789
        }
790
      else if ((r->sbit == e->range.sbit && r->ebit == e->range.ebit)
791
               || (e->range.sbit == 0 && e->range.ebit == 0))
792
        {
793
          eval = apply_range (e->value, *r);
794
          val = apply_range (val, *r);
795
        }
796
      else
797
        continue;
798
      if (val == eval)
799
        return e;
800
    }
801
  return 0;
802
}
803
 
804
/* Return a pointer to the list of entries for a given processor and type.  */
805
 
806
static struct itbl_entry **
807
get_entries (e_processor processor, e_type type)
808
{
809
  return &entries[processor][type];
810
}
811
 
812
/* Return an integral value for the processor passed from yyparse.  */
813
 
814
static e_processor
815
get_processor (int yyproc)
816
{
817
  /* translate from yacc's processor to enum */
818
  if (yyproc >= e_p0 && yyproc < e_nprocs)
819
    return (e_processor) yyproc;
820
  return e_invproc;             /* error; invalid processor */
821
}
822
 
823
/* Return an integral value for the entry type passed from yyparse.  */
824
 
825
static e_type
826
get_type (int yytype)
827
{
828
  switch (yytype)
829
    {
830
      /* translate from yacc's type to enum */
831
    case INSN:
832
      return e_insn;
833
    case DREG:
834
      return e_dreg;
835
    case CREG:
836
      return e_creg;
837
    case GREG:
838
      return e_greg;
839
    case ADDR:
840
      return e_addr;
841
    case IMMED:
842
      return e_immed;
843
    default:
844
      return e_invtype;         /* error; invalid type */
845
    }
846
}
847
 
848
/* Allocate and initialize an entry */
849
 
850
static struct itbl_entry *
851
alloc_entry (e_processor processor, e_type type,
852
             char *name, unsigned long value)
853
{
854
  struct itbl_entry *e, **es;
855
  if (!name)
856
    return 0;
857
  e = (struct itbl_entry *) malloc (sizeof (struct itbl_entry));
858
  if (e)
859
    {
860
      memset (e, 0, sizeof (struct itbl_entry));
861
      e->name = (char *) malloc (sizeof (strlen (name)) + 1);
862
      if (e->name)
863
        strcpy (e->name, name);
864
      e->processor = processor;
865
      e->type = type;
866
      e->value = value;
867
      es = get_entries (e->processor, e->type);
868
      e->next = *es;
869
      *es = e;
870
    }
871
  return e;
872
}
873
 
874
/* Allocate and initialize an entry's field */
875
 
876
static struct itbl_field *
877
alloc_field (e_type type, int sbit, int ebit,
878
             unsigned long flags)
879
{
880
  struct itbl_field *f;
881
  f = (struct itbl_field *) malloc (sizeof (struct itbl_field));
882
  if (f)
883
    {
884
      memset (f, 0, sizeof (struct itbl_field));
885
      f->type = type;
886
      f->range.sbit = sbit;
887
      f->range.ebit = ebit;
888
      f->flags = flags;
889
    }
890
  return f;
891
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.