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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [opcodes/] [frv-asm.c] - Blame information for rev 53

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

Line No. Rev Author Line
1 18 khays
/* Assembler interface for targets using CGEN. -*- C -*-
2
   CGEN: Cpu tools GENerator
3
 
4
   THIS FILE IS MACHINE GENERATED WITH CGEN.
5
   - the resultant file is machine generated, cgen-asm.in isn't
6
 
7
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2007, 2008, 2010
8
   Free Software Foundation, Inc.
9
 
10
   This file is part of libopcodes.
11
 
12
   This library is free software; you can redistribute it and/or modify
13
   it under the terms of the GNU General Public License as published by
14
   the Free Software Foundation; either version 3, or (at your option)
15
   any later version.
16
 
17
   It is distributed in the hope that it will be useful, but WITHOUT
18
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
20
   License for more details.
21
 
22
   You should have received a copy of the GNU General Public License
23
   along with this program; if not, write to the Free Software Foundation, Inc.,
24
   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
25
 
26
 
27
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
28
   Keep that in mind.  */
29
 
30
#include "sysdep.h"
31
#include <stdio.h>
32
#include "ansidecl.h"
33
#include "bfd.h"
34
#include "symcat.h"
35
#include "frv-desc.h"
36
#include "frv-opc.h"
37
#include "opintl.h"
38
#include "xregex.h"
39
#include "libiberty.h"
40
#include "safe-ctype.h"
41
 
42
#undef  min
43
#define min(a,b) ((a) < (b) ? (a) : (b))
44
#undef  max
45
#define max(a,b) ((a) > (b) ? (a) : (b))
46
 
