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