~ubuntu-branches/ubuntu/utopic/binutils-arm64-cross/utopic

« back to all changes in this revision

Viewing changes to binutils-2.23.52.20130611/opcodes/mep-asm.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-06-20 17:38:09 UTC
  • Revision ID: package-import@ubuntu.com-20130620173809-app8lzgvymy5fg6c
Tags: 0.7
Build-depend on binutils-source (>= 2.23.52.20130620-1~).

Show diffs side-by-side

added added

removed removed

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