Coverage Report

Created: 2023-08-28 06:31

/src/binutils-gdb/bfd/xtensa-isa.c
Line
Count
Source (jump to first uncovered line)
1
/* Configurable Xtensa ISA support.
2
   Copyright (C) 2003-2023 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
4
  do { \
48
4
    if ((MEM) == 0) \
49
4
      { \
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
4
  } while (0)
55
56
#define CHECK_ALLOC_FOR_INIT(MEM,ERRVAL,ERRNO_P,ERROR_MSG_P) \
57
14
  do { \
58
14
    if ((MEM) == 0) \
59
14
      { \
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
14
  } while (0)
67
68
69

70
/* Instruction buffers.  */
71
72
int
73
xtensa_insnbuf_size (xtensa_isa isa)
74
11.5M
{
75
11.5M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
76
11.5M
  return intisa->insnbuf_size;
77
11.5M
}
78
79
80
xtensa_insnbuf
81
xtensa_insnbuf_alloc (xtensa_isa isa)
82
4
{
83
4
  xtensa_insnbuf result = (xtensa_insnbuf)
84
4
    malloc (xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
85
4
  CHECK_ALLOC (result, 0);
86
4
  return result;
87
4
}
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
20.7M
{
105
20.7M
  return byte_index / sizeof (xtensa_insnbuf_word);
106
20.7M
}
107
108
109
static inline int
110
byte_to_bit_index (int byte_index)
111
20.7M
{
112
20.7M
  return (byte_index & 0x3) * 8;
113
20.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
0
{
131
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
132
0
  int insn_size = xtensa_isa_maxlength (isa);
133
0
  int fence_post, start, increment, i, byte_count;
134
0
  xtensa_format fmt;
135
136
0
  if (num_chars == 0)
137
0
    num_chars = insn_size;
138
139
0
  if (intisa->is_big_endian)
140
0
    {
141
0
      start = insn_size - 1;
142
0
      increment = -1;
143
0
    }
144
0
  else
145
0
    {
146
0
      start = 0;
147
0
      increment = 1;
148
0
    }
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
0
  fmt = xtensa_format_decode (isa, insn);
153
0
  if (fmt == XTENSA_UNDEFINED)
154
0
    return XTENSA_UNDEFINED;
155
156
0
  byte_count = xtensa_format_length (isa, fmt);
157
0
  if (byte_count == XTENSA_UNDEFINED)
158
0
    return XTENSA_UNDEFINED;
159
160
0
  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
0
  fence_post = start + (byte_count * increment);
168
169
0
  for (i = start; i != fence_post; i += increment, ++cp)
170
0
    {
171
0
      int word_inx = byte_to_word_index (i);
172
0
      int bit_inx = byte_to_bit_index (i);
173
174
0
      *cp = (insn[word_inx] >> bit_inx) & 0xff;
175
0
    }
176
177
0
  return byte_count;
178
0
}
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
5.76M
{
191
5.76M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
192
5.76M
  int max_size, insn_size, fence_post, start, increment, i;
193
194
5.76M
  max_size = xtensa_isa_maxlength (isa);
195
196
  /* Decode the instruction length so we know how many bytes to read.  */
197
5.76M
  insn_size = (intisa->length_decode_fn) (cp);
198
5.76M
  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
5.76M
  if (num_chars == 0 || num_chars > insn_size)
206
4.80M
    num_chars = insn_size;
207
208
5.76M
  if (intisa->is_big_endian)
209
0
    {
210
0
      start = max_size - 1;
211
0
      increment = -1;
212
0
    }
213
5.76M
  else
214
5.76M
    {
215
5.76M
      start = 0;
216
5.76M
      increment = 1;
217
5.76M
    }
218
219
5.76M
  fence_post = start + (num_chars * increment);
220
5.76M
  memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
221
222
26.4M
  for (i = start; i != fence_post; i += increment, ++cp)
223
20.7M
    {
224
20.7M
      int word_inx = byte_to_word_index (i);
225
20.7M
      int bit_inx = byte_to_bit_index (i);
226
227
20.7M
      insn[word_inx] |= (unsigned) (*cp & 0xff) << bit_inx;
228
20.7M
    }
229
5.76M
}
230
231

232
/* ISA information.  */
233
234
extern xtensa_isa_internal xtensa_modules;
235
236
static xtensa_isa_internal *xtensa_get_modules (void)
237
2
{
238
2
  static xtensa_isa_internal *modules;
239
240
2
  if (!modules)
241
2
    modules = (xtensa_isa_internal *) xtensa_load_config ("xtensa_modules",
242
2
                &xtensa_modules,
243
2
                NULL);
244
2
  return modules;
245
2
}
246
247
xtensa_isa
248
xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p)
249
2
{
250
2
  xtensa_isa_internal *isa = xtensa_get_modules ();
251
2
  int n, is_user;
252
253
  /* Set up the opcode name lookup table.  */
254
2
  isa->opname_lookup_table =
255
2
    bfd_malloc (isa->num_opcodes * sizeof (xtensa_lookup_entry));
256
2
  CHECK_ALLOC_FOR_INIT (isa->opname_lookup_table, NULL, errno_p, error_msg_p);
257
1.06k
  for (n = 0; n < isa->num_opcodes; n++)
258
1.06k
    {
259
1.06k
      isa->opname_lookup_table[n].key = isa->opcodes[n].name;
260
1.06k
      isa->opname_lookup_table[n].u.opcode = n;
261
1.06k
    }
262
2
  qsort (isa->opname_lookup_table, isa->num_opcodes,
263
2
   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
264
265
  /* Set up the state name lookup table.  */
266
2
  isa->state_lookup_table =
267
2
    bfd_malloc (isa->num_states * sizeof (xtensa_lookup_entry));
268
2
  CHECK_ALLOC_FOR_INIT (isa->state_lookup_table, NULL, errno_p, error_msg_p);
269
180
  for (n = 0; n < isa->num_states; n++)
270
178
    {
271
178
      isa->state_lookup_table[n].key = isa->states[n].name;
272
178
      isa->state_lookup_table[n].u.state = n;
273
178
    }
274
2
  qsort (isa->state_lookup_table, isa->num_states,
275
2
   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
276
277
  /* Set up the sysreg name lookup table.  */
278
2
  isa->sysreg_lookup_table =
279
2
    bfd_malloc (isa->num_sysregs * sizeof (xtensa_lookup_entry));
280
2
  CHECK_ALLOC_FOR_INIT (isa->sysreg_lookup_table, NULL, errno_p, error_msg_p);
281
150
  for (n = 0; n < isa->num_sysregs; n++)
282
148
    {
283
148
      isa->sysreg_lookup_table[n].key = isa->sysregs[n].name;
284
148
      isa->sysreg_lookup_table[n].u.sysreg = n;
285
148
    }
286
2
  qsort (isa->sysreg_lookup_table, isa->num_sysregs,
287
2
   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
288
289
  /* Set up the user & system sysreg number tables.  */
290
6
  for (is_user = 0; is_user < 2; is_user++)
291
4
    {
292
4
      isa->sysreg_table[is_user] =
293
4
  bfd_malloc ((isa->max_sysreg_num[is_user] + 1)
294
4
        * sizeof (xtensa_sysreg));
295
4
      CHECK_ALLOC_FOR_INIT (isa->sysreg_table[is_user], NULL,
296
4
          errno_p, error_msg_p);
297
298
968
      for (n = 0; n <= isa->max_sysreg_num[is_user]; n++)
299
964
  isa->sysreg_table[is_user][n] = XTENSA_UNDEFINED;
300
4
    }
301
150
  for (n = 0; n < isa->num_sysregs; n++)
302
148
    {
303
148
      xtensa_sysreg_internal *sreg = &isa->sysregs[n];
304
148
      is_user = sreg->is_user;
305
306
148
      if (sreg->number >= 0)
307
148
  isa->sysreg_table[is_user][sreg->number] = n;
308
148
    }
309
310
  /* Set up the interface lookup table.  */
311
2
  isa->interface_lookup_table =
312
2
    bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry));
313
2
  CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p,
314
2
      error_msg_p);
315
2
  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
2
  qsort (isa->interface_lookup_table, isa->num_interfaces,
321
2
   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
322
323
  /* Set up the funcUnit lookup table.  */
324
2
  isa->funcUnit_lookup_table =
325
2
    bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry));
326
2
  CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p,
327
2
      error_msg_p);
