Coverage Report

Created: 2026-07-25 10:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/bfd/xtensa-isa.c
Line
Count
Source
1
/* Configurable Xtensa ISA support.
2
   Copyright (C) 2003-2026 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
13.8M
{
75
13.8M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
76
13.8M
  return intisa->insnbuf_size;
77
13.8M
}
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
25.7M
{
105
25.7M
  return byte_index / sizeof (xtensa_insnbuf_word);
106
25.7M
}
107
108
109
static inline int
110
byte_to_bit_index (int byte_index)
111
25.7M
{
112
25.7M
  return (byte_index & 0x3) * 8;
113
25.7M
}
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
265
{
131
265
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
132
265
  int insn_size = xtensa_isa_maxlength (isa);
133
265
  int fence_post, start, increment, i, byte_count;
134
265
  xtensa_format fmt;
135
136
265
  if (num_chars == 0)
137
0
    num_chars = insn_size;
138
139
265
  if (intisa->is_big_endian)
140
0
    {
141
0
      start = insn_size - 1;
142
0
      increment = -1;
143
0
    }
144
265
  else
145
265
    {
146
265
      start = 0;
147
265
      increment = 1;
148
265
    }
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
265
  fmt = xtensa_format_decode (isa, insn);
153
265
  if (fmt == XTENSA_UNDEFINED)
154
0
    return XTENSA_UNDEFINED;
155
156
265
  byte_count = xtensa_format_length (isa, fmt);
157
265
  if (byte_count == XTENSA_UNDEFINED)
158
0
    return XTENSA_UNDEFINED;
159
160
265
  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
265
  fence_post = start + (byte_count * increment);
168
169
1.23k
  for (i = start; i != fence_post; i += increment, ++cp)
170
972
    {
171
972
      int word_inx = byte_to_word_index (i);
172
972
      int bit_inx = byte_to_bit_index (i);
173
174
972
      *cp = (insn[word_inx] >> bit_inx) & 0xff;
175
972
    }
176
177
265
  return byte_count;
178
265
}
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.94M
{
191
6.94M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
192
6.94M
  int max_size, insn_size, fence_post, start, increment, i;
193
194
6.94M
  max_size = xtensa_isa_maxlength (isa);
195
196
  /* Decode the instruction length so we know how many bytes to read.  */
197
6.94M
  insn_size = (intisa->length_decode_fn) (cp);
198
6.94M
  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.94M
  if (num_chars == 0 || num_chars > insn_size)
206
5.64M
    num_chars = insn_size;
207
208
6.94M
  if (intisa->is_big_endian)
209
0
    {
210
0
      start = max_size - 1;
211
0
      increment = -1;
212
0
    }
213
6.94M
  else
214
6.94M
    {
215
6.94M
      start = 0;
216
6.94M
      increment = 1;
217
6.94M
    }
218
219
6.94M
  fence_post = start + (num_chars * increment);
220
6.94M
  memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
221
222
32.7M
  for (i = start; i != fence_post; i += increment, ++cp)
223
25.7M
    {
224
25.7M
      int word_inx = byte_to_word_index (i);
225
25.7M
      int bit_inx = byte_to_bit_index (i);
226
227
25.7M
      insn[word_inx] |= (unsigned) (*cp & 0xff) << bit_inx;
228
25.7M
    }
229
6.94M
}
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
20.8M
{
390
20.8M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
391
20.8M
  return intisa->insn_size;
392
20.8M
}
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
50.5M
  do { \
495
50.5M
    if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \
496
50.5M
      { \
497
0
  xtisa_errno = xtensa_isa_bad_format; \
498
0
  strcpy (xtisa_error_msg, "invalid format specifier"); \
499
0
  return (ERRVAL); \
500
0
      } \
501
50.5M
  } while (0)
