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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [opcodes/] [mep-asm.c] - Blame information for rev 298

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

Line No. Rev Author Line
1 24 jeremybenn
/* 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 225 jeremybenn
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2007, 2008
8 24 jeremybenn
   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 "mep-desc.h"
36
#include "mep-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
 
54 225 jeremybenn
#include "elf/mep.h"
55
 
56 24 jeremybenn
#define CGEN_VALIDATE_INSN_SUPPORTED
57 225 jeremybenn
#define mep_cgen_insn_supported mep_cgen_insn_supported_asm
58 24 jeremybenn
 
59
       const char * parse_csrn       (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
60
       const char * parse_tpreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
61
       const char * parse_spreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
62
       const char * parse_mep_align  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, long *);
63
       const char * parse_mep_alignu (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
64
static const char * parse_signed16   (CGEN_CPU_DESC, const char **, int, long *);
65 225 jeremybenn
static const char * parse_signed16_range   (CGEN_CPU_DESC, const char **, int, long *) ATTRIBUTE_UNUSED;
66 24 jeremybenn
static const char * parse_unsigned16 (CGEN_CPU_DESC, const char **, int, unsigned long *);
67 225 jeremybenn
static const char * parse_unsigned16_range (CGEN_CPU_DESC, const char **, int, unsigned long *) ATTRIBUTE_UNUSED;
68 24 jeremybenn
static const char * parse_lo16       (CGEN_CPU_DESC, const char **, int, long *, long);
69
static const char * parse_unsigned7  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
70
static const char * parse_zero       (CGEN_CPU_DESC, const char **, int, long *);
71
 
72
const char *
73
parse_csrn (CGEN_CPU_DESC cd, const char **strp,
74
            CGEN_KEYWORD *keyword_table, long *field)
75
{
76
  const char *err;
77
  unsigned long value;
78
 
79
  err = cgen_parse_keyword (cd, strp, keyword_table, field);
80
  if (!err)
81
    return NULL;
82
 
83
  err = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, & value);
84
  if (err)
85
    return err;
86
  *field = value;
87
  return NULL;
88
}
89
 
90
/* begin-cop-ip-parse-handlers */
91
static const char *
92 225 jeremybenn
parse_ivc2_cr (CGEN_CPU_DESC,
93
        const char **,
94
        CGEN_KEYWORD *,
95
        long *) ATTRIBUTE_UNUSED;
96
static const char *
97
parse_ivc2_cr (CGEN_CPU_DESC cd,
98 24 jeremybenn
        const char **strp,
99
        CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
100
        long *field)
101
{
102 225 jeremybenn
  return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr_ivc2, field);
103 24 jeremybenn
}
104
static const char *
105 225 jeremybenn
parse_ivc2_ccr (CGEN_CPU_DESC,
106
        const char **,
107
        CGEN_KEYWORD *,
108
        long *) ATTRIBUTE_UNUSED;
109
static const char *
110
parse_ivc2_ccr (CGEN_CPU_DESC cd,
111 24 jeremybenn
        const char **strp,
112
        CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
113
        long *field)
114
{
115 225 jeremybenn
  return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, field);
116 24 jeremybenn
}
117
/* end-cop-ip-parse-handlers */
118
 
119
const char *
120
parse_tpreg (CGEN_CPU_DESC cd, const char ** strp,
121
             CGEN_KEYWORD *keyword_table, long *field)
122
{
123
  const char *err;
124
 
125
  err = cgen_parse_keyword (cd, strp, keyword_table, field);
126
  if (err)
127
    return err;
128
  if (*field != 13)
129
    return _("Only $tp or $13 allowed for this opcode");
130
  return NULL;
131
}
132
 
133
const char *
134
parse_spreg (CGEN_CPU_DESC cd, const char ** strp,
135
             CGEN_KEYWORD *keyword_table, long *field)
136
{
137
  const char *err;
138
 
139
  err = cgen_parse_keyword (cd, strp, keyword_table, field);
140
  if (err)
141
    return err;
142
  if (*field != 15)
143
    return _("Only $sp or $15 allowed for this opcode");
144
  return NULL;
145
}
146
 
147
const char *
148
parse_mep_align (CGEN_CPU_DESC cd, const char ** strp,
149
                 enum cgen_operand_type type, long *field)
150
{
151
  long lsbs = 0;
152
  const char *err;
153
 
154
  switch (type)
155
    {
156
    case MEP_OPERAND_PCREL8A2:
157
    case MEP_OPERAND_PCREL12A2:
158
    case MEP_OPERAND_PCREL17A2:
159
    case MEP_OPERAND_PCREL24A2:
160
      err = cgen_parse_signed_integer   (cd, strp, type, field);
161
      break;
162
    case MEP_OPERAND_PCABS24A2:
163
    case MEP_OPERAND_UDISP7:
164
    case MEP_OPERAND_UDISP7A2:
165
    case MEP_OPERAND_UDISP7A4:
166
    case MEP_OPERAND_UIMM7A4:
167
    case MEP_OPERAND_ADDR24A4:
168
      err = cgen_parse_unsigned_integer (cd, strp, type, (unsigned long *) field);
169
      break;
170
    default:
171
      abort();
172
    }
173
  if (err)
174
    return err;
175
  switch (type)
176
    {
177
    case MEP_OPERAND_UDISP7:
178
      lsbs = 0;
179
      break;
180
    case MEP_OPERAND_PCREL8A2:
181
    case MEP_OPERAND_PCREL12A2:
182
    case MEP_OPERAND_PCREL17A2:
183
    case MEP_OPERAND_PCREL24A2:
184
    case MEP_OPERAND_PCABS24A2:
185
    case MEP_OPERAND_UDISP7A2:
186
      lsbs = *field & 1;
187
      break;
188
    case MEP_OPERAND_UDISP7A4:
189
    case MEP_OPERAND_UIMM7A4:
190
    case MEP_OPERAND_ADDR24A4:
191
      lsbs = *field & 3;
192
      break;
193
      lsbs = *field & 7;
194
      break;
195
    default:
196
      /* Safe assumption?  */
197
      abort ();
198
    }
199
  if (lsbs)
200
    return "Value is not aligned enough";
201
  return NULL;
202
}
203
 
204
const char *
205
parse_mep_alignu (CGEN_CPU_DESC cd, const char ** strp,
206
                 enum cgen_operand_type type, unsigned long *field)
207
{
208
  return parse_mep_align (cd, strp, type, (long *) field);
209
}
210
 
211
 
212
/* Handle %lo(), %tpoff(), %sdaoff(), %hi(), and other signed
213
   constants in a signed context.  */
214
 
215
static const char *
216
parse_signed16 (CGEN_CPU_DESC cd,
217
                const char **strp,
218
                int opindex,
219
                long *valuep)
220
{
221
  return parse_lo16 (cd, strp, opindex, valuep, 1);
222
}
223
 
224
static const char *
225
parse_lo16 (CGEN_CPU_DESC cd,
226
            const char **strp,
227
            int opindex,
228
            long *valuep,
229
            long signedp)
