Coverage Report

Created: 2023-08-28 06:31

/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-2023 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
0
    return _("invalid %function() here");
309
310
0
  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
311
0
}
312
313
static const char *
314
parse_unsigned16 (CGEN_CPU_DESC cd,
315
      const char **strp,
316
      int opindex,
317
      unsigned long *valuep)
318
0
{
319
0
  return parse_lo16 (cd, strp, opindex, (long *) valuep, 0);
320
0
}
321
322
static const char *
323
parse_signed16_range (CGEN_CPU_DESC cd,
324
          const char **strp,
325
          int opindex,
326
          signed long *valuep)
327
0
{
328
0
  const char *errmsg = 0;
329
0
  signed long value;
330
331
0
  errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
332
0
  if (errmsg)
333
0
    return errmsg;
334
335
0
  if (value < -32768 || value > 32767)
336
0
    return _("Immediate is out of range -32768 to 32767");
337
338
0
  *valuep = value;
339
0
  return 0;
340
0
}
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
0
{
348
0
  const char *errmsg = 0;
349
0
  unsigned long value;
350
351
0
  errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
352
0
  if (errmsg)
353
0
    return errmsg;
354
355
0
  if (value > 65535)
356
0
    return _("Immediate is out of range 0 to 65535");
357
358
0
  *valuep = value;
359
0
  return 0;
360
0
}
361
362
/* 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
0
{
367
0
  const char *errmsg;
368
0
  enum cgen_parse_operand_result result_type;
369
0
  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
0
  if (strncmp (*strp, "($", 2) == 0)
377
0
    return "not zero"; /* any string will do -- will never be seen.  */
378
379
0
  if (strncasecmp (*strp, "%lo(", 4) == 0)
380
0
    {
381
0
      *strp += 4;
382
0
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
383
0
           &result_type, &value);
384
0
      if (**strp != ')')
385
0
  return "missing `)'";
386
0
      ++*strp;
387
0
      if (errmsg == NULL
388
0
    && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
389
0
  return "not zero"; /* any string will do -- will never be seen.  */
390
0
      *valuep = value;
391
0
      return errmsg;
392
0
    }
393
394
0
  if (strncasecmp (*strp, "%hi(", 4) == 0)
395
0
    {
396
0
      *strp += 4;
397
0
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
398
0
           &result_type, &value);
399
0
      if (**strp != ')')
400
0
  return "missing `)'";
401
0
      ++*strp;
402
0
      if (errmsg == NULL
403
0
    && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
404
0
  return "not zero"; /* any string will do -- will never be seen.  */
405
0
      *valuep = value;
406
0
      return errmsg;
407
0
    }
408
409
0
  if (strncasecmp (*strp, "%uhi(", 5) == 0)
410
0
    {
411
0
      *strp += 5;
412
0
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
413
0
           &result_type, &value);
414
0
      if (**strp != ')')
415
0
  return "missing `)'";
416
0
      ++*strp;
417
0
      if (errmsg == NULL
418
0
    && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
419
0
  return "not zero"; /* any string will do -- will never be seen.  */
420
0
      *valuep = value;
421
0
      return errmsg;
422
0
    }
423
424
0
  if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
425
0
    {
426
0
      *strp += 8;
427
0
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
428
0
           &result_type, &value);
429
0
      if (**strp != ')')
430
0
  return "missing `)'";
431
0
      ++*strp;
432
0
      if (errmsg == NULL
433
0
    && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
434
0
  return "not zero"; /* any string will do -- will never be seen.  */
435
0
      *valuep = value;
436
0
      return errmsg;
437
0
    }
438
439
0
  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
440
0
    {
441
0
      *strp += 7;
442
0
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
443
0
           &result_type, &value);
444
0
      if (**strp != ')')
445
0
  return "missing `)'";
446
0
      ++*strp;
447
0
      if (errmsg == NULL
448
0
    && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
449
0
  return "not zero"; /* any string will do -- will never be seen.  */
450
0
      *valuep = value;
451
0
      return errmsg;
452
0
    }
453
454
0
  if (**strp == '%')
455
0
    return "invalid %function() here";
456
457
0
  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_NONE,
458
0
             &result_type, &value);
459
0
  if (errmsg == NULL
460
0
      && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
461
0
    return "not zero"; /* any string will do -- will never be seen.  */
462
463
0
  return errmsg;
464
0
}
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
0
{
470
0
  const char *errmsg;
471
0
  bfd_vma value;
472
473
  /* fprintf(stderr, "dj: unsigned7 parse `%s'\n", *strp); */
474
475
0
  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
476
0
    {
477
0
      int reloc;
478
0
      *strp += 7;
479
0
      switch (opindex)
480
0
  {
481
0
  case MEP_OPERAND_UDISP7:
482
0
    reloc = BFD_RELOC_MEP_TPREL7;
483
0
    break;
484
0
  case MEP_OPERAND_UDISP7A2:
485
0
    reloc = BFD_RELOC_MEP_TPREL7A2;
486
0
    break;
487
0
  case MEP_OPERAND_UDISP7A4:
488
0
    reloc = BFD_RELOC_MEP_TPREL7A4;
489
0
    break;
490
0
  default:
491
    /* Safe assumption?  */
492
0
    abort ();
493
0
  }
494
0
      errmsg = cgen_parse_address (cd, strp, opindex, reloc,
495
0
           NULL, &value);
496
0
      if (**strp != ')')
497
0
  return "missing `)'";
498
0
      ++*strp;
499
0
      *valuep = value;
500
0
      return errmsg;
501
0
    }
502
503
0
  if (**strp == '%')
504
0
    return _("invalid %function() here");
505
506
0
  return parse_mep_alignu (cd, strp, opindex, valuep);
507
0
}
508
509
static ATTRIBUTE_UNUSED const char *
510
parse_cdisp10 (CGEN_CPU_DESC cd,
511
         const char **strp,
512
         int opindex,
513
         long *valuep)
