Add support for ColdFire MAC instructions and tidy up support for other m68k
[external/binutils.git] / gas / config / m68k-parse.y
1 /* m68k.y -- bison grammar for m68k operand parsing
2    Copyright 1995, 1996, 1997, 1998, 2001 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 2, 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, 59 Temple Place - Suite 330, Boston, MA
20    02111-1307, 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 PARAMS ((char **));
86 static int yylex PARAMS ((void));
87 static void yyerror PARAMS ((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
126         ;
127
128 /* A trailing ampersand(for MAC/EMAC mask addressing).  */
129 optional_ampersand:
130         /* empty */
131                 { $$ = 0; }
132         | '&'
133                 { $$ = 1; }
134         ;
135
136 /* A generic operand.  */
137
138 generic_operand:
139           '<' '<'
140                 {
141                   op->mode = LSH;
142                 }
143
144         | '>' '>'
145                 {
146                   op->mode = RSH;
147                 }
148
149         | DR
150                 {
151                   op->mode = DREG;
152                   op->reg = $1;
153                 }
154         | AR
155                 {
156                   op->mode = AREG;
157                   op->reg = $1;
158                 }
159         | FPR
160                 {
161                   op->mode = FPREG;
162                   op->reg = $1;
163                 }
164         | FPCR
165                 {
166                   op->mode = CONTROL;
167                   op->reg = $1;
168                 }
169         | CREG
170                 {
171                   op->mode = CONTROL;
172                   op->reg = $1;
173                 }
174         | EXPR
175                 {
176                   op->mode = ABSL;
177                   op->disp = $1;
178                 }
179         | '#' EXPR
180                 {
181                   op->mode = IMMED;
182                   op->disp = $2;
183                 }
184         | '&' EXPR
185                 {
186                   op->mode = IMMED;
187                   op->disp = $2;
188                 }
189         | reglist
190                 {
191                   op->mode = REGLST;
192                   op->mask = $1;
193                 }
194         ;
195
196 /* An operand in Motorola syntax.  This includes MRI syntax as well,
197    which may or may not be different in that it permits commutativity
198    of index and base registers, and permits an offset expression to
199    appear inside or outside of the parentheses.  */
200
201 motorola_operand:
202           '(' AR ')'
203                 {
204                   op->mode = AINDR;
205                   op->reg = $2;
206                 }
207         | '(' AR ')' '+'
208                 {
209                   op->mode = AINC;
210                   op->reg = $2;
211                 }
212         | '-' '(' AR ')'
213                 {
214                   op->mode = ADEC;
215                   op->reg = $3;
216                 }
217         | '(' EXPR ',' zapc ')'
218                 {
219                   op->reg = $4;
220                   op->disp = $2;
221                   if (($4 >= ZADDR0 && $4 <= ZADDR7)
222                       || $4 == ZPC)
223                     op->mode = BASE;
224                   else
225                     op->mode = DISP;
226                 }
227         | '(' zapc ',' EXPR ')'
228                 {
229                   op->reg = $2;
230                   op->disp = $4;
231                   if (($2 >= ZADDR0 && $2 <= ZADDR7)
232                       || $2 == ZPC)
233                     op->mode = BASE;
234                   else
235                     op->mode = DISP;
236                 }
237         | EXPR '(' zapc ')'
238                 {
239                   op->reg = $3;
240                   op->disp = $1;
241                   if (($3 >= ZADDR0 && $3 <= ZADDR7)
242                       || $3 == ZPC)
243                     op->mode = BASE;
244                   else
245                     op->mode = DISP;
246                 }
247         | '(' LPC ')'
248                 {
249                   op->mode = DISP;
250                   op->reg = $2;
251                 }
252         | '(' ZAR ')'
253                 {
254                   op->mode = BASE;
255                   op->reg = $2;
256                 }
257         | '(' LZPC ')'
258                 {
259                   op->mode = BASE;
260                   op->reg = $2;
261                 }
262         | '(' EXPR ',' zapc ',' zireg ')'
263                 {
264                   op->mode = BASE;
265                   op->reg = $4;
266                   op->disp = $2;
267                   op->index = $6;
268                 }
269         | '(' EXPR ',' zapc ',' zpc ')'
270                 {
271                   if ($4 == PC || $4 == ZPC)
272                     yyerror (_("syntax error"));
273                   op->mode = BASE;
274                   op->reg = $6;
275                   op->disp = $2;
276                   op->index.reg = $4;
277                   op->index.size = SIZE_UNSPEC;
278                   op->index.scale = 1;
279                 }
280         | '(' EXPR ',' zdireg optczapc ')'
281                 {
282                   op->mode = BASE;
283                   op->reg = $5;
284                   op->disp = $2;
285                   op->index = $4;
286                 }
287         | '(' zdireg ',' EXPR ')'
288                 {
289                   op->mode = BASE;
290                   op->disp = $4;
291                   op->index = $2;
292                 }
293         | EXPR '(' zapc ',' zireg ')'
294                 {
295                   op->mode = BASE;
296                   op->reg = $3;
297                   op->disp = $1;
298                   op->index = $5;
299                 }
300         | '(' zapc ',' zireg ')'
301                 {
302                   op->mode = BASE;
303                   op->reg = $2;
304                   op->index = $4;
305                 }
306         | EXPR '(' zapc ',' zpc ')'
307                 {
308                   if ($3 == PC || $3 == ZPC)
309                     yyerror (_("syntax error"));
310                   op->mode = BASE;
311                   op->reg = $5;
312                   op->disp = $1;
313                   op->index.reg = $3;
314                   op->index.size = SIZE_UNSPEC;
315                   op->index.scale = 1;
316                 }
317         | '(' zapc ',' zpc ')'
318                 {
319                   if ($2 == PC || $2 == ZPC)
320                     yyerror (_("syntax error"));
321                   op->mode = BASE;
322                   op->reg = $4;
323                   op->index.reg = $2;
324                   op->index.size = SIZE_UNSPEC;
325                   op->index.scale = 1;
326                 }
327         | EXPR '(' zdireg optczapc ')'
328                 {
329                   op->mode = BASE;
330                   op->reg = $4;
331                   op->disp = $1;
332                   op->index = $3;
333                 }
334         | '(' zdireg optczapc ')'
335                 {
336                   op->mode = BASE;
337                   op->reg = $3;
338                   op->index = $2;
339                 }
340         | '(' '[' EXPR optczapc ']' ',' zireg optcexpr ')'
341                 {
342                   op->mode = POST;
343                   op->reg = $4;
344                   op->disp = $3;
345                   op->index = $7;
346                   op->odisp = $8;
347                 }
348         | '(' '[' EXPR optczapc ']' optcexpr ')'
349                 {
350                   op->mode = POST;
351                   op->reg = $4;
352                   op->disp = $3;
353                   op->odisp = $6;
354                 }
355         | '(' '[' zapc ']' ',' zireg optcexpr ')'
356                 {
357                   op->mode = POST;
358                   op->reg = $3;
359                   op->index = $6;
360                   op->odisp = $7;
361                 }
362         | '(' '[' zapc ']' optcexpr ')'
363                 {
364                   op->mode = POST;
365                   op->reg = $3;
366                   op->odisp = $5;
367                 }
368         | '(' '[' EXPR ',' zapc ',' zireg ']' optcexpr ')'
369                 {
370                   op->mode = PRE;
371                   op->reg = $5;
372                   op->disp = $3;
373                   op->index = $7;
374                   op->odisp = $9;
375                 }
376         | '(' '[' zapc ',' zireg ']' optcexpr ')'
377                 {
378                   op->mode = PRE;
379                   op->reg = $3;
380                   op->index = $5;
381                   op->odisp = $7;
382                 }
383         | '(' '[' EXPR ',' zapc ',' zpc ']' optcexpr ')'
384                 {
385                   if ($5 == PC || $5 == ZPC)
386                     yyerror (_("syntax error"));
387                   op->mode = PRE;
388                   op->reg = $7;
389                   op->disp = $3;
390                   op->index.reg = $5;
391                   op->index.size = SIZE_UNSPEC;
392                   op->index.scale = 1;
393                   op->odisp = $9;
394                 }
395         | '(' '[' zapc ',' zpc ']' optcexpr ')'
396                 {
397                   if ($3 == PC || $3 == ZPC)
398                     yyerror (_("syntax error"));
399                   op->mode = PRE;
400                   op->reg = $5;
401                   op->index.reg = $3;
402                   op->index.size = SIZE_UNSPEC;
403                   op->index.scale = 1;
404                   op->odisp = $7;
405                 }
406         | '(' '[' optexprc zdireg optczapc ']' optcexpr ')'
407                 {
408                   op->mode = PRE;
409                   op->reg = $5;
410                   op->disp = $3;
411                   op->index = $4;
412                   op->odisp = $7;
413                 }
414         ;
415
416 /* An operand in MIT syntax.  */
417
418 mit_operand:
419           optzapc '@'
420                 {
421                   /* We use optzapc to avoid a shift/reduce conflict.  */
422                   if ($1 < ADDR0 || $1 > ADDR7)
423                     yyerror (_("syntax error"));
424                   op->mode = AINDR;
425                   op->reg = $1;
426                 }
427         | optzapc '@' '+'
428                 {
429                   /* We use optzapc to avoid a shift/reduce conflict.  */
430                   if ($1 < ADDR0 || $1 > ADDR7)
431                     yyerror (_("syntax error"));
432                   op->mode = AINC;
433                   op->reg = $1;
434                 }
435         | optzapc '@' '-'
436                 {
437                   /* We use optzapc to avoid a shift/reduce conflict.  */
438                   if ($1 < ADDR0 || $1 > ADDR7)
439                     yyerror (_("syntax error"));
440                   op->mode = ADEC;
441                   op->reg = $1;
442                 }
443         | optzapc '@' '(' EXPR ')'
444                 {
445                   op->reg = $1;
446                   op->disp = $4;
447                   if (($1 >= ZADDR0 && $1 <= ZADDR7)
448                       || $1 == ZPC)
449                     op->mode = BASE;
450                   else
451                     op->mode = DISP;
452                 }
453         | optzapc '@' '(' optexprc zireg ')'
454                 {
455                   op->mode = BASE;
456                   op->reg = $1;
457                   op->disp = $4;
458                   op->index = $5;
459                 }
460         | optzapc '@' '(' EXPR ')' '@' '(' optexprc zireg ')'
461                 {
462                   op->mode = POST;
463                   op->reg = $1;
464                   op->disp = $4;
465                   op->index = $9;
466                   op->odisp = $8;
467                 }
468         | optzapc '@' '(' EXPR ')' '@' '(' EXPR ')'
469                 {
470                   op->mode = POST;
471                   op->reg = $1;
472                   op->disp = $4;
473                   op->odisp = $8;
474                 }
475         | optzapc '@' '(' optexprc zireg ')' '@' '(' EXPR ')'
476                 {
477                   op->mode = PRE;
478                   op->reg = $1;
479                   op->disp = $4;
480                   op->index = $5;
481                   op->odisp = $9;
482                 }
483         ;
484
485 /* An index register, possibly suppressed, which need not have a size
486    or scale.  */
487
488 zireg:
489           INDEXREG
490         | zadr
491                 {
492                   $$.reg = $1;
493                   $$.size = SIZE_UNSPEC;
494                   $$.scale = 1;
495                 }
496         ;
497
498 /* A register which may be an index register, but which may not be an
499    address register.  This nonterminal is used to avoid ambiguity when
500    trying to parse something like (0,d5,a6) as compared to (0,a6,d5).  */
501
502 zdireg:
503           INDEXREG
504         | zdr
505                 {
506                   $$.reg = $1;
507                   $$.size = SIZE_UNSPEC;
508                   $$.scale = 1;
509                 }
510         ;
511
512 /* An address or data register, or a suppressed address or data
513    register.  */
514
515 zadr:
516           zdr
517         | AR
518         | ZAR
519         ;
520
521 /* A data register which may be suppressed.  */
522
523 zdr:
524           DR
525         | ZDR
526         ;
527
528 /* Either an address register or the PC.  */
529
530 apc:
531           AR
532         | LPC
533         ;
534
535 /* Either an address register, or the PC, or a suppressed address
536    register, or a suppressed PC.  */
537
538 zapc:
539           apc
540         | LZPC
541         | ZAR
542         ;
543
544 /* An optional zapc.  */
545
546 optzapc:
547           /* empty */
548                 {
549                   $$ = ZADDR0;
550                 }
551         | zapc
552         ;
553
554 /* The PC, optionally suppressed.  */
555
556 zpc:
557           LPC
558         | LZPC
559         ;
560
561 /* ',' zapc when it may be omitted.  */
562
563 optczapc:
564           /* empty */
565                 {
566                   $$ = ZADDR0;
567                 }
568         | ',' zapc
569                 {
570                   $$ = $2;
571                 }
572         ;
573
574 /* ',' EXPR when it may be omitted.  */
575
576 optcexpr:
577           /* empty */
578                 {
579                   $$.exp.X_op = O_absent;
580                   $$.size = SIZE_UNSPEC;
581                 }
582         | ',' EXPR
583                 {
584                   $$ = $2;
585                 }
586         ;
587
588 /* EXPR ',' when it may be omitted.  */
589
590 optexprc:
591           /* empty */
592                 {
593                   $$.exp.X_op = O_absent;
594                   $$.size = SIZE_UNSPEC;
595                 }
596         | EXPR ','
597                 {
598                   $$ = $1;
599                 }
600         ;
601
602 /* A register list for the movem instruction.  */
603
604 reglist:
605           reglistpair
606         | reglistpair '/' ireglist
607                 {
608                   $$ = $1 | $3;
609                 }
610         | reglistreg '/' ireglist
611                 {
612                   $$ = (1 << $1) | $3;
613                 }
614         ;
615
616 /* We use ireglist when we know we are looking at a reglist, and we
617    can safely reduce a simple register to reglistreg.  If we permitted
618    reglist to reduce to reglistreg, it would be ambiguous whether a
619    plain register were a DREG/AREG/FPREG or a REGLST.  */
620
621 ireglist:
622           reglistreg
623                 {
624                   $$ = 1 << $1;
625                 }
626         | reglistpair
627         | reglistpair '/' ireglist
628                 {
629                   $$ = $1 | $3;
630                 }
631         | reglistreg '/' ireglist
632                 {
633                   $$ = (1 << $1) | $3;
634                 }
635         ;
636
637 reglistpair:
638           reglistreg '-' reglistreg
639                 {
640                   if ($1 <= $3)
641                     $$ = (1 << ($3 + 1)) - 1 - ((1 << $1) - 1);
642                   else
643                     $$ = (1 << ($1 + 1)) - 1 - ((1 << $3) - 1);
644                 }
645         ;
646
647 reglistreg:
648           DR
649                 {
650                   $$ = $1 - DATA0;
651                 }
652         | AR
653                 {
654                   $$ = $1 - ADDR0 + 8;
655                 }
656         | FPR
657                 {
658                   $$ = $1 - FP0 + 16;
659                 }
660         | FPCR
661                 {
662                   if ($1 == FPI)
663                     $$ = 24;
664                   else if ($1 == FPS)
665                     $$ = 25;
666                   else
667                     $$ = 26;
668                 }
669         ;
670
671 %%
672
673 /* The string to parse is stored here, and modified by yylex.  */
674
675 static char *str;
676
677 /* The original string pointer.  */
678
679 static char *strorig;
680
681 /* If *CCP could be a register, return the register number and advance
682    *CCP.  Otherwise don't change *CCP, and return 0.  */
683
684 static enum m68k_register
685 m68k_reg_parse (ccp)
686      register char **ccp;
687 {
688   char *start = *ccp;
689   char c;
690   char *p;
691   symbolS *symbolp;
692
693   if (flag_reg_prefix_optional)
694     {
695       if (*start == REGISTER_PREFIX)
696         start++;
697       p = start;
698     }
699   else
700     {
701       if (*start != REGISTER_PREFIX)
702         return 0;
703       p = start + 1;
704     }
705
706   if (! is_name_beginner (*p))
707     return 0;
708
709   p++;
710   while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
711     p++;
712
713   c = *p;
714   *p = 0;
715   symbolp = symbol_find (start);
716   *p = c;
717
718   if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
719     {
720       *ccp = p;
721       return S_GET_VALUE (symbolp);
722     }
723
724   /* In MRI mode, something like foo.bar can be equated to a register
725      name.  */
726   while (flag_mri && c == '.')
727     {
728       ++p;
729       while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
730         p++;
731       c = *p;
732       *p = '\0';
733       symbolp = symbol_find (start);
734       *p = c;
735       if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
736         {
737           *ccp = p;
738           return S_GET_VALUE (symbolp);
739         }
740     }
741
742   return 0;
743 }
744
745 /* The lexer.  */
746
747 static int
748 yylex ()
749 {
750   enum m68k_register reg;
751   char *s;
752   int parens;
753   int c = 0;
754   int tail = 0;
755   char *hold;
756
757   if (*str == ' ')
758     ++str;
759
760   if (*str == '\0')
761     return 0;
762
763   /* Various special characters are just returned directly.  */
764   switch (*str)
765     {
766     case '@':
767       /* In MRI mode, this can be the start of an octal number.  */
768       if (flag_mri)
769         {
770           if (ISDIGIT (str[1])
771               || ((str[1] == '+' || str[1] == '-')
772                   && ISDIGIT (str[2])))
773             break;
774         }
775       /* Fall through.  */
776     case '#':
777     case '&':
778     case ',':
779     case ')':
780     case '/':
781     case '[':
782     case ']':
783     case '<':
784     case '>':
785       return *str++;
786     case '+':
787       /* It so happens that a '+' can only appear at the end of an
788          operand, or if it is trailed by an '&'(see mac load insn).
789          If it appears anywhere else, it must be a unary.  */
790       if (str[1] == '\0' || (str[1] == '&' && str[2] == '\0'))
791         return *str++;
792       break;
793     case '-':
794       /* A '-' can only appear in -(ar), rn-rn, or ar@-.  If it
795          appears anywhere else, it must be a unary minus on an
796          expression.  */
797       if (str[1] == '\0')
798         return *str++;
799       s = str + 1;
800       if (*s == '(')
801         ++s;
802       if (m68k_reg_parse (&s) != 0)
803         return *str++;
804       break;
805     case '(':
806       /* A '(' can only appear in `(reg)', `(expr,...', `([', `@(', or
807          `)('.  If it appears anywhere else, it must be starting an
808          expression.  */
809       if (str[1] == '['
810           || (str > strorig
811               && (str[-1] == '@'
812                   || str[-1] == ')')))
813         return *str++;
814       s = str + 1;
815       if (m68k_reg_parse (&s) != 0)
816         return *str++;
817       /* Check for the case of '(expr,...' by scanning ahead.  If we
818          find a comma outside of balanced parentheses, we return '('.
819          If we find an unbalanced right parenthesis, then presumably
820          the '(' really starts an expression.  */
821       parens = 0;
822       for (s = str + 1; *s != '\0'; s++)
823         {
824           if (*s == '(')
825             ++parens;
826           else if (*s == ')')
827             {
828               if (parens == 0)
829                 break;
830               --parens;
831             }
832           else if (*s == ',' && parens == 0)
833             {
834               /* A comma can not normally appear in an expression, so
835                  this is a case of '(expr,...'.  */
836               return *str++;
837             }
838         }
839     }
840
841   /* See if it's a register.  */
842
843   reg = m68k_reg_parse (&str);
844   if (reg != 0)
845     {
846       int ret;
847
848       yylval.reg = reg;
849
850       if (reg >= DATA0 && reg <= DATA7)
851         ret = DR;
852       else if (reg >= ADDR0 && reg <= ADDR7)
853         ret = AR;
854       else if (reg >= FP0 && reg <= FP7)
855         return FPR;
856       else if (reg == FPI
857                || reg == FPS
858                || reg == FPC)
859         return FPCR;
860       else if (reg == PC)
861         return LPC;
862       else if (reg >= ZDATA0 && reg <= ZDATA7)
863         ret = ZDR;
864       else if (reg >= ZADDR0 && reg <= ZADDR7)
865         ret = ZAR;
866       else if (reg == ZPC)
867         return LZPC;
868       else
869         return CREG;
870
871       /* If we get here, we have a data or address register.  We
872          must check for a size or scale; if we find one, we must
873          return INDEXREG.  */
874
875       s = str;
876
877       if (*s != '.' && *s != ':' && *s != '*')
878         return ret;
879
880       yylval.indexreg.reg = reg;
881
882       if (*s != '.' && *s != ':')
883         yylval.indexreg.size = SIZE_UNSPEC;
884       else
885         {
886           ++s;
887           switch (*s)
888             {
889             case 'w':
890             case 'W':
891               yylval.indexreg.size = SIZE_WORD;
892               ++s;
893               break;
894             case 'l':
895             case 'L':
896               yylval.indexreg.size = SIZE_LONG;
897               ++s;
898               break;
899             default:
900               yyerror (_("illegal size specification"));
901               yylval.indexreg.size = SIZE_UNSPEC;
902               break;
903             }
904         }
905
906       yylval.indexreg.scale = 1;
907
908       if (*s == '*' || *s == ':')
909         {
910           expressionS scale;
911
912           ++s;
913
914           hold = input_line_pointer;
915           input_line_pointer = s;
916           expression (&scale);
917           s = input_line_pointer;
918           input_line_pointer = hold;
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 - 6 > str && cp[-6] == '@')
1010       {
1011         if (strncmp (cp - 6, "@PLTPC", 6) == 0)
1012           {
1013             yylval.exp.pic_reloc = pic_plt_pcrel;
1014             tail += 6;
1015           }
1016         else if (strncmp (cp - 6, "@GOTPC", 6) == 0)
1017           {
1018             yylval.exp.pic_reloc = pic_got_pcrel;
1019             tail += 6;
1020           }
1021       }
1022     else if (cp - 4 > str && cp[-4] == '@')
1023       {
1024         if (strncmp (cp - 4, "@PLT", 4) == 0)
1025           {
1026             yylval.exp.pic_reloc = pic_plt_off;
1027             tail += 4;
1028           }
1029         else if (strncmp (cp - 4, "@GOT", 4) == 0)
1030           {
1031             yylval.exp.pic_reloc = pic_got_off;
1032             tail += 4;
1033           }
1034       }
1035   }
1036 #endif
1037
1038   if (tail != 0)
1039     {
1040       c = s[-tail];
1041       s[-tail] = 0;
1042     }
1043
1044   hold = input_line_pointer;
1045   input_line_pointer = str;
1046   expression (&yylval.exp.exp);
1047   str = input_line_pointer;
1048   input_line_pointer = hold;
1049
1050   if (tail != 0)
1051     {
1052       s[-tail] = c;
1053       str = s;
1054     }
1055
1056   return EXPR;
1057 }
1058
1059 /* Parse an m68k operand.  This is the only function which is called
1060    from outside this file.  */
1061
1062 int
1063 m68k_ip_op (s, oparg)
1064      char *s;
1065      struct m68k_op *oparg;
1066 {
1067   memset (oparg, 0, sizeof *oparg);
1068   oparg->error = NULL;
1069   oparg->index.reg = ZDATA0;
1070   oparg->index.scale = 1;
1071   oparg->disp.exp.X_op = O_absent;
1072   oparg->odisp.exp.X_op = O_absent;
1073
1074   str = strorig = s;
1075   op = oparg;
1076
1077   return yyparse ();
1078 }
1079
1080 /* The error handler.  */
1081
1082 static void
1083 yyerror (s)
1084      const char *s;
1085 {
1086   op->error = s;
1087 }