OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [gas/] [config/] [m68k-parse.y] - Blame information for rev 332

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

Line No. Rev Author Line
1 38 julius
/* m68k.y -- bison grammar for m68k operand parsing
2
   Copyright 1995, 1996, 1997, 1998, 2001, 2003, 2004, 2005, 2007
3
   Free Software Foundation, Inc.
4
   Written by Ken Raeburn and Ian Lance Taylor, Cygnus Support
5
 
6
   This file is part of GAS, the GNU Assembler.
7
 
8
   GAS is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3, or (at your option)
11
   any later version.
12
 
13
   GAS is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with GAS; see the file COPYING.  If not, write to the Free
20
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21
   02110-1301, USA.  */
22
 
23
/* This file holds a bison grammar to parse m68k operands.  The m68k
24
   has a complicated operand syntax, and gas supports two main
25
   variations of it.  Using a grammar is probably overkill, but at
26
   least it makes clear exactly what we do support.  */
27
 
28
%{
29
 
30
#include "as.h"
31
#include "tc-m68k.h"
32
#include "m68k-parse.h"
33
#include "safe-ctype.h"
34
 
35
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror,
36
   etc), as well as gratuitously global symbol names If other parser
37
   generators (bison, byacc, etc) produce additional global names that
38
   conflict at link time, then those parser generators need to be
39
   fixed instead of adding those names to this list.  */
40
 
41
#define yymaxdepth m68k_maxdepth
42
#define yyparse m68k_parse
43
#define yylex   m68k_lex
44
#define yyerror m68k_error
45
#define yylval  m68k_lval
46
#define yychar  m68k_char
47
#define yydebug m68k_debug
48
#define yypact  m68k_pact
49
#define yyr1    m68k_r1
50
#define yyr2    m68k_r2
51
#define yydef   m68k_def
52
#define yychk   m68k_chk
53
#define yypgo   m68k_pgo
54
#define yyact   m68k_act
55
#define yyexca  m68k_exca
56
#define yyerrflag m68k_errflag
57
#define yynerrs m68k_nerrs
58
#define yyps    m68k_ps
59
#define yypv    m68k_pv
60
#define yys     m68k_s
61
#define yy_yys  m68k_yys
62
#define yystate m68k_state
63
#define yytmp   m68k_tmp
64
#define yyv     m68k_v
65
#define yy_yyv  m68k_yyv
66
#define yyval   m68k_val
67
#define yylloc  m68k_lloc
68
#define yyreds  m68k_reds               /* With YYDEBUG defined */
69
#define yytoks  m68k_toks               /* With YYDEBUG defined */
70
#define yylhs   m68k_yylhs
71
#define yylen   m68k_yylen
72
#define yydefred m68k_yydefred
73
#define yydgoto m68k_yydgoto
74
#define yysindex m68k_yysindex
75
#define yyrindex m68k_yyrindex
76
#define yygindex m68k_yygindex
77
#define yytable  m68k_yytable
78
#define yycheck  m68k_yycheck
79
 
80
#ifndef YYDEBUG
81
#define YYDEBUG 1
82
#endif
83
 
84
/* Internal functions.  */
85
 
86
static enum m68k_register m68k_reg_parse (char **);
87
static int yylex (void);
88
static void yyerror (const char *);
89
 
90
/* The parser sets fields pointed to by this global variable.  */
91
static struct m68k_op *op;
92
 
93
%}
94
 
95
%union
96
{
97
  struct m68k_indexreg indexreg;
98
  enum m68k_register reg;
99
  struct m68k_exp exp;
100
  unsigned long mask;
101
  int onereg;
102
  int trailing_ampersand;
103
}
104
 
105
%token  DR AR FPR FPCR LPC ZAR ZDR LZPC CREG
106
%token  INDEXREG
107
%token  EXPR
108
 
109
%type  zireg zdireg
110
%type  zadr zdr apc zapc zpc optzapc optczapc
111
%type  optcexpr optexprc
112
%type  reglist ireglist reglistpair
113
%type  reglistreg
114
%type  optional_ampersand
115
 
116
%%
117
 
