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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [xtensa-isa.c] - Blame information for rev 145

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

Line No. Rev Author Line
1 14 khays
/* Configurable Xtensa ISA support.
2
   Copyright 2003, 2004, 2005, 2007, 2008, 2009 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)
1032
    return -1;
1033
 
1034
  if (!intop->encode)
1035
    {
1036
      /* This is a default operand for a field.  How can we tell if the
1037
         value fits in the field?  Write the value into the field,
1038
         read it back, and then make sure we get the same value.  */
1039
      static xtensa_insnbuf tmpbuf = 0;
1040
      int slot_id;
1041
 
1042
      if (!tmpbuf)
1043
        {
1044
          tmpbuf = xtensa_insnbuf_alloc (isa);
1045
          CHECK_ALLOC (tmpbuf, -1);
1046
        }
1047
 
1048
      /* A default operand is always associated with a field,
1049
         but check just to be sure....  */
1050
      if (intop->field_id == XTENSA_UNDEFINED)
1051
        {
1052
          xtisa_errno = xtensa_isa_internal_error;
1053
          strcpy (xtisa_error_msg, "operand has no field");
1054
          return -1;
1055
        }
1056
 
1057
      /* Find some slot that includes the field.  */
1058
      for (slot_id = 0; slot_id < intisa->num_slots; slot_id++)
1059
        {
1060
          xtensa_get_field_fn get_fn =
1061
            intisa->slots[slot_id].get_field_fns[intop->field_id];
1062
          xtensa_set_field_fn set_fn =
1063
            intisa->slots[slot_id].set_field_fns[intop->field_id];
1064
 
1065
          if (get_fn && set_fn)
1066
            {
1067
              (*set_fn) (tmpbuf, *valp);
1068
              return ((*get_fn) (tmpbuf) != *valp);
1069
            }
1070
        }
1071
 
1072
      /* Couldn't find any slot containing the field....  */
1073
      xtisa_errno = xtensa_isa_no_field;
1074
      strcpy (xtisa_error_msg, "field does not exist in any slot");
1075
      return -1;
1076
    }
1077
 
1078
  /* Encode the value.  In some cases, the encoding function may detect
1079
     errors, but most of the time the only way to determine if the value
1080
     was successfully encoded is to decode it and check if it matches
1081
     the original value.  */
1082
  orig_val = *valp;
1083
  if ((*intop->encode) (valp)
1084
      || (test_val = *valp, (*intop->decode) (&test_val))
1085
      || test_val != orig_val)
1086
    {
1087
      xtisa_errno = xtensa_isa_bad_value;
1088
      sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp);
1089
      return -1;
1090
    }
1091
 
1092
  return 0;
1093
}
1094
 
1095
 
1096
int
1097
xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1098
                       uint32 *valp)
1099
{
1100
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1101
  xtensa_operand_internal *intop;
1102
 
1103
  intop = get_operand (intisa, opc, opnd);
1104
  if (!intop) return -1;
1105
 
1106
  /* Use identity function for "default" operands.  */
1107
  if (!intop->decode)
1108
    return 0;
1109
 
1110
  if ((*intop->decode) (valp))
1111
    {
1112
      xtisa_errno = xtensa_isa_bad_value;
1113
      sprintf (xtisa_error_msg, "cannot decode operand value 0x%08x", *valp);
1114
      return -1;
1115
    }
1116
  return 0;
1117
}
1118
 
1119
 
1120
int
1121
xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
1122
{
1123
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1124
  xtensa_operand_internal *intop;
1125
 
1126
  intop = get_operand (intisa, opc, opnd);
1127
  if (!intop) return XTENSA_UNDEFINED;
1128
 
1129
  if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
1130
    return 1;
1131
  return 0;
1132
}
1133
 
1134
 
1135
xtensa_regfile
1136
xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
1137
{
1138
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1139
  xtensa_operand_internal *intop;
1140
 
1141
  intop = get_operand (intisa, opc, opnd);
1142
  if (!intop) return XTENSA_UNDEFINED;
1143
 
1144
  return intop->regfile;
1145
}
1146
 