514
0
{
515
0
  const char *errmsg = 0;
516
0
  signed long value;
517
0
  long have_zero = 0;
518
0
  int wide = 0;
519
0
  int alignment;
520
521
0
  switch (opindex)
522
0
    {
523
0
    case MEP_OPERAND_CDISP10A4:
524
0
      alignment = 2;
525
0
      break;
526
0
    case MEP_OPERAND_CDISP10A2:
527
0
      alignment = 1;
528
0
      break;
529
0
    case MEP_OPERAND_CDISP10:
530
0
    default:
531
0
      alignment = 0;
532
0
      break;
533
0
    }
534
535
0
  if ((MEP_CPU & EF_MEP_CPU_MASK) == EF_MEP_CPU_C5)
536
0
    wide = 1;
537
538
0
  if (strncmp (*strp, "0x0", 3) == 0
539
0
      || (**strp == '0' && *(*strp + 1) != 'x'))
540
0
    have_zero = 1;
541
542
0
  errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
543
0
  if (errmsg)
544
0
    return errmsg;
545
546
0
  if (wide)
547
0
    {
548
0
      if (value < -512 || value > 511)
549
0
  return _("Immediate is out of range -512 to 511");
550
0
    }
551
0
  else
552
0
    {
553
0
      if (value < -128 || value > 127)
554
0
  return _("Immediate is out of range -128 to 127");
555
0
    }
556
557
0
  if (value & ((1<<alignment)-1))
558
0
    return _("Value is not aligned enough");
559
560
  /* If this field may require a relocation then use larger dsp16.  */
561
0
  if (! have_zero && value == 0)
562
0
    return (wide ? _("Immediate is out of range -512 to 511")
563
0
      : _("Immediate is out of range -128 to 127"));
564
565
0
  *valuep = value;
566
0
  return 0;
567
0
}
568
569
/* BEGIN LIGHTWEIGHT MACRO PROCESSOR.  */
570
571
0
#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
static macro const 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
0
{
606
0
  char *new_dest;
607
0
  int oldlen;
608
609
0
  if (len == 0)
610
0
    return dest;
611
  /* printf("str_append: <<%s>>, <<%s>>, %d\n", dest, input, len); */
612
0
  oldlen = (dest ? strlen(dest) : 0);
613
0
  new_dest = realloc (dest, oldlen + len + 1);
614
0
  memset (new_dest + oldlen, 0, len + 1);
615
0
  return strncat (new_dest, input, len);
616
0
}
617
618
static const macro *
619
lookup_macro (const char *name)
620
0
{
621
0
  const macro *m;
622
623
0
  for (m = macros; m->name; ++m)
624
0
    if (strncmp (m->name, name, strlen(m->name)) == 0)
625
0
      return m;
626
627
0
  return 0;
628
0
}
629
630
static char *
631
expand_macro (arg *args, int narg, const macro *mac)
632
0
{
633
0
  char *result = 0, *rescanned_result = 0;
634
0
  char *e = mac->expansion;
635
0
  char *mark = e;
636
0
  int mac_arg = 0;
637
638
  /*  printf("expanding macro %s with %d args\n", mac->name, narg + 1); */
639
0
  while (*e)
640
0
    {
641
0
      if (*e == '`'
642
0
    && (*e+1)
643
0
    && ((*(e + 1) - '1') <= MAXARGS)
644
0
    && ((*(e + 1) - '1') <= narg))
645
0
  {
646
0
    result = str_append (result, mark, e - mark);
647
0
    mac_arg = (*(e + 1) - '1');
648
    /* printf("replacing `%d with %s\n", mac_arg+1, args[mac_arg].start); */
649
0
    result = str_append (result, args[mac_arg].start, args[mac_arg].len);
650
0
    ++e;
651
0
    mark = e+1;
652
0
  }
653
0
      ++e;
654
0
    }
655
656
0
  if (mark != e)
657
0
    result = str_append (result, mark, e - mark);
658
659
0
  if (result)
660
0
    {
661
0
      rescanned_result = expand_string (result, 0);
662
0
      free (result);
663
0
      return rescanned_result;
664
0
    }
665
0
  else
666
0
    return result;
667
0
}
668
669
0
#define IN_TEXT 0
670
0
#define IN_ARGS 1
671
672
static char *
673
expand_string (const char *in, int first_only)
674
0
{
675
0
  int num_expansions = 0;
676
0
  int depth = 0;
677
0
  int narg = -1;
678
0
  arg args[MAXARGS];
679
0
  int state = IN_TEXT;
680
0
  const char *mark = in;
681
0
  const macro *pmacro = NULL;
682
0
  char *expansion = 0;
683
0
  char *result = 0;
684
685
0
  while (*in)
686
0
    {
687
0
      switch (state)
688
0
  {
689
0
  case IN_TEXT:
690
0
    if (*in == '%' && *(in + 1) && (!first_only || num_expansions == 0))
691
0
      {
692
0
        pmacro = lookup_macro (in + 1);
693
0
        if (pmacro)
694
0
    {
695
      /* printf("entering state %d at '%s'...\n", state, in); */
696
0
      result = str_append (result, mark, in - mark);
697
0
      mark = in;
698
0
      in += 1 + strlen (pmacro->name);
699
0
      while (*in == ' ') ++in;
700
0
      if (*in != '(')
701
0
        {
702
0
          state = IN_TEXT;
703
0
          pmacro = NULL;
704
0
        }
705
0
      else
706
0
        {
707
0
          state = IN_ARGS;
708
0
          narg = 0;
709
0
          args[narg].start = in + 1;
710
0
          args[narg].len = 0;
711
0
          mark = in + 1;
712
0
        }
713
0
    }
714
0
      }
715
0
    break;
716
0
  case IN_ARGS:
717
0
    if (depth == 0)
718
0
      {
719
0
        switch (*in)
720
0
    {
721
0
    case ',':
722
0
      narg++;
723
0
      args[narg].start = (in + 1);
724
0
      args[narg].len = 0;
725
0
      break;
726
0
    case ')':
727
0
      state = IN_TEXT;
728
      /* printf("entering state %d at '%s'...\n", state, in); */
729
0
      if (pmacro)
730
0
        {
731
0
          expansion = 0;
732
0
          expansion = expand_macro (args, narg, pmacro);
733
0
          num_expansions++;
734
0
          if (expansion)
735
0
      {
736
0
        result = str_append (result, expansion, strlen (expansion));
737
0
        free (expansion);
738
0
      }
739
0
        }
740
0
      else
741
0
        {
742
0
          result = str_append (result, mark, in - mark);
743
0
        }
744
0
      pmacro = NULL;
745
0
      mark = in + 1;
746
0
      break;
747
0
    case '(':
748
0
      depth++;
749
      /* Fall through.  */
750
0
    default:
751
0
      args[narg].len++;
752
0
      break;
753
0
    }
754
0
      }
755
0
    else
756
0
      {
757
0
        if (*in == ')')
758
0
    depth--;
759
0
        if (narg > -1)
760
0
    args[narg].len++;
761
0
      }
762
0
  }
763
0
      ++in;
764
0
    }
765
766
0
  if (mark != in)
767
0
    result = str_append (result, mark, in - mark);
768
769
0
  return result;
770
0
}
771
772
#undef IN_ARGS
773
#undef IN_TEXT
774
#undef MAXARGS
775
776
777
/* END LIGHTWEIGHT MACRO PROCESSOR.  */
778
779
const char * mep_cgen_parse_operand
780
  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