118
/* An operand.  */
119
 
120
operand:
121
          generic_operand
122
        | motorola_operand optional_ampersand
123
                {
124
                  op->trailing_ampersand = $2;
125
                }
126
        | mit_operand optional_ampersand
127
                {
128
                  op->trailing_ampersand = $2;
129
                }
130
        ;
131
 
132
/* A trailing ampersand(for MAC/EMAC mask addressing).  */
133
optional_ampersand:
134
        /* empty */
135
                { $$ = 0; }
136
        | '&'
137
                { $$ = 1; }
138
        ;
139
 
140
/* A generic operand.  */
141
 
142
generic_operand:
143
          '<' '<'
144
                {
145
                  op->mode = LSH;
146
                }
147
 
148
        | '>' '>'
149
                {
150
                  op->mode = RSH;
151
                }
152
 
153
        | DR
154
                {
155
                  op->mode = DREG;
156
                  op->reg = $1;
157
                }
158
        | AR
159
                {
160
                  op->mode = AREG;
161
                  op->reg = $1;
162
                }
163
        | FPR
164
                {
165
                  op->mode = FPREG;
166
                  op->reg = $1;
167
                }
168
        | FPCR
169
                {
170
                  op->mode = CONTROL;
171
                  op->reg = $1;
172
                }
173
        | CREG
174
                {
175
                  op->mode = CONTROL;
176
                  op->reg = $1;
177
                }
178
        | EXPR
179
                {
180
                  op->mode = ABSL;
181
                  op->disp = $1;
182
                }
183
        | '#' EXPR
184
                {
185
                  op->mode = IMMED;
186
                  op->disp = $2;
187
                }
188
        | '&' EXPR
189
                {
190
                  op->mode = IMMED;
191
                  op->disp = $2;
192
                }
193
        | reglist
194
                {
195
                  op->mode = REGLST;
196
                  op->mask = $1;
197
                }
198
        ;
199
 
200
/* An operand in Motorola syntax.  This includes MRI syntax as well,
201
   which may or may not be different in that it permits commutativity
202
   of index and base registers, and permits an offset expression to
203
   appear inside or outside of the parentheses.  */
204
 
205
motorola_operand:
206
          '(' AR ')'
207
                {
208
                  op->mode = AINDR;
209
                  op->reg = $2;
210
                }
211
        | '(' AR ')' '+'
212
                {
213
                  op->mode = AINC;
214
                  op->reg = $2;
215
                }
216
        | '-' '(' AR ')'
217
                {
218
                  op->mode = ADEC;
219
                  op->reg = $3;
220
                }
221
        | '(' EXPR ',' zapc ')'
222
                {
223
                  op->reg = $4;
224
                  op->disp = $2;
225
                  if (($4 >= ZADDR0 && $4 <= ZADDR7)
226
                      || $4 == ZPC)
227
                    op->mode = BASE;
228
                  else
229
                    op->mode = DISP;
230
                }
231
        | '(' zapc ',' EXPR ')'
232
                {
233
                  op->reg = $2;
234
                  op->disp = $4;
235
                  if (($2 >= ZADDR0 && $2 <= ZADDR7)
236
                      || $2 == ZPC)
237
                    op->mode = BASE;
238
                  else
239
                    op->mode = DISP;
240
                }
241
        | EXPR '(' zapc ')'
242
                {
243
                  op->reg = $3;
244
                  op->disp = $1;
245
                  if (($3 >= ZADDR0 && $3 <= ZADDR7)
246
                      || $3 == ZPC)
247
                    op->mode = BASE;
248
                  else
249
                    op->mode = DISP;
250
                }
251
        | '(' LPC ')'
252
                {
253
                  op->mode = DISP;
254
                  op->reg = $2;
255
                }
256
        | '(' ZAR ')'
257
                {
258
                  op->mode = BASE;
259
                  op->reg = $2;
260
                }
261
        | '(' LZPC ')'
262
                {
263
                  op->mode = BASE;
264
                  op->reg = $2;
265
                }
266
        | '(' EXPR ',' zapc ',' zireg ')'