502
503
504
#define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \
505
38.1M
  do { \
506
38.1M
    if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \
507
38.1M
      { \
508
968
  xtisa_errno = xtensa_isa_bad_slot; \
509
968
  strcpy (xtisa_error_msg, "invalid slot specifier"); \
510
968
  return (ERRVAL); \
511
968
      } \
512
38.1M
  } 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.94M
{
552
6.94M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
553
6.94M
  xtensa_format fmt;
554
555
6.94M
  fmt = (intisa->format_decode_fn) (insn);
556
6.94M
  if (fmt != XTENSA_UNDEFINED)
557
6.22M
    return fmt;
558
559
722k
  xtisa_errno = xtensa_isa_bad_format;
560
722k
  strcpy (xtisa_error_msg, "cannot decode instruction format");
561
722k
  return XTENSA_UNDEFINED;
562
6.94M
}
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
6.21M
{
578
6.21M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
579
6.21M
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
580
6.21M
  return intisa->formats[fmt].length;
581
6.21M
}
582
583
584
int
585
xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
586
6.20M
{
587
6.20M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
588
6.20M
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
589
6.20M
  return intisa->formats[fmt].num_slots;
590
6.20M
}
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
14.0M
{
611
14.0M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
612
14.0M
  int slot_id;
613
614
14.0M
  CHECK_FORMAT (intisa, fmt, -1);
615
14.0M
  CHECK_SLOT (intisa, fmt, slot, -1);
616
617
14.0M
  slot_id = intisa->formats[fmt].slot_id[slot];
618
14.0M
  (*intisa->slots[slot_id].get_fn) (insn, slotbuf);
619
14.0M
  return 0;
620
14.0M
}
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
265
{
627
265
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
628
265
  int slot_id;
629
630
265
  CHECK_FORMAT (intisa, fmt, -1);
631
265
  CHECK_SLOT (intisa, fmt, slot, -1);
632
633
265
  slot_id = intisa->formats[fmt].slot_id[slot];
634
265
  (*intisa->slots[slot_id].set_fn) (insn, slotbuf);
635
265
  return 0;
636
265
}
637
638
639

640
/* Opcode information.  */
641
642
643
#define CHECK_OPCODE(INTISA,OPC,ERRVAL) \
644
103M
  do { \
645
103M
    if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \
646
103M
      { \
647
0
  xtisa_errno = xtensa_isa_bad_opcode; \
648
0
  strcpy (xtisa_error_msg, "invalid opcode specifier"); \
649
0
  return (ERRVAL); \
650
0
      } \
651
103M
  } 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
14.0M
{
690
14.0M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
691
14.0M
  int slot_id;
692
14.0M
  xtensa_opcode opc;
693
694
14.0M
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
695
14.0M
  CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
696
697
14.0M
  slot_id = intisa->formats[fmt].slot_id[slot];
698
699
14.0M
  opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
700
14.0M
  if (opc != XTENSA_UNDEFINED)
701
14.0M
    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
14.0M
}
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
8.26M
{
739
8.26M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
740
8.26M
  CHECK_OPCODE (intisa, opc, NULL);
741
8.26M
  return intisa->opcodes[opc].name;
742
8.26M
}
743
744
745
int
746
xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc)
747
7.03M
{
748
7.03M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
749
7.03M
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
750
7.03M
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0)
751
474k
    return 1;
752
6.55M
  return 0;
753
7.03M
}
754
755
756
int
757
xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc)
758
6.55M
{
759
6.55M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
760
6.55M
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
761
6.55M
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0)
762
136k
    return 1;
763
6.42M
  return 0;
764
6.55M
}
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
6.42M
{
781
6.42M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
782
6.42M
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
783
6.42M
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0)
784
255k
    return 1;
785
6.16M
  return 0;
