Initial revision
[binutils.git] / gas / config / m68k-parse.y
blob70a4e4fe86ebc8509883893c252da4e6e53de85d
1 /* m68k.y -- bison grammar for m68k operand parsing
2 Copyright (C) 1995, 96, 1997, 1998 Free Software Foundation, Inc.
3 Written by Ken Raeburn and Ian Lance Taylor, Cygnus Support
5 This file is part of GAS, the GNU Assembler.
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.
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.
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. */
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. */
29 #include "as.h"
30 #include "tc-m68k.h"
31 #include "m68k-parse.h"
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. */
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
78 #ifndef YYDEBUG
79 #define YYDEBUG 1
80 #endif
82 /* Internal functions. */
84 static enum m68k_register m68k_reg_parse PARAMS ((char **));
85 static int yylex PARAMS ((void));
86 static void yyerror PARAMS ((const char *));
88 /* The parser sets fields pointed to by this global variable. */
89 static struct m68k_op *op;
93 %union
95 struct m68k_indexreg indexreg;
96 enum m68k_register reg;
97 struct m68k_exp exp;
98 unsigned long mask;
99 int onereg;
102 %token <reg> DR AR FPR FPCR LPC ZAR ZDR LZPC CREG
103 %token <indexreg> INDEXREG
104 %token <exp> EXPR
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
114 /* An operand. */
116 operand:
117 generic_operand
118 | motorola_operand
119 | mit_operand
122 /* A generic operand. */
124 generic_operand:
127 op->mode = DREG;
128 op->reg = $1;
130 | AR
132 op->mode = AREG;
133 op->reg = $1;
135 | FPR
137 op->mode = FPREG;
138 op->reg = $1;
140 | FPCR
142 op->mode = CONTROL;
143 op->reg = $1;
145 | CREG
147 op->mode = CONTROL;
148 op->reg = $1;
150 | EXPR
152 op->mode = ABSL;
153 op->disp = $1;
155 | '#' EXPR
157 op->mode = IMMED;
158 op->disp = $2;
160 | '&' EXPR
162 op->mode = IMMED;
163 op->disp = $2;
165 | reglist
167 op->mode = REGLST;
168 op->mask = $1;
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. */
177 motorola_operand:
178 '(' AR ')'
180 op->mode = AINDR;
181 op->reg = $2;
183 | '(' AR ')' '+'
185 op->mode = AINC;
186 op->reg = $2;
188 | '-' '(' AR ')'
190 op->mode = ADEC;
191 op->reg = $3;
193 | '(' EXPR ',' zapc ')'
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;
203 | '(' zapc ',' EXPR ')'
205 op->reg = $2;
206 op->disp = $4;
207 if (($2 >= ZADDR0 && $2 <= ZADDR7)
208 || $2 == ZPC)
209 op->mode = BASE;
210 else
211 op->mode = DISP;
213 | EXPR '(' zapc ')'
215 op->reg = $3;
216 op->disp = $1;
217 if (($3 >= ZADDR0 && $3 <= ZADDR7)
218 || $3 == ZPC)
219 op->mode = BASE;
220 else
221 op->mode = DISP;
223 | '(' LPC ')'
225 op->mode = DISP;
226 op->reg = $2;
228 | '(' ZAR ')'
230 op->mode = BASE;
231 op->reg = $2;
233 | '(' LZPC ')'
235 op->mode = BASE;
236 op->reg = $2;
238 | '(' EXPR ',' zapc ',' zireg ')'
240 op->mode = BASE;
241 op->reg = $4;
242 op->disp = $2;
243 op->index = $6;
245 | '(' EXPR ',' zapc ',' zpc ')'
247 if ($4 == PC || $4 == ZPC)
248 yyerror (_("syntax error"));
249 op->mode = BASE;
250 op->reg = $6;
251 op->disp = $2;
252 op->index.reg = $4;
253 op->index.size = SIZE_UNSPEC;
254 op->index.scale = 1;
256 | '(' EXPR ',' zdireg optczapc ')'
258 op->mode = BASE;
259 op->reg = $5;
260 op->disp = $2;
261 op->index = $4;
263 | '(' zdireg ',' EXPR ')'
265 op->mode = BASE;
266 op->disp = $4;
267 op->index = $2;
269 | EXPR '(' zapc ',' zireg ')'
271 op->mode = BASE;
272 op->reg = $3;
273 op->disp = $1;
274 op->index = $5;
276 | '(' zapc ',' zireg ')'
278 op->mode = BASE;
279 op->reg = $2;
280 op->index = $4;
282 | EXPR '(' zapc ',' zpc ')'
284 if ($3 == PC || $3 == ZPC)
285 yyerror (_("syntax error"));
286 op->mode = BASE;
287 op->reg = $5;
288 op->disp = $1;
289 op->index.reg = $3;
290 op->index.size = SIZE_UNSPEC;
291 op->index.scale = 1;
293 | '(' zapc ',' zpc ')'
295 if ($2 == PC || $2 == ZPC)
296 yyerror (_("syntax error"));
297 op->mode = BASE;
298 op->reg = $4;
299 op->index.reg = $2;
300 op->index.size = SIZE_UNSPEC;
301 op->index.scale = 1;
303 | EXPR '(' zdireg optczapc ')'
305 op->mode = BASE;
306 op->reg = $4;
307 op->disp = $1;
308 op->index = $3;
310 | '(' zdireg optczapc ')'
312 op->mode = BASE;
313 op->reg = $3;
314 op->index = $2;
316 | '(' '[' EXPR optczapc ']' ',' zireg optcexpr ')'
318 op->mode = POST;
319 op->reg = $4;
320 op->disp = $3;
321 op->index = $7;
322 op->odisp = $8;
324 | '(' '[' EXPR optczapc ']' optcexpr ')'
326 op->mode = POST;
327 op->reg = $4;
328 op->disp = $3;
329 op->odisp = $6;
331 | '(' '[' zapc ']' ',' zireg optcexpr ')'
333 op->mode = POST;
334 op->reg = $3;
335 op->index = $6;
336 op->odisp = $7;
338 | '(' '[' zapc ']' optcexpr ')'
340 op->mode = POST;
341 op->reg = $3;
342 op->odisp = $5;
344 | '(' '[' EXPR ',' zapc ',' zireg ']' optcexpr ')'
346 op->mode = PRE;
347 op->reg = $5;
348 op->disp = $3;
349 op->index = $7;
350 op->odisp = $9;
352 | '(' '[' zapc ',' zireg ']' optcexpr ')'
354 op->mode = PRE;
355 op->reg = $3;
356 op->index = $5;
357 op->odisp = $7;
359 | '(' '[' EXPR ',' zapc ',' zpc ']' optcexpr ')'
361 if ($5 == PC || $5 == ZPC)
362 yyerror (_("syntax error"));
363 op->mode = PRE;
364 op->reg = $7;
365 op->disp = $3;
366 op->index.reg = $5;
367 op->index.size = SIZE_UNSPEC;
368 op->index.scale = 1;
369 op->odisp = $9;
371 | '(' '[' zapc ',' zpc ']' optcexpr ')'
373 if ($3 == PC || $3 == ZPC)
374 yyerror (_("syntax error"));
375 op->mode = PRE;
376 op->reg = $5;
377 op->index.reg = $3;
378 op->index.size = SIZE_UNSPEC;
379 op->index.scale = 1;
380 op->odisp = $7;
382 | '(' '[' optexprc zdireg optczapc ']' optcexpr ')'
384 op->mode = PRE;
385 op->reg = $5;
386 op->disp = $3;
387 op->index = $4;
388 op->odisp = $7;
392 /* An operand in MIT syntax. */
394 mit_operand:
395 optzapc '@'
397 /* We use optzapc to avoid a shift/reduce conflict. */
398 if ($1 < ADDR0 || $1 > ADDR7)
399 yyerror (_("syntax error"));
400 op->mode = AINDR;
401 op->reg = $1;
403 | optzapc '@' '+'
405 /* We use optzapc to avoid a shift/reduce conflict. */
406 if ($1 < ADDR0 || $1 > ADDR7)
407 yyerror (_("syntax error"));
408 op->mode = AINC;
409 op->reg = $1;
411 | optzapc '@' '-'
413 /* We use optzapc to avoid a shift/reduce conflict. */
414 if ($1 < ADDR0 || $1 > ADDR7)
415 yyerror (_("syntax error"));
416 op->mode = ADEC;
417 op->reg = $1;
419 | optzapc '@' '(' EXPR ')'
421 op->reg = $1;
422 op->disp = $4;
423 if (($1 >= ZADDR0 && $1 <= ZADDR7)
424 || $1 == ZPC)
425 op->mode = BASE;
426 else
427 op->mode = DISP;
429 | optzapc '@' '(' optexprc zireg ')'
431 op->mode = BASE;
432 op->reg = $1;
433 op->disp = $4;
434 op->index = $5;
436 | optzapc '@' '(' EXPR ')' '@' '(' optexprc zireg ')'
438 op->mode = POST;
439 op->reg = $1;
440 op->disp = $4;
441 op->index = $9;
442 op->odisp = $8;
444 | optzapc '@' '(' EXPR ')' '@' '(' EXPR ')'
446 op->mode = POST;
447 op->reg = $1;
448 op->disp = $4;
449 op->odisp = $8;
451 | optzapc '@' '(' optexprc zireg ')' '@' '(' EXPR ')'
453 op->mode = PRE;
454 op->reg = $1;
455 op->disp = $4;
456 op->index = $5;
457 op->odisp = $9;
461 /* An index register, possibly suppressed, which need not have a size
462 or scale. */
464 zireg:
465 INDEXREG
466 | zadr
468 $$.reg = $1;
469 $$.size = SIZE_UNSPEC;
470 $$.scale = 1;
474 /* A register which may be an index register, but which may not be an
475 address register. This nonterminal is used to avoid ambiguity when
476 trying to parse something like (0,d5,a6) as compared to (0,a6,d5). */
478 zdireg:
479 INDEXREG
480 | zdr
482 $$.reg = $1;
483 $$.size = SIZE_UNSPEC;
484 $$.scale = 1;
488 /* An address or data register, or a suppressed address or data
489 register. */
491 zadr:
493 | AR
494 | ZAR
497 /* A data register which may be suppressed. */
499 zdr:
501 | ZDR
504 /* Either an address register or the PC. */
506 apc:
508 | LPC
511 /* Either an address register, or the PC, or a suppressed address
512 register, or a suppressed PC. */
514 zapc:
516 | LZPC
517 | ZAR
520 /* An optional zapc. */
522 optzapc:
523 /* empty */
525 $$ = ZADDR0;
527 | zapc
530 /* The PC, optionally suppressed. */
532 zpc:
534 | LZPC
537 /* ',' zapc when it may be omitted. */
539 optczapc:
540 /* empty */
542 $$ = ZADDR0;
544 | ',' zapc
546 $$ = $2;
550 /* ',' EXPR when it may be omitted. */
552 optcexpr:
553 /* empty */
555 $$.exp.X_op = O_absent;
556 $$.size = SIZE_UNSPEC;
558 | ',' EXPR
560 $$ = $2;
564 /* EXPR ',' when it may be omitted. */
566 optexprc:
567 /* empty */
569 $$.exp.X_op = O_absent;
570 $$.size = SIZE_UNSPEC;
572 | EXPR ','
574 $$ = $1;
578 /* A register list for the movem instruction. */
580 reglist:
581 reglistpair
582 | reglistpair '/' ireglist
584 $$ = $1 | $3;
586 | reglistreg '/' ireglist
588 $$ = (1 << $1) | $3;
592 /* We use ireglist when we know we are looking at a reglist, and we
593 can safely reduce a simple register to reglistreg. If we permitted
594 reglist to reduce to reglistreg, it would be ambiguous whether a
595 plain register were a DREG/AREG/FPREG or a REGLST. */
597 ireglist:
598 reglistreg
600 $$ = 1 << $1;
602 | reglistpair
603 | reglistpair '/' ireglist
605 $$ = $1 | $3;
607 | reglistreg '/' ireglist
609 $$ = (1 << $1) | $3;
613 reglistpair:
614 reglistreg '-' reglistreg
616 if ($1 <= $3)
617 $$ = (1 << ($3 + 1)) - 1 - ((1 << $1) - 1);
618 else
619 $$ = (1 << ($1 + 1)) - 1 - ((1 << $3) - 1);
623 reglistreg:
626 $$ = $1 - DATA0;
628 | AR
630 $$ = $1 - ADDR0 + 8;
632 | FPR
634 $$ = $1 - FP0 + 16;
636 | FPCR
638 if ($1 == FPI)
639 $$ = 24;
640 else if ($1 == FPS)
641 $$ = 25;
642 else
643 $$ = 26;
649 /* The string to parse is stored here, and modified by yylex. */
651 static char *str;
653 /* The original string pointer. */
655 static char *strorig;
657 /* If *CCP could be a register, return the register number and advance
658 *CCP. Otherwise don't change *CCP, and return 0. */
660 static enum m68k_register
661 m68k_reg_parse (ccp)
662 register char **ccp;
664 char *start = *ccp;
665 char c;
666 char *p;
667 symbolS *symbolp;
669 if (flag_reg_prefix_optional)
671 if (*start == REGISTER_PREFIX)
672 start++;
673 p = start;
675 else
677 if (*start != REGISTER_PREFIX)
678 return 0;
679 p = start + 1;
682 if (! is_name_beginner (*p))
683 return 0;
685 p++;
686 while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
687 p++;
689 c = *p;
690 *p = 0;
691 symbolp = symbol_find (start);
692 *p = c;
694 if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
696 *ccp = p;
697 return S_GET_VALUE (symbolp);
700 /* In MRI mode, something like foo.bar can be equated to a register
701 name. */
702 while (flag_mri && c == '.')
704 ++p;
705 while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
706 p++;
707 c = *p;
708 *p = '\0';
709 symbolp = symbol_find (start);
710 *p = c;
711 if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
713 *ccp = p;
714 return S_GET_VALUE (symbolp);
718 return 0;
721 /* The lexer. */
723 static int
724 yylex ()
726 enum m68k_register reg;
727 char *s;
728 int parens;
729 int c = 0;
730 int tail = 0;
731 char *hold;
733 if (*str == ' ')
734 ++str;
736 if (*str == '\0')
737 return 0;
739 /* Various special characters are just returned directly. */
740 switch (*str)
742 case '@':
743 /* In MRI mode, this can be the start of an octal number. */
744 if (flag_mri)
746 if (isdigit (str[1])
747 || ((str[1] == '+' || str[1] == '-')
748 && isdigit (str[2])))
749 break;
751 /* Fall through. */
752 case '#':
753 case '&':
754 case ',':
755 case ')':
756 case '/':
757 case '[':
758 case ']':
759 return *str++;
760 case '+':
761 /* It so happens that a '+' can only appear at the end of an
762 operand. If it appears anywhere else, it must be a unary
763 plus on an expression. */
764 if (str[1] == '\0')
765 return *str++;
766 break;
767 case '-':
768 /* A '-' can only appear in -(ar), rn-rn, or ar@-. If it
769 appears anywhere else, it must be a unary minus on an
770 expression. */
771 if (str[1] == '\0')
772 return *str++;
773 s = str + 1;
774 if (*s == '(')
775 ++s;
776 if (m68k_reg_parse (&s) != 0)
777 return *str++;
778 break;
779 case '(':
780 /* A '(' can only appear in `(reg)', `(expr,...', `([', `@(', or
781 `)('. If it appears anywhere else, it must be starting an
782 expression. */
783 if (str[1] == '['
784 || (str > strorig
785 && (str[-1] == '@'
786 || str[-1] == ')')))
787 return *str++;
788 s = str + 1;
789 if (m68k_reg_parse (&s) != 0)
790 return *str++;
791 /* Check for the case of '(expr,...' by scanning ahead. If we
792 find a comma outside of balanced parentheses, we return '('.
793 If we find an unbalanced right parenthesis, then presumably
794 the '(' really starts an expression. */
795 parens = 0;
796 for (s = str + 1; *s != '\0'; s++)
798 if (*s == '(')
799 ++parens;
800 else if (*s == ')')
802 if (parens == 0)
803 break;
804 --parens;
806 else if (*s == ',' && parens == 0)
808 /* A comma can not normally appear in an expression, so
809 this is a case of '(expr,...'. */
810 return *str++;
815 /* See if it's a register. */
817 reg = m68k_reg_parse (&str);
818 if (reg != 0)
820 int ret;
822 yylval.reg = reg;
824 if (reg >= DATA0 && reg <= DATA7)
825 ret = DR;
826 else if (reg >= ADDR0 && reg <= ADDR7)
827 ret = AR;
828 else if (reg >= FP0 && reg <= FP7)
829 return FPR;
830 else if (reg == FPI
831 || reg == FPS
832 || reg == FPC)
833 return FPCR;
834 else if (reg == PC)
835 return LPC;
836 else if (reg >= ZDATA0 && reg <= ZDATA7)
837 ret = ZDR;
838 else if (reg >= ZADDR0 && reg <= ZADDR7)
839 ret = ZAR;
840 else if (reg == ZPC)
841 return LZPC;
842 else
843 return CREG;
845 /* If we get here, we have a data or address register. We
846 must check for a size or scale; if we find one, we must
847 return INDEXREG. */
849 s = str;
851 if (*s != '.' && *s != ':' && *s != '*')
852 return ret;
854 yylval.indexreg.reg = reg;
856 if (*s != '.' && *s != ':')
857 yylval.indexreg.size = SIZE_UNSPEC;
858 else
860 ++s;
861 switch (*s)
863 case 'w':
864 case 'W':
865 yylval.indexreg.size = SIZE_WORD;
866 ++s;
867 break;
868 case 'l':
869 case 'L':
870 yylval.indexreg.size = SIZE_LONG;
871 ++s;
872 break;
873 default:
874 yyerror (_("illegal size specification"));
875 yylval.indexreg.size = SIZE_UNSPEC;
876 break;
880 yylval.indexreg.scale = 1;
882 if (*s == '*' || *s == ':')
884 expressionS scale;
886 ++s;
888 hold = input_line_pointer;
889 input_line_pointer = s;
890 expression (&scale);
891 s = input_line_pointer;
892 input_line_pointer = hold;
894 if (scale.X_op != O_constant)
895 yyerror (_("scale specification must resolve to a number"));
896 else
898 switch (scale.X_add_number)
900 case 1:
901 case 2:
902 case 4:
903 case 8:
904 yylval.indexreg.scale = scale.X_add_number;
905 break;
906 default:
907 yyerror (_("invalid scale value"));
908 break;
913 str = s;
915 return INDEXREG;
918 /* It must be an expression. Before we call expression, we need to
919 look ahead to see if there is a size specification. We must do
920 that first, because otherwise foo.l will be treated as the symbol
921 foo.l, rather than as the symbol foo with a long size
922 specification. The grammar requires that all expressions end at
923 the end of the operand, or with ',', '(', ']', ')'. */
925 parens = 0;
926 for (s = str; *s != '\0'; s++)
928 if (*s == '(')
930 if (parens == 0
931 && s > str
932 && (s[-1] == ')' || isalnum ((unsigned char) s[-1])))
933 break;
934 ++parens;
936 else if (*s == ')')
938 if (parens == 0)
939 break;
940 --parens;
942 else if (parens == 0
943 && (*s == ',' || *s == ']'))
944 break;
947 yylval.exp.size = SIZE_UNSPEC;
948 if (s <= str + 2
949 || (s[-2] != '.' && s[-2] != ':'))
950 tail = 0;
951 else
953 switch (s[-1])
955 case 's':
956 case 'S':
957 case 'b':
958 case 'B':
959 yylval.exp.size = SIZE_BYTE;
960 break;
961 case 'w':
962 case 'W':
963 yylval.exp.size = SIZE_WORD;
964 break;
965 case 'l':
966 case 'L':
967 yylval.exp.size = SIZE_LONG;
968 break;
969 default:
970 break;
972 if (yylval.exp.size != SIZE_UNSPEC)
973 tail = 2;
976 #ifdef OBJ_ELF
978 /* Look for @PLTPC, etc. */
979 char *cp;
981 yylval.exp.pic_reloc = pic_none;
982 cp = s - tail;
983 if (cp - 6 > str && cp[-6] == '@')
985 if (strncmp (cp - 6, "@PLTPC", 6) == 0)
987 yylval.exp.pic_reloc = pic_plt_pcrel;
988 tail += 6;
990 else if (strncmp (cp - 6, "@GOTPC", 6) == 0)
992 yylval.exp.pic_reloc = pic_got_pcrel;
993 tail += 6;
996 else if (cp - 4 > str && cp[-4] == '@')
998 if (strncmp (cp - 4, "@PLT", 4) == 0)
1000 yylval.exp.pic_reloc = pic_plt_off;
1001 tail += 4;
1003 else if (strncmp (cp - 4, "@GOT", 4) == 0)
1005 yylval.exp.pic_reloc = pic_got_off;
1006 tail += 4;
1010 #endif
1012 if (tail != 0)
1014 c = s[-tail];
1015 s[-tail] = 0;
1018 hold = input_line_pointer;
1019 input_line_pointer = str;
1020 expression (&yylval.exp.exp);
1021 str = input_line_pointer;
1022 input_line_pointer = hold;
1024 if (tail != 0)
1026 s[-tail] = c;
1027 str = s;
1030 return EXPR;
1033 /* Parse an m68k operand. This is the only function which is called
1034 from outside this file. */
1037 m68k_ip_op (s, oparg)
1038 char *s;
1039 struct m68k_op *oparg;
1041 memset (oparg, 0, sizeof *oparg);
1042 oparg->error = NULL;
1043 oparg->index.reg = ZDATA0;
1044 oparg->index.scale = 1;
1045 oparg->disp.exp.X_op = O_absent;
1046 oparg->odisp.exp.X_op = O_absent;
1048 str = strorig = s;
1049 op = oparg;
1051 return yyparse ();
1054 /* The error handler. */
1056 static void
1057 yyerror (s)
1058 const char *s;
1060 op->error = s;