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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [bfd/] [xtensa-isa.c] - Blame information for rev 818

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* Configurable Xtensa ISA support.
2
   Copyright 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
3
 
4
   This file is part of BFD, the Binary File Descriptor library.
5
 
6
   This program 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 3 of the License, or
9
   (at your option) any later version.
10
 
11
   This program 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 this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   MA 02110-1301, USA.  */
20
 
21
#include "sysdep.h"
22
#include "bfd.h"
23
#include "libbfd.h"
24
#include "xtensa-isa.h"
25
#include "xtensa-isa-internal.h"
26
 
27
xtensa_isa_status xtisa_errno;
28
char xtisa_error_msg[1024];
29
 
30
 
31
xtensa_isa_status
32
xtensa_isa_errno (xtensa_isa isa __attribute__ ((unused)))
33
{
34
  return xtisa_errno;
35
}
36
 
37
 
38
char *
39
xtensa_isa_error_msg (xtensa_isa isa __attribute__ ((unused)))
40
{
41
  return xtisa_error_msg;
42
}
43
 
44
 
45
#define CHECK_ALLOC(MEM,ERRVAL) \
46
  do { \
47
    if ((MEM) == 0) \
48
      { \
49
        xtisa_errno = xtensa_isa_out_of_memory; \
50
        strcpy (xtisa_error_msg, "out of memory"); \
51
        return (ERRVAL); \
52
      } \
53
  } while (0)
54
 
55
#define CHECK_ALLOC_FOR_INIT(MEM,ERRVAL,ERRNO_P,ERROR_MSG_P) \
56
  do { \
57
    if ((MEM) == 0) \
58
      { \
59
        xtisa_errno = xtensa_isa_out_of_memory; \
60
        strcpy (xtisa_error_msg, "out of memory"); \
61
        if (ERRNO_P) *(ERRNO_P) = xtisa_errno; \
62
        if (ERROR_MSG_P) *(ERROR_MSG_P) = xtisa_error_msg; \
63
        return (ERRVAL); \
64
      } \
65
  } while (0)
66
 
67
 
68
 
69
/* Instruction buffers.  */
70
 
71
int
72
xtensa_insnbuf_size (xtensa_isa isa)
73
{
74
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
75
  return intisa->insnbuf_size;
76
}
77
 
78
 
79
xtensa_insnbuf
80
xtensa_insnbuf_alloc (xtensa_isa isa)
81
{
82
  xtensa_insnbuf result = (xtensa_insnbuf)
83
    malloc (xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
84
  CHECK_ALLOC (result, 0);
85
  return result;
86
}
87
 
88
 
89
void
90
xtensa_insnbuf_free (xtensa_isa isa __attribute__ ((unused)),
91
                     xtensa_insnbuf buf)
92
{
93
  free (buf);
94
}
95
 
96
 
97
/* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our
98
   internal representation of a xtensa instruction word, return the index of
99
   its word and the bit index of its low order byte in the xtensa_insnbuf.  */
100
 
101
static inline int
102
byte_to_word_index (int byte_index)
103
{
104
  return byte_index / sizeof (xtensa_insnbuf_word);
105
}
106
 
107
 
108
static inline int
109
byte_to_bit_index (int byte_index)
110
{
111
  return (byte_index & 0x3) * 8;
112
}
113
 
114
 
115
/* Copy an instruction in the 32-bit words pointed at by "insn" to
116
   characters pointed at by "cp".  This is more complicated than you
117
   might think because we want 16-bit instructions in bytes 2 & 3 for
118
   big-endian configurations.  This function allows us to specify
119
   which byte in "insn" to start with and which way to increment,
120
   allowing trivial implementation for both big- and little-endian
121
   configurations....and it seems to make pretty good code for
122
   both.  */
123
 
124
int
125
xtensa_insnbuf_to_chars (xtensa_isa isa,
126
                         const xtensa_insnbuf insn,
127
                         unsigned char *cp,
128
                         int num_chars)
129
{
130
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
131
  int insn_size = xtensa_isa_maxlength (isa);
132
  int fence_post, start, increment, i, byte_count;
133
  xtensa_format fmt;
134
 
135
  if (num_chars == 0)
136
    num_chars = insn_size;
137
 
138
  if (intisa->is_big_endian)
139
    {
140
      start = insn_size - 1;
141
      increment = -1;
142
    }
143
  else
144
    {
145
      start = 0;
146
      increment = 1;
147
    }
148
 
149
  /* Find the instruction format.  Do nothing if the buffer does not contain
150
     a valid instruction since we need to know how many bytes to copy.  */
151
  fmt = xtensa_format_decode (isa, insn);
152
  if (fmt == XTENSA_UNDEFINED)
153
    return XTENSA_UNDEFINED;
154
 
155
  byte_count = xtensa_format_length (isa, fmt);
156
  if (byte_count == XTENSA_UNDEFINED)
157
    return XTENSA_UNDEFINED;
158
 
159
  if (byte_count > num_chars)
160
    {
161
      xtisa_errno = xtensa_isa_buffer_overflow;
162
      strcpy (xtisa_error_msg, "output buffer too small for instruction");
163
      return XTENSA_UNDEFINED;
164
    }
165
 
166
  fence_post = start + (byte_count * increment);
167
 
168
  for (i = start; i != fence_post; i += increment, ++cp)
169
    {
170
      int word_inx = byte_to_word_index (i);
171
      int bit_inx = byte_to_bit_index (i);
172
 
173
      *cp = (insn[word_inx] >> bit_inx) & 0xff;
174
    }
175
 
176
  return byte_count;
177
}
178
 
179
 
180
/* Inward conversion from byte stream to xtensa_insnbuf.  See
181
   xtensa_insnbuf_to_chars for a discussion of why this is complicated
182
   by endianness.  */
183
 
184
void
185
xtensa_insnbuf_from_chars (xtensa_isa isa,
186
                           xtensa_insnbuf insn,
187
                           const unsigned char *cp,
188
                           int num_chars)
189
{
190
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
191
  int max_size, insn_size, fence_post, start, increment, i;
192
 
193
  max_size = xtensa_isa_maxlength (isa);
194
 
195
  /* Decode the instruction length so we know how many bytes to read.  */
196
  insn_size = (intisa->length_decode_fn) (cp);
197
  if (insn_size == XTENSA_UNDEFINED)
198
    {
199
      /* This should never happen when the byte stream contains a
200
         valid instruction.  Just read the maximum number of bytes....  */
201
      insn_size = max_size;
202
    }
203
 
204
  if (num_chars == 0 || num_chars > insn_size)
205
    num_chars = insn_size;
206
 
207
  if (intisa->is_big_endian)
208
    {
209
      start = max_size - 1;
210
      increment = -1;
211
    }
212
  else
213
    {
214
      start = 0;
215
      increment = 1;
216
    }
217
 
218
  fence_post = start + (num_chars * increment);
219
  memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
220
 
221
  for (i = start; i != fence_post; i += increment, ++cp)
222
    {
223
      int word_inx = byte_to_word_index (i);
224
      int bit_inx = byte_to_bit_index (i);
225
 
226
      insn[word_inx] |= (*cp & 0xff) << bit_inx;
227
    }
228
}
229
 
230
 
231
 
232
/* ISA information.  */
233
 
234
extern xtensa_isa_internal xtensa_modules;
235
 
236
xtensa_isa
237
xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p)
238
{
239
  xtensa_isa_internal *isa = &xtensa_modules;
240
  int n, is_user;
241
 
242
  /* Set up the opcode name lookup table.  */
243
  isa->opname_lookup_table =
244
    bfd_malloc (isa->num_opcodes * sizeof (xtensa_lookup_entry));
245
  CHECK_ALLOC_FOR_INIT (isa->opname_lookup_table, NULL, errno_p, error_msg_p);
246
  for (n = 0; n < isa->num_opcodes; n++)
247
    {
248
      isa->opname_lookup_table[n].key = isa->opcodes[n].name;
249
      isa->opname_lookup_table[n].u.opcode = n;
250
    }
251
  qsort (isa->opname_lookup_table, isa->num_opcodes,
252
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
253
 
254
  /* Set up the state name lookup table.  */
255
  isa->state_lookup_table =
256
    bfd_malloc (isa->num_states * sizeof (xtensa_lookup_entry));
257
  CHECK_ALLOC_FOR_INIT (isa->state_lookup_table, NULL, errno_p, error_msg_p);
258
  for (n = 0; n < isa->num_states; n++)
259
    {
260
      isa->state_lookup_table[n].key = isa->states[n].name;
261
      isa->state_lookup_table[n].u.state = n;
262
    }
263
  qsort (isa->state_lookup_table, isa->num_states,
264
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
265
 
266
  /* Set up the sysreg name lookup table.  */
267
  isa->sysreg_lookup_table =
268
    bfd_malloc (isa->num_sysregs * sizeof (xtensa_lookup_entry));
269
  CHECK_ALLOC_FOR_INIT (isa->sysreg_lookup_table, NULL, errno_p, error_msg_p);
270
  for (n = 0; n < isa->num_sysregs; n++)
271
    {
272
      isa->sysreg_lookup_table[n].key = isa->sysregs[n].name;
273
      isa->sysreg_lookup_table[n].u.sysreg = n;
274
    }
275
  qsort (isa->sysreg_lookup_table, isa->num_sysregs,
276
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
277
 
278
  /* Set up the user & system sysreg number tables.  */
279
  for (is_user = 0; is_user < 2; is_user++)
280
    {
281
      isa->sysreg_table[is_user] =
282
        bfd_malloc ((isa->max_sysreg_num[is_user] + 1)
283
                    * sizeof (xtensa_sysreg));
284
      CHECK_ALLOC_FOR_INIT (isa->sysreg_table[is_user], NULL,
285
                            errno_p, error_msg_p);
286
 
287
      for (n = 0; n <= isa->max_sysreg_num[is_user]; n++)
288
        isa->sysreg_table[is_user][n] = XTENSA_UNDEFINED;
289
    }
290
  for (n = 0; n < isa->num_sysregs; n++)
291
    {
292
      xtensa_sysreg_internal *sreg = &isa->sysregs[n];
293
      is_user = sreg->is_user;
294
 
295
      isa->sysreg_table[is_user][sreg->number] = n;
296
    }
297
 
298
  /* Set up the interface lookup table.  */
299
  isa->interface_lookup_table =
300
    bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry));
301
  CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p,
302
                        error_msg_p);
303
  for (n = 0; n < isa->num_interfaces; n++)
304
    {
305
      isa->interface_lookup_table[n].key = isa->interfaces[n].name;
306
      isa->interface_lookup_table[n].u.intf = n;
307
    }
308
  qsort (isa->interface_lookup_table, isa->num_interfaces,
309
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
310
 
311
  /* Set up the funcUnit lookup table.  */
312
  isa->funcUnit_lookup_table =
313
    bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry));