267
                {
268
                  op->mode = BASE;
269
                  op->reg = $4;
270
                  op->disp = $2;
271
                  op->index = $6;
272
                }
273
        | '(' EXPR ',' zapc ',' zpc ')'
274
                {
275
                  if ($4 == PC || $4 == ZPC)
276
                    yyerror (_("syntax error"));
277
                  op->mode = BASE;
278
                  op->reg = $6;
279
                  op->disp = $2;
280
                  op->index.reg = $4;
281
                  op->index.size = SIZE_UNSPEC;
282
                  op->index.scale = 1;
283
                }
284
        | '(' EXPR ',' zdireg optczapc ')'
285
                {
286
                  op->mode = BASE;
287
                  op->reg = $5;
288
                  op->disp = $2;
289
                  op->index = $4;
290
                }
291
        | '(' zdireg ',' EXPR ')'
292
                {
293
                  op->mode = BASE;
294
                  op->disp = $4;
295
                  op->index = $2;
296
                }
297
        | EXPR '(' zapc ',' zireg ')'
298
                {
299
                  op->mode = BASE;
300
                  op->reg = $3;
301
                  op->disp = $1;
302
                  op->index = $5;
303
                }
304
        | '(' zapc ',' zireg ')'
305
                {
306
                  op->mode = BASE;
307
                  op->reg = $2;
308
                  op->index = $4;
309
                }
310
        | EXPR '(' zapc ',' zpc ')'
311
                {
312
                  if ($3 == PC || $3 == ZPC)
313
                    yyerror (_("syntax error"));
314
                  op->mode = BASE;
315
                  op->reg = $5;
316
                  op->disp = $1;
317
                  op->index.reg = $3;
318
                  op->index.size = SIZE_UNSPEC;
319
                  op->index.scale = 1;
320
                }
321
        | '(' zapc ',' zpc ')'
322
                {
323
                  if ($2 == PC || $2 == ZPC)
324
                    yyerror (_("syntax error"));
325
                  op->mode = BASE;
326
                  op->reg = $4;
327
                  op->index.reg = $2;
328
                  op->index.size = SIZE_UNSPEC;
329
                  op->index.scale = 1;
330
                }
331
        | EXPR '(' zdireg optczapc ')'
332
                {
333
                  op->mode = BASE;
334
                  op->reg = $4;
335
                  op->disp = $1;
336
                  op->index = $3;
337
                }
338
        | '(' zdireg optczapc ')'
339
                {
340
                  op->mode = BASE;
341
                  op->reg = $3;
342
                  op->index = $2;
343
                }
344
        | '(' '[' EXPR optczapc ']' ',' zireg optcexpr ')'
345
                {
346
                  op->mode = POST;
347
                  op->reg = $4;
348
                  op->disp = $3;
349
                  op->index = $7;
350
                  op->odisp = $8;
351
                }
352
        | '(' '[' EXPR optczapc ']' optcexpr ')'
353
                {
354
                  op->mode = POST;
355
                  op->reg = $4;
356
                  op->disp = $3;
357
                  op->odisp = $6;
358
                }
359
        | '(' '[' zapc ']' ',' zireg optcexpr ')'
360
                {
361
                  op->mode = POST;
362
                  op->reg = $3;
363
                  op->index = $6;
364
                  op->odisp = $7;
365
                }
366
        | '(' '[' zapc ']' optcexpr ')'
367
                {
368
                  op->mode = POST;
369
                  op->reg = $3;
370
                  op->odisp = $5;
371
                }
372
        | '(' '[' EXPR ',' zapc ',' zireg ']' optcexpr ')'
373
                {
374
                  op->mode = PRE;
375
                  op->reg = $5;
376
                  op->disp = $3;
377
                  op->index = $7;
378
                  op->odisp = $9;
379
                }
380
        | '(' '[' zapc ',' zireg ']' optcexpr ')'
381
                {
382
                  op->mode = PRE;
383
                  op->reg = $3;
384
                  op->index = $5;
385
                  op->odisp = $7;
386
                }
387
        | '(' '[' EXPR ',' zapc ',' zpc ']' optcexpr ')'
