Changeset 609 for branches/GNU/src/binutils/gas/expr.c
- Timestamp:
- Aug 16, 2003, 6:59:22 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GNU/src/binutils/gas/expr.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.1.1.2
r608 r609 1 1 /* expr.c -operands, expressions- 2 2 Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3 1999, 2000, 2001 3 1999, 2000, 2001, 2002 4 4 Free Software Foundation, Inc. 5 5 … … 26 26 Here, "operand"s are of expressions, not instructions. */ 27 27 28 #include <ctype.h>29 28 #include <string.h> 30 29 #define min(a, b) ((a) < (b) ? (a) : (b)) 31 30 32 31 #include "as.h" 32 #include "safe-ctype.h" 33 33 #include "obstack.h" 34 34 … … 80 80 { 81 81 /* This won't work, because the actual value is stored in 82 83 82 generic_floating_point_number or generic_bignum, and we are 83 going to lose it if we haven't already. */ 84 84 if (expressionP->X_add_number > 0) 85 as_bad (_("bignum invalid ; zero assumed"));85 as_bad (_("bignum invalid")); 86 86 else 87 as_bad (_("floating point number invalid ; zero assumed"));87 as_bad (_("floating point number invalid")); 88 88 zero.X_op = O_constant; 89 89 zero.X_add_number = 0; … … 107 107 108 108 if (expressionP->X_op == O_constant) 109 resolve_symbol_value (symbolP , 1);109 resolve_symbol_value (symbolP); 110 110 111 111 n = (struct expr_symbol_line *) xmalloc (sizeof *n); … … 248 248 if (error_code == ERROR_EXPONENT_OVERFLOW) 249 249 { 250 as_bad (_("bad floating-point constant: exponent overflow , probably assembling junk"));250 as_bad (_("bad floating-point constant: exponent overflow")); 251 251 } 252 252 else 253 253 { 254 as_bad (_("bad floating-point constant: unknown error code=%d."), error_code); 254 as_bad (_("bad floating-point constant: unknown error code=%d"), 255 error_code); 255 256 } 256 257 } … … 333 334 334 335 /* In MRI mode, the number may have a suffix indicating the 335 radix. For that matter, it might actually be a floating 336 point constant. */ 337 for (suffix = input_line_pointer; 338 isalnum ((unsigned char) *suffix); 339 suffix++) 336 radix. For that matter, it might actually be a floating 337 point constant. */ 338 for (suffix = input_line_pointer; ISALNUM (*suffix); suffix++) 340 339 { 341 340 if (*suffix == 'e' || *suffix == 'E') … … 351 350 { 352 351 c = *--suffix; 353 if (islower ((unsigned char) c)) 354 c = toupper (c); 352 c = TOUPPER (c); 355 353 if (c == 'B') 356 354 radix = 2; … … 408 406 { 409 407 /* This is literal of the form 0x333_0_12345678_1. 410 408 This example is equivalent to 0x00000333000000001234567800000001. */ 411 409 412 410 int num_little_digits = 0; … … 432 430 /* Check for 8 digit per word max. */ 433 431 if (ndigit > 8) 434 as_bad (_(" A bignum with underscores may not have more than 8 hex digits in any word."));432 as_bad (_("a bignum with underscores may not have more than 8 hex digits in any word")); 435 433 436 434 /* Add this chunk to the bignum. … … 455 453 456 454 if (num_little_digits != 8) 457 as_bad (_(" A bignum with underscores must have exactly 4 words."));455 as_bad (_("a bignum with underscores must have exactly 4 words")); 458 456 459 457 /* We might have some leading zeros. These can be trimmed to give … … 578 576 /* @@ Should print out the original string instead of 579 577 the parsed number. */ 580 as_bad (_("backw . ref to unknown label \"%d:\", 0 assumed."),578 as_bad (_("backward ref to unknown label \"%d:\""), 581 579 (int) number); 582 580 expressionP->X_op = O_constant; … … 688 686 { 689 687 /* If there is more than one littlenum, left justify the 690 691 688 last one to make it match the earlier ones. If there is 689 only one, we can just use the value directly. */ 692 690 for (; j < CHARS_PER_LITTLENUM; j++) 693 691 generic_bignum[i] <<= 8; … … 701 699 if (i < 0) 702 700 { 703 as_bad (_(" Character constant too large"));701 as_bad (_("character constant too large")); 704 702 i = 0; 705 703 } … … 766 764 be a space. 767 765 768 Out: A expressionS.766 Out: An expressionS. 769 767 The operand may have been empty: in this case X_op == O_absent. 770 768 Input_line_pointer->(next non-blank) char after operand. */ … … 810 808 integer_constant ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) 811 809 ? 0 : 10, 812 810 expressionP); 813 811 break; 814 812 815 813 #ifdef LITERAL_PREFIXDOLLAR_HEX 816 814 case '$': 815 /* $L is the start of a local label, not a hex constant. */ 816 if (* input_line_pointer == 'L') 817 goto isname; 817 818 integer_constant (16, expressionP); 818 819 break; … … 832 833 char *s; 833 834 834 /* Check for a hex constant. */835 /* Check for a hex or float constant. */ 835 836 for (s = input_line_pointer; hex_p (*s); s++) 836 837 ; 837 if (*s == 'h' || *s == 'H' )838 if (*s == 'h' || *s == 'H' || *input_line_pointer == '.') 838 839 { 839 840 --input_line_pointer; … … 863 864 input_line_pointer++; 864 865 floating_constant (expressionP); 865 expressionP->X_add_number = 866 - (isupper ((unsigned char) c) ? tolower (c) : c); 866 expressionP->X_add_number = - TOLOWER (c); 867 867 } 868 868 else … … 986 986 input_line_pointer++; 987 987 floating_constant (expressionP); 988 expressionP->X_add_number = 989 - (isupper ((unsigned char) c) ? tolower (c) : c); 988 expressionP->X_add_number = - TOLOWER (c); 990 989 break; 991 990 … … 1015 1014 if (c != '(') 1016 1015 #endif 1017 as_bad (_(" Missing '%c' assumed"), c == '(' ? ')' : ']');1016 as_bad (_("missing '%c'"), c == '(' ? ')' : ']'); 1018 1017 } 1019 1018 else … … 1085 1084 expressionP->X_add_number = ! expressionP->X_add_number; 1086 1085 } 1086 else if (expressionP->X_op == O_big 1087 && expressionP->X_add_number <= 0 1088 && c == '-' 1089 && (generic_floating_point_number.sign == '+' 1090 || generic_floating_point_number.sign == 'P')) 1091 { 1092 /* Negative flonum (eg, -1.000e0). */ 1093 if (generic_floating_point_number.sign == '+') 1094 generic_floating_point_number.sign = '-'; 1095 else 1096 generic_floating_point_number.sign = 'N'; 1097 } 1087 1098 else if (expressionP->X_op != O_illegal 1088 1099 && expressionP->X_op != O_absent) … … 1106 1117 case '$': 1107 1118 /* '$' is the program counter when in MRI mode, or when 1108 1119 DOLLAR_DOT is defined. */ 1109 1120 #ifndef DOLLAR_DOT 1110 1121 if (! flag_m68k_mri) … … 1114 1125 { 1115 1126 /* In MRI mode, '$' is also used as the prefix for a 1116 1127 hexadecimal constant. */ 1117 1128 integer_constant (16, expressionP); 1118 1129 break; … … 1205 1216 1206 1217 /* In MRI mode, this is a floating point constant represented 1207 1218 using hexadecimal digits. */ 1208 1219 1209 1220 ++input_line_pointer; … … 1233 1244 #ifdef md_parse_name 1234 1245 /* This is a hook for the backend to parse certain names 1235 1236 1237 1238 if (md_parse_name (name, expressionP ))1246 specially in certain contexts. If a name always has a 1247 specific value, it can often be handled by simply 1248 entering it in the symbol table. */ 1249 if (md_parse_name (name, expressionP, &c)) 1239 1250 { 1240 1251 *input_line_pointer = c; … … 1317 1328 { 1318 1329 ++input_line_pointer; 1319 as_bad (_(" Bad expression"));1330 as_bad (_("bad expression")); 1320 1331 expressionP->X_op = O_constant; 1321 1332 expressionP->X_add_number = 0; … … 1349 1360 /* Internal. Simplify a struct expression for use by expr (). */ 1350 1361 1351 /* In: address of a expressionS.1362 /* In: address of an expressionS. 1352 1363 The X_op field of the expressionS may only take certain values. 1353 1364 Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT. 1354 1365 1355 1366 Out: expressionS may have been modified: 1356 'foo-foo' symbol references cancelled to 0, which changes X_op1357 from O_subtract to O_constant.1358 1367 Unused fields zeroed to help expr (). */ 1359 1368 … … 1378 1387 expressionP->X_op_symbol = NULL; 1379 1388 break; 1380 case O_subtract:1381 if (expressionP->X_op_symbol == expressionP->X_add_symbol1382 || ((symbol_get_frag (expressionP->X_op_symbol)1383 == symbol_get_frag (expressionP->X_add_symbol))1384 && SEG_NORMAL (S_GET_SEGMENT (expressionP->X_add_symbol))1385 && (S_GET_VALUE (expressionP->X_op_symbol)1386 == S_GET_VALUE (expressionP->X_add_symbol))))1387 {1388 addressT diff = (S_GET_VALUE (expressionP->X_add_symbol)1389 - S_GET_VALUE (expressionP->X_op_symbol));1390 1391 expressionP->X_op = O_constant;1392 expressionP->X_add_symbol = NULL;1393 expressionP->X_op_symbol = NULL;1394 expressionP->X_add_number += diff;1395 }1396 break;1397 1389 default: 1398 1390 break; … … 1407 1399 As usual, Q==quantity==operand, O==operator, X==expression mnemonics. 1408 1400 1409 We used to do a aho/ullman shift-reduce parser, but the logic got so1401 We used to do an aho/ullman shift-reduce parser, but the logic got so 1410 1402 warped that I flushed it and wrote a recursive-descent parser instead. 1411 1403 Now things are stable, would anybody like to write a fast parser? … … 1463 1455 1 || 1464 1456 2 && 1465 3 = <> < <= >= >1457 3 == <> < <= >= > 1466 1458 4 + - 1467 1459 5 used for * / % in MRI mode … … 1668 1660 know (rank >= 0); 1669 1661 1662 /* Save the value of dot for the fixup code. */ 1663 if (rank == 0) 1664 dot_value = frag_now_fix (); 1665 1670 1666 retval = operand (resultP); 1671 1667 … … 1702 1698 } 1703 1699 } 1704 1705 if (retval == undefined_section)1706 {1707 if (SEG_NORMAL (rightseg))1708 retval = rightseg;1709 }1710 else if (! SEG_NORMAL (retval))1711 retval = rightseg;1712 else if (SEG_NORMAL (rightseg)1713 && retval != rightseg1714 #ifdef DIFF_EXPR_OK1715 && op_left != O_subtract1716 #endif1717 )1718 as_bad (_("operation combines symbols in different segments"));1719 1700 1720 1701 op_right = operator (&op_chars); … … 1773 1754 && (symbol_get_frag (right.X_add_symbol) 1774 1755 == symbol_get_frag (resultP->X_add_symbol)) 1775 && SEG_NORMAL (S_GET_SEGMENT (right.X_add_symbol)))1776 1756 && (SEG_NORMAL (rightseg) 1757 || right.X_add_symbol == resultP->X_add_symbol)) 1777 1758 { 1778 1759 resultP->X_add_number -= right.X_add_number; … … 1814 1795 case O_right_shift: 1815 1796 /* We always use unsigned shifts, to avoid relying on 1816 1797 characteristics of the compiler used to compile gas. */ 1817 1798 resultP->X_add_number = 1818 1799 (offsetT) ((valueT) resultP->X_add_number >> (valueT) v); … … 1869 1850 resultP->X_add_number += right.X_add_number; 1870 1851 else if (op_left == O_subtract) 1871 resultP->X_add_number -= right.X_add_number; 1852 { 1853 resultP->X_add_number -= right.X_add_number; 1854 if (retval == rightseg && SEG_NORMAL (retval)) 1855 { 1856 retval = absolute_section; 1857 rightseg = absolute_section; 1858 } 1859 } 1872 1860 } 1873 1861 else … … 1879 1867 resultP->X_add_number = 0; 1880 1868 resultP->X_unsigned = 1; 1869 } 1870 1871 if (retval != rightseg) 1872 { 1873 if (! SEG_NORMAL (retval)) 1874 { 1875 if (retval != undefined_section || SEG_NORMAL (rightseg)) 1876 retval = rightseg; 1877 } 1878 else if (SEG_NORMAL (rightseg) 1879 #ifdef DIFF_EXPR_OK 1880 && op_left != O_subtract 1881 #endif 1882 ) 1883 as_bad (_("operation combines symbols in different segments")); 1881 1884 } 1882 1885 -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.