786
6.42M
}
787
788
789
int
790
xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
791
7.03M
{
792
7.03M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
793
7.03M
  int iclass_id;
794
795
7.03M
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
796
7.03M
  iclass_id = intisa->opcodes[opc].iclass_id;
797
7.03M
  return intisa->iclasses[iclass_id].num_operands;
798
7.03M
}
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
68.2M
  do { \
857
68.2M
    if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \
858
68.2M
      { \
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
68.2M
  } while (0)
866
867
868
static xtensa_operand_internal *
869
get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd)
870
57.9M
{
871
57.9M
  xtensa_iclass_internal *iclass;
872
57.9M
  int iclass_id, operand_id;
873
874
57.9M
  CHECK_OPCODE (intisa, opc, NULL);
875
57.9M
  iclass_id = intisa->opcodes[opc].iclass_id;
876
57.9M
  iclass = &intisa->iclasses[iclass_id];
877
57.9M
  CHECK_OPERAND (intisa, opc, iclass, opnd, NULL);
878
57.9M
  operand_id = iclass->operands[opnd].u.operand_id;
879
57.9M
  return &intisa->operands[operand_id];
880
57.9M
}
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
10.2M
{
898
10.2M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
899
10.2M
  xtensa_iclass_internal *iclass;
900
10.2M
  int iclass_id, operand_id;
901
10.2M
  xtensa_operand_internal *intop;
902
903
10.2M
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
904
10.2M
  iclass_id = intisa->opcodes[opc].iclass_id;
905
10.2M
  iclass = &intisa->iclasses[iclass_id];
906
10.2M
  CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED);
907
908
  /* Special case for "sout" operands.  */
909
10.2M
  if (iclass->operands[opnd].inout == 's')
910
18.9k
    return 0;
911
912
10.2M
  operand_id = iclass->operands[opnd].u.operand_id;
913
10.2M
  intop = &intisa->operands[operand_id];
914
915
10.2M
  if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0)
916
9.99M
    return 1;
917
272k
  return 0;
918
10.2M
}
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.98M
{
948
9.98M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
949
9.98M
  xtensa_operand_internal *intop;
950
9.98M
  int slot_id;
951
9.98M
  xtensa_get_field_fn get_fn;
952
953
9.98M
  intop = get_operand (intisa, opc, opnd);
954
9.98M
  if (!intop) return -1;
955
956
9.98M
  CHECK_FORMAT (intisa, fmt, -1);
957
9.98M
  CHECK_SLOT (intisa, fmt, slot, -1);
958
959
9.98M
  slot_id = intisa->formats[fmt].slot_id[slot];
960
9.98M
  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.98M
  get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
967
9.98M
  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.98M
  *valp = (*get_fn) (slotbuf);
976
9.98M
  return 0;
977
9.98M
}
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
266
{
985
266
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
986
266
  xtensa_operand_internal *intop;
987
266
  int slot_id;
988
266
  xtensa_set_field_fn set_fn;
989
990
266
  intop = get_operand (intisa, opc, opnd);
991
266
  if (!intop) return -1;
992
993
266
  CHECK_FORMAT (intisa, fmt, -1);
994
266
  CHECK_SLOT (intisa, fmt, slot, -1);
995
996
266
  slot_id = intisa->formats[fmt].slot_id[slot];
997
266
  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
266
  set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id];
1004
266
  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
266
  (*set_fn) (slotbuf, val);
1013
266
  return 0;
1014
266
}
1015
1016
1017
int
1018
xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1019
           uint32 *valp)
1020
405
{
1021
405
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1022
405
  xtensa_operand_internal *intop;
1023
405
  uint32 test_val, orig_val;
1024
1025
405
  intop = get_operand (intisa, opc, opnd);
1026
405
  if (!intop)
1027
0
    return -1;
1028
1029
405
  if (!intop->encode)
1030
37
    {
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
37
      static xtensa_insnbuf tmpbuf = 0;
1035
37
      int slot_id;
1036
1037
37
      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
37
      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
37
      for (slot_id = 0; slot_id < intisa->num_slots; slot_id++)
1054
37
  {
1055
37
    xtensa_get_field_fn get_fn =
1056
37
      intisa->slots[slot_id].get_field_fns[intop->field_id];
1057
37
    xtensa_set_field_fn set_fn =
1058
37
      intisa->slots[slot_id].set_field_fns[intop->field_id];
1059
1060
37
    if (get_fn && set_fn)
1061
37
      {
1062
37
        (*set_fn) (tmpbuf, *valp);
1063
37
        return ((*get_fn) (tmpbuf) != *valp);
1064
37
      }
1065
37
  }
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
37
    }
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
368
  orig_val = *valp;
1078
368
  if ((*intop->encode) (valp)
1079
368
      || (test_val = *valp, (*intop->decode) (&test_val))
1080
368
      || test_val != orig_val)
1081
133
    {
1082
133
      xtisa_errno = xtensa_isa_bad_value;
1083
133
      sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp);
1084
133
      return -1;
1085
133
    }