314
  CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p,
315
                        error_msg_p);
316
  for (n = 0; n < isa->num_funcUnits; n++)
317
    {
318
      isa->funcUnit_lookup_table[n].key = isa->funcUnits[n].name;
319
      isa->funcUnit_lookup_table[n].u.fun = n;
320
    }
321
  qsort (isa->funcUnit_lookup_table, isa->num_funcUnits,
322
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
323
 
324
  isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
325
                       sizeof (xtensa_insnbuf_word));
326
 
327
  return (xtensa_isa) isa;
328
}
329
 
330
 
331
void
332
xtensa_isa_free (xtensa_isa isa)
333
{
334
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
335
  int n;
336
 
337
  /* With this version of the code, the xtensa_isa structure is not
338
     dynamically allocated, so this function is not essential.  Free
339
     the memory allocated by xtensa_isa_init and restore the xtensa_isa
340
     structure to its initial state.  */
341
 
342
  if (intisa->opname_lookup_table)
343
    {
344
      free (intisa->opname_lookup_table);
345
      intisa->opname_lookup_table = 0;
346
    }
347
 
348
  if (intisa->state_lookup_table)
349
    {
350
      free (intisa->state_lookup_table);
351
      intisa->state_lookup_table = 0;
352
    }
353
 
354
  if (intisa->sysreg_lookup_table)
355
    {
356
      free (intisa->sysreg_lookup_table);
357
      intisa->sysreg_lookup_table = 0;
358
    }
359
  for (n = 0; n < 2; n++)
360
    {
361
      if (intisa->sysreg_table[n])
362
        {
363
          free (intisa->sysreg_table[n]);
364
          intisa->sysreg_table[n] = 0;
365
        }
366
    }
367
 
368
  if (intisa->interface_lookup_table)
369
    {
370
      free (intisa->interface_lookup_table);
371
      intisa->interface_lookup_table = 0;
372
    }
373
 
374
  if (intisa->funcUnit_lookup_table)
375
    {
376
      free (intisa->funcUnit_lookup_table);
377
      intisa->funcUnit_lookup_table = 0;
378
    }
379
}
380
 
381
 
382
int
383
xtensa_isa_name_compare (const void *v1, const void *v2)
384
{
385
  xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1;
386
  xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2;
387
 
388
  return strcasecmp (e1->key, e2->key);
389
}
390
 
391
 
392
int
393
xtensa_isa_maxlength (xtensa_isa isa)
394
{
395
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
396
  return intisa->insn_size;
397
}
398
 
399
 
400
int
401
xtensa_isa_length_from_chars (xtensa_isa isa, const unsigned char *cp)
402
{
403
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
404
  return (intisa->length_decode_fn) (cp);
405
}
406
 
407
 
