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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [opcodes/] [frv-asm.c] - Blame information for rev 1777

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

Line No. Rev Author Line
1 1181 sfurman
/* 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 Free Software Foundation, Inc.
8
 
9
This file is part of the GNU Binutils and GDB, the GNU debugger.
10
 
11
This program is free software; you can redistribute it and/or modify
12
it under the terms of the GNU General Public License as published by
13
the Free Software Foundation; either version 2, or (at your option)
14
any later version.
15
 
16
This program is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
GNU General Public License for more details.
20
 
21
You should have received a copy of the GNU General Public License
22
along with this program; if not, write to the Free Software Foundation, Inc.,
23
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
24
 
25
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
26
   Keep that in mind.  */
27
 
28
#include "sysdep.h"
29
#include <stdio.h>
30
#include "ansidecl.h"
31
#include "bfd.h"
32
#include "symcat.h"
33
#include "frv-desc.h"
34
#include "frv-opc.h"
35
#include "opintl.h"
36
#include "xregex.h"
37
#include "libiberty.h"
38
#include "safe-ctype.h"
39
 
40
#undef  min
41
#define min(a,b) ((a) < (b) ? (a) : (b))
42
#undef  max
43
#define max(a,b) ((a) > (b) ? (a) : (b))
44
 
45
static const char * parse_insn_normal
46
     PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *));
47
 
48
/* -- assembler routines inserted here.  */
49
 
50
/* -- asm.c */
51
static const char * parse_ulo16
52
  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
53
static const char * parse_uslo16
54
  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
55
static const char * parse_uhi16
56
  PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
57
static long parse_register_number
58
  PARAMS ((const char **));
59
static const char * parse_spr
60
  PARAMS ((CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *));
61
static const char * parse_d12
62
  PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
63
static const char * parse_s12
64
  PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
65
static const char * parse_u12
66
  PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
67
 
68
static const char *
69
parse_ulo16 (cd, strp, opindex, valuep)
70
     CGEN_CPU_DESC cd;
71
     const char **strp;
72
     int opindex;
73
     unsigned long *valuep;
74
{
75
  const char *errmsg;
76
  enum cgen_parse_operand_result result_type;
77
  bfd_vma value;
78
 
79
  if (**strp == '#' || **strp == '%')
80
    {
81
      if (strncasecmp (*strp + 1, "lo(", 3) == 0)
82
        {
83
          *strp += 4;
84
          errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
85
                                       &result_type, &value);
86
          if (**strp != ')')
87
            return "missing `)'";
88
          ++*strp;
89
          if (errmsg == NULL
90
              && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
91
            value &= 0xffff;
92
          *valuep = value;
93
          return errmsg;
94
        }
95
      if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
96
        {
97
          *strp += 9;
98
          errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
99
                                       &result_type, &value);
100
          if (**strp != ')')
101
            return "missing ')'";
102
          ++*strp;
103
          if (errmsg == NULL
104
              && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
105
            value >>= 16;
106
          *valuep = value;
107
          return errmsg;
108
        }
109
    }
110
  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
111
}
112
 
113
static const char *
114
parse_uslo16 (cd, strp, opindex, valuep)
115
     CGEN_CPU_DESC cd;
116
     const char **strp;
117
     int opindex;
118
     unsigned long *valuep;
119
{
120
  const char *errmsg;
121
  enum cgen_parse_operand_result result_type;
122
  bfd_vma value;
123
 
124
  if (**strp == '#' || **strp == '%')
125
    {
126
      if (strncasecmp (*strp + 1, "lo(", 3) == 0)
127
        {
128
          *strp += 4;
129
          errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
130
                                       &result_type, &value);
131
          if (**strp != ')')
132
            return "missing `)'";
133
          ++*strp;
134
          if (errmsg == NULL
135
              && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
136
            value &= 0xffff;
137
          *valuep = value;
138
          return errmsg;
139
        }
140
      else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
141
        {
142
          *strp += 9;
143
          errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
144
                                       &result_type, &value);
145
          if (**strp != ')')
146
            return "missing ')'";
147
          ++*strp;
148
          if (errmsg == NULL
149
              && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
150
            value &= 0xffff;
151
          *valuep = value;
152
          return errmsg;
153
        }
154
    }
155
  return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
156
}
157
 