230
{
231
  const char *errmsg;
232
  enum cgen_parse_operand_result result_type;
233
  bfd_vma value;
234
 
235
  if (strncasecmp (*strp, "%lo(", 4) == 0)
236
    {
237
      *strp += 4;
238
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
239
                                   & result_type, & value);
240
      if (**strp != ')')
241
        return _("missing `)'");
242
      ++*strp;
243
      if (errmsg == NULL
244
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
245
        value &= 0xffff;
246
      if (signedp)
247
        *valuep = (long)(short) value;
248
      else
249
        *valuep = value;
250
      return errmsg;
251
    }
252
 
253
  if (strncasecmp (*strp, "%hi(", 4) == 0)
254
    {
255
      *strp += 4;
256
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
257
                                   & result_type, & value);
258
      if (**strp != ')')
259
        return _("missing `)'");
260
      ++*strp;
261
      if (errmsg == NULL
262
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
263
        value = (value + 0x8000) >> 16;
264
      *valuep = value;
265
      return errmsg;
266
    }
267
 
268
  if (strncasecmp (*strp, "%uhi(", 5) == 0)
269
    {
270
      *strp += 5;
271
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
272
                                   & result_type, & value);
273
      if (**strp != ')')
274
        return _("missing `)'");
275
      ++*strp;
276
      if (errmsg == NULL
277
          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
278
        value = value >> 16;
279
      *valuep = value;
280
      return errmsg;
281
    }
282
 
283
  if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
284
    {
285
      *strp += 8;
286
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
287
                                   NULL, & value);
288
      if (**strp != ')')
289
        return _("missing `)'");
290
      ++*strp;
291
      *valuep = value;
292
      return errmsg;
293
    }
294
 
295
  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
296
    {
297
      *strp += 7;
298
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
299
                                   NULL, & value);
300
      if (**strp != ')')
301
        return _("missing `)'");
302
      ++*strp;
303
      *valuep = value;
304
      return errmsg;
305
    }
306
 
307
  if (**strp == '%')
308
    return _("invalid %function() here");
309
 
310
  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
311
}
312
 
313
static const char *
314
parse_unsigned16 (CGEN_CPU_DESC cd,
315
                  const char **strp,
316
                  int opindex,
317
                  unsigned long *valuep)
318
{
319
  return parse_lo16 (cd, strp, opindex, (long *) valuep, 0);
320
}
321
 
322 225 jeremybenn
static const char *
323
parse_signed16_range (CGEN_CPU_DESC cd,
324
                      const char **strp,
325
                      int opindex,
326
                      signed long *valuep)
327
{
328
  const char *errmsg = 0;
329
  signed long value;
330
 
331
  errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
332
  if (errmsg)
333
    return errmsg;
334
 
335
  if (value < -32768 || value > 32767)
336
    return _("Immediate is out of range -32768 to 32767");
337
 
338
  *valuep = value;
339
  return 0;
340
}
341
 
342
static const char *
343
parse_unsigned16_range (CGEN_CPU_DESC cd,
344
                        const char **strp,
345
                        int opindex,
346
                        unsigned long *valuep)
347
{
348
  const char *errmsg = 0;
349
  unsigned long value;
350
 
351
  errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
352
  if (errmsg)
353
    return errmsg;
354
 
355
  if (value > 65535)
356
    return _("Immediate is out of range 0 to 65535");
357
 
358
  *valuep = value;
359
  return 0;
360
}
361
 
362 24 jeremybenn
/* A special case of parse_signed16 which accepts only the value zero.  */
363
 
