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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [opcodes/] [mt-asm.c] - Blame information for rev 160

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

Line No. Rev Author Line
1 18 khays
/* 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 "mt-desc.h"
36
#include "mt-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
/* Range checking for signed numbers.  Returns 0 if acceptable
54
   and 1 if the value is out of bounds for a signed quantity.  */
55
 
56
static int
57
signed_out_of_bounds (long val)
58
{
59
  if ((val < -32768) || (val > 32767))
60
    return 1;
61
  return 0;
62
}
63
 
64
static const char *
65
parse_loopsize (CGEN_CPU_DESC cd,
66
                const char **strp,
67
                int opindex,
68
                void *arg)
69
{
70
  signed long * valuep = (signed long *) arg;
71
  const char *errmsg;
72
  bfd_reloc_code_real_type code = BFD_RELOC_NONE;
73
  enum cgen_parse_operand_result result_type;
74
  bfd_vma value;
75
 
76
  /* Is it a control transfer instructions?  */
77
  if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_LOOPSIZE)
78
    {
79
      code = BFD_RELOC_MT_PCINSN8;
80
      errmsg = cgen_parse_address (cd, strp, opindex, code,
81
                                   & result_type, & value);
82
      *valuep = value;
83
      return errmsg;
84
    }
85
 
86
  abort ();
87
}
88
 
89
static const char *
90
parse_imm16 (CGEN_CPU_DESC cd,
91
             const char **strp,
92
             int opindex,
93
             void *arg)
94
{
95
  signed long * valuep = (signed long *) arg;
96
  const char *errmsg;
97
  enum cgen_parse_operand_result result_type;
98
  bfd_reloc_code_real_type code = BFD_RELOC_NONE;
99
  bfd_vma value;
100
 
101
  /* Is it a control transfer instructions?  */
102
  if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16O)
103
    {
104
      code = BFD_RELOC_16_PCREL;
105
      errmsg = cgen_parse_address (cd, strp, opindex, code,
106
                                   & result_type, & value);
107
      if (errmsg == NULL)
108
        {
109
          if (signed_out_of_bounds (value))
110
            errmsg = _("Operand out of range. Must be between -32768 and 32767.");
111
        }
112
      *valuep = value;
113
      return errmsg;
114
    }
115
 
116
  /* If it's not a control transfer instruction, then
117
     we have to check for %OP relocating operators.  */
118
  if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16L)
119
    ;
120
  else if (strncmp (*strp, "%hi16", 5) == 0)
121
    {
122
      *strp += 5;
123
      code = BFD_RELOC_HI16;
124
    }
125
  else if (strncmp (*strp, "%lo16", 5) == 0)
126
    {
127
      *strp += 5;
128
      code = BFD_RELOC_LO16;
129
    }
130
 
131
  /* If we found a %OP relocating operator, then parse it as an address.
132
     If not, we need to parse it as an integer, either signed or unsigned
133
     depending on which operand type we have.  */
134
  if (code != BFD_RELOC_NONE)
135
    {
136
       /* %OP relocating operator found.  */
137
       errmsg = cgen_parse_address (cd, strp, opindex, code,
138
                                   & result_type, & value);
139
       if (errmsg == NULL)
140
         {
141
           switch (result_type)
142
             {
143
             case (CGEN_PARSE_OPERAND_RESULT_NUMBER):
144
               if (code == BFD_RELOC_HI16)
145
                 value = (value >> 16) & 0xFFFF;
146
               else if (code == BFD_RELOC_LO16)
147
                 value = value  & 0xFFFF;
148
               else
149
                 errmsg = _("Biiiig Trouble in parse_imm16!");
150
               break;
151
 
152
             case (CGEN_PARSE_OPERAND_RESULT_QUEUED):
153
               /* No special processing for this case.  */
154
               break;
155
 
156
             default:
157
               errmsg = _("The percent-operator's operand is not a symbol");
158
               break;
159
             }
160
         }
161
       *valuep = value;
162
    }
