Fix formatting.
[deliverable/binutils-gdb.git] / gas / config / m68k-parse.y
CommitLineData
252b5132
RH
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
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
84static enum m68k_register m68k_reg_parse PARAMS ((char **));
85static int yylex PARAMS ((void));
86static void yyerror PARAMS ((const char *));
87
88/* The parser sets fields pointed to by this global variable. */
89static 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
116operand:
117 generic_operand
118 | motorola_operand
119 | mit_operand
120 ;
121
122/* A generic operand. */
123
124generic_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
177motorola_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 | '(' zapc ',' EXPR ')'
204 {
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;
212 }
213 | EXPR '(' zapc ')'
214 {
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;
222 }
223 | '(' LPC ')'
224 {
225 op->mode = DISP;
226 op->reg = $2;
227 }
228 | '(' ZAR ')'
229 {
230 op->mode = BASE;
231 op->reg = $2;
232 }
233 | '(' LZPC ')'
234 {
235 op->mode = BASE;
236 op->reg = $2;
237 }
238 | '(' EXPR ',' zapc ',' zireg ')'
239 {
240 op->mode = BASE;
241 op->reg = $4;
242 op->disp = $2;
243 op->index = $6;
244 }
245 | '(' EXPR ',' zapc ',' zpc ')'
246 {
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;
255 }
256 | '(' EXPR ',' zdireg optczapc ')'
257 {
258 op->mode = BASE;
259 op->reg = $5;
260 op->disp = $2;
261 op->index = $4;
262 }
263 | '(' zdireg ',' EXPR ')'
264 {
265 op->mode = BASE;
266 op->disp = $4;
267 op->index = $2;
268 }
269 | EXPR '(' zapc ',' zireg ')'
270 {
271 op->mode = BASE;
272 op->reg = $3;
273 op->disp = $1;
274 op->index = $5;
275 }
276 | '(' zapc ',' zireg ')'
277 {
278 op->mode = BASE;
279 op->reg = $2;
280 op->index = $4;
281 }
282 | EXPR '(' zapc ',' zpc ')'
283 {
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;
292 }
293 | '(' zapc ',' zpc ')'
294 {
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;
302 }
303 | EXPR '(' zdireg optczapc ')'
304 {
305 op->mode = BASE;
306 op->reg = $4;
307 op->disp = $1;
308 op->index = $3;
309 }
310 | '(' zdireg optczapc ')'
311 {
312 op->mode = BASE;
313 op->reg = $3;
314 op->index = $2;
315 }
316 | '(' '[' EXPR optczapc ']' ',' zireg optcexpr ')'
317 {
318 op->mode = POST;
319 op->reg = $4;
320 op->disp = $3;
321 op->index = $7;
322 op->odisp = $8;
323 }
324 | '(' '[' EXPR optczapc ']' optcexpr ')'
325 {
326 op->mode = POST;
327 op->reg = $4;
328 op->disp = $3;
329 op->odisp = $6;
330 }
331 | '(' '[' zapc ']' ',' zireg optcexpr ')'
332 {
333 op->mode = POST;
334 op->reg = $3;
335 op->index = $6;
336 op->odisp = $7;
337 }
338 | '(' '[' zapc ']' optcexpr ')'
339 {
340 op->mode = POST;
341 op->reg = $3;
342 op->odisp = $5;
343 }
344 | '(' '[' EXPR ',' zapc ',' zireg ']' optcexpr ')'
345 {
346 op->mode = PRE;
347 op->reg = $5;
348 op->disp = $3;
349 op->index = $7;
350 op->odisp = $9;
351 }
352 | '(' '[' zapc ',' zireg ']' optcexpr ')'
353 {
354 op->mode = PRE;
355 op->reg = $3;
356 op->index = $5;
357 op->odisp = $7;
358 }
359 | '(' '[' EXPR ',' zapc ',' zpc ']' optcexpr ')'
360 {
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;
370 }
371 | '(' '[' zapc ',' zpc ']' optcexpr ')'
372 {
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;
381 }
382 | '(' '[' optexprc zdireg optczapc ']' optcexpr ')'
383 {
384 op->mode = PRE;
385 op->reg = $5;
386 op->disp = $3;
387 op->index = $4;
388 op->odisp = $7;
389 }
390 ;
391
392/* An operand in MIT syntax. */
393
394mit_operand:
395 optzapc '@'
396 {
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;
402 }
403 | optzapc '@' '+'
404 {
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;
410 }
411 | optzapc '@' '-'
412 {
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;
418 }
419 | optzapc '@' '(' EXPR ')'
420 {
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;
428 }
429 | optzapc '@' '(' optexprc zireg ')'
430 {
431 op->mode = BASE;
432 op->reg = $1;
433 op->disp = $4;
434 op->index = $5;
435 }
436 | optzapc '@' '(' EXPR ')' '@' '(' optexprc zireg ')'
437 {
438 op->mode = POST;
439 op->reg = $1;
440 op->disp = $4;
441 op->index = $9;
442 op->odisp = $8;
443 }
444 | optzapc '@' '(' EXPR ')' '@' '(' EXPR ')'
445 {
446 op->mode = POST;
447 op->reg = $1;
448 op->disp = $4;
449 op->odisp = $8;
450 }
451 | optzapc '@' '(' optexprc zireg ')' '@' '(' EXPR ')'
452 {
453 op->mode = PRE;
454 op->reg = $1;
455 op->disp = $4;
456 op->index = $5;
457 op->odisp = $9;
458 }
459 ;
460
461/* An index register, possibly suppressed, which need not have a size
462 or scale. */
463
464zireg:
465 INDEXREG
466 | zadr
467 {
468 $$.reg = $1;
469 $$.size = SIZE_UNSPEC;
470 $$.scale = 1;
471 }
472 ;
473
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). */
477
478zdireg:
479 INDEXREG
480 | zdr
481 {
482 $$.reg = $1;
483 $$.size = SIZE_UNSPEC;
484 $$.scale = 1;
485 }
486 ;
487
488/* An address or data register, or a suppressed address or data
489 register. */
490
491zadr:
492 zdr
493 | AR
494 | ZAR
495 ;
496
497/* A data register which may be suppressed. */
498
499zdr:
500 DR
501 | ZDR
502 ;
503
504/* Either an address register or the PC. */
505
506apc:
507 AR
508 | LPC
509 ;
510
511/* Either an address register, or the PC, or a suppressed address
512 register, or a suppressed PC. */
513
514zapc:
515 apc
516 | LZPC
517 | ZAR
518 ;
519
520/* An optional zapc. */
521
522optzapc:
523 /* empty */
524 {
525 $$ = ZADDR0;
526 }
527 | zapc
528 ;
529
530/* The PC, optionally suppressed. */
531
532zpc:
533 LPC
534 | LZPC
535 ;
536
537/* ',' zapc when it may be omitted. */
538
539optczapc:
540 /* empty */
541 {
542 $$ = ZADDR0;
543 }
544 | ',' zapc
545 {
546 $$ = $2;
547 }
548 ;
549
550/* ',' EXPR when it may be omitted. */
551
552optcexpr:
553 /* empty */
554 {
555 $$.exp.X_op = O_absent;
556 $$.size = SIZE_UNSPEC;
557 }
558 | ',' EXPR
559 {
560 $$ = $2;
561 }
562 ;
563
564/* EXPR ',' when it may be omitted. */
565
566optexprc:
567 /* empty */
568 {
569 $$.exp.X_op = O_absent;
570 $$.size = SIZE_UNSPEC;
571 }
572 | EXPR ','
573 {
574 $$ = $1;
575 }
576 ;
577
578/* A register list for the movem instruction. */
579
580reglist:
581 reglistpair
582 | reglistpair '/' ireglist
583 {
584 $$ = $1 | $3;
585 }
586 | reglistreg '/' ireglist
587 {
588 $$ = (1 << $1) | $3;
589 }
590 ;
591
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. */
596
597ireglist:
598 reglistreg
599 {
600 $$ = 1 << $1;
601 }
602 | reglistpair
603 | reglistpair '/' ireglist
604 {
605 $$ = $1 | $3;
606 }
607 | reglistreg '/' ireglist
608 {
609 $$ = (1 << $1) | $3;
610 }
611 ;
612
613reglistpair:
614 reglistreg '-' reglistreg
615 {
616 if ($1 <= $3)
617 $$ = (1 << ($3 + 1)) - 1 - ((1 << $1) - 1);
618 else
619 $$ = (1 << ($1 + 1)) - 1 - ((1 << $3) - 1);
620 }
621 ;
622
623reglistreg:
624 DR
625 {
626 $$ = $1 - DATA0;
627 }
628 | AR
629 {
630 $$ = $1 - ADDR0 + 8;
631 }
632 | FPR
633 {
634 $$ = $1 - FP0 + 16;
635 }
636 | FPCR
637 {
638 if ($1 == FPI)
639 $$ = 24;
640 else if ($1 == FPS)
641 $$ = 25;
642 else
643 $$ = 26;
644 }
645 ;
646
647%%
648
649/* The string to parse is stored here, and modified by yylex. */
650
651static char *str;
652
653/* The original string pointer. */
654
655static char *strorig;
656
657/* If *CCP could be a register, return the register number and advance
658 *CCP. Otherwise don't change *CCP, and return 0. */
659
660static enum m68k_register
661m68k_reg_parse (ccp)
662 register char **ccp;
663{
664 char *start = *ccp;
665 char c;
666 char *p;
667 symbolS *symbolp;
668
669 if (flag_reg_prefix_optional)
670 {
671 if (*start == REGISTER_PREFIX)
672 start++;
673 p = start;
674 }
675 else
676 {
677 if (*start != REGISTER_PREFIX)
678 return 0;
679 p = start + 1;
680 }
681
682 if (! is_name_beginner (*p))
683 return 0;
684
685 p++;
686 while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
687 p++;
688
689 c = *p;
690 *p = 0;
691 symbolp = symbol_find (start);
692 *p = c;
693
694 if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
695 {
696 *ccp = p;
697 return S_GET_VALUE (symbolp);
698 }
699
700 /* In MRI mode, something like foo.bar can be equated to a register
701 name. */
702 while (flag_mri && c == '.')
703 {
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)
712 {
713 *ccp = p;
714 return S_GET_VALUE (symbolp);
715 }
716 }
717
718 return 0;
719}
720
721/* The lexer. */
722
723static int
724yylex ()
725{
726 enum m68k_register reg;
727 char *s;
728 int parens;
729 int c = 0;
730 int tail = 0;
731 char *hold;
732
733 if (*str == ' ')
734 ++str;
735
736 if (*str == '\0')
737 return 0;
738
739 /* Various special characters are just returned directly. */
740 switch (*str)
741 {
742 case '@':
743 /* In MRI mode, this can be the start of an octal number. */
744 if (flag_mri)
745 {
746 if (isdigit (str[1])
747 || ((str[1] == '+' || str[1] == '-')
748 && isdigit (str[2])))
749 break;
750 }
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++)
797 {
798 if (*s == '(')
799 ++parens;
800 else if (*s == ')')
801 {
802 if (parens == 0)
803 break;
804 --parens;
805 }
806 else if (*s == ',' && parens == 0)
807 {
808 /* A comma can not normally appear in an expression, so
809 this is a case of '(expr,...'. */
810 return *str++;
811 }
812 }
813 }
814
815 /* See if it's a register. */
816
817 reg = m68k_reg_parse (&str);
818 if (reg != 0)
819 {
820 int ret;
821
822 yylval.reg = reg;
823
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;
844
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. */
848
849 s = str;
850
851 if (*s != '.' && *s != ':' && *s != '*')
852 return ret;
853
854 yylval.indexreg.reg = reg;
855
856 if (*s != '.' && *s != ':')
857 yylval.indexreg.size = SIZE_UNSPEC;
858 else
859 {
860 ++s;
861 switch (*s)
862 {
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;
877 }
878 }
879
880 yylval.indexreg.scale = 1;
881
882 if (*s == '*' || *s == ':')
883 {
884 expressionS scale;
885
886 ++s;
887
888 hold = input_line_pointer;
889 input_line_pointer = s;
890 expression (&scale);
891 s = input_line_pointer;
892 input_line_pointer = hold;
893
894 if (scale.X_op != O_constant)
895 yyerror (_("scale specification must resolve to a number"));
896 else
897 {
898 switch (scale.X_add_number)
899 {
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;
909 }
910 }
911 }
912
913 str = s;
914
915 return INDEXREG;
916 }
917
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 ',', '(', ']', ')'. */
924
925 parens = 0;
926 for (s = str; *s != '\0'; s++)
927 {
928 if (*s == '(')
929 {
930 if (parens == 0
931 && s > str
932 && (s[-1] == ')' || isalnum ((unsigned char) s[-1])))
933 break;
934 ++parens;
935 }
936 else if (*s == ')')
937 {
938 if (parens == 0)
939 break;
940 --parens;
941 }
942 else if (parens == 0
943 && (*s == ',' || *s == ']'))
944 break;
945 }
946
947 yylval.exp.size = SIZE_UNSPEC;
948 if (s <= str + 2
949 || (s[-2] != '.' && s[-2] != ':'))
950 tail = 0;
951 else
952 {
953 switch (s[-1])
954 {
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;
971 }
972 if (yylval.exp.size != SIZE_UNSPEC)
973 tail = 2;
974 }
975
976#ifdef OBJ_ELF
977 {
978 /* Look for @PLTPC, etc. */
979 char *cp;
980
981 yylval.exp.pic_reloc = pic_none;
982 cp = s - tail;
983 if (cp - 6 > str && cp[-6] == '@')
984 {
985 if (strncmp (cp - 6, "@PLTPC", 6) == 0)
986 {
987 yylval.exp.pic_reloc = pic_plt_pcrel;
988 tail += 6;
989 }
990 else if (strncmp (cp - 6, "@GOTPC", 6) == 0)
991 {
992 yylval.exp.pic_reloc = pic_got_pcrel;
993 tail += 6;
994 }
995 }
996 else if (cp - 4 > str && cp[-4] == '@')
997 {
998 if (strncmp (cp - 4, "@PLT", 4) == 0)
999 {
1000 yylval.exp.pic_reloc = pic_plt_off;
1001 tail += 4;
1002 }
1003 else if (strncmp (cp - 4, "@GOT", 4) == 0)
1004 {
1005 yylval.exp.pic_reloc = pic_got_off;
1006 tail += 4;
1007 }
1008 }
1009 }
1010#endif
1011
1012 if (tail != 0)
1013 {
1014 c = s[-tail];
1015 s[-tail] = 0;
1016 }
1017
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;
1023
1024 if (tail != 0)
1025 {
1026 s[-tail] = c;
1027 str = s;
1028 }
1029
1030 return EXPR;
1031}
1032
1033/* Parse an m68k operand. This is the only function which is called
1034 from outside this file. */
1035
1036int
1037m68k_ip_op (s, oparg)
1038 char *s;
1039 struct m68k_op *oparg;
1040{
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;
1047
1048 str = strorig = s;
1049 op = oparg;
1050
1051 return yyparse ();
1052}
1053
1054/* The error handler. */
1055
1056static void
1057yyerror (s)
1058 const char *s;
1059{
1060 op->error = s;
1061}
This page took 0.087491 seconds and 4 git commands to generate.