781
782
const char *
783
mep_cgen_expand_macros_and_parse_operand (CGEN_CPU_DESC cd, int opindex,
784
            const char ** strp_in, CGEN_FIELDS * fields)
785
0
{
786
0
  const char * errmsg = NULL;
787
0
  char *str = 0, *hold = 0;
788
0
  const char **strp = 0;
789
790
  /* Set up a new pointer to macro-expanded string.  */
791
0
  str = expand_string (*strp_in, 1);
792
  /* fprintf (stderr, " expanded <<%s>> to <<%s>>\n", *strp_in, str); */
793
794
0
  hold = str;
795
0
  strp = (const char **)(&str);
796
797
0
  errmsg = mep_cgen_parse_operand (cd, opindex, strp, fields);
798
799
  /* Now work out the advance.  */
800
0
  if (strlen (str) == 0)
801
0
    *strp_in += strlen (*strp_in);
802
803
0
  else
804
0
    {
805
0
      if (strstr (*strp_in, str))
806
  /* A macro-expansion was pulled off the front.  */
807
0
  *strp_in = strstr (*strp_in, str);
808
0
      else
809
  /* A non-macro-expansion was pulled off the front.  */
810
0
  *strp_in += (str - hold);
811
0
    }
812
813
0
  free (hold);
814
815
0
  return errmsg;
816
0
}
817
818
0
#define CGEN_ASM_INIT_HOOK (cd->parse_operand = mep_cgen_expand_macros_and_parse_operand);
819
820
/* -- dis.c */
821
822
const char * mep_cgen_parse_operand
823
  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
824
825
/* Main entry point for operand parsing.
826
827
   This function is basically just a big switch statement.  Earlier versions
828
   used tables to look up the function to use, but
829
   - if the table contains both assembler and disassembler functions then
830
     the disassembler contains much of the assembler and vice-versa,
831
   - there's a lot of inlining possibilities as things grow,
832
   - using a switch statement avoids the function call overhead.
833
834
   This function could be moved into `parse_insn_normal', but keeping it
835
   separate makes clear the interface between `parse_insn_normal' and each of
836
   the handlers.  */
837
838
const char *
839
mep_cgen_parse_operand (CGEN_CPU_DESC cd,
840
         int opindex,
841
         const char ** strp,
842
         CGEN_FIELDS * fields)
843
0
{
844
0
  const char * errmsg = NULL;
845
  /* Used by scalar operands that still need to be parsed.  */
846
0
  long junk ATTRIBUTE_UNUSED;
847
848
0
  switch (opindex)
849
0
    {
850
0
    case MEP_OPERAND_ADDR24A4 :
851
0
      errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_ADDR24A4, (unsigned long *) (& fields->f_24u8a4n));
852
0
      break;
853
0
    case MEP_OPERAND_C5RMUIMM20 :
854
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RMUIMM20, (unsigned long *) (& fields->f_c5_rmuimm20));
855
0
      break;
856
0
    case MEP_OPERAND_C5RNMUIMM24 :
857
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RNMUIMM24, (unsigned long *) (& fields->f_c5_rnmuimm24));
858
0
      break;
859
0
    case MEP_OPERAND_CALLNUM :
860
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CALLNUM, (unsigned long *) (& fields->f_callnum));
861
0
      break;
862
0
    case MEP_OPERAND_CCCC :
863
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CCCC, (unsigned long *) (& fields->f_rm));
864
0
      break;
865
0
    case MEP_OPERAND_CCRN :
866
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & fields->f_ccrn);
867
0
      break;
868
0
    case MEP_OPERAND_CDISP10 :
869
0
      errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10, (long *) (& fields->f_cdisp10));
870
0
      break;
871
0
    case MEP_OPERAND_CDISP10A2 :
872
0
      errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A2, (long *) (& fields->f_cdisp10));
873
0
      break;
874
0
    case MEP_OPERAND_CDISP10A4 :
875
0
      errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A4, (long *) (& fields->f_cdisp10));
876
0
      break;
877
0
    case MEP_OPERAND_CDISP10A8 :
878
0
      errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A8, (long *) (& fields->f_cdisp10));
879
0
      break;
880
0
    case MEP_OPERAND_CDISP12 :
881
0
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_CDISP12, (long *) (& fields->f_12s20));
882
0
      break;
883
0
    case MEP_OPERAND_CIMM4 :
884
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM4, (unsigned long *) (& fields->f_rn));
885
0
      break;