47
static const char * parse_insn_normal
48
  (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
49
 
50
/* -- assembler routines inserted here.  */
51
 
52
/* -- asm.c */
53
inline static const char *
54
parse_symbolic_address (CGEN_CPU_DESC cd,
55
                        const char **strp,
56
                        int opindex,
57
                        int opinfo,
58
                        enum cgen_parse_operand_result *resultp,
59
                        bfd_vma *valuep)
60
{
61
  enum cgen_parse_operand_result result_type;
62
  const char *errmsg = (* cd->parse_operand_fn)
63
    (cd, CGEN_PARSE_OPERAND_SYMBOLIC, strp, opindex, opinfo,
64
     &result_type, valuep);
65
 
66
  if (errmsg == NULL
67
      && result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED)
68
    return "symbolic expression required";
69
 
70
  if (resultp)
71
    *resultp = result_type;
72
 
73
  return errmsg;
74
}
75
 
76
static const char *
77
parse_ldd_annotation (CGEN_CPU_DESC cd,
78
                      const char **strp,
79
                      int opindex,
80
                      unsigned long *valuep)
81
{
82
  const char *errmsg;
83
  enum cgen_parse_operand_result result_type;
84
  bfd_vma value;
85
 
86
  if (**strp == '#' || **strp == '%')
87
    {
88
      if (strncasecmp (*strp + 1, "tlsdesc(", 8) == 0)
89
        {
90
          *strp += 9;
91
          errmsg = parse_symbolic_address (cd, strp, opindex,
92
                                           BFD_RELOC_FRV_TLSDESC_RELAX,
93
                                           &result_type, &value);
94
          if (**strp != ')')
95
            return "missing ')'";
96
          if (valuep)
97
            *valuep = value;
98
          ++*strp;
99
          if (errmsg)
100
            return errmsg;
101
        }
102
    }
103
 
104
  while (**strp == ' ' || **strp == '\t')
105
    ++*strp;
106
 
107
  if (**strp != '@')
108
    return "missing `@'";
109
 
110
  ++*strp;
111
 
112
  return NULL;
113
}
114
 
115
static const char *
116
parse_call_annotation (CGEN_CPU_DESC cd,
117
                       const char **strp,
118
                       int opindex,
119
                       unsigned long *valuep)
120
{
121
  const char *errmsg;
122
  enum cgen_parse_operand_result result_type;
123
  bfd_vma value;
124
 
125
  if (**strp == '#' || **strp == '%')
126
    {
127
      if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
128
        {
129
          *strp += 11;
130
          errmsg = parse_symbolic_address (cd, strp, opindex,
131
                                           BFD_RELOC_FRV_GETTLSOFF_RELAX,
132
                                           &result_type, &value);
133
          if (**strp != ')')
134
            return "missing ')'";
135
          if (valuep)
136
            *valuep = value;
137
          ++*strp;
138
          if (errmsg)
139
            return errmsg;
140
        }
141
    }
142
 
143
  while (**strp == ' ' || **strp == '\t')
144
    ++*strp;
145
 
146
  if (**strp != '@')
147
    return "missing `@'";
148
 
149
  ++*strp;
150
 
151
  return NULL;
152
}
153
 
154
static const char *
155
parse_ld_annotation (CGEN_CPU_DESC cd,
156
                     const char **strp,
157
                     int opindex,
158
                     unsigned long *valuep)
159
{
160
  const char *errmsg;
161
  enum cgen_parse_operand_result result_type;
162
  bfd_vma value;
163
 
164
  if (**strp == '#' || **strp == '%')
165
    {
166
      if (strncasecmp (*strp + 1, "tlsoff(", 7) == 0)
167
        {
168
          *strp += 8;
169
          errmsg = parse_symbolic_address (cd, strp, opindex,
170
                                           BFD_RELOC_FRV_TLSOFF_RELAX,
171
                                           &result_type, &value);
172
          if (**strp != ')')
173
            return "missing ')'";
174
          if (valuep)
175
            *valuep = value;
176
          ++*strp;
177
          if (errmsg)
178
            return errmsg;
179
        }
180
    }
181
 
182
  while (**strp == ' ' || **strp == '\t')
183
    ++*strp;
184
 
185
  if (**strp != '@')
186
    return "missing `@'";
187
 
188
  ++*strp;
189
 
190
  return NULL;
191
}
192
 
193
static const char *
194
parse_ulo16 (CGEN_CPU_DESC cd,
195
             const char **strp,
196
             int opindex,
197
             unsigned long *valuep)
198
{
199
  const char *errmsg;
200
  enum cgen_parse_operand_result result_type;
201
  bfd_vma value;
202
 
203
  if (**strp == '#' || **strp == '%')
204
    {
205
      if (strncasecmp (*strp + 1, "lo(", 3) == 0)
206
        {
207
          *strp += 4;
208
          errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
209
                                       & result_type, & value);
210
          if (**strp != ')')
211
            return "missing `)'";
212
          ++*strp;
213
          if (errmsg == NULL
214
              && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
215
            value &= 0xffff;
216
          *valuep = value;
217
          return errmsg;
218
        }
219
      if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
220
        {
221
          *strp += 9;
222
          errmsg = parse_symbolic_address (cd, strp, opindex,
223
                                           BFD_RELOC_FRV_GPRELLO,
224
                                           & result_type, & value);
225
          if (**strp != ')')
226
            return "missing ')'";
227
          ++*strp;
228
          *valuep = value;
229
          return errmsg;
230
        }
231
      else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
232
        {
233
          *strp += 7;
234
          errmsg = parse_symbolic_address (cd, strp, opindex,
235
                                           BFD_RELOC_FRV_GOTLO,
236
                                           & result_type, & value);
237
          if (**strp != ')')
238
            return "missing ')'";
239
          ++*strp;
240
          *valuep = value;
241
          return errmsg;
242
        }
243
      else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
244
        {
245
          *strp += 15;
246
          errmsg = parse_symbolic_address (cd, strp, opindex,
247
                                           BFD_RELOC_FRV_FUNCDESC_GOTLO,
248
                                           & result_type, & value);
249
          if (**strp != ')')
250
            return "missing ')'";
251
          ++*strp;
252
          *valuep = value;
253
          return errmsg;
254
        }
255
      else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
256
        {
257
          *strp += 10;
258
          errmsg = parse_symbolic_address (cd, strp, opindex,
259
                                           BFD_RELOC_FRV_GOTOFFLO,
260
                                           & result_type, & value);
261
          if (**strp != ')')
262
            return "missing ')'";
263
          ++*strp;
264
          *valuep = value;
265
          return errmsg;
266
        }
267
      else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
268
        {
269
          *strp += 18;
270
          errmsg = parse_symbolic_address (cd, strp, opindex,
271
                                           BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
272
                                           & result_type, & value);
273
          if (**strp != ')')
274
            return "missing ')'";
275
          ++*strp;
276
          *valuep = value;
277
          return errmsg;
278
        }
279
      else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
280
        {
281
          *strp += 14;
282
          errmsg = parse_symbolic_address (cd, strp, opindex,
283
                                           BFD_RELOC_FRV_GOTTLSDESCLO,
284
                                           & result_type, & value);
285
          if (**strp != ')')
286
            return "missing ')'";
287
          ++*strp;
288
          *valuep = value;
289
          return errmsg;
290
        }
291
      else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
292
        {
293
          *strp += 11;
294
          errmsg = parse_symbolic_address (cd, strp, opindex,
295
                                           BFD_RELOC_FRV_TLSMOFFLO,
296
                                           & result_type, & value);
297
          if (**strp != ')')
298
            return "missing ')'";
299
          ++*strp;
300
          *valuep = value;
301
          return errmsg;
302
        }
303
      else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
304
        {
305
          *strp += 13;
306
          errmsg = parse_symbolic_address (cd, strp, opindex,
307
                                           BFD_RELOC_FRV_GOTTLSOFFLO,
308
                                           & result_type, & value);
309
          if (**strp != ')')
310
            return "missing ')'";
311
          ++*strp;
312
          *valuep = value;
313
          return errmsg;
314
        }
315
    }
316
  return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
317
}
318
 
319
static const char *
320
parse_uslo16 (CGEN_CPU_DESC cd,
321
              const char **strp,
322
              int opindex,
323
              signed long *valuep)
324
{
325
  const char *errmsg;
326
  enum cgen_parse_operand_result result_type;
327
  bfd_vma value;
328
 
329
  if (**strp == '#' || **strp == '%')
330
    {
331
      if (strncasecmp (*strp + 1, "lo(", 3) == 0)
332
        {
333
          *strp += 4;
334
          errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
335
                                       & result_type, & value);
336
          if (**strp != ')')
337
            return "missing `)'";
338
          ++*strp;
339
          if (errmsg == NULL
340
              && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
341
            value &= 0xffff;
342
          *valuep = value;
343
          return errmsg;
344
        }
345
      else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
346
        {
347
          *strp += 9;
348
          errmsg = parse_symbolic_address (cd, strp, opindex,
349
                                           BFD_RELOC_FRV_GPRELLO,
350
                                           & result_type, & value);
351
          if (**strp != ')')
352
            return "missing ')'";
353
          ++*strp;
354
          *valuep = value;
355
          return errmsg;
356
        }
357
      else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
358
        {
359
          *strp += 7;
360
          errmsg = parse_symbolic_address (cd, strp, opindex,
361
                                           BFD_RELOC_FRV_GOTLO,
362
                                           & result_type, & value);
363
          if (**strp != ')')
364
            return "missing ')'";
365
          ++*strp;
366
          *valuep = value;
367
          return errmsg;
368
        }
369
      else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
370
        {
371
          *strp += 15;
372
          errmsg = parse_symbolic_address (cd, strp, opindex,
373
                                           BFD_RELOC_FRV_FUNCDESC_GOTLO,
374
                                           & result_type, & value);
375
          if (**strp != ')')
376
            return "missing ')'";
377
          ++*strp;
378
          *valuep = value;
379
          return errmsg;
380
        }
381
      else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
382
        {
383
          *strp += 10;
384
          errmsg = parse_symbolic_address (cd, strp, opindex,
385
                                           BFD_RELOC_FRV_GOTOFFLO,
386
                                           & result_type, & value);
387
          if (**strp != ')')
388
            return "missing ')'";
389
          ++*strp;
390
          *valuep = value;
391
          return errmsg;
392
        }
393
      else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
394
        {
395
          *strp += 18;
396
          errmsg = parse_symbolic_address (cd, strp, opindex,
397
                                           BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
398
                                           & result_type, & value);
399
          if (**strp != ')')
400
            return "missing ')'";
401
          ++*strp;
402
          *valuep = value;
403
          return errmsg;
404
        }
405
      else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
406
        {
407
          *strp += 14;
408
          errmsg = parse_symbolic_address (cd, strp, opindex,
409
                                           BFD_RELOC_FRV_GOTTLSDESCLO,
410
                                           & result_type, & value);
411
          if (**strp != ')')
412
            return "missing ')'";
413
          ++*strp;
414
          *valuep = value;
415
          return errmsg;
416
        }
417
      else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
418
        {
419
          *strp += 11;
420
          errmsg = parse_symbolic_address (cd, strp, opindex,
421
                                           BFD_RELOC_FRV_TLSMOFFLO,
422
                                           & result_type, & value);
423
          if (**strp != ')')
424
            return "missing ')'";
425
          ++*strp;
426
          *valuep = value;
427
          return errmsg;
428
        }
429
      else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
430
        {
431
          *strp += 13;
432
          errmsg = parse_symbolic_address (cd, strp, opindex,
433
                                           BFD_RELOC_FRV_GOTTLSOFFLO,
434
                                           & result_type, & value);
435
          if (**strp != ')')
436
            return "missing ')'";
437
          ++*strp;
438
          *valuep = value;
439
          return errmsg;
440
        }
441
    }
442
  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
443
}
444
 
445
static const char *
446
parse_uhi16 (CGEN_CPU_DESC cd,
447
             const char **strp,
448
             int opindex,
449
             unsigned long *valuep)
450
{
451
  const char *errmsg;
452
  enum cgen_parse_operand_result result_type;
453
  bfd_vma value;
454
 
455
  if (**strp == '#' || **strp == '%')
456
    {
457
      if (strncasecmp (*strp + 1, "hi(", 3) == 0)
458
        {
459
          *strp += 4;
460
          errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
461
                                       & result_type, & value);
462
          if (**strp != ')')
463
            return "missing `)'";
464
          ++*strp;
465
          if (errmsg == NULL
466
              && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
467
            {
468
              /* If bfd_vma is wider than 32 bits, but we have a sign-
469
                 or zero-extension, truncate it.  */
470
              if (value >= - ((bfd_vma)1 << 31)
471
                  || value <= ((bfd_vma)1 << 31) - (bfd_vma)1)
472
                value &= (((bfd_vma)1 << 16) << 16) - 1;
473
              value >>= 16;
474
            }
475
          *valuep = value;
476
          return errmsg;
477
        }
478
      else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
479
        {
480
          *strp += 9;
481
          errmsg = parse_symbolic_address (cd, strp, opindex,
482
                                           BFD_RELOC_FRV_GPRELHI,
483
                                           & result_type, & value);
484
          if (**strp != ')')
485
            return "missing ')'";
486
          ++*strp;
487
          *valuep = value;
488
          return errmsg;
489
        }
490
      else if (strncasecmp (*strp + 1, "gothi(", 6) == 0)
491
        {
492
          *strp += 7;
493
          errmsg = parse_symbolic_address (cd, strp, opindex,
494
                                           BFD_RELOC_FRV_GOTHI,
495
                                           & result_type, & value);
496
          if (**strp != ')')
497
            return "missing ')'";
498
          ++*strp;
499
          *valuep = value;
500
          return errmsg;
501
        }
502
      else if (strncasecmp (*strp + 1, "gotfuncdeschi(", 14) == 0)
503
        {
504
          *strp += 15;
505
          errmsg = parse_symbolic_address (cd, strp, opindex,
506
                                           BFD_RELOC_FRV_FUNCDESC_GOTHI,
507
                                           & result_type, & value);
508
          if (**strp != ')')
509
            return "missing ')'";
510
          ++*strp;
511
          *valuep = value;
512
          return errmsg;
513
        }
514
      else if (strncasecmp (*strp + 1, "gotoffhi(", 9) == 0)
515
        {
516
          *strp += 10;
517
          errmsg = parse_symbolic_address (cd, strp, opindex,
518
                                           BFD_RELOC_FRV_GOTOFFHI,
519
                                           & result_type, & value);
520
          if (**strp != ')')
521
            return "missing ')'";
522
          ++*strp;
523
          *valuep = value;
524
          return errmsg;
525
        }
526
      else if (strncasecmp (*strp + 1, "gotofffuncdeschi(", 17) == 0)
527
        {
528
          *strp += 18;
529
          errmsg = parse_symbolic_address (cd, strp, opindex,
530
                                           BFD_RELOC_FRV_FUNCDESC_GOTOFFHI,
531
                                           & result_type, & value);
532
          if (**strp != ')')
533
            return "missing ')'";
534
          ++*strp;
535
          *valuep = value;
536
          return errmsg;
537
        }
538
      else if (strncasecmp (*strp + 1, "gottlsdeschi(", 13) == 0)
539
        {
540
          *strp += 14;
541
          errmsg = parse_symbolic_address (cd, strp, opindex,
542
                                           BFD_RELOC_FRV_GOTTLSDESCHI,
543
                                           &result_type, &value);
544
          if (**strp != ')')
545
            return "missing ')'";
546
          ++*strp;
547
          *valuep = value;
548
          return errmsg;
549
        }
550
      else if (strncasecmp (*strp + 1, "tlsmoffhi(", 10) == 0)
551
        {
552
          *strp += 11;
553
          errmsg = parse_symbolic_address (cd, strp, opindex,
554
                                           BFD_RELOC_FRV_TLSMOFFHI,
555
                                           & result_type, & value);
556
          if (**strp != ')')
557
            return "missing ')'";
558
          ++*strp;
559
          *valuep = value;
560
          return errmsg;
561
        }
562
      else if (strncasecmp (*strp + 1, "gottlsoffhi(", 12) == 0)
563
        {
564
          *strp += 13;
565
          errmsg = parse_symbolic_address (cd, strp, opindex,
566
                                           BFD_RELOC_FRV_GOTTLSOFFHI,
567
                                           & result_type, & value);
568
          if (**strp != ')')
569
            return "missing ')'";
570
          ++*strp;
571
          *valuep = value;
572
          return errmsg;
573
        }
574
    }
575
  return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
576
}
577
 
578
static long
579
parse_register_number (const char **strp)
580
{
581
  int regno;
582
 
583
  if (**strp < '0' || **strp > '9')
584
    return -1; /* error */
585
 
586
  regno = **strp - '0';
587
  for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
588
    regno = regno * 10 + (**strp - '0');
589
 
590
  return regno;
591
}
592
 
593
static const char *
594
parse_spr (CGEN_CPU_DESC cd,
595
           const char **strp,
596
           CGEN_KEYWORD * table,
597
           long *valuep)
598
{
599
  const char *save_strp;
600
  long regno;
601
 
602
  /* Check for spr index notation.  */
603
  if (strncasecmp (*strp, "spr[", 4) == 0)
604
    {
605
      *strp += 4;
606
      regno = parse_register_number (strp);
607
      if (**strp != ']')
608
        return _("missing `]'");
609
      ++*strp;
610
      if (! spr_valid (regno))
611
        return _("Special purpose register number is out of range");
612
      *valuep = regno;
613
      return NULL;
614
    }
615
 
616
  save_strp = *strp;
617
  regno = parse_register_number (strp);
618
  if (regno != -1)
619
    {
620
      if (! spr_valid (regno))
621
        return _("Special purpose register number is out of range");
622
      *valuep = regno;
623
      return NULL;
624
    }
625
 
626
  *strp = save_strp;
627
  return cgen_parse_keyword (cd, strp, table, valuep);
628
}
629
 
630
static const char *
631
parse_d12 (CGEN_CPU_DESC cd,
632
           const char **strp,
633
           int opindex,
634
           long *valuep)
635
{
636
  const char *errmsg;
637
  enum cgen_parse_operand_result result_type;
638
  bfd_vma value;
639
 
640
  /* Check for small data reference.  */
641
  if (**strp == '#' || **strp == '%')
642
    {
643
      if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
644
        {
645
          *strp += 9;
646
          errmsg = parse_symbolic_address (cd, strp, opindex,
647
                                           BFD_RELOC_FRV_GPREL12,
648
                                           & result_type, & value);
649
          if (**strp != ')')
650
            return "missing `)'";
651
          ++*strp;
652
          *valuep = value;
653
          return errmsg;
654
        }
655
      else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
656
        {
657
          *strp += 7;
658
          errmsg = parse_symbolic_address (cd, strp, opindex,
659
                                           BFD_RELOC_FRV_GOT12,
660
                                           & result_type, & value);
661
          if (**strp != ')')
662
            return "missing ')'";
663
          ++*strp;
664
          *valuep = value;
665
          return errmsg;
666
        }
667
      else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
668
        {
669
          *strp += 15;
670
          errmsg = parse_symbolic_address (cd, strp, opindex,
671
                                           BFD_RELOC_FRV_FUNCDESC_GOT12,
672
                                           & result_type, & value);
673
          if (**strp != ')')
674
            return "missing ')'";
675
          ++*strp;
676
          *valuep = value;
677
          return errmsg;
678
        }
679
      else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
680
        {
681
          *strp += 10;
682
          errmsg = parse_symbolic_address (cd, strp, opindex,
683
                                           BFD_RELOC_FRV_GOTOFF12,
684
                                           & result_type, & value);
685
          if (**strp != ')')
686
            return "missing ')'";
687
          ++*strp;
688
          *valuep = value;
689
          return errmsg;
690
        }
691
      else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
692
        {
693
          *strp += 18;
694
          errmsg = parse_symbolic_address (cd, strp, opindex,
695
                                           BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
696
                                           & result_type, & value);
697
          if (**strp != ')')
698
            return "missing ')'";
699
          ++*strp;
700
          *valuep = value;
701
          return errmsg;
702
        }
703
      else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
704
        {
705
          *strp += 14;
706
          errmsg = parse_symbolic_address (cd, strp, opindex,
707
                                           BFD_RELOC_FRV_GOTTLSDESC12,
708
                                           & result_type, & value);
709
          if (**strp != ')')
710
            return "missing ')'";
711
          ++*strp;
712
          *valuep = value;
713
          return errmsg;
714
        }
715
      else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
716
        {
717
          *strp += 11;
718
          errmsg = parse_symbolic_address (cd, strp, opindex,
719
                                           BFD_RELOC_FRV_TLSMOFF12,
720
                                           & result_type, & value);
721
          if (**strp != ')')
722
            return "missing ')'";
723
          ++*strp;
724
          *valuep = value;
725
          return errmsg;
726
        }
727
      else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
728
        {
729
          *strp += 13;
730
          errmsg = parse_symbolic_address (cd, strp, opindex,
731
                                           BFD_RELOC_FRV_GOTTLSOFF12,
732
                                           & result_type, & value);
733
          if (**strp != ')')
734
            return "missing ')'";
735
          ++*strp;
736
          *valuep = value;
737
          return errmsg;
738
        }
739
    }
740
  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
741
}
742
 
743
static const char *
744
parse_s12 (CGEN_CPU_DESC cd,
745
           const char **strp,
746
           int opindex,
747
           long *valuep)
748
{
749
  const char *errmsg;
750
  enum cgen_parse_operand_result result_type;
751
  bfd_vma value;
752
 
753
  /* Check for small data reference.  */
754
  if (**strp == '#' || **strp == '%')
755
    {
756
      if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
757
        {
758
          *strp += 9;
759
          errmsg = parse_symbolic_address (cd, strp, opindex,
760
                                           BFD_RELOC_FRV_GPREL12,
761
                                           & result_type, & value);
762
          if (**strp != ')')
763
            return "missing `)'";
764
          ++*strp;
765
          *valuep = value;
766
          return errmsg;
767
        }
768
      else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
769
        {
770
          *strp += 7;
771
          errmsg = parse_symbolic_address (cd, strp, opindex,
772
                                           BFD_RELOC_FRV_GOT12,
773
                                           & result_type, & value);
774
          if (**strp != ')')
775
            return "missing ')'";
776
          ++*strp;
777
          *valuep = value;
778
          return errmsg;
779
        }
780
      else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
781
        {
782
          *strp += 15;
783
          errmsg = parse_symbolic_address (cd, strp, opindex,
784
                                           BFD_RELOC_FRV_FUNCDESC_GOT12,
785
                                           & result_type, & value);
786
          if (**strp != ')')
787
            return "missing ')'";
788
          ++*strp;
789
          *valuep = value;
790
          return errmsg;
791
        }
792
      else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
793
        {
794
          *strp += 10;
795
          errmsg = parse_symbolic_address (cd, strp, opindex,
796
                                           BFD_RELOC_FRV_GOTOFF12,
797
                                           & result_type, & value);
798
          if (**strp != ')')
799
            return "missing ')'";
800
          ++*strp;
801
          *valuep = value;
802
          return errmsg;
803
        }
804
      else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
805
        {
806
          *strp += 18;
807
          errmsg = parse_symbolic_address (cd, strp, opindex,
808
                                           BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
809
                                           & result_type, & value);
810
          if (**strp != ')')
811
            return "missing ')'";
812
          ++*strp;
813
          *valuep = value;
814
          return errmsg;
815
        }
816
      else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
817
        {
818
          *strp += 14;
819
          errmsg = parse_symbolic_address (cd, strp, opindex,
820
                                           BFD_RELOC_FRV_GOTTLSDESC12,
821
                                           & result_type, & value);
822
          if (**strp != ')')
823
            return "missing ')'";
824
          ++*strp;
825
          *valuep = value;
826
          return errmsg;
827
        }
828
      else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
829
        {
830
          *strp += 11;
831
          errmsg = parse_symbolic_address (cd, strp, opindex,
832
                                           BFD_RELOC_FRV_TLSMOFF12,
833
                                           & result_type, & value);
834
          if (**strp != ')')
835
            return "missing ')'";
836
          ++*strp;
837
          *valuep = value;
838
          return errmsg;
839
        }
840
      else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
841
        {
842
          *strp += 13;
843
          errmsg = parse_symbolic_address (cd, strp, opindex,
844
                                           BFD_RELOC_FRV_GOTTLSOFF12,
845
                                           & result_type, & value);
846
          if (**strp != ')')
847
            return "missing ')'";
848
          ++*strp;
849
          *valuep = value;
850
          return errmsg;
851
        }
852
    }
853
 
854
  if (**strp == '#')
855
    ++*strp;
856
  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
857
}
858
 
859
static const char *
860
parse_u12 (CGEN_CPU_DESC cd,
861
           const char **strp,
862
           int opindex,
863
           long *valuep)
864
{
865
  const char *errmsg;
866
  enum cgen_parse_operand_result result_type;
867
  bfd_vma value;
868
 
869
  /* Check for small data reference.  */
870
  if ((**strp == '#' || **strp == '%')
871
      && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
872
    {
873
      *strp += 9;
874
      errmsg = parse_symbolic_address (cd, strp, opindex,
875
                                       BFD_RELOC_FRV_GPRELU12,
876
                                       & result_type, & value);
877
      if (**strp != ')')
878
        return "missing `)'";
879
      ++*strp;
880
      *valuep = value;
881
      return errmsg;
882
    }
883
  else
884
    {
885
      if (**strp == '#')
886
        ++*strp;
887
      return cgen_parse_signed_integer (cd, strp, opindex, valuep);
888
    }
889
}
890
 
891
static const char *
892
parse_A (CGEN_CPU_DESC cd,
893
         const char **strp,
894
         int opindex,
895
         unsigned long *valuep,
896
         unsigned long A)
897
{
898
  const char *errmsg;
899
 
900
  if (**strp == '#')
901
    ++*strp;
902
 
903
  errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
904
  if (errmsg)
905
    return errmsg;
906
 
907
  if (*valuep != A)
908
    return _("Value of A operand must be 0 or 1");
909
 
910
  return NULL;
911
}
912
 
913
static const char *
914
parse_A0 (CGEN_CPU_DESC cd,
915
          const char **strp,
916
          int opindex,
917
          unsigned long *valuep)
918
{
919
  return parse_A (cd, strp, opindex, valuep, 0);
920
}
921
 
922
static const char *
923
parse_A1 (CGEN_CPU_DESC cd,
924
          const char **strp,
925
          int opindex,
926
          unsigned long *valuep)
927
{
928
  return parse_A (cd, strp, opindex, valuep, 1);
929
}
930
 
931
static const char *
932
parse_even_register (CGEN_CPU_DESC  cd,
933
                     const char **  strP,
934
                     CGEN_KEYWORD * tableP,
935
                     long *         valueP)
936
{
937
  const char * errmsg;
938
  const char * saved_star_strP = * strP;
939
 
940
  errmsg = cgen_parse_keyword (cd, strP, tableP, valueP);
941
 
942
  if (errmsg == NULL && ((* valueP) & 1))
943
    {
944
      errmsg = _("register number must be even");
945
      * strP = saved_star_strP;
946
    }
947
 
948
  return errmsg;
949
}
950
 
951
static const char *
952
parse_call_label (CGEN_CPU_DESC cd,
953
                  const char **strp,
954
                  int opindex,
955
                  int opinfo,
956
                  enum cgen_parse_operand_result *resultp,
957
                  bfd_vma *valuep)
958
{
959
  const char *errmsg;
960
  bfd_vma value;
961
 
962
  /* Check for small data reference.  */
963
  if (opinfo == 0 && (**strp == '#' || **strp == '%'))
964
    {
965
      if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
966
        {
967
          *strp += 11;
968
          errmsg = parse_symbolic_address (cd, strp, opindex,
969
                                           BFD_RELOC_FRV_GETTLSOFF,
970
                                           resultp, &value);
971
          if (**strp != ')')
972
            return _("missing `)'");
973
          ++*strp;
974
          *valuep = value;
975
          return errmsg;
976
        }
977
    }
978
 
979
  return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
980
}
981
 
982
/* -- */
983
 
984
const char * frv_cgen_parse_operand
985
  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
986
 
987
/* Main entry point for operand parsing.
988
 
989
   This function is basically just a big switch statement.  Earlier versions
990
   used tables to look up the function to use, but
991
   - if the table contains both assembler and disassembler functions then
992
     the disassembler contains much of the assembler and vice-versa,
993
   - there's a lot of inlining possibilities as things grow,
994
   - using a switch statement avoids the function call overhead.
995
 
996
   This function could be moved into `parse_insn_normal', but keeping it
997
   separate makes clear the interface between `parse_insn_normal' and each of
998
   the handlers.  */
999
 
1000
const char *
1001
frv_cgen_parse_operand (CGEN_CPU_DESC cd,
1002
                           int opindex,
1003
                           const char ** strp,
1004
                           CGEN_FIELDS * fields)
1005
{
1006
  const char * errmsg = NULL;
1007
  /* Used by scalar operands that still need to be parsed.  */
1008
  long junk ATTRIBUTE_UNUSED;
1009
 
1010
  switch (opindex)
1011
    {
1012
    case FRV_OPERAND_A0 :
1013
      errmsg = parse_A0 (cd, strp, FRV_OPERAND_A0, (unsigned long *) (& fields->f_A));
1014
      break;
1015
    case FRV_OPERAND_A1 :
1016
      errmsg = parse_A1 (cd, strp, FRV_OPERAND_A1, (unsigned long *) (& fields->f_A));
1017
      break;
1018
    case FRV_OPERAND_ACC40SI :
1019
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Si);
1020
      break;
1021
    case FRV_OPERAND_ACC40SK :
1022
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Sk);
1023
      break;
1024
    case FRV_OPERAND_ACC40UI :
1025
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Ui);
1026
      break;
1027
    case FRV_OPERAND_ACC40UK :
1028
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Uk);
1029
      break;