163
  else
164
    {
165
      /* Parse hex values like 0xffff as unsigned, and sign extend
166
         them manually.  */
167
      int parse_signed = (opindex == (CGEN_OPERAND_TYPE)MT_OPERAND_IMM16);
168
 
169
      if ((*strp)[0] == '0'
170
          && ((*strp)[1] == 'x' || (*strp)[1] == 'X'))
171
        parse_signed = 0;
172
 
173
      /* No relocating operator.  Parse as an number.  */
174
      if (parse_signed)
175
        {
176
          /* Parse as as signed integer.  */
177
 
178
          errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
179
 
180
          if (errmsg == NULL)
181
            {
182
#if 0
183
              /* Manual range checking is needed for the signed case.  */
184
              if (*valuep & 0x8000)
185
                value = 0xffff0000 | *valuep;
186
              else
187
                value = *valuep;
188
 
189
              if (signed_out_of_bounds (value))
190
                errmsg = _("Operand out of range. Must be between -32768 and 32767.");
191
              /* Truncate to 16 bits. This is necessary
192
                 because cgen will have sign extended *valuep.  */
193
              *valuep &= 0xFFFF;
194
#endif
195
            }
196
        }
197
      else
198
        {
199
          /* MT_OPERAND_IMM16Z.  Parse as an unsigned integer.  */
200
          errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, (unsigned long *) valuep);
201
 
202
          if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16
203
              && *valuep >= 0x8000
204
              && *valuep <= 0xffff)
205
            *valuep -= 0x10000;
206
        }
207
    }
208
 
209
  return errmsg;
210
}
211
 
212
 
213
static const char *
214
parse_dup (CGEN_CPU_DESC cd,
215
           const char **strp,
216
           int opindex,
217
           unsigned long *valuep)
218
{
219
  const char *errmsg = NULL;
220
 
221
  if (strncmp (*strp, "dup", 3) == 0 || strncmp (*strp, "DUP", 3) == 0)
222
    {
223
      *strp += 3;
224
      *valuep = 1;
225
    }
226
  else if (strncmp (*strp, "xx", 2) == 0 || strncmp (*strp, "XX", 2) == 0)
227
    {
228
      *strp += 2;
229
      *valuep = 0;
230
    }
231
  else
232
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
233
 
234
  return errmsg;
235
}
236
 
237
 
238
static const char *
239
parse_ball (CGEN_CPU_DESC cd,
240
            const char **strp,
241
            int opindex,
242
            unsigned long *valuep)
243
{
244
  const char *errmsg = NULL;
245
 
246
  if (strncmp (*strp, "all", 3) == 0 || strncmp (*strp, "ALL", 3) == 0)
247
    {
248
      *strp += 3;
249
      *valuep = 1;
250
    }
251
  else if (strncmp (*strp, "one", 3) == 0 || strncmp (*strp, "ONE", 3) == 0)
252
    {
253
      *strp += 3;
254
      *valuep = 0;
255
    }
256
  else
257
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
258
 
259
  return errmsg;
260
}
261
 
262
static const char *
263
parse_xmode (CGEN_CPU_DESC cd,
264
             const char **strp,
265
             int opindex,
266
             unsigned long *valuep)
267
{
268
  const char *errmsg = NULL;
269
 
270
  if (strncmp (*strp, "pm", 2) == 0 || strncmp (*strp, "PM", 2) == 0)
271
    {
272
      *strp += 2;
273
      *valuep = 1;
274
    }
275
  else if (strncmp (*strp, "xm", 2) == 0 || strncmp (*strp, "XM", 2) == 0)
276
    {
277
      *strp += 2;
278
      *valuep = 0;
279
    }
280
  else
281
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
282
 
283
  return errmsg;
284
}
285
 
286
static const char *
287
parse_rc (CGEN_CPU_DESC cd,
288
          const char **strp,
289
          int opindex,
290
          unsigned long *valuep)
