1 /* m68k.y -- bison grammar for m68k operand parsing
2 Copyright (C) 1995-2019 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 3, 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, 51 Franklin Street - Fifth Floor, 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"
32 #include "safe-ctype.h"
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. */
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
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
60 #define yy_yys m68k_yys
61 #define yystate m68k_state
62 #define yytmp m68k_tmp
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
83 /* Internal functions. */
85 static enum m68k_register m68k_reg_parse
(char **);
86 static int yylex (void);
87 static void yyerror (const char *);
89 /* The parser sets fields pointed to by this global variable. */
90 static struct m68k_op
*op
;
96 struct m68k_indexreg indexreg
;
97 enum m68k_register reg
;
101 int trailing_ampersand
;
104 %token
<reg
> DR AR FPR FPCR LPC ZAR ZDR LZPC CREG
105 %token
<indexreg
> INDEXREG
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
121 | motorola_operand optional_ampersand
123 op
->trailing_ampersand
= $2;
125 | mit_operand optional_ampersand
127 op
->trailing_ampersand
= $2;
131 /* A trailing ampersand(for MAC/EMAC mask addressing). */
139 /* A generic operand. */
199 /* An operand in Motorola syntax. This includes MRI syntax as well,
200 which may or may not be different in that it permits commutativity
201 of index and base registers, and permits an offset expression to
202 appear inside or outside of the parentheses. */
220 |
'(' EXPR
',' zapc
')'
224 if
(($4 >= ZADDR0
&& $4 <= ZADDR7
)
230 |
'(' zapc
',' EXPR
')'
234 if
(($2 >= ZADDR0
&& $2 <= ZADDR7
)
244 if
(($3 >= ZADDR0
&& $3 <= ZADDR7
)
265 |
'(' EXPR
',' zapc
',' zireg
')'
272 |
'(' EXPR
',' zapc
',' zpc
')'
274 if
($4 == PC ||
$4 == ZPC
)
275 yyerror (_
("syntax error"));
280 op
->index.size
= SIZE_UNSPEC
;
283 |
'(' EXPR
',' zdireg optczapc
')'
290 |
'(' zdireg
',' EXPR
')'
296 | EXPR
'(' zapc
',' zireg
')'
303 |
'(' zapc
',' zireg
')'
309 | EXPR
'(' zapc
',' zpc
')'
311 if
($3 == PC ||
$3 == ZPC
)
312 yyerror (_
("syntax error"));
317 op
->index.size
= SIZE_UNSPEC
;
320 |
'(' zapc
',' zpc
')'
322 if
($2 == PC ||
$2 == ZPC
)
323 yyerror (_
("syntax error"));
327 op
->index.size
= SIZE_UNSPEC
;
330 | EXPR
'(' zdireg optczapc
')'
337 |
'(' zdireg optczapc
')'
343 |
'(' '[' EXPR optczapc
']' ',' zireg optcexpr
')'
351 |
'(' '[' EXPR optczapc
']' optcexpr
')'
358 |
'(' '[' zapc
']' ',' zireg optcexpr
')'
365 |
'(' '[' zapc
']' optcexpr
')'
371 |
'(' '[' EXPR
',' zapc
',' zireg
']' optcexpr
')'
379 |
'(' '[' zapc
',' zireg
']' optcexpr
')'
386 |
'(' '[' EXPR
',' zapc
',' zpc
']' optcexpr
')'
388 if
($5 == PC ||
$5 == ZPC
)
389 yyerror (_
("syntax error"));
394 op
->index.size
= SIZE_UNSPEC
;
398 |
'(' '[' zapc
',' zpc
']' optcexpr
')'
400 if
($3 == PC ||
$3 == ZPC
)
401 yyerror (_
("syntax error"));
405 op
->index.size
= SIZE_UNSPEC
;
409 |
'(' '[' optexprc zdireg optczapc
']' optcexpr
')'
419 /* An operand in MIT syntax. */
424 /* We use optzapc to avoid a shift/reduce conflict. */
425 if
($1 < ADDR0 ||
$1 > ADDR7
)
426 yyerror (_
("syntax error"));
432 /* We use optzapc to avoid a shift/reduce conflict. */
433 if
($1 < ADDR0 ||
$1 > ADDR7
)
434 yyerror (_
("syntax error"));
440 /* We use optzapc to avoid a shift/reduce conflict. */
441 if
($1 < ADDR0 ||
$1 > ADDR7
)
442 yyerror (_
("syntax error"));
446 | optzapc
'@' '(' EXPR
')'
450 if
(($1 >= ZADDR0
&& $1 <= ZADDR7
)
456 | optzapc
'@' '(' optexprc zireg
')'
463 | optzapc
'@' '(' EXPR
')' '@' '(' optexprc zireg
')'
471 | optzapc
'@' '(' EXPR
')' '@' '(' EXPR
')'
478 | optzapc
'@' '(' optexprc zireg
')' '@' '(' EXPR
')'
488 /* An index register, possibly suppressed, which need not have a size
496 $$.size
= SIZE_UNSPEC
;
501 /* A register which may be an index register, but which may not be an
502 address register. This nonterminal is used to avoid ambiguity when
503 trying to parse something like (0,d5,a6) as compared to (0,a6,d5). */
510 $$.size
= SIZE_UNSPEC
;
515 /* An address or data register, or a suppressed address or data
524 /* A data register which may be suppressed. */
531 /* Either an address register or the PC. */
538 /* Either an address register, or the PC, or a suppressed address
539 register, or a suppressed PC. */
547 /* An optional zapc. */
557 /* The PC, optionally suppressed. */
564 /* ',' zapc when it may be omitted. */
577 /* ',' EXPR when it may be omitted. */
582 $$.exp.X_op
= O_absent
;
583 $$.size
= SIZE_UNSPEC
;
591 /* EXPR ',' when it may be omitted. */
596 $$.exp.X_op
= O_absent
;
597 $$.size
= SIZE_UNSPEC
;
605 /* A register list for the movem instruction. */
609 | reglistpair
'/' ireglist
613 | reglistreg
'/' ireglist
619 /* We use ireglist when we know we are looking at a reglist, and we
620 can safely reduce a simple register to reglistreg. If we permitted
621 reglist to reduce to reglistreg, it would be ambiguous whether a
622 plain register were a DREG/AREG/FPREG or a REGLST. */
630 | reglistpair
'/' ireglist
634 | reglistreg
'/' ireglist
641 reglistreg
'-' reglistreg
644 $$
= (1 << ($3 + 1)) - 1 - ((1 << $1) - 1);
646 $$
= (1 << ($1 + 1)) - 1 - ((1 << $3) - 1);
676 /* The string to parse is stored here, and modified by yylex. */
680 /* The original string pointer. */
682 static char *strorig
;
684 /* If *CCP could be a register, return the register number and advance
685 *CCP. Otherwise don't change *CCP, and return 0. */
687 static enum m68k_register
688 m68k_reg_parse
(char **ccp
)
695 if
(flag_reg_prefix_optional
)
697 if
(*start
== REGISTER_PREFIX
)
703 if
(*start
!= REGISTER_PREFIX
)
708 if
(! is_name_beginner
(*p
))
712 while
(is_part_of_name
(*p
) && *p
!= '.' && *p
!= ':' && *p
!= '*')
717 symbolp
= symbol_find
(start
);
720 if
(symbolp
!= NULL
&& S_GET_SEGMENT
(symbolp
) == reg_section
)
723 return S_GET_VALUE
(symbolp
);
726 /* In MRI mode, something like foo.bar can be equated to a register
728 while
(flag_mri
&& c
== '.')
731 while
(is_part_of_name
(*p
) && *p
!= '.' && *p
!= ':' && *p
!= '*')
735 symbolp
= symbol_find
(start
);
737 if
(symbolp
!= NULL
&& S_GET_SEGMENT
(symbolp
) == reg_section
)
740 return S_GET_VALUE
(symbolp
);
752 enum m68k_register reg
;
764 /* Various special characters are just returned directly. */
768 /* In MRI mode, this can be the start of an octal number. */
772 ||
((str
[1] == '+' || str
[1] == '-')
773 && ISDIGIT
(str
[2])))
788 /* It so happens that a '+' can only appear at the end of an
789 operand, or if it is trailed by an '&'(see mac load insn).
790 If it appears anywhere else, it must be a unary. */
791 if
(str
[1] == '\0' ||
(str
[1] == '&' && str
[2] == '\0'))
795 /* A '-' can only appear in -(ar), rn-rn, or ar@-. If it
796 appears anywhere else, it must be a unary minus on an
797 expression, unless it it trailed by a '&'(see mac load insn). */
798 if
(str
[1] == '\0' ||
(str
[1] == '&' && str
[2] == '\0'))
803 if
(m68k_reg_parse
(&s
) != 0)
807 /* A '(' can only appear in `(reg)', `(expr,...', `([', `@(', or
808 `)('. If it appears anywhere else, it must be starting an
816 if
(m68k_reg_parse
(&s
) != 0)
818 /* Check for the case of '(expr,...' by scanning ahead. If we
819 find a comma outside of balanced parentheses, we return '('.
820 If we find an unbalanced right parenthesis, then presumably
821 the '(' really starts an expression. */
823 for
(s
= str
+ 1; *s
!= '\0'; s
++)
833 else if
(*s
== ',' && parens
== 0)
835 /* A comma can not normally appear in an expression, so
836 this is a case of '(expr,...'. */
842 /* See if it's a register. */
844 reg
= m68k_reg_parse
(&str
);
851 if
(reg
>= DATA0
&& reg
<= DATA7
)
853 else if
(reg
>= ADDR0
&& reg
<= ADDR7
)
855 else if
(reg
>= FP0
&& reg
<= FP7
)
863 else if
(reg
>= ZDATA0
&& reg
<= ZDATA7
)
865 else if
(reg
>= ZADDR0
&& reg
<= ZADDR7
)
872 /* If we get here, we have a data or address register. We
873 must check for a size or scale; if we find one, we must
878 if
(*s
!= '.' && *s
!= ':' && *s
!= '*')
881 yylval.indexreg.reg
= reg
;
883 if
(*s
!= '.' && *s
!= ':')
884 yylval.indexreg.size
= SIZE_UNSPEC
;
892 yylval.indexreg.size
= SIZE_WORD
;
897 yylval.indexreg.size
= SIZE_LONG
;
901 yyerror (_
("illegal size specification"));
902 yylval.indexreg.size
= SIZE_UNSPEC
;
907 yylval.indexreg.scale
= 1;
909 if
(*s
== '*' ||
*s
== ':')
917 s
= input_line_pointer
;
920 if
(scale.X_op
!= O_constant
)
921 yyerror (_
("scale specification must resolve to a number"));
924 switch
(scale.X_add_number
)
930 yylval.indexreg.scale
= scale.X_add_number
;
933 yyerror (_
("invalid scale value"));
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 ',', '(', ']', ')'. */
952 for
(s
= str
; *s
!= '\0'; s
++)
958 && (s
[-1] == ')' || ISALNUM
(s
[-1])))
969 && (*s
== ',' ||
*s
== ']'))
973 yylval.exp.size
= SIZE_UNSPEC
;
975 ||
(s
[-2] != '.' && s
[-2] != ':'))
985 yylval.exp.size
= SIZE_BYTE
;
989 yylval.exp.size
= SIZE_WORD
;
993 yylval.exp.size
= SIZE_LONG
;
998 if
(yylval.exp.size
!= SIZE_UNSPEC
)
1004 /* Look for @PLTPC, etc. */
1007 yylval.exp.pic_reloc
= pic_none
;
1009 if
(cp
- 7 > str
&& cp
[-7] == '@')
1011 if
(strncmp
(cp
- 7, "@TLSLDM", 7) == 0)
1013 yylval.exp.pic_reloc
= pic_tls_ldm
;
1016 else if
(strncmp
(cp
- 7, "@TLSLDO", 7) == 0)
1018 yylval.exp.pic_reloc
= pic_tls_ldo
;
1022 else if
(cp
- 6 > str
&& cp
[-6] == '@')
1024 if
(strncmp
(cp
- 6, "@PLTPC", 6) == 0)
1026 yylval.exp.pic_reloc
= pic_plt_pcrel
;
1029 else if
(strncmp
(cp
- 6, "@GOTPC", 6) == 0)
1031 yylval.exp.pic_reloc
= pic_got_pcrel
;
1034 else if
(strncmp
(cp
- 6, "@TLSGD", 6) == 0)
1036 yylval.exp.pic_reloc
= pic_tls_gd
;
1039 else if
(strncmp
(cp
- 6, "@TLSIE", 6) == 0)
1041 yylval.exp.pic_reloc
= pic_tls_ie
;
1044 else if
(strncmp
(cp
- 6, "@TLSLE", 6) == 0)
1046 yylval.exp.pic_reloc
= pic_tls_le
;
1050 else if
(cp
- 4 > str
&& cp
[-4] == '@')
1052 if
(strncmp
(cp
- 4, "@PLT", 4) == 0)
1054 yylval.exp.pic_reloc
= pic_plt_off
;
1057 else if
(strncmp
(cp
- 4, "@GOT", 4) == 0)
1059 yylval.exp.pic_reloc
= pic_got_off
;
1073 expression
(&yylval.exp.exp
);
1074 str
= input_line_pointer
;
1086 /* Parse an m68k operand. This is the only function which is called
1087 from outside this file. */
1090 m68k_ip_op
(char *s
, struct m68k_op
*oparg
)
1092 memset
(oparg
, 0, sizeof
*oparg
);
1093 oparg
->error = NULL
;
1094 oparg
->index.reg
= ZDATA0
;
1095 oparg
->index.scale
= 1;
1096 oparg
->disp.exp.X_op
= O_absent
;
1097 oparg
->odisp.exp.X_op
= O_absent
;
1105 /* The error handler. */
1108 yyerror (const char *s
)