408
int
409
xtensa_isa_num_pipe_stages (xtensa_isa isa)
410
{
411
  xtensa_opcode opcode;
412
  xtensa_funcUnit_use *use;
413
  int num_opcodes, num_uses;
414
  int i, stage;
415
  static int max_stage = XTENSA_UNDEFINED;
416
 
417
  /* Only compute the value once.  */
418
  if (max_stage != XTENSA_UNDEFINED)
419
    return max_stage + 1;
420
 
421
  num_opcodes = xtensa_isa_num_opcodes (isa);
422
  for (opcode = 0; opcode < num_opcodes; opcode++)
423
    {
424
      num_uses = xtensa_opcode_num_funcUnit_uses (isa, opcode);
425
      for (i = 0; i < num_uses; i++)
426
        {
427
          use = xtensa_opcode_funcUnit_use (isa, opcode, i);
428
          stage = use->stage;
429
          if (stage > max_stage)
430
            max_stage = stage;
431
        }
432
    }
433
 
434
  return max_stage + 1;
435
}
436
 
437
 
438
int
439
xtensa_isa_num_formats (xtensa_isa isa)
440
{
441
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
442
  return intisa->num_formats;
443
}
444
 
445
 
446
int
447
xtensa_isa_num_opcodes (xtensa_isa isa)
448
{
449
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
450
  return intisa->num_opcodes;
451
}
452
 
453
 
454
int
455
xtensa_isa_num_regfiles (xtensa_isa isa)
456
{
457
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
458
  return intisa->num_regfiles;
459
}
460
 
461
 
462
int
463
xtensa_isa_num_states (xtensa_isa isa)
464
{
465
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
466
  return intisa->num_states;
467
}
468
 
469
 
470
int
471
xtensa_isa_num_sysregs (xtensa_isa isa)
472
{
473
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
474
  return intisa->num_sysregs;
475
}
476
 
477
 
478
int
479
xtensa_isa_num_interfaces (xtensa_isa isa)
480
{
481
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
482
  return intisa->num_interfaces;
483
}
484
 
485
 
486
int
487
xtensa_isa_num_funcUnits (xtensa_isa isa)
488
{
489
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
490
  return intisa->num_funcUnits;
491
}
492
 
493
 
494
 
495
/* Instruction formats.  */
496
 
497
 
498
#define CHECK_FORMAT(INTISA,FMT,ERRVAL) \
499
  do { \
500
    if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \
501
      { \
502
        xtisa_errno = xtensa_isa_bad_format; \
503
        strcpy (xtisa_error_msg, "invalid format specifier"); \
504
        return (ERRVAL); \
505
      } \
506
  } while (0)
507
 
508
 
509
#define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \
510
  do { \
511
    if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \
512
      { \
513
        xtisa_errno = xtensa_isa_bad_slot; \
514
        strcpy (xtisa_error_msg, "invalid slot specifier"); \
515
        return (ERRVAL); \
516
      } \
517
  } while (0)
518
 
519
 
520
const char *
521
xtensa_format_name (xtensa_isa isa, xtensa_format fmt)
522
{
523
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
524
  CHECK_FORMAT (intisa, fmt, NULL);
525
  return intisa->formats[fmt].name;
526
}
527
 
528
 
529
xtensa_format
530
xtensa_format_lookup (xtensa_isa isa, const char *fmtname)
531
{
532
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
533
  int fmt;
534
 
535
  if (!fmtname || !*fmtname)
536
    {
537
      xtisa_errno = xtensa_isa_bad_format;
538
      strcpy (xtisa_error_msg, "invalid format name");
539
      return XTENSA_UNDEFINED;
540
    }
541
 
542
  for (fmt = 0; fmt < intisa->num_formats; fmt++)
543
    {
544
      if (strcasecmp (fmtname, intisa->formats[fmt].name) == 0)
545
        return fmt;
546
    }
547
 
548
  xtisa_errno = xtensa_isa_bad_format;
549
  sprintf (xtisa_error_msg, "format \"%s\" not recognized", fmtname);
550
  return XTENSA_UNDEFINED;
551
}
552
 
553
 
554
xtensa_format
555
xtensa_format_decode (xtensa_isa isa, const xtensa_insnbuf insn)
556
{
557
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
558
  xtensa_format fmt;
559
 
560
  fmt = (intisa->format_decode_fn) (insn);
561
  if (fmt != XTENSA_UNDEFINED)
562
    return fmt;
563
 
564
  xtisa_errno = xtensa_isa_bad_format;
565
  strcpy (xtisa_error_msg, "cannot decode instruction format");
566
  return XTENSA_UNDEFINED;
567
}
568
 
569
 
570
int
571
xtensa_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn)
572
{
573
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
574
  CHECK_FORMAT (intisa, fmt, -1);
575
  (*intisa->formats[fmt].encode_fn) (insn);
576
  return 0;
577
}
578
 
579
 
580
int
581
xtensa_format_length (xtensa_isa isa, xtensa_format fmt)
582
{
583
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
584
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
585
  return intisa->formats[fmt].length;
586
}
587
 
588
 
589
int
590
xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
591
{
592
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
593
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
594
  return intisa->formats[fmt].num_slots;
595
}
596
 
597
 
598
xtensa_opcode
599
xtensa_format_slot_nop_opcode (xtensa_isa isa, xtensa_format fmt, int slot)
600
{
601
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
602
  int slot_id;
603
 
604
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
605
  CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
606
 
607
  slot_id = intisa->formats[fmt].slot_id[slot];
608
  return xtensa_opcode_lookup (isa, intisa->slots[slot_id].nop_name);
609
}
610
 
611
 
612
int
613
xtensa_format_get_slot (xtensa_isa isa, xtensa_format fmt, int slot,
614
                        const xtensa_insnbuf insn, xtensa_insnbuf slotbuf)
615
{
616
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
617
  int slot_id;
618
 
619
  CHECK_FORMAT (intisa, fmt, -1);
620
  CHECK_SLOT (intisa, fmt, slot, -1);
621
 
622
  slot_id = intisa->formats[fmt].slot_id[slot];
623
  (*intisa->slots[slot_id].get_fn) (insn, slotbuf);
624
  return 0;
625
}
626
 
627
 
628
int
629
xtensa_format_set_slot (xtensa_isa isa, xtensa_format fmt, int slot,
630
                        xtensa_insnbuf insn, const xtensa_insnbuf slotbuf)
631
{
632
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
633
  int slot_id;
634
 
635
  CHECK_FORMAT (intisa, fmt, -1);
636
  CHECK_SLOT (intisa, fmt, slot, -1);
637
 
638
  slot_id = intisa->formats[fmt].slot_id[slot];
639
  (*intisa->slots[slot_id].set_fn) (insn, slotbuf);
640
  return 0;
641
}
642
 
643
 
644
 
645
/* Opcode information.  */
646
 
647
 
648
#define CHECK_OPCODE(INTISA,OPC,ERRVAL) \
649
  do { \
650
    if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \
651
      { \
652
        xtisa_errno = xtensa_isa_bad_opcode; \
653
        strcpy (xtisa_error_msg, "invalid opcode specifier"); \
654
        return (ERRVAL); \
655
      } \
656
  } while (0)
657
 
658
 