291
{
292
  const char *errmsg = NULL;
293
 
294
  if (strncmp (*strp, "r", 1) == 0 || strncmp (*strp, "R", 1) == 0)
295
    {
296
      *strp += 1;
297
      *valuep = 1;
298
    }
299
  else if (strncmp (*strp, "c", 1) == 0 || strncmp (*strp, "C", 1) == 0)
300
    {
301
      *strp += 1;
302
      *valuep = 0;
303
    }
304
  else
305
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
306
 
307
  return errmsg;
308
}
309
 
310
static const char *
311
parse_cbrb (CGEN_CPU_DESC cd,
312
            const char **strp,
313
            int opindex,
314
            unsigned long *valuep)
315
{
316
  const char *errmsg = NULL;
317
 
318
  if (strncmp (*strp, "rb", 2) == 0 || strncmp (*strp, "RB", 2) == 0)
319
    {
320
      *strp += 2;
321
      *valuep = 1;
322
    }
323
  else if (strncmp (*strp, "cb", 2) == 0 || strncmp (*strp, "CB", 2) == 0)
324
    {
325
      *strp += 2;
326
      *valuep = 0;
327
    }
328
  else
329
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
330
 
331
  return errmsg;
332
}
333
 
334
static const char *
335
parse_rbbc (CGEN_CPU_DESC cd,
336
            const char **strp,
337
            int opindex,
338
            unsigned long *valuep)
339
{
340
  const char *errmsg = NULL;
341
 
342
  if (strncmp (*strp, "rt", 2) == 0 || strncmp (*strp, "RT", 2) == 0)
343
    {
344
      *strp += 2;
345
      *valuep = 0;
346
    }
347
  else if (strncmp (*strp, "br1", 3) == 0 || strncmp (*strp, "BR1", 3) == 0)
348
    {
349
      *strp += 3;
350
      *valuep = 1;
351
    }
352
  else if (strncmp (*strp, "br2", 3) == 0 || strncmp (*strp, "BR2", 3) == 0)
353
    {
354
      *strp += 3;
355
      *valuep = 2;
356
    }
357
  else if (strncmp (*strp, "cs", 2) == 0 || strncmp (*strp, "CS", 2) == 0)
358
    {
359
      *strp += 2;
360
      *valuep = 3;
361
    }
362
  else
363
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
364
 
365
  return errmsg;
366
}
367
 
368
static const char *
369
parse_type (CGEN_CPU_DESC cd,
370
            const char **strp,
371
            int opindex,
372
            unsigned long *valuep)
373
{
374
  const char *errmsg = NULL;
375
 
376
  if (strncmp (*strp, "odd", 3) == 0 || strncmp (*strp, "ODD", 3) == 0)
377
    {
378
      *strp += 3;
379
      *valuep = 0;
380
    }
381
  else if (strncmp (*strp, "even", 4) == 0 || strncmp (*strp, "EVEN", 4) == 0)
382
    {
383
      *strp += 4;
384
      *valuep = 1;
385
    }
386
  else if (strncmp (*strp, "oe", 2) == 0 || strncmp (*strp, "OE", 2) == 0)
387
    {
388
      *strp += 2;
389
      *valuep = 2;
390
    }
391
  else
392
    errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
393
 
394
 if ((errmsg == NULL) && (*valuep == 3))
395
    errmsg = _("invalid operand.  type may have values 0,1,2 only.");
396
 
397
  return errmsg;
398
}
399
 
400
/* -- dis.c */
401
 
402
const char * mt_cgen_parse_operand
403
  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
404
 
405
/* Main entry point for operand parsing.
406
 
407
   This function is basically just a big switch statement.  Earlier versions
408
   used tables to look up the function to use, but
409
   - if the table contains both assembler and disassembler functions then
410
     the disassembler contains much of the assembler and vice-versa,
411
   - there's a lot of inlining possibilities as things grow,
412
   - using a switch statement avoids the function call overhead.
413
 
414
   This function could be moved into `parse_insn_normal', but keeping it
415
   separate makes clear the interface between `parse_insn_normal' and each of
416
   the handlers.  */
