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