659
xtensa_opcode
660
xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
661
{
662
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
663
  xtensa_lookup_entry entry, *result = 0;
664
 
665
  if (!opname || !*opname)
666
    {
667
      xtisa_errno = xtensa_isa_bad_opcode;
668
      strcpy (xtisa_error_msg, "invalid opcode name");
669
      return XTENSA_UNDEFINED;
670
    }
671
 
672
  if (intisa->num_opcodes != 0)
673
    {
674
      entry.key = opname;
675
      result = bsearch (&entry, intisa->opname_lookup_table,
676
                        intisa->num_opcodes, sizeof (xtensa_lookup_entry),
677
                        xtensa_isa_name_compare);
678
    }
679
 
680
  if (!result)
681
    {
682
      xtisa_errno = xtensa_isa_bad_opcode;
683
      sprintf (xtisa_error_msg, "opcode \"%s\" not recognized", opname);
684
      return XTENSA_UNDEFINED;
685
    }
686
 
687
  return result->u.opcode;
688
}
689
 
690
 
691
xtensa_opcode
692
xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot,
693
                      const xtensa_insnbuf slotbuf)
694
{
695
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
696
  int slot_id;
697
  xtensa_opcode opc;
698
 
699
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
700
  CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
701
 
702
  slot_id = intisa->formats[fmt].slot_id[slot];
703
 
704
  opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
705
  if (opc != XTENSA_UNDEFINED)
706
    return opc;
707
 
708
  xtisa_errno = xtensa_isa_bad_opcode;
709
  strcpy (xtisa_error_msg, "cannot decode opcode");
710
  return XTENSA_UNDEFINED;
711
}
712
 
713
 
714
int
715
xtensa_opcode_encode (xtensa_isa isa, xtensa_format fmt, int slot,
716
                      xtensa_insnbuf slotbuf, xtensa_opcode opc)
717
{
718
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
719
  int slot_id;
720
  xtensa_opcode_encode_fn encode_fn;
721
 
722
  CHECK_FORMAT (intisa, fmt, -1);
723
  CHECK_SLOT (intisa, fmt, slot, -1);
724
  CHECK_OPCODE (intisa, opc, -1);
725
 
726
  slot_id = intisa->formats[fmt].slot_id[slot];
727
  encode_fn = intisa->opcodes[opc].encode_fns[slot_id];
728
  if (!encode_fn)
729
    {
730
      xtisa_errno = xtensa_isa_wrong_slot;
731
      sprintf (xtisa_error_msg,
732
               "opcode \"%s\" is not allowed in slot %d of format \"%s\"",
733
               intisa->opcodes[opc].name, slot, intisa->formats[fmt].name);
734
      return -1;
735
    }
736
  (*encode_fn) (slotbuf);
737
  return 0;
738
}
739
 
740
 
741
const char *
742
xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
743
{
744
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
745
  CHECK_OPCODE (intisa, opc, NULL);
746
  return intisa->opcodes[opc].name;
747
}
748
 
749
 
750
int
751
xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc)
752
{
753
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
754
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
755
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0)
756
    return 1;
757
  return 0;
758
}
759
 
760
 
761
int
762
xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc)
763
{
764
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
765
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
766
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0)
767
    return 1;
768
  return 0;
769
}
770
 
771
 
772
int
773
xtensa_opcode_is_loop (xtensa_isa isa, xtensa_opcode opc)
774
{
775
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
776
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
777
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_LOOP) != 0)
778
    return 1;
779
  return 0;
780
}
781
 
782
 
783
int
784
xtensa_opcode_is_call (xtensa_isa isa, xtensa_opcode opc)
785
{
786
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
787
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
788
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0)
789
    return 1;
790
  return 0;
791
}
792
 
793
 
794
int
795
xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
796
{
797
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
798
  int iclass_id;
799
 
800
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
801
  iclass_id = intisa->opcodes[opc].iclass_id;
802
  return intisa->iclasses[iclass_id].num_operands;
803
}
804
 
805
 
806
int
807
xtensa_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc)
808
{
809
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
810
  int iclass_id;
811
 
812
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
813
  iclass_id = intisa->opcodes[opc].iclass_id;
814
  return intisa->iclasses[iclass_id].num_stateOperands;
815
}
816
 
817
 
818
int
819
xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc)
820
{
821
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
822
  int iclass_id;
823
 
824
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
825
  iclass_id = intisa->opcodes[opc].iclass_id;
826
  return intisa->iclasses[iclass_id].num_interfaceOperands;
827
}
828
 
829
 
830
int
831
xtensa_opcode_num_funcUnit_uses (xtensa_isa isa, xtensa_opcode opc)
832
{
833
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
834
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
835
  return intisa->opcodes[opc].num_funcUnit_uses;
836
}
837
 
838
 
839
xtensa_funcUnit_use *
840
xtensa_opcode_funcUnit_use (xtensa_isa isa, xtensa_opcode opc, int u)
841
{
842
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
843
  CHECK_OPCODE (intisa, opc, NULL);
844
  if (u < 0 || u >= intisa->opcodes[opc].num_funcUnit_uses)
845
    {
846
      xtisa_errno = xtensa_isa_bad_funcUnit;
847
      sprintf (xtisa_error_msg, "invalid functional unit use number (%d); "
848
               "opcode \"%s\" has %d", u, intisa->opcodes[opc].name,
849
               intisa->opcodes[opc].num_funcUnit_uses);
850
      return NULL;
851
    }
852
  return &intisa->opcodes[opc].funcUnit_uses[u];
853
}
854
 
855
 
856
 
857
/* Operand information.  */
858
 
859
 
860
#define CHECK_OPERAND(INTISA,OPC,ICLASS,OPND,ERRVAL) \
861
  do { \
862
    if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \
863
      { \
864
        xtisa_errno = xtensa_isa_bad_operand; \
865
        sprintf (xtisa_error_msg, "invalid operand number (%d); " \
866
                 "opcode \"%s\" has %d operands", (OPND), \
867
                 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_operands); \
868
        return (ERRVAL); \
869
      } \
870
  } while (0)
871
 
872
 
873
static xtensa_operand_internal *
874
get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd)
875
{
876
  xtensa_iclass_internal *iclass;
877
  int iclass_id, operand_id;
878
 
879
  CHECK_OPCODE (intisa, opc, NULL);
880
  iclass_id = intisa->opcodes[opc].iclass_id;
881
  iclass = &intisa->iclasses[iclass_id];
882
  CHECK_OPERAND (intisa, opc, iclass, opnd, NULL);
883
  operand_id = iclass->operands[opnd].u.operand_id;
884
  return &intisa->operands[operand_id];
885
}
886
 
887
 
888
const char *
889
xtensa_operand_name (xtensa_isa isa, xtensa_opcode opc, int opnd)
890
{
891
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
892
  xtensa_operand_internal *intop;
893
 
894
  intop = get_operand (intisa, opc, opnd);
895
  if (!intop) return NULL;
896
  return intop->name;
897
}
898
 
899
 