417
 
418
const char *
419
mt_cgen_parse_operand (CGEN_CPU_DESC cd,
420
                           int opindex,
421
                           const char ** strp,
422
                           CGEN_FIELDS * fields)
423
{
424
  const char * errmsg = NULL;
425
  /* Used by scalar operands that still need to be parsed.  */
426
  long junk ATTRIBUTE_UNUSED;
427
 
428
  switch (opindex)
429
    {
430
    case MT_OPERAND_A23 :
431
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_A23, (unsigned long *) (& fields->f_a23));
432
      break;
433
    case MT_OPERAND_BALL :
434
      errmsg = parse_ball (cd, strp, MT_OPERAND_BALL, (unsigned long *) (& fields->f_ball));
435
      break;
436
    case MT_OPERAND_BALL2 :
437
      errmsg = parse_ball (cd, strp, MT_OPERAND_BALL2, (unsigned long *) (& fields->f_ball2));
438
      break;
439
    case MT_OPERAND_BANKADDR :
440
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_BANKADDR, (unsigned long *) (& fields->f_bankaddr));
441
      break;
442
    case MT_OPERAND_BRC :
443
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_BRC, (unsigned long *) (& fields->f_brc));
444
      break;
445
    case MT_OPERAND_BRC2 :
446
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_BRC2, (unsigned long *) (& fields->f_brc2));
447
      break;
448
    case MT_OPERAND_CB1INCR :
449
      errmsg = cgen_parse_signed_integer (cd, strp, MT_OPERAND_CB1INCR, (long *) (& fields->f_cb1incr));
450
      break;
451
    case MT_OPERAND_CB1SEL :
452
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CB1SEL, (unsigned long *) (& fields->f_cb1sel));
453
      break;
454
    case MT_OPERAND_CB2INCR :
455
      errmsg = cgen_parse_signed_integer (cd, strp, MT_OPERAND_CB2INCR, (long *) (& fields->f_cb2incr));
456
      break;
457
    case MT_OPERAND_CB2SEL :
458
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CB2SEL, (unsigned long *) (& fields->f_cb2sel));
459
      break;
460
    case MT_OPERAND_CBRB :
461
      errmsg = parse_cbrb (cd, strp, MT_OPERAND_CBRB, (unsigned long *) (& fields->f_cbrb));
462
      break;
463
    case MT_OPERAND_CBS :
464
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CBS, (unsigned long *) (& fields->f_cbs));
465
      break;
466
    case MT_OPERAND_CBX :
467
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CBX, (unsigned long *) (& fields->f_cbx));
468
      break;
469
    case MT_OPERAND_CCB :
470
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CCB, (unsigned long *) (& fields->f_ccb));
471
      break;
472
    case MT_OPERAND_CDB :
473
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CDB, (unsigned long *) (& fields->f_cdb));
474
      break;
475
    case MT_OPERAND_CELL :
476
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CELL, (unsigned long *) (& fields->f_cell));
477
      break;
478
    case MT_OPERAND_COLNUM :
479
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_COLNUM, (unsigned long *) (& fields->f_colnum));
480
      break;
481
    case MT_OPERAND_CONTNUM :
482
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CONTNUM, (unsigned long *) (& fields->f_contnum));
483
      break;
484
    case MT_OPERAND_CR :
485
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CR, (unsigned long *) (& fields->f_cr));
486
      break;
487
    case MT_OPERAND_CTXDISP :
488
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CTXDISP, (unsigned long *) (& fields->f_ctxdisp));
489
      break;
490
    case MT_OPERAND_DUP :
491
      errmsg = parse_dup (cd, strp, MT_OPERAND_DUP, (unsigned long *) (& fields->f_dup));
492
      break;
493
    case MT_OPERAND_FBDISP :