328
2
  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
2
  qsort (isa->funcUnit_lookup_table, isa->num_funcUnits,
334
2
   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
335
336
2
  isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
337
2
           sizeof (xtensa_insnbuf_word));
338
339
2
  return (xtensa_isa) isa;
340
2
}
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
9.44k
{
380
9.44k
  xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1;
381
9.44k
  xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2;
382
383
9.44k
  return strcasecmp (e1->key, e2->key);
384
9.44k
}
385
386
387
int
388
xtensa_isa_maxlength (xtensa_isa isa)
389
17.3M
{
390
17.3M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
391
17.3M
  return intisa->insn_size;
392
17.3M
}
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
43.3M
  do { \
495
43.3M
    if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \
496
43.3M
      { \
497
0
  xtisa_errno = xtensa_isa_bad_format; \
498
0
  strcpy (xtisa_error_msg, "invalid format specifier"); \
499
0
  return (ERRVAL); \
500
0
      } \
501
43.3M
  } while (0)
502
503
504
#define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \
505
32.7M
  do { \
506
32.7M
    if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \
507
32.7M
      { \
508
0
  xtisa_errno = xtensa_isa_bad_slot; \
509
0
  strcpy (xtisa_error_msg, "invalid slot specifier"); \
510
0
  return (ERRVAL); \
511
0
      } \
512
32.7M
  } 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