1147
 
1148
int
1149
xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
1150
{
1151
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1152
  xtensa_operand_internal *intop;
1153
 
1154
  intop = get_operand (intisa, opc, opnd);
1155
  if (!intop) return XTENSA_UNDEFINED;
1156
 
1157
  return intop->num_regs;
1158
}
1159
 
1160
 
1161
int
1162
xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd)
1163
{
1164
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1165
  xtensa_operand_internal *intop;
1166
 
1167
  intop = get_operand (intisa, opc, opnd);
1168
  if (!intop) return XTENSA_UNDEFINED;
1169
 
1170
  if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0)
1171
    return 1;
1172
  return 0;
1173
}
1174
 
1175
 
1176
int
1177
xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd)
1178
{
1179
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1180
  xtensa_operand_internal *intop;
1181
 
1182
  intop = get_operand (intisa, opc, opnd);
1183
  if (!intop) return XTENSA_UNDEFINED;
1184
 
1185
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0)
1186
    return 1;
1187
  return 0;
1188
}
1189
 
1190
 
1191
int
1192
xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
1193
                         uint32 *valp, uint32 pc)
1194
{
1195
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1196
  xtensa_operand_internal *intop;
1197
 
1198
  intop = get_operand (intisa, opc, opnd);
1199
  if (!intop) return -1;
1200
 
1201
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1202
    return 0;
1203
 
1204
  if (!intop->do_reloc)
1205
    {
1206
      xtisa_errno = xtensa_isa_internal_error;
1207
      strcpy (xtisa_error_msg, "operand missing do_reloc function");
1208
      return -1;
1209
    }
1210
 
1211
  if ((*intop->do_reloc) (valp, pc))
1212
    {
1213
      xtisa_errno = xtensa_isa_bad_value;
1214
      sprintf (xtisa_error_msg,
1215
               "do_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
1216
      return -1;
1217
    }
1218
 
1219
  return 0;
1220
}
1221
 
1222
 
1223
int
1224
xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
1225
                           uint32 *valp, uint32 pc)
1226
{
1227
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1228
  xtensa_operand_internal *intop;
1229
 
1230
  intop = get_operand (intisa, opc, opnd);
1231
  if (!intop) return -1;
1232
 
1233
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1234
    return 0;
1235
 
1236
  if (!intop->undo_reloc)
1237
    {
1238
      xtisa_errno = xtensa_isa_internal_error;
1239
      strcpy (xtisa_error_msg, "operand missing undo_reloc function");
1240
      return -1;
1241
    }
1242
 
1243
  if ((*intop->undo_reloc) (valp, pc))
1244
    {
1245
      xtisa_errno = xtensa_isa_bad_value;
1246
      sprintf (xtisa_error_msg,
1247
               "undo_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
1248
      return -1;
1249
    }
1250
 
1251
  return 0;
1252
}
1253
 
1254
 
1255
 
1256
/* State Operands.  */
1257
 
1258
 
1259
#define CHECK_STATE_OPERAND(INTISA,OPC,ICLASS,STOP,ERRVAL) \
1260
  do { \
1261
    if ((STOP) < 0 || (STOP) >= (ICLASS)->num_stateOperands) \
1262
      { \
1263
        xtisa_errno = xtensa_isa_bad_operand; \
1264
        sprintf (xtisa_error_msg, "invalid state operand number (%d); " \
1265
                 "opcode \"%s\" has %d state operands", (STOP), \
1266
                 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_stateOperands); \
1267
        return (ERRVAL); \
1268
      } \
1269
  } while (0)
1270
 
1271
 
1272
xtensa_state
1273
xtensa_stateOperand_state (xtensa_isa isa, xtensa_opcode opc, int stOp)
1274
{
1275
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1276
  xtensa_iclass_internal *iclass;
1277
  int iclass_id;
1278
 
1279
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
1280
  iclass_id = intisa->opcodes[opc].iclass_id;
1281
  iclass = &intisa->iclasses[iclass_id];
1282
  CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, XTENSA_UNDEFINED);
1283
  return iclass->stateOperands[stOp].u.state;
1284
}
1285
 