494
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_FBDISP, (unsigned long *) (& fields->f_fbdisp));
495
      break;
496
    case MT_OPERAND_FBINCR :
497
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_FBINCR, (unsigned long *) (& fields->f_fbincr));
498
      break;
499
    case MT_OPERAND_FRDR :
500
      errmsg = cgen_parse_keyword (cd, strp, & mt_cgen_opval_h_spr, & fields->f_dr);
501
      break;
502
    case MT_OPERAND_FRDRRR :
503
      errmsg = cgen_parse_keyword (cd, strp, & mt_cgen_opval_h_spr, & fields->f_drrr);
504
      break;
505
    case MT_OPERAND_FRSR1 :
506
      errmsg = cgen_parse_keyword (cd, strp, & mt_cgen_opval_h_spr, & fields->f_sr1);
507
      break;
508
    case MT_OPERAND_FRSR2 :
509
      errmsg = cgen_parse_keyword (cd, strp, & mt_cgen_opval_h_spr, & fields->f_sr2);
510
      break;
511
    case MT_OPERAND_ID :
512
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_ID, (unsigned long *) (& fields->f_id));
513
      break;
514
    case MT_OPERAND_IMM16 :
515
      errmsg = parse_imm16 (cd, strp, MT_OPERAND_IMM16, (long *) (& fields->f_imm16s));
516
      break;
517
    case MT_OPERAND_IMM16L :
518
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_IMM16L, (unsigned long *) (& fields->f_imm16l));
519
      break;
520
    case MT_OPERAND_IMM16O :
521
      errmsg = parse_imm16 (cd, strp, MT_OPERAND_IMM16O, (unsigned long *) (& fields->f_imm16s));
522
      break;
523
    case MT_OPERAND_IMM16Z :
524
      errmsg = parse_imm16 (cd, strp, MT_OPERAND_IMM16Z, (unsigned long *) (& fields->f_imm16u));
525
      break;
526
    case MT_OPERAND_INCAMT :
527
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_INCAMT, (unsigned long *) (& fields->f_incamt));
528
      break;
529
    case MT_OPERAND_INCR :
530
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_INCR, (unsigned long *) (& fields->f_incr));
531
      break;
532
    case MT_OPERAND_LENGTH :
533
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_LENGTH, (unsigned long *) (& fields->f_length));
534
      break;
535
    case MT_OPERAND_LOOPSIZE :
536
      errmsg = parse_loopsize (cd, strp, MT_OPERAND_LOOPSIZE, (unsigned long *) (& fields->f_loopo));
537
      break;
538
    case MT_OPERAND_MASK :
539
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_MASK, (unsigned long *) (& fields->f_mask));
540
      break;
541
    case MT_OPERAND_MASK1 :
542
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_MASK1, (unsigned long *) (& fields->f_mask1));
543
      break;
544
    case MT_OPERAND_MODE :
545
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_MODE, (unsigned long *) (& fields->f_mode));
546
      break;
547
    case MT_OPERAND_PERM :
548
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_PERM, (unsigned long *) (& fields->f_perm));
549
      break;
550
    case MT_OPERAND_RBBC :
551
      errmsg = parse_rbbc (cd, strp, MT_OPERAND_RBBC, (unsigned long *) (& fields->f_rbbc));
552
      break;
553
    case MT_OPERAND_RC :
554
      errmsg = parse_rc (cd, strp, MT_OPERAND_RC, (unsigned long *) (& fields->f_rc));
555
      break;
556
    case MT_OPERAND_RC1 :
557
      errmsg = parse_rc (cd, strp, MT_OPERAND_RC1, (unsigned long *) (& fields->f_rc1));
558
      break;
559
    case MT_OPERAND_RC2 :
560
      errmsg = parse_rc (cd, strp, MT_OPERAND_RC2, (unsigned long *) (& fields->f_rc2));
561
      break;
562
    case MT_OPERAND_RC3 :