388
                {
389
                  if ($5 == PC || $5 == ZPC)
390
                    yyerror (_("syntax error"));
391
                  op->mode = PRE;
392
                  op->reg = $7;
393
                  op->disp = $3;
394
                  op->index.reg = $5;
395
                  op->index.size = SIZE_UNSPEC;
396
                  op->index.scale = 1;
397
                  op->odisp = $9;
398
                }
399
        | '(' '[' zapc ',' zpc ']' optcexpr ')'
400
                {
401
                  if ($3 == PC || $3 == ZPC)
402
                    yyerror (_("syntax error"));
403
                  op->mode = PRE;
404
                  op->reg = $5;
405
                  op->index.reg = $3;
406
                  op->index.size = SIZE_UNSPEC;
407
                  op->index.scale = 1;
408
                  op->odisp = $7;
409
                }
410
        | '(' '[' optexprc zdireg optczapc ']' optcexpr ')'
411
                {
412
                  op->mode = PRE;
413
                  op->reg = $5;
414
                  op->disp = $3;
415
                  op->index = $4;
416
                  op->odisp = $7;
417
                }
418
        ;
419
 
420
/* An operand in MIT syntax.  */
421
 
422
mit_operand:
423
          optzapc '@'
424
                {
425
                  /* We use optzapc to avoid a shift/reduce conflict.  */
426
                  if ($1 < ADDR0 || $1 > ADDR7)
427
                    yyerror (_("syntax error"));
428
                  op->mode = AINDR;
429
                  op->reg = $1;
430
                }
431
        | optzapc '@' '+'
432
                {
433
                  /* We use optzapc to avoid a shift/reduce conflict.  */
434
                  if ($1 < ADDR0 || $1 > ADDR7)
435
                    yyerror (_("syntax error"));
436
                  op->mode = AINC;
437
                  op->reg = $1;
438
                }
439
        | optzapc '@' '-'
440
                {
441
                  /* We use optzapc to avoid a shift/reduce conflict.  */
442
                  if ($1 < ADDR0 || $1 > ADDR7)
443
                    yyerror (_("syntax error"));
444
                  op->mode = ADEC;
445
                  op->reg = $1;
446
                }
447
        | optzapc '@' '(' EXPR ')'
448
                {
449
                  op->reg = $1;
450
                  op->disp = $4;
451
                  if (($1 >= ZADDR0 && $1 <= ZADDR7)
452
                      || $1 == ZPC)
453
                    op->mode = BASE;
454
                  else
455
                    op->mode = DISP;
456
                }
457
        | optzapc '@' '(' optexprc zireg ')'
458
                {
459
                  op->mode = BASE;
460
                  op->reg = $1;
461
                  op->disp = $4;
462
                  op->index = $5;
463
                }
464
        | optzapc '@' '(' EXPR ')' '@' '(' optexprc zireg ')'
465
                {
466
                  op->mode = POST;
467
                  op->reg = $1;
468
                  op->disp = $4;
469
                  op->index = $9;
470
                  op->odisp = $8;
471
                }
472
        | optzapc '@' '(' EXPR ')' '@' '(' EXPR ')'
473
                {
474
                  op->mode = POST;
475
                  op->reg = $1;
476
                  op->disp = $4;
477
                  op->odisp = $8;
478
                }
479
        | optzapc '@' '(' optexprc zireg ')' '@' '(' EXPR ')'
480
                {
481
                  op->mode = PRE;
482
                  op->reg = $1;
483
                  op->disp = $4;
484
                  op->index = $5;
485
                  op->odisp = $9;
486
                }
487
        ;
488
 
489
/* An index register, possibly suppressed, which need not have a size
490
   or scale.  */
491
 
492
zireg:
493
          INDEXREG
494
        | zadr
495
                {
496
                  $$.reg = $1;
497
                  $$.size = SIZE_UNSPEC;
498
                  $$.scale = 1;
499
                }
500
        ;
501
 
502
/* A register which may be an index register, but which may not be an
503
   address register.  This nonterminal is used to avoid ambiguity when
504
   trying to parse something like (0,d5,a6) as compared to (0,a6,d5).  */
505
 
