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