364
static const char *
365
parse_zero (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
366
{
367
  const char *errmsg;
368
  enum cgen_parse_operand_result result_type;
369
  bfd_vma value;
370
 
371
  /*fprintf(stderr, "dj: signed parse opindex `%s'\n", *strp);*/
372
 
373
  /* Prevent ($ry) from being attempted as an expression on 'sw $rx,($ry)'.
374
     It will fail and cause ry to be listed as an undefined symbol in the
375
     listing.  */
376
  if (strncmp (*strp, "($", 2) == 0)
377
    return "not zero"; /* any string will do -- will never be seen.  */
378
 
379
  if (strncasecmp (*strp, "%lo(", 4) == 0)
380
    {
381
      *strp += 4;
382
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
383
                                   &result_type, &value);
384
      if (**strp != ')')
385
        return "missing `)'";
386
      ++*strp;
387
      if (errmsg == NULL
388
          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
389
        return "not zero"; /* any string will do -- will never be seen.  */
390
      *valuep = value;
391
      return errmsg;
392
    }
393
 
394
  if (strncasecmp (*strp, "%hi(", 4) == 0)
395
    {
396
      *strp += 4;
397
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
398
                                   &result_type, &value);
399
      if (**strp != ')')
400
        return "missing `)'";
401
      ++*strp;
402
      if (errmsg == NULL
403
          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
404
        return "not zero"; /* any string will do -- will never be seen.  */
405
      *valuep = value;
406
      return errmsg;
407
    }
408
 
409
  if (strncasecmp (*strp, "%uhi(", 5) == 0)
410
    {
411
      *strp += 5;
412
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
413
                                   &result_type, &value);
414
      if (**strp != ')')
415
        return "missing `)'";
416
      ++*strp;
417
      if (errmsg == NULL
418
          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
419
        return "not zero"; /* any string will do -- will never be seen.  */
420
      *valuep = value;
421
      return errmsg;
422
    }
423
 
424
  if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
425
    {
426
      *strp += 8;
427
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
428
                                   &result_type, &value);
429
      if (**strp != ')')
430
        return "missing `)'";
431
      ++*strp;
432
      if (errmsg == NULL
433
          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
434
        return "not zero"; /* any string will do -- will never be seen.  */
435
      *valuep = value;
436
      return errmsg;
437
    }
438
 
439
  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
440
    {
441
      *strp += 7;
442
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
443
                                   &result_type, &value);
444
      if (**strp != ')')
445
        return "missing `)'";
446
      ++*strp;
447
      if (errmsg == NULL
448
          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
449
        return "not zero"; /* any string will do -- will never be seen.  */
450
      *valuep = value;
451
      return errmsg;
452
    }
453
 
454
  if (**strp == '%')
455
    return "invalid %function() here";
456
 
457
  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_NONE,
458
                               &result_type, &value);
459
  if (errmsg == NULL
460
      && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
461
    return "not zero"; /* any string will do -- will never be seen.  */
462
 
463
  return errmsg;
464
}
465
 
466
static const char *
467
parse_unsigned7 (CGEN_CPU_DESC cd, const char **strp,
468
                 enum cgen_operand_type opindex, unsigned long *valuep)
469
{
470
  const char *errmsg;
471
  bfd_vma value;
472
 
473
  /* fprintf(stderr, "dj: unsigned7 parse `%s'\n", *strp); */
474
 
475
  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
476
    {
477
      int reloc;
478
      *strp += 7;
479
      switch (opindex)
480
        {
481
        case MEP_OPERAND_UDISP7:
482
          reloc = BFD_RELOC_MEP_TPREL7;
483
          break;
484
        case MEP_OPERAND_UDISP7A2:
485
          reloc = BFD_RELOC_MEP_TPREL7A2;
486
          break;
487
        case MEP_OPERAND_UDISP7A4:
488
          reloc = BFD_RELOC_MEP_TPREL7A4;
489
          break;
490
        default:
491
          /* Safe assumption?  */
492
          abort ();
493
        }
494
      errmsg = cgen_parse_address (cd, strp, opindex, reloc,
495
                                   NULL, &value);
496
      if (**strp != ')')
497
        return "missing `)'";
498
      ++*strp;
499
      *valuep = value;
500
      return errmsg;
501
    }
502
 
503
  if (**strp == '%')
504
    return _("invalid %function() here");
505
 
506
  return parse_mep_alignu (cd, strp, opindex, valuep);
507
}
508
 
509 225 jeremybenn
static ATTRIBUTE_UNUSED const char *
510
parse_cdisp10 (CGEN_CPU_DESC cd,
511
               const char **strp,
512
               int opindex,
513
               long *valuep)
514
{
515
  const char *errmsg = 0;
516
  signed long value;
517
  long have_zero = 0;
518
  int wide = 0;
519
  int alignment;
520
 
521
  switch (opindex)
522
    {
523
    case MEP_OPERAND_CDISP10A4:
524
      alignment = 2;
525
      break;
526
    case MEP_OPERAND_CDISP10A2:
527
      alignment = 1;
528
      break;
529
    case MEP_OPERAND_CDISP10:
530
    default:
531
      alignment = 0;
532
      break;
533
    }
534
 
535
  if ((MEP_CPU & EF_MEP_CPU_MASK) == EF_MEP_CPU_C5)
536
    wide = 1;
537
 
538
  if (strncmp (*strp, "0x0", 3) == 0
539
      || (**strp == '0' && *(*strp + 1) != 'x'))
540
    have_zero = 1;
541
 
542
  errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
543
  if (errmsg)
544
    return errmsg;
545
 
546
  if (wide)
547
    {
548
      if (value < -512 || value > 511)
549
        return _("Immediate is out of range -512 to 511");
550
    }
551
  else
552
    {
553
      if (value < -128 || value > 127)
554
        return _("Immediate is out of range -128 to 127");
555
    }
556
 
557
  if (value & ((1<<alignment)-1))
558
    return _("Value is not aligned enough");
559
 
560
  /* If this field may require a relocation then use larger dsp16.  */
561
  if (! have_zero && value == 0)
562
    return (wide ? _("Immediate is out of range -512 to 511")
563
            : _("Immediate is out of range -128 to 127"));
564
 
565
  *valuep = value;
566
  return 0;
567
}
568
 
569 24 jeremybenn
/* BEGIN LIGHTWEIGHT MACRO PROCESSOR.  */
570
 
571
#define MAXARGS 9
572
 
573
typedef struct
574
{
575
  char *name;
576
  char *expansion;
577
}  macro;
578
 
579
typedef struct
580
{
581
  const char *start;
582
  int len;
583
} arg;
584
 
585
macro macros[] =
586
{
587
  { "sizeof", "(`1.end + (- `1))"},
588
  { "startof", "(`1 | 0)" },
589
  { "align4", "(`1&(~3))"},
590
/*{ "hi", "(((`1+0x8000)>>16) & 0xffff)" },  */
591
/*{ "lo", "(`1 & 0xffff)" },  */
592
/*{ "sdaoff", "((`1-__sdabase) & 0x7f)"},  */
593
/*{ "tpoff", "((`1-__tpbase) & 0x7f)"},  */
594
  { 0,0 }
595
};
596
 
597
static char  * expand_string    (const char *, int);
598
 
599
static const char *
600
mep_cgen_expand_macros_and_parse_operand
601
  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
602
 
603
static char *
604
str_append (char *dest, const char *input, int len)
605
{
606
  char *new_dest;
607
  int oldlen;
608
 
609
  if (len == 0)
610
    return dest;
611
  /* printf("str_append: <<%s>>, <<%s>>, %d\n", dest, input, len); */
612
  oldlen = (dest ? strlen(dest) : 0);
613
  new_dest = realloc (dest, oldlen + len + 1);
614
  memset (new_dest + oldlen, 0, len + 1);
615
  return strncat (new_dest, input, len);
616
}
617
 
618
static macro *
619
lookup_macro (const char *name)
620
{
621
  macro *m;
622
 
623
  for (m = macros; m->name; ++m)
624
    if (strncmp (m->name, name, strlen(m->name)) == 0)
625
      return m;
626
 
627
  return 0;
628
}
629
 
630
static char *
631
expand_macro (arg *args, int narg, macro *mac)
632
{
633
  char *result = 0, *rescanned_result = 0;
634
  char *e = mac->expansion;
635
  char *mark = e;
636
  int arg = 0;
637
 
638
  /*  printf("expanding macro %s with %d args\n", mac->name, narg + 1); */
639
  while (*e)
640
    {
641
      if (*e == '`' &&
642
          (*e+1) &&
643
          ((*(e + 1) - '1') <= MAXARGS) &&
644
          ((*(e + 1) - '1') <= narg))
645
        {
646
          result = str_append (result, mark, e - mark);
647
          arg = (*(e + 1) - '1');
648
          /* printf("replacing `%d with %s\n", arg+1, args[arg].start); */
649
          result = str_append (result, args[arg].start, args[arg].len);
650
          ++e;
651
          mark = e+1;
652
        }
653
      ++e;
654
    }
655
 
656
  if (mark != e)
657
    result = str_append (result, mark, e - mark);
658
 
659
  if (result)
660
    {
661
      rescanned_result = expand_string (result, 0);
662
      free (result);
663
      return rescanned_result;
664
    }
665
  else
666
    return result;
667
}
668
 
669
#define IN_TEXT 0
670
#define IN_ARGS 1
671
 
672
static char *
673
expand_string (const char *in, int first_only)
674
{
675
  int num_expansions = 0;
676
  int depth = 0;
677
  int narg = -1;
678
  arg args[MAXARGS];
679
  int state = IN_TEXT;
680
  const char *mark = in;
681
  macro *macro = 0;
682
 
683
  char *expansion = 0;
684
  char *result = 0;
685
 
686
  while (*in)
687
    {
688
      switch (state)
689
        {
690
        case IN_TEXT:
691
          if (*in == '%' && *(in + 1) && (!first_only || num_expansions == 0))
692
            {
693
              macro = lookup_macro (in + 1);
694
              if (macro)
695
                {
696
                  /* printf("entering state %d at '%s'...\n", state, in); */
697
                  result = str_append (result, mark, in - mark);
698
                  mark = in;
699
                  in += 1 + strlen (macro->name);
700
                  while (*in == ' ') ++in;
701
                  if (*in != '(')
702
                    {
703
                      state = IN_TEXT;
704
                      macro = 0;
705
                    }
706
                  else
707
                    {
708
                      state = IN_ARGS;
709
                      narg = 0;
710
                      args[narg].start = in + 1;
711
                      args[narg].len = 0;
712
                      mark = in + 1;
713
                    }
714
                }
715
            }
716
          break;
717
        case IN_ARGS:
718
          if (depth == 0)
719
            {
720
              switch (*in)
721
                {
722
                case ',':
723
                  narg++;
724
                  args[narg].start = (in + 1);
725
                  args[narg].len = 0;
726
                  break;
727
                case ')':
728
                  state = IN_TEXT;
729
                  /* printf("entering state %d at '%s'...\n", state, in); */
730
                  if (macro)
731
                    {
732
                      expansion = 0;
733
                      expansion = expand_macro (args, narg, macro);
734
                      num_expansions++;
735
                      if (expansion)
736
                        {
737
                          result = str_append (result, expansion, strlen (expansion));
738
                          free (expansion);
739
                        }
740
                    }
741
                  else
742
                    {
743
                      result = str_append (result, mark, in - mark);
744
                    }
745
                  macro = 0;
746
                  mark = in + 1;
747
                  break;
748
                case '(':
749
                  depth++;
750
                default:
751
                  args[narg].len++;
752
                  break;
753
                }
754
            }
755
          else
756
            {
757
              if (*in == ')')
758
                depth--;
759
              if (narg > -1)
760
                args[narg].len++;
761
            }
762
 
763
        }
764
      ++in;
765
    }
766
 
767
  if (mark != in)
768
    result = str_append (result, mark, in - mark);
769
 
770
  return result;
771
}
772
 
773
#undef IN_ARGS
774
#undef IN_TEXT
775
#undef MAXARGS
776
 
777
 
778
/* END LIGHTWEIGHT MACRO PROCESSOR.  */
779
 
780
const char * mep_cgen_parse_operand
781
  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
782
 
783
const char *
784
mep_cgen_expand_macros_and_parse_operand (CGEN_CPU_DESC cd, int opindex,
785
                                          const char ** strp_in, CGEN_FIELDS * fields)
786
{
787
  const char * errmsg = NULL;
788
  char *str = 0, *hold = 0;
789
  const char **strp = 0;
790
 
791
  /* Set up a new pointer to macro-expanded string.  */
792
  str = expand_string (*strp_in, 1);
793
  /* fprintf (stderr, " expanded <<%s>> to <<%s>>\n", *strp_in, str); */
794
 
795
  hold = str;
796
  strp = (const char **)(&str);
797
 
798
  errmsg = mep_cgen_parse_operand (cd, opindex, strp, fields);
799
 
800
  /* Now work out the advance.  */
801
  if (strlen (str) == 0)
802
    *strp_in += strlen (*strp_in);
803
 
804
  else
805
    {
806
      if (strstr (*strp_in, str))
807
        /* A macro-expansion was pulled off the front.  */
808
        *strp_in = strstr (*strp_in, str);
809
      else
810
        /* A non-macro-expansion was pulled off the front.  */
811
        *strp_in += (str - hold);
812
    }
813
 
814
  if (hold)
815
    free (hold);
816
 
817
  return errmsg;
818
}
819
 
820
#define CGEN_ASM_INIT_HOOK (cd->parse_operand = mep_cgen_expand_macros_and_parse_operand); 
821
 
822
/* -- dis.c */
823
 
824
const char * mep_cgen_parse_operand
825
  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
826
 
827
/* Main entry point for operand parsing.
828
 
829
   This function is basically just a big switch statement.  Earlier versions
830
   used tables to look up the function to use, but
831
   - if the table contains both assembler and disassembler functions then
832
     the disassembler contains much of the assembler and vice-versa,
833
   - there's a lot of inlining possibilities as things grow,
834
   - using a switch statement avoids the function call overhead.
835
 
836
   This function could be moved into `parse_insn_normal', but keeping it
837
   separate makes clear the interface between `parse_insn_normal' and each of
838
   the handlers.  */
839
 
840
const char *
841
mep_cgen_parse_operand (CGEN_CPU_DESC cd,
842
                           int opindex,
843
                           const char ** strp,
844
                           CGEN_FIELDS * fields)
845
{
846
  const char * errmsg = NULL;
847
  /* Used by scalar operands that still need to be parsed.  */
848
  long junk ATTRIBUTE_UNUSED;
849
 
850
  switch (opindex)
851
    {
852
    case MEP_OPERAND_ADDR24A4 :
853
      errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_ADDR24A4, (unsigned long *) (& fields->f_24u8a4n));
854
      break;
855 225 jeremybenn
    case MEP_OPERAND_C5RMUIMM20 :
856
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RMUIMM20, (unsigned long *) (& fields->f_c5_rmuimm20));
857
      break;
858
    case MEP_OPERAND_C5RNMUIMM24 :
859
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RNMUIMM24, (unsigned long *) (& fields->f_c5_rnmuimm24));
860
      break;
