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