Change various calls (e.g., to symbol_new, md_number_to_chars) to cast
[deliverable/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 && (S_GET_VALUE (expressionP->X_subtract_symbol)
685 == S_GET_VALUE (expressionP->X_add_symbol))))
686 {
687 expressionP->X_subtract_symbol = NULL;
688 expressionP->X_add_symbol = NULL;
689 expressionP->X_seg = absolute_section;
690 }
691 }
692 else if (s == reg_section)
693 {
694 expressionP->X_add_symbol = NULL;
695 expressionP->X_subtract_symbol = NULL;
696 }
697 else
698 {
699 if (SEG_NORMAL (expressionP->X_seg))
700 {
701 expressionP->X_subtract_symbol = NULL;
702 }
703 else
704 {
705 BAD_CASE (expressionP->X_seg);
706 }
707 }
708 }
709 \f
710 /*
711 * expr_part ()
712 *
713 * Internal. Made a function because this code is used in 2 places.
714 * Generate error or correct X_?????_symbol of expressionS.
715 */
716
717 /*
718 * symbol_1 += symbol_2 ... well ... sort of.
719 */
720
721 static segT
722 expr_part (symbol_1_PP, symbol_2_P)
723 symbolS **symbol_1_PP;
724 symbolS *symbol_2_P;
725 {
726 segT return_value;
727
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)));
734 assert (test);
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)));
740 assert (test);
741 #endif
742 if (*symbol_1_PP)
743 {
744 if (!S_IS_DEFINED (*symbol_1_PP))
745 {
746 if (symbol_2_P)
747 {
748 return_value = pass1_section;
749 *symbol_1_PP = NULL;
750 }
751 else
752 {
753 know (!S_IS_DEFINED (*symbol_1_PP));
754 return_value = undefined_section;
755 }
756 }
757 else
758 {
759 if (symbol_2_P)
760 {
761 if (!S_IS_DEFINED (symbol_2_P))
762 {
763 *symbol_1_PP = NULL;
764 return_value = pass1_section;
765 }
766 else
767 {
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));
771 *symbol_1_PP = NULL;
772 return_value = absolute_section;
773 }
774 }
775 else
776 {
777 return_value = S_GET_SEGMENT (*symbol_1_PP);
778 }
779 }
780 }
781 else
782 { /* (* symbol_1_PP) == NULL */
783 if (symbol_2_P)
784 {
785 *symbol_1_PP = symbol_2_P;
786 return_value = S_GET_SEGMENT (symbol_2_P);
787 }
788 else
789 {
790 *symbol_1_PP = NULL;
791 return_value = absolute_section;
792 }
793 }
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);
801 assert (test);
802 #endif
803 know ((*symbol_1_PP) == NULL
804 || (S_GET_SEGMENT (*symbol_1_PP) == return_value));
805 return (return_value);
806 }
807 \f
808 /* Expression parser. */
809
810 /*
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.
814 *
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
821 * are parsed.
822 *
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.
826 */
827
828 typedef enum
829 {
830 O_illegal, /* (0) what we get for illegal op */
831
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) & */
841 O_add, /* (10) + */
842 O_subtract /* (11) - */
843 }
844
845 operatorT;
846
847 #undef __
848 #define __ O_illegal
849
850 static const operatorT op_encoding[256] =
851 { /* maps ASCII->operators */
852
853 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
854 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
855
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, __, __, __,
868
869 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
870 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
871 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
872 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
873 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
874 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
875 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
876 __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
877 };
878
879
880 /*
881 * Rank Examples
882 * 0 operand, (expression)
883 * 1 + -
884 * 2 & ^ ! |
885 * 3 * / % << >>
886 */
887 static const operator_rankT
888 op_rank[] =
889 {0, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1};
890 \f
891 /* Return resultP->X_seg. */
892 segT
893 expr (rank, resultP)
894 operator_rankT rank; /* Larger # is higher rank. */
895 expressionS *resultP; /* Deliver result here. */
896 {
897 expressionS right;
898 operatorT op_left;
899 char c_left; /* 1st operator character. */
900 operatorT op_right;
901 char c_right;
902
903 know (rank >= 0);
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)
909 {
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 == '>'))
913 {
914 input_line_pointer++;
915 } /*->after operator. */
916 if (absent_section == expr (op_rank[(int) op_left], &right))
917 {
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;
923 }
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 == '>'))
928 {
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)
937 {
938 resultP->X_seg = pass1_section;
939 }
940 else
941 {
942 if (resultP->X_seg == big_section)
943 {
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;
950 }
951 if (right.X_seg == big_section)
952 {
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;
959 }
960 if (op_left == O_subtract)
961 {
962 /*
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.
967 */
968
969 symbolS *symbolP;
970
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;
975 if (symbolP)
976 {
977 right.X_seg = diff_section;
978 }
979 op_left = O_add;
980 }
981 \f
982 if (op_left == O_add)
983 {
984 segT seg1;
985 segT seg2;
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);
990
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);
992 #endif
993 #endif /* 0 */
994 clean_up_expression (&right);
995 clean_up_expression (resultP);
996
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)
1000 {
1001 need_pass_2 = 1;
1002 resultP->X_seg = pass1_section;
1003 }
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
1009 && seg1 != seg2)
1010 {
1011 know (seg2 != absolute_section);
1012 know (resultP->X_subtract_symbol);
1013 #ifndef MANY_SEGMENTS
1014 #ifndef OBJ_ECOFF
1015 know (seg1 == text_section || seg1 == data_section || seg1 == bss_section);
1016 know (seg2 == text_section || seg2 == data_section || seg2 == bss_section);
1017 #endif
1018 #endif
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. */
1026 }
1027 else
1028 resultP->X_seg = diff_section;
1029
1030 resultP->X_add_number += right.X_add_number;
1031 clean_up_expression (resultP);
1032 }
1033 else
1034 { /* Not +. */
1035 if (resultP->X_seg == undefined_section || right.X_seg == undefined_section)
1036 {
1037 resultP->X_seg = pass1_section;
1038 need_pass_2 = 1;
1039 }
1040 else
1041 {
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)
1046 {
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;
1051 }
1052 else
1053 {
1054 switch (op_left)
1055 {
1056 case O_bit_inclusive_or:
1057 resultP->X_add_number |= right.X_add_number;
1058 break;
1059
1060 case O_modulus:
1061 if (right.X_add_number)
1062 {
1063 resultP->X_add_number %= right.X_add_number;
1064 }
1065 else
1066 {
1067 as_warn ("Division by 0. Result of 0 substituted.");
1068 resultP->X_add_number = 0;
1069 }
1070 break;
1071
1072 case O_bit_and:
1073 resultP->X_add_number &= right.X_add_number;
1074 break;
1075
1076 case O_multiply:
1077 resultP->X_add_number *= right.X_add_number;
1078 break;
1079
1080 case O_divide:
1081 if (right.X_add_number)
1082 {
1083 resultP->X_add_number /= right.X_add_number;
1084 }
1085 else
1086 {
1087 as_warn ("Division by 0. 0 assumed.");
1088 resultP->X_add_number = 0;
1089 }
1090 break;
1091
1092 case O_left_shift:
1093 resultP->X_add_number <<= right.X_add_number;
1094 break;
1095
1096 case O_right_shift:
1097 /* @@ We should distinguish signed versus
1098 unsigned here somehow. */
1099 resultP->X_add_number >>= right.X_add_number;
1100 break;
1101
1102 case O_bit_exclusive_or:
1103 resultP->X_add_number ^= right.X_add_number;
1104 break;
1105
1106 case O_bit_or_not:
1107 resultP->X_add_number |= ~right.X_add_number;
1108 break;
1109
1110 default:
1111 BAD_CASE (op_left);
1112 break;
1113 } /* switch(operator) */
1114 }
1115 } /* If we have to force need_pass_2. */
1116 } /* If operator was +. */
1117 } /* If we didn't set need_pass_2. */
1118 op_left = op_right;
1119 } /* While next operator is >= this rank. */
1120 return (resultP->X_seg);
1121 }
1122 \f
1123 /*
1124 * get_symbol_end()
1125 *
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.
1129 *
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.
1137 */
1138 char
1139 get_symbol_end ()
1140 {
1141 char c;
1142
1143 while (is_part_of_name (c = *input_line_pointer++))
1144 ;
1145 *--input_line_pointer = 0;
1146 return (c);
1147 }
1148
1149
1150 unsigned int
1151 get_single_number ()
1152 {
1153 expressionS exp;
1154 operand (&exp);
1155 return exp.X_add_number;
1156
1157 }
1158
1159 /* end of expr.c */
This page took 0.05187 seconds and 4 git commands to generate.