|
|
1.1 root 1: /* expr.c -operands, expressions-
2: Copyright (C) 1987 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 1, 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: #include "stuff/round.h"
30: #include "as.h"
31: #include "flonum.h"
32: #include "struc-symbol.h"
33: #include "expr.h"
34: #include "read.h"
35: #include "obstack.h"
36: #include "symbols.h"
37: #include "hex_value.h"
38: #include "md.h"
39: #include "messages.h"
40: #include "sections.h"
41:
42: char *seg_name[] = {
43: "absolute",
44: "section",
45: "difference",
46: "unknown",
47: "absent",
48: "bignum/flonum",
49: };
50:
51: #ifdef SUSPECT
52: static int seg_N_TYPE[] = {
53: N_ABS, /* absolute */
54: N_SECT, /* section */
55: -1, /* difference */
56: N_UNDF, /* unknown */
57: -1, /* absent */
58: -1 /* bignum/flonum */
59: };
60: #endif
61:
62: segT N_TYPE_seg[] =
63: {
64: /* N_UNDF == 0, N_ABS == 2 */
65: SEG_UNKNOWN, -1, SEG_ABSOLUTE, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
66: /* N_SECT == 0xe */
67: SEG_SECT, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
68: };
69:
70: /*
71: * SEG_BIG expressions encode either a floating point number or an integer
72: * larger than 32 bits in this manner:
73: * For a floating point number:
74: * X_add_number is < 0
75: * The result is in the global variable generic_floating_point_number.
76: * The value in X_add_number is -'c' where c is the character that
77: * introduced the constant. e.g. "0f6.9" will have -'f' as a
78: * X_add_number value.
79: * For an integer larger than 32 bits:
80: * X_add_number > 0
81: * The result is in the global variable generic_bignum.
82: * The value in X_add_number is a count of how many littlenums it
83: * took to represent the bignum.
84: */
85:
86: /* LITTLENUM_TYPE generic_buffer [6]; JF this is a hack */
87: /* Seems atof_machine can backscan through generic_bignum and hit whatever
88: happens to be loaded before it in memory. And its way too complicated
89: for me to fix right. Thus a hack. JF: Just make generic_bignum bigger,
90: and never write into the early words, thus they'll always be zero.
91: I hate Dean's floating-point code. Bleh.
92: */
93: LITTLENUM_TYPE generic_bignum[SIZE_OF_LARGE_NUMBER + 6] = { 0 };
94:
95: FLONUM_TYPE generic_floating_point_number = {
96: &generic_bignum[6], /* low (JF: Was 0) */
97: &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1],/* high JF: (added +6) */
98: 0, /* leader */
99: 0, /* exponent */
100: 0 /* sign */
101: };
102:
103: /*
104: * The type operatorT is for the types of operators in expressions.
105: */
106: typedef enum {
107: O_illegal, /* (0) what we get for illegal op */
108:
109: O_multiply, /* (1) * Ordered by rank*/
110: O_divide, /* (2) / */
111: O_modulus, /* (3) % */
112:
113: O_add, /* (4) + */
114: O_subtract, /* (5) - */
115:
116: O_right_shift, /* (6) >> */
117: O_left_shift, /* (7) << */
118:
119: O_less_than, /* (8) < */
120: O_greater_than, /* (9) > */
121: O_less_than_or_equal, /* (10) <= */
122: O_greater_than_or_equal, /* (11) >= */
123:
124: O_equal, /* (12) == */
125: O_not_equal, /* (13) != */ /* or <> */
126:
127: O_bit_and, /* (14) & */
128:
129: O_bit_exclusive_or, /* (15) ^ */
130:
131: O_bit_inclusive_or, /* (16) | */
132: O_bit_or_not, /* (17) ! */
133: two_char_operator /* (18) encoding for two char operator */
134: } operatorT;
135:
136: /*
137: * op_size is indexed by an operatorT and tells the size of the operator
138: * which is used to advance the input_line_pointer over the operator.
139: */
140: static int op_size [] =
141: { 0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1 };
142:
143: /*
144: * op_rank is indexed by an operatorT and tells the rank of the operator.
145: *
146: * Rank Examples
147: * 8 * / %
148: * 7 + -
149: * 6 >> <<
150: * 5 < > <= >=
151: * 4 == !=
152: * 3 &
153: * 2 ^
154: * 1 | !
155: * 0 operand, (expression)
156: */
157: typedef char operator_rankT;
158: static operator_rankT op_rank [] =
159: { 0, 8, 8, 8, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 3, 2, 1, 1 };
160:
161: /*
162: * op_encoding is indexed by a an ASCII character and maps it to an operator.
163: */
164: #define __ O_illegal
165: static const operatorT op_encoding [256] = {
166: __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
167: __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
168:
169: __, two_char_operator, __, __, __, O_modulus, O_bit_and, __,
170: __, __, O_multiply, O_add, __, O_subtract, __, O_divide,
171: __, __, __, __, __, __, __, __,
172: __, __, __, __, two_char_operator, two_char_operator, two_char_operator, __,
173: __, __, __, __, __, __, __, __,
174: __, __, __, __, __, __, __, __,
175: __, __, __, __, __, __, __, __,
176: __, __, __, __, __, __, O_bit_exclusive_or, __,
177: __, __, __, __, __, __, __, __,
178: __, __, __, __, __, __, __, __,
179: __, __, __, __, __, __, __, __,
180: __, __, __, __, O_bit_inclusive_or, __, __, __,
181:
182: __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
183: __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
184: __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
185: __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
186: __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
187: __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
188: __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
189: __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
190: };
191:
192: static segT expr(
193: operator_rankT rank,
194: expressionS *resultP);
195:
196: static segT operand(
197: expressionS *expressionP);
198:
199: static void clean_up_expression(
200: expressionS *expressionP);
201:
202: static segT expr_part(
203: struct symbol **symbol_1_PP,
204: struct symbol *symbol_2_P);
205:
206: static operatorT two_char_op_encoding(
207: char first_op_char);
208:
209: segT /* Return resultP -> X_seg */
210: expression(
211: expressionS *resultP) /* deliver result here */
212: {
213: segT segment;
214:
215: segment = expr(0, resultP);
216:
217: /* what about caller's that just want to ignore this and print the're own
218: error message? ok I guess */
219: if(segment == SEG_DIFFSECT &&
220: resultP->X_add_symbol == NULL &&
221: (resultP->X_subtract_symbol->sy_type & N_TYPE) != N_UNDF){
222: as_warn("Subtracting symbol \"%s\"(segment\"%s\") is too "
223: "hard. Absolute segment assumed.",
224: resultP->X_subtract_symbol->sy_name,
225: seg_name[(int)N_TYPE_seg[
226: resultP->X_subtract_symbol->sy_type & N_TYPE]]);
227: segment = SEG_ABSOLUTE;
228: /* Leave exp .X_add_number alone. */
229: }
230: return(segment);
231: }
232:
233: /* Expression parser. */
234:
235: /*
236: * We allow an empty expression, and just assume (absolute,0) silently.
237: * Unary operators and parenthetical expressions are treated as operands.
238: * As usual, Q==quantity==operand, O==operator, X==expression mnemonics.
239: *
240: * Most expressions are either register (which does not even reach here)
241: * or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common.
242: *
243: * After expr(RANK,resultP) input_line_pointer -> operator of rank <= RANK.
244: * Also, we have consumed any leading or trailing spaces (operand does that)
245: * and done all intervening operators.
246: */
247: static
248: segT /* Return resultP -> X_seg */
249: expr(
250: operator_rankT rank, /* larger # is higher rank */
251: expressionS *resultP) /* deliver result here */
252: {
253: expressionS right;
254: operatorT op_left;
255: char c_left; /* 1st operator character. */
256: operatorT op_right;
257: char c_right;
258:
259: know(rank >= 0);
260:
261: (void)operand(resultP);
262: know(*input_line_pointer != ' '); /* Operand() gobbles spaces. */
263:
264: c_left = *input_line_pointer; /* Potential operator character. */
265: op_left = (operatorT)op_encoding[(int)c_left];
266: if(op_left == two_char_operator)
267: op_left = two_char_op_encoding(c_left);
268:
269: while(op_left != O_illegal && op_rank[op_left] > rank){
270:
271: input_line_pointer += op_size[op_left];
272: /* -> after 1st character of operator. */
273:
274: if(SEG_NONE == expr(op_rank[op_left], &right)){
275: as_warn("Missing operand value assumed absolute 0.");
276: resultP->X_add_number = 0;
277: resultP->X_subtract_symbol = NULL;
278: resultP->X_add_symbol = NULL;
279: resultP->X_seg = SEG_ABSOLUTE;
280: }
281: know(*input_line_pointer != ' ');
282:
283: c_right = *input_line_pointer;
284: op_right = (operatorT)op_encoding[(int)c_right];
285: if(op_right == two_char_operator)
286: op_right = two_char_op_encoding(c_right);
287:
288: /* -> after 1st character of operator. */
289: know(op_right == 0 || op_rank [op_right] <= op_rank[op_left]);
290:
291: /* input_line_pointer -> after right-hand quantity. */
292: /* left-hand quantity in resultP */
293: /* right-hand quantity in right. */
294: /* operator in op_left. */
295:
296: /*
297: * Operations are not supported on bignums or floating-point
298: * operands.
299: */
300: if(resultP->X_seg == SEG_BIG){
301: as_warn("Left operand of %c is a %s integer 0 assumed",
302: c_left, resultP->X_add_number > 0 ? "bignum" :
303: "float");
304: resultP->X_seg = SEG_ABSOLUTE;
305: resultP->X_add_symbol = 0;
306: resultP->X_subtract_symbol = 0;
307: resultP->X_add_number = 0;
308: }
309: if(right.X_seg == SEG_BIG){
310: as_warn("Right operand of %c is a %s integer 0 assumed",
311: c_left, right.X_add_number > 0 ? "bignum" :
312: "float");
313: right.X_seg = SEG_ABSOLUTE;
314: right.X_add_symbol = 0;
315: right.X_subtract_symbol = 0;
316: right.X_add_number = 0;
317: }
318: if(op_left == O_subtract){
319: /*
320: * Convert - into + by exchanging symbols and negating
321: * number. I know -infinity can't be negated in 2's
322: * complement: but then it can't be subtracted either.
323: * This trick does not cause any further inaccuracy.
324: */
325: struct symbol *symbolP;
326:
327: right.X_add_number = - right.X_add_number;
328: symbolP = right.X_add_symbol;
329: right.X_add_symbol = right.X_subtract_symbol;
330: right.X_subtract_symbol = symbolP;
331: if(symbolP){
332: /* This is not used, as it drops in to the next if */
333: right.X_seg = SEG_DIFFSECT;
334: }
335: op_left = O_add;
336: }
337: if(op_left == O_add){
338: segT seg1;
339: segT seg2;
340:
341: /* not SEG_NONE and not SEG_BIG */
342: know(resultP->X_seg == SEG_SECT ||
343: resultP->X_seg == SEG_UNKNOWN ||
344: resultP->X_seg == SEG_DIFFSECT ||
345: resultP->X_seg == SEG_ABSOLUTE);
346: /* not SEG_NONE and not SEG_BIG */
347: know(right.X_seg == SEG_SECT ||
348: right.X_seg == SEG_UNKNOWN ||
349: right.X_seg == SEG_DIFFSECT ||
350: right.X_seg == SEG_ABSOLUTE);
351:
352: clean_up_expression(&right);
353: clean_up_expression(resultP);
354:
355: /* could this just return -1 instead of SEG_PASS1? and tested in the below if
356: statement */
357: seg1 = expr_part(&resultP->X_add_symbol,
358: right.X_add_symbol);
359: seg2 = expr_part(&resultP->X_subtract_symbol,
360: right.X_subtract_symbol);
361: if(seg1 == -1 || seg2 == -1){
362: as_warn("Can't relocate expression. Absolute 0 assumed.");
363: resultP->X_seg = SEG_ABSOLUTE;
364: resultP->X_add_number = 0;
365: }
366: else{
367: if(seg2 == SEG_ABSOLUTE){
368: resultP->X_seg = seg1;
369: }
370: else{
371: /* also know seg2 != -1 (SEG_PASS1) */
372: know(seg2 != SEG_ABSOLUTE);
373: /* seg2 is for the subtract symbols, since seg2 != SEG_ABSOLUTE as would be
374: returned when there is no subtract symbols then expr_part() must have
375: combined a symbol into resultP->X_subtract_symbol that is either undefined
376: or defined in a section. */
377: know(resultP->X_subtract_symbol);
378: /*
379: * If we are not to use the new incompatible features
380: * then "symbol1 - symbol2" must both be in the same
381: * section and will turn out as absolute.
382: */
383: if(!flagseen['k']){
384: if(seg1 != SEG_UNKNOWN &&
385: seg1 != SEG_ABSOLUTE &&
386: seg2 != SEG_UNKNOWN &&
387: seg1 != seg2 &&
388: resultP->X_add_symbol->sy_other !=
389: resultP->X_subtract_symbol->sy_other){
390: know(seg1 == SEG_SECT);
391: know(seg2 == SEG_SECT);
392: know(resultP->X_add_symbol);
393: know(resultP->X_subtract_symbol);
394: as_warn("Expression too complex: "
395: "forgetting %s - %s",
396: resultP->X_add_symbol->sy_name,
397: resultP->X_subtract_symbol->sy_name);
398: resultP->X_seg = SEG_ABSOLUTE;
399: /* Clean_up_expression() will do the rest */
400: }
401: else{
402: /* this can result in returning an expression that is NULL - symbol and the
403: caller must deal with this being illegal. maybe this should be put in
404: expression() routine (not a macro). Note the code in cons() */
405: resultP->X_seg = SEG_DIFFSECT;
406: } /* If relocation too complex. */
407: }
408: else{
409: resultP->X_seg = SEG_DIFFSECT;
410: }
411:
412: } /* If seg2 == SEG_ABSOLUTE. */
413: } /* If need pass 2. */
414: resultP->X_add_number += right.X_add_number;
415: clean_up_expression(resultP);
416: }
417: else{ /* Not +. */
418: if(resultP->X_seg == SEG_UNKNOWN ||
419: right.X_seg == SEG_UNKNOWN){
420: as_warn("Can't relocate expression. Absolute 0 assumed.");
421: resultP->X_seg = SEG_ABSOLUTE;
422: resultP->X_add_number = 0;
423: }
424: else{
425: /*
426: * Will be SEG_ABSOLUTE. (or error)
427: */
428: try_to_make_absolute(resultP);
429: try_to_make_absolute(&right);
430: resultP->X_subtract_symbol = NULL;
431: resultP->X_add_symbol = NULL;
432: if(resultP->X_seg != SEG_ABSOLUTE ||
433: right.X_seg != SEG_ABSOLUTE){
434: as_warn("Relocation error. Absolute 0 assumed");
435: resultP->X_seg = SEG_ABSOLUTE;
436: resultP->X_add_number = 0;
437: }
438: else{
439: /*
440: * Both are absolute so perform the operation
441: * on the constants.
442: */
443: switch(op_left){
444: case O_bit_inclusive_or:
445: resultP->X_add_number |= right.X_add_number;
446: break;
447:
448: case O_modulus:
449: if(right.X_add_number){
450: resultP->X_add_number %=
451: right.X_add_number;
452: }
453: else{
454: as_warn("Division by 0. 0 assumed.");
455: resultP->X_add_number = 0;
456: }
457: break;
458:
459: case O_bit_and:
460: resultP->X_add_number &= right.X_add_number;
461: break;
462:
463: case O_multiply:
464: resultP->X_add_number *= right.X_add_number;
465: break;
466:
467: case O_divide:
468: if(right.X_add_number){
469: resultP->X_add_number /=
470: right.X_add_number;
471: }
472: else{
473: as_warn("Division by 0. 0 assumed.");
474: resultP->X_add_number = 0;
475: }
476: break;
477:
478: case O_left_shift:
479: resultP->X_add_number <<=
480: right.X_add_number;
481: break;
482:
483: case O_right_shift:
484: resultP->X_add_number >>=
485: right.X_add_number;
486: break;
487:
488: case O_bit_exclusive_or:
489: resultP->X_add_number ^= right.X_add_number;
490: break;
491:
492: case O_bit_or_not:
493: resultP->X_add_number |=
494: ~right.X_add_number;
495: break;
496:
497: case O_less_than:
498: resultP->X_add_number =
499: (resultP->X_add_number <
500: right.X_add_number);
501: break;
502:
503: case O_greater_than:
504: resultP->X_add_number =
505: (resultP->X_add_number >
506: right.X_add_number);
507: break;
508:
509: case O_less_than_or_equal:
510: resultP->X_add_number =
511: (resultP->X_add_number <=
512: right.X_add_number);
513: break;
514:
515: case O_greater_than_or_equal:
516: resultP->X_add_number =
517: (resultP->X_add_number >=
518: right.X_add_number);
519: break;
520:
521: case O_equal:
522: resultP->X_add_number =
523: (resultP->X_add_number ==
524: right.X_add_number);
525: break;
526:
527: case O_not_equal:
528: resultP->X_add_number =
529: (resultP->X_add_number !=
530: right.X_add_number);
531: break;
532:
533: default:
534: BAD_CASE( op_left );
535: break;
536: } /* switch(op_left) */
537: }
538: } /* If we have to force need_pass_2 */
539: } /* If operator was + */
540: op_left = op_right;
541: } /* While next operator is >= this rank */
542: return(resultP->X_seg);
543: }
544:
545: /*
546: * Summary of operand().
547: *
548: * in: Input_line_pointer points to 1st char of operand, which may
549: * be a space.
550: *
551: * out: A expressionS. X_seg determines how to understand the rest of the
552: * expressionS.
553: * The operand may have been empty: in this case X_seg == SEG_NONE.
554: * Input_line_pointer -> (next non-blank) char after operand.
555: *
556: */
557: static
558: segT
559: operand(
560: expressionS *expressionP)
561: {
562: char c, q;
563: char *name; /* points to name of symbol */
564: struct symbol *symbolP; /* Points to symbol */
565:
566:
567: SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */
568: c = *input_line_pointer++;/* Input_line_pointer -> past char in c. */
569:
570: if(isdigit(c)){
571: valueT number; /* offset or (absolute) value */
572: int digit; /* value of next digit in current radix */
573: /* invented for humans only, hope */
574: /* optimising compiler flushes it! */
575: int radix; /* 8, 10 or 16 */
576: /* 0 means we saw start of a floating- */
577: /* point constant. */
578: int maxdig; /* Highest permitted digit value. */
579: int too_many_digits;/* If we see >= this number of */
580: /* digits, assume it is a bignum. */
581: char *digit_2; /* -> 2nd digit of number. */
582: int small; /* TRUE if fits in 32 bits. */
583: int force_bignum; /* TRUE if number is 0xb... */
584:
585: force_bignum = FALSE;
586: /*
587: * These two initiaizations are to shut up compiler warning as the
588: * may be used with out being set. There used only if radix != 0
589: * when the number is not a floating-point number.
590: */
591: maxdig = 0;
592: too_many_digits = 0;
593:
594: if(c == '0'){ /* non-decimal radix */
595: c = *input_line_pointer++;
596: if(c == 'x' || c=='X'){
597: c = *input_line_pointer++; /* read past "0x" or "0X" */
598: maxdig = 16;
599: radix = 16;
600: too_many_digits = 9;
601: }
602: /*
603: * If we have "0b" and some hex digits then treat it as a hex
604: * number and return a bignum. This is for hex immediate
605: * bit-patterns for floating-point immediate constants.
606: */
607: else if((c == 'b' || c == 'B') &&
608: (*input_line_pointer != '\0') &&
609: strchr("0123456789abcdefABCDEF",
610: *input_line_pointer) != NULL){
611: force_bignum = TRUE;
612: c = *input_line_pointer++; /* read past "0b" or "0B" */
613: maxdig = 16;
614: radix = 16;
615: too_many_digits = 9;
616: }
617: else{
618: /*
619: * If it says '0f' and the line ends or it DOESN'T look like
620: * a floating point #, its a local label ref.
621: */
622: if(c == 'f' &&
623: (*input_line_pointer == '\0' ||
624: (strchr("+-.0123456789", *input_line_pointer) == NULL &&
625: strchr(md_EXP_CHARS, *input_line_pointer) == NULL) )){
626: maxdig = 10;
627: radix = 10;
628: too_many_digits = 11;
629: c = '0';
630: input_line_pointer -= 2;
631: }
632: else if(c != '\0' && strchr(md_FLT_CHARS, c) != NULL){
633: radix = 0;/* Start of floating-point constant. */
634: /* input_line_pointer -> 1st char of number */
635: expressionP->X_add_number =
636: - (isupper(c) ? tolower(c) : c);
637: }
638: else{ /* By elimination, assume octal radix. */
639: radix = 8;
640: maxdig = 10; /* Un*x sux. Compatibility. */
641: too_many_digits = 11;
642: }
643: }
644: /* c == char after "0" or "0x" or "0X" or "0e" etc.*/
645: }
646: else{
647: maxdig = 10;
648: radix = 10;
649: too_many_digits = 11;
650: }
651: if(radix != 0){ /* Fixed-point integer constant. */
652: /* May be bignum, or may fit in 32 bits. */
653: /*
654: * Most numbers fit into 32 bits, and we want this case to be
655: * fast. So we pretend it will fit into 32 bits. If, after
656: * making up a 32 bit number, we realize that we have scanned
657: * more digits than comfortably fit into 32 bits, we re-scan the
658: * digits coding them into a bignum. For decimal and octal
659: * numbers we are conservative: some numbers may be assumed
660: * bignums when in fact they do fit into 32 bits. Numbers of
661: * any radix can have excess leading zeros: we strive to
662: * recognise this and cast them back into 32 bits. We must
663: * check that the bignum really is more than 32 bits, and
664: * change it back to a 32-bit number if it fits. The number we
665: * are looking for is expected to be positive, but if it fits
666: * into 32 bits as an unsigned number, we let it be a 32-bit
667: * number. The cavalier approach is for speed in ordinary cases.
668: */
669: digit_2 = input_line_pointer;
670: for(number = 0;
671: (digit = hex_value[(int)c]) < maxdig;
672: c = *input_line_pointer++){
673: number = number * radix + digit;
674: }
675: /* c contains character after number. */
676: /* Input_line_pointer -> char after c. */
677: small = input_line_pointer - digit_2 < too_many_digits;
678: if(force_bignum == TRUE)
679: small = FALSE;
680: if(small == FALSE){
681: /*
682: * Manufacture a bignum.
683: */
684: /* -> high order littlenum of the bignum. */
685: LITTLENUM_TYPE *leader;
686: /* -> littlenum we are frobbing now. */
687: LITTLENUM_TYPE *pointer;
688: long carry;
689:
690: leader = generic_bignum;
691: generic_bignum [0] = 0;
692: /* We could just use digit_2, but lets be mnemonic. */
693: input_line_pointer = --digit_2; /* -> 1st digit. */
694: c = *input_line_pointer++;
695: for( ;
696: (carry = hex_value[(int)c]) < maxdig;
697: c = * input_line_pointer++){
698: for(pointer = generic_bignum;
699: pointer <= leader;
700: pointer++){
701: long work;
702:
703: work = carry + radix * *pointer;
704: *pointer = work & LITTLENUM_MASK;
705: carry = work >> LITTLENUM_NUMBER_OF_BITS;
706: }
707: if(carry){
708: if(leader < generic_bignum +
709: SIZE_OF_LARGE_NUMBER - 1){
710: /* Room to grow a longer bignum. */
711: *++leader = carry;
712: }
713: }
714: }
715: /* Again, C is char after number, */
716: /* input_line_pointer -> after C. */
717: /* know(BITS_PER_INT == 32); */
718: know(LITTLENUM_NUMBER_OF_BITS == 16);
719: /* Hence the constant "2" in the next line. */
720: if(leader < generic_bignum + 2 && force_bignum == FALSE)
721: { /* Will fit into 32 bits. */
722: number = ((generic_bignum[1] & LITTLENUM_MASK) <<
723: LITTLENUM_NUMBER_OF_BITS) |
724: (generic_bignum[0] & LITTLENUM_MASK);
725: small = TRUE;
726: }
727: else{
728: /* Number of littlenums in the bignum. */
729: number = leader - generic_bignum + 1;
730: }
731: }
732: if(small){
733: /*
734: * Here with number, in correct radix. c is the next char.
735: * Note that unlike Un*x, we allow "011f" "0x9f" to both
736: * mean the same as the (conventional) "9f". This is simply
737: * easier than checking for strict canonical form.
738: */
739: if(number < 10){
740: if(c == 'b'){
741: /*
742: * Backward ref to local label.
743: * Because it is backward, expect it to be DEFINED.
744: */
745: /*
746: * Construct a local label.
747: */
748: name = local_label_name((int)number, 0);
749: symbolP = symbol_table_lookup(name);
750: if((symbolP != NULL) &&
751: (symbolP->sy_type & N_TYPE) != N_UNDF){
752: /* Expected path: symbol defined. */
753: /* Local labels are never absolute. Don't waste
754: time checking absoluteness. */
755: know((symbolP->sy_type & N_TYPE) == N_SECT);
756: expressionP->X_add_symbol = symbolP;
757: expressionP->X_add_number = 0;
758: expressionP->X_seg = SEG_SECT;
759: }
760: else{ /* Either not seen or not defined. */
761: as_warn("Backw. ref to unknown label \"%d:\", 0"
762: " assumed.", number);
763: expressionP->X_add_number = 0;
764: expressionP->X_seg = SEG_ABSOLUTE;
765: }
766: }
767: else if(c == 'f'){
768: /*
769: * Forward reference. Expect symbol to be
770: * undefined or unknown. Undefined: seen it
771: * before. Unknown: never seen it in this pass.
772: * Construct a local label name, then an
773: * undefined symbol. Don't create a XSEG frag
774: * for it: caller may do that.
775: * Just return it as never seen before.
776: */
777: name = local_label_name((int)number, 1);
778: symbolP = symbol_table_lookup(name);
779: if(symbolP != NULL){
780: /* We have no need to check symbol
781: properties. */
782: know((symbolP->sy_type & N_TYPE) == N_UNDF ||
783: (symbolP->sy_type & N_TYPE) == N_SECT);
784: }
785: else{
786: symbolP = symbol_new(name, N_UNDF, 0,0,0,
787: &zero_address_frag);
788: symbol_table_insert(symbolP);
789: }
790: expressionP->X_add_symbol = symbolP;
791: expressionP->X_seg = SEG_UNKNOWN;
792: expressionP->X_subtract_symbol = NULL;
793: expressionP->X_add_number = 0;
794: }
795: else{ /* Really a number, not a local label. */
796: expressionP->X_add_number = number;
797: expressionP->X_seg = SEG_ABSOLUTE;
798: input_line_pointer--; /* restore following char */
799: }
800: }
801: else{ /* a number >= 10 */
802: expressionP->X_add_number = number;
803: expressionP->X_seg = SEG_ABSOLUTE;
804: input_line_pointer--; /* restore following char */
805: }
806: } /* not a small number encode returning a bignum */
807: else{
808: expressionP->X_add_number = number;
809: expressionP->X_seg = SEG_BIG;
810: input_line_pointer--; /* -> char following number. */
811: } /* if (small) */
812: } /* (If integer constant) */
813: else{ /* input_line_pointer -> floating-point constant. */
814:
815: int error_code;
816:
817: error_code = atof_generic(&input_line_pointer, ".", md_EXP_CHARS,
818: &generic_floating_point_number);
819:
820: if(error_code){
821: if(error_code == ERROR_EXPONENT_OVERFLOW){
822: as_warn("Bad floating-point constant: exponent "
823: "overflow, probably assembling junk" );
824: }
825: else{
826: as_warn("Bad floating-point constant: unknown error "
827: "code=%d.", error_code);
828: }
829: }
830: expressionP->X_seg = SEG_BIG;
831: /* input_line_pointer -> just after constant, */
832: /* which may point to whitespace. */
833: know(expressionP->X_add_number < 0);
834: /* < 0 means "floating point". */
835: } /* if (not floating-point constant) */
836: }
837: else if(c == '.' && !is_part_of_name(*input_line_pointer)){
838: /*
839: JF: '.' is pseudo symbol with value of current location in current
840: segment. . .
841: */
842: symbolP = symbol_new("L0\001",
843: N_SECT,
844: frchain_now->frch_nsect,
845: 0,
846: (valueT)(obstack_next_free(&frags) -
847: frag_now->fr_literal),
848: frag_now);
849: expressionP->X_add_number = 0;
850: expressionP->X_add_symbol = symbolP;
851: expressionP->X_seg = SEG_SECT;
852: }
853: /* here if did not begin with a digit */
854: else if(is_name_beginner(c) || c == '"'){
855: /*
856: * Identifier begins here.
857: * This is kludged for speed, so code is repeated.
858: */
859: q = c;
860: if(q == '"')
861: name = input_line_pointer-- ;
862: else
863: name = -- input_line_pointer;
864: c = get_symbol_end();
865: symbolP = symbol_table_lookup(name);
866: if(symbolP != NULL){
867: /*
868: * If we have an absolute symbol, then we know it's value now.
869: */
870: segT seg;
871:
872: seg = N_TYPE_seg[(int)symbolP->sy_type & N_TYPE];
873: expressionP->X_seg = seg;
874: if(seg == SEG_ABSOLUTE){
875: expressionP->X_add_number = symbolP->sy_value;
876: }
877: else{
878: expressionP->X_add_number = 0;
879: expressionP->X_add_symbol = symbolP;
880: }
881: }
882: else{
883: symbolP = symbol_new(name, N_UNDF, 0,0,0, &zero_address_frag);
884: expressionP->X_add_symbol = symbolP;
885: expressionP->X_add_number = 0;
886: expressionP->X_seg = SEG_UNKNOWN;
887: symbol_table_insert(symbolP);
888: }
889: *input_line_pointer = c;
890: if(q == '"')
891: input_line_pointer[-1] = '"';
892: expressionP->X_subtract_symbol = NULL;
893: }
894: /* didn't begin with digit & not a name */
895: else if (c == '('){
896: (void)expression(expressionP);
897: /* Expression() will pass trailing whitespace */
898: if(*input_line_pointer++ != ')'){
899: as_warn("Missing ')' assumed");
900: input_line_pointer--;
901: }
902: /* here with input_line_pointer -> char after "(...)" */
903: }
904: /* unary operator: hope for SEG_ABSOLUTE */
905: else if(c == '~' || c == '-' || c == '!'){
906: switch(operand(expressionP)){
907: case SEG_ABSOLUTE:
908: /* input_line_pointer -> char after operand */
909: if(c == '-' ){
910: /*
911: * Notice: '-' may overflow: no warning is given. This is
912: * compatible with other people's assemblers.
913: */
914: expressionP->X_add_number = - expressionP->X_add_number;
915: }
916: else if(c == '!'){
917: expressionP->X_add_number = ! expressionP->X_add_number;
918: }
919: else{
920: expressionP->X_add_number = ~ expressionP->X_add_number;
921: }
922: break;
923: case SEG_SECT:
924: case SEG_UNKNOWN:
925: if(c == '-'){ /* JF I hope this hack works */
926: expressionP->X_subtract_symbol = expressionP->X_add_symbol;
927: expressionP->X_add_symbol = 0;
928: expressionP->X_seg = SEG_DIFFSECT;
929: break;
930: }
931: default: /* unary on non-absolute is unsuported */
932: as_warn("Unary operator %c ignored because bad operand follows",
933: c);
934: break;
935: /* Expression undisturbed from operand(). */
936: }
937: }
938: /*
939: * Warning: to conform to other people's assemblers NO ESCAPEMENT is
940: * permitted for a single quote. The next character, parity errors and
941: * all, is taken as the value of the operand. VERY KINKY.
942: */
943: else if(c == '\''){
944: expressionP->X_add_number = *input_line_pointer++;
945: expressionP->X_seg = SEG_ABSOLUTE;
946: }
947: /* can't imagine any other kind of operand */
948: else{
949: expressionP->X_seg = SEG_NONE;
950: input_line_pointer--;
951: }
952: /*
953: * It is more 'efficient' to clean up the expressions when they are
954: * created. Doing it here saves lines of code.
955: */
956: clean_up_expression(expressionP);
957: SKIP_WHITESPACE(); /* -> 1st char after operand. */
958: know(*input_line_pointer != ' ');
959: return(expressionP->X_seg);
960: }
961:
962: /* Internal. Simplify a struct expression for use by expr() */
963:
964: /*
965: * In: address of a expressionS.
966: * The X_seg field of the expressionS may only take certain values.
967: * Now, we permit SEG_NONE to make code smaller & faster.
968: * Elsewise we waste time special-case testing. Sigh.
969: * Out: expressionS may have been modified:
970: * 'foo-foo' symbol references cancelled to 0,
971: * which changes X_seg from SEG_DIFFSECT to SEG_ABSOLUTE;
972: * Unused fields zeroed to help expr().
973: */
974: static
975: void
976: clean_up_expression(
977: expressionS *expressionP)
978: {
979: switch(expressionP->X_seg){
980: case SEG_NONE:
981: expressionP->X_add_symbol = NULL;
982: expressionP->X_subtract_symbol = NULL;
983: expressionP->X_add_number = 0;
984: break;
985:
986: case SEG_BIG:
987: case SEG_ABSOLUTE:
988: expressionP->X_subtract_symbol = NULL;
989: expressionP->X_add_symbol = NULL;
990: break;
991:
992: case SEG_SECT:
993: case SEG_UNKNOWN:
994: expressionP->X_subtract_symbol = NULL;
995: break;
996:
997: case SEG_DIFFSECT:
998: /*
999: * It does not hurt to 'cancel' NULL==NULL
1000: * when comparing symbols for 'eq'ness.
1001: * It is faster to re-cancel them to NULL
1002: * than to check for this special case.
1003: */
1004: if(expressionP->X_subtract_symbol == expressionP->X_add_symbol){
1005: expressionP->X_subtract_symbol = NULL;
1006: expressionP->X_add_symbol = NULL;
1007: expressionP->X_seg = SEG_ABSOLUTE;
1008: }
1009: break;
1010:
1011: default:
1012: BAD_CASE(expressionP->X_seg);
1013: break;
1014: }
1015: }
1016:
1017: /*
1018: * expr_part ()
1019: *
1020: * Internal. Made a function because this code is used in 2 places.
1021: * Generate error or correct X_?????_symbol of expressionS.
1022: */
1023:
1024: /*
1025: Combine and subsume symbol2 into symbol1 where the symbols come from
1026: expression's add or subtract symbols.
1027: The combining always occurs even if it would be an error.
1028: Either symbol maybe NULL which means there is no symbol.
1029: In that case symbol1 is set to the non NULL symbol.
1030: If both are NULL then SEG_ABSOLUTE is returned.
1031: Either symbol maybe undefined.
1032: The only combinations that are not errors are when one symbol does not exist.
1033: if one symbol is undefined and the other doesn't exist SEG_UNKNOWN is
1034: returned.
1035: For errant combinations symbol1 is set to NULL and SEG_ABSOLUTE (or -1
1036: (SEG_PASS1) when one of the symbols is undefined and the other exists)
1037:
1038: * symbol_1 += symbol_2 ... well ... sort of.
1039: * symbol_1 -= symbol_2 ... well ... sort of.
1040: */
1041:
1042: static
1043: segT
1044: expr_part(
1045: struct symbol **symbol_1_PP,
1046: struct symbol *symbol_2_P)
1047: {
1048: segT return_value;
1049:
1050: /* The symbols can't be N_ABS as they are in expressions and whould just have
1051: their value copied into the X_add_number part. */
1052: know( (*symbol_1_PP) == NULL ||
1053: ((*symbol_1_PP)->sy_type & N_TYPE) == N_SECT ||
1054: ((*symbol_1_PP)->sy_type & N_TYPE) == N_UNDF);
1055:
1056: know( symbol_2_P == NULL ||
1057: (symbol_2_P->sy_type & N_TYPE) == N_SECT ||
1058: (symbol_2_P->sy_type & N_TYPE) == N_UNDF);
1059:
1060: /* check to see if there is a symbol1 */
1061: if(*symbol_1_PP != NULL){
1062: /* there is a symbol1 */
1063:
1064: /* check to see if symbol1 is undefined */
1065: if(((*symbol_1_PP)->sy_type & N_TYPE) == N_UNDF){
1066: /* symbol1 is undefined */
1067:
1068: /* check to see if there is a symbol2 */
1069: if(symbol_2_P != NULL){
1070: /* symbol1 is undefined and there is a symbol2 */
1071: *symbol_1_PP = NULL;
1072: return_value = -1;
1073: }
1074: else{
1075: /* symbol1 is undefined and there is no symbol2 */
1076: return_value = SEG_UNKNOWN;
1077: }
1078: }
1079: else{
1080: /* there is a defined symbol1 */
1081:
1082: /* check to see if there is a symbol2 */
1083: if(symbol_2_P != NULL){
1084: /* there is a symbol2 */
1085:
1086: /* check to see if symbol2 is undefined */
1087: if((symbol_2_P->sy_type & N_TYPE) == N_UNDF){
1088: /* symbol2 is undefined and symbol1 is defined */
1089: *symbol_1_PP = NULL;
1090: return_value = -1;
1091: }
1092: else{
1093: /* symbol1 is defined and symbol2 is defined */
1094: /* + {symbol1} + {symbol2} or */
1095: /* - {symbol1} - {symbol2} */
1096: as_warn("Expression too complex, 2 symbols forgotten: "
1097: "\"%s\" \"%s\"", (*symbol_1_PP)->sy_name,
1098: symbol_2_P->sy_name);
1099: *symbol_1_PP = NULL;
1100: return_value = SEG_ABSOLUTE;
1101: }
1102: }
1103: else{
1104: /* symbol1 is defined and there is no symbol2 */
1105: return_value = N_TYPE_seg[(*symbol_1_PP)->sy_type & N_TYPE];
1106: }
1107: }
1108: }
1109: else{
1110: /* there is no symbol1 */
1111:
1112: /* check to see if there is a symbol2 */
1113: if(symbol_2_P != NULL){
1114: /* symbol2 is defined and there is no symbol1 */
1115: *symbol_1_PP = symbol_2_P;
1116: return_value = N_TYPE_seg[(symbol_2_P)->sy_type & N_TYPE];
1117: }
1118: else{
1119: /* there is no symbol1 or symbol2 */
1120: /* ??? why not SEG_UNKNOWN or SEG_NONE */
1121: return_value = SEG_ABSOLUTE;
1122: }
1123: }
1124:
1125: know(return_value == SEG_ABSOLUTE ||
1126: return_value == SEG_SECT ||
1127: return_value == SEG_UNKNOWN ||
1128: return_value == -1);
1129: know((*symbol_1_PP) == NULL ||
1130: ((*symbol_1_PP)->sy_type & N_TYPE) ==
1131: seg_N_TYPE[(int)return_value]);
1132:
1133: return(return_value);
1134: }
1135:
1136: /*
1137: * DJA -- Here we make a last ditch effort to turn expressions into
1138: * absolutes. This is particularly useful for doing arithemtic
1139: * on already declared labels, for example in going through the
1140: * following table the moveq can really be evaluated.
1141: *
1142: * start: .word 1
1143: * .word 2
1144: * .word 3
1145: * end:
1146: * lea start,a0
1147: * moveq #((end-start) / 2) + 1,d0
1148: * loop: cmpw d1,a0@+
1149: * dbra d0,loop
1150: */
1151: segT /* Return expressionP->X_seg. */
1152: try_to_make_absolute(
1153: expressionS *expressionP) /* Deliver result here. */
1154: {
1155: symbolS *add_symbol;
1156: symbolS *subtract_symbol;
1157:
1158: if(expressionP->X_seg == SEG_DIFFSECT){
1159:
1160: add_symbol = expressionP->X_add_symbol;
1161: if(add_symbol == NULL)
1162: goto giveup;
1163: if((add_symbol->sy_type & N_TYPE) != N_SECT)
1164: goto giveup;
1165:
1166: subtract_symbol = expressionP->X_subtract_symbol;
1167: if(subtract_symbol == NULL)
1168: goto giveup;
1169: if((subtract_symbol->sy_type & N_TYPE) != N_SECT)
1170: goto giveup;
1171:
1172: if(add_symbol->sy_frag == subtract_symbol->sy_frag){
1173: if(add_symbol->sy_frag != NULL &&
1174: expressionP->X_add_number +
1175: (int)add_symbol->sy_value -
1176: (int)subtract_symbol->sy_value >= 0){
1177: expressionP->X_add_number += add_symbol->sy_value -
1178: subtract_symbol->sy_value;
1179: expressionP->X_seg = SEG_ABSOLUTE;
1180: expressionP->X_add_symbol = NULL;
1181: expressionP->X_subtract_symbol = NULL;
1182:
1183: }
1184: }
1185: else{
1186: /*
1187: * This logic works only if the chain of frags can't later be
1188: * separated by scattered loading. To make sure that this can't
1189: * happen we would have to make sure all symbols associated with
1190: * frags in the chain are of the Lx form and the -L flag is not
1191: * see so they will not appear in the output (if they are not in
1192: * the output then the link editor can't separate the chain of
1193: * frags by scattered loading). Since this code does not make
1194: * sure of this it is broken. But this is a known bug in the
1195: * NeXT 3.2 and earilier releases so this code is if'ed
1196: * !flagseen['k'] which will make it compatable with 3.2 and
1197: * previous releases.
1198: */
1199: if(!flagseen['k']){
1200: /*
1201: * Try to see if the chain of frags between the subtract
1202: * symbol and the add symbol is made up of only rs_fill and
1203: * rs_align frags and then calculate the difference. This
1204: * will always work on RISC machines since they won't have
1205: * any machine dependent frags of variable length in the
1206: * chain.
1207: */
1208: unsigned long size, fail;
1209: struct frag *frag;
1210:
1211: if(add_symbol->sy_frag != NULL &&
1212: subtract_symbol->sy_frag != NULL){
1213: fail = 0;
1214: size = 0;
1215: frag = subtract_symbol->sy_frag;
1216: while(!fail && frag != NULL &&
1217: frag != add_symbol->sy_frag){
1218: if(frag->fr_type == rs_align)
1219: size = round(size + frag->fr_fix,
1220: 1 << frag->fr_offset);
1221: else if(frag->fr_type == rs_fill)
1222: size += frag->fr_fix +
1223: frag->fr_var * frag->fr_offset;
1224: else
1225: fail = 1;
1226: frag = frag->fr_next;
1227: }
1228:
1229: if(!fail && frag == add_symbol->sy_frag){
1230: expressionP->X_add_number = size +
1231: add_symbol->sy_value -
1232: subtract_symbol->sy_value;
1233: expressionP->X_seg = SEG_ABSOLUTE;
1234: expressionP->X_add_symbol = NULL;
1235: expressionP->X_subtract_symbol = NULL;
1236: }
1237: }
1238: }
1239: }
1240: }
1241: giveup:
1242:
1243: return(expressionP->X_seg);
1244: }
1245:
1246: /*
1247: * two_char_op_encoding() return the operator type for two character operators.
1248: * The first_op_char is part of a two character operator and this routine is
1249: * then used to determine the operator type looking at the second character.
1250: */
1251: static
1252: operatorT
1253: two_char_op_encoding(
1254: char first_op_char)
1255: {
1256: char second_op_char;
1257:
1258: second_op_char = input_line_pointer[1];
1259: switch(first_op_char){
1260: case '<':
1261: if(second_op_char == '<')
1262: return(O_left_shift);
1263: if(second_op_char == '=')
1264: return(O_less_than_or_equal);
1265: if(second_op_char == '>')
1266: return(O_not_equal);
1267: return(O_less_than);
1268: case '>':
1269: if(second_op_char == '>')
1270: return(O_right_shift);
1271: if(second_op_char == '=')
1272: return(O_greater_than_or_equal);
1273: return(O_greater_than);
1274: case '=':
1275: if(second_op_char == '=')
1276: return(O_equal);
1277: return(O_illegal);
1278: case '!':
1279: if(second_op_char == '=')
1280: return(O_not_equal);
1281: return O_not_equal;
1282: default:
1283: BAD_CASE(first_op_char);
1284: return O_illegal;
1285: }
1286: }
1287:
1288: /*
1289: * get_symbol_end()
1290: *
1291: * This lives here because it belongs equally in expr.c & read.c.
1292: * Expr.c is just a branch office read.c anyway, and putting it
1293: * here lessens the crowd at read.c.
1294: *
1295: * Assume input_line_pointer is at start of symbol name.
1296: * Advance input_line_pointer past symbol name.
1297: * Turn that character into a '\0', returning its former value.
1298: * This allows a string compare (RMS wants symbol names to be strings)
1299: * of the symbol name.
1300: * There will always be a char following symbol name, because all good
1301: * lines end in end-of-line.
1302: */
1303: char
1304: get_symbol_end(
1305: void)
1306: {
1307: register char c;
1308:
1309: /*
1310: * Symbol names are allowed to have surrounding ""s so that names can
1311: * have any characters in them (including spacesi, colons, etc). This
1312: * is done so names like "[Foo bar:fuz:]" can be used as symbol names.
1313: */
1314: if(*input_line_pointer == '"'){
1315: input_line_pointer++;
1316: do{
1317: c = *input_line_pointer++ ;
1318: }while(c != '"' && c != '\0' && c != '\n');
1319: if(c == '"'){
1320: *(input_line_pointer - 1) = 0;
1321: c = *input_line_pointer++;
1322: }
1323: }
1324: else{
1325: while(is_part_of_name(c = *input_line_pointer++))
1326: ;
1327: }
1328: *--input_line_pointer = 0;
1329: return(c);
1330: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.