Coverage Report

Created: 2025-06-24 06:45

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