Coverage Report

Created: 2023-08-28 06:26

/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
0
  do { \
48
0
    if ((MEM) == 0) \
49
0
      { \
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
0
  } while (0)
55
56
#define CHECK_ALLOC_FOR_INIT(MEM,ERRVAL,ERRNO_P,ERROR_MSG_P) \
57
0
  do { \
58
0
    if ((MEM) == 0) \
59
0
      { \
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
0
  } while (0)
67
68
69

70
/* Instruction buffers.  */
71
72
int
73
xtensa_insnbuf_size (xtensa_isa isa)
74
0
{
75
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
76
0
  return intisa->insnbuf_size;
77
0
}
78
79
80
xtensa_insnbuf
81
xtensa_insnbuf_alloc (xtensa_isa isa)
82
0
{
83
0
  xtensa_insnbuf result = (xtensa_insnbuf)
84
0
    malloc (xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
85
0
  CHECK_ALLOC (result, 0);
86
0
  return result;
87
0
}
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
0
{
105
0
  return byte_index / sizeof (xtensa_insnbuf_word);
106
0
}
107
108
109
static inline int
110
byte_to_bit_index (int byte_index)
111
0
{
112
0
  return (byte_index & 0x3) * 8;
113
0
}
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
0
{
191
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
192
0
  int max_size, insn_size, fence_post, start, increment, i;
193
194
0
  max_size = xtensa_isa_maxlength (isa);
195
196
  /* Decode the instruction length so we know how many bytes to read.  */
197
0
  insn_size = (intisa->length_decode_fn) (cp);
198
0
  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
0
  if (num_chars == 0 || num_chars > insn_size)
206
0
    num_chars = insn_size;
207
208
0
  if (intisa->is_big_endian)
209
0
    {
210
0
      start = max_size - 1;
211
0
      increment = -1;
212
0
    }
213
0
  else
214
0
    {
215
0
      start = 0;
216
0
      increment = 1;
217
0
    }
218
219
0
  fence_post = start + (num_chars * increment);
220
0
  memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
221
222
0
  for (i = start; i != fence_post; i += increment, ++cp)
223
0
    {
224
0
      int word_inx = byte_to_word_index (i);
225
0
      int bit_inx = byte_to_bit_index (i);
226
227
0
      insn[word_inx] |= (unsigned) (*cp & 0xff) << bit_inx;
228
0
    }
229
0
}
230
231

232
/* ISA information.  */
233
234
extern xtensa_isa_internal xtensa_modules;
235
236
static xtensa_isa_internal *xtensa_get_modules (void)
237
0
{
238
0
  static xtensa_isa_internal *modules;
239
240
0
  if (!modules)
241
0
    modules = (xtensa_isa_internal *) xtensa_load_config ("xtensa_modules",
242
0
                &xtensa_modules,
243
0
                NULL);
244
0
  return modules;
245
0
}
246
247
xtensa_isa
248
xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p)
249
0
{
250
0
  xtensa_isa_internal *isa = xtensa_get_modules ();
251
0
  int n, is_user;
252
253
  /* Set up the opcode name lookup table.  */
254
0
  isa->opname_lookup_table =
255
0
    bfd_malloc (isa->num_opcodes * sizeof (xtensa_lookup_entry));
256
0
  CHECK_ALLOC_FOR_INIT (isa->opname_lookup_table, NULL, errno_p, error_msg_p);
257
0
  for (n = 0; n < isa->num_opcodes; n++)
258
0
    {
259
0
      isa->opname_lookup_table[n].key = isa->opcodes[n].name;
260
0
      isa->opname_lookup_table[n].u.opcode = n;
261
0
    }
262
0
  qsort (isa->opname_lookup_table, isa->num_opcodes,
263
0
   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
264
265
  /* Set up the state name lookup table.  */
266
0
  isa->state_lookup_table =
267
0
    bfd_malloc (isa->num_states * sizeof (xtensa_lookup_entry));
268
0
  CHECK_ALLOC_FOR_INIT (isa->state_lookup_table, NULL, errno_p, error_msg_p);
269
0
  for (n = 0; n < isa->num_states; n++)
270
0
    {
271
0
      isa->state_lookup_table[n].key = isa->states[n].name;
272
0
      isa->state_lookup_table[n].u.state = n;
273
0
    }
274
0
  qsort (isa->state_lookup_table, isa->num_states,
275
0
   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
276
277
  /* Set up the sysreg name lookup table.  */
278
0
  isa->sysreg_lookup_table =
279
0
    bfd_malloc (isa->num_sysregs * sizeof (xtensa_lookup_entry));
280
0
  CHECK_ALLOC_FOR_INIT (isa->sysreg_lookup_table, NULL, errno_p, error_msg_p);
281
0
  for (n = 0; n < isa->num_sysregs; n++)
282
0
    {
283
0
      isa->sysreg_lookup_table[n].key = isa->sysregs[n].name;
284
0
      isa->sysreg_lookup_table[n].u.sysreg = n;
285
0
    }
286
0
  qsort (isa->sysreg_lookup_table, isa->num_sysregs,
287
0
   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
288
289
  /* Set up the user & system sysreg number tables.  */
290
0
  for (is_user = 0; is_user < 2; is_user++)
291
0
    {
292
0
      isa->sysreg_table[is_user] =
293
0
  bfd_malloc ((isa->max_sysreg_num[is_user] + 1)
294
0
        * sizeof (xtensa_sysreg));
295
0
      CHECK_ALLOC_FOR_INIT (isa->sysreg_table[is_user], NULL,
296
0
          errno_p, error_msg_p);
297
298
0
      for (n = 0; n <= isa->max_sysreg_num[is_user]; n++)
299
0
  isa->sysreg_table[is_user][n] = XTENSA_UNDEFINED;
300
0
    }
301
0
  for (n = 0; n < isa->num_sysregs; n++)
302
0
    {
303
0
      xtensa_sysreg_internal *sreg = &isa->sysregs[n];
304
0
      is_user = sreg->is_user;
305
306
0
      if (sreg->number >= 0)
307
0
  isa->sysreg_table[is_user][sreg->number] = n;
308
0
    }
309
310
  /* Set up the interface lookup table.  */
311
0
  isa->interface_lookup_table =
312
0
    bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry));
313
0
  CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p,
314
0
      error_msg_p);
315
0
  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
0
  qsort (isa->interface_lookup_table, isa->num_interfaces,
321
0
   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
322
323
  /* Set up the funcUnit lookup table.  */
324
0
  isa->funcUnit_lookup_table =
325
0
    bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry));
326
0
  CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p,
327
0
      error_msg_p);
328
0
  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
0
  qsort (isa->funcUnit_lookup_table, isa->num_funcUnits,
334
0
   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
335
336
0
  isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
337
0
           sizeof (xtensa_insnbuf_word));
338
339
0
  return (xtensa_isa) isa;
340
0
}
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
0
{
380
0
  xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1;
381
0
  xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2;
382
383
0
  return strcasecmp (e1->key, e2->key);
384
0
}
385
386
387
int
388
xtensa_isa_maxlength (xtensa_isa isa)
389
0
{
390
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
391
0
  return intisa->insn_size;
392
0
}
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
0
  do { \
495
0
    if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \
496
0
      { \
497
0
  xtisa_errno = xtensa_isa_bad_format; \
498
0
  strcpy (xtisa_error_msg, "invalid format specifier"); \
499
0
  return (ERRVAL); \
500
0
      } \
501
0
  } while (0)