1030
    case FRV_OPERAND_ACCGI :
1031
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGi);
1032
      break;
1033
    case FRV_OPERAND_ACCGK :
1034
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGk);
1035
      break;
1036
    case FRV_OPERAND_CCI :
1037
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CCi);
1038
      break;
1039
    case FRV_OPERAND_CPRDOUBLEK :
1040
      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
1041
      break;
1042
    case FRV_OPERAND_CPRI :
1043
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRi);
1044
      break;
1045
    case FRV_OPERAND_CPRJ :
1046
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRj);
1047
      break;
1048
    case FRV_OPERAND_CPRK :
1049
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
1050
      break;
1051
    case FRV_OPERAND_CRI :
1052
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRi);
1053
      break;
1054
    case FRV_OPERAND_CRJ :
1055
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj);
1056
      break;
1057
    case FRV_OPERAND_CRJ_FLOAT :
1058
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_float);
1059
      break;
1060
    case FRV_OPERAND_CRJ_INT :
1061
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_int);
1062
      break;
1063
    case FRV_OPERAND_CRK :
1064
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRk);
1065
      break;
1066
    case FRV_OPERAND_FCCI_1 :
1067
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_1);
1068
      break;
1069
    case FRV_OPERAND_FCCI_2 :
1070
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_2);
1071
      break;