1286
 
1287
char
1288
xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp)
1289
{
1290
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1291
  xtensa_iclass_internal *iclass;
1292
  int iclass_id;
1293
 
1294
  CHECK_OPCODE (intisa, opc, 0);
1295
  iclass_id = intisa->opcodes[opc].iclass_id;
1296
  iclass = &intisa->iclasses[iclass_id];
1297
  CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, 0);
1298
  return iclass->stateOperands[stOp].inout;
1299
}
1300
 
1301
 
1302
 
1303
/* Interface Operands.  */
1304
 
1305
 
1306
#define CHECK_INTERFACE_OPERAND(INTISA,OPC,ICLASS,IFOP,ERRVAL) \
1307
  do { \
1308
    if ((IFOP) < 0 || (IFOP) >= (ICLASS)->num_interfaceOperands) \
1309
      { \
1310
        xtisa_errno = xtensa_isa_bad_operand; \
1311
        sprintf (xtisa_error_msg, "invalid interface operand number (%d); " \
1312
                 "opcode \"%s\" has %d interface operands", (IFOP), \
1313
                 (INTISA)->opcodes[(OPC)].name, \
1314
                 (ICLASS)->num_interfaceOperands); \
1315
        return (ERRVAL); \
1316
      } \
1317
  } while (0)
1318
 
1319
 
1320
xtensa_interface
1321
xtensa_interfaceOperand_interface (xtensa_isa isa, xtensa_opcode opc,
1322
                                   int ifOp)
1323
{
1324
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1325
  xtensa_iclass_internal *iclass;
1326
  int iclass_id;
1327
 
1328
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
1329
  iclass_id = intisa->opcodes[opc].iclass_id;
1330
  iclass = &intisa->iclasses[iclass_id];
1331
  CHECK_INTERFACE_OPERAND (intisa, opc, iclass, ifOp, XTENSA_UNDEFINED);
1332
  return iclass->interfaceOperands[ifOp];
1333
}
1334
 
1335
 
1336
 
1337
/* Register Files.  */
1338
 
1339
 
1340
#define CHECK_REGFILE(INTISA,RF,ERRVAL) \
1341
  do { \
1342
    if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \
1343
      { \
1344
        xtisa_errno = xtensa_isa_bad_regfile; \
1345
        strcpy (xtisa_error_msg, "invalid regfile specifier"); \
1346
        return (ERRVAL); \
1347
      } \
1348
  } while (0)
1349
 
1350
 
1351
xtensa_regfile
1352
xtensa_regfile_lookup (xtensa_isa isa, const char *name)
1353
{
1354
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1355
  int n;
1356
 
1357
  if (!name || !*name)
1358
    {
1359
      xtisa_errno = xtensa_isa_bad_regfile;
1360
      strcpy (xtisa_error_msg, "invalid regfile name");
1361
      return XTENSA_UNDEFINED;
1362
    }
1363
 
1364
  /* The expected number of regfiles is small; use a linear search.  */
1365
  for (n = 0; n < intisa->num_regfiles; n++)
1366
    {
1367
      if (!filename_cmp (intisa->regfiles[n].name, name))
1368
        return n;
1369
    }
1370
 
1371
  xtisa_errno = xtensa_isa_bad_regfile;
1372
  sprintf (xtisa_error_msg, "regfile \"%s\" not recognized", name);
1373
  return XTENSA_UNDEFINED;
1374
}
1375
 
1376
 