563
      errmsg = parse_rc (cd, strp, MT_OPERAND_RC3, (unsigned long *) (& fields->f_rc3));
564
      break;
565
    case MT_OPERAND_RCNUM :
566
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_RCNUM, (unsigned long *) (& fields->f_rcnum));
567
      break;
568
    case MT_OPERAND_RDA :
569
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_RDA, (unsigned long *) (& fields->f_rda));
570
      break;
571
    case MT_OPERAND_ROWNUM :
572
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_ROWNUM, (unsigned long *) (& fields->f_rownum));
573
      break;
574
    case MT_OPERAND_ROWNUM1 :
575
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_ROWNUM1, (unsigned long *) (& fields->f_rownum1));
576
      break;
577
    case MT_OPERAND_ROWNUM2 :
578
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_ROWNUM2, (unsigned long *) (& fields->f_rownum2));
579
      break;
580
    case MT_OPERAND_SIZE :
581
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_SIZE, (unsigned long *) (& fields->f_size));
582
      break;
583
    case MT_OPERAND_TYPE :
584
      errmsg = parse_type (cd, strp, MT_OPERAND_TYPE, (unsigned long *) (& fields->f_type));
585
      break;
586
    case MT_OPERAND_WR :
587
      errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_WR, (unsigned long *) (& fields->f_wr));
588
      break;
589
    case MT_OPERAND_XMODE :
590
      errmsg = parse_xmode (cd, strp, MT_OPERAND_XMODE, (unsigned long *) (& fields->f_xmode));
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 mt_cgen_parse_handlers[] =
603
{
604
  parse_insn_normal,
605
};
606
 
607
void
608
mt_cgen_init_asm (CGEN_CPU_DESC cd)
609
{
610
  mt_cgen_init_opcode_table (cd);
611
  mt_cgen_init_ibld_table (cd);
612
  cd->parse_handlers = & mt_cgen_parse_handlers[0];
613
  cd->parse_operand = mt_cgen_parse_operand;
614
#ifdef CGEN_ASM_INIT_HOOK
615
CGEN_ASM_INIT_HOOK
616
#endif
617
}
618
 
619
 
620
 
621
/* Regex construction routine.
622
 
623
   This translates an opcode syntax string into a regex string,
624
   by replacing any non-character syntax element (such as an
625
   opcode) with the pattern '.*'
626
 
627
   It then compiles the regex and stores it in the opcode, for
628
   later use by mt_cgen_assemble_insn
629
 
630
   Returns NULL for success, an error message for failure.  */
631
 
