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

Subversion Repositories openrisc_me

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

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

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

powered by: WebSVN 2.1.0

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