886
0
    case MEP_OPERAND_CIMM5 :
887
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM5, (unsigned long *) (& fields->f_5u24));
888
0
      break;
889
0
    case MEP_OPERAND_CODE16 :
890
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE16, (unsigned long *) (& fields->f_16u16));
891
0
      break;
892
0
    case MEP_OPERAND_CODE24 :
893
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE24, (unsigned long *) (& fields->f_24u4n));
894
0
      break;
895
0
    case MEP_OPERAND_CP_FLAG :
896
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & junk);
897
0
      break;
898
0
    case MEP_OPERAND_CRN :
899
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crn);
900
0
      break;
901
0
    case MEP_OPERAND_CRN64 :
902
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crn);
903
0
      break;
904
0
    case MEP_OPERAND_CRNX :
905
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crnx);
906
0
      break;
907
0
    case MEP_OPERAND_CRNX64 :
908
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crnx);
909
0
      break;
910
0
    case MEP_OPERAND_CROC :
911
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u7);
912
0
      break;
913
0
    case MEP_OPERAND_CROP :
914
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u23);
915
0
      break;
916
0
    case MEP_OPERAND_CRPC :
917
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u26);
918
0
      break;
919
0
    case MEP_OPERAND_CRPP :
920
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u18);
921
0
      break;
922
0
    case MEP_OPERAND_CRQC :
923
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u21);
924
0
      break;
925
0
    case MEP_OPERAND_CRQP :
926
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u13);
927
0
      break;
928
0
    case MEP_OPERAND_CSRN :
929
0
      errmsg = parse_csrn (cd, strp, & mep_cgen_opval_h_csr, & fields->f_csrn);
930
0
      break;
931
0
    case MEP_OPERAND_CSRN_IDX :
932
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, (unsigned long *) (& fields->f_csrn));
933
0
      break;
934
0
    case MEP_OPERAND_DBG :
935
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
936
0
      break;
937
0
    case MEP_OPERAND_DEPC :
938
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
939
0
      break;
940
0
    case MEP_OPERAND_EPC :
941
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
942
0
      break;
943
0
    case MEP_OPERAND_EXC :
944
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
945
0
      break;
946
0
    case MEP_OPERAND_HI :
947
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
948
0
      break;
949
0
    case MEP_OPERAND_IMM16P0 :
950
0
      errmsg = parse_unsigned16_range (cd, strp, MEP_OPERAND_IMM16P0, (unsigned long *) (& fields->f_ivc2_imm16p0));
951
0
      break;
952
0
    case MEP_OPERAND_IMM3P12 :
953
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P12, (unsigned long *) (& fields->f_ivc2_3u12));
954
0
      break;
955
0
    case MEP_OPERAND_IMM3P25 :
956
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P25, (unsigned long *) (& fields->f_ivc2_3u25));
957
0
      break;
958
0
    case MEP_OPERAND_IMM3P4 :
959
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P4, (unsigned long *) (& fields->f_ivc2_3u4));
960
0
      break;
961
0
    case MEP_OPERAND_IMM3P5 :
962
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P5, (unsigned long *) (& fields->f_ivc2_3u5));
963
0
      break;
964
0
    case MEP_OPERAND_IMM3P9 :
965
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P9, (unsigned long *) (& fields->f_ivc2_3u9));
966
0
      break;
967
0
    case MEP_OPERAND_IMM4P10 :
968
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P10, (unsigned long *) (& fields->f_ivc2_4u10));
969
0
      break;
970
0
    case MEP_OPERAND_IMM4P4 :
971
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P4, (unsigned long *) (& fields->f_ivc2_4u4));
972
0
      break;
973
0
    case MEP_OPERAND_IMM4P8 :
974
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P8, (unsigned long *) (& fields->f_ivc2_4u8));
975
0
      break;
976
0
    case MEP_OPERAND_IMM5P23 :
977
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P23, (unsigned long *) (& fields->f_ivc2_5u23));
978
0
      break;
979
0
    case MEP_OPERAND_IMM5P3 :
980
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P3, (unsigned long *) (& fields->f_ivc2_5u3));
981
0
      break;
982
0
    case MEP_OPERAND_IMM5P7 :
983
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P7, (unsigned long *) (& fields->f_ivc2_5u7));
984
0
      break;
985
0
    case MEP_OPERAND_IMM5P8 :
986
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P8, (unsigned long *) (& fields->f_ivc2_5u8));
987
0
      break;
988
0
    case MEP_OPERAND_IMM6P2 :
989
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM6P2, (unsigned long *) (& fields->f_ivc2_6u2));
990
0
      break;
991
0
    case MEP_OPERAND_IMM6P6 :
992
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM6P6, (unsigned long *) (& fields->f_ivc2_6u6));
993
0
      break;
994
0
    case MEP_OPERAND_IMM8P0 :
995
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P0, (unsigned long *) (& fields->f_ivc2_8u0));
996
0
      break;
997
0
    case MEP_OPERAND_IMM8P20 :
998
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P20, (unsigned long *) (& fields->f_ivc2_8u20));
999
0
      break;
1000
0
    case MEP_OPERAND_IMM8P4 :
1001
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P4, (unsigned long *) (& fields->f_ivc2_8u4));
1002
0
      break;
1003
0
    case MEP_OPERAND_IVC_X_0_2 :
1004
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_2, (unsigned long *) (& fields->f_ivc2_2u0));
1005
0
      break;
1006
0
    case MEP_OPERAND_IVC_X_0_3 :
1007
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_3, (unsigned long *) (& fields->f_ivc2_3u0));
1008
0
      break;
1009
0
    case MEP_OPERAND_IVC_X_0_4 :
1010
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_4, (unsigned long *) (& fields->f_ivc2_4u0));
1011
0
      break;
1012
0
    case MEP_OPERAND_IVC_X_0_5 :
1013
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_5, (unsigned long *) (& fields->f_ivc2_5u0));
1014
0
      break;