158
static const char *
159
parse_uhi16 (cd, strp, opindex, valuep)
160
     CGEN_CPU_DESC cd;
161
     const char **strp;
162
     int opindex;
163
     unsigned long *valuep;
164
{
165
  const char *errmsg;
166
  enum cgen_parse_operand_result result_type;
167
  bfd_vma value;
168
 
169
  if (**strp == '#' || **strp == '%')
170
    {
171
      if (strncasecmp (*strp + 1, "hi(", 3) == 0)
172
        {
173
          *strp += 4;
174
          errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
175
                                       &result_type, &value);
176
          if (**strp != ')')
177
            return "missing `)'";
178
          ++*strp;
179
          if (errmsg == NULL
180
              && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
181
            value >>= 16;
182
          *valuep = value;
183
          return errmsg;
184
        }
185
      else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
186
        {
187
          *strp += 9;
188
          errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELHI,
189
                                       &result_type, &value);
190
          if (**strp != ')')
191
            return "missing ')'";
192
          ++*strp;
193
          if (errmsg == NULL
194
              && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
195
            value >>= 16;
196
          *valuep = value;
197
          return errmsg;
198
        }
199
    }
200
  return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
201
}
202
 
203
static long
204
parse_register_number (strp)
205
     const char **strp;
206
{
207
  int regno;
208
  if (**strp < '0' || **strp > '9')
209
    return -1; /* error */
210
 
211
  regno = **strp - '0';
212
  for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
213
    regno = regno * 10 + (**strp - '0');
214
 
215
  return regno;
216
}
217
 
218
static const char *
219
parse_spr (cd, strp, table, valuep)
220
     CGEN_CPU_DESC cd;
221
     const char **strp;
222
     CGEN_KEYWORD * table;
223
     long *valuep;
224
{
225
  const char *save_strp;
226
  long regno;
227
 
228
  /* Check for spr index notation.  */
229
  if (strncasecmp (*strp, "spr[", 4) == 0)
230
    {
231
      *strp += 4;
232
      regno = parse_register_number (strp);
233
      if (**strp != ']')
234
        return "missing `]'";
235
      ++*strp;
236
      if (! spr_valid (regno))
237
        return "Special purpose register number is out of range";
238
      *valuep = regno;
239
      return NULL;
240
    }
241
 
242
  save_strp = *strp;
243
  regno = parse_register_number (strp);
244
  if (regno != -1)
245
    {
246
      if (! spr_valid (regno))
247
        return "Special purpose register number is out of range";
248
      *valuep = regno;
249
      return NULL;
250
    }
251
 
252
  *strp = save_strp;
253
  return cgen_parse_keyword (cd, strp, table, valuep);
254
}
255
 
256
static const char *
257
parse_d12 (cd, strp, opindex, valuep)
258
     CGEN_CPU_DESC cd;
259
     const char **strp;
260
     int opindex;
261
     long *valuep;
262
{
263
  const char *errmsg;
264
  enum cgen_parse_operand_result result_type;
265
  bfd_vma value;
266
 
267
  /* Check for small data reference.  */
268
  if (**strp == '#' || **strp == '%')
269
    {
270
      if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
271
        {
272
          *strp += 9;
273
          errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
274
                                       &result_type, &value);
275
          if (**strp != ')')
276
            return "missing `)'";
277
          ++*strp;
278
          *valuep = value;
279
          return errmsg;
280
        }
281
    }
282
  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
283
}
284
 
285
static const char *
286
parse_s12 (cd, strp, opindex, valuep)
287
     CGEN_CPU_DESC cd;
288
     const char **strp;
289
     int opindex;
290
     long *valuep;