1072
    case FRV_OPERAND_FCCI_3 :
1073
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_3);
1074
      break;
1075
    case FRV_OPERAND_FCCK :
1076
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCk);
1077
      break;
1078
    case FRV_OPERAND_FRDOUBLEI :
1079
      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1080
      break;
1081
    case FRV_OPERAND_FRDOUBLEJ :
1082
      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1083
      break;
1084
    case FRV_OPERAND_FRDOUBLEK :
1085
      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1086
      break;
1087
    case FRV_OPERAND_FRI :
1088
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1089
      break;
1090
    case FRV_OPERAND_FRINTI :
1091
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1092
      break;
1093
    case FRV_OPERAND_FRINTIEVEN :
1094
      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1095
      break;
1096
    case FRV_OPERAND_FRINTJ :
1097
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1098
      break;
1099
    case FRV_OPERAND_FRINTJEVEN :
1100
      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1101
      break;
1102
    case FRV_OPERAND_FRINTK :
1103
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1104
      break;
1105
    case FRV_OPERAND_FRINTKEVEN :
1106
      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1107
      break;
1108
    case FRV_OPERAND_FRJ :
1109
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1110
      break;
1111
    case FRV_OPERAND_FRK :
1112
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1113
      break;
1114
    case FRV_OPERAND_FRKHI :