506
zdireg:
507
          INDEXREG
508
        | zdr
509
                {
510
                  $$.reg = $1;
511
                  $$.size = SIZE_UNSPEC;
512
                  $$.scale = 1;
513
                }
514
        ;
515
 
516
/* An address or data register, or a suppressed address or data
517
   register.  */
518
 
519
zadr:
520
          zdr
521
        | AR
522
        | ZAR
523
        ;
524
 
525
/* A data register which may be suppressed.  */
526
 
527
zdr:
528
          DR
529
        | ZDR
530
        ;
531
 
532
/* Either an address register or the PC.  */
533
 
534
apc:
535
          AR
536
        | LPC
537
        ;
538
 
539
/* Either an address register, or the PC, or a suppressed address
540
   register, or a suppressed PC.  */
541
 
542
zapc:
543
          apc
544
        | LZPC
545
        | ZAR
546
        ;
547
 
548
/* An optional zapc.  */
549
 
550
optzapc:
551
          /* empty */
552
                {
553
                  $$ = ZADDR0;
554
                }
555
        | zapc
556
        ;
557
 
558
/* The PC, optionally suppressed.  */
559
 
560
zpc:
561
          LPC
562
        | LZPC
563
        ;
564
 
565
/* ',' zapc when it may be omitted.  */
566
 
567
optczapc:
568
          /* empty */
569
                {
570
                  $$ = ZADDR0;
571
                }
572
        | ',' zapc
573
                {
574
                  $$ = $2;
575
                }
576
        ;
577
 
578
/* ',' EXPR when it may be omitted.  */
579
 
580
optcexpr:
581
          /* empty */
582
                {
583
                  $$.exp.X_op = O_absent;
584
                  $$.size = SIZE_UNSPEC;
585
                }
586
        | ',' EXPR
587
                {
588
                  $$ = $2;
589
                }
590
        ;
591
 
592
/* EXPR ',' when it may be omitted.  */
593
 
594
optexprc:
595
          /* empty */
596
                {
597
                  $$.exp.X_op = O_absent;
598
                  $$.size = SIZE_UNSPEC;
599
                }
600
        | EXPR ','
601
                {
602
                  $$ = $1;
603
                }
604
        ;
605
 
606
/* A register list for the movem instruction.  */
607
 
608
reglist:
609
          reglistpair
610
        | reglistpair '/' ireglist
611
                {
612
                  $$ = $1 | $3;
613
                }
614
        | reglistreg '/' ireglist
615
                {
616
                  $$ = (1 << $1) | $3;
617
                }
618
        ;
619
 
620
/* We use ireglist when we know we are looking at a reglist, and we
621
   can safely reduce a simple register to reglistreg.  If we permitted
622
   reglist to reduce to reglistreg, it would be ambiguous whether a
623
   plain register were a DREG/AREG/FPREG or a REGLST.  */
624
 
625
ireglist:
626
          reglistreg
627
                {
628
                  $$ = 1 << $1;
629
                }
630
        | reglistpair
631
        | reglistpair '/' ireglist
632
                {
633
                  $$ = $1 | $3;
634
                }
635
        | reglistreg '/' ireglist
636
                {
637
                  $$ = (1 << $1) | $3;
638
                }
639
        ;
640
 
641
reglistpair:
642
          reglistreg '-' reglistreg
643
                {
644
                  if ($1 <= $3)
645
                    $$ = (1 << ($3 + 1)) - 1 - ((1 << $1) - 1);
646
                  else
647
                    $$ = (1 << ($1 + 1)) - 1 - ((1 << $3) - 1);
648
                }
649
        ;
650
 
651
reglistreg:
652
          DR
653
                {
654
                  $$ = $1 - DATA0;
655
                }
656
        | AR
657
                {
658
                  $$ = $1 - ADDR0 + 8;
659
                }
660
        | FPR
661
                {
662
                  $$ = $1 - FP0 + 16;
663
                }
664
        | FPCR
665
                {
666
                  if ($1 == FPI)
667
                    $$ = 24;
668
                  else if ($1 == FPS)
669
                    $$ = 25;
670
                  else
671
                    $$ = 26;
672
                }