291
{
292
  const char *errmsg;
293
  enum cgen_parse_operand_result result_type;
294
  bfd_vma value;
295
 
296
  /* Check for small data reference.  */
297
  if ((**strp == '#' || **strp == '%')
298
      && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
299
    {
300
      *strp += 9;
301
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
302
                                    &result_type, &value);
303
      if (**strp != ')')
304
        return "missing `)'";
305
      ++*strp;
306
      *valuep = value;
307
      return errmsg;
308
    }
309
  else
310
    {
311
      if (**strp == '#')
312
        ++*strp;
313
      return cgen_parse_signed_integer (cd, strp, opindex, valuep);
314
    }
315
}
316
 
317
static const char *
318
parse_u12 (cd, strp, opindex, valuep)
319
     CGEN_CPU_DESC cd;
320
     const char **strp;
321
     int opindex;
322
     long *valuep;
323
{
324
  const char *errmsg;
325
  enum cgen_parse_operand_result result_type;
326
  bfd_vma value;
327
 
328
  /* Check for small data reference.  */
329
  if ((**strp == '#' || **strp == '%')
330
      && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
331
    {
332
      *strp += 9;
333
      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELU12,
334
                                    &result_type, &value);
335
      if (**strp != ')')
336
        return "missing `)'";
337
      ++*strp;
338
      *valuep = value;
339
      return errmsg;
340
    }
341
  else
342
    {
343
      if (**strp == '#')
344
        ++*strp;
345
      return cgen_parse_signed_integer (cd, strp, opindex, valuep);
346
    }
347
}
348
 
349
/* -- */
350
 
351
const char * frv_cgen_parse_operand
352
  PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *));
353
 
354
/* Main entry point for operand parsing.
355
 
356
   This function is basically just a big switch statement.  Earlier versions
357
   used tables to look up the function to use, but
358
   - if the table contains both assembler and disassembler functions then
359
     the disassembler contains much of the assembler and vice-versa,
360
   - there's a lot of inlining possibilities as things grow,
361
   - using a switch statement avoids the function call overhead.
362
 
363
   This function could be moved into `parse_insn_normal', but keeping it
364
   separate makes clear the interface between `parse_insn_normal' and each of
365
   the handlers.  */
366
 
367
const char *
368
frv_cgen_parse_operand (cd, opindex, strp, fields)
369
     CGEN_CPU_DESC cd;
370
     int opindex;
371
     const char ** strp;
372
     CGEN_FIELDS * fields;
373
{
374
  const char * errmsg = NULL;
375
  /* Used by scalar operands that still need to be parsed.  */
376
  long junk ATTRIBUTE_UNUSED;
377
 
378
  switch (opindex)
379
    {
380
    case FRV_OPERAND_A :
381
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_A, &fields->f_A);
382
      break;
383
    case FRV_OPERAND_ACC40SI :
384
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Si);
385
      break;
386
    case FRV_OPERAND_ACC40SK :
387
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Sk);
388
      break;
389
    case FRV_OPERAND_ACC40UI :
390
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Ui);
391
      break;
392
    case FRV_OPERAND_ACC40UK :
393
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Uk);
394
      break;
395
    case FRV_OPERAND_ACCGI :
396
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGi);
397
      break;
398
    case FRV_OPERAND_ACCGK :
399
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGk);
400
      break;
401
    case FRV_OPERAND_CCI :
402
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CCi);
403
      break;
404
    case FRV_OPERAND_CPRDOUBLEK :
405
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
406
      break;
407
    case FRV_OPERAND_CPRI :
408
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRi);
409
      break;
410
    case FRV_OPERAND_CPRJ :
411
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRj);
412
      break;
413
    case FRV_OPERAND_CPRK :
414
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
415
      break;
416
    case FRV_OPERAND_CRI :
417
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRi);
418
      break;
419
    case FRV_OPERAND_CRJ :
420
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj);
421
      break;
422
    case FRV_OPERAND_CRJ_FLOAT :
423
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_float);
424
      break;
425
    case FRV_OPERAND_CRJ_INT :
426
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_int);
427
      break;
428
    case FRV_OPERAND_CRK :
429
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRk);
430
      break;