900
int
901
xtensa_operand_is_visible (xtensa_isa isa, xtensa_opcode opc, int opnd)
902
{
903
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
904
  xtensa_iclass_internal *iclass;
905
  int iclass_id, operand_id;
906
  xtensa_operand_internal *intop;
907
 
908
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
909
  iclass_id = intisa->opcodes[opc].iclass_id;
910
  iclass = &intisa->iclasses[iclass_id];
911
  CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED);
912
 
913
  /* Special case for "sout" operands.  */
914
  if (iclass->operands[opnd].inout == 's')
915
    return 0;
916
 
917
  operand_id = iclass->operands[opnd].u.operand_id;
918
  intop = &intisa->operands[operand_id];
919
 
920
  if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0)
921
    return 1;
922
  return 0;
923
}
924
 
925
 
926
char
927
xtensa_operand_inout (xtensa_isa isa, xtensa_opcode opc, int opnd)
928
{
929
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
930
  xtensa_iclass_internal *iclass;
931
  int iclass_id;
932
  char inout;
933
 
934
  CHECK_OPCODE (intisa, opc, 0);
935
  iclass_id = intisa->opcodes[opc].iclass_id;
936
  iclass = &intisa->iclasses[iclass_id];
937
  CHECK_OPERAND (intisa, opc, iclass, opnd, 0);
938
  inout = iclass->operands[opnd].inout;
939
 
940
  /* Special case for "sout" operands.  */
941
  if (inout == 's')
942
    return 'o';
943
 
944
  return inout;
945
}
946
 
947
 
948
int
949
xtensa_operand_get_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
950
                          xtensa_format fmt, int slot,
951
                          const xtensa_insnbuf slotbuf, uint32 *valp)
952
{
953
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
954
  xtensa_operand_internal *intop;
955
  int slot_id;
956
  xtensa_get_field_fn get_fn;
957
 
958
  intop = get_operand (intisa, opc, opnd);
959
  if (!intop) return -1;
960
 
961
  CHECK_FORMAT (intisa, fmt, -1);
962
  CHECK_SLOT (intisa, fmt, slot, -1);
963
 
964
  slot_id = intisa->formats[fmt].slot_id[slot];
965
  if (intop->field_id == XTENSA_UNDEFINED)
966
    {
967
      xtisa_errno = xtensa_isa_no_field;
968
      strcpy (xtisa_error_msg, "implicit operand has no field");
969
      return -1;
970
    }
971
  get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
972
  if (!get_fn)
973
    {
974
      xtisa_errno = xtensa_isa_wrong_slot;
975
      sprintf (xtisa_error_msg,
976
               "operand \"%s\" does not exist in slot %d of format \"%s\"",
977
               intop->name, slot, intisa->formats[fmt].name);
978
      return -1;
979
    }
980
  *valp = (*get_fn) (slotbuf);
981
  return 0;
982
}
983
 
984
 
985
int
986
xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
987
                          xtensa_format fmt, int slot,
988
                          xtensa_insnbuf slotbuf, uint32 val)
989
{
990
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
991
  xtensa_operand_internal *intop;
992
  int slot_id;
993
  xtensa_set_field_fn set_fn;
994
 
995
  intop = get_operand (intisa, opc, opnd);
996
  if (!intop) return -1;
997
 
998
  CHECK_FORMAT (intisa, fmt, -1);
999
  CHECK_SLOT (intisa, fmt, slot, -1);
1000
 
1001
  slot_id = intisa->formats[fmt].slot_id[slot];
1002
  if (intop->field_id == XTENSA_UNDEFINED)
1003
    {
1004
      xtisa_errno = xtensa_isa_no_field;
1005
      strcpy (xtisa_error_msg, "implicit operand has no field");
1006
      return -1;
1007
    }
1008
  set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id];
1009
  if (!set_fn)
1010
    {
1011
      xtisa_errno = xtensa_isa_wrong_slot;
1012
      sprintf (xtisa_error_msg,
1013
               "operand \"%s\" does not exist in slot %d of format \"%s\"",
1014
               intop->name, slot, intisa->formats[fmt].name);
1015
      return -1;
1016
    }
1017
  (*set_fn) (slotbuf, val);
1018
  return 0;
1019
}
1020
 
1021
 
1022
int
1023
xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1024
                       uint32 *valp)
1025
{
1026
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1027
  xtensa_operand_internal *intop;
1028
  uint32 test_val, orig_val;
1029
 
1030
  intop = get_operand (intisa, opc, opnd);
1031
  if (!intop) return -1;
1032
 
1033
  if (!intop->encode)
1034
    {
1035
      /* This is a default operand for a field.  How can we tell if the
1036
         value fits in the field?  Write the value into the field,
1037
         read it back, and then make sure we get the same value.  */
1038
 
1039
      xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1040
      static xtensa_insnbuf tmpbuf = 0;
1041
      int slot_id;
1042
 
1043
      if (!tmpbuf)
1044
        {
1045
          tmpbuf = xtensa_insnbuf_alloc (isa);
1046
          CHECK_ALLOC (tmpbuf, -1);
1047
        }
1048
 
1049
      /* A default operand is always associated with a field,
1050
         but check just to be sure....  */
1051
      if (intop->field_id == XTENSA_UNDEFINED)
1052
        {
1053
          xtisa_errno = xtensa_isa_internal_error;
1054
          strcpy (xtisa_error_msg, "operand has no field");
1055
          return -1;
1056
        }
1057
 
1058
      /* Find some slot that includes the field.  */
1059
      for (slot_id = 0; slot_id < intisa->num_slots; slot_id++)
1060
        {
1061
          xtensa_get_field_fn get_fn =
1062
            intisa->slots[slot_id].get_field_fns[intop->field_id];
1063
          xtensa_set_field_fn set_fn =
1064
            intisa->slots[slot_id].set_field_fns[intop->field_id];
1065
 
1066
          if (get_fn && set_fn)
1067
            {
1068
              (*set_fn) (tmpbuf, *valp);
1069
              return ((*get_fn) (tmpbuf) != *valp);
1070
            }
1071
        }
1072
 
1073
      /* Couldn't find any slot containing the field....  */
1074
      xtisa_errno = xtensa_isa_no_field;
1075
      strcpy (xtisa_error_msg, "field does not exist in any slot");
1076
      return -1;
1077
    }
1078
 
1079
  /* Encode the value.  In some cases, the encoding function may detect
1080
     errors, but most of the time the only way to determine if the value
1081
     was successfully encoded is to decode it and check if it matches
1082
     the original value.  */
1083
  orig_val = *valp;
1084
  if ((*intop->encode) (valp) ||
1085
      (test_val = *valp, (*intop->decode) (&test_val)) ||
1086
      test_val != orig_val)
1087
    {
1088
      xtisa_errno = xtensa_isa_bad_value;
1089
      sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp);
1090
      return -1;
1091
    }
1092
 
1093
  return 0;
1094
}
1095
 
1096
 
1097
int
1098
xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1099
                       uint32 *valp)