1015
0
    case MEP_OPERAND_IVC_X_6_1 :
1016
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_1, (unsigned long *) (& fields->f_ivc2_1u6));
1017
0
      break;
1018
0
    case MEP_OPERAND_IVC_X_6_2 :
1019
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_2, (unsigned long *) (& fields->f_ivc2_2u6));
1020
0
      break;
1021
0
    case MEP_OPERAND_IVC_X_6_3 :
1022
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_3, (unsigned long *) (& fields->f_ivc2_3u6));
1023
0
      break;
1024
0
    case MEP_OPERAND_IVC2_ACC0_0 :
1025
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1026
0
      break;
1027
0
    case MEP_OPERAND_IVC2_ACC0_1 :
1028
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1029
0
      break;
1030
0
    case MEP_OPERAND_IVC2_ACC0_2 :
1031
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1032
0
      break;
1033
0
    case MEP_OPERAND_IVC2_ACC0_3 :
1034
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1035
0
      break;
1036
0
    case MEP_OPERAND_IVC2_ACC0_4 :
1037
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1038
0
      break;
1039
0
    case MEP_OPERAND_IVC2_ACC0_5 :
1040
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1041
0
      break;
1042
0
    case MEP_OPERAND_IVC2_ACC0_6 :
1043
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1044
0
      break;
1045
0
    case MEP_OPERAND_IVC2_ACC0_7 :
1046
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1047
0
      break;
1048
0
    case MEP_OPERAND_IVC2_ACC1_0 :
1049
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1050
0
      break;
1051
0
    case MEP_OPERAND_IVC2_ACC1_1 :
1052
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1053
0
      break;
1054
0
    case MEP_OPERAND_IVC2_ACC1_2 :
1055
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1056
0
      break;
1057
0
    case MEP_OPERAND_IVC2_ACC1_3 :
1058
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1059
0
      break;
1060
0
    case MEP_OPERAND_IVC2_ACC1_4 :
1061
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1062
0
      break;
1063
0
    case MEP_OPERAND_IVC2_ACC1_5 :
1064
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1065
0
      break;
1066
0
    case MEP_OPERAND_IVC2_ACC1_6 :
1067
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1068
0
      break;
1069
0
    case MEP_OPERAND_IVC2_ACC1_7 :
1070
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1071
0
      break;
1072
0
    case MEP_OPERAND_IVC2_CC :
1073
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1074
0
      break;
1075
0
    case MEP_OPERAND_IVC2_COFA0 :
1076
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1077
0
      break;
1078
0
    case MEP_OPERAND_IVC2_COFA1 :
1079
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1080
0
      break;
1081
0
    case MEP_OPERAND_IVC2_COFR0 :
1082
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1083
0
      break;
1084
0
    case MEP_OPERAND_IVC2_COFR1 :
1085
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1086
0
      break;
1087
0
    case MEP_OPERAND_IVC2_CSAR0 :
1088
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1089
0
      break;
1090
0
    case MEP_OPERAND_IVC2_CSAR1 :
1091
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
1092
0
      break;
1093
0
    case MEP_OPERAND_IVC2C3CCRN :
1094
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & fields->f_ivc2_ccrn_c3);
1095
0
      break;
1096
0
    case MEP_OPERAND_IVC2CCRN :
1097
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & fields->f_ivc2_ccrn);
1098
0
      break;
1099
0
    case MEP_OPERAND_IVC2CRN :
1100
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_crnx);
1101
0
      break;
1102
0
    case MEP_OPERAND_IVC2RM :
1103
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_ivc2_crm);
1104
0
      break;
1105
0
    case MEP_OPERAND_LO :
1106
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1107
0
      break;
1108
0
    case MEP_OPERAND_LP :
1109
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1110
0
      break;
1111
0
    case MEP_OPERAND_MB0 :
1112
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1113
0
      break;
1114
0
    case MEP_OPERAND_MB1 :
1115
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1116
0
      break;
1117
0
    case MEP_OPERAND_ME0 :
1118
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1119
0
      break;
1120
0
    case MEP_OPERAND_ME1 :
1121
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1122
0
      break;
1123
0
    case MEP_OPERAND_NPC :
1124
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1125
0
      break;
1126
0
    case MEP_OPERAND_OPT :
1127
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1128
0
      break;
1129
0
    case MEP_OPERAND_PCABS24A2 :
1130
0
      errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_PCABS24A2, (unsigned long *) (& fields->f_24u5a2n));
1131
0
      break;
1132
0
    case MEP_OPERAND_PCREL12A2 :
1133
0
      errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL12A2, (long *) (& fields->f_12s4a2));
1134
0
      break;
1135
0
    case MEP_OPERAND_PCREL17A2 :
1136
0
      errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL17A2, (long *) (& fields->f_17s16a2));
1137
0
      break;
1138
0
    case MEP_OPERAND_PCREL24A2 :
1139
0
      errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL24A2, (long *) (& fields->f_24s5a2n));
1140
0
      break;
1141
0
    case MEP_OPERAND_PCREL8A2 :
1142
0
      errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL8A2, (long *) (& fields->f_8s8a2));
1143
0
      break;
1144
0
    case MEP_OPERAND_PSW :
1145
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1146
0
      break;
1147
0
    case MEP_OPERAND_R0 :
1148
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1149
0
      break;
1150
0
    case MEP_OPERAND_R1 :
1151
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1152
0
      break;
1153
0
    case MEP_OPERAND_RL :
1154
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl);
1155
0
      break;
1156
0
    case MEP_OPERAND_RL5 :
1157
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl5);
1158
0
      break;
1159
0
    case MEP_OPERAND_RM :
1160
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
1161
0
      break;
1162
0
    case MEP_OPERAND_RMA :
1163
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
1164
0
      break;
1165
0
    case MEP_OPERAND_RN :
1166
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1167
0
      break;
1168
0
    case MEP_OPERAND_RN3 :
1169
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1170
0
      break;
1171
0
    case MEP_OPERAND_RN3C :
