summaryrefslogtreecommitdiffstats
path: root/contrib/binutils/gas/expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/binutils/gas/expr.c')
-rw-r--r--contrib/binutils/gas/expr.c181
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);
OpenPOWER on IntegriCloud