861 24 jeremybenn
    case MEP_OPERAND_CALLNUM :
862
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CALLNUM, (unsigned long *) (& fields->f_callnum));
863
      break;
864
    case MEP_OPERAND_CCCC :
865
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CCCC, (unsigned long *) (& fields->f_rm));
866
      break;
867
    case MEP_OPERAND_CCRN :
868
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & fields->f_ccrn);
869
      break;
870 225 jeremybenn
    case MEP_OPERAND_CDISP10 :
871
      errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10, (long *) (& fields->f_cdisp10));
872 24 jeremybenn
      break;
873 225 jeremybenn
    case MEP_OPERAND_CDISP10A2 :
874
      errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A2, (long *) (& fields->f_cdisp10));
875 24 jeremybenn
      break;
876 225 jeremybenn
    case MEP_OPERAND_CDISP10A4 :
877
      errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A4, (long *) (& fields->f_cdisp10));
878 24 jeremybenn
      break;
879 225 jeremybenn
    case MEP_OPERAND_CDISP10A8 :
880
      errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A8, (long *) (& fields->f_cdisp10));
881 24 jeremybenn
      break;
882 225 jeremybenn
    case MEP_OPERAND_CDISP12 :
883
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_CDISP12, (long *) (& fields->f_12s20));
884
      break;
885 24 jeremybenn
    case MEP_OPERAND_CIMM4 :
886
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM4, (unsigned long *) (& fields->f_rn));
887
      break;
888
    case MEP_OPERAND_CIMM5 :
889
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM5, (unsigned long *) (& fields->f_5u24));
890
      break;
891
    case MEP_OPERAND_CODE16 :
892
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE16, (unsigned long *) (& fields->f_16u16));
893
      break;
894
    case MEP_OPERAND_CODE24 :
895
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE24, (unsigned long *) (& fields->f_24u4n));
896
      break;
897
    case MEP_OPERAND_CP_FLAG :
898
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & junk);
899
      break;
900
    case MEP_OPERAND_CRN :
901
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crn);
902
      break;
903
    case MEP_OPERAND_CRN64 :
904
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crn);
905
      break;
906
    case MEP_OPERAND_CRNX :
907
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crnx);
908
      break;
909
    case MEP_OPERAND_CRNX64 :
910
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crnx);
911
      break;
912 225 jeremybenn
    case MEP_OPERAND_CROC :
913
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u7);
914
      break;
915
    case MEP_OPERAND_CROP :
916
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u23);
917
      break;
918
    case MEP_OPERAND_CRPC :
919
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u26);
920
      break;
921
    case MEP_OPERAND_CRPP :
922
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u18);
923
      break;
924
    case MEP_OPERAND_CRQC :
925
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u21);
926
      break;
927
    case MEP_OPERAND_CRQP :
928
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u13);
929
      break;
