#include "obstack.h"
+static void floating_constant PARAMS ((expressionS * expressionP));
+static void integer_constant PARAMS ((int radix, expressionS * expressionP));
static void clean_up_expression PARAMS ((expressionS * expressionP));
static symbolS *make_expr_symbol PARAMS ((expressionS * expressionP));
/* FIXME: This should be something which decode_local_label_name
will handle. */
-#ifdef DOT_LABEL_PREFIX
- fake = ".L0\001";
-#else
- fake = "L0\001";
-#endif
+ 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
FLONUM_TYPE generic_floating_point_number =
{
&generic_bignum[6], /* low (JF: Was 0) */
- &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1], /* high JF: (added +6) */
+ &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1], /* high JF: (added +6) */
0, /* leader */
0, /* exponent */
0 /* sign */
/* If nonzero, we've been asked to assemble nan, +inf or -inf */
int generic_floating_point_magic;
\f
-void
+static void
floating_constant (expressionP)
expressionS *expressionP;
{
/* floating-point constant. */
int error_code;
- error_code = atof_generic
- (&input_line_pointer, ".", EXP_CHARS,
- &generic_floating_point_number);
+ error_code = atof_generic (&input_line_pointer, ".", EXP_CHARS,
+ &generic_floating_point_number);
if (error_code)
{
expressionP->X_add_number = -1;
}
-void
+static void
integer_constant (radix, expressionP)
int radix;
expressionS *expressionP;
{
- char *digit_2; /*->2nd digit of number. */
+ char *start; /* start of number. */
char c;
valueT number; /* offset or (absolute) value */
number we are looking for is expected to be positive, but if it
fits into 32 bits as an unsigned number, we let it be a 32-bit
number. The cavalier approach is for speed in ordinary cases. */
+ /* This has been extended for 64 bits. We blindly assume that if
+ you're compiling in 64-bit mode, the target is a 64-bit machine.
+ This should be cleaned up. */
+
+#ifdef BFD64
+#define valuesize 64
+#else /* includes non-bfd case, mostly */
+#define valuesize 32
+#endif
switch (radix)
{
-
case 2:
maxdig = 2;
- too_many_digits = 33;
+ too_many_digits = valuesize + 1;
break;
case 8:
maxdig = radix = 8;
- too_many_digits = 11;
+ too_many_digits = (valuesize + 2) / 3 + 1;
break;
case 16:
-
-
maxdig = radix = 16;
- too_many_digits = 9;
+ too_many_digits = (valuesize + 3) / 4 + 1;
break;
case 10:
maxdig = radix = 10;
- too_many_digits = 11;
+ too_many_digits = (valuesize + 12) / 4; /* very rough */
}
- c = *input_line_pointer;
- input_line_pointer++;
- digit_2 = input_line_pointer;
- for (number = 0; (digit = hex_value[c]) < maxdig; c = *input_line_pointer++)
+#undef valuesize
+ start = input_line_pointer;
+ c = *input_line_pointer++;
+ for (number = 0;
+ (digit = hex_value[(unsigned char) c]) < maxdig;
+ c = *input_line_pointer++)
{
number = number * radix + digit;
}
/* c contains character after number. */
/* input_line_pointer->char after c. */
- small = input_line_pointer - digit_2 < too_many_digits;
+ small = (input_line_pointer - start - 1) < too_many_digits;
if (!small)
{
/*
leader = generic_bignum;
generic_bignum[0] = 0;
generic_bignum[1] = 0;
- /* we could just use digit_2, but lets be mnemonic. */
- input_line_pointer = --digit_2; /*->1st digit. */
+ input_line_pointer = start; /*->1st digit. */
c = *input_line_pointer++;
- for (; (carry = hex_value[c]) < maxdig; c = *input_line_pointer++)
+ for (;
+ (carry = hex_value[(unsigned char) c]) < maxdig;
+ c = *input_line_pointer++)
{
for (pointer = generic_bignum;
pointer <= leader;
if (carry)
{
if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1)
- { /* room to grow a longer bignum. */
+ {
+ /* room to grow a longer bignum. */
*++leader = carry;
}
}
}
/* again, c is char after number, */
/* input_line_pointer->after c. */
- know (sizeof (int) * 8 == 32);
know (LITTLENUM_NUMBER_OF_BITS == 16);
- /* hence the constant "2" in the next line. */
if (leader < generic_bignum + 2)
- { /* will fit into 32 bits. */
+ {
+ /* will fit into 32 bits. */
number =
((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
| (generic_bignum[0] & LITTLENUM_MASK);
then this is a fresh instantiation of that number, so create
it. */
- if (dollar_label_defined (number))
+ if (dollar_label_defined ((long) number))
{
- name = dollar_label_name (number, 0);
+ name = dollar_label_name ((long) number, 0);
symbolP = symbol_find (name);
know (symbolP != NULL);
}
else
{
- name = dollar_label_name (number, 1);
+ name = dollar_label_name ((long) number, 1);
symbolP = symbol_find_or_make (name);
}
} /* switch on char following the number */
-
}
else
{
/* not a small number */
expressionP->X_op = O_big;
- expressionP->X_add_number = number;
+ expressionP->X_add_number = number; /* number of littlenums */
input_line_pointer--; /*->char following number. */
}
-} /* integer_constant() */
+}
/*
char c;
symbolS *symbolP; /* points to symbol */
char *name; /* points to name of symbol */
- segT retval = absolute_section;
+ segT segment;
+
+ /* All integers are regarded as unsigned unless they are negated.
+ This is because the only thing which cares whether a number is
+ unsigned is the code in emit_expr which extends constants into
+ bignums. It should only sign extend negative numbers, so that
+ something like ``.quad 0x80000000'' is not sign extended even
+ though it appears negative if valueT is 32 bits. */
+ expressionP->X_unsigned = 1;
/* digits, assume it is a bignum. */
{
input_line_pointer++;
floating_constant (expressionP);
+ expressionP->X_add_number = -(isupper (c) ? tolower (c) : c);
}
else
{
case 'b':
#ifdef LOCAL_LABELS_FB
- /* FIXME: This seems to be nonsense. At this point we know
- for sure that *input_line_pointer is 'b'. So why are we
- checking it? What is this code supposed to do? */
- if (!*input_line_pointer
- || (!strchr ("+-.0123456789", *input_line_pointer)
- && !strchr (EXP_CHARS, *input_line_pointer)))
+ if (!input_line_pointer[1]
+ /* Strictly speaking, we should only need to check for
+ "+-01", since that's all you'd normally have in a
+ binary constant. But some of our code does permit
+ digits greater than the base we're expecting. */
+ || !strchr ("+-0123456789", input_line_pointer[1]))
{
input_line_pointer--;
integer_constant (10, expressionP);
/* if it says '0f' and the line ends or it doesn't look like
a floating point #, its a local label ref. dtrt */
/* likewise for the b's. xoxorich. */
- /* FIXME: As in the 'b' case, we know that the
- *input_line_pointer is 'f'. What is this code really
- trying to do? */
if (c == 'f'
- && (!*input_line_pointer ||
- (!strchr ("+-.0123456789", *input_line_pointer) &&
- !strchr (EXP_CHARS, *input_line_pointer))))
+ && (!input_line_pointer[1]
+ || (!strchr ("+-.0123456789", input_line_pointer[1])
+ && !strchr (EXP_CHARS, input_line_pointer[1]))))
{
input_line_pointer -= 1;
integer_constant (10, expressionP);
case '(':
/* didn't begin with digit & not a name */
- retval = expression (expressionP);
+ segment = expression (expressionP);
/* Expression() will pass trailing whitespace */
if (*input_line_pointer++ != ')')
{
input_line_pointer--;
}
/* here with input_line_pointer->char after "(...)" */
- return retval;
+ return segment;
case '\'':
/* Warning: to conform to other people's assemblers NO ESCAPEMENT is
break;
case '+':
- retval = operand (expressionP);
+ (void) operand (expressionP);
break;
case '~':
case '-':
{
- /* When computing - foo, ignore the segment of foo. It has
- nothing to do with the segment of the result, which is
- ill-defined. */
operand (expressionP);
if (expressionP->X_op == O_constant)
{
expressionP->X_add_number = - expressionP->X_add_number;
/* Notice: '-' may overflow: no warning is given. This is
compatible with other people's assemblers. Sigh. */
+ expressionP->X_unsigned = 0;
}
else
expressionP->X_add_number = ~ expressionP->X_add_number;
/* JF: '.' is pseudo symbol with value of current location
in current segment. */
-#ifdef DOT_LABEL_PREFIX
- fake = ".L0\001";
-#else
- fake = "L0\001";
-#endif
+ fake = FAKE_LABEL_NAME;
symbolP = symbol_new (fake,
now_seg,
(valueT) frag_now_fix (),
expressionP->X_op = O_symbol;
expressionP->X_add_symbol = symbolP;
expressionP->X_add_number = 0;
- retval = now_seg;
break;
}
else
break;
default:
- if (is_end_of_line[c])
+ if (is_end_of_line[(unsigned char) c])
goto eol;
if (is_name_beginner (c)) /* here if did not begin with a digit */
{
/* If we have an absolute symbol or a reg, then we know its
value now. */
- retval = S_GET_SEGMENT (symbolP);
- if (retval == absolute_section)
+ segment = S_GET_SEGMENT (symbolP);
+ if (segment == absolute_section)
{
expressionP->X_op = O_constant;
expressionP->X_add_number = S_GET_VALUE (symbolP);
}
- else if (retval == reg_section)
+ else if (segment == reg_section)
{
expressionP->X_op = O_register;
expressionP->X_add_number = S_GET_VALUE (symbolP);
clean_up_expression (expressionP);
SKIP_WHITESPACE (); /*->1st char after operand. */
know (*input_line_pointer != ' ');
- return expressionP->X_op == O_constant ? absolute_section : retval;
+
+ /* The PA port needs this information. */
+ if (expressionP->X_add_symbol)
+ expressionP->X_add_symbol->sy_used = 1;
+
+ switch (expressionP->X_op)
+ {
+ default:
+ return absolute_section;
+ case O_symbol:
+ return S_GET_SEGMENT (expressionP->X_add_symbol);
+ case O_register:
+ return reg_section;
+ }
} /* operand() */
\f
/* Internal. Simplify a struct expression for use by expr() */
know (*input_line_pointer != ' '); /* Operand() gobbles spaces. */
c_left = *input_line_pointer; /* Potential operator character. */
- op_left = op_encoding[c_left];
+ op_left = op_encoding[(unsigned char) c_left];
while (op_left != O_illegal && op_rank[(int) op_left] > rank)
{
segT rightseg;
as_warn ("missing operand; zero assumed");
right.X_op = O_constant;
right.X_add_number = 0;
- resultP->X_add_symbol = NULL;
- resultP->X_op_symbol = NULL;
+ right.X_add_symbol = NULL;
+ right.X_op_symbol = NULL;
}
know (*input_line_pointer != ' ');
- if (! SEG_NORMAL (retval))
+ if (retval == undefined_section)
+ {
+ if (SEG_NORMAL (rightseg))
+ retval = rightseg;
+ }
+ else if (! SEG_NORMAL (retval))
retval = rightseg;
else if (SEG_NORMAL (rightseg)
- && retval != rightseg)
+ && retval != rightseg
+#ifdef DIFF_EXPR_OK
+ && op_left != O_subtract
+#endif
+ )
as_bad ("operation combines symbols in different segments");
c_right = *input_line_pointer;
- op_right = op_encoding[c_right];
+ op_right = op_encoding[(unsigned char) c_right];
if (*input_line_pointer == c_right && (c_right == '<' || c_right == '>'))
++input_line_pointer;
resultP->X_op_symbol = make_expr_symbol (&right);
resultP->X_op = op_left;
resultP->X_add_number = 0;
+ resultP->X_unsigned = 1;
}
-
+
op_left = op_right;
} /* While next operator is >= this rank. */
+ /* The PA port needs this information. */
+ if (resultP->X_add_symbol)
+ resultP->X_add_symbol->sy_used = 1;
+
return resultP->X_op == O_constant ? absolute_section : retval;
}
\f
}
-unsigned int
+unsigned int
get_single_number ()
{
expressionS exp;