diff options
author | obrien <obrien@FreeBSD.org> | 2004-06-16 05:45:41 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2004-06-16 05:45:41 +0000 |
commit | 2504df11e1275f63f4c53377bf91eee996360cb5 (patch) | |
tree | 04848ae93445e503c4190ca1748abe15eabc9e11 /contrib/binutils/gas/expr.c | |
parent | 6b4c52b743ec5e2e9f65d42b517feefad5017901 (diff) | |
download | FreeBSD-src-2504df11e1275f63f4c53377bf91eee996360cb5.zip FreeBSD-src-2504df11e1275f63f4c53377bf91eee996360cb5.tar.gz |
Import of Binutils from the FSF 2.15 branch (just post-.0 release).
These bits are taken from the FSF anoncvs repo on 23-May-2004 04:41:00 UTC.
Diffstat (limited to 'contrib/binutils/gas/expr.c')
-rw-r--r-- | contrib/binutils/gas/expr.c | 181 |
1 files changed, 85 insertions, 96 deletions
diff --git a/contrib/binutils/gas/expr.c b/contrib/binutils/gas/expr.c index 13c167a..d520a04 100644 --- a/contrib/binutils/gas/expr.c +++ b/contrib/binutils/gas/expr.c @@ -1,6 +1,6 @@ /* expr.c -operands, expressions- Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001 + 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -32,17 +32,17 @@ #include "safe-ctype.h" #include "obstack.h" -static void floating_constant PARAMS ((expressionS * expressionP)); -static valueT generic_bignum_to_int32 PARAMS ((void)); +static void floating_constant (expressionS * expressionP); +static valueT generic_bignum_to_int32 (void); #ifdef BFD64 -static valueT generic_bignum_to_int64 PARAMS ((void)); +static valueT generic_bignum_to_int64 (void); #endif -static void integer_constant PARAMS ((int radix, expressionS * expressionP)); -static void mri_char_constant PARAMS ((expressionS *)); -static void current_location PARAMS ((expressionS *)); -static void clean_up_expression PARAMS ((expressionS * expressionP)); -static segT operand PARAMS ((expressionS *)); -static operatorT operator PARAMS ((int *)); +static void integer_constant (int radix, expressionS * expressionP); +static void mri_char_constant (expressionS *); +static void current_location (expressionS *); +static void clean_up_expression (expressionS * expressionP); +static segT operand (expressionS *); +static operatorT operator (int *); extern const char EXP_CHARS[], FLT_CHARS[]; @@ -63,11 +63,9 @@ static struct expr_symbol_line *expr_symbol_lines; into the fake section expr_section. */ symbolS * -make_expr_symbol (expressionP) - expressionS *expressionP; +make_expr_symbol (expressionS *expressionP) { expressionS zero; - const char *fake; symbolS *symbolP; struct expr_symbol_line *n; @@ -78,8 +76,8 @@ make_expr_symbol (expressionP) if (expressionP->X_op == O_big) { /* This won't work, because the actual value is stored in - generic_floating_point_number or generic_bignum, and we are - going to lose it if we haven't already. */ + generic_floating_point_number or generic_bignum, and we are + going to lose it if we haven't already. */ if (expressionP->X_add_number > 0) as_bad (_("bignum invalid")); else @@ -91,13 +89,11 @@ make_expr_symbol (expressionP) expressionP = &zero; } - fake = FAKE_LABEL_NAME; - /* Putting constant symbols in absolute_section rather than expr_section is convenient for the old a.out code, for which S_GET_SEGMENT does not always retrieve the value put in by S_SET_SEGMENT. */ - symbolP = symbol_create (fake, + symbolP = symbol_create (FAKE_LABEL_NAME, (expressionP->X_op == O_constant ? absolute_section : expr_section), @@ -121,10 +117,7 @@ make_expr_symbol (expressionP) the symbol. */ int -expr_symbol_where (sym, pfile, pline) - symbolS *sym; - char **pfile; - unsigned int *pline; +expr_symbol_where (symbolS *sym, char **pfile, unsigned int *pline) { register struct expr_symbol_line *l; @@ -154,8 +147,7 @@ expr_symbol_where (sym, pfile, pline) but that seems more clumsy. */ symbolS * -expr_build_uconstant (value) - offsetT value; +expr_build_uconstant (offsetT value) { expressionS e; @@ -168,9 +160,7 @@ expr_build_uconstant (value) /* Build an expression for OP s1. */ symbolS * -expr_build_unary (op, s1) - operatorT op; - symbolS *s1; +expr_build_unary (operatorT op, symbolS *s1) { expressionS e; @@ -183,10 +173,7 @@ expr_build_unary (op, s1) /* Build an expression for s1 OP s2. */ symbolS * -expr_build_binary (op, s1, s2) - operatorT op; - symbolS *s1; - symbolS *s2; +expr_build_binary (operatorT op, symbolS *s1, symbolS *s2) { expressionS e; @@ -200,7 +187,7 @@ expr_build_binary (op, s1, s2) /* Build an expression for the current location ('.'). */ symbolS * -expr_build_dot () +expr_build_dot (void) { expressionS e; @@ -230,8 +217,7 @@ FLONUM_TYPE generic_floating_point_number = { int generic_floating_point_magic; static void -floating_constant (expressionP) - expressionS *expressionP; +floating_constant (expressionS *expressionP) { /* input_line_pointer -> floating-point constant. */ int error_code; @@ -258,7 +244,7 @@ floating_constant (expressionP) } static valueT -generic_bignum_to_int32 () +generic_bignum_to_int32 (void) { valueT number = ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS) @@ -269,7 +255,7 @@ generic_bignum_to_int32 () #ifdef BFD64 static valueT -generic_bignum_to_int64 () +generic_bignum_to_int64 (void) { valueT number = ((((((((valueT) generic_bignum[3] & LITTLENUM_MASK) @@ -284,9 +270,7 @@ generic_bignum_to_int64 () #endif static void -integer_constant (radix, expressionP) - int radix; - expressionS *expressionP; +integer_constant (int radix, expressionS *expressionP) { char *start; /* Start of number. */ char *suffix = NULL; @@ -329,8 +313,8 @@ integer_constant (radix, expressionP) int flt = 0; /* In MRI mode, the number may have a suffix indicating the - radix. For that matter, it might actually be a floating - point constant. */ + radix. For that matter, it might actually be a floating + point constant. */ for (suffix = input_line_pointer; ISALNUM (*suffix); suffix++) { if (*suffix == 'e' || *suffix == 'E') @@ -401,7 +385,7 @@ integer_constant (radix, expressionP) if (radix == 16 && c == '_') { /* This is literal of the form 0x333_0_12345678_1. - This example is equivalent to 0x00000333000000001234567800000001. */ + This example is equivalent to 0x00000333000000001234567800000001. */ int num_little_digits = 0; int i; @@ -645,8 +629,7 @@ integer_constant (radix, expressionP) /* Parse an MRI multi character constant. */ static void -mri_char_constant (expressionP) - expressionS *expressionP; +mri_char_constant (expressionS *expressionP) { int i; @@ -681,8 +664,8 @@ mri_char_constant (expressionP) if (i < SIZE_OF_LARGE_NUMBER - 1) { /* If there is more than one littlenum, left justify the - last one to make it match the earlier ones. If there is - only one, we can just use the value directly. */ + last one to make it match the earlier ones. If there is + only one, we can just use the value directly. */ for (; j < CHARS_PER_LITTLENUM; j++) generic_bignum[i] <<= 8; } @@ -735,8 +718,7 @@ mri_char_constant (expressionP) handles the magic symbol `.'. */ static void -current_location (expressionp) - expressionS *expressionp; +current_location (expressionS *expressionp) { if (now_seg == absolute_section) { @@ -745,13 +727,8 @@ current_location (expressionp) } else { - symbolS *symbolp; - - symbolp = symbol_new (FAKE_LABEL_NAME, now_seg, - (valueT) frag_now_fix (), - frag_now); expressionp->X_op = O_symbol; - expressionp->X_add_symbol = symbolp; + expressionp->X_add_symbol = symbol_temp_new_now (); expressionp->X_add_number = 0; } } @@ -764,8 +741,7 @@ current_location (expressionp) Input_line_pointer->(next non-blank) char after operand. */ static segT -operand (expressionP) - expressionS *expressionP; +operand (expressionS *expressionP) { char c; symbolS *symbolP; /* Points to symbol. */ @@ -828,10 +804,10 @@ operand (expressionP) { char *s; - /* Check for a hex constant. */ + /* Check for a hex or float constant. */ for (s = input_line_pointer; hex_p (*s); s++) ; - if (*s == 'h' || *s == 'H') + if (*s == 'h' || *s == 'H' || *input_line_pointer == '.') { --input_line_pointer; integer_constant (0, expressionP); @@ -1045,6 +1021,10 @@ operand (expressionP) break; case '+': + /* Do not accept ++e as +(+e). + Disabled, since the preprocessor removes whitespace. */ + if (0 && *input_line_pointer == '+') + goto target_op; (void) operand (expressionP); break; @@ -1062,6 +1042,11 @@ operand (expressionP) case '!': case '-': { + /* Do not accept --e as -(-e) + Disabled, since the preprocessor removes whitespace. */ + if (0 && c == '-' && *input_line_pointer == '-') + goto target_op; + operand (expressionP); if (expressionP->X_op == O_constant) { @@ -1079,6 +1064,18 @@ operand (expressionP) else expressionP->X_add_number = ! expressionP->X_add_number; } + else if (expressionP->X_op == O_big + && expressionP->X_add_number <= 0 + && c == '-' + && (generic_floating_point_number.sign == '+' + || generic_floating_point_number.sign == 'P')) + { + /* Negative flonum (eg, -1.000e0). */ + if (generic_floating_point_number.sign == '+') + generic_floating_point_number.sign = '-'; + else + generic_floating_point_number.sign = 'N'; + } else if (expressionP->X_op != O_illegal && expressionP->X_op != O_absent) { @@ -1100,7 +1097,7 @@ operand (expressionP) #if defined (DOLLAR_DOT) || defined (TC_M68K) case '$': /* '$' is the program counter when in MRI mode, or when - DOLLAR_DOT is defined. */ + DOLLAR_DOT is defined. */ #ifndef DOLLAR_DOT if (! flag_m68k_mri) goto de_fault; @@ -1108,7 +1105,7 @@ operand (expressionP) if (flag_m68k_mri && hex_p (*input_line_pointer)) { /* In MRI mode, '$' is also used as the prefix for a - hexadecimal constant. */ + hexadecimal constant. */ integer_constant (16, expressionP); break; } @@ -1199,7 +1196,7 @@ operand (expressionP) goto de_fault; /* In MRI mode, this is a floating point constant represented - using hexadecimal digits. */ + using hexadecimal digits. */ ++input_line_pointer; integer_constant (16, expressionP); @@ -1227,9 +1224,9 @@ operand (expressionP) #ifdef md_parse_name /* This is a hook for the backend to parse certain names - specially in certain contexts. If a name always has a - specific value, it can often be handled by simply - entering it in the symbol table. */ + specially in certain contexts. If a name always has a + specific value, it can often be handled by simply + entering it in the symbol table. */ if (md_parse_name (name, expressionP, &c)) { *input_line_pointer = c; @@ -1301,6 +1298,7 @@ operand (expressionP) } else { + target_op: /* Let the target try to parse it. Success is indicated by changing the X_op field to something other than O_absent and pointing input_line_pointer past the expression. If it can't parse the @@ -1347,13 +1345,10 @@ operand (expressionP) Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT. Out: expressionS may have been modified: - 'foo-foo' symbol references cancelled to 0, which changes X_op - from O_subtract to O_constant. Unused fields zeroed to help expr (). */ static void -clean_up_expression (expressionP) - expressionS *expressionP; +clean_up_expression (expressionS *expressionP) { switch (expressionP->X_op) { @@ -1371,23 +1366,6 @@ clean_up_expression (expressionP) case O_bit_not: expressionP->X_op_symbol = NULL; break; - case O_subtract: - if (expressionP->X_op_symbol == expressionP->X_add_symbol - || ((symbol_get_frag (expressionP->X_op_symbol) - == symbol_get_frag (expressionP->X_add_symbol)) - && SEG_NORMAL (S_GET_SEGMENT (expressionP->X_add_symbol)) - && (S_GET_VALUE (expressionP->X_op_symbol) - == S_GET_VALUE (expressionP->X_add_symbol)))) - { - addressT diff = (S_GET_VALUE (expressionP->X_add_symbol) - - S_GET_VALUE (expressionP->X_op_symbol)); - - expressionP->X_op = O_constant; - expressionP->X_add_symbol = NULL; - expressionP->X_op_symbol = NULL; - expressionP->X_add_number += diff; - } - break; default: break; } @@ -1521,7 +1499,7 @@ static operator_rankT op_rank[] = { #define MRI_MUL_PRECEDENCE 6 void -expr_set_precedence () +expr_set_precedence (void) { if (flag_m68k_mri) { @@ -1540,7 +1518,7 @@ expr_set_precedence () /* Initialize the expression parser. */ void -expr_begin () +expr_begin (void) { expr_set_precedence (); @@ -1557,8 +1535,7 @@ expr_begin () Does not advance INPUT_LINE_POINTER. */ static inline operatorT -operator (num_chars) - int *num_chars; +operator (int *num_chars) { int c; operatorT ret; @@ -1574,6 +1551,14 @@ operator (num_chars) default: return op_encoding[c]; + case '+': + case '-': + /* Do not allow a++b and a--b to be a + (+b) and a - (-b) + Disabled, since the preprocessor removes whitespace. */ + if (1 || input_line_pointer[1] != c) + return op_encoding[c]; + return O_illegal; + case '<': switch (input_line_pointer[1]) { @@ -1646,9 +1631,8 @@ operator (num_chars) /* Parse an expression. */ segT -expr (rankarg, resultP) - int rankarg; /* Larger # is higher rank. */ - expressionS *resultP; /* Deliver result here. */ +expr (int rankarg, /* Larger # is higher rank. */ + expressionS *resultP /* Deliver result here. */) { operator_rankT rank = (operator_rankT) rankarg; segT retval; @@ -1659,6 +1643,10 @@ expr (rankarg, resultP) know (rank >= 0); + /* Save the value of dot for the fixup code. */ + if (rank == 0) + dot_value = frag_now_fix (); + retval = operand (resultP); /* operand () gobbles spaces. */ @@ -1749,7 +1737,8 @@ expr (rankarg, resultP) && resultP->X_op == O_symbol && (symbol_get_frag (right.X_add_symbol) == symbol_get_frag (resultP->X_add_symbol)) - && SEG_NORMAL (rightseg)) + && (SEG_NORMAL (rightseg) + || right.X_add_symbol == resultP->X_add_symbol)) { resultP->X_add_number -= right.X_add_number; resultP->X_add_number += (S_GET_VALUE (resultP->X_add_symbol) @@ -1789,7 +1778,7 @@ expr (rankarg, resultP) case O_left_shift: resultP->X_add_number <<= v; break; case O_right_shift: /* We always use unsigned shifts, to avoid relying on - characteristics of the compiler used to compile gas. */ + characteristics of the compiler used to compile gas. */ resultP->X_add_number = (offsetT) ((valueT) resultP->X_add_number >> (valueT) v); break; @@ -1901,7 +1890,7 @@ expr (rankarg, resultP) lines end in end-of-line. */ char -get_symbol_end () +get_symbol_end (void) { char c; @@ -1920,7 +1909,7 @@ get_symbol_end () } unsigned int -get_single_number () +get_single_number (void) { expressionS exp; operand (&exp); |