* expr.h (expr_build_uconstant): Add prototype.
(expr_build_unary,expr_build_binary): Add prototypes. * expr.c (expr_build_uconstant): New function. (expr_build_unary,expr_build_binary): New functions.
This commit is contained in:
parent
8d0bd9889c
commit
e5d62150f3
|
@ -1,3 +1,10 @@
|
||||||
|
Wed Mar 25 13:44:18 1998 Doug Evans <devans@canuck.cygnus.com>
|
||||||
|
|
||||||
|
* expr.h (expr_build_uconstant): Add prototype.
|
||||||
|
(expr_build_unary,expr_build_binary): Add prototypes.
|
||||||
|
* expr.c (expr_build_uconstant): New function.
|
||||||
|
(expr_build_unary,expr_build_binary): New functions.
|
||||||
|
|
||||||
Wed Mar 25 13:10:42 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
|
Wed Mar 25 13:10:42 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
|
||||||
|
|
||||||
* gasp.c (IS*): Cast argument to unsigned char, not unsigned int.
|
* gasp.c (IS*): Cast argument to unsigned char, not unsigned int.
|
||||||
|
|
179
gas/expr.c
179
gas/expr.c
|
@ -1,5 +1,5 @@
|
||||||
/* expr.c -operands, expressions-
|
/* expr.c -operands, expressions-
|
||||||
Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 1997
|
Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 1997, 1998
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is part of GAS, the GNU Assembler.
|
This file is part of GAS, the GNU Assembler.
|
||||||
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
#include "as.h"
|
#include "as.h"
|
||||||
#include "obstack.h"
|
#include "obstack.h"
|
||||||
|
@ -121,6 +122,62 @@ expr_symbol_where (sym, pfile, pline)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Utilities for building expressions.
|
||||||
|
Since complex expressions are recorded as symbols for use in other
|
||||||
|
expressions these return a symbolS * and not an expressionS *.
|
||||||
|
These explicitly do not take an "add_number" argument. */
|
||||||
|
/* ??? For completeness' sake one might want expr_build_symbol.
|
||||||
|
It would just return its argument. */
|
||||||
|
|
||||||
|
/* Build an expression for an unsigned constant.
|
||||||
|
The corresponding one for signed constants is missing because
|
||||||
|
there's currently no need for it. One could add an unsigned_p flag
|
||||||
|
but that seems more clumsy. */
|
||||||
|
|
||||||
|
symbolS *
|
||||||
|
expr_build_uconstant (value)
|
||||||
|
offsetT value;
|
||||||
|
{
|
||||||
|
expressionS e;
|
||||||
|
|
||||||
|
e.X_op = O_constant;
|
||||||
|
e.X_add_number = value;
|
||||||
|
e.X_unsigned = 1;
|
||||||
|
return make_expr_symbol (&e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build an expression for OP s1. */
|
||||||
|
|
||||||
|
symbolS *
|
||||||
|
expr_build_unary (op, s1)
|
||||||
|
operatorT op;
|
||||||
|
symbolS *s1;
|
||||||
|
{
|
||||||
|
expressionS e;
|
||||||
|
|
||||||
|
e.X_op = op;
|
||||||
|
e.X_add_symbol = s1;
|
||||||
|
e.X_add_number = 0;
|
||||||
|
return make_expr_symbol (&e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build an expression for s1 OP s2. */
|
||||||
|
|
||||||
|
symbolS *
|
||||||
|
expr_build_binary (op, s1, s2)
|
||||||
|
operatorT op;
|
||||||
|
symbolS *s1;
|
||||||
|
symbolS *s2;
|
||||||
|
{
|
||||||
|
expressionS e;
|
||||||
|
|
||||||
|
e.X_op = op;
|
||||||
|
e.X_add_symbol = s1;
|
||||||
|
e.X_op_symbol = s2;
|
||||||
|
e.X_add_number = 0;
|
||||||
|
return make_expr_symbol (&e);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build any floating-point literal here.
|
* Build any floating-point literal here.
|
||||||
* Also build any bignum literal here.
|
* Also build any bignum literal here.
|
||||||
|
@ -171,6 +228,32 @@ floating_constant (expressionP)
|
||||||
expressionP->X_add_number = -1;
|
expressionP->X_add_number = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static valueT
|
||||||
|
generic_bignum_to_int32 ()
|
||||||
|
{
|
||||||
|
valueT number =
|
||||||
|
((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
|
||||||
|
| (generic_bignum[0] & LITTLENUM_MASK);
|
||||||
|
number &= 0xffffffff;
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BFD64
|
||||||
|
static valueT
|
||||||
|
generic_bignum_to_int64 ()
|
||||||
|
{
|
||||||
|
valueT number =
|
||||||
|
((((((((valueT) generic_bignum[3] & LITTLENUM_MASK)
|
||||||
|
<< LITTLENUM_NUMBER_OF_BITS)
|
||||||
|
| ((valueT) generic_bignum[2] & LITTLENUM_MASK))
|
||||||
|
<< LITTLENUM_NUMBER_OF_BITS)
|
||||||
|
| ((valueT) generic_bignum[1] & LITTLENUM_MASK))
|
||||||
|
<< LITTLENUM_NUMBER_OF_BITS)
|
||||||
|
| ((valueT) generic_bignum[0] & LITTLENUM_MASK));
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
integer_constant (radix, expressionP)
|
integer_constant (radix, expressionP)
|
||||||
int radix;
|
int radix;
|
||||||
|
@ -286,7 +369,83 @@ integer_constant (radix, expressionP)
|
||||||
/* c contains character after number. */
|
/* c contains character after number. */
|
||||||
/* input_line_pointer->char after c. */
|
/* input_line_pointer->char after c. */
|
||||||
small = (input_line_pointer - start - 1) < too_many_digits;
|
small = (input_line_pointer - start - 1) < too_many_digits;
|
||||||
if (!small)
|
|
||||||
|
if (radix == 16 && c == '_')
|
||||||
|
{
|
||||||
|
/* This is literal of the form 0x333_0_12345678_1.
|
||||||
|
This example is equivalent to 0x00000333000000001234567800000001. */
|
||||||
|
|
||||||
|
int num_little_digits = 0;
|
||||||
|
int i;
|
||||||
|
input_line_pointer = start; /*->1st digit. */
|
||||||
|
|
||||||
|
know (LITTLENUM_NUMBER_OF_BITS == 16);
|
||||||
|
|
||||||
|
for (c = '_'; c == '_'; num_little_digits+=2)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Convert one 64-bit word. */
|
||||||
|
int ndigit = 0;
|
||||||
|
number = 0;
|
||||||
|
for (c = *input_line_pointer++;
|
||||||
|
(digit = hex_value (c)) < maxdig;
|
||||||
|
c = *(input_line_pointer++))
|
||||||
|
{
|
||||||
|
number = number * radix + digit;
|
||||||
|
ndigit++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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.");
|
||||||
|
|
||||||
|
/* Add this chunk to the bignum. Shift things down 2 little digits.*/
|
||||||
|
know (LITTLENUM_NUMBER_OF_BITS == 16);
|
||||||
|
for (i = min (num_little_digits + 1, SIZE_OF_LARGE_NUMBER - 1); i >= 2; i--)
|
||||||
|
generic_bignum[i] = generic_bignum[i-2];
|
||||||
|
|
||||||
|
/* Add the new digits as the least significant new ones. */
|
||||||
|
generic_bignum[0] = number & 0xffffffff;
|
||||||
|
generic_bignum[1] = number >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Again, c is char after number, input_line_pointer->after c. */
|
||||||
|
|
||||||
|
if (num_little_digits > SIZE_OF_LARGE_NUMBER - 1)
|
||||||
|
num_little_digits = SIZE_OF_LARGE_NUMBER - 1;
|
||||||
|
|
||||||
|
assert (num_little_digits >= 4);
|
||||||
|
|
||||||
|
if (num_little_digits != 8)
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
while (generic_bignum[num_little_digits-1] == 0 && num_little_digits > 1)
|
||||||
|
num_little_digits--;
|
||||||
|
|
||||||
|
if (num_little_digits <= 2)
|
||||||
|
{
|
||||||
|
/* will fit into 32 bits. */
|
||||||
|
number = generic_bignum_to_int32 ();
|
||||||
|
small = 1;
|
||||||
|
}
|
||||||
|
#ifdef BFD64
|
||||||
|
else if (num_little_digits <= 4)
|
||||||
|
{
|
||||||
|
/* Will fit into 64 bits. */
|
||||||
|
number = generic_bignum_to_int64 ();
|
||||||
|
small = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
{
|
||||||
|
small = 0;
|
||||||
|
number = num_little_digits; /* number of littlenums in the bignum. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!small)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* we saw a lot of digits. manufacture a bignum the hard way.
|
* we saw a lot of digits. manufacture a bignum the hard way.
|
||||||
|
@ -331,24 +490,14 @@ integer_constant (radix, expressionP)
|
||||||
if (leader < generic_bignum + 2)
|
if (leader < generic_bignum + 2)
|
||||||
{
|
{
|
||||||
/* will fit into 32 bits. */
|
/* will fit into 32 bits. */
|
||||||
number =
|
number = generic_bignum_to_int32 ();
|
||||||
((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
|
|
||||||
| (generic_bignum[0] & LITTLENUM_MASK);
|
|
||||||
number &= 0xffffffff
|
|
||||||
small = 1;
|
small = 1;
|
||||||
}
|
}
|
||||||
#ifdef BFD64
|
#ifdef BFD64
|
||||||
else if (leader < generic_bignum + 4)
|
else if (leader < generic_bignum + 4)
|
||||||
{
|
{
|
||||||
/* Will fit into 64 bits. */
|
/* Will fit into 64 bits. */
|
||||||
number =
|
number = generic_bignum_to_int64 ();
|
||||||
((((((((valueT) generic_bignum[3] & LITTLENUM_MASK)
|
|
||||||
<< LITTLENUM_NUMBER_OF_BITS)
|
|
||||||
| ((valueT) generic_bignum[2] & LITTLENUM_MASK))
|
|
||||||
<< LITTLENUM_NUMBER_OF_BITS)
|
|
||||||
| ((valueT) generic_bignum[1] & LITTLENUM_MASK))
|
|
||||||
<< LITTLENUM_NUMBER_OF_BITS)
|
|
||||||
| ((valueT) generic_bignum[0] & LITTLENUM_MASK));
|
|
||||||
small = 1;
|
small = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1395,7 +1544,7 @@ operator ()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parse an expression. */
|
/* Parse an expression. */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue