1 /* expr.c -operands, expressions-
2 Copyright (C) 1987, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
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.
34 static void clean_up_expression PARAMS ((expressionS * expressionP));
35 extern const char EXP_CHARS[], FLT_CHARS[];
38 * Build any floating-point literal here.
39 * Also build any bignum literal here.
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 =
50 &generic_bignum[6], /* low (JF: Was 0) */
51 &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1], /* high JF: (added +6) */
56 /* If nonzero, we've been asked to assemble nan, +inf or -inf */
57 int generic_floating_point_magic;
60 floating_constant (expressionP)
61 expressionS *expressionP;
63 /* input_line_pointer->*/
64 /* floating-point constant. */
67 error_code = atof_generic
68 (&input_line_pointer, ".", EXP_CHARS,
69 &generic_floating_point_number);
73 if (error_code == ERROR_EXPONENT_OVERFLOW)
75 as_bad ("bad floating-point constant: exponent overflow, probably assembling junk");
79 as_bad ("bad floating-point constant: unknown error code=%d.", error_code);
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;
90 integer_constant (radix, expressionP)
92 expressionS *expressionP;
94 char *digit_2; /*->2nd digit of number. */
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 */
104 int small; /* true if fits in 32 bits. */
105 extern const char hex_value[]; /* in hex_value.c */
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. */
127 too_many_digits = 33;
131 too_many_digits = 11;
141 too_many_digits = 11;
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++)
148 number = number * radix + digit;
150 /* c contains character after number. */
151 /* input_line_pointer->char after c. */
152 small = input_line_pointer - digit_2 < too_many_digits;
156 * we saw a lot of digits. manufacture a bignum the hard way.
158 LITTLENUM_TYPE *leader; /*->high order littlenum of the bignum. */
159 LITTLENUM_TYPE *pointer; /*->littlenum we are frobbing now. */
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++)
170 for (pointer = generic_bignum;
176 work = carry + radix * *pointer;
177 *pointer = work & LITTLENUM_MASK;
178 carry = work >> LITTLENUM_NUMBER_OF_BITS;
182 if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1)
183 { /* room to grow a longer bignum. */
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. */
196 ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
197 | (generic_bignum[0] & LITTLENUM_MASK);
202 number = leader - generic_bignum + 1; /* number of littlenums in the bignum. */
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!
217 #ifdef LOCAL_LABELS_FB
221 * backward ref to local label.
222 * because it is backward, expect it to be defined.
224 /* Construct a local label. */
225 name = fb_label_name ((int) number, 0);
227 /* seen before, or symbol is defined: ok */
228 symbolP = symbol_find (name);
229 if ((symbolP != NULL) && (S_IS_DEFINED (symbolP)))
232 /* local labels are never absolute. don't waste time
233 checking absoluteness. */
234 know (SEG_NORMAL (S_GET_SEGMENT (symbolP)));
236 expressionP->X_add_symbol = symbolP;
237 expressionP->X_seg = S_GET_SEGMENT (symbolP);
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.",
247 expressionP->X_seg = absolute_section;
250 expressionP->X_add_number = 0;
257 * forward reference. expect symbol to be undefined or
258 * unknown. undefined: seen it before. unknown: never seen
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.
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);
272 expressionP->X_add_symbol = symbolP;
273 expressionP->X_seg = undefined_section;
274 expressionP->X_subtract_symbol = NULL;
275 expressionP->X_add_number = 0;
280 #endif /* LOCAL_LABELS_FB */
282 #ifdef LOCAL_LABELS_DOLLAR
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
292 if (dollar_label_defined (number))
294 name = dollar_label_name (number, 0);
295 symbolP = symbol_find (name);
296 know (symbolP != NULL);
300 name = dollar_label_name (number, 1);
301 symbolP = symbol_find_or_make (name);
304 expressionP->X_add_symbol = symbolP;
305 expressionP->X_add_number = 0;
306 expressionP->X_seg = S_GET_SEGMENT (symbolP);
311 #endif /* LOCAL_LABELS_DOLLAR */
315 expressionP->X_add_number = number;
316 expressionP->X_seg = absolute_section;
317 input_line_pointer--; /* restore following character. */
319 } /* really just a number */
321 } /* switch on char following the number */
327 /* not a small number */
328 expressionP->X_add_number = number;
329 expressionP->X_seg = big_section;
330 input_line_pointer--; /*->char following number. */
332 } /* integer_constant() */
336 * Summary of operand().
338 * in: Input_line_pointer points to 1st char of operand, which may
341 * out: A expressionS. X_seg determines how to understand the rest of the
343 * The operand may have been empty: in this case X_seg == SEG_ABSENT.
344 * Input_line_pointer->(next non-blank) char after operand.
351 operand (expressionP)
352 expressionS *expressionP;
355 symbolS *symbolP; /* points to symbol */
356 char *name; /* points to name of symbol */
358 /* digits, assume it is a bignum. */
360 SKIP_WHITESPACE (); /* leading whitespace is part of operand. */
361 c = *input_line_pointer++; /* input_line_pointer->past char in c. */
367 integer_constant (2, expressionP);
370 integer_constant (8, expressionP);
373 integer_constant (16, expressionP);
385 input_line_pointer--;
387 integer_constant (10, expressionP);
391 /* non-decimal radix */
394 c = *input_line_pointer;
399 if (c && strchr (FLT_CHARS, c))
401 input_line_pointer++;
402 floating_constant (expressionP);
406 /* The string was only zero */
407 expressionP->X_add_symbol = 0;
408 expressionP->X_add_number = 0;
409 expressionP->X_seg = absolute_section;
416 input_line_pointer++;
417 integer_constant (16, expressionP);
421 #ifdef LOCAL_LABELS_FB
422 if (!*input_line_pointer
423 || (!strchr ("+-.0123456789", *input_line_pointer)
424 && !strchr (EXP_CHARS, *input_line_pointer)))
426 input_line_pointer--;
427 integer_constant (10, expressionP);
432 input_line_pointer++;
433 integer_constant (2, expressionP);
444 integer_constant (8, expressionP);
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. */
453 && (!*input_line_pointer ||
454 (!strchr ("+-.0123456789", *input_line_pointer) &&
455 !strchr (EXP_CHARS, *input_line_pointer))))
457 input_line_pointer -= 1;
458 integer_constant (10, expressionP);
472 input_line_pointer++;
473 floating_constant (expressionP);
474 expressionP->X_add_number = -(isupper (c) ? tolower (c) : c);
477 #ifdef LOCAL_LABELS_DOLLAR
479 integer_constant (10, expressionP);
486 /* didn't begin with digit & not a name */
488 (void) expression (expressionP);
489 /* Expression() will pass trailing whitespace */
490 if (*input_line_pointer++ != ')')
492 as_bad ("Missing ')' assumed");
493 input_line_pointer--;
495 /* here with input_line_pointer->char after "(...)" */
497 return expressionP->X_seg;
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;
509 operand (expressionP);
515 /* unary operator: hope for SEG_ABSOLUTE */
516 segT opseg = operand (expressionP);
517 if (opseg == absolute_section)
519 /* input_line_pointer -> char after operand */
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. */
528 expressionP->X_add_number = ~expressionP->X_add_number;
531 else if (opseg == text_section
532 || opseg == data_section
533 || opseg == bss_section
534 || opseg == pass1_section
535 || opseg == undefined_section)
539 expressionP->X_subtract_symbol = expressionP->X_add_symbol;
540 expressionP->X_add_symbol = 0;
541 expressionP->X_seg = diff_section;
544 as_warn ("Unary operator %c ignored because bad operand follows",
548 as_warn ("Unary operator %c ignored because bad operand follows", c);
553 if (!is_part_of_name (*input_line_pointer))
556 extern struct obstack frags;
558 /* JF: '.' is pseudo symbol with value of current location
559 in current segment. */
560 #ifdef DOT_LABEL_PREFIX
565 symbolP = symbol_new (fake,
567 (valueT) ((char*)obstack_next_free (&frags) - frag_now->fr_literal),
570 expressionP->X_add_number = 0;
571 expressionP->X_add_symbol = symbolP;
572 expressionP->X_seg = now_seg;
586 /* can't imagine any other kind of operand */
587 expressionP->X_seg = absent_section;
588 input_line_pointer--;
589 md_operand (expressionP);
593 if (is_end_of_line[c])
595 if (is_name_beginner (c)) /* here if did not begin with a digit */
598 * Identifier begins here.
599 * This is kludged for speed, so code is repeated.
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
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);
613 expressionP->X_add_number = 0;
614 expressionP->X_add_symbol = symbolP;
616 *input_line_pointer = c;
617 expressionP->X_subtract_symbol = NULL;
621 as_bad ("Bad expression");
622 expressionP->X_add_number = 0;
623 expressionP->X_seg = absolute_section;
628 * It is more 'efficient' to clean up the expressionS when they are created.
629 * Doing it here saves lines of code.
631 clean_up_expression (expressionP);
632 SKIP_WHITESPACE (); /*->1st char after operand. */
633 know (*input_line_pointer != ' ');
634 return (expressionP->X_seg);
638 /* Internal. Simplify a struct expression for use by expr() */
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().
652 clean_up_expression (expressionP)
653 expressionS *expressionP;
655 segT s = expressionP->X_seg;
656 if (s == absent_section
657 || s == pass1_section)
659 expressionP->X_add_symbol = NULL;
660 expressionP->X_subtract_symbol = NULL;
661 expressionP->X_add_number = 0;
663 else if (s == big_section
664 || s == absolute_section)
666 expressionP->X_subtract_symbol = NULL;
667 expressionP->X_add_symbol = NULL;
669 else if (s == undefined_section)
670 expressionP->X_subtract_symbol = NULL;
671 else if (s == diff_section)
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.
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 && (S_GET_VALUE (expressionP->X_subtract_symbol)
685 == S_GET_VALUE (expressionP->X_add_symbol))))
687 expressionP->X_subtract_symbol = NULL;
688 expressionP->X_add_symbol = NULL;
689 expressionP->X_seg = absolute_section;
692 else if (s == reg_section)
694 expressionP->X_add_symbol = NULL;
695 expressionP->X_subtract_symbol = NULL;
699 if (SEG_NORMAL (expressionP->X_seg))
701 expressionP->X_subtract_symbol = NULL;
705 BAD_CASE (expressionP->X_seg);
713 * Internal. Made a function because this code is used in 2 places.
714 * Generate error or correct X_?????_symbol of expressionS.
718 * symbol_1 += symbol_2 ... well ... sort of.
722 expr_part (symbol_1_PP, symbol_2_P)
723 symbolS **symbol_1_PP;
728 #if !defined (BFD_ASSEMBLER) && (defined (OBJ_AOUT) || defined (OBJ_BOUT))
729 int test = ((*symbol_1_PP) == NULL
730 || (S_GET_SEGMENT (*symbol_1_PP) == text_section)
731 || (S_GET_SEGMENT (*symbol_1_PP) == data_section)
732 || (S_GET_SEGMENT (*symbol_1_PP) == bss_section)
733 || (!S_IS_DEFINED (*symbol_1_PP)));
735 test = (symbol_2_P == NULL
736 || (S_GET_SEGMENT (symbol_2_P) == text_section)
737 || (S_GET_SEGMENT (symbol_2_P) == data_section)
738 || (S_GET_SEGMENT (symbol_2_P) == bss_section)
739 || (!S_IS_DEFINED (symbol_2_P)));
744 if (!S_IS_DEFINED (*symbol_1_PP))
748 return_value = pass1_section;
753 know (!S_IS_DEFINED (*symbol_1_PP));
754 return_value = undefined_section;
761 if (!S_IS_DEFINED (symbol_2_P))
764 return_value = pass1_section;
768 /* {seg1} - {seg2} */
769 as_bad ("Expression too complex, 2 symbolS forgotten: \"%s\" \"%s\"",
770 S_GET_NAME (*symbol_1_PP), S_GET_NAME (symbol_2_P));
772 return_value = absolute_section;
777 return_value = S_GET_SEGMENT (*symbol_1_PP);
782 { /* (* symbol_1_PP) == NULL */
785 *symbol_1_PP = symbol_2_P;
786 return_value = S_GET_SEGMENT (symbol_2_P);
791 return_value = absolute_section;
794 #if defined (OBJ_AOUT) && !defined (BFD_ASSEMBLER)
795 test = (return_value == absolute_section
796 || return_value == text_section
797 || return_value == data_section
798 || return_value == bss_section
799 || return_value == undefined_section
800 || return_value == pass1_section);
803 know ((*symbol_1_PP) == NULL
804 || (S_GET_SEGMENT (*symbol_1_PP) == return_value));
805 return (return_value);
808 /* Expression parser. */
811 * We allow an empty expression, and just assume (absolute,0) silently.
812 * Unary operators and parenthetical expressions are treated as operands.
813 * As usual, Q==quantity==operand, O==operator, X==expression mnemonics.
815 * We used to do a aho/ullman shift-reduce parser, but the logic got so
816 * warped that I flushed it and wrote a recursive-descent parser instead.
817 * Now things are stable, would anybody like to write a fast parser?
818 * Most expressions are either register (which does not even reach here)
819 * or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common.
820 * So I guess it doesn't really matter how inefficient more complex expressions
823 * After expr(RANK,resultP) input_line_pointer->operator of rank <= RANK.
824 * Also, we have consumed any leading or trailing spaces (operand does that)
825 * and done all intervening operators.
830 O_illegal, /* (0) what we get for illegal op */
832 O_multiply, /* (1) * */
833 O_divide, /* (2) / */
834 O_modulus, /* (3) % */
835 O_left_shift, /* (4) < */
836 O_right_shift, /* (5) > */
837 O_bit_inclusive_or, /* (6) | */
838 O_bit_or_not, /* (7) ! */
839 O_bit_exclusive_or, /* (8) ^ */
840 O_bit_and, /* (9) & */
842 O_subtract /* (11) - */
850 static const operatorT op_encoding[256] =
851 { /* maps ASCII->operators */
853 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
854 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
856 __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __,
857 __, __, O_multiply, O_add, __, O_subtract, __, O_divide,
858 __, __, __, __, __, __, __, __,
859 __, __, __, __, O_left_shift, __, O_right_shift, __,
860 __, __, __, __, __, __, __, __,
861 __, __, __, __, __, __, __, __,
862 __, __, __, __, __, __, __, __,
863 __, __, __, __, __, __, O_bit_exclusive_or, __,
864 __, __, __, __, __, __, __, __,
865 __, __, __, __, __, __, __, __,
866 __, __, __, __, __, __, __, __,
867 __, __, __, __, O_bit_inclusive_or, __, __, __,
869 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
870 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
871 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
872 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
873 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
874 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
875 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
876 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
882 * 0 operand, (expression)
887 static const operator_rankT
889 {0, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1};
891 /* Return resultP->X_seg. */
894 operator_rankT rank; /* Larger # is higher rank. */
895 expressionS *resultP; /* Deliver result here. */
899 char c_left; /* 1st operator character. */
904 (void) operand (resultP);
905 know (*input_line_pointer != ' '); /* Operand() gobbles spaces. */
906 c_left = *input_line_pointer; /* Potential operator character. */
907 op_left = op_encoding[c_left];
908 while (op_left != O_illegal && op_rank[(int) op_left] > rank)
910 input_line_pointer++; /*->after 1st character of operator. */
911 /* Operators "<<" and ">>" have 2 characters. */
912 if (*input_line_pointer == c_left && (c_left == '<' || c_left == '>'))
914 input_line_pointer++;
915 } /*->after operator. */
916 if (absent_section == expr (op_rank[(int) op_left], &right))
918 as_warn ("Missing operand value assumed absolute 0.");
919 resultP->X_add_number = 0;
920 resultP->X_subtract_symbol = NULL;
921 resultP->X_add_symbol = NULL;
922 resultP->X_seg = absolute_section;
924 know (*input_line_pointer != ' ');
925 c_right = *input_line_pointer;
926 op_right = op_encoding[c_right];
927 if (*input_line_pointer == c_right && (c_right == '<' || c_right == '>'))
929 input_line_pointer++;
930 } /*->after operator. */
931 know ((int) op_right == 0 || op_rank[(int) op_right] <= op_rank[(int) op_left]);
932 /* input_line_pointer->after right-hand quantity. */
933 /* left-hand quantity in resultP */
934 /* right-hand quantity in right. */
935 /* operator in op_left. */
936 if (resultP->X_seg == pass1_section || right.X_seg == pass1_section)
938 resultP->X_seg = pass1_section;
942 if (resultP->X_seg == big_section)
944 as_warn ("Left operand of %c is a %s. Integer 0 assumed.",
945 c_left, resultP->X_add_number > 0 ? "bignum" : "float");
946 resultP->X_seg = absolute_section;
947 resultP->X_add_symbol = 0;
948 resultP->X_subtract_symbol = 0;
949 resultP->X_add_number = 0;
951 if (right.X_seg == big_section)
953 as_warn ("Right operand of %c is a %s. Integer 0 assumed.",
954 c_left, right.X_add_number > 0 ? "bignum" : "float");
955 right.X_seg = absolute_section;
956 right.X_add_symbol = 0;
957 right.X_subtract_symbol = 0;
958 right.X_add_number = 0;
960 if (op_left == O_subtract)
963 * Convert - into + by exchanging symbolS and negating number.
964 * I know -infinity can't be negated in 2's complement:
965 * but then it can't be subtracted either. This trick
966 * does not cause any further inaccuracy.
971 right.X_add_number = -right.X_add_number;
972 symbolP = right.X_add_symbol;
973 right.X_add_symbol = right.X_subtract_symbol;
974 right.X_subtract_symbol = symbolP;
977 right.X_seg = diff_section;
982 if (op_left == O_add)
986 #if 0 /* @@ This rejects stuff in common sections too. Figure out some
987 reasonable test, and make it clean... */
988 #if !defined (MANY_SEGMENTS) && !defined (OBJ_ECOFF)
989 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 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);
994 clean_up_expression (&right);
995 clean_up_expression (resultP);
997 seg1 = expr_part (&resultP->X_add_symbol, right.X_add_symbol);
998 seg2 = expr_part (&resultP->X_subtract_symbol, right.X_subtract_symbol);
999 if (seg1 == pass1_section || seg2 == pass1_section)
1002 resultP->X_seg = pass1_section;
1004 else if (seg2 == absolute_section)
1005 resultP->X_seg = seg1;
1006 else if (seg1 != undefined_section
1007 && seg1 != absolute_section
1008 && seg2 != undefined_section
1011 know (seg2 != absolute_section);
1012 know (resultP->X_subtract_symbol);
1013 #ifndef MANY_SEGMENTS
1015 know (seg1 == text_section || seg1 == data_section || seg1 == bss_section);
1016 know (seg2 == text_section || seg2 == data_section || seg2 == bss_section);
1019 know (resultP->X_add_symbol);
1020 know (resultP->X_subtract_symbol);
1021 as_bad ("Expression too complex: forgetting %s - %s",
1022 S_GET_NAME (resultP->X_add_symbol),
1023 S_GET_NAME (resultP->X_subtract_symbol));
1024 resultP->X_seg = absolute_section;
1025 /* Clean_up_expression() will do the rest. */
1028 resultP->X_seg = diff_section;
1030 resultP->X_add_number += right.X_add_number;
1031 clean_up_expression (resultP);
1035 if (resultP->X_seg == undefined_section || right.X_seg == undefined_section)
1037 resultP->X_seg = pass1_section;
1042 resultP->X_subtract_symbol = NULL;
1043 resultP->X_add_symbol = NULL;
1044 /* Will be absolute_section. */
1045 if (resultP->X_seg != absolute_section || right.X_seg != absolute_section)
1047 as_bad ("Relocation error: Symbolic expressions may only involve");
1048 as_bad (" addition and subtraction. Absolute 0 assumed.");
1049 resultP->X_seg = absolute_section;
1050 resultP->X_add_number = 0;
1056 case O_bit_inclusive_or:
1057 resultP->X_add_number |= right.X_add_number;
1061 if (right.X_add_number)
1063 resultP->X_add_number %= right.X_add_number;
1067 as_warn ("Division by 0. Result of 0 substituted.");
1068 resultP->X_add_number = 0;
1073 resultP->X_add_number &= right.X_add_number;
1077 resultP->X_add_number *= right.X_add_number;
1081 if (right.X_add_number)
1083 resultP->X_add_number /= right.X_add_number;
1087 as_warn ("Division by 0. 0 assumed.");
1088 resultP->X_add_number = 0;
1093 resultP->X_add_number <<= right.X_add_number;
1097 /* @@ We should distinguish signed versus
1098 unsigned here somehow. */
1099 resultP->X_add_number >>= right.X_add_number;
1102 case O_bit_exclusive_or:
1103 resultP->X_add_number ^= right.X_add_number;
1107 resultP->X_add_number |= ~right.X_add_number;
1113 } /* switch(operator) */
1115 } /* If we have to force need_pass_2. */
1116 } /* If operator was +. */
1117 } /* If we didn't set need_pass_2. */
1119 } /* While next operator is >= this rank. */
1120 return (resultP->X_seg);
1126 * This lives here because it belongs equally in expr.c & read.c.
1127 * Expr.c is just a branch office read.c anyway, and putting it
1128 * here lessens the crowd at read.c.
1130 * Assume input_line_pointer is at start of symbol name.
1131 * Advance input_line_pointer past symbol name.
1132 * Turn that character into a '\0', returning its former value.
1133 * This allows a string compare (RMS wants symbol names to be strings)
1134 * of the symbol name.
1135 * There will always be a char following symbol name, because all good
1136 * lines end in end-of-line.
1143 while (is_part_of_name (c = *input_line_pointer++))
1145 *--input_line_pointer = 0;
1151 get_single_number ()
1155 return exp.X_add_number;