930 24 jeremybenn
    case MEP_OPERAND_CSRN :
931
      errmsg = parse_csrn (cd, strp, & mep_cgen_opval_h_csr, & fields->f_csrn);
932
      break;
933
    case MEP_OPERAND_CSRN_IDX :
934
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, (unsigned long *) (& fields->f_csrn));
935
      break;
936
    case MEP_OPERAND_DBG :
937
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
938
      break;
939
    case MEP_OPERAND_DEPC :
940
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
941
      break;
942
    case MEP_OPERAND_EPC :
943
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
944
      break;
945
    case MEP_OPERAND_EXC :
946
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
947
      break;
948 225 jeremybenn
    case MEP_OPERAND_HI :
949
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
950 24 jeremybenn
      break;
951 225 jeremybenn
    case MEP_OPERAND_IMM16P0 :
952
      errmsg = parse_unsigned16_range (cd, strp, MEP_OPERAND_IMM16P0, (unsigned long *) (& fields->f_ivc2_imm16p0));
953 24 jeremybenn
      break;
954 225 jeremybenn
    case MEP_OPERAND_IMM3P12 :
955
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P12, (unsigned long *) (& fields->f_ivc2_3u12));
956 24 jeremybenn
      break;
957 225 jeremybenn
    case MEP_OPERAND_IMM3P25 :
958
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P25, (unsigned long *) (& fields->f_ivc2_3u25));
959 24 jeremybenn
      break;
960 225 jeremybenn
    case MEP_OPERAND_IMM3P4 :
961
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P4, (unsigned long *) (& fields->f_ivc2_3u4));
962 24 jeremybenn
      break;
963 225 jeremybenn
    case MEP_OPERAND_IMM3P5 :
964
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P5, (unsigned long *) (& fields->f_ivc2_3u5));
965 24 jeremybenn
      break;
966 225 jeremybenn
    case MEP_OPERAND_IMM3P9 :
967
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P9, (unsigned long *) (& fields->f_ivc2_3u9));
968 24 jeremybenn
      break;
969 225 jeremybenn
    case MEP_OPERAND_IMM4P10 :
970
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P10, (unsigned long *) (& fields->f_ivc2_4u10));
971 24 jeremybenn
      break;
972 225 jeremybenn
    case MEP_OPERAND_IMM4P4 :
973
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P4, (unsigned long *) (& fields->f_ivc2_4u4));
974
      break;
975
    case MEP_OPERAND_IMM4P8 :
976
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P8, (unsigned long *) (& fields->f_ivc2_4u8));
977
      break;
978
    case MEP_OPERAND_IMM5P23 :
979
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P23, (unsigned long *) (& fields->f_ivc2_5u23));
980
      break;
981
    case MEP_OPERAND_IMM5P3 :
982
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P3, (unsigned long *) (& fields->f_ivc2_5u3));
983
      break;
984
    case MEP_OPERAND_IMM5P7 :
985
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P7, (unsigned long *) (& fields->f_ivc2_5u7));
986
      break;
987
    case MEP_OPERAND_IMM5P8 :
988
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P8, (unsigned long *) (& fields->f_ivc2_5u8));
989
      break;
990
    case MEP_OPERAND_IMM6P2 :
991
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM6P2, (unsigned long *) (& fields->f_ivc2_6u2));
992
      break;
993
    case MEP_OPERAND_IMM6P6 :
994
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM6P6, (unsigned long *) (& fields->f_ivc2_6u6));
995
      break;
996
    case MEP_OPERAND_IMM8P0 :
997
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P0, (unsigned long *) (& fields->f_ivc2_8u0));
998
      break;
999
    case MEP_OPERAND_IMM8P20 :
1000
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P20, (unsigned long *) (& fields->f_ivc2_8u20));
1001
      break;
1002
    case MEP_OPERAND_IMM8P4 :
1003
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P4, (unsigned long *) (& fields->f_ivc2_8u4));
1004
      break;
1005
    case MEP_OPERAND_IVC_X_0_2 :
1006
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_2, (unsigned long *) (& fields->f_ivc2_2u0));
1007
      break;
1008
    case MEP_OPERAND_IVC_X_0_3 :
1009
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_3, (unsigned long *) (& fields->f_ivc2_3u0));
1010
      break;
1011
    case MEP_OPERAND_IVC_X_0_4 :
1012
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_4, (unsigned long *) (& fields->f_ivc2_4u0));
1013
      break;
1014
    case MEP_OPERAND_IVC_X_0_5 :
1015
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_5, (unsigned long *) (& fields->f_ivc2_5u0));
1016
      break;
1017
    case MEP_OPERAND_IVC_X_6_1 :
1018
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_1, (unsigned long *) (& fields->f_ivc2_1u6));
1019
      break;
1020
    case MEP_OPERAND_IVC_X_6_2 :
1021
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_2, (unsigned long *) (& fields->f_ivc2_2u6));
1022
      break;
1023
    case MEP_OPERAND_IVC_X_6_3 :
1024
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_3, (unsigned long *) (& fields->f_ivc2_3u6));
1025
      break;
1026
    case MEP_OPERAND_IVC2_ACC0_0 :
1027
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1028
      break;
1029
    case MEP_OPERAND_IVC2_ACC0_1 :
1030
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1031
      break;
1032
    case MEP_OPERAND_IVC2_ACC0_2 :
1033
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1034
      break;
1035
    case MEP_OPERAND_IVC2_ACC0_3 :
1036
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1037
      break;
1038
    case MEP_OPERAND_IVC2_ACC0_4 :
1039
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1040
      break;
1041
    case MEP_OPERAND_IVC2_ACC0_5 :
1042
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1043
      break;
1044
    case MEP_OPERAND_IVC2_ACC0_6 :
1045
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1046
      break;
1047
    case MEP_OPERAND_IVC2_ACC0_7 :
1048
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1049
      break;
1050
    case MEP_OPERAND_IVC2_ACC1_0 :
1051
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1052
      break;
1053
    case MEP_OPERAND_IVC2_ACC1_1 :
1054
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1055
      break;
1056
    case MEP_OPERAND_IVC2_ACC1_2 :
1057
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1058
      break;
1059
    case MEP_OPERAND_IVC2_ACC1_3 :
1060
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1061
      break;
1062
    case MEP_OPERAND_IVC2_ACC1_4 :
1063
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1064
      break;
1065
    case MEP_OPERAND_IVC2_ACC1_5 :
1066
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1067
      break;
1068
    case MEP_OPERAND_IVC2_ACC1_6 :
1069
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1070
      break;
1071
    case MEP_OPERAND_IVC2_ACC1_7 :
1072
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1073
      break;
1074
    case MEP_OPERAND_IVC2_CC :
1075
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1076
      break;
1077
    case MEP_OPERAND_IVC2_COFA0 :
1078
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1079
      break;
1080
    case MEP_OPERAND_IVC2_COFA1 :
1081
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1082
      break;
1083
    case MEP_OPERAND_IVC2_COFR0 :
1084
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1085
      break;
1086
    case MEP_OPERAND_IVC2_COFR1 :
1087
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1088
      break;
1089
    case MEP_OPERAND_IVC2_CSAR0 :
1090
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1091
      break;