1377
xtensa_regfile
1378
xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname)
1379
{
1380
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1381
  int n;
1382
 
1383
  if (!shortname || !*shortname)
1384
    {
1385
      xtisa_errno = xtensa_isa_bad_regfile;
1386
      strcpy (xtisa_error_msg, "invalid regfile shortname");
1387
      return XTENSA_UNDEFINED;
1388
    }
1389
 
1390
  /* The expected number of regfiles is small; use a linear search.  */
1391
  for (n = 0; n < intisa->num_regfiles; n++)
1392
    {
1393
      /* Ignore regfile views since they always have the same shortnames
1394
         as their parents.  */
1395
      if (intisa->regfiles[n].parent != n)
1396
        continue;
1397
      if (!filename_cmp (intisa->regfiles[n].shortname, shortname))
1398
        return n;
1399
    }
1400
 
1401
  xtisa_errno = xtensa_isa_bad_regfile;
1402
  sprintf (xtisa_error_msg, "regfile shortname \"%s\" not recognized",
1403
           shortname);
1404
  return XTENSA_UNDEFINED;
1405
}
1406
 
1407
 
1408
const char *
1409
xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf)
1410
{
1411
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1412
  CHECK_REGFILE (intisa, rf, NULL);
1413
  return intisa->regfiles[rf].name;
1414
}
1415
 
1416
 
1417
const char *
1418
xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf)
1419
{
1420
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1421
  CHECK_REGFILE (intisa, rf, NULL);
1422
  return intisa->regfiles[rf].shortname;
1423
}
1424
 
1425
 
1426
xtensa_regfile
1427
xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf)
1428
{
1429
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1430
  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1431
  return intisa->regfiles[rf].parent;
1432
}
1433
 
1434
 
1435
int
1436
xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf)
1437
{
1438
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1439
  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1440
  return intisa->regfiles[rf].num_bits;
1441
}
1442
 
1443
 
1444
int
1445
xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf)
1446
{
1447
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1448
  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
1449
  return intisa->regfiles[rf].num_entries;
1450
}
1451
 
1452
 
1453
 
1454
/* Processor States.  */
1455
 
1456
 
1457
#define CHECK_STATE(INTISA,ST,ERRVAL) \
1458
  do { \
1459
    if ((ST) < 0 || (ST) >= (INTISA)->num_states) \
1460
      { \
1461
        xtisa_errno = xtensa_isa_bad_state; \
1462
        strcpy (xtisa_error_msg, "invalid state specifier"); \
1463
        return (ERRVAL); \
1464
      } \
1465
  } while (0)
1466
 
1467
 
1468
xtensa_state
1469
xtensa_state_lookup (xtensa_isa isa, const char *name)
1470
{
1471
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1472
  xtensa_lookup_entry entry, *result = 0;
1473
 
1474
  if (!name || !*name)
1475
    {
1476
      xtisa_errno = xtensa_isa_bad_state;
1477
      strcpy (xtisa_error_msg, "invalid state name");
1478
      return XTENSA_UNDEFINED;
1479
    }
1480
 
1481
  if (intisa->num_states != 0)
1482
    {
1483
      entry.key = name;
1484
      result = bsearch (&entry, intisa->state_lookup_table, intisa->num_states,
1485
                        sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
1486
    }
1487
 
1488
  if (!result)
1489
    {
1490
      xtisa_errno = xtensa_isa_bad_state;
1491
      sprintf (xtisa_error_msg, "state \"%s\" not recognized", name);
1492
      return XTENSA_UNDEFINED;
1493
    }
1494
 
1495
  return result->u.state;
1496
}
1497
 
1498
 
1499
const char *
1500
xtensa_state_name (xtensa_isa isa, xtensa_state st)
1501
{
1502
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1503
  CHECK_STATE (intisa, st, NULL);
1504
  return intisa->states[st].name;
1505
}
1506
 
1507
 
1508
int
1509
xtensa_state_num_bits (xtensa_isa isa, xtensa_state st)
1510
{
1511
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1512
  CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1513
  return intisa->states[st].num_bits;
1514
}
1515
 
1516
 
1517
int
1518
xtensa_state_is_exported (xtensa_isa isa, xtensa_state st)
1519
{
1520
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1521
  CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1522
  if ((intisa->states[st].flags & XTENSA_STATE_IS_EXPORTED) != 0)
1523
    return 1;
1524
  return 0;
1525
}
1526
 
1527
 
1528
int
1529
xtensa_state_is_shared_or (xtensa_isa isa, xtensa_state st)
1530
{
1531
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1532
  CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
1533
  if ((intisa->states[st].flags & XTENSA_STATE_IS_SHARED_OR) != 0)
1534
    return 1;
1535
  return 0;
1536
}
1537
 
1538
 
1539
 
1540
/* Sysregs.  */
1541
 
1542
 
1543
#define CHECK_SYSREG(INTISA,SYSREG,ERRVAL) \
1544
  do { \
1545
    if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) \
1546
      { \
1547
        xtisa_errno = xtensa_isa_bad_sysreg; \
1548
        strcpy (xtisa_error_msg, "invalid sysreg specifier"); \
1549
        return (ERRVAL); \
1550
      } \
1551
  } while (0)