431
    case FRV_OPERAND_FCCI_1 :
432
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_1);
433
      break;
434
    case FRV_OPERAND_FCCI_2 :
435
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_2);
436
      break;
437
    case FRV_OPERAND_FCCI_3 :
438
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_3);
439
      break;
440
    case FRV_OPERAND_FCCK :
441
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCk);
442
      break;
443
    case FRV_OPERAND_FRDOUBLEI :
444
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
445
      break;
446
    case FRV_OPERAND_FRDOUBLEJ :
447
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
448
      break;
449
    case FRV_OPERAND_FRDOUBLEK :
450
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
451
      break;
452
    case FRV_OPERAND_FRI :
453
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
454
      break;
455
    case FRV_OPERAND_FRINTI :
456
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
457
      break;
458
    case FRV_OPERAND_FRINTJ :
459
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
460
      break;
461
    case FRV_OPERAND_FRINTK :
462
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
463
      break;
464
    case FRV_OPERAND_FRJ :
465
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
466
      break;
467
    case FRV_OPERAND_FRK :
468
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
469
      break;
470
    case FRV_OPERAND_FRKHI :
471
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
472
      break;
473
    case FRV_OPERAND_FRKLO :
474
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
475
      break;
476
    case FRV_OPERAND_GRDOUBLEK :
477
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
478
      break;
479
    case FRV_OPERAND_GRI :
480
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRi);
481
      break;
482
    case FRV_OPERAND_GRJ :
483
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRj);
484
      break;
485
    case FRV_OPERAND_GRK :
486
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
487
      break;
488
    case FRV_OPERAND_GRKHI :
489
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
490
      break;
491
    case FRV_OPERAND_GRKLO :
492
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
493
      break;
494
    case FRV_OPERAND_ICCI_1 :
495
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_1);
496
      break;
497
    case FRV_OPERAND_ICCI_2 :
498
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_2);
499
      break;
500
    case FRV_OPERAND_ICCI_3 :
501
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_3);
502
      break;
503
    case FRV_OPERAND_LI :
504
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LI, &fields->f_LI);
505
      break;
506
    case FRV_OPERAND_AE :
507
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_AE, &fields->f_ae);
508
      break;
509
    case FRV_OPERAND_CCOND :
510
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_CCOND, &fields->f_ccond);
511
      break;
512
    case FRV_OPERAND_COND :
513
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_COND, &fields->f_cond);
514
      break;
515
    case FRV_OPERAND_D12 :
516
      errmsg = parse_d12 (cd, strp, FRV_OPERAND_D12, &fields->f_d12);
517
      break;
518
    case FRV_OPERAND_DEBUG :
519
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_DEBUG, &fields->f_debug);
520
      break;
521
    case FRV_OPERAND_EIR :
522
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_EIR, &fields->f_eir);
523
      break;
524
    case FRV_OPERAND_HINT :
525
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_HINT, &fields->f_hint);
526
      break;
527
    case FRV_OPERAND_HINT_NOT_TAKEN :
528
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_not_taken, & fields->f_hint);
529
      break;
530
    case FRV_OPERAND_HINT_TAKEN :
531
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_taken, & fields->f_hint);
532
      break;
533
    case FRV_OPERAND_LABEL16 :
534
      {
535
        bfd_vma value;
536
        errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL16, 0, NULL,  & value);
537
        fields->f_label16 = value;
538
      }
539
      break;
540
    case FRV_OPERAND_LABEL24 :
541
      {
542
        bfd_vma value;
543
        errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL24, 0, NULL,  & value);
544
        fields->f_label24 = value;
545
      }
546
      break;
547
    case FRV_OPERAND_LOCK :
548
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LOCK, &fields->f_lock);
549
      break;
550
    case FRV_OPERAND_PACK :
551
      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_pack, & fields->f_pack);
552
      break;
553
    case FRV_OPERAND_S10 :
554
      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S10, &fields->f_s10);
555
      break;
556
    case FRV_OPERAND_S12 :