1092
    case MEP_OPERAND_IVC2_CSAR1 :
1093
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1094
      break;
1095
    case MEP_OPERAND_IVC2C3CCRN :
1096
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & fields->f_ivc2_ccrn_c3);
1097
      break;
1098
    case MEP_OPERAND_IVC2CCRN :
1099
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & fields->f_ivc2_ccrn);
1100
      break;
1101
    case MEP_OPERAND_IVC2CRN :
1102
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_crnx);
1103
      break;
1104
    case MEP_OPERAND_IVC2RM :
1105
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_ivc2_crm);
1106
      break;
1107 24 jeremybenn
    case MEP_OPERAND_LO :
1108
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1109
      break;
1110
    case MEP_OPERAND_LP :
1111
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1112
      break;
1113
    case MEP_OPERAND_MB0 :
1114
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1115
      break;
1116
    case MEP_OPERAND_MB1 :
1117
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1118
      break;
1119
    case MEP_OPERAND_ME0 :
1120
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1121
      break;
1122
    case MEP_OPERAND_ME1 :
1123
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1124
      break;
1125
    case MEP_OPERAND_NPC :
1126
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1127
      break;
1128
    case MEP_OPERAND_OPT :
1129
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1130
      break;
1131
    case MEP_OPERAND_PCABS24A2 :
1132
      errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_PCABS24A2, (unsigned long *) (& fields->f_24u5a2n));
1133
      break;
1134
    case MEP_OPERAND_PCREL12A2 :
1135
      errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL12A2, (long *) (& fields->f_12s4a2));
1136
      break;
1137
    case MEP_OPERAND_PCREL17A2 :
1138
      errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL17A2, (long *) (& fields->f_17s16a2));
1139
      break;
1140
    case MEP_OPERAND_PCREL24A2 :
1141
      errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL24A2, (long *) (& fields->f_24s5a2n));
1142
      break;
1143
    case MEP_OPERAND_PCREL8A2 :
1144
      errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL8A2, (long *) (& fields->f_8s8a2));
1145
      break;
1146
    case MEP_OPERAND_PSW :
1147
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1148
      break;
1149
    case MEP_OPERAND_R0 :
1150
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1151
      break;
1152
    case MEP_OPERAND_R1 :
1153
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1154
      break;
1155
    case MEP_OPERAND_RL :
1156
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl);
1157
      break;
1158 225 jeremybenn
    case MEP_OPERAND_RL5 :
1159
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl5);
1160
      break;
1161 24 jeremybenn
    case MEP_OPERAND_RM :
1162
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
1163
      break;
1164
    case MEP_OPERAND_RMA :
1165
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
1166
      break;
1167
    case MEP_OPERAND_RN :
1168
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1169
      break;
1170
    case MEP_OPERAND_RN3 :
1171
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1172
      break;
1173
    case MEP_OPERAND_RN3C :
1174
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1175
      break;
1176
    case MEP_OPERAND_RN3L :
1177
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1178
      break;
1179
    case MEP_OPERAND_RN3S :
1180
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1181
      break;
1182
    case MEP_OPERAND_RN3UC :
1183
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1184
      break;
1185
    case MEP_OPERAND_RN3UL :
1186
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1187
      break;
1188
    case MEP_OPERAND_RN3US :
1189
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1190
      break;
1191
    case MEP_OPERAND_RNC :
1192
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1193
      break;
1194
    case MEP_OPERAND_RNL :
1195
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1196
      break;
1197
    case MEP_OPERAND_RNS :
1198
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1199
      break;
1200
    case MEP_OPERAND_RNUC :
1201
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1202
      break;
1203
    case MEP_OPERAND_RNUL :
1204
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1205
      break;
1206
    case MEP_OPERAND_RNUS :
1207
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1208
      break;
1209
    case MEP_OPERAND_SAR :
1210
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1211
      break;
1212
    case MEP_OPERAND_SDISP16 :
1213
      errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SDISP16, (long *) (& fields->f_16s16));
1214
      break;
1215
    case MEP_OPERAND_SIMM16 :
1216
      errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SIMM16, (long *) (& fields->f_16s16));
1217
      break;
1218 225 jeremybenn
    case MEP_OPERAND_SIMM16P0 :
1219
      errmsg = parse_signed16_range (cd, strp, MEP_OPERAND_SIMM16P0, (long *) (& fields->f_ivc2_simm16p0));
1220
      break;
1221 24 jeremybenn
    case MEP_OPERAND_SIMM6 :
1222
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM6, (long *) (& fields->f_6s8));
1223
      break;
1224
    case MEP_OPERAND_SIMM8 :
1225
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8, (long *) (& fields->f_8s8));
1226
      break;
1227 225 jeremybenn
    case MEP_OPERAND_SIMM8P0 :
1228
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P0, (long *) (& fields->f_ivc2_8s0));
1229
      break;
1230
    case MEP_OPERAND_SIMM8P20 :
1231
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P20, (long *) (& fields->f_ivc2_8s20));
1232
      break;
1233
    case MEP_OPERAND_SIMM8P4 :
1234
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P4, (long *) (& fields->f_ivc2_8s4));
1235
      break;
1236 24 jeremybenn
    case MEP_OPERAND_SP :
1237
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1238
      break;
1239
    case MEP_OPERAND_SPR :
1240
      errmsg = parse_spreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1241
      break;
1242
    case MEP_OPERAND_TP :
1243
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1244
      break;
1245
    case MEP_OPERAND_TPR :
1246
      errmsg = parse_tpreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1247
      break;
1248
    case MEP_OPERAND_UDISP2 :
1249
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_UDISP2, (long *) (& fields->f_2u6));
1250
      break;
1251
    case MEP_OPERAND_UDISP7 :
1252
      errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7, (unsigned long *) (& fields->f_7u9));
1253
      break;
1254
    case MEP_OPERAND_UDISP7A2 :
1255
      errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A2, (unsigned long *) (& fields->f_7u9a2));
1256
      break;
1257
    case MEP_OPERAND_UDISP7A4 :
1258
      errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A4, (unsigned long *) (& fields->f_7u9a4));
1259
      break;
1260
    case MEP_OPERAND_UIMM16 :
1261
      errmsg = parse_unsigned16 (cd, strp, MEP_OPERAND_UIMM16, (unsigned long *) (& fields->f_16u16));
1262
      break;
1263
    case MEP_OPERAND_UIMM2 :
1264
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM2, (unsigned long *) (& fields->f_2u10));
1265
      break;
1266
    case MEP_OPERAND_UIMM24 :
1267
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM24, (unsigned long *) (& fields->f_24u8n));
1268
      break;
1269
    case MEP_OPERAND_UIMM3 :
1270
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM3, (unsigned long *) (& fields->f_3u5));
1271
      break;
1272
    case MEP_OPERAND_UIMM4 :
1273
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM4, (unsigned long *) (& fields->f_4u8));
1274
      break;
1275
    case MEP_OPERAND_UIMM5 :
1276
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM5, (unsigned long *) (& fields->f_5u8));
1277
      break;
1278
    case MEP_OPERAND_UIMM7A4 :
1279
      errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_UIMM7A4, (unsigned long *) (& fields->f_7u9a4));
1280
      break;
