* 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
2 changed files with 171 additions and 15 deletions
|
@ -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>
|
||||
|
||||
* 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-
|
||||
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.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
#include "as.h"
|
||||
#include "obstack.h"
|
||||
|
@ -121,6 +122,62 @@ expr_symbol_where (sym, pfile, pline)
|
|||
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.
|
||||
* Also build any bignum literal here.
|
||||
|
@ -171,6 +228,32 @@ floating_constant (expressionP)
|
|||
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
|
||||
integer_constant (radix, expressionP)
|
||||
int radix;
|
||||
|
@ -286,7 +369,83 @@ integer_constant (radix, expressionP)
|
|||
/* c contains character after number. */
|
||||
/* input_line_pointer->char after c. */
|
||||
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.
|
||||
|
@ -331,24 +490,14 @@ integer_constant (radix, expressionP)
|
|||
if (leader < generic_bignum + 2)
|
||||
{
|
||||
/* will fit into 32 bits. */
|
||||
number =
|
||||
((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
|
||||
| (generic_bignum[0] & LITTLENUM_MASK);
|
||||
number &= 0xffffffff
|
||||
number = generic_bignum_to_int32 ();
|
||||
small = 1;
|
||||
}
|
||||
#ifdef BFD64
|
||||
else if (leader < generic_bignum + 4)
|
||||
{
|
||||
/* Will fit into 64 bits. */
|
||||
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));
|
||||
number = generic_bignum_to_int64 ();
|
||||
small = 1;
|
||||
}
|
||||
#endif
|
||||
|
@ -1395,7 +1544,7 @@ operator ()
|
|||
}
|
||||
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse an expression. */
|
||||
|
||||
|
|
Loading…
Reference in a new issue