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
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)
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
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. */
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
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
59 #define yy_yys m68k_yys
60 #define yystate m68k_state
61 #define yytmp m68k_tmp
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
82 /* Internal functions. */
84 static int yylex PARAMS (());
85 static void yyerror PARAMS ((const char *));
87 /* The parser sets fields pointed to by this global variable. */
88 static struct m68k_op *op;
94 struct m68k_indexreg indexreg;
95 enum m68k_register reg;
101 %token <reg> DR AR FPR FPCR LPC ZAR ZDR LZPC CREG
102 %token <indexreg> INDEXREG
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
121 /* A generic operand. */
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. */
192 | '(' EXPR ',' zapc ')'
196 if (($4 >= ZADDR0 && $4 <= ZADDR7)
206 if (($3 >= ZADDR0 && $3 <= ZADDR7)
227 | '(' EXPR ',' zapc ',' zireg ')'
234 | '(' EXPR ',' zapc ',' zpc ')'
236 if ($4 == PC || $4 == ZPC)
237 yyerror ("syntax error");
242 op->index.size = SIZE_UNSPEC;
245 | '(' EXPR ',' zdireg optczapc ')'
252 | EXPR '(' zapc ',' zireg ')'
259 | '(' zapc ',' zireg ')'
265 | EXPR '(' zapc ',' zpc ')'
267 if ($3 == PC || $3 == ZPC)
268 yyerror ("syntax error");
273 op->index.size = SIZE_UNSPEC;
276 | '(' zapc ',' zpc ')'
278 if ($2 == PC || $2 == ZPC)
279 yyerror ("syntax error");
283 op->index.size = SIZE_UNSPEC;
286 | EXPR '(' zdireg optczapc ')'
293 | '(' zdireg optczapc ')'
299 | '(' '[' EXPR optczapc ']' ',' zireg optcexpr ')'
307 | '(' '[' EXPR optczapc ']' optcexpr ')'
314 | '(' '[' zapc ']' ',' zireg optcexpr ')'
321 | '(' '[' zapc ']' optcexpr ')'
327 | '(' '[' EXPR ',' zapc ',' zireg ']' optcexpr ')'
335 | '(' '[' zapc ',' zireg ']' optcexpr ')'
342 | '(' '[' EXPR ',' zapc ',' zpc ']' optcexpr ')'
344 if ($5 == PC || $5 == ZPC)
345 yyerror ("syntax error");
350 op->index.size = SIZE_UNSPEC;
354 | '(' '[' zapc ',' zpc ']' optcexpr ')'
356 if ($3 == PC || $3 == ZPC)
357 yyerror ("syntax error");
361 op->index.size = SIZE_UNSPEC;
365 | '(' '[' optexprc zdireg optczapc ']' optcexpr ')'
375 /* An operand in MIT syntax. */
380 /* We use optzapc to avoid a shift/reduce conflict. */
381 if ($1 < ADDR0 || $1 > ADDR7)
382 yyerror ("syntax error");
388 /* We use optzapc to avoid a shift/reduce conflict. */
389 if ($1 < ADDR0 || $1 > ADDR7)
390 yyerror ("syntax error");
396 /* We use optzapc to avoid a shift/reduce conflict. */
397 if ($1 < ADDR0 || $1 > ADDR7)
398 yyerror ("syntax error");
402 | optzapc '@' '(' EXPR ')'
406 if (($1 >= ZADDR0 && $1 <= ZADDR7)
412 | optzapc '@' '(' optexprc zireg ')'
419 | optzapc '@' '(' EXPR ')' '@' '(' optexprc zireg ')'
427 | optzapc '@' '(' EXPR ')' '@' '(' EXPR ')'
434 | optzapc '@' '(' optexprc zireg ')' '@' '(' EXPR ')'
444 /* An index register, possibly suppressed, which need not have a size
452 $$.size = SIZE_UNSPEC;
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). */
466 $$.size = SIZE_UNSPEC;
471 /* An address or data register, or a suppressed address or data
480 /* A data register which may be suppressed. */
487 /* Either an address register or the PC. */
494 /* Either an address register, or the PC, or a suppressed address
495 register, or a suppressed PC. */
503 /* An optional zapc. */
513 /* The PC, optionally suppressed. */
520 /* ',' zapc when it may be omitted. */
533 /* ',' EXPR when it may be omitted. */
538 $$.exp.X_op = O_absent;
539 $$.size = SIZE_UNSPEC;
547 /* EXPR ',' when it may be omitted. */
552 $$.exp.X_op = O_absent;
553 $$.size = SIZE_UNSPEC;
561 /* A register list for the movem instruction. */
565 | reglistpair '/' ireglist
569 | reglistreg '/' ireglist
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. */
586 | reglistpair '/' ireglist
590 | reglistreg '/' ireglist
597 reglistreg '-' reglistreg
599 $$ = (1 << ($3 + 1)) - 1 - ((1 << $1) - 1);
629 /* The string to parse is stored here, and modified by yylex. */
633 /* The original string pointer. */
635 static char *strorig;
637 /* If *CCP could be a register, return the register number and advance
638 *CCP. Otherwise don't change *CCP, and return 0. */
649 if (flag_reg_prefix_optional)
651 if (*start == REGISTER_PREFIX)
657 if (*start != REGISTER_PREFIX)
662 if (! is_name_beginner (*p))
666 while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
671 symbolp = symbol_find (start);
674 if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
677 return S_GET_VALUE (symbolp);
688 enum m68k_register reg;
700 /* Various special characters are just returned directly. */
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. */
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
728 if (m68k_reg_parse (&s) != 0)
732 /* A '(' can only appear in `(reg)', `(expr,...', `([', `@(', or
733 `)('. If it appears anywhere else, it must be starting an
741 if (m68k_reg_parse (&s) != 0)
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. */
748 for (s = str + 1; *s != '\0'; s++)
758 else if (*s == ',' && parens == 0)
760 /* A comma can not normally appear in an expression, so
761 this is a case of '(expr,...'. */
767 /* See if it's a register. */
769 reg = m68k_reg_parse (&str);
776 if (reg >= DATA0 && reg <= DATA7)
778 else if (reg >= ADDR0 && reg <= ADDR7)
780 else if (reg >= FP0 && reg <= FP7)
788 else if (reg >= ZDATA0 && reg <= ZDATA7)
790 else if (reg >= ZADDR0 && reg <= ZADDR7)
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
803 if (*s != '.' && *s != ':' && *s != '*')
806 yylval.indexreg.reg = reg;
808 if (*s != '.' && *s != ':')
809 yylval.indexreg.size = SIZE_UNSPEC;
817 yylval.indexreg.size = SIZE_WORD;
822 yylval.indexreg.size = SIZE_LONG;
826 yyerror ("illegal size specification");
827 yylval.indexreg.size = SIZE_UNSPEC;
832 if (*s != '*' && *s != ':')
833 yylval.indexreg.scale = 1;
843 yylval.indexreg.scale = *s - '0';
847 yyerror ("illegal scale specification");
848 yylval.indexreg.scale = 1;
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 ',', '(', ']', ')'. */
866 for (s = str; *s != '\0'; s++)
872 && (s[-1] == ')' || isalnum ((unsigned char) s[-1])))
883 && (*s == ',' || *s == ']'))
887 yylval.exp.size = SIZE_UNSPEC;
889 || (s[-2] != '.' && s[-2] != ':'))
899 yylval.exp.size = SIZE_BYTE;
903 yylval.exp.size = SIZE_WORD;
907 yylval.exp.size = SIZE_LONG;
913 if (yylval.exp.size != SIZE_UNSPEC)
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;
935 /* Parse an m68k operand. This is the only function which is called
936 from outside this file. */
939 m68k_ip_op (s, oparg)
941 struct m68k_op *oparg;
943 memset (oparg, 0, sizeof *oparg);
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;
956 /* The error handler. */