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