* 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:
Doug Evans 1998-03-25 22:03:19 +00:00
parent 8d0bd9889c
commit e5d62150f3
2 changed files with 171 additions and 15 deletions

View file

@ -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.

View file

@ -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. */