5.76M
{
552
5.76M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
553
5.76M
  xtensa_format fmt;
554
555
5.76M
  fmt = (intisa->format_decode_fn) (insn);
556
5.76M
  if (fmt != XTENSA_UNDEFINED)
557
5.28M
    return fmt;
558
559
482k
  xtisa_errno = xtensa_isa_bad_format;
560
482k
  strcpy (xtisa_error_msg, "cannot decode instruction format");
561
482k
  return XTENSA_UNDEFINED;
562
5.76M
}
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.28M
{
578
5.28M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
579
5.28M
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
580
5.28M
  return intisa->formats[fmt].length;
581
5.28M
}
582
583
584
int
585
xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
586
5.28M
{
587
5.28M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
588
5.28M
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
589
5.28M
  return intisa->formats[fmt].num_slots;
590
5.28M
}
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
11.9M
{
611
11.9M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
612
11.9M
  int slot_id;
613
614
11.9M
  CHECK_FORMAT (intisa, fmt, -1);
615
11.9M
  CHECK_SLOT (intisa, fmt, slot, -1);
616
617
11.9M
  slot_id = intisa->formats[fmt].slot_id[slot];
618
11.9M
  (*intisa->slots[slot_id].get_fn) (insn, slotbuf);
619
11.9M
  return 0;
620
11.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
0
{
627
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
628
0
  int slot_id;
629
630
0
  CHECK_FORMAT (intisa, fmt, -1);
631
0
  CHECK_SLOT (intisa, fmt, slot, -1);
632
633
0
  slot_id = intisa->formats[fmt].slot_id[slot];
634
0
  (*intisa->slots[slot_id].set_fn) (insn, slotbuf);
635
0
  return 0;
636
0
}
637
638
639

640
/* Opcode information.  */
641
642
643
#define CHECK_OPCODE(INTISA,OPC,ERRVAL) \
644
90.5M
  do { \
645
90.5M
    if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \
646
90.5M
      { \
647
0
  xtisa_errno = xtensa_isa_bad_opcode; \
648
0
  strcpy (xtisa_error_msg, "invalid opcode specifier"); \
649
0
  return (ERRVAL); \
650
0
      } \
651
90.5M
  } while (0)
652
653
654
xtensa_opcode
655
xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
656
0
{
657
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
658
0
  xtensa_lookup_entry entry, *result = 0;
659
660
0
  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
0
  if (intisa->num_opcodes != 0)
668
0
    {
669
0
      entry.key = opname;
670
0
      result = bsearch (&entry, intisa->opname_lookup_table,
671
0
      intisa->num_opcodes, sizeof (xtensa_lookup_entry),
672
0
      xtensa_isa_name_compare);
673
0
    }
674
675
0
  if (!result)
676
0
    {
677
0
      xtisa_errno = xtensa_isa_bad_opcode;
678
0
      sprintf (xtisa_error_msg, "opcode \"%s\" not recognized", opname);
679
0
      return XTENSA_UNDEFINED;
680
0
    }
681
682
0
  return result->u.opcode;
683
0
}
684
685
686
xtensa_opcode
687
xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot,
688
          const xtensa_insnbuf slotbuf)
689
11.9M
{
690
11.9M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
691
11.9M
  int slot_id;
692
11.9M
  xtensa_opcode opc;
693
694
11.9M
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
695
11.9M
  CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
696
697
11.9M
  slot_id = intisa->formats[fmt].slot_id[slot];
698
699
11.9M
  opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
700
11.9M
  if (opc != XTENSA_UNDEFINED)
701
11.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
11.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.12M
{
739
7.12M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
740
7.12M
  CHECK_OPCODE (intisa, opc, NULL);
741
7.12M
  return intisa->opcodes[opc].name;
742
7.12M
}
743
744
745
int
746
xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc)
747
5.97M
{
748
5.97M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
749
5.97M
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
750
5.97M
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0)
751
446k
    return 1;
