Annotation of src/external/gpl3/binutils.old/dist/gas/config/m68k-parse.y, Revision 1.5
1.1 christos 1: /* m68k.y -- bison grammar for m68k operand parsing
1.5 ! christos 2: Copyright (C) 1995-2016 Free Software Foundation, Inc.
1.1 christos 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA
20: 02110-1301, 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: #include "safe-ctype.h"
33:
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. */
39:
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
1.3 christos 47: #define yypact m68k_pact
48: #define yyr1 m68k_r1
49: #define yyr2 m68k_r2
50: #define yydef m68k_def
51: #define yychk m68k_chk
52: #define yypgo m68k_pgo
53: #define yyact m68k_act
1.1 christos 54: #define yyexca m68k_exca
55: #define yyerrflag m68k_errflag
56: #define yynerrs m68k_nerrs
57: #define yyps m68k_ps
58: #define yypv m68k_pv
59: #define yys m68k_s
60: #define yy_yys m68k_yys
61: #define yystate m68k_state
62: #define yytmp m68k_tmp
63: #define yyv m68k_v
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
78:
79: #ifndef YYDEBUG
80: #define YYDEBUG 1
81: #endif
82:
83: /* Internal functions. */
84:
85: static enum m68k_register m68k_reg_parse (char **);
86: static int yylex (void);
87: static void yyerror (const char *);
88:
89: /* The parser sets fields pointed to by this global variable. */
90: static struct m68k_op *op;
91:
92: %}
93:
94: %union
95: {
96: struct m68k_indexreg indexreg;
97: enum m68k_register reg;
98: struct m68k_exp exp;
99: unsigned long mask;
100: int onereg;
101: int trailing_ampersand;
102: }
103:
104: %token <reg> DR AR FPR FPCR LPC ZAR ZDR LZPC CREG
105: %token <indexreg> INDEXREG
106: %token <exp> EXPR
107:
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
114:
115: %%
116:
117: /* An operand. */
118:
119: operand:
120: generic_operand
121: | motorola_operand optional_ampersand
122: {
123: op->trailing_ampersand = $2;
124: }
125: | mit_operand optional_ampersand
126: {
127: op->trailing_ampersand = $2;
128: }
129: ;
130:
131: /* A trailing ampersand(for MAC/EMAC mask addressing). */
132: optional_ampersand:
133: /* empty */
134: { $$ = 0; }
135: | '&'
136: { $$ = 1; }
137: ;
138:
139: /* A generic operand. */
140:
141: generic_operand:
142: '<' '<'
143: {
144: op->mode = LSH;
145: }
146:
147: | '>' '>'
148: {
149: op->mode = RSH;
150: }
151:
152: | DR
153: {
154: op->mode = DREG;
155: op->reg = $1;
156: }
157: | AR
158: {
159: op->mode = AREG;
160: op->reg = $1;
161: }
162: | FPR
163: {
164: op->mode = FPREG;
165: op->reg = $1;
166: }
167: | FPCR
168: {
169: op->mode = CONTROL;
170: op->reg = $1;
171: }
172: | CREG
173: {
174: op->mode = CONTROL;
175: op->reg = $1;
176: }
177: | EXPR
178: {
179: op->mode = ABSL;
180: op->disp = $1;
181: }
182: | '#' EXPR
183: {
184: op->mode = IMMED;
185: op->disp = $2;
186: }
187: | '&' EXPR
188: {
189: op->mode = IMMED;
190: op->disp = $2;
191: }
192: | reglist
193: {
194: op->mode = REGLST;
195: op->mask = $1;
196: }
197: ;
198:
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. */
203:
204: motorola_operand:
205: '(' AR ')'
206: {
207: op->mode = AINDR;
208: op->reg = $2;
209: }
210: | '(' AR ')' '+'
211: {
212: op->mode = AINC;
213: op->reg = $2;
214: }
215: | '-' '(' AR ')'
216: {
217: op->mode = ADEC;
218: op->reg = $3;
219: }
220: | '(' EXPR ',' zapc ')'
221: {
222: op->reg = $4;
223: op->disp = $2;
224: if (($4 >= ZADDR0 && $4 <= ZADDR7)
225: || $4 == ZPC)
226: op->mode = BASE;
227: else
228: op->mode = DISP;
229: }
230: | '(' zapc ',' EXPR ')'
231: {
232: op->reg = $2;
233: op->disp = $4;
234: if (($2 >= ZADDR0 && $2 <= ZADDR7)
235: || $2 == ZPC)
236: op->mode = BASE;
237: else
238: op->mode = DISP;
239: }
240: | EXPR '(' zapc ')'
241: {
242: op->reg = $3;
243: op->disp = $1;
244: if (($3 >= ZADDR0 && $3 <= ZADDR7)
245: || $3 == ZPC)
246: op->mode = BASE;
247: else
248: op->mode = DISP;
249: }
250: | '(' LPC ')'
251: {
252: op->mode = DISP;
253: op->reg = $2;
254: }
255: | '(' ZAR ')'
256: {
257: op->mode = BASE;
258: op->reg = $2;
259: }
260: | '(' LZPC ')'
261: {
262: op->mode = BASE;
263: op->reg = $2;
264: }
265: | '(' EXPR ',' zapc ',' zireg ')'
266: {
267: op->mode = BASE;
268: op->reg = $4;
269: op->disp = $2;
270: op->index = $6;
271: }
272: | '(' EXPR ',' zapc ',' zpc ')'
273: {
274: if ($4 == PC || $4 == ZPC)
275: yyerror (_("syntax error"));
276: op->mode = BASE;
277: op->reg = $6;
278: op->disp = $2;
279: op->index.reg = $4;
280: op->index.size = SIZE_UNSPEC;
281: op->index.scale = 1;
282: }
283: | '(' EXPR ',' zdireg optczapc ')'
284: {
285: op->mode = BASE;
286: op->reg = $5;
287: op->disp = $2;
288: op->index = $4;
289: }
290: | '(' zdireg ',' EXPR ')'
291: {
292: op->mode = BASE;
293: op->disp = $4;
294: op->index = $2;
295: }
296: | EXPR '(' zapc ',' zireg ')'
297: {
298: op->mode = BASE;
299: op->reg = $3;
300: op->disp = $1;
301: op->index = $5;
302: }
303: | '(' zapc ',' zireg ')'
304: {
305: op->mode = BASE;
306: op->reg = $2;
307: op->index = $4;
308: }
309: | EXPR '(' zapc ',' zpc ')'
310: {
311: if ($3 == PC || $3 == ZPC)
312: yyerror (_("syntax error"));
313: op->mode = BASE;
314: op->reg = $5;
315: op->disp = $1;
316: op->index.reg = $3;
317: op->index.size = SIZE_UNSPEC;
318: op->index.scale = 1;
319: }
320: | '(' zapc ',' zpc ')'
321: {
322: if ($2 == PC || $2 == ZPC)
323: yyerror (_("syntax error"));
324: op->mode = BASE;
325: op->reg = $4;
326: op->index.reg = $2;
327: op->index.size = SIZE_UNSPEC;
328: op->index.scale = 1;
329: }
330: | EXPR '(' zdireg optczapc ')'
331: {
332: op->mode = BASE;
333: op->reg = $4;
334: op->disp = $1;
335: op->index = $3;
336: }
337: | '(' zdireg optczapc ')'
338: {
339: op->mode = BASE;
340: op->reg = $3;
341: op->index = $2;
342: }
343: | '(' '[' EXPR optczapc ']' ',' zireg optcexpr ')'
344: {
345: op->mode = POST;
346: op->reg = $4;
347: op->disp = $3;
348: op->index = $7;
349: op->odisp = $8;
350: }
351: | '(' '[' EXPR optczapc ']' optcexpr ')'
352: {
353: op->mode = POST;
354: op->reg = $4;
355: op->disp = $3;
356: op->odisp = $6;
357: }
358: | '(' '[' zapc ']' ',' zireg optcexpr ')'
359: {
360: op->mode = POST;
361: op->reg = $3;
362: op->index = $6;
363: op->odisp = $7;
364: }
365: | '(' '[' zapc ']' optcexpr ')'
366: {
367: op->mode = POST;
368: op->reg = $3;
369: op->odisp = $5;
370: }
371: | '(' '[' EXPR ',' zapc ',' zireg ']' optcexpr ')'
372: {
373: op->mode = PRE;
374: op->reg = $5;
375: op->disp = $3;
376: op->index = $7;
377: op->odisp = $9;
378: }
379: | '(' '[' zapc ',' zireg ']' optcexpr ')'
380: {
381: op->mode = PRE;
382: op->reg = $3;
383: op->index = $5;
384: op->odisp = $7;
385: }
386: | '(' '[' EXPR ',' zapc ',' zpc ']' optcexpr ')'
387: {
388: if ($5 == PC || $5 == ZPC)
389: yyerror (_("syntax error"));
390: op->mode = PRE;
391: op->reg = $7;
392: op->disp = $3;
393: op->index.reg = $5;
394: op->index.size = SIZE_UNSPEC;
395: op->index.scale = 1;
396: op->odisp = $9;
397: }
398: | '(' '[' zapc ',' zpc ']' optcexpr ')'
399: {
400: if ($3 == PC || $3 == ZPC)
401: yyerror (_("syntax error"));
402: op->mode = PRE;
403: op->reg = $5;
404: op->index.reg = $3;
405: op->index.size = SIZE_UNSPEC;
406: op->index.scale = 1;
407: op->odisp = $7;
408: }
409: | '(' '[' optexprc zdireg optczapc ']' optcexpr ')'
410: {
411: op->mode = PRE;
412: op->reg = $5;
413: op->disp = $3;
414: op->index = $4;
415: op->odisp = $7;
416: }
417: ;
418:
419: /* An operand in MIT syntax. */
420:
421: mit_operand:
422: optzapc '@'
423: {
424: /* We use optzapc to avoid a shift/reduce conflict. */
425: if ($1 < ADDR0 || $1 > ADDR7)
426: yyerror (_("syntax error"));
427: op->mode = AINDR;
428: op->reg = $1;
429: }
430: | optzapc '@' '+'
431: {
432: /* We use optzapc to avoid a shift/reduce conflict. */
433: if ($1 < ADDR0 || $1 > ADDR7)
434: yyerror (_("syntax error"));
435: op->mode = AINC;
436: op->reg = $1;
437: }
438: | optzapc '@' '-'
439: {
440: /* We use optzapc to avoid a shift/reduce conflict. */
441: if ($1 < ADDR0 || $1 > ADDR7)
442: yyerror (_("syntax error"));
443: op->mode = ADEC;
444: op->reg = $1;
445: }
446: | optzapc '@' '(' EXPR ')'
447: {
448: op->reg = $1;
449: op->disp = $4;
450: if (($1 >= ZADDR0 && $1 <= ZADDR7)
451: || $1 == ZPC)
452: op->mode = BASE;
453: else
454: op->mode = DISP;
455: }
456: | optzapc '@' '(' optexprc zireg ')'
457: {
458: op->mode = BASE;
459: op->reg = $1;
460: op->disp = $4;
461: op->index = $5;
462: }
463: | optzapc '@' '(' EXPR ')' '@' '(' optexprc zireg ')'
464: {
465: op->mode = POST;
466: op->reg = $1;
467: op->disp = $4;
468: op->index = $9;
469: op->odisp = $8;
470: }
471: | optzapc '@' '(' EXPR ')' '@' '(' EXPR ')'
472: {
473: op->mode = POST;
474: op->reg = $1;
475: op->disp = $4;
476: op->odisp = $8;
477: }
478: | optzapc '@' '(' optexprc zireg ')' '@' '(' EXPR ')'
479: {
480: op->mode = PRE;
481: op->reg = $1;
482: op->disp = $4;
483: op->index = $5;
484: op->odisp = $9;
485: }
486: ;
487:
488: /* An index register, possibly suppressed, which need not have a size
489: or scale. */
490:
491: zireg:
492: INDEXREG
493: | zadr
494: {
495: $$.reg = $1;
496: $$.size = SIZE_UNSPEC;
497: $$.scale = 1;
498: }
499: ;
500:
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). */
504:
505: zdireg:
506: INDEXREG
507: | zdr
508: {
509: $$.reg = $1;
510: $$.size = SIZE_UNSPEC;
511: $$.scale = 1;
512: }
513: ;
514:
515: /* An address or data register, or a suppressed address or data
516: register. */
517:
518: zadr:
519: zdr
520: | AR
521: | ZAR
522: ;
523:
524: /* A data register which may be suppressed. */
525:
526: zdr:
527: DR
528: | ZDR
529: ;
530:
531: /* Either an address register or the PC. */
532:
533: apc:
534: AR
535: | LPC
536: ;
537:
538: /* Either an address register, or the PC, or a suppressed address
539: register, or a suppressed PC. */
540:
541: zapc:
542: apc
543: | LZPC
544: | ZAR
545: ;
546:
547: /* An optional zapc. */
548:
549: optzapc:
550: /* empty */
551: {
552: $$ = ZADDR0;
553: }
554: | zapc
555: ;
556:
557: /* The PC, optionally suppressed. */
558:
559: zpc:
560: LPC
561: | LZPC
562: ;
563:
564: /* ',' zapc when it may be omitted. */
565:
566: optczapc:
567: /* empty */
568: {
569: $$ = ZADDR0;
570: }
571: | ',' zapc
572: {
573: $$ = $2;
574: }
575: ;
576:
577: /* ',' EXPR when it may be omitted. */
578:
579: optcexpr:
580: /* empty */
581: {
582: $$.exp.X_op = O_absent;
583: $$.size = SIZE_UNSPEC;
584: }
585: | ',' EXPR
586: {
587: $$ = $2;
588: }
589: ;
590:
591: /* EXPR ',' when it may be omitted. */
592:
593: optexprc:
594: /* empty */
595: {
596: $$.exp.X_op = O_absent;
597: $$.size = SIZE_UNSPEC;
598: }
599: | EXPR ','
600: {
601: $$ = $1;
602: }
603: ;
604:
605: /* A register list for the movem instruction. */
606:
607: reglist:
608: reglistpair
609: | reglistpair '/' ireglist
610: {
611: $$ = $1 | $3;
612: }
613: | reglistreg '/' ireglist
614: {
615: $$ = (1 << $1) | $3;
616: }
617: ;
618:
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. */
623:
624: ireglist:
625: reglistreg
626: {
627: $$ = 1 << $1;
628: }
629: | reglistpair
630: | reglistpair '/' ireglist
631: {
632: $$ = $1 | $3;
633: }
634: | reglistreg '/' ireglist
635: {
636: $$ = (1 << $1) | $3;
637: }
638: ;
639:
640: reglistpair:
641: reglistreg '-' reglistreg
642: {
643: if ($1 <= $3)
644: $$ = (1 << ($3 + 1)) - 1 - ((1 << $1) - 1);
645: else
646: $$ = (1 << ($1 + 1)) - 1 - ((1 << $3) - 1);
647: }
648: ;
649:
650: reglistreg:
651: DR
652: {
653: $$ = $1 - DATA0;
654: }
655: | AR
656: {
657: $$ = $1 - ADDR0 + 8;
658: }
659: | FPR
660: {
661: $$ = $1 - FP0 + 16;
662: }
663: | FPCR
664: {
665: if ($1 == FPI)
666: $$ = 24;
667: else if ($1 == FPS)
668: $$ = 25;
669: else
670: $$ = 26;
671: }
672: ;
673:
674: %%
675:
676: /* The string to parse is stored here, and modified by yylex. */
677:
678: static char *str;
679:
680: /* The original string pointer. */
681:
682: static char *strorig;
683:
684: /* If *CCP could be a register, return the register number and advance
685: *CCP. Otherwise don't change *CCP, and return 0. */
686:
687: static enum m68k_register
1.3 christos 688: m68k_reg_parse (char **ccp)
1.1 christos 689: {
690: char *start = *ccp;
691: char c;
692: char *p;
693: symbolS *symbolp;
694:
695: if (flag_reg_prefix_optional)
696: {
697: if (*start == REGISTER_PREFIX)
698: start++;
699: p = start;
700: }
701: else
702: {
703: if (*start != REGISTER_PREFIX)
704: return 0;
705: p = start + 1;
706: }
707:
708: if (! is_name_beginner (*p))
709: return 0;
710:
711: p++;
712: while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
713: p++;
714:
715: c = *p;
716: *p = 0;
717: symbolp = symbol_find (start);
718: *p = c;
719:
720: if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
721: {
722: *ccp = p;
723: return S_GET_VALUE (symbolp);
724: }
725:
726: /* In MRI mode, something like foo.bar can be equated to a register
727: name. */
728: while (flag_mri && c == '.')
729: {
730: ++p;
731: while (is_part_of_name (*p) && *p != '.' && *p != ':' && *p != '*')
732: p++;
733: c = *p;
734: *p = '\0';
735: symbolp = symbol_find (start);
736: *p = c;
737: if (symbolp != NULL && S_GET_SEGMENT (symbolp) == reg_section)
738: {
739: *ccp = p;
740: return S_GET_VALUE (symbolp);
741: }
742: }
743:
744: return 0;
745: }
746:
747: /* The lexer. */
748:
749: static int
1.3 christos 750: yylex (void)
1.1 christos 751: {
752: enum m68k_register reg;
753: char *s;
754: int parens;
755: int c = 0;
756: int tail = 0;
757: char *hold;
758:
759: if (*str == ' ')
760: ++str;
761:
762: if (*str == '\0')
763: return 0;
764:
765: /* Various special characters are just returned directly. */
766: switch (*str)
767: {
768: case '@':
769: /* In MRI mode, this can be the start of an octal number. */
770: if (flag_mri)
771: {
772: if (ISDIGIT (str[1])
773: || ((str[1] == '+' || str[1] == '-')
774: && ISDIGIT (str[2])))
775: break;
776: }
777: /* Fall through. */
778: case '#':
779: case '&':
780: case ',':
781: case ')':
782: case '/':
783: case '[':
784: case ']':
785: case '<':
786: case '>':
787: return *str++;
788: case '+':
789: /* It so happens that a '+' can only appear at the end of an
790: operand, or if it is trailed by an '&'(see mac load insn).
791: If it appears anywhere else, it must be a unary. */
792: if (str[1] == '\0' || (str[1] == '&' && str[2] == '\0'))
793: return *str++;
794: break;
795: case '-':
796: /* A '-' can only appear in -(ar), rn-rn, or ar@-. If it
797: appears anywhere else, it must be a unary minus on an
798: expression, unless it it trailed by a '&'(see mac load insn). */
799: if (str[1] == '\0' || (str[1] == '&' && str[2] == '\0'))
800: return *str++;
801: s = str + 1;
802: if (*s == '(')
803: ++s;
804: if (m68k_reg_parse (&s) != 0)
805: return *str++;
806: break;
807: case '(':
808: /* A '(' can only appear in `(reg)', `(expr,...', `([', `@(', or
809: `)('. If it appears anywhere else, it must be starting an
810: expression. */
811: if (str[1] == '['
812: || (str > strorig
813: && (str[-1] == '@'
814: || str[-1] == ')')))
815: return *str++;
816: s = str + 1;
817: if (m68k_reg_parse (&s) != 0)
818: return *str++;
819: /* Check for the case of '(expr,...' by scanning ahead. If we
820: find a comma outside of balanced parentheses, we return '('.
821: If we find an unbalanced right parenthesis, then presumably
822: the '(' really starts an expression. */
823: parens = 0;
824: for (s = str + 1; *s != '\0'; s++)
825: {
826: if (*s == '(')
827: ++parens;
828: else if (*s == ')')
829: {
830: if (parens == 0)
831: break;
832: --parens;
833: }
834: else if (*s == ',' && parens == 0)
835: {
836: /* A comma can not normally appear in an expression, so
837: this is a case of '(expr,...'. */
838: return *str++;
839: }
840: }
841: }
842:
843: /* See if it's a register. */
844:
845: reg = m68k_reg_parse (&str);
846: if (reg != 0)
847: {
848: int ret;
849:
850: yylval.reg = reg;
851:
852: if (reg >= DATA0 && reg <= DATA7)
853: ret = DR;
854: else if (reg >= ADDR0 && reg <= ADDR7)
855: ret = AR;
856: else if (reg >= FP0 && reg <= FP7)
857: return FPR;
858: else if (reg == FPI
859: || reg == FPS
860: || reg == FPC)
861: return FPCR;
862: else if (reg == PC)
863: return LPC;
864: else if (reg >= ZDATA0 && reg <= ZDATA7)
865: ret = ZDR;
866: else if (reg >= ZADDR0 && reg <= ZADDR7)
867: ret = ZAR;
868: else if (reg == ZPC)
869: return LZPC;
870: else
871: return CREG;
872:
873: /* If we get here, we have a data or address register. We
874: must check for a size or scale; if we find one, we must
875: return INDEXREG. */
876:
877: s = str;
878:
879: if (*s != '.' && *s != ':' && *s != '*')
880: return ret;
881:
882: yylval.indexreg.reg = reg;
883:
884: if (*s != '.' && *s != ':')
885: yylval.indexreg.size = SIZE_UNSPEC;
886: else
887: {
888: ++s;
889: switch (*s)
890: {
891: case 'w':
892: case 'W':
893: yylval.indexreg.size = SIZE_WORD;
894: ++s;
895: break;
896: case 'l':
897: case 'L':
898: yylval.indexreg.size = SIZE_LONG;
899: ++s;
900: break;
901: default:
902: yyerror (_("illegal size specification"));
903: yylval.indexreg.size = SIZE_UNSPEC;
904: break;
905: }
906: }
907:
908: yylval.indexreg.scale = 1;
909:
910: if (*s == '*' || *s == ':')
911: {
912: expressionS scale;
913:
914: ++s;
915:
916: hold = input_line_pointer;
917: input_line_pointer = s;
918: expression (&scale);
919: s = input_line_pointer;
920: input_line_pointer = hold;
921:
922: if (scale.X_op != O_constant)
923: yyerror (_("scale specification must resolve to a number"));
924: else
925: {
926: switch (scale.X_add_number)
927: {
928: case 1:
929: case 2:
930: case 4:
931: case 8:
932: yylval.indexreg.scale = scale.X_add_number;
933: break;
934: default:
935: yyerror (_("invalid scale value"));
936: break;
937: }
938: }
939: }
940:
941: str = s;
942:
943: return INDEXREG;
944: }
945:
946: /* It must be an expression. Before we call expression, we need to
947: look ahead to see if there is a size specification. We must do
948: that first, because otherwise foo.l will be treated as the symbol
949: foo.l, rather than as the symbol foo with a long size
950: specification. The grammar requires that all expressions end at
951: the end of the operand, or with ',', '(', ']', ')'. */
952:
953: parens = 0;
954: for (s = str; *s != '\0'; s++)
955: {
956: if (*s == '(')
957: {
958: if (parens == 0
959: && s > str
960: && (s[-1] == ')' || ISALNUM (s[-1])))
961: break;
962: ++parens;
963: }
964: else if (*s == ')')
965: {
966: if (parens == 0)
967: break;
968: --parens;
969: }
970: else if (parens == 0
971: && (*s == ',' || *s == ']'))
972: break;
973: }
974:
975: yylval.exp.size = SIZE_UNSPEC;
976: if (s <= str + 2
977: || (s[-2] != '.' && s[-2] != ':'))
978: tail = 0;
979: else
980: {
981: switch (s[-1])
982: {
983: case 's':
984: case 'S':
985: case 'b':
986: case 'B':
987: yylval.exp.size = SIZE_BYTE;
988: break;
989: case 'w':
990: case 'W':
991: yylval.exp.size = SIZE_WORD;
992: break;
993: case 'l':
994: case 'L':
995: yylval.exp.size = SIZE_LONG;
996: break;
997: default:
998: break;
999: }
1000: if (yylval.exp.size != SIZE_UNSPEC)
1001: tail = 2;
1002: }
1003:
1004: #ifdef OBJ_ELF
1005: {
1006: /* Look for @PLTPC, etc. */
1007: char *cp;
1008:
1009: yylval.exp.pic_reloc = pic_none;
1010: cp = s - tail;
1011: if (cp - 7 > str && cp[-7] == '@')
1012: {
1013: if (strncmp (cp - 7, "@TLSLDM", 7) == 0)
1014: {
1015: yylval.exp.pic_reloc = pic_tls_ldm;
1016: tail += 7;
1017: }
1018: else if (strncmp (cp - 7, "@TLSLDO", 7) == 0)
1019: {
1020: yylval.exp.pic_reloc = pic_tls_ldo;
1021: tail += 7;
1022: }
1023: }
1024: else if (cp - 6 > str && cp[-6] == '@')
1025: {
1026: if (strncmp (cp - 6, "@PLTPC", 6) == 0)
1027: {
1028: yylval.exp.pic_reloc = pic_plt_pcrel;
1029: tail += 6;
1030: }
1031: else if (strncmp (cp - 6, "@GOTPC", 6) == 0)
1032: {
1033: yylval.exp.pic_reloc = pic_got_pcrel;
1034: tail += 6;
1035: }
1036: else if (strncmp (cp - 6, "@TLSGD", 6) == 0)
1037: {
1038: yylval.exp.pic_reloc = pic_tls_gd;
1039: tail += 6;
1040: }
1041: else if (strncmp (cp - 6, "@TLSIE", 6) == 0)
1042: {
1043: yylval.exp.pic_reloc = pic_tls_ie;
1044: tail += 6;
1.3 christos 1045: }
1.1 christos 1046: else if (strncmp (cp - 6, "@TLSLE", 6) == 0)
1047: {
1048: yylval.exp.pic_reloc = pic_tls_le;
1049: tail += 6;
1.3 christos 1050: }
1.1 christos 1051: }
1052: else if (cp - 4 > str && cp[-4] == '@')
1053: {
1054: if (strncmp (cp - 4, "@PLT", 4) == 0)
1055: {
1056: yylval.exp.pic_reloc = pic_plt_off;
1057: tail += 4;
1058: }
1059: else if (strncmp (cp - 4, "@GOT", 4) == 0)
1060: {
1061: yylval.exp.pic_reloc = pic_got_off;
1062: tail += 4;
1063: }
1064: }
1065: }
1066: #endif
1067:
1068: if (tail != 0)
1069: {
1070: c = s[-tail];
1071: s[-tail] = 0;
1072: }
1073:
1074: hold = input_line_pointer;
1075: input_line_pointer = str;
1076: expression (&yylval.exp.exp);
1077: str = input_line_pointer;
1078: input_line_pointer = hold;
1079:
1080: if (tail != 0)
1081: {
1082: s[-tail] = c;
1083: str = s;
1084: }
1085:
1086: return EXPR;
1087: }
1088:
1089: /* Parse an m68k operand. This is the only function which is called
1090: from outside this file. */
1091:
1092: int
1.3 christos 1093: m68k_ip_op (char *s, struct m68k_op *oparg)
1.1 christos 1094: {
1095: memset (oparg, 0, sizeof *oparg);
1096: oparg->error = NULL;
1097: oparg->index.reg = ZDATA0;
1098: oparg->index.scale = 1;
1099: oparg->disp.exp.X_op = O_absent;
1100: oparg->odisp.exp.X_op = O_absent;
1101:
1102: str = strorig = s;
1103: op = oparg;
1104:
1105: return yyparse ();
1106: }
1107:
1108: /* The error handler. */
1109:
1110: static void
1.3 christos 1111: yyerror (const char *s)
1.1 christos 1112: {
1113: op->error = s;
1114: }
CVSweb <webmaster@jp.NetBSD.org>