1115
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1116
      break;
1117
    case FRV_OPERAND_FRKLO :
1118
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1119
      break;
1120
    case FRV_OPERAND_GRDOUBLEK :
1121
      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1122
      break;
1123
    case FRV_OPERAND_GRI :
1124
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRi);
1125
      break;
1126
    case FRV_OPERAND_GRJ :
1127
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRj);
1128
      break;
1129
    case FRV_OPERAND_GRK :
1130
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1131
      break;
1132
    case FRV_OPERAND_GRKHI :
1133
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1134
      break;
1135
    case FRV_OPERAND_GRKLO :
1136
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1137
      break;
1138
    case FRV_OPERAND_ICCI_1 :
1139
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_1);
1140
      break;
1141
    case FRV_OPERAND_ICCI_2 :
1142
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_2);
1143
      break;
1144
    case FRV_OPERAND_ICCI_3 :
1145
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_3);
1146
      break;
1147
    case FRV_OPERAND_LI :
1148
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LI, (unsigned long *) (& fields->f_LI));
1149
      break;
1150
    case FRV_OPERAND_LRAD :
1151
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAD, (unsigned long *) (& fields->f_LRAD));
1152
      break;
1153
    case FRV_OPERAND_LRAE :
1154
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAE, (unsigned long *) (& fields->f_LRAE));
1155
      break;
