]> Git Repo - binutils.git/blob - gas/expr.c
* as.h (struct relax_type): Add forward declaration for type.
[binutils.git] / gas / expr.c
1 /* expr.c -operands, expressions-
2    Copyright (C) 1987, 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
3
4    This file is part of GAS, the GNU Assembler.
5
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    GAS is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with GAS; see the file COPYING.  If not, write to
18    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /*
21  * This is really a branch office of as-read.c. I split it out to clearly
22  * distinguish the world of expressions from the world of statements.
23  * (It also gives smaller files to re-compile.)
24  * Here, "operand"s are of expressions, not instructions.
25  */
26
27 #include <ctype.h>
28 #include <string.h>
29
30 #include "as.h"
31 #include "libiberty.h"
32 #include "obstack.h"
33
34 static void floating_constant PARAMS ((expressionS * expressionP));
35 static void integer_constant PARAMS ((int radix, expressionS * expressionP));
36 static void clean_up_expression PARAMS ((expressionS * expressionP));
37
38 extern const char EXP_CHARS[], FLT_CHARS[];
39 \f
40 /* Build a dummy symbol to hold a complex expression.  This is how we
41    build expressions up out of other expressions.  The symbol is put
42    into the fake section expr_section.  */
43
44 symbolS *
45 make_expr_symbol (expressionP)
46      expressionS *expressionP;
47 {
48   const char *fake;
49   symbolS *symbolP;
50
51   if (expressionP->X_op == O_symbol
52       && expressionP->X_add_number == 0)
53     return expressionP->X_add_symbol;
54
55   /* FIXME: This should be something which decode_local_label_name
56      will handle.  */
57   fake = FAKE_LABEL_NAME;
58
59   /* Putting constant symbols in absolute_section rather than
60      expr_section is convenient for the old a.out code, for which
61      S_GET_SEGMENT does not always retrieve the value put in by
62      S_SET_SEGMENT.  */
63   symbolP = symbol_create (fake,
64                            (expressionP->X_op == O_constant
65                             ? absolute_section
66                             : expr_section),
67                            0, &zero_address_frag);
68   symbolP->sy_value = *expressionP;
69
70   if (expressionP->X_op == O_constant)
71     resolve_symbol_value (symbolP);
72
73   return symbolP;
74 }
75 \f
76 /*
77  * Build any floating-point literal here.
78  * Also build any bignum literal here.
79  */
80
81 /* Seems atof_machine can backscan through generic_bignum and hit whatever
82    happens to be loaded before it in memory.  And its way too complicated
83    for me to fix right.  Thus a hack.  JF:  Just make generic_bignum bigger,
84    and never write into the early words, thus they'll always be zero.
85    I hate Dean's floating-point code.  Bleh.  */
86 LITTLENUM_TYPE generic_bignum[SIZE_OF_LARGE_NUMBER + 6];
87 FLONUM_TYPE generic_floating_point_number =
88 {
89   &generic_bignum[6],           /* low (JF: Was 0) */
90   &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1], /* high JF: (added +6) */
91   0,                            /* leader */
92   0,                            /* exponent */
93   0                             /* sign */
94 };
95 /* If nonzero, we've been asked to assemble nan, +inf or -inf */
96 int generic_floating_point_magic;
97 \f
98 static void
99 floating_constant (expressionP)
100      expressionS *expressionP;
101 {
102   /* input_line_pointer->*/
103   /* floating-point constant. */
104   int error_code;
105
106   error_code = atof_generic (&input_line_pointer, ".", EXP_CHARS,
107                              &generic_floating_point_number);
108
109   if (error_code)
110     {
111       if (error_code == ERROR_EXPONENT_OVERFLOW)
112         {
113           as_bad ("bad floating-point constant: exponent overflow, probably assembling junk");
114         }
115       else
116         {
117           as_bad ("bad floating-point constant: unknown error code=%d.", error_code);
118         }
119     }
120   expressionP->X_op = O_big;
121   /* input_line_pointer->just after constant, */
122   /* which may point to whitespace. */
123   expressionP->X_add_number = -1;
124 }
125
126 static void
127 integer_constant (radix, expressionP)
128      int radix;
129      expressionS *expressionP;
130 {
131   char *start;          /* start of number. */
132   char c;
133
134   valueT number;        /* offset or (absolute) value */
135   short int digit;      /* value of next digit in current radix */
136   short int maxdig = 0;/* highest permitted digit value. */
137   int too_many_digits = 0;      /* if we see >= this number of */
138   char *name;           /* points to name of symbol */
139   symbolS *symbolP;     /* points to symbol */
140
141   int small;                    /* true if fits in 32 bits. */
142
143   /* May be bignum, or may fit in 32 bits. */
144   /* Most numbers fit into 32 bits, and we want this case to be fast.
145      so we pretend it will fit into 32 bits.  If, after making up a 32
146      bit number, we realise that we have scanned more digits than
147      comfortably fit into 32 bits, we re-scan the digits coding them
148      into a bignum.  For decimal and octal numbers we are
149      conservative: Some numbers may be assumed bignums when in fact
150      they do fit into 32 bits.  Numbers of any radix can have excess
151      leading zeros: We strive to recognise this and cast them back
152      into 32 bits.  We must check that the bignum really is more than
153      32 bits, and change it back to a 32-bit number if it fits.  The
154      number we are looking for is expected to be positive, but if it
155      fits into 32 bits as an unsigned number, we let it be a 32-bit
156      number.  The cavalier approach is for speed in ordinary cases. */
157   /* This has been extended for 64 bits.  We blindly assume that if
158      you're compiling in 64-bit mode, the target is a 64-bit machine.
159      This should be cleaned up.  */
160
161 #ifdef BFD64
162 #define valuesize 64
163 #else /* includes non-bfd case, mostly */
164 #define valuesize 32
165 #endif
166
167   switch (radix)
168     {
169     case 2:
170       maxdig = 2;
171       too_many_digits = valuesize + 1;
172       break;
173     case 8:
174       maxdig = radix = 8;
175       too_many_digits = (valuesize + 2) / 3 + 1;
176       break;
177     case 16:
178       maxdig = radix = 16;
179       too_many_digits = (valuesize + 3) / 4 + 1;
180       break;
181     case 10:
182       maxdig = radix = 10;
183       too_many_digits = (valuesize + 12) / 4; /* very rough */
184     }
185 #undef valuesize
186   start = input_line_pointer;
187   c = *input_line_pointer++;
188   for (number = 0;
189        (digit = hex_value (c)) < maxdig;
190        c = *input_line_pointer++)
191     {
192       number = number * radix + digit;
193     }
194   /* c contains character after number. */
195   /* input_line_pointer->char after c. */
196   small = (input_line_pointer - start - 1) < too_many_digits;
197   if (!small)
198     {
199       /*
200        * we saw a lot of digits. manufacture a bignum the hard way.
201        */
202       LITTLENUM_TYPE *leader;   /*->high order littlenum of the bignum. */
203       LITTLENUM_TYPE *pointer;  /*->littlenum we are frobbing now. */
204       long carry;
205
206       leader = generic_bignum;
207       generic_bignum[0] = 0;
208       generic_bignum[1] = 0;
209       input_line_pointer = start;       /*->1st digit. */
210       c = *input_line_pointer++;
211       for (;
212            (carry = hex_value (c)) < maxdig;
213            c = *input_line_pointer++)
214         {
215           for (pointer = generic_bignum;
216                pointer <= leader;
217                pointer++)
218             {
219               long work;
220
221               work = carry + radix * *pointer;
222               *pointer = work & LITTLENUM_MASK;
223               carry = work >> LITTLENUM_NUMBER_OF_BITS;
224             }
225           if (carry)
226             {
227               if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1)
228                 {
229                   /* room to grow a longer bignum. */
230                   *++leader = carry;
231                 }
232             }
233         }
234       /* again, c is char after number, */
235       /* input_line_pointer->after c. */
236       know (LITTLENUM_NUMBER_OF_BITS == 16);
237       if (leader < generic_bignum + 2)
238         {
239           /* will fit into 32 bits. */
240           number =
241             ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
242             | (generic_bignum[0] & LITTLENUM_MASK);
243           small = 1;
244         }
245       else
246         {
247           number = leader - generic_bignum + 1; /* number of littlenums in the bignum. */
248         }
249     }
250   if (small)
251     {
252       /*
253        * here with number, in correct radix. c is the next char.
254        * note that unlike un*x, we allow "011f" "0x9f" to
255        * both mean the same as the (conventional) "9f". this is simply easier
256        * than checking for strict canonical form. syntax sux!
257        */
258
259       switch (c)
260         {
261
262 #ifdef LOCAL_LABELS_FB
263         case 'b':
264           {
265             /*
266              * backward ref to local label.
267              * because it is backward, expect it to be defined.
268              */
269             /* Construct a local label.  */
270             name = fb_label_name ((int) number, 0);
271
272             /* seen before, or symbol is defined: ok */
273             symbolP = symbol_find (name);
274             if ((symbolP != NULL) && (S_IS_DEFINED (symbolP)))
275               {
276                 /* local labels are never absolute. don't waste time
277                    checking absoluteness. */
278                 know (SEG_NORMAL (S_GET_SEGMENT (symbolP)));
279
280                 expressionP->X_op = O_symbol;
281                 expressionP->X_add_symbol = symbolP;
282               }
283             else
284               {
285                 /* either not seen or not defined. */
286                 /* @@ Should print out the original string instead of
287                    the parsed number.  */
288                 as_bad ("backw. ref to unknown label \"%d:\", 0 assumed.",
289                         (int) number);
290                 expressionP->X_op = O_constant;
291               }
292
293             expressionP->X_add_number = 0;
294             break;
295           }                     /* case 'b' */
296
297         case 'f':
298           {
299             /*
300              * forward reference. expect symbol to be undefined or
301              * unknown. undefined: seen it before. unknown: never seen
302              * it before.
303              * construct a local label name, then an undefined symbol.
304              * don't create a xseg frag for it: caller may do that.
305              * just return it as never seen before.
306              */
307             name = fb_label_name ((int) number, 1);
308             symbolP = symbol_find_or_make (name);
309             /* we have no need to check symbol properties. */
310 #ifndef many_segments
311             /* since "know" puts its arg into a "string", we
312                can't have newlines in the argument.  */
313             know (S_GET_SEGMENT (symbolP) == undefined_section || S_GET_SEGMENT (symbolP) == text_section || S_GET_SEGMENT (symbolP) == data_section);
314 #endif
315             expressionP->X_op = O_symbol;
316             expressionP->X_add_symbol = symbolP;
317             expressionP->X_add_number = 0;
318
319             break;
320           }                     /* case 'f' */
321
322 #endif /* LOCAL_LABELS_FB */
323
324 #ifdef LOCAL_LABELS_DOLLAR
325
326         case '$':
327           {
328
329             /* If the dollar label is *currently* defined, then this is just
330                another reference to it.  If it is not *currently* defined,
331                then this is a fresh instantiation of that number, so create
332                it.  */
333
334             if (dollar_label_defined ((long) number))
335               {
336                 name = dollar_label_name ((long) number, 0);
337                 symbolP = symbol_find (name);
338                 know (symbolP != NULL);
339               }
340             else
341               {
342                 name = dollar_label_name ((long) number, 1);
343                 symbolP = symbol_find_or_make (name);
344               }
345
346             expressionP->X_op = O_symbol;
347             expressionP->X_add_symbol = symbolP;
348             expressionP->X_add_number = 0;
349
350             break;
351           }                     /* case '$' */
352
353 #endif /* LOCAL_LABELS_DOLLAR */
354
355         default:
356           {
357             expressionP->X_op = O_constant;
358             expressionP->X_add_number = number;
359             input_line_pointer--;       /* restore following character. */
360             break;
361           }                     /* really just a number */
362
363         }                       /* switch on char following the number */
364
365     }
366   else
367     {
368       /* not a small number */
369       expressionP->X_op = O_big;
370       expressionP->X_add_number = number;       /* number of littlenums */
371       input_line_pointer--;     /*->char following number. */
372     }
373 }
374
375
376 /*
377  * Summary of operand().
378  *
379  * in:  Input_line_pointer points to 1st char of operand, which may
380  *      be a space.
381  *
382  * out: A expressionS.
383  *      The operand may have been empty: in this case X_op == O_absent.
384  *      Input_line_pointer->(next non-blank) char after operand.
385  */
386
387 static segT
388 operand (expressionP)
389      expressionS *expressionP;
390 {
391   char c;
392   symbolS *symbolP;     /* points to symbol */
393   char *name;           /* points to name of symbol */
394   segT segment;
395
396   /* All integers are regarded as unsigned unless they are negated.
397      This is because the only thing which cares whether a number is
398      unsigned is the code in emit_expr which extends constants into
399      bignums.  It should only sign extend negative numbers, so that
400      something like ``.quad 0x80000000'' is not sign extended even
401      though it appears negative if valueT is 32 bits.  */
402   expressionP->X_unsigned = 1;
403
404   /* digits, assume it is a bignum. */
405
406   SKIP_WHITESPACE ();           /* leading whitespace is part of operand. */
407   c = *input_line_pointer++;    /* input_line_pointer->past char in c. */
408
409   switch (c)
410     {
411 #ifdef MRI
412     case '%':
413       integer_constant (2, expressionP);
414       break;
415     case '@':
416       integer_constant (8, expressionP);
417       break;
418     case '$':
419       integer_constant (16, expressionP);
420       break;
421 #endif
422     case '1':
423     case '2':
424     case '3':
425     case '4':
426     case '5':
427     case '6':
428     case '7':
429     case '8':
430     case '9':
431       input_line_pointer--;
432
433       integer_constant (10, expressionP);
434       break;
435
436     case '0':
437       /* non-decimal radix */
438
439       c = *input_line_pointer;
440       switch (c)
441         {
442
443         default:
444           if (c && strchr (FLT_CHARS, c))
445             {
446               input_line_pointer++;
447               floating_constant (expressionP);
448               expressionP->X_add_number = -(isupper (c) ? tolower (c) : c);
449             }
450           else
451             {
452               /* The string was only zero */
453               expressionP->X_op = O_constant;
454               expressionP->X_add_number = 0;
455             }
456
457           break;
458
459         case 'x':
460         case 'X':
461           input_line_pointer++;
462           integer_constant (16, expressionP);
463           break;
464
465         case 'b':
466 #ifdef LOCAL_LABELS_FB
467           switch (input_line_pointer[1])
468             {
469             case '+':
470             case '-':
471               /* If unambiguously a difference expression, treat it as
472                  one by indicating a label; otherwise, it's always a
473                  binary number.  */
474               {
475                 char *cp = input_line_pointer + 1;
476                 while (strchr ("0123456789", *++cp))
477                   ;
478                 if (*cp == 'b' || *cp == 'f')
479                   goto is_0b_label;
480               }
481               goto is_0b_binary;
482             case '0':    case '1':
483               /* Some of our code elsewhere does permit digits greater
484                  than the expected base; for consistency, do the same
485                  here.  */
486             case '2':    case '3':    case '4':    case '5':
487             case '6':    case '7':    case '8':    case '9':
488               goto is_0b_binary;
489             case 0:
490               goto is_0b_label;
491             default:
492               goto is_0b_label;
493             }
494         is_0b_label:
495           input_line_pointer--;
496           integer_constant (10, expressionP);
497           break;
498         is_0b_binary:
499 #endif
500         case 'B':
501           input_line_pointer++;
502           integer_constant (2, expressionP);
503           break;
504
505         case '0':
506         case '1':
507         case '2':
508         case '3':
509         case '4':
510         case '5':
511         case '6':
512         case '7':
513           integer_constant (8, expressionP);
514           break;
515
516         case 'f':
517 #ifdef LOCAL_LABELS_FB
518           /* If it says "0f" and it could possibly be a floating point
519              number, make it one.  Otherwise, make it a local label,
520              and try to deal with parsing the rest later.  */
521           if (!input_line_pointer[1]
522               || (is_end_of_line[0xff & input_line_pointer[1]]))
523             goto is_0f_label;
524           {
525             char *cp = input_line_pointer + 1;
526             int r = atof_generic (&cp, ".", EXP_CHARS,
527                                   &generic_floating_point_number);
528             switch (r)
529               {
530               case 0:
531               case ERROR_EXPONENT_OVERFLOW:
532                 if (*cp == 'f' || *cp == 'b')
533                   /* looks like a difference expression */
534                   goto is_0f_label;
535                 else
536                   goto is_0f_float;
537               default:
538                 as_fatal ("expr.c(operand): bad atof_generic return val %d",
539                           r);
540               }
541           }
542
543           /* Okay, now we've sorted it out.  We resume at one of these
544              two labels, depending on what we've decided we're probably
545              looking at.  */
546         is_0f_label:
547           input_line_pointer--;
548           integer_constant (10, expressionP);
549           break;
550
551         is_0f_float:
552           /* fall through */
553 #endif
554
555         case 'd':
556         case 'D':
557         case 'F':
558         case 'r':
559         case 'e':
560         case 'E':
561         case 'g':
562         case 'G':
563           input_line_pointer++;
564           floating_constant (expressionP);
565           expressionP->X_add_number = -(isupper (c) ? tolower (c) : c);
566           break;
567
568 #ifdef LOCAL_LABELS_DOLLAR
569         case '$':
570           integer_constant (10, expressionP);
571           break;
572 #endif
573         }
574
575       break;
576
577     case '(':
578     case '[':
579       /* didn't begin with digit & not a name */
580       segment = expression (expressionP);
581       /* Expression() will pass trailing whitespace */
582       if (c == '(' && *input_line_pointer++ != ')' ||
583           c == '[' && *input_line_pointer++ != ']') 
584         {
585           as_bad ("Missing ')' assumed");
586           input_line_pointer--;
587         }
588       /* here with input_line_pointer->char after "(...)" */
589       return segment;
590
591     case '\'':
592       /* Warning: to conform to other people's assemblers NO ESCAPEMENT is
593          permitted for a single quote. The next character, parity errors and
594          all, is taken as the value of the operand. VERY KINKY.  */
595       expressionP->X_op = O_constant;
596       expressionP->X_add_number = *input_line_pointer++;
597       break;
598
599     case '+':
600       (void) operand (expressionP);
601       break;
602
603     case '~':
604     case '-':
605       {
606         operand (expressionP);
607         if (expressionP->X_op == O_constant)
608           {
609             /* input_line_pointer -> char after operand */
610             if (c == '-')
611               {
612                 expressionP->X_add_number = - expressionP->X_add_number;
613                 /* Notice: '-' may overflow: no warning is given. This is
614                    compatible with other people's assemblers. Sigh.  */
615                 expressionP->X_unsigned = 0;
616               }
617             else
618               expressionP->X_add_number = ~ expressionP->X_add_number;
619           }
620         else if (expressionP->X_op != O_illegal
621                  && expressionP->X_op != O_absent)
622           {
623             expressionP->X_add_symbol = make_expr_symbol (expressionP);
624             if (c == '-')
625               expressionP->X_op = O_uminus;
626             else
627               expressionP->X_op = O_bit_not;
628             expressionP->X_add_number = 0;
629           }
630         else
631           as_warn ("Unary operator %c ignored because bad operand follows",
632                    c);
633       }
634       break;
635
636     case '.':
637 #ifdef DOLLAR_DOT
638     case '$':
639 #endif
640       if (!is_part_of_name (*input_line_pointer))
641         {
642           const char *fake;
643
644           /* JF: '.' is pseudo symbol with value of current location
645              in current segment.  */
646           fake = FAKE_LABEL_NAME;
647           symbolP = symbol_new (fake,
648                                 now_seg,
649                                 (valueT) frag_now_fix (),
650                                 frag_now);
651
652           expressionP->X_op = O_symbol;
653           expressionP->X_add_symbol = symbolP;
654           expressionP->X_add_number = 0;
655           break;
656         }
657       else
658         {
659           goto isname;
660         }
661     case ',':
662     case '\n':
663     case '\0':
664     eol:
665       /* can't imagine any other kind of operand */
666       expressionP->X_op = O_absent;
667       input_line_pointer--;
668       md_operand (expressionP);
669       break;
670
671     default:
672       if (is_end_of_line[(unsigned char) c])
673         goto eol;
674       if (is_name_beginner (c)) /* here if did not begin with a digit */
675         {
676           /*
677            * Identifier begins here.
678            * This is kludged for speed, so code is repeated.
679            */
680         isname:
681           name = --input_line_pointer;
682           c = get_symbol_end ();
683           symbolP = symbol_find_or_make (name);
684
685           /* If we have an absolute symbol or a reg, then we know its
686              value now.  */
687           segment = S_GET_SEGMENT (symbolP);
688           if (segment == absolute_section)
689             {
690               expressionP->X_op = O_constant;
691               expressionP->X_add_number = S_GET_VALUE (symbolP);
692             }
693           else if (segment == reg_section)
694             {
695               expressionP->X_op = O_register;
696               expressionP->X_add_number = S_GET_VALUE (symbolP);
697             }
698           else
699             {
700               expressionP->X_op = O_symbol;
701               expressionP->X_add_symbol = symbolP;
702               expressionP->X_add_number = 0;
703             }
704           *input_line_pointer = c;
705         }
706       else
707         {
708           as_bad ("Bad expression");
709           expressionP->X_op = O_constant;
710           expressionP->X_add_number = 0;
711         }
712     }
713
714   /*
715    * It is more 'efficient' to clean up the expressionS when they are created.
716    * Doing it here saves lines of code.
717    */
718   clean_up_expression (expressionP);
719   SKIP_WHITESPACE ();           /*->1st char after operand. */
720   know (*input_line_pointer != ' ');
721
722   /* The PA port needs this information.  */
723   if (expressionP->X_add_symbol)
724     expressionP->X_add_symbol->sy_used = 1;
725
726   switch (expressionP->X_op)
727     {
728     default:
729       return absolute_section;
730     case O_symbol:
731       return S_GET_SEGMENT (expressionP->X_add_symbol);
732     case O_register:
733       return reg_section;
734     }
735 }                               /* operand() */
736 \f
737 /* Internal. Simplify a struct expression for use by expr() */
738
739 /*
740  * In:  address of a expressionS.
741  *      The X_op field of the expressionS may only take certain values.
742  *      Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT.
743  * Out: expressionS may have been modified:
744  *      'foo-foo' symbol references cancelled to 0,
745  *              which changes X_op from O_subtract to O_constant.
746  *      Unused fields zeroed to help expr().
747  */
748
749 static void
750 clean_up_expression (expressionP)
751      expressionS *expressionP;
752 {
753   switch (expressionP->X_op)
754     {
755     case O_illegal:
756     case O_absent:
757       expressionP->X_add_number = 0;
758       /* Fall through.  */
759     case O_big:
760     case O_constant:
761     case O_register:
762       expressionP->X_add_symbol = NULL;
763       /* Fall through.  */
764     case O_symbol:
765     case O_uminus:
766     case O_bit_not:
767       expressionP->X_op_symbol = NULL;
768       break;
769     case O_subtract:
770       if (expressionP->X_op_symbol == expressionP->X_add_symbol
771           || ((expressionP->X_op_symbol->sy_frag
772                == expressionP->X_add_symbol->sy_frag)
773               && SEG_NORMAL (S_GET_SEGMENT (expressionP->X_add_symbol))
774               && (S_GET_VALUE (expressionP->X_op_symbol)
775                   == S_GET_VALUE (expressionP->X_add_symbol))))
776         {
777           addressT diff = (S_GET_VALUE (expressionP->X_add_symbol)
778                            - S_GET_VALUE (expressionP->X_op_symbol));
779
780           expressionP->X_op = O_constant;
781           expressionP->X_add_symbol = NULL;
782           expressionP->X_op_symbol = NULL;
783           expressionP->X_add_number += diff;
784         }
785       break;
786     default:
787       break;
788     }
789 }
790 \f
791 /* Expression parser. */
792
793 /*
794  * We allow an empty expression, and just assume (absolute,0) silently.
795  * Unary operators and parenthetical expressions are treated as operands.
796  * As usual, Q==quantity==operand, O==operator, X==expression mnemonics.
797  *
798  * We used to do a aho/ullman shift-reduce parser, but the logic got so
799  * warped that I flushed it and wrote a recursive-descent parser instead.
800  * Now things are stable, would anybody like to write a fast parser?
801  * Most expressions are either register (which does not even reach here)
802  * or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common.
803  * So I guess it doesn't really matter how inefficient more complex expressions
804  * are parsed.
805  *
806  * After expr(RANK,resultP) input_line_pointer->operator of rank <= RANK.
807  * Also, we have consumed any leading or trailing spaces (operand does that)
808  * and done all intervening operators.
809  *
810  * This returns the segment of the result, which will be
811  * absolute_section or the segment of a symbol.
812  */
813
814 #undef __
815 #define __ O_illegal
816
817 static const operatorT op_encoding[256] =
818 {                               /* maps ASCII->operators */
819
820   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
821   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
822
823   __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __,
824   __, __, O_multiply, O_add, __, O_subtract, __, O_divide,
825   __, __, __, __, __, __, __, __,
826   __, __, __, __, O_left_shift, __, O_right_shift, __,
827   __, __, __, __, __, __, __, __,
828   __, __, __, __, __, __, __, __,
829   __, __, __, __, __, __, __, __,
830   __, __, __, __, __, __, O_bit_exclusive_or, __,
831   __, __, __, __, __, __, __, __,
832   __, __, __, __, __, __, __, __,
833   __, __, __, __, __, __, __, __,
834   __, __, __, __, O_bit_inclusive_or, __, __, __,
835
836   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
837   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
838   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
839   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
840   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
841   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
842   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
843   __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
844 };
845
846
847 /*
848  *      Rank    Examples
849  *      0       operand, (expression)
850  *      1       + -
851  *      2       & ^ ! |
852  *      3       * / % << >>
853  *      4       unary - unary ~
854  */
855 static const operator_rankT op_rank[] =
856 {
857   0,    /* O_illegal */
858   0,    /* O_absent */
859   0,    /* O_constant */
860   0,    /* O_symbol */
861   0,    /* O_register */
862   0,    /* O_bit */
863   4,    /* O_uminus */
864   4,    /* O_bit_now */
865   3,    /* O_multiply */
866   3,    /* O_divide */
867   3,    /* O_modulus */
868   3,    /* O_left_shift */
869   3,    /* O_right_shift */
870   2,    /* O_bit_inclusive_or */
871   2,    /* O_bit_or_not */
872   2,    /* O_bit_exclusive_or */
873   2,    /* O_bit_and */
874   1,    /* O_add */
875   1,    /* O_subtract */
876 };
877 \f
878 segT
879 expr (rank, resultP)
880      operator_rankT rank;       /* Larger # is higher rank. */
881      expressionS *resultP;      /* Deliver result here. */
882 {
883   segT retval;
884   expressionS right;
885   operatorT op_left;
886   char c_left;          /* 1st operator character. */
887   operatorT op_right;
888   char c_right;
889
890   know (rank >= 0);
891
892   retval = operand (resultP);
893
894   know (*input_line_pointer != ' ');    /* Operand() gobbles spaces. */
895
896   c_left = *input_line_pointer; /* Potential operator character. */
897   op_left = op_encoding[(unsigned char) c_left];
898   while (op_left != O_illegal && op_rank[(int) op_left] > rank)
899     {
900       segT rightseg;
901
902       input_line_pointer++;     /*->after 1st character of operator. */
903       /* Operators "<<" and ">>" have 2 characters. */
904       if (*input_line_pointer == c_left && (c_left == '<' || c_left == '>'))
905         ++input_line_pointer;
906
907       rightseg = expr (op_rank[(int) op_left], &right);
908       if (right.X_op == O_absent)
909         {
910           as_warn ("missing operand; zero assumed");
911           right.X_op = O_constant;
912           right.X_add_number = 0;
913           right.X_add_symbol = NULL;
914           right.X_op_symbol = NULL;
915         }
916
917       know (*input_line_pointer != ' ');
918
919       if (retval == undefined_section)
920         {
921           if (SEG_NORMAL (rightseg))
922             retval = rightseg;
923         }
924       else if (! SEG_NORMAL (retval))
925         retval = rightseg;
926       else if (SEG_NORMAL (rightseg)
927                && retval != rightseg
928 #ifdef DIFF_EXPR_OK
929                && op_left != O_subtract
930 #endif
931                )
932         as_bad ("operation combines symbols in different segments");
933
934       c_right = *input_line_pointer;
935       op_right = op_encoding[(unsigned char) c_right];
936       if (*input_line_pointer == c_right && (c_right == '<' || c_right == '>'))
937         ++input_line_pointer;
938
939       know (op_right == O_illegal || op_rank[(int) op_right] <= op_rank[(int) op_left]);
940       know ((int) op_left >= (int) O_multiply && (int) op_left <= (int) O_subtract);
941
942       /* input_line_pointer->after right-hand quantity. */
943       /* left-hand quantity in resultP */
944       /* right-hand quantity in right. */
945       /* operator in op_left. */
946
947       if (resultP->X_op == O_big)
948         {
949           as_warn ("left operand of %c is a %s; integer 0 assumed",
950                    c_left, resultP->X_add_number > 0 ? "bignum" : "float");
951           resultP->X_op = O_constant;
952           resultP->X_add_number = 0;
953           resultP->X_add_symbol = NULL;
954           resultP->X_op_symbol = NULL;
955         }
956       if (right.X_op == O_big)
957         {
958           as_warn ("right operand of %c is a %s; integer 0 assumed",
959                    c_left, right.X_add_number > 0 ? "bignum" : "float");
960           right.X_op = O_constant;
961           right.X_add_number = 0;
962           right.X_add_symbol = NULL;
963           right.X_op_symbol = NULL;
964         }
965
966       /* Optimize common cases.  */
967 #if 0
968       if (op_left == O_add && resultP->X_got_symbol)
969         {
970           /* XXX - kludge here to accomodate "_GLOBAL_OFFSET_TABLE + (x - y)"
971            * expressions: this only works for this special case, the
972            * _GLOBAL_OFFSET_TABLE thing *must* be the left operand, the whole
973            * expression is given the segment of right expression (always a DIFFERENCE,
974            * which should get resolved by fixup_segment())
975            */
976           resultP->X_op = right.X_op;
977           resultP->X_add_symbol = right.X_add_symbol;
978           resultP->X_op_symbol = right.X_op_symbol;
979         }
980       else
981 #endif
982         if (op_left == O_add && right.X_op == O_constant)
983         {
984           /* X + constant.  */
985           resultP->X_add_number += right.X_add_number;
986         }
987       /* This case comes up in PIC code.  */
988       else if (op_left == O_subtract
989                && right.X_op == O_symbol
990                && resultP->X_op == O_symbol
991                && (right.X_add_symbol->sy_frag
992                    == resultP->X_add_symbol->sy_frag)
993                && SEG_NORMAL (S_GET_SEGMENT (right.X_add_symbol)))
994
995         {
996           resultP->X_add_number += right.X_add_number;
997           resultP->X_add_number += (S_GET_VALUE (resultP->X_add_symbol)
998                                     - S_GET_VALUE (right.X_add_symbol));
999           resultP->X_op = O_constant;
1000           resultP->X_add_symbol = 0;
1001         }
1002       else if (op_left == O_subtract && right.X_op == O_constant)
1003         {
1004           /* X - constant.  */
1005           resultP->X_add_number -= right.X_add_number;
1006         }
1007       else if (op_left == O_add && resultP->X_op == O_constant)
1008         {
1009           /* Constant + X.  */
1010           resultP->X_op = right.X_op;
1011           resultP->X_add_symbol = right.X_add_symbol;
1012           resultP->X_op_symbol = right.X_op_symbol;
1013           resultP->X_add_number += right.X_add_number;
1014           retval = rightseg;
1015         }
1016       else if (resultP->X_op == O_constant && right.X_op == O_constant)
1017         {
1018           /* Constant OP constant.  */
1019           offsetT v = right.X_add_number;
1020           if (v == 0 && (op_left == O_divide || op_left == O_modulus))
1021             {
1022               as_warn ("division by zero");
1023               v = 1;
1024             }
1025           switch (op_left)
1026             {
1027             case O_multiply:            resultP->X_add_number *= v; break;
1028             case O_divide:              resultP->X_add_number /= v; break;
1029             case O_modulus:             resultP->X_add_number %= v; break;
1030             case O_left_shift:          resultP->X_add_number <<= v; break;
1031             case O_right_shift:         resultP->X_add_number >>= v; break;
1032             case O_bit_inclusive_or:    resultP->X_add_number |= v; break;
1033             case O_bit_or_not:          resultP->X_add_number |= ~v; break;
1034             case O_bit_exclusive_or:    resultP->X_add_number ^= v; break;
1035             case O_bit_and:             resultP->X_add_number &= v; break;
1036             case O_add:                 resultP->X_add_number += v; break;
1037             case O_subtract:            resultP->X_add_number -= v; break;
1038             default:                    abort ();
1039             }
1040         }
1041       else if (resultP->X_op == O_symbol
1042                && right.X_op == O_symbol
1043                && (op_left == O_add
1044                    || op_left == O_subtract
1045                    || (resultP->X_add_number == 0
1046                        && right.X_add_number == 0)))
1047         {
1048           /* Symbol OP symbol.  */
1049           resultP->X_op = op_left;
1050           resultP->X_op_symbol = right.X_add_symbol;
1051           if (op_left == O_add)
1052             resultP->X_add_number += right.X_add_number;
1053           else if (op_left == O_subtract)
1054             resultP->X_add_number -= right.X_add_number;
1055         }
1056       else
1057         {
1058           /* The general case.  */
1059           resultP->X_add_symbol = make_expr_symbol (resultP);
1060           resultP->X_op_symbol = make_expr_symbol (&right);
1061           resultP->X_op = op_left;
1062           resultP->X_add_number = 0;
1063           resultP->X_unsigned = 1;
1064         }
1065
1066       op_left = op_right;
1067     }                           /* While next operator is >= this rank. */
1068
1069   /* The PA port needs this information.  */
1070   if (resultP->X_add_symbol)
1071     resultP->X_add_symbol->sy_used = 1;
1072
1073   return resultP->X_op == O_constant ? absolute_section : retval;
1074 }
1075 \f
1076 /*
1077  *                      get_symbol_end()
1078  *
1079  * This lives here because it belongs equally in expr.c & read.c.
1080  * Expr.c is just a branch office read.c anyway, and putting it
1081  * here lessens the crowd at read.c.
1082  *
1083  * Assume input_line_pointer is at start of symbol name.
1084  * Advance input_line_pointer past symbol name.
1085  * Turn that character into a '\0', returning its former value.
1086  * This allows a string compare (RMS wants symbol names to be strings)
1087  * of the symbol name.
1088  * There will always be a char following symbol name, because all good
1089  * lines end in end-of-line.
1090  */
1091 char
1092 get_symbol_end ()
1093 {
1094   char c;
1095
1096   while (is_part_of_name (c = *input_line_pointer++))
1097     ;
1098   *--input_line_pointer = 0;
1099   return (c);
1100 }
1101
1102
1103 unsigned int
1104 get_single_number ()
1105 {
1106   expressionS exp;
1107   operand (&exp);
1108   return exp.X_add_number;
1109
1110 }
1111
1112 /* end of expr.c */
This page took 0.086358 seconds and 4 git commands to generate.