632
char *
633
mt_cgen_build_insn_regex (CGEN_INSN *insn)
634
{
635
  CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
636
  const char *mnem = CGEN_INSN_MNEMONIC (insn);
637
  char rxbuf[CGEN_MAX_RX_ELEMENTS];
638
  char *rx = rxbuf;
639
  const CGEN_SYNTAX_CHAR_TYPE *syn;
640
  int reg_err;
641
 
642
  syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
643
 
644
  /* Mnemonics come first in the syntax string.  */
645
  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
646
    return _("missing mnemonic in syntax string");
647
  ++syn;
648
 
649
  /* Generate a case sensitive regular expression that emulates case
650
     insensitive matching in the "C" locale.  We cannot generate a case
651
     insensitive regular expression because in Turkish locales, 'i' and 'I'
652
     are not equal modulo case conversion.  */
653
 
654
  /* Copy the literal mnemonic out of the insn.  */
655
  for (; *mnem; mnem++)
656
    {
657
      char c = *mnem;
658
 
659
      if (ISALPHA (c))
660
        {
661
          *rx++ = '[';
662
          *rx++ = TOLOWER (c);
663
          *rx++ = TOUPPER (c);
664
          *rx++ = ']';
665
        }
666
      else
667
        *rx++ = c;
668
    }
669
 
670
  /* Copy any remaining literals from the syntax string into the rx.  */
671
  for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
672
    {
673
      if (CGEN_SYNTAX_CHAR_P (* syn))
674
        {
675
          char c = CGEN_SYNTAX_CHAR (* syn);
676
 
677
          switch (c)
678
            {
679
              /* Escape any regex metacharacters in the syntax.  */
680
            case '.': case '[': case '\\':
681
            case '*': case '^': case '$':
682
 
683
#ifdef CGEN_ESCAPE_EXTENDED_REGEX
684
            case '?': case '{': case '}':
685
            case '(': case ')': case '*':
686
            case '|': case '+': case ']':
687
#endif
688
              *rx++ = '\\';
689
              *rx++ = c;
690
              break;
691
 
692
            default:
693
              if (ISALPHA (c))
694
                {
695
                  *rx++ = '[';
696
                  *rx++ = TOLOWER (c);
697
                  *rx++ = TOUPPER (c);
698
                  *rx++ = ']';
699
                }
700
              else
701
                *rx++ = c;
702
              break;
703
            }
704
        }
705
      else
706
        {
707
          /* Replace non-syntax fields with globs.  */
708
          *rx++ = '.';
709
          *rx++ = '*';
710
        }
711
    }
712
 
713
  /* Trailing whitespace ok.  */
714
  * rx++ = '[';
715
  * rx++ = ' ';
716
  * rx++ = '\t';
717
  * rx++ = ']';
718
  * rx++ = '*';
719
 
720
  /* But anchor it after that.  */
721
  * rx++ = '$';
722
  * rx = '\0';
723
 
724
  CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
725
  reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
726
 
727
  if (reg_err == 0)
728
    return NULL;
729
  else
730
    {
731
      static char msg[80];
732
 
733
      regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
734
      regfree ((regex_t *) CGEN_INSN_RX (insn));
735
      free (CGEN_INSN_RX (insn));
736
      (CGEN_INSN_RX (insn)) = NULL;
737
      return msg;
738
    }
739
}
740
 
741
 
742
/* Default insn parser.
743
 
744
   The syntax string is scanned and operands are parsed and stored in FIELDS.
745
   Relocs are queued as we go via other callbacks.
746
 
747
   ??? Note that this is currently an all-or-nothing parser.  If we fail to
748
   parse the instruction, we return 0 and the caller will start over from
749
   the beginning.  Backtracking will be necessary in parsing subexpressions,
750
   but that can be handled there.  Not handling backtracking here may get
751
   expensive in the case of the m68k.  Deal with later.
752
 
753
   Returns NULL for success, an error message for failure.  */
754
 
755
static const char *
756
parse_insn_normal (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
#ifdef CGEN_MNEMONIC_OPERANDS
846
      (void) past_opcode_p;
847
#endif
848
      /* We have an operand of some sort.  */
849
      errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
850
      if (errmsg)
851
        return errmsg;
852
 
853
      /* Done with this operand, continue with next one.  */
854
      ++ syn;
855
    }
856
 
857
  /* If we're at the end of the syntax string, we're done.  */
858
  if (* syn == 0)
859
    {
860
      /* FIXME: For the moment we assume a valid `str' can only contain
861
         blanks now.  IE: We needn't try again with a longer version of
862
         the insn and it is assumed that longer versions of insns appear
863
         before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
864
      while (ISSPACE (* str))
865
        ++ str;
866
 
867
      if (* str != '\0')
868
        return _("junk at end of line"); /* FIXME: would like to include `str' */
869
 
870
      return NULL;
871
    }
872
 
873
  /* We couldn't parse it.  */
874
  return _("unrecognized instruction");
875
}
876
 