557
      errmsg = parse_s12 (cd, strp, FRV_OPERAND_S12, &fields->f_d12);
558
      break;
559
    case FRV_OPERAND_S16 :
560
      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S16, &fields->f_s16);
561
      break;
562
    case FRV_OPERAND_S5 :
563
      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S5, &fields->f_s5);
564
      break;
565
    case FRV_OPERAND_S6 :
566
      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6, &fields->f_s6);
567
      break;
568
    case FRV_OPERAND_S6_1 :
569
      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6_1, &fields->f_s6_1);
570
      break;
571
    case FRV_OPERAND_SLO16 :
572
      errmsg = parse_uslo16 (cd, strp, FRV_OPERAND_SLO16, &fields->f_s16);
573
      break;
574
    case FRV_OPERAND_SPR :
575
      errmsg = parse_spr (cd, strp, & frv_cgen_opval_spr_names, & fields->f_spr);
576
      break;
577
    case FRV_OPERAND_U12 :
578
      errmsg = parse_u12 (cd, strp, FRV_OPERAND_U12, &fields->f_u12);
579
      break;
580
    case FRV_OPERAND_U16 :
581
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U16, &fields->f_u16);
582
      break;
583
    case FRV_OPERAND_U6 :
584
      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U6, &fields->f_u6);
585
      break;
586
    case FRV_OPERAND_UHI16 :
587
      errmsg = parse_uhi16 (cd, strp, FRV_OPERAND_UHI16, &fields->f_u16);
588
      break;
589
    case FRV_OPERAND_ULO16 :
590
      errmsg = parse_ulo16 (cd, strp, FRV_OPERAND_ULO16, &fields->f_u16);
591
      break;
592
 
593
    default :
594
      /* xgettext:c-format */
595
      fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
596
      abort ();
597
  }
598
 
599
  return errmsg;
600
}
601
 
602
cgen_parse_fn * const frv_cgen_parse_handlers[] =
603
{
604
  parse_insn_normal,
605
};
606
 
607
void
608
frv_cgen_init_asm (cd)
609
     CGEN_CPU_DESC cd;
610
{
611
  frv_cgen_init_opcode_table (cd);
612
  frv_cgen_init_ibld_table (cd);
613
  cd->parse_handlers = & frv_cgen_parse_handlers[0];
614
  cd->parse_operand = frv_cgen_parse_operand;
615
}
616
 
617
 
618
 
619
/* Regex construction routine.
620
 
621
   This translates an opcode syntax string into a regex string,
622
   by replacing any non-character syntax element (such as an
623
   opcode) with the pattern '.*'
624
 
625
   It then compiles the regex and stores it in the opcode, for
626
   later use by frv_cgen_assemble_insn
627
 
628
   Returns NULL for success, an error message for failure.  */
629
 
630
char *
631
frv_cgen_build_insn_regex (insn)
632
     CGEN_INSN *insn;