502
503
504
#define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \
505
0
  do { \
506
0
    if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \
507
0
      { \
508
0
  xtisa_errno = xtensa_isa_bad_slot; \
509
0
  strcpy (xtisa_error_msg, "invalid slot specifier"); \
510
0
  return (ERRVAL); \
511
0
      } \
512
0
  } 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
0
{
552
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
553
0
  xtensa_format fmt;
554
555
0
  fmt = (intisa->format_decode_fn) (insn);
556
0
  if (fmt != XTENSA_UNDEFINED)
557
0
    return fmt;
558
559
0
  xtisa_errno = xtensa_isa_bad_format;
560
0
  strcpy (xtisa_error_msg, "cannot decode instruction format");
561
0
  return XTENSA_UNDEFINED;
562
0
}
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
0
{
578
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
579
0
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
580
0
  return intisa->formats[fmt].length;
581
0
}
582
583
584
int
585
xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
586
0
{
587
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
588
0
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
589
0
  return intisa->formats[fmt].num_slots;
590
0
}
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
0
{
611
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
612
0
  int slot_id;
613
614
0
  CHECK_FORMAT (intisa, fmt, -1);
615
0
  CHECK_SLOT (intisa, fmt, slot, -1);
616
617
0
  slot_id = intisa->formats[fmt].slot_id[slot];
618
0
  (*intisa->slots[slot_id].get_fn) (insn, slotbuf);
619
0
  return 0;
620
0
}
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
0
  do { \
645
0
    if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \
646
0
      { \
647
0
  xtisa_errno = xtensa_isa_bad_opcode; \
648
0
  strcpy (xtisa_error_msg, "invalid opcode specifier"); \
649
0
  return (ERRVAL); \
650
0
      } \
651
0
  } 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
0
{
690
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
691
0
  int slot_id;
692
0
  xtensa_opcode opc;
693
694
0
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
695
0
  CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
696
697
0
  slot_id = intisa->formats[fmt].slot_id[slot];
698
699
0
  opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
700
0
  if (opc != XTENSA_UNDEFINED)
701
0
    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
0
}
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
0
{
739
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
740
0
  CHECK_OPCODE (intisa, opc, NULL);
741
0
  return intisa->opcodes[opc].name;
742
0
}
743
744
745
int
746
xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc)
747
0
{
748
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
749
0
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
750
0
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0)
751
0
    return 1;
752
0
  return 0;
753
0
}
754
755
756
int
757
xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc)
758
0
{
759
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
760
0
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
761
0
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0)
762
0
    return 1;
763
0
  return 0;