1156
    case FRV_OPERAND_LRAS :
1157
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAS, (unsigned long *) (& fields->f_LRAS));
1158
      break;
1159
    case FRV_OPERAND_TLBPRL :
1160
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPRL, (unsigned long *) (& fields->f_TLBPRL));
1161
      break;
1162
    case FRV_OPERAND_TLBPROPX :
1163
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPROPX, (unsigned long *) (& fields->f_TLBPRopx));
1164
      break;
1165
    case FRV_OPERAND_AE :
1166
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_AE, (unsigned long *) (& fields->f_ae));
1167
      break;
1168
    case FRV_OPERAND_CALLANN :
1169
      errmsg = parse_call_annotation (cd, strp, FRV_OPERAND_CALLANN, (unsigned long *) (& fields->f_reloc_ann));
1170
      break;
1171
    case FRV_OPERAND_CCOND :
1172
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_CCOND, (unsigned long *) (& fields->f_ccond));
1173
      break;
1174
    case FRV_OPERAND_COND :
1175
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_COND, (unsigned long *) (& fields->f_cond));
1176
      break;
1177
    case FRV_OPERAND_D12 :
1178
      errmsg = parse_d12 (cd, strp, FRV_OPERAND_D12, (long *) (& fields->f_d12));
1179
      break;
1180
    case FRV_OPERAND_DEBUG :
1181
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_DEBUG, (unsigned long *) (& fields->f_debug));
1182
      break;
1183
    case FRV_OPERAND_EIR :
1184
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_EIR, (unsigned long *) (& fields->f_eir));
1185
      break;
1186
    case FRV_OPERAND_HINT :
1187
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_HINT, (unsigned long *) (& fields->f_hint));
1188
      break;
1189
    case FRV_OPERAND_HINT_NOT_TAKEN :
1190
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_not_taken, & fields->f_hint);
1191
      break;
1192
    case FRV_OPERAND_HINT_TAKEN :
1193
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_taken, & fields->f_hint);
1194
      break;
1195
    case FRV_OPERAND_LABEL16 :
1196
      {
1197
        bfd_vma value = 0;
1198
        errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL16, 0, NULL,  & value);
1199
        fields->f_label16 = value;
1200
      }
1201
      break;
1202
    case FRV_OPERAND_LABEL24 :
1203
      {
1204
        bfd_vma value = 0;
1205
        errmsg = parse_call_label (cd, strp, FRV_OPERAND_LABEL24, 0, NULL,  & value);
1206
        fields->f_label24 = value;
1207
      }
1208
      break;
1209
    case FRV_OPERAND_LDANN :
1210
      errmsg = parse_ld_annotation (cd, strp, FRV_OPERAND_LDANN, (unsigned long *) (& fields->f_reloc_ann));
1211
      break;
1212
    case FRV_OPERAND_LDDANN :
1213
      errmsg = parse_ldd_annotation (cd, strp, FRV_OPERAND_LDDANN, (unsigned long *) (& fields->f_reloc_ann));
1214
      break;
1215
    case FRV_OPERAND_LOCK :
1216
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LOCK, (unsigned long *) (& fields->f_lock));
1217
      break;
1218
    case FRV_OPERAND_PACK :
1219
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_pack, & fields->f_pack);
1220
      break;
1221
    case FRV_OPERAND_S10 :
1222
      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S10, (long *) (& fields->f_s10));
1223
      break;
1224
    case FRV_OPERAND_S12 :
1225
      errmsg = parse_s12 (cd, strp, FRV_OPERAND_S12, (long *) (& fields->f_d12));
1226
      break;
1227
    case FRV_OPERAND_S16 :
1228
      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S16, (long *) (& fields->f_s16));
1229
      break;
1230
    case FRV_OPERAND_S5 :
1231
      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S5, (long *) (& fields->f_s5));
1232
      break;
1233
    case FRV_OPERAND_S6 :
1234
      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6, (long *) (& fields->f_s6));
1235
      break;
1236
    case FRV_OPERAND_S6_1 :
1237
      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6_1, (long *) (& fields->f_s6_1));
1238
      break;
1239
    case FRV_OPERAND_SLO16 :
1240
      errmsg = parse_uslo16 (cd, strp, FRV_OPERAND_SLO16, (long *) (& fields->f_s16));
1241
      break;
1242
    case FRV_OPERAND_SPR :
1243
      errmsg = parse_spr (cd, strp, & frv_cgen_opval_spr_names, & fields->f_spr);
1244
      break;
1245
    case FRV_OPERAND_U12 :
1246
      errmsg = parse_u12 (cd, strp, FRV_OPERAND_U12, (long *) (& fields->f_u12));
1247
      break;
1248
    case FRV_OPERAND_U16 :
1249
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U16, (unsigned long *) (& fields->f_u16));
1250
      break;
1251
    case FRV_OPERAND_U6 :
1252
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U6, (unsigned long *) (& fields->f_u6));
1253
      break;
1254
    case FRV_OPERAND_UHI16 :
1255
      errmsg = parse_uhi16 (cd, strp, FRV_OPERAND_UHI16, (unsigned long *) (& fields->f_u16));
1256
      break;
1257
    case FRV_OPERAND_ULO16 :
1258
      errmsg = parse_ulo16 (cd, strp, FRV_OPERAND_ULO16, (unsigned long *) (& fields->f_u16));
1259
      break;
1260
 
1261
    default :
1262
      /* xgettext:c-format */
1263
      fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
1264
      abort ();
1265
  }
1266
 
1267
  return errmsg;
1268
}
1269
 
1270
cgen_parse_fn * const frv_cgen_parse_handlers[] =
1271
{
1272
  parse_insn_normal,
1273
};
1274
 
