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