1100
{
1101
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1102
  xtensa_operand_internal *intop;
1103
 
1104
  intop = get_operand (intisa, opc, opnd);
1105
  if (!intop) return -1;
1106
 
1107
  /* Use identity function for "default" operands.  */
1108
  if (!intop->decode)
1109
    return 0;
1110
 
1111
  if ((*intop->decode) (valp))
1112
    {
1113
      xtisa_errno = xtensa_isa_bad_value;
1114
      sprintf (xtisa_error_msg, "cannot decode operand value 0x%08x", *valp);
1115
      return -1;
1116
    }
1117
  return 0;
1118
}
1119
 
1120
 
1121
int
1122
xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
1123
{
1124
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1125
  xtensa_operand_internal *intop;
1126
 
1127
  intop = get_operand (intisa, opc, opnd);
1128
  if (!intop) return XTENSA_UNDEFINED;
1129
 
1130
  if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
1131
    return 1;
1132
  return 0;
1133
}
1134
 
1135
 
1136
xtensa_regfile
1137
xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
1138
{
1139
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1140
  xtensa_operand_internal *intop;
1141
 
1142
  intop = get_operand (intisa, opc, opnd);
1143
  if (!intop) return XTENSA_UNDEFINED;
1144
 
1145
  return intop->regfile;
1146
}
1147
 
1148
 
1149
int
1150
xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
1151
{
1152
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1153
  xtensa_operand_internal *intop;
1154
 
1155
  intop = get_operand (intisa, opc, opnd);
1156
  if (!intop) return XTENSA_UNDEFINED;
1157
 
1158
  return intop->num_regs;
1159
}
1160
 
1161
 
1162
int
1163
xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd)
1164
{
1165
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1166
  xtensa_operand_internal *intop;
1167
 
1168
  intop = get_operand (intisa, opc, opnd);
1169
  if (!intop) return XTENSA_UNDEFINED;
1170
 
1171
  if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0)
1172
    return 1;
1173
  return 0;
1174
}
1175
 
1176
 
1177
int
1178
xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd)
1179
{
1180
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1181
  xtensa_operand_internal *intop;
1182
 
1183
  intop = get_operand (intisa, opc, opnd);
1184
  if (!intop) return XTENSA_UNDEFINED;
1185
 
1186
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0)
1187
    return 1;
1188
  return 0;
1189
}
1190
 
1191
 
1192
int
1193
xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
1194
                         uint32 *valp, uint32 pc)
1195
{
1196
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1197
  xtensa_operand_internal *intop;
1198
 
1199
  intop = get_operand (intisa, opc, opnd);
1200
  if (!intop) return -1;
1201
 
1202
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1203
    return 0;
1204
 
1205
  if (!intop->do_reloc)
1206
    {
1207
      xtisa_errno = xtensa_isa_internal_error;
1208
      strcpy (xtisa_error_msg, "operand missing do_reloc function");
1209
      return -1;
1210
    }
1211
 
1212
  if ((*intop->do_reloc) (valp, pc))
1213
    {
1214
      xtisa_errno = xtensa_isa_bad_value;
1215
      sprintf (xtisa_error_msg,
1216
               "do_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
1217
      return -1;
1218
    }
1219
 
1220
  return 0;
1221
}
1222
 
1223
 
1224
int
1225
xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
1226
                           uint32 *valp, uint32 pc)
1227
{
1228
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1229
  xtensa_operand_internal *intop;
1230
 
1231
  intop = get_operand (intisa, opc, opnd);
1232
  if (!intop) return -1;
1233
 
1234
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1235
    return 0;
1236
 
1237
  if (!intop->undo_reloc)
1238
    {
1239
      xtisa_errno = xtensa_isa_internal_error;
1240
      strcpy (xtisa_error_msg, "operand missing undo_reloc function");
1241
      return -1;
1242
    }
1243
 
1244
  if ((*intop->undo_reloc) (valp, pc))
1245
    {
1246
      xtisa_errno = xtensa_isa_bad_value;
1247
      sprintf (xtisa_error_msg,
1248
               "undo_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
1249
      return -1;
1250
    }
1251
 
1252
  return 0;
1253
}
1254
 
1255
 
1256
 
1257
/* State Operands.  */
1258
 
1259
 
1260
#define CHECK_STATE_OPERAND(INTISA,OPC,ICLASS,STOP,ERRVAL) \
1261
  do { \
1262
    if ((STOP) < 0 || (STOP) >= (ICLASS)->num_stateOperands) \
1263
      { \
1264
        xtisa_errno = xtensa_isa_bad_operand; \
1265
        sprintf (xtisa_error_msg, "invalid state operand number (%d); " \
1266
                 "opcode \"%s\" has %d state operands", (STOP), \
1267
                 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_stateOperands); \
1268
        return (ERRVAL); \
1269
      } \
1270
  } while (0)
1271
 
1272
 
1273
xtensa_state
1274
xtensa_stateOperand_state (xtensa_isa isa, xtensa_opcode opc, int stOp)
1275
{
1276
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1277
  xtensa_iclass_internal *iclass;
1278
  int iclass_id;
1279
 
1280
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
1281
  iclass_id = intisa->opcodes[opc].iclass_id;
1282
  iclass = &intisa->iclasses[iclass_id];
1283
  CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, XTENSA_UNDEFINED);
1284
  return iclass->stateOperands[stOp].u.state;
1285
}
1286
 
1287
 
1288
char
1289
xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp)
1290
{
1291
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1292
  xtensa_iclass_internal *iclass;
1293
  int iclass_id;
1294
 
1295
  CHECK_OPCODE (intisa, opc, 0);
1296
  iclass_id = intisa->opcodes[opc].iclass_id;
1297
  iclass = &intisa->iclasses[iclass_id];
1298
  CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, 0);
1299
  return iclass->stateOperands[stOp].inout;
1300
}
1301
 
1302
 
1303
 
1304
/* Interface Operands.  */
1305
 
1306
 
1307
#define CHECK_INTERFACE_OPERAND(INTISA,OPC,ICLASS,IFOP,ERRVAL) \
1308
  do { \
1309
    if ((IFOP) < 0 || (IFOP) >= (ICLASS)->num_interfaceOperands) \
1310
      { \
1311
        xtisa_errno = xtensa_isa_bad_operand; \
1312
        sprintf (xtisa_error_msg, "invalid interface operand number (%d); " \
1313
                 "opcode \"%s\" has %d interface operands", (IFOP), \
1314
                 (INTISA)->opcodes[(OPC)].name, \
1315
                 (ICLASS)->num_interfaceOperands); \
1316
        return (ERRVAL); \
1317
      } \
1318
  } while (0)
1319
 
1320
 
1321
xtensa_interface
1322
xtensa_interfaceOperand_interface (xtensa_isa isa, xtensa_opcode opc,
1323
                                   int ifOp)