1172
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1173
0
      break;
1174
0
    case MEP_OPERAND_RN3L :
1175
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1176
0
      break;
1177
0
    case MEP_OPERAND_RN3S :
1178
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1179
0
      break;
1180
0
    case MEP_OPERAND_RN3UC :
1181
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1182
0
      break;
1183
0
    case MEP_OPERAND_RN3UL :
1184
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1185
0
      break;
1186
0
    case MEP_OPERAND_RN3US :
1187
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1188
0
      break;
1189
0
    case MEP_OPERAND_RNC :
1190
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1191
0
      break;
1192
0
    case MEP_OPERAND_RNL :
1193
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1194
0
      break;
1195
0
    case MEP_OPERAND_RNS :
1196
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1197
0
      break;
1198
0
    case MEP_OPERAND_RNUC :
1199
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1200
0
      break;
1201
0
    case MEP_OPERAND_RNUL :
1202
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1203
0
      break;
1204
0
    case MEP_OPERAND_RNUS :
1205
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1206
0
      break;
1207
0
    case MEP_OPERAND_SAR :
1208
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1209
0
      break;
1210
0
    case MEP_OPERAND_SDISP16 :
1211
0
      errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SDISP16, (long *) (& fields->f_16s16));
1212
0
      break;
1213
0
    case MEP_OPERAND_SIMM16 :
1214
0
      errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SIMM16, (long *) (& fields->f_16s16));
1215
0
      break;
1216
0
    case MEP_OPERAND_SIMM16P0 :
1217
0
      errmsg = parse_signed16_range (cd, strp, MEP_OPERAND_SIMM16P0, (long *) (& fields->f_ivc2_simm16p0));
1218
0
      break;
1219
0
    case MEP_OPERAND_SIMM6 :
1220
0
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM6, (long *) (& fields->f_6s8));
1221
0
      break;
1222
0
    case MEP_OPERAND_SIMM8 :
1223
0
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8, (long *) (& fields->f_8s8));
1224
0
      break;
1225
0
    case MEP_OPERAND_SIMM8P0 :
1226
0
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P0, (long *) (& fields->f_ivc2_8s0));
1227
0
      break;
1228
0
    case MEP_OPERAND_SIMM8P20 :
1229
0
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P20, (long *) (& fields->f_ivc2_8s20));
1230
0
      break;
1231
0
    case MEP_OPERAND_SIMM8P4 :
1232
0
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P4, (long *) (& fields->f_ivc2_8s4));
1233
0
      break;
1234
0
    case MEP_OPERAND_SP :
1235
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1236
0
      break;
1237
0
    case MEP_OPERAND_SPR :
1238
0
      errmsg = parse_spreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1239
0
      break;
1240
0
    case MEP_OPERAND_TP :
1241
0
      errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1242
0
      break;
1243
0
    case MEP_OPERAND_TPR :
1244
0
      errmsg = parse_tpreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1245
0
      break;
1246
0
    case MEP_OPERAND_UDISP2 :
1247
0
      errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_UDISP2, (long *) (& fields->f_2u6));
1248
0
      break;
1249
0
    case MEP_OPERAND_UDISP7 :
1250
0
      errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7, (unsigned long *) (& fields->f_7u9));
1251
0
      break;
1252
0
    case MEP_OPERAND_UDISP7A2 :
1253
0
      errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A2, (unsigned long *) (& fields->f_7u9a2));
1254
0
      break;
1255
0
    case MEP_OPERAND_UDISP7A4 :
1256
0
      errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A4, (unsigned long *) (& fields->f_7u9a4));
1257
0
      break;
1258
0
    case MEP_OPERAND_UIMM16 :
1259
0
      errmsg = parse_unsigned16 (cd, strp, MEP_OPERAND_UIMM16, (unsigned long *) (& fields->f_16u16));
1260
0
      break;
1261
0
    case MEP_OPERAND_UIMM2 :
1262
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM2, (unsigned long *) (& fields->f_2u10));
1263
0
      break;
1264
0
    case MEP_OPERAND_UIMM24 :
1265
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM24, (unsigned long *) (& fields->f_24u8n));
1266
0
      break;
1267
0
    case MEP_OPERAND_UIMM3 :
1268
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM3, (unsigned long *) (& fields->f_3u5));
1269
0
      break;
1270
0
    case MEP_OPERAND_UIMM4 :
1271
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM4, (unsigned long *) (& fields->f_4u8));
1272
0
      break;
1273
0
    case MEP_OPERAND_UIMM5 :
1274
0
      errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM5, (unsigned long *) (& fields->f_5u8));
1275
0
      break;
1276
0
    case MEP_OPERAND_UIMM7A4 :
1277
0
      errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_UIMM7A4, (unsigned long *) (& fields->f_7u9a4));
1278
0
      break;
1279
0
    case MEP_OPERAND_ZERO :
1280
0
      errmsg = parse_zero (cd, strp, MEP_OPERAND_ZERO, (long *) (& junk));
1281
0
      break;
1282
1283
0
    default :
1284
      /* xgettext:c-format */
1285
0
      opcodes_error_handler
1286
0
  (_("internal error: unrecognized field %d while parsing"),
1287
0
   opindex);
1288
0
      abort ();
1289
0
  }
1290
1291
0
  return errmsg;