633
{
634
  CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
635
  const char *mnem = CGEN_INSN_MNEMONIC (insn);
636
  char rxbuf[CGEN_MAX_RX_ELEMENTS];
637
  char *rx = rxbuf;
638
  const CGEN_SYNTAX_CHAR_TYPE *syn;
639
  int reg_err;
640
 
641
  syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
642
 
643
  /* Mnemonics come first in the syntax string.  */
644
  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
645
    return _("missing mnemonic in syntax string");
646
  ++syn;
647
 
648
  /* Generate a case sensitive regular expression that emulates case
649
     insensitive matching in the "C" locale.  We cannot generate a case
650
     insensitive regular expression because in Turkish locales, 'i' and 'I'
651
     are not equal modulo case conversion.  */
652
 
653
  /* Copy the literal mnemonic out of the insn.  */
654
  for (; *mnem; mnem++)
655
    {
656
      char c = *mnem;
657
 
658
      if (ISALPHA (c))
659
        {
660
          *rx++ = '[';
661
          *rx++ = TOLOWER (c);
662
          *rx++ = TOUPPER (c);
663
          *rx++ = ']';
664
        }
665
      else
666
        *rx++ = c;
667
    }
668
 
669
  /* Copy any remaining literals from the syntax string into the rx.  */
670
  for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
671
    {
672
      if (CGEN_SYNTAX_CHAR_P (* syn))
673
        {
674
          char c = CGEN_SYNTAX_CHAR (* syn);
675
 
676
          switch (c)
677
            {
678
              /* Escape any regex metacharacters in the syntax.  */
679
            case '.': case '[': case '\\':
680
            case '*': case '^': case '$':
681
 
682
#ifdef CGEN_ESCAPE_EXTENDED_REGEX
683
            case '?': case '{': case '}':
684
            case '(': case ')': case '*':
685
            case '|': case '+': case ']':
686
#endif
687
              *rx++ = '\\';
688
              *rx++ = c;
689
              break;
690
 
691
            default:
692
              if (ISALPHA (c))
693
                {
694
                  *rx++ = '[';
695
                  *rx++ = TOLOWER (c);
696
                  *rx++ = TOUPPER (c);
697
                  *rx++ = ']';
698
                }
699
              else
700
                *rx++ = c;
701
              break;
702
            }
703
        }
704
      else
705
        {
706
          /* Replace non-syntax fields with globs.  */
707
          *rx++ = '.';
708
          *rx++ = '*';
709
        }
710
    }
711
 
712
  /* Trailing whitespace ok.  */
713
  * rx++ = '[';
714
  * rx++ = ' ';
715
  * rx++ = '\t';
716
  * rx++ = ']';
717
  * rx++ = '*';
718
 
719
  /* But anchor it after that.  */
720
  * rx++ = '$';
721
  * rx = '\0';
722
 
723
  CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
724
  reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
725
 
726
  if (reg_err == 0)
727
    return NULL;
728
  else
729
    {
730
      static char msg[80];
731
 
732
      regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
733
      regfree ((regex_t *) CGEN_INSN_RX (insn));
734
      free (CGEN_INSN_RX (insn));
735
      (CGEN_INSN_RX (insn)) = NULL;
736
      return msg;
737
    }
738
}
739
 
740
 
741
/* Default insn parser.
742
 
743
   The syntax string is scanned and operands are parsed and stored in FIELDS.
744
   Relocs are queued as we go via other callbacks.
745
 
746
   ??? Note that this is currently an all-or-nothing parser.  If we fail to
747
   parse the instruction, we return 0 and the caller will start over from
748
   the beginning.  Backtracking will be necessary in parsing subexpressions,
749
   but that can be handled there.  Not handling backtracking here may get
750
   expensive in the case of the m68k.  Deal with later.
751
 
752
   Returns NULL for success, an error message for failure.  */
753
 
754
static const char *
755
parse_insn_normal (cd, insn, strp, fields)
756
     CGEN_CPU_DESC cd;
757
     const CGEN_INSN *insn;
758
     const char **strp;
759
     CGEN_FIELDS *fields;