877
/* Main entry point.
878
   This routine is called for each instruction to be assembled.
879
   STR points to the insn to be assembled.
880
   We assume all necessary tables have been initialized.
881
   The assembled instruction, less any fixups, is stored in BUF.
882
   Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
883
   still needs to be converted to target byte order, otherwise BUF is an array
884
   of bytes in target byte order.
885
   The result is a pointer to the insn's entry in the opcode table,
886
   or NULL if an error occured (an error message will have already been
887
   printed).
888
 
889
   Note that when processing (non-alias) macro-insns,
890
   this function recurses.
891
 
892
   ??? It's possible to make this cpu-independent.
893
   One would have to deal with a few minor things.
894
   At this point in time doing so would be more of a curiosity than useful
895
   [for example this file isn't _that_ big], but keeping the possibility in
896
   mind helps keep the design clean.  */
897
 
898
const CGEN_INSN *
899
mt_cgen_assemble_insn (CGEN_CPU_DESC cd,
900
                           const char *str,
901
                           CGEN_FIELDS *fields,
902
                           CGEN_INSN_BYTES_PTR buf,
903
                           char **errmsg)
904
{
905
  const char *start;
906
  CGEN_INSN_LIST *ilist;
907
  const char *parse_errmsg = NULL;
908
  const char *insert_errmsg = NULL;
909
  int recognized_mnemonic = 0;
910
 
911
  /* Skip leading white space.  */
912
  while (ISSPACE (* str))
913
    ++ str;
914
 
915
  /* The instructions are stored in hashed lists.
916
     Get the first in the list.  */
917
  ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
918
 
919
  /* Keep looking until we find a match.  */
920
  start = str;
921
  for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
922
    {
923
      const CGEN_INSN *insn = ilist->insn;
924
      recognized_mnemonic = 1;
925
 
926
#ifdef CGEN_VALIDATE_INSN_SUPPORTED 
927
      /* Not usually needed as unsupported opcodes
928
         shouldn't be in the hash lists.  */
929
      /* Is this insn supported by the selected cpu?  */
930
      if (! mt_cgen_insn_supported (cd, insn))
931
        continue;
932
#endif
933
      /* If the RELAXED attribute is set, this is an insn that shouldn't be
934
         chosen immediately.  Instead, it is used during assembler/linker
935
         relaxation if possible.  */
936
      if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
937
        continue;
938
 
939
      str = start;
940
 
941
      /* Skip this insn if str doesn't look right lexically.  */
942
      if (CGEN_INSN_RX (insn) != NULL &&
943
          regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
944
        continue;
945
 
946
      /* Allow parse/insert handlers to obtain length of insn.  */
947
      CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
948
 
949
      parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
950
      if (parse_errmsg != NULL)
951
        continue;
952
 
953
      /* ??? 0 is passed for `pc'.  */
954
      insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
955
                                                 (bfd_vma) 0);
956
      if (insert_errmsg != NULL)
957
        continue;
958
 
959
      /* It is up to the caller to actually output the insn and any
960
         queued relocs.  */
961
      return insn;
962
    }
963
 
964
  {
965
    static char errbuf[150];
966
    const char *tmp_errmsg;
967
#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
968
#define be_verbose 1
969
#else
970
#define be_verbose 0
971
#endif
972
 
973
    if (be_verbose)
974
      {
975
        /* If requesting verbose error messages, use insert_errmsg.
976
           Failing that, use parse_errmsg.  */
977
        tmp_errmsg = (insert_errmsg ? insert_errmsg :
978
                      parse_errmsg ? parse_errmsg :
979
                      recognized_mnemonic ?
980
                      _("unrecognized form of instruction") :
981
                      _("unrecognized instruction"));
982
 
983
        if (strlen (start) > 50)
984
          /* xgettext:c-format */
985
          sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
986
        else
987
          /* xgettext:c-format */
988
          sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
989
      }
990
    else
991
      {
992
        if (strlen (start) > 50)
993
          /* xgettext:c-format */
994
          sprintf (errbuf, _("bad instruction `%.50s...'"), start);
995
        else
996
          /* xgettext:c-format */
997
          sprintf (errbuf, _("bad instruction `%.50s'"), start);
998
      }
999
 
1000
    *errmsg = errbuf;
1001
    return NULL;
1002
  }
1003
}

powered by: WebSVN 2.1.0

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