764
0
}
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
0
{
781
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
782
0
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
783
0
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0)
784
0
    return 1;
785
0
  return 0;
786
0
}
787
788
789
int
790
xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
791
0
{
792
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
793
0
  int iclass_id;
794
795
0
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
796
0
  iclass_id = intisa->opcodes[opc].iclass_id;
797
0
  return intisa->iclasses[iclass_id].num_operands;
798
0
}
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
0
  do { \
857
0
    if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \
858
0
      { \
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
0
  } while (0)
866
867
868
static xtensa_operand_internal *
869
get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd)
870
0
{
871
0
  xtensa_iclass_internal *iclass;
872
0
  int iclass_id, operand_id;
873
874
0
  CHECK_OPCODE (intisa, opc, NULL);
875
0
  iclass_id = intisa->opcodes[opc].iclass_id;
876
0
  iclass = &intisa->iclasses[iclass_id];
877
0
  CHECK_OPERAND (intisa, opc, iclass, opnd, NULL);
878
0
  operand_id = iclass->operands[opnd].u.operand_id;
879
0
  return &intisa->operands[operand_id];
880
0
}
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
0
{
898
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
899
0
  xtensa_iclass_internal *iclass;
900
0
  int iclass_id, operand_id;
901
0
  xtensa_operand_internal *intop;
902
903
0
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
904
0
  iclass_id = intisa->opcodes[opc].iclass_id;
905
0
  iclass = &intisa->iclasses[iclass_id];
906
0
  CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED);
907
908
  /* Special case for "sout" operands.  */
909
0
  if (iclass->operands[opnd].inout == 's')
910
0
    return 0;
911
912
0
  operand_id = iclass->operands[opnd].u.operand_id;
913
0
  intop = &intisa->operands[operand_id];
914
915
0
  if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0)
916
0
    return 1;
917
0
  return 0;
918
0
}
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
0
{
948
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
949
0
  xtensa_operand_internal *intop;
950
0
  int slot_id;
951
0
  xtensa_get_field_fn get_fn;
952
953
0
  intop = get_operand (intisa, opc, opnd);
954
0
  if (!intop) return -1;
955
956
0
  CHECK_FORMAT (intisa, fmt, -1);
957
0
  CHECK_SLOT (intisa, fmt, slot, -1);
958
959
0
  slot_id = intisa->formats[fmt].slot_id[slot];
960
0
  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
0
  get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
967
0
  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
0
  *valp = (*get_fn) (slotbuf);
976
0
  return 0;
977
0
}
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
0
{
1095
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1096
0
  xtensa_operand_internal *intop;
1097
1098
0
  intop = get_operand (intisa, opc, opnd);
1099
0
  if (!intop) return -1;
1100
1101
  /* Use identity function for "default" operands.  */
1102
0
  if (!intop->decode)
1103
0
    return 0;
1104
1105
0
  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
0
  return 0;
1112
0
}
1113
1114
1115
int
1116
xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
1117
0
{
1118
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1119
0
  xtensa_operand_internal *intop;
1120
1121
0
  intop = get_operand (intisa, opc, opnd);
1122
0
  if (!intop) return XTENSA_UNDEFINED;
1123
1124
0
  if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
1125
0
    return 1;
1126
0
  return 0;
1127
0
}
1128
1129
1130
xtensa_regfile
1131
xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
1132
0
{
1133
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1134
0
  xtensa_operand_internal *intop;
1135
1136
0
  intop = get_operand (intisa, opc, opnd);
1137
0
  if (!intop) return XTENSA_UNDEFINED;
1138
1139
0
  return intop->regfile;
1140
0
}
1141
1142
1143
int
1144
xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
1145
0
{
1146
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1147
0
  xtensa_operand_internal *intop;
1148
1149
0
  intop = get_operand (intisa, opc, opnd);
1150
0
  if (!intop) return XTENSA_UNDEFINED;
1151
1152
0
  return intop->num_regs;
1153
0
}
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
0
{
1174
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1175
0
  xtensa_operand_internal *intop;
1176
1177
0
  intop = get_operand (intisa, opc, opnd);
1178
0
  if (!intop) return XTENSA_UNDEFINED;
1179
1180
0
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0)
1181
0
    return 1;
1182
0
  return 0;
1183
0
}
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
0
{
1222
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1223
0
  xtensa_operand_internal *intop;
1224
1225
0
  intop = get_operand (intisa, opc, opnd);
1226
0
  if (!intop) return -1;
1227
1228
0
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
1229
0
    return 0;
1230
1231
0
  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
0
  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
0
  return 0;
1247
0
}
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
0
  do { \
1337
0
    if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \
1338
0
      { \
1339
0
  xtisa_errno = xtensa_isa_bad_regfile; \
1340
0
  strcpy (xtisa_error_msg, "invalid regfile specifier"); \
1341
0
  return (ERRVAL); \
1342
0
      } \
1343
0
  } 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
0
{
1415
0
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
1416
0
  CHECK_REGFILE (intisa, rf, NULL);
1417
0
  return intisa->regfiles[rf].shortname;
1418
0
}
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