760
{
761
  /* ??? Runtime added insns not handled yet.  */
762
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
763
  const char *str = *strp;
764
  const char *errmsg;
765
  const char *p;
766
  const CGEN_SYNTAX_CHAR_TYPE * syn;
767
#ifdef CGEN_MNEMONIC_OPERANDS
768
  /* FIXME: wip */
769
  int past_opcode_p;
770
#endif
771
 
772
  /* For now we assume the mnemonic is first (there are no leading operands).
773
     We can parse it without needing to set up operand parsing.
774
     GAS's input scrubber will ensure mnemonics are lowercase, but we may
775
     not be called from GAS.  */
776
  p = CGEN_INSN_MNEMONIC (insn);
777
  while (*p && TOLOWER (*p) == TOLOWER (*str))
778
    ++p, ++str;
779
 
780
  if (* p)
781
    return _("unrecognized instruction");
782
 
783
#ifndef CGEN_MNEMONIC_OPERANDS
784
  if (* str && ! ISSPACE (* str))
785
    return _("unrecognized instruction");
786
#endif
787
 
788
  CGEN_INIT_PARSE (cd);
789
  cgen_init_parse_operand (cd);
790
#ifdef CGEN_MNEMONIC_OPERANDS
791
  past_opcode_p = 0;
792
#endif
793
 
794
  /* We don't check for (*str != '\0') here because we want to parse
795
     any trailing fake arguments in the syntax string.  */
796
  syn = CGEN_SYNTAX_STRING (syntax);
797
 
798
  /* Mnemonics come first for now, ensure valid string.  */
799
  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
800
    abort ();
801
 
802
  ++syn;
803
 
804
  while (* syn != 0)
805
    {
806
      /* Non operand chars must match exactly.  */
807
      if (CGEN_SYNTAX_CHAR_P (* syn))
808
        {
809
          /* FIXME: While we allow for non-GAS callers above, we assume the
810
             first char after the mnemonic part is a space.  */
811
          /* FIXME: We also take inappropriate advantage of the fact that
812
             GAS's input scrubber will remove extraneous blanks.  */
813
          if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
814
            {
815
#ifdef CGEN_MNEMONIC_OPERANDS
816
              if (CGEN_SYNTAX_CHAR(* syn) == ' ')
817
                past_opcode_p = 1;
818
#endif
819
              ++ syn;
820
              ++ str;
821
            }
822
          else if (*str)
823
            {
824
              /* Syntax char didn't match.  Can't be this insn.  */
825
              static char msg [80];
826
 
827
              /* xgettext:c-format */
828
              sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
829
                       CGEN_SYNTAX_CHAR(*syn), *str);
830
              return msg;
831
            }
832
          else
833
            {
834
              /* Ran out of input.  */
835
              static char msg [80];
836
 
837
              /* xgettext:c-format */
838
              sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
839
                       CGEN_SYNTAX_CHAR(*syn));
840
              return msg;
841
            }
842
          continue;
843
        }
844
 
845
      /* We have an operand of some sort.  */
846
      errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
847
                                          &str, fields);
848
      if (errmsg)
849
        return errmsg;
850
 
851
      /* Done with this operand, continue with next one.  */
852
      ++ syn;
853
    }
854
 
855
  /* If we're at the end of the syntax string, we're done.  */
856
  if (* syn == 0)
857
    {
858
      /* FIXME: For the moment we assume a valid `str' can only contain
859
         blanks now.  IE: We needn't try again with a longer version of
860
         the insn and it is assumed that longer versions of insns appear
861
         before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
862
      while (ISSPACE (* str))
863
        ++ str;
864
 
865
      if (* str != '\0')
866
        return _("junk at end of line"); /* FIXME: would like to include `str' */
867
 
868
      return NULL;
869
    }
870
 
871
  /* We couldn't parse it.  */
872
  return _("unrecognized instruction");
873
}
874
 
875
/* Main entry point.
876
   This routine is called for each instruction to be assembled.
877
   STR points to the insn to be assembled.
878
   We assume all necessary tables have been initialized.
879
   The assembled instruction, less any fixups, is stored in BUF.
880
   Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
881
   still needs to be converted to target byte order, otherwise BUF is an array
882
   of bytes in target byte order.
883
   The result is a pointer to the insn's entry in the opcode table,
884
   or NULL if an error occured (an error message will have already been
885
   printed).
886
 
887
   Note that when processing (non-alias) macro-insns,
888
   this function recurses.
889
 
890
   ??? It's possible to make this cpu-independent.
891
   One would have to deal with a few minor things.
892
   At this point in time doing so would be more of a curiosity than useful
893
   [for example this file isn't _that_ big], but keeping the possibility in
894
   mind helps keep the design clean.  */
895
 
896
const CGEN_INSN *
897
frv_cgen_assemble_insn (cd, str, fields, buf, errmsg)
898
     CGEN_CPU_DESC cd;
899
     const char *str;
900
     CGEN_FIELDS *fields;
901
     CGEN_INSN_BYTES_PTR buf;
902
     char **errmsg;