1324
{
1325
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1326
  xtensa_iclass_internal *iclass;
1327
  int iclass_id;
1328
 
1329
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
1330
  iclass_id = intisa->opcodes[opc].iclass_id;
1331
  iclass = &intisa->iclasses[iclass_id];
1332
  CHECK_INTERFACE_OPERAND (intisa, opc, iclass, ifOp, XTENSA_UNDEFINED);
1333
  return iclass->interfaceOperands[ifOp];
1334
}
1335
 
1336
 
1337
 
1338
/* Register Files.  */
1339
 
1340
 
1341
#define CHECK_REGFILE(INTISA,RF,ERRVAL) \
1342
  do { \
1343
    if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \
1344
      { \
1345
        xtisa_errno = xtensa_isa_bad_regfile; \
1346
        strcpy (xtisa_error_msg, "invalid regfile specifier"); \
1347
        return (ERRVAL); \
1348
      } \
1349
  } while (0)
1350
 
1351
 
1352
xtensa_regfile
1353
xtensa_regfile_lookup (xtensa_isa isa, const char *name)
1354
{
1355
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1356
  int n;
1357
 
1358
  if (!name || !*name)
1359
    {
1360
      xtisa_errno = xtensa_isa_bad_regfile;
1361
      strcpy (xtisa_error_msg, "invalid regfile name");
1362
      return XTENSA_UNDEFINED;
1363
    }
1364
 
1365
  /* The expected number of regfiles is small; use a linear search.  */
1366
  for (n = 0; n < intisa->num_regfiles; n++)
1367
    {
1368
      if (!strcmp (intisa->regfiles[n].name, name))
1369
        return n;
1370
    }
1371
 
1372
  xtisa_errno = xtensa_isa_bad_regfile;
1373
  sprintf (xtisa_error_msg, "regfile \"%s\" not recognized", name);
1374
  return XTENSA_UNDEFINED;
1375
}
1376
 
1377
 
1378
xtensa_regfile
1379
xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname)
1380
{
1381
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1382
  int n;
1383
 
1384
  if (!shortname || !*shortname)
1385
    {
1386
      xtisa_errno = xtensa_isa_bad_regfile;
1387
      strcpy (xtisa_error_msg, "invalid regfile shortname");
1388
      return XTENSA_UNDEFINED;
1389
    }
1390
 
1391
  /* The expected number of regfiles is small; use a linear search.  */
1392
  for (n = 0; n < intisa->num_regfiles; n++)
1393
    {
1394
      /* Ignore regfile views since they always have the same shortnames
1395
         as their parents.  */
1396
      if (intisa->regfiles[n].parent != n)
1397
        continue;
1398
      if (!strcmp (intisa->regfiles[n].shortname, shortname))
1399
        return n;
1400
    }
1401
 
1402
  xtisa_errno = xtensa_isa_bad_regfile;
1403
  sprintf (xtisa_error_msg, "regfile shortname \"%s\" not recognized",
1404
           shortname);
1405
  return XTENSA_UNDEFINED;
1406
}
1407
 
1408
 
1409
const char *
1410
xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf)
1411
{
1412
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1413
  CHECK_REGFILE (intisa, rf, NULL);
1414
  return intisa->regfiles[rf].name;
1415
}
1416
 
1417
 
1418
const char *
1419
xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf)
1420
{
1421
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1422
  CHECK_REGFILE (intisa, rf, NULL);
1423
  return intisa->regfiles[rf].shortname;
1424
}
1425
 
1426
 
1427
xtensa_regfile
1428
xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf)
1429
{
1430
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1431
  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1432
  return intisa->regfiles[rf].parent;
1433
}
1434
 
1435
 
1436
int
1437
xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf)
1438
{
1439
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1440
  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1441
  return intisa->regfiles[rf].num_bits;
1442
}
1443
 
1444
 
1445
int
1446
xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf)
1447
{
1448
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1449
  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1450
  return intisa->regfiles[rf].num_entries;
1451
}
1452
 
1453
 
1454
 
1455
/* Processor States.  */
1456
 
1457
 
1458
#define CHECK_STATE(INTISA,ST,ERRVAL) \
1459
  do { \
1460
    if ((ST) < 0 || (ST) >= (INTISA)->num_states) \
1461
      { \
1462
        xtisa_errno = xtensa_isa_bad_state; \
1463
        strcpy (xtisa_error_msg, "invalid state specifier"); \
1464
        return (ERRVAL); \
1465
      } \
1466
  } while (0)
1467
 
1468
 
1469
xtensa_state
1470
xtensa_state_lookup (xtensa_isa isa, const char *name)
1471
{
1472
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1473
  xtensa_lookup_entry entry, *result = 0;
1474
 
1475
  if (!name || !*name)
1476
    {
1477
      xtisa_errno = xtensa_isa_bad_state;
1478
      strcpy (xtisa_error_msg, "invalid state name");
1479
      return XTENSA_UNDEFINED;
1480
    }
1481
 
1482
  if (intisa->num_states != 0)
1483
    {
1484
      entry.key = name;
1485
      result = bsearch (&entry, intisa->state_lookup_table, intisa->num_states,
1486
                        sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
1487
    }
1488
 
1489
  if (!result)
1490
    {
1491
      xtisa_errno = xtensa_isa_bad_state;
1492
      sprintf (xtisa_error_msg, "state \"%s\" not recognized", name);
1493
      return XTENSA_UNDEFINED;
1494
    }
1495
 
1496
  return result->u.state;
1497
}
1498
 
1499
 
1500
const char *
1501
xtensa_state_name (xtensa_isa isa, xtensa_state st)
1502
{
1503
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1504
  CHECK_STATE (intisa, st, NULL);
1505
  return intisa->states[st].name;
1506
}
1507
 
1508
 
1509
int
1510
xtensa_state_num_bits (xtensa_isa isa, xtensa_state st)
1511
{
1512
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1513
  CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1514
  return intisa->states[st].num_bits;
1515
}
1516
 
1517
 
1518
int
1519
xtensa_state_is_exported (xtensa_isa isa, xtensa_state st)
1520
{
1521
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1522
  CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1523
  if ((intisa->states[st].flags & XTENSA_STATE_IS_EXPORTED) != 0)
1524
    return 1;
1525
  return 0;
1526
}
1527
 
1528
 
1529
int
1530
xtensa_state_is_shared_or (xtensa_isa isa, xtensa_state st)
1531
{
1532
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1533
  CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1534
  if ((intisa->states[st].flags & XTENSA_STATE_IS_SHARED_OR) != 0)
1535
    return 1;
1536
  return 0;
1537
}
1538
 
1539
 
1540
 
1541
/* Sysregs.  */
1542
 
1543
 
1544
#define CHECK_SYSREG(INTISA,SYSREG,ERRVAL) \
1545
  do { \
1546
    if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) \
1547
      { \
1548
        xtisa_errno = xtensa_isa_bad_sysreg; \
1549
        strcpy (xtisa_error_msg, "invalid sysreg specifier"); \
1550
        return (ERRVAL); \
1551
      } \
1552
  } while (0)
1553
 
1554
 