1275
void
1276
frv_cgen_init_asm (CGEN_CPU_DESC cd)
1277
{
1278
  frv_cgen_init_opcode_table (cd);
1279
  frv_cgen_init_ibld_table (cd);
1280
  cd->parse_handlers = & frv_cgen_parse_handlers[0];
1281
  cd->parse_operand = frv_cgen_parse_operand;
1282
#ifdef CGEN_ASM_INIT_HOOK
1283
CGEN_ASM_INIT_HOOK
1284
#endif
1285
}
1286
 
1287
 
1288
 
1289
/* Regex construction routine.
1290
 
1291
   This translates an opcode syntax string into a regex string,
1292
   by replacing any non-character syntax element (such as an
1293
   opcode) with the pattern '.*'
1294
 
1295
   It then compiles the regex and stores it in the opcode, for
1296
   later use by frv_cgen_assemble_insn
1297
 
1298
   Returns NULL for success, an error message for failure.  */
1299
 
1300
char *
1301
frv_cgen_build_insn_regex (CGEN_INSN *insn)
1302
{
1303
  CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
1304
  const char *mnem = CGEN_INSN_MNEMONIC (insn);
1305
  char rxbuf[CGEN_MAX_RX_ELEMENTS];
1306
  char *rx = rxbuf;
1307
  const CGEN_SYNTAX_CHAR_TYPE *syn;
1308
  int reg_err;
1309
 
1310
  syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
1311
 
1312
  /* Mnemonics come first in the syntax string.  */
1313
  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1314
    return _("missing mnemonic in syntax string");
1315
  ++syn;
1316
 
1317
  /* Generate a case sensitive regular expression that emulates case
1318
     insensitive matching in the "C" locale.  We cannot generate a case
1319
     insensitive regular expression because in Turkish locales, 'i' and 'I'
1320
     are not equal modulo case conversion.  */
1321
 
1322
  /* Copy the literal mnemonic out of the insn.  */
1323
  for (; *mnem; mnem++)
1324
    {
1325
      char c = *mnem;
1326
 
1327
      if (ISALPHA (c))
1328
        {
1329
          *rx++ = '[';
1330
          *rx++ = TOLOWER (c);
1331
          *rx++ = TOUPPER (c);
1332
          *rx++ = ']';
1333
        }
1334
      else
1335
        *rx++ = c;
1336
    }
1337
 
1338
  /* Copy any remaining literals from the syntax string into the rx.  */
1339
  for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
1340
    {
1341
      if (CGEN_SYNTAX_CHAR_P (* syn))
1342
        {
1343
          char c = CGEN_SYNTAX_CHAR (* syn);
1344
 
1345
          switch (c)
1346
            {
1347
              /* Escape any regex metacharacters in the syntax.  */
1348
            case '.': case '[': case '\\':
1349
            case '*': case '^': case '$':
1350
 
1351
#ifdef CGEN_ESCAPE_EXTENDED_REGEX
1352
            case '?': case '{': case '}':
1353
            case '(': case ')': case '*':
1354
            case '|': case '+': case ']':
1355
#endif
1356
              *rx++ = '\\';
1357
              *rx++ = c;
1358
              break;
1359
 
1360
            default:
1361
              if (ISALPHA (c))
1362
                {
1363
                  *rx++ = '[';
1364
                  *rx++ = TOLOWER (c);
1365
                  *rx++ = TOUPPER (c);
1366
                  *rx++ = ']';
1367
                }
1368
              else
1369
                *rx++ = c;
1370
              break;
1371
            }
1372
        }
1373
      else
1374
        {
1375
          /* Replace non-syntax fields with globs.  */
1376
          *rx++ = '.';
1377
          *rx++ = '*';
1378
        }
1379
    }
1380
 
1381
  /* Trailing whitespace ok.  */
1382
  * rx++ = '[';
1383
  * rx++ = ' ';
1384
  * rx++ = '\t';
1385
  * rx++ = ']';
1386
  * rx++ = '*';
1387
 
1388
  /* But anchor it after that.  */
1389
  * rx++ = '$';
1390
  * rx = '\0';
1391
 
1392
  CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
1393
  reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
1394
 
1395
  if (reg_err == 0)
1396
    return NULL;
1397
  else
1398
    {
1399
      static char msg[80];
1400
 
1401
      regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
1402
      regfree ((regex_t *) CGEN_INSN_RX (insn));
1403
      free (CGEN_INSN_RX (insn));
1404
      (CGEN_INSN_RX (insn)) = NULL;
1405
      return msg;
1406
    }
1407
}
1408
 
1409
 
1410
/* Default insn parser.
1411
 
1412
   The syntax string is scanned and operands are parsed and stored in FIELDS.
1413
   Relocs are queued as we go via other callbacks.
1414
 
1415
   ??? Note that this is currently an all-or-nothing parser.  If we fail to
1416
   parse the instruction, we return 0 and the caller will start over from
1417
   the beginning.  Backtracking will be necessary in parsing subexpressions,
1418
   but that can be handled there.  Not handling backtracking here may get
1419
   expensive in the case of the m68k.  Deal with later.
1420
 
1421
   Returns NULL for success, an error message for failure.  */
1422
 
1423
static const char *
1424
parse_insn_normal (CGEN_CPU_DESC cd,
1425
                   const CGEN_INSN *insn,
1426
                   const char **strp,
1427
                   CGEN_FIELDS *fields)
1428
{
1429
  /* ??? Runtime added insns not handled yet.  */
1430
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1431
  const char *str = *strp;
1432
  const char *errmsg;
1433
  const char *p;
1434
  const CGEN_SYNTAX_CHAR_TYPE * syn;
1435
#ifdef CGEN_MNEMONIC_OPERANDS
1436
  /* FIXME: wip */
1437
  int past_opcode_p;
1438
#endif
1439
 
1440
  /* For now we assume the mnemonic is first (there are no leading operands).
1441
     We can parse it without needing to set up operand parsing.
1442
     GAS's input scrubber will ensure mnemonics are lowercase, but we may
1443
     not be called from GAS.  */
1444
  p = CGEN_INSN_MNEMONIC (insn);
1445
  while (*p && TOLOWER (*p) == TOLOWER (*str))
1446
    ++p, ++str;
1447
 
1448
  if (* p)
1449
    return _("unrecognized instruction");
1450
 
1451
#ifndef CGEN_MNEMONIC_OPERANDS
1452
  if (* str && ! ISSPACE (* str))
1453
    return _("unrecognized instruction");
1454
#endif
1455
 
1456
  CGEN_INIT_PARSE (cd);
1457
  cgen_init_parse_operand (cd);
1458
#ifdef CGEN_MNEMONIC_OPERANDS
1459
  past_opcode_p = 0;
1460
#endif
1461
 
1462
  /* We don't check for (*str != '\0') here because we want to parse
1463
     any trailing fake arguments in the syntax string.  */
1464
  syn = CGEN_SYNTAX_STRING (syntax);
1465
 
1466
  /* Mnemonics come first for now, ensure valid string.  */
1467
  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1468
    abort ();
1469
 
1470
  ++syn;
1471
 
1472
  while (* syn != 0)
1473
    {
1474
      /* Non operand chars must match exactly.  */
1475
      if (CGEN_SYNTAX_CHAR_P (* syn))
1476
        {
1477
          /* FIXME: While we allow for non-GAS callers above, we assume the
1478
             first char after the mnemonic part is a space.  */
1479
          /* FIXME: We also take inappropriate advantage of the fact that
1480
             GAS's input scrubber will remove extraneous blanks.  */
1481
          if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
1482
            {
1483
#ifdef CGEN_MNEMONIC_OPERANDS
1484
              if (CGEN_SYNTAX_CHAR(* syn) == ' ')
1485
                past_opcode_p = 1;
1486
#endif
1487
              ++ syn;
1488
              ++ str;
1489
            }
1490
          else if (*str)
1491
            {
1492
              /* Syntax char didn't match.  Can't be this insn.  */
1493
              static char msg [80];
1494
 
1495
              /* xgettext:c-format */
1496
              sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
1497
                       CGEN_SYNTAX_CHAR(*syn), *str);
1498
              return msg;
1499
            }
1500
          else
1501
            {
1502
              /* Ran out of input.  */
1503
              static char msg [80];
1504
 
1505
              /* xgettext:c-format */
1506
              sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
1507
                       CGEN_SYNTAX_CHAR(*syn));
1508
              return msg;
1509
            }
1510
          continue;
1511
        }