1552
 
1553
 
1554
xtensa_sysreg
1555
xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user)
1556
{
1557
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1558
 
1559
  if (is_user != 0)
1560
    is_user = 1;
1561
 
1562
  if (num < 0 || num > intisa->max_sysreg_num[is_user]
1563
      || intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED)
1564
    {
1565
      xtisa_errno = xtensa_isa_bad_sysreg;
1566
      strcpy (xtisa_error_msg, "sysreg not recognized");
1567
      return XTENSA_UNDEFINED;
1568
    }
1569
 
1570
  return intisa->sysreg_table[is_user][num];
1571
}
1572
 
1573
 
1574
xtensa_sysreg
1575
xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name)
1576
{
1577
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1578
  xtensa_lookup_entry entry, *result = 0;
1579
 
1580
  if (!name || !*name)
1581
    {
1582
      xtisa_errno = xtensa_isa_bad_sysreg;
1583
      strcpy (xtisa_error_msg, "invalid sysreg name");
1584
      return XTENSA_UNDEFINED;
1585
    }
1586
 
1587
  if (intisa->num_sysregs != 0)
1588
    {
1589
      entry.key = name;
1590
      result = bsearch (&entry, intisa->sysreg_lookup_table,
1591
                        intisa->num_sysregs, sizeof (xtensa_lookup_entry),
1592
                        xtensa_isa_name_compare);
1593
    }
1594
 
1595
  if (!result)
1596
    {
1597
      xtisa_errno = xtensa_isa_bad_sysreg;
1598
      sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name);
1599
      return XTENSA_UNDEFINED;
1600
    }
1601
 
1602
  return result->u.sysreg;
1603
}
1604
 
1605
 
1606
const char *
1607
xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg)
1608
{
1609
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1610
  CHECK_SYSREG (intisa, sysreg, NULL);
1611
  return intisa->sysregs[sysreg].name;
1612
}
1613
 
1614
 
1615
int
1616
xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg)
1617
{
1618
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1619
  CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
1620
  return intisa->sysregs[sysreg].number;
1621
}
1622
 
1623
 
1624
int
1625
xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg)
1626
{
1627
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1628
  CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
1629
  if (intisa->sysregs[sysreg].is_user)
1630
    return 1;
1631
  return 0;
1632
}
1633
 
1634
 
1635
 
1636
/* Interfaces.  */
1637
 
1638
 
1639
#define CHECK_INTERFACE(INTISA,INTF,ERRVAL) \
1640
  do { \
1641
    if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) \
1642
      { \
1643
        xtisa_errno = xtensa_isa_bad_interface; \
1644
        strcpy (xtisa_error_msg, "invalid interface specifier"); \
1645
        return (ERRVAL); \
1646
      } \
1647
  } while (0)
1648
 
1649
 