1555
xtensa_sysreg
1556
xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user)
1557
{
1558
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1559
 
1560
  if (is_user != 0)
1561
    is_user = 1;
1562
 
1563
  if (num < 0 || num > intisa->max_sysreg_num[is_user]
1564
      || intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED)
1565
    {
1566
      xtisa_errno = xtensa_isa_bad_sysreg;
1567
      strcpy (xtisa_error_msg, "sysreg not recognized");
1568
      return XTENSA_UNDEFINED;
1569
    }
1570
 
1571
  return intisa->sysreg_table[is_user][num];
1572
}
1573
 
1574
 
1575
xtensa_sysreg
1576
xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name)
1577
{
1578
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1579
  xtensa_lookup_entry entry, *result = 0;
1580
 
1581
  if (!name || !*name)
1582
    {
1583
      xtisa_errno = xtensa_isa_bad_sysreg;
1584
      strcpy (xtisa_error_msg, "invalid sysreg name");
1585
      return XTENSA_UNDEFINED;
1586
    }
1587
 
1588
  if (intisa->num_sysregs != 0)
1589
    {
1590
      entry.key = name;
1591
      result = bsearch (&entry, intisa->sysreg_lookup_table,
1592
                        intisa->num_sysregs, sizeof (xtensa_lookup_entry),
1593
                        xtensa_isa_name_compare);
1594
    }
1595
 
1596
  if (!result)
1597
    {
1598
      xtisa_errno = xtensa_isa_bad_sysreg;
1599
      sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name);
1600
      return XTENSA_UNDEFINED;
1601
    }
1602
 
1603
  return result->u.sysreg;
1604
}
1605
 
1606
 
1607
const char *
1608
xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg)
1609
{
1610
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1611
  CHECK_SYSREG (intisa, sysreg, NULL);
1612
  return intisa->sysregs[sysreg].name;
1613
}
1614
 
1615
 
1616
int
1617
xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg)
1618
{
1619
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1620
  CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
1621
  return intisa->sysregs[sysreg].number;
1622
}
1623
 
1624
 
1625
int
1626
xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg)
1627
{
1628
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1629
  CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
1630
  if (intisa->sysregs[sysreg].is_user)
1631
    return 1;
1632
  return 0;
1633
}
1634
 
1635
 
1636
 
1637
/* Interfaces.  */
1638
 
1639
 
1640
#define CHECK_INTERFACE(INTISA,INTF,ERRVAL) \
1641
  do { \
1642
    if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) \
1643
      { \
1644
        xtisa_errno = xtensa_isa_bad_interface; \
1645
        strcpy (xtisa_error_msg, "invalid interface specifier"); \
1646
        return (ERRVAL); \
1647
      } \
1648
  } while (0)
1649
 
1650
 
1651
xtensa_interface
1652
xtensa_interface_lookup (xtensa_isa isa, const char *ifname)
1653
{
1654
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1655
  xtensa_lookup_entry entry, *result = 0;
1656
 
1657
  if (!ifname || !*ifname)
1658
    {
1659
      xtisa_errno = xtensa_isa_bad_interface;
1660
      strcpy (xtisa_error_msg, "invalid interface name");
1661
      return XTENSA_UNDEFINED;
1662
    }
1663
 
1664
  if (intisa->num_interfaces != 0)
1665
    {
1666
      entry.key = ifname;
1667
      result = bsearch (&entry, intisa->interface_lookup_table,
1668
                        intisa->num_interfaces, sizeof (xtensa_lookup_entry),
1669
                        xtensa_isa_name_compare);
1670
    }
1671
 
1672
  if (!result)
1673
    {
1674
      xtisa_errno = xtensa_isa_bad_interface;
1675
      sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname);
1676
      return XTENSA_UNDEFINED;
1677
    }
1678
 
1679
  return result->u.intf;
1680
}
1681
 
1682
 
1683
const char *
1684
xtensa_interface_name (xtensa_isa isa, xtensa_interface intf)
1685
{
1686
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1687
  CHECK_INTERFACE (intisa, intf, NULL);
1688
  return intisa->interfaces[intf].name;
1689
}
1690
 
1691
 
1692
int
1693
xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf)
1694
{
1695
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1696
  CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1697
  return intisa->interfaces[intf].num_bits;
1698
}
1699
 
1700
 
1701
char
1702
xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf)
1703
{
1704
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1705
  CHECK_INTERFACE (intisa, intf, 0);
1706
  return intisa->interfaces[intf].inout;
1707
}
1708
 
1709
 
1710
int
1711
xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf)
1712
{
1713
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1714
  CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1715
  if ((intisa->interfaces[intf].flags & XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0)
1716
    return 1;
1717
  return 0;
1718
}
1719
 
1720
 
1721
int
1722
xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf)
1723
{
1724
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1725
  CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1726
  return intisa->interfaces[intf].class_id;
1727
}
1728
 
1729
 
1730
 
1731
/* Functional Units.  */
1732
 
1733
 
1734
#define CHECK_FUNCUNIT(INTISA,FUN,ERRVAL) \
1735
  do { \
1736
    if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) \
1737
      { \
1738
        xtisa_errno = xtensa_isa_bad_funcUnit; \
1739
        strcpy (xtisa_error_msg, "invalid functional unit specifier"); \
1740
        return (ERRVAL); \
1741
      } \
1742
  } while (0)
1743
 
1744
 
1745
xtensa_funcUnit
1746
xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname)
1747
{
1748
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1749
  xtensa_lookup_entry entry, *result = 0;
1750
 
1751
  if (!fname || !*fname)
1752
    {
1753
      xtisa_errno = xtensa_isa_bad_funcUnit;
1754
      strcpy (xtisa_error_msg, "invalid functional unit name");
1755
      return XTENSA_UNDEFINED;
1756
    }
1757
 
1758
  if (intisa->num_funcUnits != 0)
1759
    {
1760
      entry.key = fname;
1761
      result = bsearch (&entry, intisa->funcUnit_lookup_table,
1762
                        intisa->num_funcUnits, sizeof (xtensa_lookup_entry),
1763
                        xtensa_isa_name_compare);
1764
    }
1765
 
1766
  if (!result)
1767
    {
1768
      xtisa_errno = xtensa_isa_bad_funcUnit;
1769
      sprintf (xtisa_error_msg,
1770
               "functional unit \"%s\" not recognized", fname);
1771
      return XTENSA_UNDEFINED;
1772
    }
1773
 
1774
  return result->u.fun;
1775
}
1776
 
1777
 
1778
const char *
1779
xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun)
1780
{
1781
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1782
  CHECK_FUNCUNIT (intisa, fun, NULL);
1783
  return intisa->funcUnits[fun].name;
1784
}
1785
 
1786
 
1787
int
1788
xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun)
1789
{
1790
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1791
  CHECK_FUNCUNIT (intisa, fun, XTENSA_UNDEFINED);
1792
  return intisa->funcUnits[fun].num_copies;
1793
}
1794
 

powered by: WebSVN 2.1.0

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