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.c273
1 files changed, 194 insertions, 79 deletions
diff --git a/contrib/binutils/gas/expr.c b/contrib/binutils/gas/expr.c
index 47e6933..7cca437 100644
--- a/contrib/binutils/gas/expr.c
+++ b/contrib/binutils/gas/expr.c
@@ -1,5 +1,5 @@
/* expr.c -operands, expressions-
- Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 1998
+ Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -34,6 +34,10 @@
#include "obstack.h"
static void floating_constant PARAMS ((expressionS * expressionP));
+static valueT generic_bignum_to_int32 PARAMS ((void));
+#ifdef BFD64
+static valueT generic_bignum_to_int64 PARAMS ((void));
+#endif
static void integer_constant PARAMS ((int radix, expressionS * expressionP));
static void mri_char_constant PARAMS ((expressionS *));
static void current_location PARAMS ((expressionS *));
@@ -64,6 +68,7 @@ symbolS *
make_expr_symbol (expressionP)
expressionS *expressionP;
{
+ expressionS zero;
const char *fake;
symbolS *symbolP;
struct expr_symbol_line *n;
@@ -72,6 +77,22 @@ make_expr_symbol (expressionP)
&& expressionP->X_add_number == 0)
return expressionP->X_add_symbol;
+ 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. */
+ if (expressionP->X_add_number > 0)
+ as_bad (_("bignum invalid; zero assumed"));
+ else
+ as_bad (_("floating point number invalid; zero assumed"));
+ zero.X_op = O_constant;
+ zero.X_add_number = 0;
+ zero.X_unsigned = 0;
+ clean_up_expression (&zero);
+ expressionP = &zero;
+ }
+
fake = FAKE_LABEL_NAME;
/* Putting constant symbols in absolute_section rather than
@@ -83,7 +104,7 @@ make_expr_symbol (expressionP)
? absolute_section
: expr_section),
0, &zero_address_frag);
- symbolP->sy_value = *expressionP;
+ symbol_set_value_expression (symbolP, expressionP);
if (expressionP->X_op == O_constant)
resolve_symbol_value (symbolP, 1);
@@ -177,6 +198,17 @@ expr_build_binary (op, s1, s2)
e.X_add_number = 0;
return make_expr_symbol (&e);
}
+
+/* Build an expression for the current location ('.'). */
+
+symbolS *
+expr_build_dot ()
+{
+ expressionS e;
+
+ current_location (&e);
+ return make_expr_symbol (&e);
+}
/*
* Build any floating-point literal here.
@@ -215,11 +247,11 @@ floating_constant (expressionP)
{
if (error_code == ERROR_EXPONENT_OVERFLOW)
{
- as_bad ("bad floating-point constant: exponent overflow, probably assembling junk");
+ as_bad (_("bad floating-point constant: exponent overflow, probably assembling junk"));
}
else
{
- as_bad ("bad floating-point constant: unknown error code=%d.", error_code);
+ as_bad (_("bad floating-point constant: unknown error code=%d."), error_code);
}
}
expressionP->X_op = O_big;
@@ -295,7 +327,7 @@ integer_constant (radix, expressionP)
#define valuesize 32
#endif
- if (flag_m68k_mri && radix == 0)
+ if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) && radix == 0)
{
int flt = 0;
@@ -357,7 +389,7 @@ integer_constant (radix, expressionP)
break;
case 10:
maxdig = radix = 10;
- too_many_digits = (valuesize + 12) / 4; /* very rough */
+ too_many_digits = (valuesize + 11) / 4; /* very rough */
}
#undef valuesize
start = input_line_pointer;
@@ -399,7 +431,7 @@ integer_constant (radix, expressionP)
/* Check for 8 digit per word max. */
if (ndigit > 8)
- as_bad ("An bignum with underscores may not have more than 8 hex digits in any word.");
+ as_bad (_("A bignum with underscores may not have more than 8 hex digits in any word."));
/* Add this chunk to the bignum. Shift things down 2 little digits.*/
know (LITTLENUM_NUMBER_OF_BITS == 16);
@@ -419,7 +451,7 @@ integer_constant (radix, expressionP)
assert (num_little_digits >= 4);
if (num_little_digits != 8)
- as_bad ("A bignum with underscores must have exactly 4 words.");
+ as_bad (_("A bignum with underscores must have exactly 4 words."));
/* We might have some leading zeros. These can be trimmed to give
* us a change to fit this constant into a small number.
@@ -509,7 +541,9 @@ integer_constant (radix, expressionP)
}
}
- if (flag_m68k_mri && suffix != NULL && input_line_pointer - 1 == suffix)
+ if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri)
+ && suffix != NULL
+ && input_line_pointer - 1 == suffix)
c = *input_line_pointer++;
if (small)
@@ -546,7 +580,7 @@ integer_constant (radix, expressionP)
/* either not seen or not defined. */
/* @@ Should print out the original string instead of
the parsed number. */
- as_bad ("backw. ref to unknown label \"%d:\", 0 assumed.",
+ as_bad (_("backw. ref to unknown label \"%d:\", 0 assumed."),
(int) number);
expressionP->X_op = O_constant;
}
@@ -670,7 +704,7 @@ mri_char_constant (expressionP)
if (i < 0)
{
- as_bad ("Character constant too large");
+ as_bad (_("Character constant too large"));
i = 0;
}
@@ -778,13 +812,15 @@ operand (expressionP)
case '9':
input_line_pointer--;
- integer_constant (flag_m68k_mri ? 0 : 10, expressionP);
+ integer_constant ((NUMBERS_WITH_SUFFIX || flag_m68k_mri)
+ ? 0 : 10,
+ expressionP);
break;
case '0':
/* non-decimal radix */
- if (flag_m68k_mri)
+ if (NUMBERS_WITH_SUFFIX || flag_m68k_mri)
{
char *s;
@@ -797,8 +833,7 @@ operand (expressionP)
integer_constant (0, expressionP);
break;
}
- }
-
+ }
c = *input_line_pointer;
switch (c)
{
@@ -808,7 +843,7 @@ operand (expressionP)
case 'Q':
case '8':
case '9':
- if (flag_m68k_mri)
+ if (NUMBERS_WITH_SUFFIX || flag_m68k_mri)
{
integer_constant (0, expressionP);
break;
@@ -841,7 +876,7 @@ operand (expressionP)
break;
case 'b':
- if (LOCAL_LABELS_FB && ! flag_m68k_mri)
+ if (LOCAL_LABELS_FB && ! (flag_m68k_mri || NUMBERS_WITH_SUFFIX))
{
/* This code used to check for '+' and '-' here, and, in
some conditions, fall through to call
@@ -863,7 +898,7 @@ operand (expressionP)
/* Fall through. */
case 'B':
input_line_pointer++;
- if (flag_m68k_mri)
+ if (flag_m68k_mri || NUMBERS_WITH_SUFFIX)
goto default_case;
integer_constant (2, expressionP);
break;
@@ -876,7 +911,9 @@ operand (expressionP)
case '5':
case '6':
case '7':
- integer_constant (flag_m68k_mri ? 0 : 8, expressionP);
+ integer_constant ((flag_m68k_mri || NUMBERS_WITH_SUFFIX)
+ ? 0 : 8,
+ expressionP);
break;
case 'f':
@@ -886,7 +923,8 @@ operand (expressionP)
number, make it one. Otherwise, make it a local label,
and try to deal with parsing the rest later. */
if (!input_line_pointer[1]
- || (is_end_of_line[0xff & input_line_pointer[1]]))
+ || (is_end_of_line[0xff & input_line_pointer[1]])
+ || strchr (FLT_CHARS, 'f') == NULL)
goto is_0f_label;
{
char *cp = input_line_pointer + 1;
@@ -899,10 +937,14 @@ operand (expressionP)
if (*cp == 'f' || *cp == 'b')
/* looks like a difference expression */
goto is_0f_label;
+ else if (cp == input_line_pointer + 1)
+ /* No characters has been accepted -- looks like
+ end of operand. */
+ goto is_0f_label;
else
goto is_0f_float;
default:
- as_fatal ("expr.c(operand): bad atof_generic return val %d",
+ as_fatal (_("expr.c(operand): bad atof_generic return val %d"),
r);
}
}
@@ -922,7 +964,7 @@ operand (expressionP)
case 'd':
case 'D':
- if (flag_m68k_mri)
+ if (flag_m68k_mri || NUMBERS_WITH_SUFFIX)
{
integer_constant (0, expressionP);
break;
@@ -953,30 +995,34 @@ operand (expressionP)
break;
case '(':
+#ifndef NEED_INDEX_OPERATOR
case '[':
+#endif
/* didn't begin with digit & not a name */
segment = expression (expressionP);
/* Expression() will pass trailing whitespace */
if ((c == '(' && *input_line_pointer++ != ')')
|| (c == '[' && *input_line_pointer++ != ']'))
{
- as_bad ("Missing ')' assumed");
+ as_bad (_("Missing ')' assumed"));
input_line_pointer--;
}
SKIP_WHITESPACE ();
/* here with input_line_pointer->char after "(...)" */
return segment;
+#ifdef TC_M68K
case 'E':
if (! flag_m68k_mri || *input_line_pointer != '\'')
goto de_fault;
- as_bad ("EBCDIC constants are not supported");
+ as_bad (_("EBCDIC constants are not supported"));
/* Fall through. */
case 'A':
if (! flag_m68k_mri || *input_line_pointer != '\'')
goto de_fault;
++input_line_pointer;
/* Fall through. */
+#endif
case '\'':
if (! flag_m68k_mri)
{
@@ -996,11 +1042,13 @@ operand (expressionP)
(void) operand (expressionP);
break;
+#ifdef TC_M68K
case '"':
/* Double quote is the bitwise not operator in MRI mode. */
if (! flag_m68k_mri)
goto de_fault;
/* Fall through. */
+#endif
case '~':
/* ~ is permitted to start a label on the Delta. */
if (is_name_beginner (c))
@@ -1037,11 +1085,12 @@ operand (expressionP)
expressionP->X_add_number = 0;
}
else
- as_warn ("Unary operator %c ignored because bad operand follows",
+ as_warn (_("Unary operator %c ignored because bad operand follows"),
c);
}
break;
+#if defined (DOLLAR_DOT) || defined (TC_M68K)
case '$':
/* $ is the program counter when in MRI mode, or when DOLLAR_DOT
is defined. */
@@ -1062,6 +1111,7 @@ operand (expressionP)
current_location (expressionP);
break;
+#endif
case '.':
if (!is_part_of_name (*input_line_pointer))
@@ -1081,7 +1131,7 @@ operand (expressionP)
input_line_pointer += start ? 8 : 7;
SKIP_WHITESPACE ();
if (*input_line_pointer != '(')
- as_bad ("syntax error in .startof. or .sizeof.");
+ as_bad (_("syntax error in .startof. or .sizeof."));
else
{
char *buf;
@@ -1106,7 +1156,7 @@ operand (expressionP)
*input_line_pointer = c;
SKIP_WHITESPACE ();
if (*input_line_pointer != ')')
- as_bad ("syntax error in .startof. or .sizeof.");
+ as_bad (_("syntax error in .startof. or .sizeof."));
else
++input_line_pointer;
}
@@ -1125,6 +1175,7 @@ operand (expressionP)
input_line_pointer--;
break;
+#ifdef TC_M68K
case '%':
if (! flag_m68k_mri)
goto de_fault;
@@ -1154,9 +1205,12 @@ operand (expressionP)
current_location (expressionP);
break;
+#endif
default:
+#ifdef TC_M68K
de_fault:
+#endif
if (is_end_of_line[(unsigned char) c])
goto eol;
if (is_name_beginner (c)) /* here if did not begin with a digit */
@@ -1255,7 +1309,7 @@ operand (expressionP)
if (expressionP->X_op == O_absent)
{
++input_line_pointer;
- as_bad ("Bad expression");
+ as_bad (_("Bad expression"));
expressionP->X_op = O_constant;
expressionP->X_add_number = 0;
}
@@ -1273,7 +1327,7 @@ operand (expressionP)
/* The PA port needs this information. */
if (expressionP->X_add_symbol)
- expressionP->X_add_symbol->sy_used = 1;
+ symbol_mark_used (expressionP->X_add_symbol);
switch (expressionP->X_op)
{
@@ -1320,8 +1374,8 @@ clean_up_expression (expressionP)
break;
case O_subtract:
if (expressionP->X_op_symbol == expressionP->X_add_symbol
- || ((expressionP->X_op_symbol->sy_frag
- == expressionP->X_add_symbol->sy_frag)
+ || ((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))))
@@ -1366,7 +1420,7 @@ clean_up_expression (expressionP)
#undef __
#define __ O_illegal
-static operatorT op_encoding[256] =
+static const operatorT op_encoding[256] =
{ /* maps ASCII->operators */
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
@@ -1379,7 +1433,13 @@ static operatorT op_encoding[256] =
__, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __,
- __, __, __, __, __, __, O_bit_exclusive_or, __,
+ __, __, __,
+#ifdef NEED_INDEX_OPERATOR
+ O_index,
+#else
+ __,
+#endif
+ __, __, O_bit_exclusive_or, __,
__, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __,
__, __, __, __, __, __, __, __,
@@ -1417,44 +1477,79 @@ static operator_rankT op_rank[] =
0, /* O_symbol_rva */
0, /* O_register */
0, /* O_bit */
- 8, /* O_uminus */
- 8, /* O_bit_not */
- 8, /* O_logical_not */
- 7, /* O_multiply */
- 7, /* O_divide */
- 7, /* O_modulus */
- 7, /* O_left_shift */
- 7, /* O_right_shift */
- 6, /* O_bit_inclusive_or */
- 6, /* O_bit_or_not */
- 6, /* O_bit_exclusive_or */
- 6, /* O_bit_and */
- 4, /* O_add */
- 4, /* O_subtract */
- 3, /* O_eq */
- 3, /* O_ne */
- 3, /* O_lt */
- 3, /* O_le */
- 3, /* O_ge */
- 3, /* O_gt */
- 2, /* O_logical_and */
- 1 /* O_logical_or */
+ 9, /* O_uminus */
+ 9, /* O_bit_not */
+ 9, /* O_logical_not */
+ 8, /* O_multiply */
+ 8, /* O_divide */
+ 8, /* O_modulus */
+ 8, /* O_left_shift */
+ 8, /* O_right_shift */
+ 7, /* O_bit_inclusive_or */
+ 7, /* O_bit_or_not */
+ 7, /* O_bit_exclusive_or */
+ 7, /* O_bit_and */
+ 5, /* O_add */
+ 5, /* O_subtract */
+ 4, /* O_eq */
+ 4, /* O_ne */
+ 4, /* O_lt */
+ 4, /* O_le */
+ 4, /* O_ge */
+ 4, /* O_gt */
+ 3, /* O_logical_and */
+ 2, /* O_logical_or */
+ 1, /* O_index */
+ 0, /* O_md1 */
+ 0, /* O_md2 */
+ 0, /* O_md3 */
+ 0, /* O_md4 */
+ 0, /* O_md5 */
+ 0, /* O_md6 */
+ 0, /* O_md7 */
+ 0, /* O_md8 */
+ 0, /* O_md9 */
+ 0, /* O_md10 */
+ 0, /* O_md11 */
+ 0, /* O_md12 */
+ 0, /* O_md13 */
+ 0, /* O_md14 */
+ 0, /* O_md15 */
+ 0, /* O_md16 */
};
-/* Initialize the expression parser. */
+/* Unfortunately, in MRI mode for the m68k, multiplication and
+ division have lower precedence than the bit wise operators. This
+ function sets the operator precedences correctly for the current
+ mode. Also, MRI uses a different bit_not operator, and this fixes
+ that as well. */
+
+#define STANDARD_MUL_PRECEDENCE (7)
+#define MRI_MUL_PRECEDENCE (5)
void
-expr_begin ()
+expr_set_precedence ()
{
- /* In MRI mode for the m68k, multiplication and division have lower
- precedence than the bit wise operators. */
if (flag_m68k_mri)
{
- op_rank[O_multiply] = 5;
- op_rank[O_divide] = 5;
- op_rank[O_modulus] = 5;
- op_encoding['"'] = O_bit_not;
+ op_rank[O_multiply] = MRI_MUL_PRECEDENCE;
+ op_rank[O_divide] = MRI_MUL_PRECEDENCE;
+ op_rank[O_modulus] = MRI_MUL_PRECEDENCE;
+ }
+ else
+ {
+ op_rank[O_multiply] = STANDARD_MUL_PRECEDENCE;
+ op_rank[O_divide] = STANDARD_MUL_PRECEDENCE;
+ op_rank[O_modulus] = STANDARD_MUL_PRECEDENCE;
}
+}
+
+/* Initialize the expression parser. */
+
+void
+expr_begin ()
+{
+ expr_set_precedence ();
/* Verify that X_op field is wide enough. */
{
@@ -1474,7 +1569,7 @@ operator ()
int c;
operatorT ret;
- c = *input_line_pointer;
+ c = *input_line_pointer & 0xff;
switch (c)
{
@@ -1553,10 +1648,11 @@ operator ()
/* Parse an expression. */
segT
-expr (rank, resultP)
- operator_rankT rank; /* Larger # is higher rank. */
+expr (rankarg, resultP)
+ int rankarg; /* Larger # is higher rank. */
expressionS *resultP; /* Deliver result here. */
{
+ operator_rankT rank = (operator_rankT) rankarg;
segT retval;
expressionS right;
operatorT op_left;
@@ -1578,7 +1674,7 @@ expr (rank, resultP)
rightseg = expr (op_rank[(int) op_left], &right);
if (right.X_op == O_absent)
{
- as_warn ("missing operand; zero assumed");
+ as_warn (_("missing operand; zero assumed"));
right.X_op = O_constant;
right.X_add_number = 0;
right.X_add_symbol = NULL;
@@ -1587,6 +1683,17 @@ expr (rank, resultP)
know (*input_line_pointer != ' ');
+ if (op_left == O_index)
+ {
+ if (*input_line_pointer != ']')
+ as_bad ("missing right bracket");
+ else
+ {
+ ++input_line_pointer;
+ SKIP_WHITESPACE ();
+ }
+ }
+
if (retval == undefined_section)
{
if (SEG_NORMAL (rightseg))
@@ -1600,7 +1707,7 @@ expr (rank, resultP)
&& op_left != O_subtract
#endif
)
- as_bad ("operation combines symbols in different segments");
+ as_bad (_("operation combines symbols in different segments"));
op_right = operator ();
@@ -1615,8 +1722,10 @@ expr (rank, resultP)
if (resultP->X_op == O_big)
{
- as_warn ("left operand is a %s; integer 0 assumed",
- resultP->X_add_number > 0 ? "bignum" : "float");
+ if (resultP->X_add_number > 0)
+ as_warn (_("left operand is a bignum; integer 0 assumed"));
+ else
+ as_warn (_("left operand is a float; integer 0 assumed"));
resultP->X_op = O_constant;
resultP->X_add_number = 0;
resultP->X_add_symbol = NULL;
@@ -1624,8 +1733,10 @@ expr (rank, resultP)
}
if (right.X_op == O_big)
{
- as_warn ("right operand is a %s; integer 0 assumed",
- right.X_add_number > 0 ? "bignum" : "float");
+ if (right.X_add_number > 0)
+ as_warn (_("right operand is a bignum; integer 0 assumed"));
+ else
+ as_warn (_("right operand is a float; integer 0 assumed"));
right.X_op = O_constant;
right.X_add_number = 0;
right.X_add_symbol = NULL;
@@ -1642,8 +1753,8 @@ expr (rank, resultP)
else if (op_left == O_subtract
&& right.X_op == O_symbol
&& resultP->X_op == O_symbol
- && (right.X_add_symbol->sy_frag
- == resultP->X_add_symbol->sy_frag)
+ && (symbol_get_frag (right.X_add_symbol)
+ == symbol_get_frag (resultP->X_add_symbol))
&& SEG_NORMAL (S_GET_SEGMENT (right.X_add_symbol)))
{
@@ -1673,7 +1784,7 @@ expr (rank, resultP)
offsetT v = right.X_add_number;
if (v == 0 && (op_left == O_divide || op_left == O_modulus))
{
- as_warn ("division by zero");
+ as_warn (_("division by zero"));
v = 1;
}
switch (op_left)
@@ -1757,7 +1868,7 @@ expr (rank, resultP)
/* The PA port needs this information. */
if (resultP->X_add_symbol)
- resultP->X_add_symbol->sy_used = 1;
+ symbol_mark_used (resultP->X_add_symbol);
return resultP->X_op == O_constant ? absolute_section : retval;
}
@@ -1785,9 +1896,13 @@ get_symbol_end ()
/* We accept \001 in a name in case this is being called with a
constructed string. */
if (is_name_beginner (c = *input_line_pointer++) || c == '\001')
- while (is_part_of_name (c = *input_line_pointer++)
- || c == '\001')
- ;
+ {
+ while (is_part_of_name (c = *input_line_pointer++)
+ || c == '\001')
+ ;
+ if (is_name_ender (c))
+ c = *input_line_pointer++;
+ }
*--input_line_pointer = 0;
return (c);
}
OpenPOWER on IntegriCloud