1650
xtensa_interface
1651
xtensa_interface_lookup (xtensa_isa isa, const char *ifname)
1652
{
1653
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1654
  xtensa_lookup_entry entry, *result = 0;
1655
 
1656
  if (!ifname || !*ifname)
1657
    {
1658
      xtisa_errno = xtensa_isa_bad_interface;
1659
      strcpy (xtisa_error_msg, "invalid interface name");
1660
      return XTENSA_UNDEFINED;
1661
    }
1662
 
1663
  if (intisa->num_interfaces != 0)
1664
    {
1665
      entry.key = ifname;
1666
      result = bsearch (&entry, intisa->interface_lookup_table,
1667
                        intisa->num_interfaces, sizeof (xtensa_lookup_entry),
1668
                        xtensa_isa_name_compare);
1669
    }
1670
 
1671
  if (!result)
1672
    {
1673
      xtisa_errno = xtensa_isa_bad_interface;
1674
      sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname);
1675
      return XTENSA_UNDEFINED;
1676
    }
1677
 
1678
  return result->u.intf;
1679
}
1680
 
1681
 
1682
const char *
1683
xtensa_interface_name (xtensa_isa isa, xtensa_interface intf)
1684
{
1685
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1686
  CHECK_INTERFACE (intisa, intf, NULL);
1687
  return intisa->interfaces[intf].name;
1688
}
1689
 
1690
 
1691
int
1692
xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf)
1693
{
1694
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1695
  CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1696
  return intisa->interfaces[intf].num_bits;
1697
}
1698
 
1699
 
1700
char
1701
xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf)
1702
{
1703
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1704
  CHECK_INTERFACE (intisa, intf, 0);
1705
  return intisa->interfaces[intf].inout;
1706
}
1707
 
1708
 
1709
int
1710
xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf)
1711
{
1712
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1713
  CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1714
  if ((intisa->interfaces[intf].flags & XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0)
1715
    return 1;
1716
  return 0;
1717
}
1718
 
1719
 
1720
int
1721
xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf)
1722
{
1723
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1724
  CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
1725
  return intisa->interfaces[intf].class_id;
1726
}
1727
 
1728
 
1729
 
1730
/* Functional Units.  */
1731
 
1732
 
1733
#define CHECK_FUNCUNIT(INTISA,FUN,ERRVAL) \
1734
  do { \
1735
    if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) \
1736
      { \
1737
        xtisa_errno = xtensa_isa_bad_funcUnit; \
1738
        strcpy (xtisa_error_msg, "invalid functional unit specifier"); \
1739
        return (ERRVAL); \
1740
      } \
1741
  } while (0)
1742
 
1743
 
1744
xtensa_funcUnit
1745
xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname)
1746
{
1747
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1748
  xtensa_lookup_entry entry, *result = 0;
1749
 
1750
  if (!fname || !*fname)
1751
    {
1752
      xtisa_errno = xtensa_isa_bad_funcUnit;
1753
      strcpy (xtisa_error_msg, "invalid functional unit name");
1754
      return XTENSA_UNDEFINED;
1755
    }
1756
 
1757
  if (intisa->num_funcUnits != 0)
1758
    {
1759
      entry.key = fname;
1760
      result = bsearch (&entry, intisa->funcUnit_lookup_table,
1761
                        intisa->num_funcUnits, sizeof (xtensa_lookup_entry),
1762
                        xtensa_isa_name_compare);
1763
    }
1764
 
1765
  if (!result)
1766
    {
1767
      xtisa_errno = xtensa_isa_bad_funcUnit;
1768
      sprintf (xtisa_error_msg,
1769
               "functional unit \"%s\" not recognized", fname);
1770
      return XTENSA_UNDEFINED;
1771
    }
1772
 
1773
  return result->u.fun;
1774
}
1775
 
1776
 
1777
const char *
1778
xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun)
1779
{
1780
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1781
  CHECK_FUNCUNIT (intisa, fun, NULL);
1782
  return intisa->funcUnits[fun].name;
1783
}
1784
 
1785
 
1786
int
1787
xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun)
1788
{
1789
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1790
  CHECK_FUNCUNIT (intisa, fun, XTENSA_UNDEFINED);
1791
  return intisa->funcUnits[fun].num_copies;
1792
}
1793
 

powered by: WebSVN 2.1.0

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