1086
1087
235
  return 0;
1088
368
}
1089
1090
1091
int
1092
xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1093
           uint32 *valp)
1094
9.98M
{
1095
9.98M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1096
9.98M
  xtensa_operand_internal *intop;
1097
1098
9.98M
  intop = get_operand (intisa, opc, opnd);
1099
9.98M
  if (!intop) return -1;
1100
1101
  /* Use identity function for "default" operands.  */
1102
9.98M
  if (!intop->decode)
1103
349k
    return 0;
1104
1105
9.63M
  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.63M
  return 0;
1112
9.63M
}
1113
1114
1115
int
1116
xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
1117
9.98M
{
1118
9.98M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1119
9.98M
  xtensa_operand_internal *intop;
1120
1121
9.98M
  intop = get_operand (intisa, opc, opnd);
1122
9.98M
  if (!intop) return XTENSA_UNDEFINED;
1123
1124
9.98M
  if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
1125
6.65M
    return 1;
1126
3.33M
  return 0;
1127
9.98M
}
1128
1129
1130
xtensa_regfile
1131
xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
1132
6.65M
{
1133
6.65M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1134
6.65M
  xtensa_operand_internal *intop;
1135
1136
6.65M
  intop = get_operand (intisa, opc, opnd);
1137
6.65M
  if (!intop) return XTENSA_UNDEFINED;
1138
1139
6.65M
  return intop->regfile;
1140
6.65M
}
1141
1142
1143
int
1144
xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
1145
6.80M
{
1146
6.80M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1147
6.80M
  xtensa_operand_internal *intop;
1148
1149
6.80M
  intop = get_operand (intisa, opc, opnd);
1150
6.80M
  if (!intop) return XTENSA_UNDEFINED;
1151
1152
6.80M
  return intop->num_regs;
1153
6.80M
}
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
13.3M
{
1174
13.3M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1175
13.3M
  xtensa_operand_internal *intop;
1176
1177
13.3M
  intop = get_operand (intisa, opc, opnd);
1178
13.3M
  if (!intop) return XTENSA_UNDEFINED;
1179
1180
13.3M
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0)
1181
2.47M
    return 1;
1182
10.8M
  return 0;
1183
13.3M
}
1184
1185
1186
int
1187
xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
1188
       uint32 *valp, uint32 pc)
1189
405
{
1190
405
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1191
405
  xtensa_operand_internal *intop;
1192
1193
405
  intop = get_operand (intisa, opc, opnd);
1194
405
  if (!intop) return -1;
1195
1196
405
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1197
240
    return 0;
1198
1199
165
  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
165
  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
165
  return 0;
1215
165
}
1216
1217
1218
int
1219
xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
1220
         uint32 *valp, uint32 pc)
1221
1.23M
{
1222
1.23M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1223
1.23M
  xtensa_operand_internal *intop;
1224
1225
1.23M
  intop = get_operand (intisa, opc, opnd);
1226
1.23M
  if (!intop) return -1;
1227
1228
1.23M
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1229
0
    return 0;
1230
1231
1.23M
  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.23M
  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.23M
  return 0;
1247
1.23M
}
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.80M
  do { \
1337
6.80M
    if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \
1338
6.80M
      { \
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.80M
  } 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.80M
{
1415
6.80M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1416
6.80M
  CHECK_REGFILE (intisa, rf, NULL);
1417
6.80M
  return intisa->regfiles[rf].shortname;
1418
6.80M
}
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