1292
0
}
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
0
{
1302
0
  mep_cgen_init_opcode_table (cd);
1303
0
  mep_cgen_init_ibld_table (cd);
1304
0
  cd->parse_handlers = & mep_cgen_parse_handlers[0];
1305
0
  cd->parse_operand = mep_cgen_parse_operand;
1306
0
#ifdef CGEN_ASM_INIT_HOOK
1307
0
CGEN_ASM_INIT_HOOK
1308
0
#endif
1309
0
}
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
5.56k
{
1327
5.56k
  CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
1328
5.56k
  const char *mnem = CGEN_INSN_MNEMONIC (insn);
1329
5.56k
  char rxbuf[CGEN_MAX_RX_ELEMENTS];
1330
5.56k
  char *rx = rxbuf;
1331
5.56k
  const CGEN_SYNTAX_CHAR_TYPE *syn;
1332
5.56k
  int reg_err;
1333
1334
5.56k
  syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
1335
1336
  /* Mnemonics come first in the syntax string.  */
1337
5.56k
  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1338
6
    return _("missing mnemonic in syntax string");
1339
5.55k
  ++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
52.2k
  for (; *mnem; mnem++)
1348
46.6k
    {
1349
46.6k
      char c = *mnem;
1350
1351
46.6k
      if (ISALPHA (c))
1352
39.2k
  {
1353
39.2k
    *rx++ = '[';
1354
39.2k
    *rx++ = TOLOWER (c);
1355
39.2k
    *rx++ = TOUPPER (c);
1356
39.2k
    *rx++ = ']';
1357
39.2k
  }
1358
7.41k
      else
1359
7.41k
  *rx++ = c;
1360
46.6k
    }
1361
1362
  /* Copy any remaining literals from the syntax string into the rx.  */
1363
31.0k
  for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
1364
25.5k
    {
1365
25.5k
      if (CGEN_SYNTAX_CHAR_P (* syn))
1366
13.5k
  {
1367
13.5k
    char c = CGEN_SYNTAX_CHAR (* syn);
1368
1369
13.5k
    switch (c)
1370
13.5k
      {
1371
        /* Escape any regex metacharacters in the syntax.  */
1372
0
      case '.': case '[': case '\\':
1373
96
      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
96
        *rx++ = '\\';
1381
96
        *rx++ = c;
1382
96
        break;
1383
1384
13.4k
      default:
1385
13.4k
        if (ISALPHA (c))
1386
72
    {
1387
72
      *rx++ = '[';
1388
72
      *rx++ = TOLOWER (c);
1389
72
      *rx++ = TOUPPER (c);
1390
72
      *rx++ = ']';
1391
72
    }
1392
13.3k
        else
1393
13.3k
    *rx++ = c;
1394
13.4k
        break;
1395
13.5k
      }
1396
13.5k
  }
1397
12.0k
      else
1398
12.0k
  {
1399
    /* Replace non-syntax fields with globs.  */
1400
12.0k
    *rx++ = '.';
1401
12.0k
    *rx++ = '*';
1402
12.0k
  }
1403
25.5k
    }
1404
1405
  /* Trailing whitespace ok.  */
1406
5.55k
  * rx++ = '[';
1407
5.55k
  * rx++ = ' ';
1408
5.55k
  * rx++ = '\t';
1409
5.55k
  * rx++ = ']';
1410
5.55k
  * rx++ = '*';
1411
1412
  /* But anchor it after that.  */
1413
5.55k
  * rx++ = '$';
1414
5.55k
  * rx = '\0';
1415
1416
5.55k
  CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
1417
5.55k
  reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
1418
1419
5.55k
  if (reg_err == 0)
1420
5.55k
    return NULL;
1421
0
  else
1422
0
    {
1423
0
      static char msg[80];
1424
1425
0
      regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
1426
0
      regfree ((regex_t *) CGEN_INSN_RX (insn));
1427
0
      free (CGEN_INSN_RX (insn));
1428
0
      (CGEN_INSN_RX (insn)) = NULL;
1429
0
      return msg;
1430
0
    }
1431
5.55k
}
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
0
{
1453
  /* ??? Runtime added insns not handled yet.  */
1454
0
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1455
0
  const char *str = *strp;
1456
0
  const char *errmsg;
1457
0
  const char *p;
1458
0
  const CGEN_SYNTAX_CHAR_TYPE * syn;
1459
0
#ifdef CGEN_MNEMONIC_OPERANDS
1460
  /* FIXME: wip */
1461
0
  int past_opcode_p;
1462
0
#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
0
  p = CGEN_INSN_MNEMONIC (insn);
1469
0
  while (*p && TOLOWER (*p) == TOLOWER (*str))
1470
0
    ++p, ++str;
1471
1472
0
  if (* p)
1473
0
    return _("unrecognized instruction");
1474
1475
#ifndef CGEN_MNEMONIC_OPERANDS
1476
  if (* str && ! ISSPACE (* str))
1477
    return _("unrecognized instruction");
1478
#endif
1479
1480
0
  CGEN_INIT_PARSE (cd);
1481
0
  cgen_init_parse_operand (cd);
1482
0
#ifdef CGEN_MNEMONIC_OPERANDS
1483
0
  past_opcode_p = 0;
1484
0
#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
0
  syn = CGEN_SYNTAX_STRING (syntax);
1489
1490
  /* Mnemonics come first for now, ensure valid string.  */
1491
0
  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1492
0
    abort ();
1493
1494
0
  ++syn;
1495
1496
0
  while (* syn != 0)
1497
0
    {
1498
      /* Non operand chars must match exactly.  */
1499
0
      if (CGEN_SYNTAX_CHAR_P (* syn))
1500
0
  {
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
0
    if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
1506
0
      {
1507
0
#ifdef CGEN_MNEMONIC_OPERANDS
1508
0
        if (CGEN_SYNTAX_CHAR(* syn) == ' ')
1509
0
    past_opcode_p = 1;
1510
0
#endif
1511
0
        ++ syn;
1512
0
        ++ str;
1513
0
      }
1514
0
    else if (*str)
1515
0
      {
1516
        /* Syntax char didn't match.  Can't be this insn.  */
1517
0
        static char msg [80];
1518
1519
        /* xgettext:c-format */
1520
0
        sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
1521
0
           CGEN_SYNTAX_CHAR(*syn), *str);
1522
0
        return msg;
1523
0
      }
1524
0
    else
1525
0
      {
1526
        /* Ran out of input.  */
1527
0
        static char msg [80];
1528
1529
        /* xgettext:c-format */
1530
0
        sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
1531
0
           CGEN_SYNTAX_CHAR(*syn));
1532
0
        return msg;
1533
0
      }
1534
0
    continue;
1535
0
  }