752
5.52M
  return 0;
753
5.97M
}
754
755
756
int
757
xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc)
758
5.52M
{
759
5.52M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
760
5.52M
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
761
5.52M
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0)
762
122k
    return 1;
763
5.40M
  return 0;
764
5.52M
}
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.40M
{
781
5.40M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
782
5.40M
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
783
5.40M
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0)
784
276k
    return 1;
785
5.12M
  return 0;
786
5.40M
}
787
788
789
int
790
xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
791
5.97M
{
792
5.97M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
793
5.97M
  int iclass_id;
794
795
5.97M
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
796
5.97M
  iclass_id = intisa->opcodes[opc].iclass_id;
797
5.97M
  return intisa->iclasses[iclass_id].num_operands;
798
5.97M
}
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
60.5M
  do { \
857
60.5M
    if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \
858
60.5M
      { \
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
60.5M
  } while (0)
866
867
868
static xtensa_operand_internal *
869
get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd)
870
51.3M
{
871
51.3M
  xtensa_iclass_internal *iclass;
872
51.3M
  int iclass_id, operand_id;
873
874
51.3M
  CHECK_OPCODE (intisa, opc, NULL);
875
51.3M
  iclass_id = intisa->opcodes[opc].iclass_id;
876
51.3M
  iclass = &intisa->iclasses[iclass_id];
877
51.3M
  CHECK_OPERAND (intisa, opc, iclass, opnd, NULL);
878
51.3M
  operand_id = iclass->operands[opnd].u.operand_id;
879
51.3M
  return &intisa->operands[operand_id];
880
51.3M
}
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.16M
{
898
9.16M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
899
9.16M
  xtensa_iclass_internal *iclass;
900
9.16M
  int iclass_id, operand_id;
901
9.16M
  xtensa_operand_internal *intop;
902
903
9.16M
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
904
9.16M
  iclass_id = intisa->opcodes[opc].iclass_id;
905
9.16M
  iclass = &intisa->iclasses[iclass_id];
906
9.16M
  CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED);
907
908
  /* Special case for "sout" operands.  */
909
9.16M
  if (iclass->operands[opnd].inout == 's')
910
12.5k
    return 0;
911
912
9.15M
  operand_id = iclass->operands[opnd].u.operand_id;
913
9.15M
  intop = &intisa->operands[operand_id];
914
915
9.15M
  if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0)
916
8.86M
    return 1;
917
288k
  return 0;
918
9.15M
}
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
8.86M
{
948
8.86M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
949
8.86M
  xtensa_operand_internal *intop;
950
8.86M
  int slot_id;
951
8.86M
  xtensa_get_field_fn get_fn;
952
953
8.86M
  intop = get_operand (intisa, opc, opnd);
954
8.86M
  if (!intop) return -1;
955
956
8.86M
  CHECK_FORMAT (intisa, fmt, -1);
957
8.86M
  CHECK_SLOT (intisa, fmt, slot, -1);
958
959
8.86M
  slot_id = intisa->formats[fmt].slot_id[slot];
960
8.86M
  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
8.86M
  get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
967
8.86M
  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
8.86M
  *valp = (*get_fn) (slotbuf);
976
8.86M
  return 0;
977
8.86M
}
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
0
{
985
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
986
0
  xtensa_operand_internal *intop;
987
0
  int slot_id;
988
0
  xtensa_set_field_fn set_fn;
989
990
0
  intop = get_operand (intisa, opc, opnd);
991
0
  if (!intop) return -1;
992
993
0
  CHECK_FORMAT (intisa, fmt, -1);
994
0
  CHECK_SLOT (intisa, fmt, slot, -1);
995
996
0
  slot_id = intisa->formats[fmt].slot_id[slot];
997
0
  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
0
  set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id];
1004
0
  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
0
  (*set_fn) (slotbuf, val);
1013
0
  return 0;
1014
0
}
1015
1016
1017
int
1018
xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1019
           uint32 *valp)