673
        ;
674
 
675
%%
676
 
677
/* The string to parse is stored here, and modified by yylex.  */
678
 
679
static char *str;
680
 
681
/* The original string pointer.  */
682
 
683
static char *strorig;
684
 
685
/* If *CCP could be a register, return the register number and advance
686
   *CCP.  Otherwise don't change *CCP, and return 0.  */
687
 
688
static enum m68k_register
689
m68k_reg_parse (ccp)
690
     register char **ccp;
691
{
692
  char *start = *ccp;
693
  char c;
694
  char *p;
695
  symbolS *symbolp;
696
 
697
  if (flag_reg_prefix_optional)
698
    {
699
      if (*start == REGISTER_PREFIX)
700
        start++;
701
      p = start;
702
    }
703
  else
704
    {
705
      if (*start != REGISTER_PREFIX)
706
        return 0;
707
      p = start + 1;
708
    }
709
 
710
  if (! is_name_beginner (*p))
711
    return 0;
712
 
713
  p++;
714
  while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
715
    p++;
716
 
717
  c = *p;
718
  *p = 0;
719
  symbolp = symbol_find (start);
720
  *p = c;
721
 
722
  if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
723
    {
724
      *ccp = p;
725
      return S_GET_VALUE (symbolp);
726
    }
727
 
728
  /* In MRI mode, something like foo.bar can be equated to a register
729
     name.  */
730
  while (flag_mri && c == '.')
731
    {
732
      ++p;
733
      while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
734
        p++;
735
      c = *p;
736
      *p = '\0';
737
      symbolp = symbol_find (start);
738
      *p = c;
739
      if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
740
        {
741
          *ccp = p;
742
          return S_GET_VALUE (symbolp);
743
        }
744
    }
745
 
746
  return 0;
747
}
748
 
749
/* The lexer.  */
750
 