903
{
904
  const char *start;
905
  CGEN_INSN_LIST *ilist;
906
  const char *parse_errmsg = NULL;
907
  const char *insert_errmsg = NULL;
908
  int recognized_mnemonic = 0;
909
 
910
  /* Skip leading white space.  */
911
  while (ISSPACE (* str))
912
    ++ str;
913
 
914
  /* The instructions are stored in hashed lists.
915
     Get the first in the list.  */
916
  ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
917
 
918
  /* Keep looking until we find a match.  */
919
  start = str;
920
  for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
921
    {
922
      const CGEN_INSN *insn = ilist->insn;
923
      recognized_mnemonic = 1;
924
 
925
#ifdef CGEN_VALIDATE_INSN_SUPPORTED 
926
      /* Not usually needed as unsupported opcodes
927
         shouldn't be in the hash lists.  */
928
      /* Is this insn supported by the selected cpu?  */
929
      if (! frv_cgen_insn_supported (cd, insn))
930
        continue;
931
#endif
932
      /* If the RELAX attribute is set, this is an insn that shouldn't be
933
         chosen immediately.  Instead, it is used during assembler/linker
934
         relaxation if possible.  */
935
      if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX) != 0)
936
        continue;
937
 
938
      str = start;
939
 
940
      /* Skip this insn if str doesn't look right lexically.  */
941
      if (CGEN_INSN_RX (insn) != NULL &&
942
          regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
943
        continue;
944
 
945
      /* Allow parse/insert handlers to obtain length of insn.  */
946
      CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
947
 
948
      parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
949
      if (parse_errmsg != NULL)
950
        continue;
951
 
952
      /* ??? 0 is passed for `pc'.  */
953
      insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
954
                                                 (bfd_vma) 0);
955
      if (insert_errmsg != NULL)
956
        continue;
957
 
958
      /* It is up to the caller to actually output the insn and any
959
         queued relocs.  */
960
      return insn;
961
    }
962
 
963
  {
964
    static char errbuf[150];
965
#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
966
    const char *tmp_errmsg;
967
 
968
    /* If requesting verbose error messages, use insert_errmsg.
969
       Failing that, use parse_errmsg.  */
970
    tmp_errmsg = (insert_errmsg ? insert_errmsg :
971
                  parse_errmsg ? parse_errmsg :
972
                  recognized_mnemonic ?
973
                  _("unrecognized form of instruction") :
974
                  _("unrecognized instruction"));
975
 
976
    if (strlen (start) > 50)
977
      /* xgettext:c-format */
978
      sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
979
    else
980
      /* xgettext:c-format */
981
      sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
982
#else
983
    if (strlen (start) > 50)
984
      /* xgettext:c-format */
985
      sprintf (errbuf, _("bad instruction `%.50s...'"), start);
986
    else
987
      /* xgettext:c-format */
988
      sprintf (errbuf, _("bad instruction `%.50s'"), start);
989
#endif
990
 
991
    *errmsg = errbuf;
992
    return NULL;
993
  }
994
}
995
 
996
#if 0 /* This calls back to GAS which we can't do without care.  */
997
 
998
/* Record each member of OPVALS in the assembler's symbol table.
999
   This lets GAS parse registers for us.
1000
   ??? Interesting idea but not currently used.  */
1001
 
1002
/* Record each member of OPVALS in the assembler's symbol table.
1003
   FIXME: Not currently used.  */
1004
 
1005
void
1006
frv_cgen_asm_hash_keywords (cd, opvals)
1007
     CGEN_CPU_DESC cd;
1008
     CGEN_KEYWORD *opvals;
1009
{
1010
  CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
1011
  const CGEN_KEYWORD_ENTRY * ke;
1012
 
1013
  while ((ke = cgen_keyword_search_next (& search)) != NULL)
1014
    {
1015
#if 0 /* Unnecessary, should be done in the search routine.  */
1016
      if (! frv_cgen_opval_supported (ke))
1017
        continue;
1018
#endif
1019
      cgen_asm_record_register (cd, ke->name, ke->value);
1020
    }
1021
}
1022
 
1023
#endif /* 0 */

powered by: WebSVN 2.1.0

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