1281
    case MEP_OPERAND_ZERO :
1282
      errmsg = parse_zero (cd, strp, MEP_OPERAND_ZERO, (long *) (& junk));
1283
      break;
1284
 
1285
    default :
1286
      /* xgettext:c-format */
1287
      fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
1288
      abort ();
1289
  }
1290
 
1291
  return errmsg;
1292
}
1293
 
1294
cgen_parse_fn * const mep_cgen_parse_handlers[] =
1295
{
1296
  parse_insn_normal,
1297
};
1298
 
1299
void
1300
mep_cgen_init_asm (CGEN_CPU_DESC cd)
1301
{
1302
  mep_cgen_init_opcode_table (cd);
1303
  mep_cgen_init_ibld_table (cd);
1304
  cd->parse_handlers = & mep_cgen_parse_handlers[0];
1305
  cd->parse_operand = mep_cgen_parse_operand;
1306
#ifdef CGEN_ASM_INIT_HOOK
1307
CGEN_ASM_INIT_HOOK
1308
#endif
1309
}
1310
 
1311
 
1312
 
1313
/* Regex construction routine.
1314
 
1315
   This translates an opcode syntax string into a regex string,
1316
   by replacing any non-character syntax element (such as an
1317
   opcode) with the pattern '.*'
1318
 
1319
   It then compiles the regex and stores it in the opcode, for
1320
   later use by mep_cgen_assemble_insn
1321
 
1322
   Returns NULL for success, an error message for failure.  */
1323
 
1324
char *
1325
mep_cgen_build_insn_regex (CGEN_INSN *insn)
1326
{
1327
  CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
1328
  const char *mnem = CGEN_INSN_MNEMONIC (insn);
1329
  char rxbuf[CGEN_MAX_RX_ELEMENTS];
1330
  char *rx = rxbuf;
1331
  const CGEN_SYNTAX_CHAR_TYPE *syn;
1332
  int reg_err;
1333
 
1334
  syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
1335
 
1336
  /* Mnemonics come first in the syntax string.  */
1337
  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1338
    return _("missing mnemonic in syntax string");
1339
  ++syn;
1340
 
1341
  /* Generate a case sensitive regular expression that emulates case
1342
     insensitive matching in the "C" locale.  We cannot generate a case
1343
     insensitive regular expression because in Turkish locales, 'i' and 'I'
1344
     are not equal modulo case conversion.  */
1345
 
1346
  /* Copy the literal mnemonic out of the insn.  */
1347
  for (; *mnem; mnem++)
1348
    {
1349
      char c = *mnem;
1350
 
1351
      if (ISALPHA (c))
1352
        {
1353
          *rx++ = '[';
1354
          *rx++ = TOLOWER (c);
1355
          *rx++ = TOUPPER (c);
1356
          *rx++ = ']';
1357
        }
1358
      else
1359
        *rx++ = c;
1360
    }
1361
 
1362
  /* Copy any remaining literals from the syntax string into the rx.  */
1363
  for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
1364
    {
1365
      if (CGEN_SYNTAX_CHAR_P (* syn))
1366
        {
1367
          char c = CGEN_SYNTAX_CHAR (* syn);
1368
 
1369
          switch (c)
1370
            {
1371
              /* Escape any regex metacharacters in the syntax.  */
1372
            case '.': case '[': case '\\':
1373
            case '*': case '^': case '$':
1374
 
1375
#ifdef CGEN_ESCAPE_EXTENDED_REGEX
1376
            case '?': case '{': case '}':
1377
            case '(': case ')': case '*':
1378
            case '|': case '+': case ']':
1379
#endif
1380
              *rx++ = '\\';
1381
              *rx++ = c;
1382
              break;
1383
 
1384
            default:
1385
              if (ISALPHA (c))
1386
                {
1387
                  *rx++ = '[';
1388
                  *rx++ = TOLOWER (c);
1389
                  *rx++ = TOUPPER (c);
1390
                  *rx++ = ']';
1391
                }
1392
              else
1393
                *rx++ = c;
1394
              break;
1395
            }
1396
        }
1397
      else
1398
        {
1399
          /* Replace non-syntax fields with globs.  */
1400
          *rx++ = '.';
1401
          *rx++ = '*';
1402
        }
1403
    }
1404
 
1405
  /* Trailing whitespace ok.  */
1406
  * rx++ = '[';
1407
  * rx++ = ' ';
1408
  * rx++ = '\t';
1409
  * rx++ = ']';
1410
  * rx++ = '*';
1411
 
1412
  /* But anchor it after that.  */
1413
  * rx++ = '$';
1414
  * rx = '\0';
1415
 
1416
  CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
1417
  reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
1418
 
1419
  if (reg_err == 0)
1420
    return NULL;
1421
  else
1422
    {
1423
      static char msg[80];
1424
 
1425
      regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
1426
      regfree ((regex_t *) CGEN_INSN_RX (insn));
1427
      free (CGEN_INSN_RX (insn));
1428
      (CGEN_INSN_RX (insn)) = NULL;
1429
      return msg;
1430
    }
1431
}
1432
 
1433
 
1434
/* Default insn parser.
1435
 
1436
   The syntax string is scanned and operands are parsed and stored in FIELDS.
1437
   Relocs are queued as we go via other callbacks.
1438
 
1439
   ??? Note that this is currently an all-or-nothing parser.  If we fail to
1440
   parse the instruction, we return 0 and the caller will start over from
1441
   the beginning.  Backtracking will be necessary in parsing subexpressions,
1442
   but that can be handled there.  Not handling backtracking here may get
1443
   expensive in the case of the m68k.  Deal with later.
1444
 
1445
   Returns NULL for success, an error message for failure.  */
1446
 
1447
static const char *
1448
parse_insn_normal (CGEN_CPU_DESC cd,
1449
                   const CGEN_INSN *insn,
1450
                   const char **strp,
1451
                   CGEN_FIELDS *fields)