751
static int
752
yylex ()
753
{
754
  enum m68k_register reg;
755
  char *s;
756
  int parens;
757
  int c = 0;
758
  int tail = 0;
759
  char *hold;
760
 
761
  if (*str == ' ')
762
    ++str;
763
 
764
  if (*str == '\0')
765
    return 0;
766
 
767
  /* Various special characters are just returned directly.  */
768
  switch (*str)
769
    {
770
    case '@':
771
      /* In MRI mode, this can be the start of an octal number.  */
772
      if (flag_mri)
773
        {
774
          if (ISDIGIT (str[1])
775
              || ((str[1] == '+' || str[1] == '-')
776
                  && ISDIGIT (str[2])))
777
            break;
778
        }
779
      /* Fall through.  */
780
    case '#':
781
    case '&':
782
    case ',':
783
    case ')':
784
    case '/':
785
    case '[':
786
    case ']':
787
    case '<':
788
    case '>':
789
      return *str++;
790
    case '+':
791
      /* It so happens that a '+' can only appear at the end of an
792
         operand, or if it is trailed by an '&'(see mac load insn).
793
         If it appears anywhere else, it must be a unary.  */
794
      if (str[1] == '\0' || (str[1] == '&' && str[2] == '\0'))
795
        return *str++;
796
      break;
797
    case '-':
798
      /* A '-' can only appear in -(ar), rn-rn, or ar@-.  If it
799
         appears anywhere else, it must be a unary minus on an
800
         expression, unless it it trailed by a '&'(see mac load insn).  */
801
      if (str[1] == '\0' || (str[1] == '&' && str[2] == '\0'))
802
        return *str++;
803
      s = str + 1;
804
      if (*s == '(')
805
        ++s;
806
      if (m68k_reg_parse (&s) != 0)
807
        return *str++;
808
      break;
809
    case '(':
810
      /* A '(' can only appear in `(reg)', `(expr,...', `([', `@(', or
811
         `)('.  If it appears anywhere else, it must be starting an
812
         expression.  */
813
      if (str[1] == '['
814
          || (str > strorig
815
              && (str[-1] == '@'
816
                  || str[-1] == ')')))
817
        return *str++;
818
      s = str + 1;
819
      if (m68k_reg_parse (&s) != 0)
820
        return *str++;
821
      /* Check for the case of '(expr,...' by scanning ahead.  If we
822
         find a comma outside of balanced parentheses, we return '('.
823
         If we find an unbalanced right parenthesis, then presumably
824
         the '(' really starts an expression.  */
825
      parens = 0;
826
      for (s = str + 1; *s != '\0'; s++)
827
        {
828
          if (*s == '(')
829
            ++parens;
830
          else if (*s == ')')
831
            {
832
              if (parens == 0)
833
                break;
834
              --parens;
835
            }
836
          else if (*s == ',' && parens == 0)
837
            {
838
              /* A comma can not normally appear in an expression, so
839
                 this is a case of '(expr,...'.  */
840
              return *str++;
841
            }
842
        }
843
    }
844
 
845
  /* See if it's a register.  */
846
 
847
  reg = m68k_reg_parse (&str);
848
  if (reg != 0)
849
    {
850
      int ret;
851
 
852
      yylval.reg = reg;
853
 
854
      if (reg >= DATA0 && reg <= DATA7)
855
        ret = DR;
856
      else if (reg >= ADDR0 && reg <= ADDR7)
857
        ret = AR;
858
      else if (reg >= FP0 && reg <= FP7)
859
        return FPR;
860
      else if (reg == FPI
861
               || reg == FPS
862
               || reg == FPC)
863
        return FPCR;
864
      else if (reg == PC)
865
        return LPC;
866
      else if (reg >= ZDATA0 && reg <= ZDATA7)
867
        ret = ZDR;
868
      else if (reg >= ZADDR0 && reg <= ZADDR7)
869
        ret = ZAR;
870
      else if (reg == ZPC)
871
        return LZPC;
872
      else
873
        return CREG;
874
 
875
      /* If we get here, we have a data or address register.  We
876
         must check for a size or scale; if we find one, we must
877
         return INDEXREG.  */
878
 
879
      s = str;
880
 
881
      if (*s != '.' && *s != ':' && *s != '*')
882
        return ret;
883
 
884
      yylval.indexreg.reg = reg;
885
 
886
      if (*s != '.' && *s != ':')
887
        yylval.indexreg.size = SIZE_UNSPEC;
888
      else
889
        {
890
          ++s;
891
          switch (*s)
892
            {
893
            case 'w':
894
            case 'W':
895
              yylval.indexreg.size = SIZE_WORD;
896
              ++s;
897
              break;
898
            case 'l':
899
            case 'L':
900
              yylval.indexreg.size = SIZE_LONG;
901
              ++s;
902
              break;
903
            default:
904
              yyerror (_("illegal size specification"));
905
              yylval.indexreg.size = SIZE_UNSPEC;
906
              break;
907
            }
908
        }
909
 
910
      yylval.indexreg.scale = 1;
911
 
912
      if (*s == '*' || *s == ':')
913
        {
914
          expressionS scale;
915
 
916
          ++s;
917
 
918
          hold = input_line_pointer;
919
          input_line_pointer = s;
920
          expression (&scale);
921
          s = input_line_pointer;
922
          input_line_pointer = hold;
923
 
924
          if (scale.X_op != O_constant)
925
            yyerror (_("scale specification must resolve to a number"));
926
          else
927
            {
928
              switch (scale.X_add_number)
929
                {
930
                case 1:
931
                case 2:
932
                case 4:
933
                case 8:
934
                  yylval.indexreg.scale = scale.X_add_number;
935
                  break;
936
                default:
937
                  yyerror (_("invalid scale value"));
938
                  break;
939
                }
940
            }
941
        }
942
 
943
      str = s;
944
 
945
      return INDEXREG;
946
    }
947
 
948
  /* It must be an expression.  Before we call expression, we need to
949
     look ahead to see if there is a size specification.  We must do
950
     that first, because otherwise foo.l will be treated as the symbol
951
     foo.l, rather than as the symbol foo with a long size
952
     specification.  The grammar requires that all expressions end at
953
     the end of the operand, or with ',', '(', ']', ')'.  */
954
 
955
  parens = 0;
956
  for (s = str; *s != '\0'; s++)
957
    {
958
      if (*s == '(')
959
        {
960
          if (parens == 0
961
              && s > str
962
              && (s[-1] == ')' || ISALNUM (s[-1])))
963
            break;
964
          ++parens;
965
        }
966
      else if (*s == ')')
967
        {
968
          if (parens == 0)
969
            break;
970
          --parens;
971
        }
972
      else if (parens == 0
973
               && (*s == ',' || *s == ']'))
974
        break;
975
    }
976
 
977
  yylval.exp.size = SIZE_UNSPEC;
978
  if (s <= str + 2
979
      || (s[-2] != '.' && s[-2] != ':'))
980
    tail = 0;
981
  else
982
    {
983
      switch (s[-1])
984
        {
985
        case 's':
986
        case 'S':
987
        case 'b':
988
        case 'B':
989
          yylval.exp.size = SIZE_BYTE;
990
          break;
991
        case 'w':
992
        case 'W':
993
          yylval.exp.size = SIZE_WORD;
994
          break;
995
        case 'l':
996
        case 'L':
997
          yylval.exp.size = SIZE_LONG;
998
          break;
999
        default:
1000
          break;
1001
        }
1002
      if (yylval.exp.size != SIZE_UNSPEC)
1003
        tail = 2;
1004
    }
1005
 
1006
#ifdef OBJ_ELF
1007
  {
1008
    /* Look for @PLTPC, etc.  */
1009
    char *cp;
1010
 
1011
    yylval.exp.pic_reloc = pic_none;
1012
    cp = s - tail;
1013
    if (cp - 6 > str && cp[-6] == '@')
1014
      {
1015
        if (strncmp (cp - 6, "@PLTPC", 6) == 0)
1016
          {
1017
            yylval.exp.pic_reloc = pic_plt_pcrel;
1018
            tail += 6;
1019
          }
1020
        else if (strncmp (cp - 6, "@GOTPC", 6) == 0)
1021
          {
1022
            yylval.exp.pic_reloc = pic_got_pcrel;
1023
            tail += 6;
1024
          }
1025
      }
1026
    else if (cp - 4 > str && cp[-4] == '@')
1027
      {
1028
        if (strncmp (cp - 4, "@PLT", 4) == 0)
1029
          {
1030
            yylval.exp.pic_reloc = pic_plt_off;
1031
            tail += 4;
1032
          }
1033
        else if (strncmp (cp - 4, "@GOT", 4) == 0)
1034
          {
1035
            yylval.exp.pic_reloc = pic_got_off;
1036
            tail += 4;
1037
          }
1038
      }
1039
  }
1040
#endif
1041
 
1042
  if (tail != 0)
1043
    {
1044
      c = s[-tail];
1045
      s[-tail] = 0;
1046
    }
1047
 
1048
  hold = input_line_pointer;
1049
  input_line_pointer = str;
1050
  expression (&yylval.exp.exp);
1051
  str = input_line_pointer;
1052
  input_line_pointer = hold;
1053
 
1054
  if (tail != 0)
1055
    {
1056
      s[-tail] = c;
1057
      str = s;
1058
    }
1059
 
1060
  return EXPR;
1061
}
1062
 
1063
/* Parse an m68k operand.  This is the only function which is called
1064
   from outside this file.  */
1065
 
1066
int
1067
m68k_ip_op (s, oparg)
1068
     char *s;
1069
     struct m68k_op *oparg;
1070
{
1071
  memset (oparg, 0, sizeof *oparg);
1072
  oparg->error = NULL;
1073
  oparg->index.reg = ZDATA0;
1074
  oparg->index.scale = 1;
1075
  oparg->disp.exp.X_op = O_absent;
1076
  oparg->odisp.exp.X_op = O_absent;
1077
 
1078
  str = strorig = s;
1079
  op = oparg;
1080
 
1081
  return yyparse ();
1082
}
1083
 
1084
/* The error handler.  */
1085
 
1086
static void
1087
yyerror (s)
1088
     const char *s;
1089
{
1090
  op->error = s;
1091
}

powered by: WebSVN 2.1.0

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