1536
1537
0
#ifdef CGEN_MNEMONIC_OPERANDS
1538
0
      (void) past_opcode_p;
1539
0
#endif
1540
      /* We have an operand of some sort.  */
1541
0
      errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
1542
0
      if (errmsg)
1543
0
  return errmsg;
1544
1545
      /* Done with this operand, continue with next one.  */
1546
0
      ++ syn;
1547
0
    }
1548
1549
  /* If we're at the end of the syntax string, we're done.  */
1550
0
  if (* syn == 0)
1551
0
    {
1552
      /* FIXME: For the moment we assume a valid `str' can only contain
1553
   blanks now.  IE: We needn't try again with a longer version of
1554
   the insn and it is assumed that longer versions of insns appear
1555
   before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
1556
0
      while (ISSPACE (* str))
1557
0
  ++ str;
1558
1559
0
      if (* str != '\0')
1560
0
  return _("junk at end of line"); /* FIXME: would like to include `str' */
1561
1562
0
      return NULL;
1563
0
    }
1564
1565
  /* We couldn't parse it.  */
1566
0
  return _("unrecognized instruction");
1567
0
}
1568

1569
/* Main entry point.
1570
   This routine is called for each instruction to be assembled.
1571
   STR points to the insn to be assembled.
1572
   We assume all necessary tables have been initialized.
1573
   The assembled instruction, less any fixups, is stored in BUF.
1574
   Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
1575
   still needs to be converted to target byte order, otherwise BUF is an array
1576
   of bytes in target byte order.
1577
   The result is a pointer to the insn's entry in the opcode table,
1578
   or NULL if an error occured (an error message will have already been
1579
   printed).
1580
1581
   Note that when processing (non-alias) macro-insns,
1582
   this function recurses.
1583
1584
   ??? It's possible to make this cpu-independent.
1585
   One would have to deal with a few minor things.
1586
   At this point in time doing so would be more of a curiosity than useful
1587
   [for example this file isn't _that_ big], but keeping the possibility in
1588
   mind helps keep the design clean.  */
1589
1590
const CGEN_INSN *
1591
mep_cgen_assemble_insn (CGEN_CPU_DESC cd,
1592
         const char *str,
1593
         CGEN_FIELDS *fields,
1594
         CGEN_INSN_BYTES_PTR buf,
1595
         char **errmsg)
1596
0
{
1597
0
  const char *start;
1598
0
  CGEN_INSN_LIST *ilist;
1599
0
  const char *parse_errmsg = NULL;
1600
0
  const char *insert_errmsg = NULL;
1601
0
  int recognized_mnemonic = 0;
1602
1603
  /* Skip leading white space.  */
1604
0
  while (ISSPACE (* str))
1605
0
    ++ str;
1606
1607
  /* The instructions are stored in hashed lists.
1608
     Get the first in the list.  */
1609
0
  ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
1610
1611
  /* Keep looking until we find a match.  */
1612
0
  start = str;
1613
0
  for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1614
0
    {
1615
0
      const CGEN_INSN *insn = ilist->insn;
1616
0
      recognized_mnemonic = 1;
1617
1618
0
#ifdef CGEN_VALIDATE_INSN_SUPPORTED
1619
      /* Not usually needed as unsupported opcodes
1620
   shouldn't be in the hash lists.  */
1621
      /* Is this insn supported by the selected cpu?  */
1622
0
      if (! mep_cgen_insn_supported (cd, insn))
1623
0
  continue;
1624
0
#endif
1625
      /* If the RELAXED attribute is set, this is an insn that shouldn't be
1626
   chosen immediately.  Instead, it is used during assembler/linker
1627
   relaxation if possible.  */
1628
0
      if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
1629
0
  continue;
1630
1631
0
      str = start;
1632
1633
      /* Skip this insn if str doesn't look right lexically.  */
1634
0
      if (CGEN_INSN_RX (insn) != NULL &&
1635
0
    regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
1636
0
  continue;
1637
1638
      /* Allow parse/insert handlers to obtain length of insn.  */
1639
0
      CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1640
1641
0
      parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
1642
0
      if (parse_errmsg != NULL)
1643
0
  continue;
1644
1645
      /* ??? 0 is passed for `pc'.  */
1646
0
      insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1647
0
             (bfd_vma) 0);
1648
0
      if (insert_errmsg != NULL)
1649
0
        continue;
1650
1651
      /* It is up to the caller to actually output the insn and any
1652
         queued relocs.  */
1653
0
      return insn;
1654
0
    }
1655
1656
0
  {
1657
0
    static char errbuf[150];
1658
0
    const char *tmp_errmsg;
1659
0
#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
1660
0
#define be_verbose 1
1661
#else
1662
#define be_verbose 0
1663
#endif
1664
1665
0
    if (be_verbose)
1666
0
      {
1667
  /* If requesting verbose error messages, use insert_errmsg.
1668
     Failing that, use parse_errmsg.  */
1669
0
  tmp_errmsg = (insert_errmsg ? insert_errmsg :
1670
0
          parse_errmsg ? parse_errmsg :
1671
0
          recognized_mnemonic ?
1672
0
          _("unrecognized form of instruction") :
1673
0
          _("unrecognized instruction"));
1674
1675
0
  if (strlen (start) > 50)
1676
    /* xgettext:c-format */
1677
0
    sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1678
0
  else
1679
    /* xgettext:c-format */
1680
0
    sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1681
0
      }
1682
0
    else
1683
0
      {
1684
0
  if (strlen (start) > 50)
1685
    /* xgettext:c-format */
1686
0
    sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1687
0
  else
1688
    /* xgettext:c-format */
1689
0
    sprintf (errbuf, _("bad instruction `%.50s'"), start);
1690
0
      }
1691
1692
0
    *errmsg = errbuf;
1693
0
    return NULL;
1694
0
  }
1695
0
}