Coverage Report

Created: 2025-06-24 06:45

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