1452
{
1453
  /* ??? Runtime added insns not handled yet.  */
1454
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1455
  const char *str = *strp;
1456
  const char *errmsg;
1457
  const char *p;
1458
  const CGEN_SYNTAX_CHAR_TYPE * syn;
1459
#ifdef CGEN_MNEMONIC_OPERANDS
1460
  /* FIXME: wip */
1461
  int past_opcode_p;
1462
#endif
1463
 
1464
  /* For now we assume the mnemonic is first (there are no leading operands).
1465
     We can parse it without needing to set up operand parsing.
1466
     GAS's input scrubber will ensure mnemonics are lowercase, but we may
1467
     not be called from GAS.  */
1468
  p = CGEN_INSN_MNEMONIC (insn);
1469
  while (*p && TOLOWER (*p) == TOLOWER (*str))
1470
    ++p, ++str;
1471
 
1472
  if (* p)
1473
    return _("unrecognized instruction");
1474
 
1475
#ifndef CGEN_MNEMONIC_OPERANDS
1476
  if (* str && ! ISSPACE (* str))
1477
    return _("unrecognized instruction");
1478
#endif
1479
 
1480
  CGEN_INIT_PARSE (cd);
1481
  cgen_init_parse_operand (cd);
1482
#ifdef CGEN_MNEMONIC_OPERANDS
1483
  past_opcode_p = 0;
1484
#endif
1485
 
1486
  /* We don't check for (*str != '\0') here because we want to parse
1487
     any trailing fake arguments in the syntax string.  */
1488
  syn = CGEN_SYNTAX_STRING (syntax);
1489
 
1490
  /* Mnemonics come first for now, ensure valid string.  */
1491
  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1492
    abort ();
1493
 
1494
  ++syn;
1495
 
1496
  while (* syn != 0)
1497
    {
1498
      /* Non operand chars must match exactly.  */
1499
      if (CGEN_SYNTAX_CHAR_P (* syn))
1500
        {
1501
          /* FIXME: While we allow for non-GAS callers above, we assume the
1502
             first char after the mnemonic part is a space.  */
1503
          /* FIXME: We also take inappropriate advantage of the fact that
1504
             GAS's input scrubber will remove extraneous blanks.  */
1505
          if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
1506
            {
1507
#ifdef CGEN_MNEMONIC_OPERANDS
1508
              if (CGEN_SYNTAX_CHAR(* syn) == ' ')
1509
                past_opcode_p = 1;
1510
#endif
1511
              ++ syn;
1512
              ++ str;
1513
            }
1514
          else if (*str)
1515
            {
1516
              /* Syntax char didn't match.  Can't be this insn.  */
1517
              static char msg [80];
1518
 
1519
              /* xgettext:c-format */
1520
              sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
1521
                       CGEN_SYNTAX_CHAR(*syn), *str);
1522
              return msg;
1523
            }
1524
          else
1525
            {
1526
              /* Ran out of input.  */
1527
              static char msg [80];
1528
 
1529
              /* xgettext:c-format */
1530
              sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
1531
                       CGEN_SYNTAX_CHAR(*syn));
1532
              return msg;
1533
            }
1534
          continue;
1535
        }
1536
 
1537
      /* We have an operand of some sort.  */
1538
      errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
1539
                                          &str, fields);
1540
      if (errmsg)
1541
        return errmsg;
1542
 
1543
      /* Done with this operand, continue with next one.  */
1544
      ++ syn;
1545
    }
1546
 
1547
  /* If we're at the end of the syntax string, we're done.  */
1548
  if (* syn == 0)
1549
    {
1550
      /* FIXME: For the moment we assume a valid `str' can only contain
1551
         blanks now.  IE: We needn't try again with a longer version of
1552
         the insn and it is assumed that longer versions of insns appear
1553
         before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
1554
      while (ISSPACE (* str))
1555
        ++ str;
1556
 
1557
      if (* str != '\0')
1558
        return _("junk at end of line"); /* FIXME: would like to include `str' */
1559
 
1560
      return NULL;
1561
    }
1562
 
1563
  /* We couldn't parse it.  */
1564
  return _("unrecognized instruction");
1565
}
1566
 
1567
/* Main entry point.
1568
   This routine is called for each instruction to be assembled.
1569
   STR points to the insn to be assembled.
1570
   We assume all necessary tables have been initialized.
1571
   The assembled instruction, less any fixups, is stored in BUF.
1572
   Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
1573
   still needs to be converted to target byte order, otherwise BUF is an array
1574
   of bytes in target byte order.
1575
   The result is a pointer to the insn's entry in the opcode table,
1576
   or NULL if an error occured (an error message will have already been
1577
   printed).
1578
 
1579
   Note that when processing (non-alias) macro-insns,
1580
   this function recurses.
1581
 
1582
   ??? It's possible to make this cpu-independent.
1583
   One would have to deal with a few minor things.
1584
   At this point in time doing so would be more of a curiosity than useful
1585
   [for example this file isn't _that_ big], but keeping the possibility in
1586
   mind helps keep the design clean.  */
1587
 
1588
const CGEN_INSN *
1589
mep_cgen_assemble_insn (CGEN_CPU_DESC cd,
1590
                           const char *str,
1591
                           CGEN_FIELDS *fields,
1592
                           CGEN_INSN_BYTES_PTR buf,
1593
                           char **errmsg)
1594
{
1595
  const char *start;
1596
  CGEN_INSN_LIST *ilist;
1597
  const char *parse_errmsg = NULL;
1598
  const char *insert_errmsg = NULL;
1599
  int recognized_mnemonic = 0;
1600
 
1601
  /* Skip leading white space.  */
1602
  while (ISSPACE (* str))
1603
    ++ str;
1604
 
1605
  /* The instructions are stored in hashed lists.
1606
     Get the first in the list.  */
1607
  ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
1608
 
1609
  /* Keep looking until we find a match.  */
1610
  start = str;
1611
  for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1612
    {
1613
      const CGEN_INSN *insn = ilist->insn;
1614
      recognized_mnemonic = 1;
1615
 
1616
#ifdef CGEN_VALIDATE_INSN_SUPPORTED 
1617
      /* Not usually needed as unsupported opcodes
1618
         shouldn't be in the hash lists.  */
1619
      /* Is this insn supported by the selected cpu?  */
1620
      if (! mep_cgen_insn_supported (cd, insn))
1621
        continue;
1622
#endif
1623
      /* If the RELAXED attribute is set, this is an insn that shouldn't be
1624
         chosen immediately.  Instead, it is used during assembler/linker
1625
         relaxation if possible.  */
1626
      if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
1627
        continue;
1628
 
1629
      str = start;
1630
 
1631
      /* Skip this insn if str doesn't look right lexically.  */
1632
      if (CGEN_INSN_RX (insn) != NULL &&
1633
          regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
1634
        continue;
1635
 
1636
      /* Allow parse/insert handlers to obtain length of insn.  */
1637
      CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1638
 
1639
      parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
1640
      if (parse_errmsg != NULL)
1641
        continue;
1642
 
1643
      /* ??? 0 is passed for `pc'.  */
1644
      insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1645
                                                 (bfd_vma) 0);
1646
      if (insert_errmsg != NULL)
1647
        continue;
1648
 
1649
      /* It is up to the caller to actually output the insn and any
1650
         queued relocs.  */
1651
      return insn;
1652
    }
1653
 
1654
  {
1655
    static char errbuf[150];
1656
#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
1657
    const char *tmp_errmsg;
1658
 
1659
    /* If requesting verbose error messages, use insert_errmsg.
1660
       Failing that, use parse_errmsg.  */
1661
    tmp_errmsg = (insert_errmsg ? insert_errmsg :
1662
                  parse_errmsg ? parse_errmsg :
1663
                  recognized_mnemonic ?
1664
                  _("unrecognized form of instruction") :
1665
                  _("unrecognized instruction"));
1666
 
1667
    if (strlen (start) > 50)
1668
      /* xgettext:c-format */
1669
      sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1670
    else
1671
      /* xgettext:c-format */
1672
      sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1673
#else
1674
    if (strlen (start) > 50)
1675
      /* xgettext:c-format */
1676
      sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1677
    else
1678
      /* xgettext:c-format */
1679
      sprintf (errbuf, _("bad instruction `%.50s'"), start);
1680
#endif
1681
 
1682
    *errmsg = errbuf;
1683
    return NULL;
1684
  }
1685
}

powered by: WebSVN 2.1.0

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