1512
 
1513
#ifdef CGEN_MNEMONIC_OPERANDS
1514
      (void) past_opcode_p;
1515
#endif
1516
      /* We have an operand of some sort.  */
1517
      errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
1518
      if (errmsg)
1519
        return errmsg;
1520
 
1521
      /* Done with this operand, continue with next one.  */
1522
      ++ syn;
1523
    }
1524
 
1525
  /* If we're at the end of the syntax string, we're done.  */
1526
  if (* syn == 0)
1527
    {
1528
      /* FIXME: For the moment we assume a valid `str' can only contain
1529
         blanks now.  IE: We needn't try again with a longer version of
1530
         the insn and it is assumed that longer versions of insns appear
1531
         before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
1532
      while (ISSPACE (* str))
1533
        ++ str;
1534
 
1535
      if (* str != '\0')
1536
        return _("junk at end of line"); /* FIXME: would like to include `str' */
1537
 
1538
      return NULL;
1539
    }
1540
 
1541
  /* We couldn't parse it.  */
1542
  return _("unrecognized instruction");
1543
}
1544
 
1545
/* Main entry point.
1546
   This routine is called for each instruction to be assembled.
1547
   STR points to the insn to be assembled.
1548
   We assume all necessary tables have been initialized.
1549
   The assembled instruction, less any fixups, is stored in BUF.
1550
   Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
1551
   still needs to be converted to target byte order, otherwise BUF is an array
1552
   of bytes in target byte order.
1553
   The result is a pointer to the insn's entry in the opcode table,
1554
   or NULL if an error occured (an error message will have already been
1555
   printed).
1556
 
1557
   Note that when processing (non-alias) macro-insns,
1558
   this function recurses.
1559
 
1560
   ??? It's possible to make this cpu-independent.
1561
   One would have to deal with a few minor things.
1562
   At this point in time doing so would be more of a curiosity than useful
1563
   [for example this file isn't _that_ big], but keeping the possibility in
1564
   mind helps keep the design clean.  */
1565
 
1566
const CGEN_INSN *
1567
frv_cgen_assemble_insn (CGEN_CPU_DESC cd,
1568
                           const char *str,
1569
                           CGEN_FIELDS *fields,
1570
                           CGEN_INSN_BYTES_PTR buf,
1571
                           char **errmsg)
1572
{
1573
  const char *start;
1574
  CGEN_INSN_LIST *ilist;
1575
  const char *parse_errmsg = NULL;
1576
  const char *insert_errmsg = NULL;
1577
  int recognized_mnemonic = 0;
1578
 
1579
  /* Skip leading white space.  */
1580
  while (ISSPACE (* str))
1581
    ++ str;
1582
 
1583
  /* The instructions are stored in hashed lists.
1584
     Get the first in the list.  */
1585
  ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
1586
 
1587
  /* Keep looking until we find a match.  */
1588
  start = str;
1589
  for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1590
    {
1591
      const CGEN_INSN *insn = ilist->insn;
1592
      recognized_mnemonic = 1;
1593
 
1594
#ifdef CGEN_VALIDATE_INSN_SUPPORTED 
1595
      /* Not usually needed as unsupported opcodes
1596
         shouldn't be in the hash lists.  */
1597
      /* Is this insn supported by the selected cpu?  */
1598
      if (! frv_cgen_insn_supported (cd, insn))
1599
        continue;
1600
#endif
1601
      /* If the RELAXED attribute is set, this is an insn that shouldn't be
1602
         chosen immediately.  Instead, it is used during assembler/linker
1603
         relaxation if possible.  */
1604
      if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
1605
        continue;
1606
 
1607
      str = start;
1608
 
1609
      /* Skip this insn if str doesn't look right lexically.  */
1610
      if (CGEN_INSN_RX (insn) != NULL &&
1611
          regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
1612
        continue;
1613
 
1614
      /* Allow parse/insert handlers to obtain length of insn.  */
1615
      CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1616
 
1617
      parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
1618
      if (parse_errmsg != NULL)
1619
        continue;
1620
 
1621
      /* ??? 0 is passed for `pc'.  */
1622
      insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1623
                                                 (bfd_vma) 0);
1624
      if (insert_errmsg != NULL)
1625
        continue;
1626
 
1627
      /* It is up to the caller to actually output the insn and any
1628
         queued relocs.  */
1629
      return insn;
1630
    }
1631
 
1632
  {
1633
    static char errbuf[150];
1634
    const char *tmp_errmsg;
1635
#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
1636
#define be_verbose 1
1637
#else
1638
#define be_verbose 0
1639
#endif
1640
 
1641
    if (be_verbose)
1642
      {
1643
        /* If requesting verbose error messages, use insert_errmsg.
1644
           Failing that, use parse_errmsg.  */
1645
        tmp_errmsg = (insert_errmsg ? insert_errmsg :
1646
                      parse_errmsg ? parse_errmsg :
1647
                      recognized_mnemonic ?
1648
                      _("unrecognized form of instruction") :
1649
                      _("unrecognized instruction"));
1650
 
1651
        if (strlen (start) > 50)
1652
          /* xgettext:c-format */
1653
          sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1654
        else
1655
          /* xgettext:c-format */
1656
          sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1657
      }
1658
    else
1659
      {
1660
        if (strlen (start) > 50)
1661
          /* xgettext:c-format */
1662
          sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1663
        else
1664
          /* xgettext:c-format */
1665
          sprintf (errbuf, _("bad instruction `%.50s'"), start);
1666
      }
1667
 
1668
    *errmsg = errbuf;
1669
    return NULL;
1670
  }
1671
}

powered by: WebSVN 2.1.0

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