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