1020
0
{
1021
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1022
0
  xtensa_operand_internal *intop;
1023
0
  uint32 test_val, orig_val;
1024
1025
0
  intop = get_operand (intisa, opc, opnd);
1026
0
  if (!intop)
1027
0
    return -1;
1028
1029
0
  if (!intop->encode)
1030
0
    {
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
0
      static xtensa_insnbuf tmpbuf = 0;
1035
0
      int slot_id;
1036
1037
0
      if (!tmpbuf)
1038
0
  {
1039
0
    tmpbuf = xtensa_insnbuf_alloc (isa);
1040
0
    CHECK_ALLOC (tmpbuf, -1);
1041
0
  }
1042
1043
      /* A default operand is always associated with a field,
1044
   but check just to be sure....  */
1045
0
      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
0
      for (slot_id = 0; slot_id < intisa->num_slots; slot_id++)
1054
0
  {
1055
0
    xtensa_get_field_fn get_fn =
1056
0
      intisa->slots[slot_id].get_field_fns[intop->field_id];
1057
0
    xtensa_set_field_fn set_fn =
1058
0
      intisa->slots[slot_id].set_field_fns[intop->field_id];
1059
1060
0
    if (get_fn && set_fn)
1061
0
      {
1062
0
        (*set_fn) (tmpbuf, *valp);
1063
0
        return ((*get_fn) (tmpbuf) != *valp);
1064
0
      }
1065
0
  }
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
0
    }
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
0
  orig_val = *valp;
1078
0
  if ((*intop->encode) (valp)
1079
0
      || (test_val = *valp, (*intop->decode) (&test_val))
1080
0
      || test_val != orig_val)
1081
0
    {
1082
0
      xtisa_errno = xtensa_isa_bad_value;
1083
0
      sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp);
1084
0
      return -1;
1085
0
    }
1086
1087
0
  return 0;
1088
0
}
1089
1090
1091
int
1092
xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
1093
           uint32 *valp)
1094
8.86M
{
1095
8.86M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1096
8.86M
  xtensa_operand_internal *intop;
1097
1098
8.86M
  intop = get_operand (intisa, opc, opnd);
1099
8.86M
  if (!intop) return -1;
1100
1101
  /* Use identity function for "default" operands.  */
1102
8.86M
  if (!intop->decode)
1103
271k
    return 0;
1104
1105
8.59M
  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
8.59M
  return 0;
1112
8.59M
}
1113
1114
1115
int
1116
xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
1117
8.86M
{
1118
8.86M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1119
8.86M
  xtensa_operand_internal *intop;
1120
1121
8.86M
  intop = get_operand (intisa, opc, opnd);
1122
8.86M
  if (!intop) return XTENSA_UNDEFINED;
1123
1124
8.86M
  if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
1125
5.80M
    return 1;
1126
3.05M
  return 0;
1127
8.86M
}
1128
1129
1130
xtensa_regfile
1131
xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
1132
5.80M
{
1133
5.80M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1134
5.80M
  xtensa_operand_internal *intop;
1135
1136
5.80M
  intop = get_operand (intisa, opc, opnd);
1137
5.80M
  if (!intop) return XTENSA_UNDEFINED;
1138
1139
5.80M
  return intop->regfile;
1140
5.80M
}
1141
1142
1143
int
1144
xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
1145
5.91M
{
1146
5.91M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1147
5.91M
  xtensa_operand_internal *intop;
1148
1149
5.91M
  intop = get_operand (intisa, opc, opnd);
1150
5.91M
  if (!intop) return XTENSA_UNDEFINED;
1151
1152
5.91M
  return intop->num_regs;
1153
5.91M
}
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
11.9M
{
1174
11.9M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1175
11.9M
  xtensa_operand_internal *intop;
1176
1177
11.9M
  intop = get_operand (intisa, opc, opnd);
1178
11.9M
  if (!intop) return XTENSA_UNDEFINED;
1179
1180
11.9M
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0)
1181
2.31M
    return 1;
1182
9.61M
  return 0;
1183
11.9M
}
1184
1185
1186
int
1187
xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
1188
       uint32 *valp, uint32 pc)
1189
0
{
1190
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1191
0
  xtensa_operand_internal *intop;
1192
1193
0
  intop = get_operand (intisa, opc, opnd);
1194
0
  if (!intop) return -1;
1195
1196
0
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1197
0
    return 0;
1198
1199
0
  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
0
  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
0
  return 0;
1215
0
}
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
5.91M
  do { \
1337
5.91M
    if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \
1338
5.91M
      { \
1339
0
  xtisa_errno = xtensa_isa_bad_regfile; \
1340
0
  strcpy (xtisa_error_msg, "invalid regfile specifier"); \
1341
0
  return (ERRVAL); \
1342
0
      } \
1343
5.91M
  } 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
5.91M
{
1415
5.91M
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1416
5.91M
  CHECK_REGFILE (intisa, rf, NULL);
1417
5.91M
  return intisa->regfiles[rf].shortname;
1418
5.91M
}
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