133965Sjdp/* expr.c -operands, expressions-
278828Sobrien   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3218822Sdim   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
433965Sjdp   Free Software Foundation, Inc.
533965Sjdp
633965Sjdp   This file is part of GAS, the GNU Assembler.
733965Sjdp
833965Sjdp   GAS is free software; you can redistribute it and/or modify
933965Sjdp   it under the terms of the GNU General Public License as published by
1033965Sjdp   the Free Software Foundation; either version 2, or (at your option)
1133965Sjdp   any later version.
1233965Sjdp
1333965Sjdp   GAS is distributed in the hope that it will be useful,
1433965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1533965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1633965Sjdp   GNU General Public License for more details.
1733965Sjdp
1833965Sjdp   You should have received a copy of the GNU General Public License
1933965Sjdp   along with GAS; see the file COPYING.  If not, write to the Free
20218822Sdim   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21218822Sdim   02110-1301, USA.  */
2233965Sjdp
2377298Sobrien/* This is really a branch office of as-read.c. I split it out to clearly
2477298Sobrien   distinguish the world of expressions from the world of statements.
2577298Sobrien   (It also gives smaller files to re-compile.)
2677298Sobrien   Here, "operand"s are of expressions, not instructions.  */
2733965Sjdp
2838889Sjdp#define min(a, b)       ((a) < (b) ? (a) : (b))
2933965Sjdp
3033965Sjdp#include "as.h"
3189857Sobrien#include "safe-ctype.h"
3233965Sjdp#include "obstack.h"
3333965Sjdp
34130561Sobrienstatic void floating_constant (expressionS * expressionP);
35130561Sobrienstatic valueT generic_bignum_to_int32 (void);
3660484Sobrien#ifdef BFD64
37130561Sobrienstatic valueT generic_bignum_to_int64 (void);
3860484Sobrien#endif
39130561Sobrienstatic void integer_constant (int radix, expressionS * expressionP);
40130561Sobrienstatic void mri_char_constant (expressionS *);
41130561Sobrienstatic void current_location (expressionS *);
42130561Sobrienstatic void clean_up_expression (expressionS * expressionP);
43218822Sdimstatic segT operand (expressionS *, enum expr_mode);
44130561Sobrienstatic operatorT operator (int *);
4533965Sjdp
4633965Sjdpextern const char EXP_CHARS[], FLT_CHARS[];
4733965Sjdp
4833965Sjdp/* We keep a mapping of expression symbols to file positions, so that
4933965Sjdp   we can provide better error messages.  */
5033965Sjdp
5177298Sobrienstruct expr_symbol_line {
5233965Sjdp  struct expr_symbol_line *next;
5333965Sjdp  symbolS *sym;
5433965Sjdp  char *file;
5533965Sjdp  unsigned int line;
5633965Sjdp};
5733965Sjdp
5833965Sjdpstatic struct expr_symbol_line *expr_symbol_lines;
5933965Sjdp
6033965Sjdp/* Build a dummy symbol to hold a complex expression.  This is how we
6133965Sjdp   build expressions up out of other expressions.  The symbol is put
6233965Sjdp   into the fake section expr_section.  */
6333965Sjdp
6433965SjdpsymbolS *
65130561Sobrienmake_expr_symbol (expressionS *expressionP)
6633965Sjdp{
6760484Sobrien  expressionS zero;
6833965Sjdp  symbolS *symbolP;
6933965Sjdp  struct expr_symbol_line *n;
7033965Sjdp
7133965Sjdp  if (expressionP->X_op == O_symbol
7233965Sjdp      && expressionP->X_add_number == 0)
7333965Sjdp    return expressionP->X_add_symbol;
7433965Sjdp
7560484Sobrien  if (expressionP->X_op == O_big)
7660484Sobrien    {
7760484Sobrien      /* This won't work, because the actual value is stored in
78130561Sobrien	 generic_floating_point_number or generic_bignum, and we are
79130561Sobrien	 going to lose it if we haven't already.  */
8060484Sobrien      if (expressionP->X_add_number > 0)
8189857Sobrien	as_bad (_("bignum invalid"));
8260484Sobrien      else
8389857Sobrien	as_bad (_("floating point number invalid"));
8460484Sobrien      zero.X_op = O_constant;
8560484Sobrien      zero.X_add_number = 0;
8660484Sobrien      zero.X_unsigned = 0;
8760484Sobrien      clean_up_expression (&zero);
8860484Sobrien      expressionP = &zero;
8960484Sobrien    }
9060484Sobrien
9133965Sjdp  /* Putting constant symbols in absolute_section rather than
9233965Sjdp     expr_section is convenient for the old a.out code, for which
9333965Sjdp     S_GET_SEGMENT does not always retrieve the value put in by
9433965Sjdp     S_SET_SEGMENT.  */
95130561Sobrien  symbolP = symbol_create (FAKE_LABEL_NAME,
9633965Sjdp			   (expressionP->X_op == O_constant
9733965Sjdp			    ? absolute_section
9833965Sjdp			    : expr_section),
9933965Sjdp			   0, &zero_address_frag);
10060484Sobrien  symbol_set_value_expression (symbolP, expressionP);
10133965Sjdp
10233965Sjdp  if (expressionP->X_op == O_constant)
10389857Sobrien    resolve_symbol_value (symbolP);
10433965Sjdp
10533965Sjdp  n = (struct expr_symbol_line *) xmalloc (sizeof *n);
10633965Sjdp  n->sym = symbolP;
10733965Sjdp  as_where (&n->file, &n->line);
10833965Sjdp  n->next = expr_symbol_lines;
10933965Sjdp  expr_symbol_lines = n;
11033965Sjdp
11133965Sjdp  return symbolP;
11233965Sjdp}
11333965Sjdp
11433965Sjdp/* Return the file and line number for an expr symbol.  Return
11533965Sjdp   non-zero if something was found, 0 if no information is known for
11633965Sjdp   the symbol.  */
11733965Sjdp
11833965Sjdpint
119130561Sobrienexpr_symbol_where (symbolS *sym, char **pfile, unsigned int *pline)
12033965Sjdp{
12133965Sjdp  register struct expr_symbol_line *l;
12233965Sjdp
12333965Sjdp  for (l = expr_symbol_lines; l != NULL; l = l->next)
12433965Sjdp    {
12533965Sjdp      if (l->sym == sym)
12633965Sjdp	{
12733965Sjdp	  *pfile = l->file;
12833965Sjdp	  *pline = l->line;
12933965Sjdp	  return 1;
13033965Sjdp	}
13133965Sjdp    }
13233965Sjdp
13333965Sjdp  return 0;
13433965Sjdp}
13533965Sjdp
13638889Sjdp/* Utilities for building expressions.
13738889Sjdp   Since complex expressions are recorded as symbols for use in other
13838889Sjdp   expressions these return a symbolS * and not an expressionS *.
13938889Sjdp   These explicitly do not take an "add_number" argument.  */
14038889Sjdp/* ??? For completeness' sake one might want expr_build_symbol.
14138889Sjdp   It would just return its argument.  */
14238889Sjdp
14338889Sjdp/* Build an expression for an unsigned constant.
14438889Sjdp   The corresponding one for signed constants is missing because
14538889Sjdp   there's currently no need for it.  One could add an unsigned_p flag
14638889Sjdp   but that seems more clumsy.  */
14738889Sjdp
14838889SjdpsymbolS *
149130561Sobrienexpr_build_uconstant (offsetT value)
15038889Sjdp{
15138889Sjdp  expressionS e;
15238889Sjdp
15338889Sjdp  e.X_op = O_constant;
15438889Sjdp  e.X_add_number = value;
15538889Sjdp  e.X_unsigned = 1;
15638889Sjdp  return make_expr_symbol (&e);
15738889Sjdp}
15838889Sjdp
15960484Sobrien/* Build an expression for the current location ('.').  */
16060484Sobrien
16160484SobriensymbolS *
162130561Sobrienexpr_build_dot (void)
16360484Sobrien{
16460484Sobrien  expressionS e;
16560484Sobrien
16660484Sobrien  current_location (&e);
16760484Sobrien  return make_expr_symbol (&e);
16860484Sobrien}
16938889Sjdp
17077298Sobrien/* Build any floating-point literal here.
17177298Sobrien   Also build any bignum literal here.  */
17233965Sjdp
17333965Sjdp/* Seems atof_machine can backscan through generic_bignum and hit whatever
17433965Sjdp   happens to be loaded before it in memory.  And its way too complicated
17533965Sjdp   for me to fix right.  Thus a hack.  JF:  Just make generic_bignum bigger,
17633965Sjdp   and never write into the early words, thus they'll always be zero.
17733965Sjdp   I hate Dean's floating-point code.  Bleh.  */
17833965SjdpLITTLENUM_TYPE generic_bignum[SIZE_OF_LARGE_NUMBER + 6];
17977298Sobrien
18077298SobrienFLONUM_TYPE generic_floating_point_number = {
18177298Sobrien  &generic_bignum[6],		/* low.  (JF: Was 0)  */
18277298Sobrien  &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1], /* high.  JF: (added +6)  */
18377298Sobrien  0,				/* leader.  */
18477298Sobrien  0,				/* exponent.  */
18577298Sobrien  0				/* sign.  */
18633965Sjdp};
18777298Sobrien
18833965Sjdp
18933965Sjdpstatic void
190130561Sobrienfloating_constant (expressionS *expressionP)
19133965Sjdp{
19277298Sobrien  /* input_line_pointer -> floating-point constant.  */
19333965Sjdp  int error_code;
19433965Sjdp
19533965Sjdp  error_code = atof_generic (&input_line_pointer, ".", EXP_CHARS,
19633965Sjdp			     &generic_floating_point_number);
19733965Sjdp
19833965Sjdp  if (error_code)
19933965Sjdp    {
20033965Sjdp      if (error_code == ERROR_EXPONENT_OVERFLOW)
20133965Sjdp	{
20289857Sobrien	  as_bad (_("bad floating-point constant: exponent overflow"));
20333965Sjdp	}
20433965Sjdp      else
20533965Sjdp	{
20689857Sobrien	  as_bad (_("bad floating-point constant: unknown error code=%d"),
20789857Sobrien		  error_code);
20833965Sjdp	}
20933965Sjdp    }
21033965Sjdp  expressionP->X_op = O_big;
21177298Sobrien  /* input_line_pointer -> just after constant, which may point to
21277298Sobrien     whitespace.  */
21333965Sjdp  expressionP->X_add_number = -1;
21433965Sjdp}
21533965Sjdp
21677298Sobrienstatic valueT
217130561Sobriengeneric_bignum_to_int32 (void)
21838889Sjdp{
21938889Sjdp  valueT number =
22038889Sjdp	   ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
22138889Sjdp	   | (generic_bignum[0] & LITTLENUM_MASK);
22238889Sjdp  number &= 0xffffffff;
22338889Sjdp  return number;
22438889Sjdp}
22538889Sjdp
22638889Sjdp#ifdef BFD64
22777298Sobrienstatic valueT
228130561Sobriengeneric_bignum_to_int64 (void)
22938889Sjdp{
23077298Sobrien  valueT number =
23177298Sobrien    ((((((((valueT) generic_bignum[3] & LITTLENUM_MASK)
23277298Sobrien	  << LITTLENUM_NUMBER_OF_BITS)
23377298Sobrien	 | ((valueT) generic_bignum[2] & LITTLENUM_MASK))
23477298Sobrien	<< LITTLENUM_NUMBER_OF_BITS)
23577298Sobrien       | ((valueT) generic_bignum[1] & LITTLENUM_MASK))
23677298Sobrien      << LITTLENUM_NUMBER_OF_BITS)
23777298Sobrien     | ((valueT) generic_bignum[0] & LITTLENUM_MASK));
23838889Sjdp  return number;
23938889Sjdp}
24038889Sjdp#endif
24138889Sjdp
24233965Sjdpstatic void
243130561Sobrieninteger_constant (int radix, expressionS *expressionP)
24433965Sjdp{
24577298Sobrien  char *start;		/* Start of number.  */
24633965Sjdp  char *suffix = NULL;
24733965Sjdp  char c;
24877298Sobrien  valueT number;	/* Offset or (absolute) value.  */
24977298Sobrien  short int digit;	/* Value of next digit in current radix.  */
25077298Sobrien  short int maxdig = 0;	/* Highest permitted digit value.  */
25177298Sobrien  int too_many_digits = 0;	/* If we see >= this number of.  */
25277298Sobrien  char *name;		/* Points to name of symbol.  */
25377298Sobrien  symbolS *symbolP;	/* Points to symbol.  */
25433965Sjdp
25577298Sobrien  int small;			/* True if fits in 32 bits.  */
25633965Sjdp
25777298Sobrien  /* May be bignum, or may fit in 32 bits.  */
25833965Sjdp  /* Most numbers fit into 32 bits, and we want this case to be fast.
25933965Sjdp     so we pretend it will fit into 32 bits.  If, after making up a 32
26033965Sjdp     bit number, we realise that we have scanned more digits than
26133965Sjdp     comfortably fit into 32 bits, we re-scan the digits coding them
26233965Sjdp     into a bignum.  For decimal and octal numbers we are
26333965Sjdp     conservative: Some numbers may be assumed bignums when in fact
26433965Sjdp     they do fit into 32 bits.  Numbers of any radix can have excess
26533965Sjdp     leading zeros: We strive to recognise this and cast them back
26633965Sjdp     into 32 bits.  We must check that the bignum really is more than
26733965Sjdp     32 bits, and change it back to a 32-bit number if it fits.  The
26833965Sjdp     number we are looking for is expected to be positive, but if it
26933965Sjdp     fits into 32 bits as an unsigned number, we let it be a 32-bit
27077298Sobrien     number.  The cavalier approach is for speed in ordinary cases.  */
27133965Sjdp  /* This has been extended for 64 bits.  We blindly assume that if
27233965Sjdp     you're compiling in 64-bit mode, the target is a 64-bit machine.
27333965Sjdp     This should be cleaned up.  */
27433965Sjdp
27533965Sjdp#ifdef BFD64
27633965Sjdp#define valuesize 64
27733965Sjdp#else /* includes non-bfd case, mostly */
27833965Sjdp#define valuesize 32
27933965Sjdp#endif
28033965Sjdp
28160484Sobrien  if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) && radix == 0)
28233965Sjdp    {
28333965Sjdp      int flt = 0;
28433965Sjdp
28533965Sjdp      /* In MRI mode, the number may have a suffix indicating the
286130561Sobrien	 radix.  For that matter, it might actually be a floating
287130561Sobrien	 point constant.  */
28889857Sobrien      for (suffix = input_line_pointer; ISALNUM (*suffix); suffix++)
28933965Sjdp	{
29033965Sjdp	  if (*suffix == 'e' || *suffix == 'E')
29133965Sjdp	    flt = 1;
29233965Sjdp	}
29333965Sjdp
29433965Sjdp      if (suffix == input_line_pointer)
29533965Sjdp	{
29633965Sjdp	  radix = 10;
29733965Sjdp	  suffix = NULL;
29833965Sjdp	}
29933965Sjdp      else
30033965Sjdp	{
30133965Sjdp	  c = *--suffix;
30289857Sobrien	  c = TOUPPER (c);
303218822Sdim	  /* If we have both NUMBERS_WITH_SUFFIX and LOCAL_LABELS_FB,
304218822Sdim	     we distinguish between 'B' and 'b'.  This is the case for
305218822Sdim	     Z80.  */
306218822Sdim	  if ((NUMBERS_WITH_SUFFIX && LOCAL_LABELS_FB ? *suffix : c) == 'B')
30733965Sjdp	    radix = 2;
30833965Sjdp	  else if (c == 'D')
30933965Sjdp	    radix = 10;
31033965Sjdp	  else if (c == 'O' || c == 'Q')
31133965Sjdp	    radix = 8;
31233965Sjdp	  else if (c == 'H')
31333965Sjdp	    radix = 16;
31433965Sjdp	  else if (suffix[1] == '.' || c == 'E' || flt)
31533965Sjdp	    {
31633965Sjdp	      floating_constant (expressionP);
31733965Sjdp	      return;
31833965Sjdp	    }
31933965Sjdp	  else
32033965Sjdp	    {
32133965Sjdp	      radix = 10;
32233965Sjdp	      suffix = NULL;
32333965Sjdp	    }
32433965Sjdp	}
32533965Sjdp    }
32633965Sjdp
32733965Sjdp  switch (radix)
32833965Sjdp    {
32933965Sjdp    case 2:
33033965Sjdp      maxdig = 2;
33133965Sjdp      too_many_digits = valuesize + 1;
33233965Sjdp      break;
33333965Sjdp    case 8:
33433965Sjdp      maxdig = radix = 8;
33533965Sjdp      too_many_digits = (valuesize + 2) / 3 + 1;
33633965Sjdp      break;
33733965Sjdp    case 16:
33833965Sjdp      maxdig = radix = 16;
33933965Sjdp      too_many_digits = (valuesize + 3) / 4 + 1;
34033965Sjdp      break;
34133965Sjdp    case 10:
34233965Sjdp      maxdig = radix = 10;
34377298Sobrien      too_many_digits = (valuesize + 11) / 4; /* Very rough.  */
34433965Sjdp    }
34533965Sjdp#undef valuesize
34633965Sjdp  start = input_line_pointer;
34733965Sjdp  c = *input_line_pointer++;
34833965Sjdp  for (number = 0;
34933965Sjdp       (digit = hex_value (c)) < maxdig;
35033965Sjdp       c = *input_line_pointer++)
35133965Sjdp    {
35233965Sjdp      number = number * radix + digit;
35333965Sjdp    }
35477298Sobrien  /* c contains character after number.  */
35577298Sobrien  /* input_line_pointer->char after c.  */
35633965Sjdp  small = (input_line_pointer - start - 1) < too_many_digits;
35738889Sjdp
35877298Sobrien  if (radix == 16 && c == '_')
35933965Sjdp    {
36038889Sjdp      /* This is literal of the form 0x333_0_12345678_1.
361130561Sobrien	 This example is equivalent to 0x00000333000000001234567800000001.  */
36238889Sjdp
36338889Sjdp      int num_little_digits = 0;
36438889Sjdp      int i;
36577298Sobrien      input_line_pointer = start;	/* -> 1st digit.  */
36638889Sjdp
36738889Sjdp      know (LITTLENUM_NUMBER_OF_BITS == 16);
36838889Sjdp
36977298Sobrien      for (c = '_'; c == '_'; num_little_digits += 2)
37038889Sjdp	{
37138889Sjdp
37277298Sobrien	  /* Convert one 64-bit word.  */
37377298Sobrien	  int ndigit = 0;
37438889Sjdp	  number = 0;
37538889Sjdp	  for (c = *input_line_pointer++;
37638889Sjdp	       (digit = hex_value (c)) < maxdig;
37738889Sjdp	       c = *(input_line_pointer++))
37838889Sjdp	    {
37938889Sjdp	      number = number * radix + digit;
38038889Sjdp	      ndigit++;
38138889Sjdp	    }
38238889Sjdp
38338889Sjdp	  /* Check for 8 digit per word max.  */
38477298Sobrien	  if (ndigit > 8)
38589857Sobrien	    as_bad (_("a bignum with underscores may not have more than 8 hex digits in any word"));
38638889Sjdp
38777298Sobrien	  /* Add this chunk to the bignum.
38877298Sobrien	     Shift things down 2 little digits.  */
38938889Sjdp	  know (LITTLENUM_NUMBER_OF_BITS == 16);
39077298Sobrien	  for (i = min (num_little_digits + 1, SIZE_OF_LARGE_NUMBER - 1);
39177298Sobrien	       i >= 2;
39277298Sobrien	       i--)
39377298Sobrien	    generic_bignum[i] = generic_bignum[i - 2];
39438889Sjdp
39577298Sobrien	  /* Add the new digits as the least significant new ones.  */
39638889Sjdp	  generic_bignum[0] = number & 0xffffffff;
39738889Sjdp	  generic_bignum[1] = number >> 16;
39838889Sjdp	}
39938889Sjdp
40077298Sobrien      /* Again, c is char after number, input_line_pointer->after c.  */
40138889Sjdp
40238889Sjdp      if (num_little_digits > SIZE_OF_LARGE_NUMBER - 1)
40338889Sjdp	num_little_digits = SIZE_OF_LARGE_NUMBER - 1;
40438889Sjdp
40538889Sjdp      assert (num_little_digits >= 4);
40638889Sjdp
40738889Sjdp      if (num_little_digits != 8)
40889857Sobrien	as_bad (_("a bignum with underscores must have exactly 4 words"));
40938889Sjdp
41038889Sjdp      /* We might have some leading zeros.  These can be trimmed to give
41177298Sobrien	 us a change to fit this constant into a small number.  */
41277298Sobrien      while (generic_bignum[num_little_digits - 1] == 0
41377298Sobrien	     && num_little_digits > 1)
41438889Sjdp	num_little_digits--;
41577298Sobrien
41638889Sjdp      if (num_little_digits <= 2)
41738889Sjdp	{
41877298Sobrien	  /* will fit into 32 bits.  */
41938889Sjdp	  number = generic_bignum_to_int32 ();
42038889Sjdp	  small = 1;
42138889Sjdp	}
42238889Sjdp#ifdef BFD64
42338889Sjdp      else if (num_little_digits <= 4)
42438889Sjdp	{
42538889Sjdp	  /* Will fit into 64 bits.  */
42638889Sjdp	  number = generic_bignum_to_int64 ();
42738889Sjdp	  small = 1;
42838889Sjdp	}
42938889Sjdp#endif
43038889Sjdp      else
43138889Sjdp	{
43238889Sjdp	  small = 0;
43377298Sobrien
43477298Sobrien	  /* Number of littlenums in the bignum.  */
43577298Sobrien	  number = num_little_digits;
43638889Sjdp	}
43738889Sjdp    }
43838889Sjdp  else if (!small)
43938889Sjdp    {
44077298Sobrien      /* We saw a lot of digits. manufacture a bignum the hard way.  */
44177298Sobrien      LITTLENUM_TYPE *leader;	/* -> high order littlenum of the bignum.  */
44277298Sobrien      LITTLENUM_TYPE *pointer;	/* -> littlenum we are frobbing now.  */
44333965Sjdp      long carry;
44433965Sjdp
44533965Sjdp      leader = generic_bignum;
44633965Sjdp      generic_bignum[0] = 0;
44733965Sjdp      generic_bignum[1] = 0;
44838889Sjdp      generic_bignum[2] = 0;
44938889Sjdp      generic_bignum[3] = 0;
45077298Sobrien      input_line_pointer = start;	/* -> 1st digit.  */
45133965Sjdp      c = *input_line_pointer++;
45277298Sobrien      for (; (carry = hex_value (c)) < maxdig; c = *input_line_pointer++)
45333965Sjdp	{
45477298Sobrien	  for (pointer = generic_bignum; pointer <= leader; pointer++)
45533965Sjdp	    {
45633965Sjdp	      long work;
45733965Sjdp
45833965Sjdp	      work = carry + radix * *pointer;
45933965Sjdp	      *pointer = work & LITTLENUM_MASK;
46033965Sjdp	      carry = work >> LITTLENUM_NUMBER_OF_BITS;
46133965Sjdp	    }
46233965Sjdp	  if (carry)
46333965Sjdp	    {
46433965Sjdp	      if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1)
46533965Sjdp		{
46677298Sobrien		  /* Room to grow a longer bignum.  */
46733965Sjdp		  *++leader = carry;
46833965Sjdp		}
46933965Sjdp	    }
47033965Sjdp	}
47177298Sobrien      /* Again, c is char after number.  */
47277298Sobrien      /* input_line_pointer -> after c.  */
47333965Sjdp      know (LITTLENUM_NUMBER_OF_BITS == 16);
47433965Sjdp      if (leader < generic_bignum + 2)
47533965Sjdp	{
47677298Sobrien	  /* Will fit into 32 bits.  */
47738889Sjdp	  number = generic_bignum_to_int32 ();
47833965Sjdp	  small = 1;
47933965Sjdp	}
48038889Sjdp#ifdef BFD64
48138889Sjdp      else if (leader < generic_bignum + 4)
48238889Sjdp	{
48338889Sjdp	  /* Will fit into 64 bits.  */
48438889Sjdp	  number = generic_bignum_to_int64 ();
48538889Sjdp	  small = 1;
48638889Sjdp	}
48738889Sjdp#endif
48833965Sjdp      else
48933965Sjdp	{
49077298Sobrien	  /* Number of littlenums in the bignum.  */
49177298Sobrien	  number = leader - generic_bignum + 1;
49233965Sjdp	}
49333965Sjdp    }
49433965Sjdp
49577298Sobrien  if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri)
49677298Sobrien      && suffix != NULL
49760484Sobrien      && input_line_pointer - 1 == suffix)
49833965Sjdp    c = *input_line_pointer++;
49933965Sjdp
50033965Sjdp  if (small)
50133965Sjdp    {
50277298Sobrien      /* Here with number, in correct radix. c is the next char.
50377298Sobrien	 Note that unlike un*x, we allow "011f" "0x9f" to both mean
50477298Sobrien	 the same as the (conventional) "9f".
50577298Sobrien	 This is simply easier than checking for strict canonical
50677298Sobrien	 form.  Syntax sux!  */
50733965Sjdp
50833965Sjdp      if (LOCAL_LABELS_FB && c == 'b')
50933965Sjdp	{
51077298Sobrien	  /* Backward ref to local label.
51177298Sobrien	     Because it is backward, expect it to be defined.  */
51233965Sjdp	  /* Construct a local label.  */
51333965Sjdp	  name = fb_label_name ((int) number, 0);
51433965Sjdp
51577298Sobrien	  /* Seen before, or symbol is defined: OK.  */
51633965Sjdp	  symbolP = symbol_find (name);
51733965Sjdp	  if ((symbolP != NULL) && (S_IS_DEFINED (symbolP)))
51833965Sjdp	    {
51977298Sobrien	      /* Local labels are never absolute.  Don't waste time
52077298Sobrien		 checking absoluteness.  */
52133965Sjdp	      know (SEG_NORMAL (S_GET_SEGMENT (symbolP)));
52233965Sjdp
52333965Sjdp	      expressionP->X_op = O_symbol;
52433965Sjdp	      expressionP->X_add_symbol = symbolP;
52533965Sjdp	    }
52633965Sjdp	  else
52733965Sjdp	    {
52877298Sobrien	      /* Either not seen or not defined.  */
52933965Sjdp	      /* @@ Should print out the original string instead of
53033965Sjdp		 the parsed number.  */
53189857Sobrien	      as_bad (_("backward ref to unknown label \"%d:\""),
53233965Sjdp		      (int) number);
53333965Sjdp	      expressionP->X_op = O_constant;
53433965Sjdp	    }
53533965Sjdp
53633965Sjdp	  expressionP->X_add_number = 0;
53733965Sjdp	}			/* case 'b' */
53833965Sjdp      else if (LOCAL_LABELS_FB && c == 'f')
53933965Sjdp	{
54077298Sobrien	  /* Forward reference.  Expect symbol to be undefined or
54177298Sobrien	     unknown.  undefined: seen it before.  unknown: never seen
54277298Sobrien	     it before.
54377298Sobrien
54477298Sobrien	     Construct a local label name, then an undefined symbol.
54577298Sobrien	     Don't create a xseg frag for it: caller may do that.
54677298Sobrien	     Just return it as never seen before.  */
54733965Sjdp	  name = fb_label_name ((int) number, 1);
54833965Sjdp	  symbolP = symbol_find_or_make (name);
54977298Sobrien	  /* We have no need to check symbol properties.  */
55033965Sjdp#ifndef many_segments
55177298Sobrien	  /* Since "know" puts its arg into a "string", we
55233965Sjdp	     can't have newlines in the argument.  */
55333965Sjdp	  know (S_GET_SEGMENT (symbolP) == undefined_section || S_GET_SEGMENT (symbolP) == text_section || S_GET_SEGMENT (symbolP) == data_section);
55433965Sjdp#endif
55533965Sjdp	  expressionP->X_op = O_symbol;
55633965Sjdp	  expressionP->X_add_symbol = symbolP;
55733965Sjdp	  expressionP->X_add_number = 0;
55833965Sjdp	}			/* case 'f' */
55933965Sjdp      else if (LOCAL_LABELS_DOLLAR && c == '$')
56033965Sjdp	{
56133965Sjdp	  /* If the dollar label is *currently* defined, then this is just
56233965Sjdp	     another reference to it.  If it is not *currently* defined,
56333965Sjdp	     then this is a fresh instantiation of that number, so create
56433965Sjdp	     it.  */
56533965Sjdp
56633965Sjdp	  if (dollar_label_defined ((long) number))
56733965Sjdp	    {
56833965Sjdp	      name = dollar_label_name ((long) number, 0);
56933965Sjdp	      symbolP = symbol_find (name);
57033965Sjdp	      know (symbolP != NULL);
57133965Sjdp	    }
57233965Sjdp	  else
57333965Sjdp	    {
57433965Sjdp	      name = dollar_label_name ((long) number, 1);
57533965Sjdp	      symbolP = symbol_find_or_make (name);
57633965Sjdp	    }
57733965Sjdp
57833965Sjdp	  expressionP->X_op = O_symbol;
57933965Sjdp	  expressionP->X_add_symbol = symbolP;
58033965Sjdp	  expressionP->X_add_number = 0;
58133965Sjdp	}			/* case '$' */
58233965Sjdp      else
58333965Sjdp	{
58433965Sjdp	  expressionP->X_op = O_constant;
58533965Sjdp	  expressionP->X_add_number = number;
58677298Sobrien	  input_line_pointer--;	/* Restore following character.  */
58777298Sobrien	}			/* Really just a number.  */
58833965Sjdp    }
58933965Sjdp  else
59033965Sjdp    {
59177298Sobrien      /* Not a small number.  */
59233965Sjdp      expressionP->X_op = O_big;
59377298Sobrien      expressionP->X_add_number = number;	/* Number of littlenums.  */
59477298Sobrien      input_line_pointer--;	/* -> char following number.  */
59533965Sjdp    }
59633965Sjdp}
59733965Sjdp
59833965Sjdp/* Parse an MRI multi character constant.  */
59933965Sjdp
60033965Sjdpstatic void
601130561Sobrienmri_char_constant (expressionS *expressionP)
60233965Sjdp{
60333965Sjdp  int i;
60433965Sjdp
60533965Sjdp  if (*input_line_pointer == '\''
60633965Sjdp      && input_line_pointer[1] != '\'')
60733965Sjdp    {
60833965Sjdp      expressionP->X_op = O_constant;
60933965Sjdp      expressionP->X_add_number = 0;
61033965Sjdp      return;
61133965Sjdp    }
61233965Sjdp
61333965Sjdp  /* In order to get the correct byte ordering, we must build the
61433965Sjdp     number in reverse.  */
61533965Sjdp  for (i = SIZE_OF_LARGE_NUMBER - 1; i >= 0; i--)
61633965Sjdp    {
61733965Sjdp      int j;
61833965Sjdp
61933965Sjdp      generic_bignum[i] = 0;
62033965Sjdp      for (j = 0; j < CHARS_PER_LITTLENUM; j++)
62133965Sjdp	{
62233965Sjdp	  if (*input_line_pointer == '\'')
62333965Sjdp	    {
62433965Sjdp	      if (input_line_pointer[1] != '\'')
62533965Sjdp		break;
62633965Sjdp	      ++input_line_pointer;
62733965Sjdp	    }
62833965Sjdp	  generic_bignum[i] <<= 8;
62933965Sjdp	  generic_bignum[i] += *input_line_pointer;
63033965Sjdp	  ++input_line_pointer;
63133965Sjdp	}
63233965Sjdp
63333965Sjdp      if (i < SIZE_OF_LARGE_NUMBER - 1)
63433965Sjdp	{
63533965Sjdp	  /* If there is more than one littlenum, left justify the
636130561Sobrien	     last one to make it match the earlier ones.  If there is
637130561Sobrien	     only one, we can just use the value directly.  */
63833965Sjdp	  for (; j < CHARS_PER_LITTLENUM; j++)
63933965Sjdp	    generic_bignum[i] <<= 8;
64033965Sjdp	}
64133965Sjdp
64233965Sjdp      if (*input_line_pointer == '\''
64333965Sjdp	  && input_line_pointer[1] != '\'')
64433965Sjdp	break;
64533965Sjdp    }
64633965Sjdp
64733965Sjdp  if (i < 0)
64833965Sjdp    {
64989857Sobrien      as_bad (_("character constant too large"));
65033965Sjdp      i = 0;
65133965Sjdp    }
65233965Sjdp
65333965Sjdp  if (i > 0)
65433965Sjdp    {
65533965Sjdp      int c;
65633965Sjdp      int j;
65733965Sjdp
65833965Sjdp      c = SIZE_OF_LARGE_NUMBER - i;
65933965Sjdp      for (j = 0; j < c; j++)
66033965Sjdp	generic_bignum[j] = generic_bignum[i + j];
66133965Sjdp      i = c;
66233965Sjdp    }
66333965Sjdp
66433965Sjdp  know (LITTLENUM_NUMBER_OF_BITS == 16);
66533965Sjdp  if (i > 2)
66633965Sjdp    {
66733965Sjdp      expressionP->X_op = O_big;
66833965Sjdp      expressionP->X_add_number = i;
66933965Sjdp    }
67033965Sjdp  else
67133965Sjdp    {
67233965Sjdp      expressionP->X_op = O_constant;
67333965Sjdp      if (i < 2)
67433965Sjdp	expressionP->X_add_number = generic_bignum[0] & LITTLENUM_MASK;
67533965Sjdp      else
67633965Sjdp	expressionP->X_add_number =
67733965Sjdp	  (((generic_bignum[1] & LITTLENUM_MASK)
67833965Sjdp	    << LITTLENUM_NUMBER_OF_BITS)
67933965Sjdp	   | (generic_bignum[0] & LITTLENUM_MASK));
68033965Sjdp    }
68133965Sjdp
68233965Sjdp  /* Skip the final closing quote.  */
68333965Sjdp  ++input_line_pointer;
68433965Sjdp}
68533965Sjdp
68633965Sjdp/* Return an expression representing the current location.  This
68733965Sjdp   handles the magic symbol `.'.  */
68833965Sjdp
68933965Sjdpstatic void
690130561Sobriencurrent_location (expressionS *expressionp)
69133965Sjdp{
69233965Sjdp  if (now_seg == absolute_section)
69333965Sjdp    {
69433965Sjdp      expressionp->X_op = O_constant;
69533965Sjdp      expressionp->X_add_number = abs_section_offset;
69633965Sjdp    }
69733965Sjdp  else
69833965Sjdp    {
69933965Sjdp      expressionp->X_op = O_symbol;
700130561Sobrien      expressionp->X_add_symbol = symbol_temp_new_now ();
70133965Sjdp      expressionp->X_add_number = 0;
70233965Sjdp    }
70333965Sjdp}
70433965Sjdp
70577298Sobrien/* In:	Input_line_pointer points to 1st char of operand, which may
70677298Sobrien	be a space.
70733965Sjdp
70889857Sobrien   Out:	An expressionS.
70977298Sobrien	The operand may have been empty: in this case X_op == O_absent.
71077298Sobrien	Input_line_pointer->(next non-blank) char after operand.  */
71177298Sobrien
71233965Sjdpstatic segT
713218822Sdimoperand (expressionS *expressionP, enum expr_mode mode)
71433965Sjdp{
71533965Sjdp  char c;
71677298Sobrien  symbolS *symbolP;	/* Points to symbol.  */
71777298Sobrien  char *name;		/* Points to name of symbol.  */
71833965Sjdp  segT segment;
71933965Sjdp
72033965Sjdp  /* All integers are regarded as unsigned unless they are negated.
72133965Sjdp     This is because the only thing which cares whether a number is
72233965Sjdp     unsigned is the code in emit_expr which extends constants into
72333965Sjdp     bignums.  It should only sign extend negative numbers, so that
72433965Sjdp     something like ``.quad 0x80000000'' is not sign extended even
72533965Sjdp     though it appears negative if valueT is 32 bits.  */
72633965Sjdp  expressionP->X_unsigned = 1;
72733965Sjdp
72877298Sobrien  /* Digits, assume it is a bignum.  */
72933965Sjdp
73077298Sobrien  SKIP_WHITESPACE ();		/* Leading whitespace is part of operand.  */
73177298Sobrien  c = *input_line_pointer++;	/* input_line_pointer -> past char in c.  */
73233965Sjdp
73377298Sobrien  if (is_end_of_line[(unsigned char) c])
73477298Sobrien    goto eol;
73577298Sobrien
73633965Sjdp  switch (c)
73733965Sjdp    {
73833965Sjdp    case '1':
73933965Sjdp    case '2':
74033965Sjdp    case '3':
74133965Sjdp    case '4':
74233965Sjdp    case '5':
74333965Sjdp    case '6':
74433965Sjdp    case '7':
74533965Sjdp    case '8':
74633965Sjdp    case '9':
74733965Sjdp      input_line_pointer--;
74833965Sjdp
74977298Sobrien      integer_constant ((NUMBERS_WITH_SUFFIX || flag_m68k_mri)
75077298Sobrien			? 0 : 10,
751104834Sobrien			expressionP);
75233965Sjdp      break;
75333965Sjdp
75477298Sobrien#ifdef LITERAL_PREFIXDOLLAR_HEX
75577298Sobrien    case '$':
75689857Sobrien      /* $L is the start of a local label, not a hex constant.  */
75789857Sobrien      if (* input_line_pointer == 'L')
75889857Sobrien      goto isname;
75977298Sobrien      integer_constant (16, expressionP);
76077298Sobrien      break;
76177298Sobrien#endif
76277298Sobrien
76377298Sobrien#ifdef LITERAL_PREFIXPERCENT_BIN
76477298Sobrien    case '%':
76577298Sobrien      integer_constant (2, expressionP);
76677298Sobrien      break;
76777298Sobrien#endif
76877298Sobrien
76933965Sjdp    case '0':
77077298Sobrien      /* Non-decimal radix.  */
77133965Sjdp
77260484Sobrien      if (NUMBERS_WITH_SUFFIX || flag_m68k_mri)
77333965Sjdp	{
77433965Sjdp	  char *s;
77533965Sjdp
776130561Sobrien	  /* Check for a hex or float constant.  */
77733965Sjdp	  for (s = input_line_pointer; hex_p (*s); s++)
77833965Sjdp	    ;
779130561Sobrien	  if (*s == 'h' || *s == 'H' || *input_line_pointer == '.')
78033965Sjdp	    {
78133965Sjdp	      --input_line_pointer;
78233965Sjdp	      integer_constant (0, expressionP);
78333965Sjdp	      break;
78433965Sjdp	    }
78577298Sobrien	}
78633965Sjdp      c = *input_line_pointer;
78733965Sjdp      switch (c)
78833965Sjdp	{
78933965Sjdp	case 'o':
79033965Sjdp	case 'O':
79133965Sjdp	case 'q':
79233965Sjdp	case 'Q':
79333965Sjdp	case '8':
79433965Sjdp	case '9':
79560484Sobrien	  if (NUMBERS_WITH_SUFFIX || flag_m68k_mri)
79633965Sjdp	    {
79733965Sjdp	      integer_constant (0, expressionP);
79833965Sjdp	      break;
79933965Sjdp	    }
80033965Sjdp	  /* Fall through.  */
80133965Sjdp	default:
80233965Sjdp	default_case:
80333965Sjdp	  if (c && strchr (FLT_CHARS, c))
80433965Sjdp	    {
80533965Sjdp	      input_line_pointer++;
80633965Sjdp	      floating_constant (expressionP);
80789857Sobrien	      expressionP->X_add_number = - TOLOWER (c);
80833965Sjdp	    }
80933965Sjdp	  else
81033965Sjdp	    {
81177298Sobrien	      /* The string was only zero.  */
81233965Sjdp	      expressionP->X_op = O_constant;
81333965Sjdp	      expressionP->X_add_number = 0;
81433965Sjdp	    }
81533965Sjdp
81633965Sjdp	  break;
81733965Sjdp
81833965Sjdp	case 'x':
81933965Sjdp	case 'X':
82033965Sjdp	  if (flag_m68k_mri)
82133965Sjdp	    goto default_case;
82233965Sjdp	  input_line_pointer++;
82333965Sjdp	  integer_constant (16, expressionP);
82433965Sjdp	  break;
82533965Sjdp
82633965Sjdp	case 'b':
82760484Sobrien	  if (LOCAL_LABELS_FB && ! (flag_m68k_mri || NUMBERS_WITH_SUFFIX))
82833965Sjdp	    {
82933965Sjdp	      /* This code used to check for '+' and '-' here, and, in
83033965Sjdp		 some conditions, fall through to call
83133965Sjdp		 integer_constant.  However, that didn't make sense,
83233965Sjdp		 as integer_constant only accepts digits.  */
83333965Sjdp	      /* Some of our code elsewhere does permit digits greater
83433965Sjdp		 than the expected base; for consistency, do the same
83533965Sjdp		 here.  */
83633965Sjdp	      if (input_line_pointer[1] < '0'
83733965Sjdp		  || input_line_pointer[1] > '9')
83833965Sjdp		{
83933965Sjdp		  /* Parse this as a back reference to label 0.  */
84033965Sjdp		  input_line_pointer--;
84133965Sjdp		  integer_constant (10, expressionP);
84233965Sjdp		  break;
84333965Sjdp		}
84433965Sjdp	      /* Otherwise, parse this as a binary number.  */
84533965Sjdp	    }
84633965Sjdp	  /* Fall through.  */
84733965Sjdp	case 'B':
84833965Sjdp	  input_line_pointer++;
84960484Sobrien	  if (flag_m68k_mri || NUMBERS_WITH_SUFFIX)
85033965Sjdp	    goto default_case;
85133965Sjdp	  integer_constant (2, expressionP);
85233965Sjdp	  break;
85333965Sjdp
85433965Sjdp	case '0':
85533965Sjdp	case '1':
85633965Sjdp	case '2':
85733965Sjdp	case '3':
85833965Sjdp	case '4':
85933965Sjdp	case '5':
86033965Sjdp	case '6':
86133965Sjdp	case '7':
86260484Sobrien	  integer_constant ((flag_m68k_mri || NUMBERS_WITH_SUFFIX)
86377298Sobrien			    ? 0 : 8,
86477298Sobrien			    expressionP);
86533965Sjdp	  break;
86633965Sjdp
86733965Sjdp	case 'f':
86833965Sjdp	  if (LOCAL_LABELS_FB)
86933965Sjdp	    {
87033965Sjdp	      /* If it says "0f" and it could possibly be a floating point
87133965Sjdp		 number, make it one.  Otherwise, make it a local label,
87233965Sjdp		 and try to deal with parsing the rest later.  */
87333965Sjdp	      if (!input_line_pointer[1]
87460484Sobrien		  || (is_end_of_line[0xff & input_line_pointer[1]])
87560484Sobrien		  || strchr (FLT_CHARS, 'f') == NULL)
87633965Sjdp		goto is_0f_label;
87733965Sjdp	      {
87833965Sjdp		char *cp = input_line_pointer + 1;
87933965Sjdp		int r = atof_generic (&cp, ".", EXP_CHARS,
88033965Sjdp				      &generic_floating_point_number);
88133965Sjdp		switch (r)
88233965Sjdp		  {
88333965Sjdp		  case 0:
88433965Sjdp		  case ERROR_EXPONENT_OVERFLOW:
88533965Sjdp		    if (*cp == 'f' || *cp == 'b')
88677298Sobrien		      /* Looks like a difference expression.  */
88733965Sjdp		      goto is_0f_label;
88860484Sobrien		    else if (cp == input_line_pointer + 1)
88960484Sobrien		      /* No characters has been accepted -- looks like
89077298Sobrien			 end of operand.  */
89160484Sobrien		      goto is_0f_label;
89233965Sjdp		    else
89333965Sjdp		      goto is_0f_float;
89433965Sjdp		  default:
89560484Sobrien		    as_fatal (_("expr.c(operand): bad atof_generic return val %d"),
89633965Sjdp			      r);
89733965Sjdp		  }
89833965Sjdp	      }
89933965Sjdp
90033965Sjdp	      /* Okay, now we've sorted it out.  We resume at one of these
90133965Sjdp		 two labels, depending on what we've decided we're probably
90233965Sjdp		 looking at.  */
90333965Sjdp	    is_0f_label:
90433965Sjdp	      input_line_pointer--;
90533965Sjdp	      integer_constant (10, expressionP);
90633965Sjdp	      break;
90733965Sjdp
90833965Sjdp	    is_0f_float:
90977298Sobrien	      /* Fall through.  */
91033965Sjdp	      ;
91133965Sjdp	    }
91233965Sjdp
91333965Sjdp	case 'd':
91433965Sjdp	case 'D':
91560484Sobrien	  if (flag_m68k_mri || NUMBERS_WITH_SUFFIX)
91633965Sjdp	    {
91733965Sjdp	      integer_constant (0, expressionP);
91833965Sjdp	      break;
91933965Sjdp	    }
92033965Sjdp	  /* Fall through.  */
92133965Sjdp	case 'F':
92233965Sjdp	case 'r':
92333965Sjdp	case 'e':
92433965Sjdp	case 'E':
92533965Sjdp	case 'g':
92633965Sjdp	case 'G':
92733965Sjdp	  input_line_pointer++;
92833965Sjdp	  floating_constant (expressionP);
92989857Sobrien	  expressionP->X_add_number = - TOLOWER (c);
93033965Sjdp	  break;
93133965Sjdp
93233965Sjdp	case '$':
93333965Sjdp	  if (LOCAL_LABELS_DOLLAR)
93433965Sjdp	    {
93533965Sjdp	      integer_constant (10, expressionP);
93633965Sjdp	      break;
93733965Sjdp	    }
93833965Sjdp	  else
93933965Sjdp	    goto default_case;
94033965Sjdp	}
94133965Sjdp
94233965Sjdp      break;
94333965Sjdp
94433965Sjdp    case '(':
94560484Sobrien#ifndef NEED_INDEX_OPERATOR
94633965Sjdp    case '[':
94760484Sobrien#endif
94877298Sobrien      /* Didn't begin with digit & not a name.  */
949218822Sdim      if (mode != expr_defer)
950218822Sdim	segment = expression (expressionP);
951218822Sdim      else
952218822Sdim	segment = deferred_expression (expressionP);
95377298Sobrien      /* expression () will pass trailing whitespace.  */
95477298Sobrien      if ((c == '(' && *input_line_pointer != ')')
95577298Sobrien	  || (c == '[' && *input_line_pointer != ']'))
956218822Sdim	as_bad (_("missing '%c'"), c == '(' ? ')' : ']');
95777298Sobrien      else
95877298Sobrien	input_line_pointer++;
95933965Sjdp      SKIP_WHITESPACE ();
96077298Sobrien      /* Here with input_line_pointer -> char after "(...)".  */
96133965Sjdp      return segment;
96233965Sjdp
96360484Sobrien#ifdef TC_M68K
96433965Sjdp    case 'E':
96533965Sjdp      if (! flag_m68k_mri || *input_line_pointer != '\'')
96633965Sjdp	goto de_fault;
96760484Sobrien      as_bad (_("EBCDIC constants are not supported"));
96833965Sjdp      /* Fall through.  */
96933965Sjdp    case 'A':
97033965Sjdp      if (! flag_m68k_mri || *input_line_pointer != '\'')
97133965Sjdp	goto de_fault;
97233965Sjdp      ++input_line_pointer;
97333965Sjdp      /* Fall through.  */
97460484Sobrien#endif
97533965Sjdp    case '\'':
97633965Sjdp      if (! flag_m68k_mri)
97733965Sjdp	{
97833965Sjdp	  /* Warning: to conform to other people's assemblers NO
97977298Sobrien	     ESCAPEMENT is permitted for a single quote.  The next
98033965Sjdp	     character, parity errors and all, is taken as the value
98177298Sobrien	     of the operand.  VERY KINKY.  */
98233965Sjdp	  expressionP->X_op = O_constant;
98333965Sjdp	  expressionP->X_add_number = *input_line_pointer++;
98433965Sjdp	  break;
98533965Sjdp	}
98633965Sjdp
98733965Sjdp      mri_char_constant (expressionP);
98833965Sjdp      break;
98933965Sjdp
99060484Sobrien#ifdef TC_M68K
99133965Sjdp    case '"':
99233965Sjdp      /* Double quote is the bitwise not operator in MRI mode.  */
99333965Sjdp      if (! flag_m68k_mri)
99433965Sjdp	goto de_fault;
99533965Sjdp      /* Fall through.  */
99660484Sobrien#endif
99733965Sjdp    case '~':
99877298Sobrien      /* '~' is permitted to start a label on the Delta.  */
99933965Sjdp      if (is_name_beginner (c))
100033965Sjdp	goto isname;
100133965Sjdp    case '!':
100233965Sjdp    case '-':
1003218822Sdim    case '+':
100433965Sjdp      {
1005218822Sdim	operand (expressionP, mode);
100633965Sjdp	if (expressionP->X_op == O_constant)
100733965Sjdp	  {
100877298Sobrien	    /* input_line_pointer -> char after operand.  */
100933965Sjdp	    if (c == '-')
101033965Sjdp	      {
101133965Sjdp		expressionP->X_add_number = - expressionP->X_add_number;
101277298Sobrien		/* Notice: '-' may overflow: no warning is given.
101377298Sobrien		   This is compatible with other people's
101477298Sobrien		   assemblers.  Sigh.  */
101533965Sjdp		expressionP->X_unsigned = 0;
101633965Sjdp	      }
101733965Sjdp	    else if (c == '~' || c == '"')
101833965Sjdp	      expressionP->X_add_number = ~ expressionP->X_add_number;
1019218822Sdim	    else if (c == '!')
102033965Sjdp	      expressionP->X_add_number = ! expressionP->X_add_number;
102133965Sjdp	  }
1022130561Sobrien	else if (expressionP->X_op == O_big
1023130561Sobrien		 && expressionP->X_add_number <= 0
1024130561Sobrien		 && c == '-'
1025130561Sobrien		 && (generic_floating_point_number.sign == '+'
1026130561Sobrien		     || generic_floating_point_number.sign == 'P'))
1027130561Sobrien	  {
1028130561Sobrien	    /* Negative flonum (eg, -1.000e0).  */
1029130561Sobrien	    if (generic_floating_point_number.sign == '+')
1030130561Sobrien	      generic_floating_point_number.sign = '-';
1031130561Sobrien	    else
1032130561Sobrien	      generic_floating_point_number.sign = 'N';
1033130561Sobrien	  }
1034218822Sdim	else if (expressionP->X_op == O_big
1035218822Sdim		 && expressionP->X_add_number > 0)
1036218822Sdim	  {
1037218822Sdim	    int i;
1038218822Sdim
1039218822Sdim	    if (c == '~' || c == '-')
1040218822Sdim	      {
1041218822Sdim		for (i = 0; i < expressionP->X_add_number; ++i)
1042218822Sdim		  generic_bignum[i] = ~generic_bignum[i];
1043276229Spfg
1044276229Spfg		/* Extend the bignum to at least the size of .octa.  */
1045276229Spfg		if (expressionP->X_add_number < SIZE_OF_LARGE_NUMBER)
1046276229Spfg		  {
1047276229Spfg		    expressionP->X_add_number = SIZE_OF_LARGE_NUMBER;
1048276229Spfg		    for (; i < expressionP->X_add_number; ++i)
1049276229Spfg		      generic_bignum[i] = ~(LITTLENUM_TYPE) 0;
1050276229Spfg		  }
1051276229Spfg
1052218822Sdim		if (c == '-')
1053218822Sdim		  for (i = 0; i < expressionP->X_add_number; ++i)
1054218822Sdim		    {
1055218822Sdim		      generic_bignum[i] += 1;
1056218822Sdim		      if (generic_bignum[i])
1057218822Sdim			break;
1058218822Sdim		    }
1059218822Sdim	      }
1060218822Sdim	    else if (c == '!')
1061218822Sdim	      {
1062218822Sdim		for (i = 0; i < expressionP->X_add_number; ++i)
1063276229Spfg		  if (generic_bignum[i] != 0)
1064276229Spfg		    break;
1065276229Spfg		expressionP->X_add_number = i >= expressionP->X_add_number;
1066276229Spfg		expressionP->X_op = O_constant;
1067276229Spfg		expressionP->X_unsigned = 1;
1068218822Sdim	      }
1069218822Sdim	  }
107033965Sjdp	else if (expressionP->X_op != O_illegal
107133965Sjdp		 && expressionP->X_op != O_absent)
107233965Sjdp	  {
1073218822Sdim	    if (c != '+')
1074218822Sdim	      {
1075218822Sdim		expressionP->X_add_symbol = make_expr_symbol (expressionP);
1076218822Sdim		if (c == '-')
1077218822Sdim		  expressionP->X_op = O_uminus;
1078218822Sdim		else if (c == '~' || c == '"')
1079218822Sdim		  expressionP->X_op = O_bit_not;
1080218822Sdim		else
1081218822Sdim		  expressionP->X_op = O_logical_not;
1082218822Sdim		expressionP->X_add_number = 0;
1083218822Sdim	      }
108433965Sjdp	  }
108533965Sjdp	else
108660484Sobrien	  as_warn (_("Unary operator %c ignored because bad operand follows"),
108733965Sjdp		   c);
108833965Sjdp      }
108933965Sjdp      break;
109033965Sjdp
109160484Sobrien#if defined (DOLLAR_DOT) || defined (TC_M68K)
109233965Sjdp    case '$':
109377298Sobrien      /* '$' is the program counter when in MRI mode, or when
1094130561Sobrien	 DOLLAR_DOT is defined.  */
109533965Sjdp#ifndef DOLLAR_DOT
109633965Sjdp      if (! flag_m68k_mri)
109733965Sjdp	goto de_fault;
109833965Sjdp#endif
1099218822Sdim      if (DOLLAR_AMBIGU && hex_p (*input_line_pointer))
110033965Sjdp	{
1101218822Sdim	  /* In MRI mode and on Z80, '$' is also used as the prefix
1102218822Sdim	     for a hexadecimal constant.  */
110333965Sjdp	  integer_constant (16, expressionP);
110433965Sjdp	  break;
110533965Sjdp	}
110633965Sjdp
110733965Sjdp      if (is_part_of_name (*input_line_pointer))
110833965Sjdp	goto isname;
110933965Sjdp
111033965Sjdp      current_location (expressionP);
111133965Sjdp      break;
111260484Sobrien#endif
111333965Sjdp
111433965Sjdp    case '.':
111533965Sjdp      if (!is_part_of_name (*input_line_pointer))
111633965Sjdp	{
111733965Sjdp	  current_location (expressionP);
111833965Sjdp	  break;
111933965Sjdp	}
112033965Sjdp      else if ((strncasecmp (input_line_pointer, "startof.", 8) == 0
112133965Sjdp		&& ! is_part_of_name (input_line_pointer[8]))
112233965Sjdp	       || (strncasecmp (input_line_pointer, "sizeof.", 7) == 0
112333965Sjdp		   && ! is_part_of_name (input_line_pointer[7])))
112433965Sjdp	{
112533965Sjdp	  int start;
112633965Sjdp
112733965Sjdp	  start = (input_line_pointer[1] == 't'
112833965Sjdp		   || input_line_pointer[1] == 'T');
112933965Sjdp	  input_line_pointer += start ? 8 : 7;
113033965Sjdp	  SKIP_WHITESPACE ();
113133965Sjdp	  if (*input_line_pointer != '(')
113260484Sobrien	    as_bad (_("syntax error in .startof. or .sizeof."));
113333965Sjdp	  else
113433965Sjdp	    {
113533965Sjdp	      char *buf;
113633965Sjdp
113733965Sjdp	      ++input_line_pointer;
113833965Sjdp	      SKIP_WHITESPACE ();
113933965Sjdp	      name = input_line_pointer;
114033965Sjdp	      c = get_symbol_end ();
114133965Sjdp
114233965Sjdp	      buf = (char *) xmalloc (strlen (name) + 10);
114333965Sjdp	      if (start)
114433965Sjdp		sprintf (buf, ".startof.%s", name);
114533965Sjdp	      else
114633965Sjdp		sprintf (buf, ".sizeof.%s", name);
114733965Sjdp	      symbolP = symbol_make (buf);
114833965Sjdp	      free (buf);
114933965Sjdp
115033965Sjdp	      expressionP->X_op = O_symbol;
115133965Sjdp	      expressionP->X_add_symbol = symbolP;
115233965Sjdp	      expressionP->X_add_number = 0;
115333965Sjdp
115433965Sjdp	      *input_line_pointer = c;
115533965Sjdp	      SKIP_WHITESPACE ();
115633965Sjdp	      if (*input_line_pointer != ')')
115760484Sobrien		as_bad (_("syntax error in .startof. or .sizeof."));
115833965Sjdp	      else
115933965Sjdp		++input_line_pointer;
116033965Sjdp	    }
116133965Sjdp	  break;
116233965Sjdp	}
116333965Sjdp      else
116433965Sjdp	{
116533965Sjdp	  goto isname;
116633965Sjdp	}
116777298Sobrien
116833965Sjdp    case ',':
116933965Sjdp    eol:
117077298Sobrien      /* Can't imagine any other kind of operand.  */
117133965Sjdp      expressionP->X_op = O_absent;
117233965Sjdp      input_line_pointer--;
117333965Sjdp      break;
117433965Sjdp
117560484Sobrien#ifdef TC_M68K
117633965Sjdp    case '%':
117733965Sjdp      if (! flag_m68k_mri)
117833965Sjdp	goto de_fault;
117933965Sjdp      integer_constant (2, expressionP);
118033965Sjdp      break;
118133965Sjdp
118233965Sjdp    case '@':
118333965Sjdp      if (! flag_m68k_mri)
118433965Sjdp	goto de_fault;
118533965Sjdp      integer_constant (8, expressionP);
118633965Sjdp      break;
118733965Sjdp
118833965Sjdp    case ':':
118933965Sjdp      if (! flag_m68k_mri)
119033965Sjdp	goto de_fault;
119133965Sjdp
119233965Sjdp      /* In MRI mode, this is a floating point constant represented
1193130561Sobrien	 using hexadecimal digits.  */
119433965Sjdp
119533965Sjdp      ++input_line_pointer;
119633965Sjdp      integer_constant (16, expressionP);
119733965Sjdp      break;
119833965Sjdp
119933965Sjdp    case '*':
120033965Sjdp      if (! flag_m68k_mri || is_part_of_name (*input_line_pointer))
120133965Sjdp	goto de_fault;
120233965Sjdp
120333965Sjdp      current_location (expressionP);
120433965Sjdp      break;
120560484Sobrien#endif
120633965Sjdp
120733965Sjdp    default:
120860484Sobrien#ifdef TC_M68K
120933965Sjdp    de_fault:
121060484Sobrien#endif
121177298Sobrien      if (is_name_beginner (c))	/* Here if did not begin with a digit.  */
121233965Sjdp	{
121377298Sobrien	  /* Identifier begins here.
121477298Sobrien	     This is kludged for speed, so code is repeated.  */
121533965Sjdp	isname:
121633965Sjdp	  name = --input_line_pointer;
121733965Sjdp	  c = get_symbol_end ();
121833965Sjdp
121933965Sjdp#ifdef md_parse_name
122033965Sjdp	  /* This is a hook for the backend to parse certain names
1221130561Sobrien	     specially in certain contexts.  If a name always has a
1222130561Sobrien	     specific value, it can often be handled by simply
1223130561Sobrien	     entering it in the symbol table.  */
1224218822Sdim	  if (md_parse_name (name, expressionP, mode, &c))
122533965Sjdp	    {
122633965Sjdp	      *input_line_pointer = c;
122733965Sjdp	      break;
122833965Sjdp	    }
122933965Sjdp#endif
123033965Sjdp
123133965Sjdp#ifdef TC_I960
123233965Sjdp	  /* The MRI i960 assembler permits
123333965Sjdp	         lda sizeof code,g13
123433965Sjdp	     FIXME: This should use md_parse_name.  */
123533965Sjdp	  if (flag_mri
123633965Sjdp	      && (strcasecmp (name, "sizeof") == 0
123733965Sjdp		  || strcasecmp (name, "startof") == 0))
123833965Sjdp	    {
123933965Sjdp	      int start;
124033965Sjdp	      char *buf;
124133965Sjdp
124233965Sjdp	      start = (name[1] == 't'
124333965Sjdp		       || name[1] == 'T');
124433965Sjdp
124533965Sjdp	      *input_line_pointer = c;
124633965Sjdp	      SKIP_WHITESPACE ();
124733965Sjdp
124833965Sjdp	      name = input_line_pointer;
124933965Sjdp	      c = get_symbol_end ();
125033965Sjdp
125133965Sjdp	      buf = (char *) xmalloc (strlen (name) + 10);
125233965Sjdp	      if (start)
125333965Sjdp		sprintf (buf, ".startof.%s", name);
125433965Sjdp	      else
125533965Sjdp		sprintf (buf, ".sizeof.%s", name);
125633965Sjdp	      symbolP = symbol_make (buf);
125733965Sjdp	      free (buf);
125833965Sjdp
125933965Sjdp	      expressionP->X_op = O_symbol;
126033965Sjdp	      expressionP->X_add_symbol = symbolP;
126133965Sjdp	      expressionP->X_add_number = 0;
126233965Sjdp
126333965Sjdp	      *input_line_pointer = c;
126433965Sjdp	      SKIP_WHITESPACE ();
126533965Sjdp
126633965Sjdp	      break;
126777298Sobrien	    }
126833965Sjdp#endif
126933965Sjdp
127033965Sjdp	  symbolP = symbol_find_or_make (name);
127133965Sjdp
127233965Sjdp	  /* If we have an absolute symbol or a reg, then we know its
127333965Sjdp	     value now.  */
127433965Sjdp	  segment = S_GET_SEGMENT (symbolP);
1275218822Sdim	  if (mode != expr_defer && segment == absolute_section)
127633965Sjdp	    {
127733965Sjdp	      expressionP->X_op = O_constant;
127833965Sjdp	      expressionP->X_add_number = S_GET_VALUE (symbolP);
127933965Sjdp	    }
1280218822Sdim	  else if (mode != expr_defer && segment == reg_section)
128133965Sjdp	    {
128233965Sjdp	      expressionP->X_op = O_register;
128333965Sjdp	      expressionP->X_add_number = S_GET_VALUE (symbolP);
128433965Sjdp	    }
128533965Sjdp	  else
128633965Sjdp	    {
128733965Sjdp	      expressionP->X_op = O_symbol;
128833965Sjdp	      expressionP->X_add_symbol = symbolP;
128933965Sjdp	      expressionP->X_add_number = 0;
129033965Sjdp	    }
129133965Sjdp	  *input_line_pointer = c;
129233965Sjdp	}
129333965Sjdp      else
129433965Sjdp	{
129533965Sjdp	  /* Let the target try to parse it.  Success is indicated by changing
129633965Sjdp	     the X_op field to something other than O_absent and pointing
129777298Sobrien	     input_line_pointer past the expression.  If it can't parse the
129833965Sjdp	     expression, X_op and input_line_pointer should be unchanged.  */
129933965Sjdp	  expressionP->X_op = O_absent;
130033965Sjdp	  --input_line_pointer;
130133965Sjdp	  md_operand (expressionP);
130233965Sjdp	  if (expressionP->X_op == O_absent)
130333965Sjdp	    {
130433965Sjdp	      ++input_line_pointer;
130589857Sobrien	      as_bad (_("bad expression"));
130633965Sjdp	      expressionP->X_op = O_constant;
130733965Sjdp	      expressionP->X_add_number = 0;
130833965Sjdp	    }
130933965Sjdp	}
131033965Sjdp      break;
131133965Sjdp    }
131233965Sjdp
131377298Sobrien  /* It is more 'efficient' to clean up the expressionS when they are
131477298Sobrien     created.  Doing it here saves lines of code.  */
131533965Sjdp  clean_up_expression (expressionP);
131677298Sobrien  SKIP_WHITESPACE ();		/* -> 1st char after operand.  */
131733965Sjdp  know (*input_line_pointer != ' ');
131833965Sjdp
131933965Sjdp  /* The PA port needs this information.  */
132033965Sjdp  if (expressionP->X_add_symbol)
132160484Sobrien    symbol_mark_used (expressionP->X_add_symbol);
132233965Sjdp
1323218822Sdim  expressionP->X_add_symbol = symbol_clone_if_forward_ref (expressionP->X_add_symbol);
1324218822Sdim  expressionP->X_op_symbol = symbol_clone_if_forward_ref (expressionP->X_op_symbol);
1325218822Sdim
132633965Sjdp  switch (expressionP->X_op)
132733965Sjdp    {
132833965Sjdp    default:
132933965Sjdp      return absolute_section;
133033965Sjdp    case O_symbol:
133133965Sjdp      return S_GET_SEGMENT (expressionP->X_add_symbol);
133233965Sjdp    case O_register:
133333965Sjdp      return reg_section;
133433965Sjdp    }
133577298Sobrien}
133633965Sjdp
133777298Sobrien/* Internal.  Simplify a struct expression for use by expr ().  */
133833965Sjdp
133989857Sobrien/* In:	address of an expressionS.
134077298Sobrien	The X_op field of the expressionS may only take certain values.
134177298Sobrien	Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT.
134233965Sjdp
134377298Sobrien   Out:	expressionS may have been modified:
134477298Sobrien	Unused fields zeroed to help expr ().  */
134577298Sobrien
134633965Sjdpstatic void
1347130561Sobrienclean_up_expression (expressionS *expressionP)
134833965Sjdp{
134933965Sjdp  switch (expressionP->X_op)
135033965Sjdp    {
135133965Sjdp    case O_illegal:
135233965Sjdp    case O_absent:
135333965Sjdp      expressionP->X_add_number = 0;
135433965Sjdp      /* Fall through.  */
135533965Sjdp    case O_big:
135633965Sjdp    case O_constant:
135733965Sjdp    case O_register:
135833965Sjdp      expressionP->X_add_symbol = NULL;
135933965Sjdp      /* Fall through.  */
136033965Sjdp    case O_symbol:
136133965Sjdp    case O_uminus:
136233965Sjdp    case O_bit_not:
136333965Sjdp      expressionP->X_op_symbol = NULL;
136433965Sjdp      break;
136533965Sjdp    default:
136633965Sjdp      break;
136733965Sjdp    }
136833965Sjdp}
136933965Sjdp
137077298Sobrien/* Expression parser.  */
137133965Sjdp
137277298Sobrien/* We allow an empty expression, and just assume (absolute,0) silently.
137377298Sobrien   Unary operators and parenthetical expressions are treated as operands.
137477298Sobrien   As usual, Q==quantity==operand, O==operator, X==expression mnemonics.
137533965Sjdp
137689857Sobrien   We used to do an aho/ullman shift-reduce parser, but the logic got so
137777298Sobrien   warped that I flushed it and wrote a recursive-descent parser instead.
137877298Sobrien   Now things are stable, would anybody like to write a fast parser?
137977298Sobrien   Most expressions are either register (which does not even reach here)
138077298Sobrien   or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common.
138177298Sobrien   So I guess it doesn't really matter how inefficient more complex expressions
138277298Sobrien   are parsed.
138377298Sobrien
138477298Sobrien   After expr(RANK,resultP) input_line_pointer->operator of rank <= RANK.
138577298Sobrien   Also, we have consumed any leading or trailing spaces (operand does that)
138677298Sobrien   and done all intervening operators.
138777298Sobrien
138877298Sobrien   This returns the segment of the result, which will be
138977298Sobrien   absolute_section or the segment of a symbol.  */
139077298Sobrien
139133965Sjdp#undef __
139233965Sjdp#define __ O_illegal
1393218822Sdim#ifndef O_SINGLE_EQ
1394218822Sdim#define O_SINGLE_EQ O_illegal
1395218822Sdim#endif
139633965Sjdp
139777298Sobrien/* Maps ASCII -> operators.  */
139877298Sobrienstatic const operatorT op_encoding[256] = {
139933965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
140033965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
140133965Sjdp
140233965Sjdp  __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __,
140333965Sjdp  __, __, O_multiply, O_add, __, O_subtract, __, O_divide,
140433965Sjdp  __, __, __, __, __, __, __, __,
1405218822Sdim  __, __, __, __, O_lt, O_SINGLE_EQ, O_gt, __,
140633965Sjdp  __, __, __, __, __, __, __, __,
140733965Sjdp  __, __, __, __, __, __, __, __,
140833965Sjdp  __, __, __, __, __, __, __, __,
140960484Sobrien  __, __, __,
141060484Sobrien#ifdef NEED_INDEX_OPERATOR
141160484Sobrien  O_index,
141260484Sobrien#else
141360484Sobrien  __,
141460484Sobrien#endif
141560484Sobrien  __, __, O_bit_exclusive_or, __,
141633965Sjdp  __, __, __, __, __, __, __, __,
141733965Sjdp  __, __, __, __, __, __, __, __,
141833965Sjdp  __, __, __, __, __, __, __, __,
141933965Sjdp  __, __, __, __, O_bit_inclusive_or, __, __, __,
142033965Sjdp
142133965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142233965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142333965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142433965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142533965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142633965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142733965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142833965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
142933965Sjdp};
143033965Sjdp
143177298Sobrien/* Rank	Examples
143277298Sobrien   0	operand, (expression)
143377298Sobrien   1	||
143477298Sobrien   2	&&
143589857Sobrien   3	== <> < <= >= >
143677298Sobrien   4	+ -
143777298Sobrien   5	used for * / % in MRI mode
143877298Sobrien   6	& ^ ! |
143977298Sobrien   7	* / % << >>
144077298Sobrien   8	unary - unary ~
144177298Sobrien*/
144277298Sobrienstatic operator_rankT op_rank[] = {
144333965Sjdp  0,	/* O_illegal */
144433965Sjdp  0,	/* O_absent */
144533965Sjdp  0,	/* O_constant */
144633965Sjdp  0,	/* O_symbol */
144733965Sjdp  0,	/* O_symbol_rva */
144833965Sjdp  0,	/* O_register */
144977298Sobrien  0,	/* O_big */
145060484Sobrien  9,	/* O_uminus */
145160484Sobrien  9,	/* O_bit_not */
145260484Sobrien  9,	/* O_logical_not */
145360484Sobrien  8,	/* O_multiply */
145460484Sobrien  8,	/* O_divide */
145560484Sobrien  8,	/* O_modulus */
145660484Sobrien  8,	/* O_left_shift */
145760484Sobrien  8,	/* O_right_shift */
145860484Sobrien  7,	/* O_bit_inclusive_or */
145960484Sobrien  7,	/* O_bit_or_not */
146060484Sobrien  7,	/* O_bit_exclusive_or */
146160484Sobrien  7,	/* O_bit_and */
146260484Sobrien  5,	/* O_add */
146360484Sobrien  5,	/* O_subtract */
146460484Sobrien  4,	/* O_eq */
146560484Sobrien  4,	/* O_ne */
146660484Sobrien  4,	/* O_lt */
146760484Sobrien  4,	/* O_le */
146860484Sobrien  4,	/* O_ge */
146960484Sobrien  4,	/* O_gt */
147060484Sobrien  3,	/* O_logical_and */
147160484Sobrien  2,	/* O_logical_or */
147260484Sobrien  1,	/* O_index */
147360484Sobrien  0,	/* O_md1 */
147460484Sobrien  0,	/* O_md2 */
147560484Sobrien  0,	/* O_md3 */
147660484Sobrien  0,	/* O_md4 */
147760484Sobrien  0,	/* O_md5 */
147860484Sobrien  0,	/* O_md6 */
147960484Sobrien  0,	/* O_md7 */
148060484Sobrien  0,	/* O_md8 */
148160484Sobrien  0,	/* O_md9 */
148260484Sobrien  0,	/* O_md10 */
148360484Sobrien  0,	/* O_md11 */
148460484Sobrien  0,	/* O_md12 */
148560484Sobrien  0,	/* O_md13 */
148660484Sobrien  0,	/* O_md14 */
148760484Sobrien  0,	/* O_md15 */
148860484Sobrien  0,	/* O_md16 */
148933965Sjdp};
149033965Sjdp
149160484Sobrien/* Unfortunately, in MRI mode for the m68k, multiplication and
149260484Sobrien   division have lower precedence than the bit wise operators.  This
149360484Sobrien   function sets the operator precedences correctly for the current
149460484Sobrien   mode.  Also, MRI uses a different bit_not operator, and this fixes
149560484Sobrien   that as well.  */
149633965Sjdp
149777298Sobrien#define STANDARD_MUL_PRECEDENCE 8
149877298Sobrien#define MRI_MUL_PRECEDENCE 6
149960484Sobrien
150033965Sjdpvoid
1501130561Sobrienexpr_set_precedence (void)
150233965Sjdp{
150333965Sjdp  if (flag_m68k_mri)
150433965Sjdp    {
150560484Sobrien      op_rank[O_multiply] = MRI_MUL_PRECEDENCE;
150660484Sobrien      op_rank[O_divide] = MRI_MUL_PRECEDENCE;
150760484Sobrien      op_rank[O_modulus] = MRI_MUL_PRECEDENCE;
150833965Sjdp    }
150960484Sobrien  else
151060484Sobrien    {
151160484Sobrien      op_rank[O_multiply] = STANDARD_MUL_PRECEDENCE;
151260484Sobrien      op_rank[O_divide] = STANDARD_MUL_PRECEDENCE;
151360484Sobrien      op_rank[O_modulus] = STANDARD_MUL_PRECEDENCE;
151460484Sobrien    }
151560484Sobrien}
151633965Sjdp
151760484Sobrien/* Initialize the expression parser.  */
151860484Sobrien
151960484Sobrienvoid
1520130561Sobrienexpr_begin (void)
152160484Sobrien{
152260484Sobrien  expr_set_precedence ();
152360484Sobrien
152433965Sjdp  /* Verify that X_op field is wide enough.  */
152533965Sjdp  {
152633965Sjdp    expressionS e;
152733965Sjdp    e.X_op = O_max;
152833965Sjdp    assert (e.X_op == O_max);
152933965Sjdp  }
153033965Sjdp}
153133965Sjdp
153277298Sobrien/* Return the encoding for the operator at INPUT_LINE_POINTER, and
153377298Sobrien   sets NUM_CHARS to the number of characters in the operator.
153477298Sobrien   Does not advance INPUT_LINE_POINTER.  */
153533965Sjdp
153633965Sjdpstatic inline operatorT
1537130561Sobrienoperator (int *num_chars)
153833965Sjdp{
153933965Sjdp  int c;
154033965Sjdp  operatorT ret;
154133965Sjdp
154260484Sobrien  c = *input_line_pointer & 0xff;
154377298Sobrien  *num_chars = 1;
154433965Sjdp
154577298Sobrien  if (is_end_of_line[c])
154677298Sobrien    return O_illegal;
154777298Sobrien
154833965Sjdp  switch (c)
154933965Sjdp    {
155033965Sjdp    default:
155133965Sjdp      return op_encoding[c];
155233965Sjdp
1553130561Sobrien    case '+':
1554130561Sobrien    case '-':
1555218822Sdim      return op_encoding[c];
1556130561Sobrien
155733965Sjdp    case '<':
155833965Sjdp      switch (input_line_pointer[1])
155933965Sjdp	{
156033965Sjdp	default:
156133965Sjdp	  return op_encoding[c];
156233965Sjdp	case '<':
156333965Sjdp	  ret = O_left_shift;
156433965Sjdp	  break;
156533965Sjdp	case '>':
156633965Sjdp	  ret = O_ne;
156733965Sjdp	  break;
156833965Sjdp	case '=':
156933965Sjdp	  ret = O_le;
157033965Sjdp	  break;
157133965Sjdp	}
157277298Sobrien      *num_chars = 2;
157333965Sjdp      return ret;
157433965Sjdp
157538889Sjdp    case '=':
157638889Sjdp      if (input_line_pointer[1] != '=')
157738889Sjdp	return op_encoding[c];
157838889Sjdp
157977298Sobrien      *num_chars = 2;
158038889Sjdp      return O_eq;
158138889Sjdp
158233965Sjdp    case '>':
158333965Sjdp      switch (input_line_pointer[1])
158433965Sjdp	{
158533965Sjdp	default:
158633965Sjdp	  return op_encoding[c];
158733965Sjdp	case '>':
158833965Sjdp	  ret = O_right_shift;
158933965Sjdp	  break;
159033965Sjdp	case '=':
159133965Sjdp	  ret = O_ge;
159233965Sjdp	  break;
159333965Sjdp	}
159477298Sobrien      *num_chars = 2;
159533965Sjdp      return ret;
159633965Sjdp
159733965Sjdp    case '!':
1598218822Sdim      switch (input_line_pointer[1])
159933965Sjdp	{
1600218822Sdim	case '!':
1601218822Sdim	  /* We accept !! as equivalent to ^ for MRI compatibility. */
1602218822Sdim	  *num_chars = 2;
1603218822Sdim	  return O_bit_exclusive_or;
1604218822Sdim	case '=':
1605218822Sdim	  /* We accept != as equivalent to <>.  */
1606218822Sdim	  *num_chars = 2;
1607218822Sdim	  return O_ne;
1608218822Sdim	default:
160933965Sjdp	  if (flag_m68k_mri)
161033965Sjdp	    return O_bit_inclusive_or;
161133965Sjdp	  return op_encoding[c];
161233965Sjdp	}
161333965Sjdp
161433965Sjdp    case '|':
161533965Sjdp      if (input_line_pointer[1] != '|')
161633965Sjdp	return op_encoding[c];
161733965Sjdp
161877298Sobrien      *num_chars = 2;
161933965Sjdp      return O_logical_or;
162033965Sjdp
162133965Sjdp    case '&':
162233965Sjdp      if (input_line_pointer[1] != '&')
162333965Sjdp	return op_encoding[c];
162433965Sjdp
162577298Sobrien      *num_chars = 2;
162633965Sjdp      return O_logical_and;
162733965Sjdp    }
162833965Sjdp
162977298Sobrien  /* NOTREACHED  */
163038889Sjdp}
163133965Sjdp
163233965Sjdp/* Parse an expression.  */
163333965Sjdp
163433965SjdpsegT
1635130561Sobrienexpr (int rankarg,		/* Larger # is higher rank.  */
1636218822Sdim      expressionS *resultP,	/* Deliver result here.  */
1637218822Sdim      enum expr_mode mode	/* Controls behavior.  */)
163833965Sjdp{
163960484Sobrien  operator_rankT rank = (operator_rankT) rankarg;
164033965Sjdp  segT retval;
164133965Sjdp  expressionS right;
164233965Sjdp  operatorT op_left;
164333965Sjdp  operatorT op_right;
164477298Sobrien  int op_chars;
164533965Sjdp
1646218822Sdim  know (rankarg >= 0);
164733965Sjdp
1648130561Sobrien  /* Save the value of dot for the fixup code.  */
1649130561Sobrien  if (rank == 0)
1650130561Sobrien    dot_value = frag_now_fix ();
1651130561Sobrien
1652218822Sdim  retval = operand (resultP, mode);
165333965Sjdp
165477298Sobrien  /* operand () gobbles spaces.  */
165577298Sobrien  know (*input_line_pointer != ' ');
165633965Sjdp
165777298Sobrien  op_left = operator (&op_chars);
165833965Sjdp  while (op_left != O_illegal && op_rank[(int) op_left] > rank)
165933965Sjdp    {
166033965Sjdp      segT rightseg;
1661218822Sdim      bfd_vma frag_off;
166233965Sjdp
166377298Sobrien      input_line_pointer += op_chars;	/* -> after operator.  */
166433965Sjdp
1665218822Sdim      rightseg = expr (op_rank[(int) op_left], &right, mode);
166633965Sjdp      if (right.X_op == O_absent)
166733965Sjdp	{
166860484Sobrien	  as_warn (_("missing operand; zero assumed"));
166933965Sjdp	  right.X_op = O_constant;
167033965Sjdp	  right.X_add_number = 0;
167133965Sjdp	  right.X_add_symbol = NULL;
167233965Sjdp	  right.X_op_symbol = NULL;
167333965Sjdp	}
167433965Sjdp
167533965Sjdp      know (*input_line_pointer != ' ');
167633965Sjdp
167760484Sobrien      if (op_left == O_index)
167860484Sobrien	{
167960484Sobrien	  if (*input_line_pointer != ']')
168060484Sobrien	    as_bad ("missing right bracket");
168160484Sobrien	  else
168260484Sobrien	    {
168360484Sobrien	      ++input_line_pointer;
168460484Sobrien	      SKIP_WHITESPACE ();
168560484Sobrien	    }
168660484Sobrien	}
168760484Sobrien
168877298Sobrien      op_right = operator (&op_chars);
168933965Sjdp
169077298Sobrien      know (op_right == O_illegal
169177298Sobrien	    || op_rank[(int) op_right] <= op_rank[(int) op_left]);
169233965Sjdp      know ((int) op_left >= (int) O_multiply
1693218822Sdim	    && (int) op_left <= (int) O_index);
169433965Sjdp
169577298Sobrien      /* input_line_pointer->after right-hand quantity.  */
169677298Sobrien      /* left-hand quantity in resultP.  */
169777298Sobrien      /* right-hand quantity in right.  */
169877298Sobrien      /* operator in op_left.  */
169933965Sjdp
170033965Sjdp      if (resultP->X_op == O_big)
170133965Sjdp	{
170260484Sobrien	  if (resultP->X_add_number > 0)
170360484Sobrien	    as_warn (_("left operand is a bignum; integer 0 assumed"));
170460484Sobrien	  else
170560484Sobrien	    as_warn (_("left operand is a float; integer 0 assumed"));
170633965Sjdp	  resultP->X_op = O_constant;
170733965Sjdp	  resultP->X_add_number = 0;
170833965Sjdp	  resultP->X_add_symbol = NULL;
170933965Sjdp	  resultP->X_op_symbol = NULL;
171033965Sjdp	}
171133965Sjdp      if (right.X_op == O_big)
171233965Sjdp	{
171360484Sobrien	  if (right.X_add_number > 0)
171460484Sobrien	    as_warn (_("right operand is a bignum; integer 0 assumed"));
171560484Sobrien	  else
171660484Sobrien	    as_warn (_("right operand is a float; integer 0 assumed"));
171733965Sjdp	  right.X_op = O_constant;
171833965Sjdp	  right.X_add_number = 0;
171933965Sjdp	  right.X_add_symbol = NULL;
172033965Sjdp	  right.X_op_symbol = NULL;
172133965Sjdp	}
172233965Sjdp
172333965Sjdp      /* Optimize common cases.  */
172477298Sobrien#ifdef md_optimize_expr
172577298Sobrien      if (md_optimize_expr (resultP, op_left, &right))
172677298Sobrien	{
172777298Sobrien	  /* Skip.  */
172877298Sobrien	  ;
172977298Sobrien	}
173077298Sobrien      else
173177298Sobrien#endif
173233965Sjdp      if (op_left == O_add && right.X_op == O_constant)
173333965Sjdp	{
173433965Sjdp	  /* X + constant.  */
173533965Sjdp	  resultP->X_add_number += right.X_add_number;
173633965Sjdp	}
173733965Sjdp      /* This case comes up in PIC code.  */
173833965Sjdp      else if (op_left == O_subtract
173933965Sjdp	       && right.X_op == O_symbol
174033965Sjdp	       && resultP->X_op == O_symbol
1741218822Sdim	       && retval == rightseg
1742130561Sobrien	       && (SEG_NORMAL (rightseg)
1743218822Sdim		   || right.X_add_symbol == resultP->X_add_symbol)
1744218822Sdim	       && frag_offset_fixed_p (symbol_get_frag (resultP->X_add_symbol),
1745218822Sdim				       symbol_get_frag (right.X_add_symbol),
1746218822Sdim				       &frag_off))
174733965Sjdp	{
174833965Sjdp	  resultP->X_add_number -= right.X_add_number;
1749218822Sdim	  resultP->X_add_number -= frag_off / OCTETS_PER_BYTE;
175033965Sjdp	  resultP->X_add_number += (S_GET_VALUE (resultP->X_add_symbol)
175133965Sjdp				    - S_GET_VALUE (right.X_add_symbol));
175233965Sjdp	  resultP->X_op = O_constant;
175333965Sjdp	  resultP->X_add_symbol = 0;
175433965Sjdp	}
175533965Sjdp      else if (op_left == O_subtract && right.X_op == O_constant)
175633965Sjdp	{
175733965Sjdp	  /* X - constant.  */
175833965Sjdp	  resultP->X_add_number -= right.X_add_number;
175933965Sjdp	}
176033965Sjdp      else if (op_left == O_add && resultP->X_op == O_constant)
176133965Sjdp	{
176233965Sjdp	  /* Constant + X.  */
176333965Sjdp	  resultP->X_op = right.X_op;
176433965Sjdp	  resultP->X_add_symbol = right.X_add_symbol;
176533965Sjdp	  resultP->X_op_symbol = right.X_op_symbol;
176633965Sjdp	  resultP->X_add_number += right.X_add_number;
176733965Sjdp	  retval = rightseg;
176833965Sjdp	}
176933965Sjdp      else if (resultP->X_op == O_constant && right.X_op == O_constant)
177033965Sjdp	{
177133965Sjdp	  /* Constant OP constant.  */
177233965Sjdp	  offsetT v = right.X_add_number;
177333965Sjdp	  if (v == 0 && (op_left == O_divide || op_left == O_modulus))
177433965Sjdp	    {
177560484Sobrien	      as_warn (_("division by zero"));
177633965Sjdp	      v = 1;
177733965Sjdp	    }
177833965Sjdp	  switch (op_left)
177933965Sjdp	    {
178033965Sjdp	    default:			abort ();
178133965Sjdp	    case O_multiply:		resultP->X_add_number *= v; break;
178233965Sjdp	    case O_divide:		resultP->X_add_number /= v; break;
178333965Sjdp	    case O_modulus:		resultP->X_add_number %= v; break;
178433965Sjdp	    case O_left_shift:		resultP->X_add_number <<= v; break;
178533965Sjdp	    case O_right_shift:
178633965Sjdp	      /* We always use unsigned shifts, to avoid relying on
1787130561Sobrien		 characteristics of the compiler used to compile gas.  */
178833965Sjdp	      resultP->X_add_number =
178933965Sjdp		(offsetT) ((valueT) resultP->X_add_number >> (valueT) v);
179033965Sjdp	      break;
179133965Sjdp	    case O_bit_inclusive_or:	resultP->X_add_number |= v; break;
179233965Sjdp	    case O_bit_or_not:		resultP->X_add_number |= ~v; break;
179333965Sjdp	    case O_bit_exclusive_or:	resultP->X_add_number ^= v; break;
179433965Sjdp	    case O_bit_and:		resultP->X_add_number &= v; break;
1795218822Sdim	      /* Constant + constant (O_add) is handled by the
1796218822Sdim		 previous if statement for constant + X, so is omitted
1797218822Sdim		 here.  */
179833965Sjdp	    case O_subtract:		resultP->X_add_number -= v; break;
179933965Sjdp	    case O_eq:
180033965Sjdp	      resultP->X_add_number =
180133965Sjdp		resultP->X_add_number == v ? ~ (offsetT) 0 : 0;
180233965Sjdp	      break;
180333965Sjdp	    case O_ne:
180433965Sjdp	      resultP->X_add_number =
180533965Sjdp		resultP->X_add_number != v ? ~ (offsetT) 0 : 0;
180633965Sjdp	      break;
180733965Sjdp	    case O_lt:
180833965Sjdp	      resultP->X_add_number =
180933965Sjdp		resultP->X_add_number <  v ? ~ (offsetT) 0 : 0;
181033965Sjdp	      break;
181133965Sjdp	    case O_le:
181233965Sjdp	      resultP->X_add_number =
181333965Sjdp		resultP->X_add_number <= v ? ~ (offsetT) 0 : 0;
181433965Sjdp	      break;
181533965Sjdp	    case O_ge:
181633965Sjdp	      resultP->X_add_number =
181733965Sjdp		resultP->X_add_number >= v ? ~ (offsetT) 0 : 0;
181833965Sjdp	      break;
181933965Sjdp	    case O_gt:
182033965Sjdp	      resultP->X_add_number =
182133965Sjdp		resultP->X_add_number >  v ? ~ (offsetT) 0 : 0;
182233965Sjdp	      break;
182333965Sjdp	    case O_logical_and:
182433965Sjdp	      resultP->X_add_number = resultP->X_add_number && v;
182533965Sjdp	      break;
182633965Sjdp	    case O_logical_or:
182733965Sjdp	      resultP->X_add_number = resultP->X_add_number || v;
182833965Sjdp	      break;
182933965Sjdp	    }
183033965Sjdp	}
183133965Sjdp      else if (resultP->X_op == O_symbol
183233965Sjdp	       && right.X_op == O_symbol
183333965Sjdp	       && (op_left == O_add
183433965Sjdp		   || op_left == O_subtract
183533965Sjdp		   || (resultP->X_add_number == 0
183633965Sjdp		       && right.X_add_number == 0)))
183733965Sjdp	{
183833965Sjdp	  /* Symbol OP symbol.  */
183933965Sjdp	  resultP->X_op = op_left;
184033965Sjdp	  resultP->X_op_symbol = right.X_add_symbol;
184133965Sjdp	  if (op_left == O_add)
184233965Sjdp	    resultP->X_add_number += right.X_add_number;
184333965Sjdp	  else if (op_left == O_subtract)
184489857Sobrien	    {
184589857Sobrien	      resultP->X_add_number -= right.X_add_number;
184689857Sobrien	      if (retval == rightseg && SEG_NORMAL (retval))
184789857Sobrien		{
184889857Sobrien		  retval = absolute_section;
184989857Sobrien		  rightseg = absolute_section;
185089857Sobrien		}
185189857Sobrien	    }
185233965Sjdp	}
185333965Sjdp      else
185433965Sjdp	{
185533965Sjdp	  /* The general case.  */
185633965Sjdp	  resultP->X_add_symbol = make_expr_symbol (resultP);
185733965Sjdp	  resultP->X_op_symbol = make_expr_symbol (&right);
185833965Sjdp	  resultP->X_op = op_left;
185933965Sjdp	  resultP->X_add_number = 0;
186033965Sjdp	  resultP->X_unsigned = 1;
186133965Sjdp	}
186233965Sjdp
186389857Sobrien      if (retval != rightseg)
186489857Sobrien	{
186589857Sobrien	  if (! SEG_NORMAL (retval))
186689857Sobrien	    {
186789857Sobrien	      if (retval != undefined_section || SEG_NORMAL (rightseg))
186889857Sobrien		retval = rightseg;
186989857Sobrien	    }
187089857Sobrien	  else if (SEG_NORMAL (rightseg)
187189857Sobrien#ifdef DIFF_EXPR_OK
187289857Sobrien		   && op_left != O_subtract
187389857Sobrien#endif
187489857Sobrien		   )
187589857Sobrien	    as_bad (_("operation combines symbols in different segments"));
187689857Sobrien	}
187789857Sobrien
187833965Sjdp      op_left = op_right;
187977298Sobrien    }				/* While next operator is >= this rank.  */
188033965Sjdp
188133965Sjdp  /* The PA port needs this information.  */
188233965Sjdp  if (resultP->X_add_symbol)
188360484Sobrien    symbol_mark_used (resultP->X_add_symbol);
188433965Sjdp
1885218822Sdim  if (rank == 0 && mode == expr_evaluate)
1886218822Sdim    resolve_expression (resultP);
1887218822Sdim
188833965Sjdp  return resultP->X_op == O_constant ? absolute_section : retval;
188933965Sjdp}
1890218822Sdim
1891218822Sdim/* Resolve an expression without changing any symbols/sub-expressions
1892218822Sdim   used.  */
1893218822Sdim
1894218822Sdimint
1895218822Sdimresolve_expression (expressionS *expressionP)
1896218822Sdim{
1897218822Sdim  /* Help out with CSE.  */
1898218822Sdim  valueT final_val = expressionP->X_add_number;
1899218822Sdim  symbolS *add_symbol = expressionP->X_add_symbol;
1900218822Sdim  symbolS *op_symbol = expressionP->X_op_symbol;
1901218822Sdim  operatorT op = expressionP->X_op;
1902218822Sdim  valueT left, right;
1903218822Sdim  segT seg_left, seg_right;
1904218822Sdim  fragS *frag_left, *frag_right;
1905218822Sdim  bfd_vma frag_off;
1906218822Sdim
1907218822Sdim  switch (op)
1908218822Sdim    {
1909218822Sdim    default:
1910218822Sdim      return 0;
1911218822Sdim
1912218822Sdim    case O_constant:
1913218822Sdim    case O_register:
1914218822Sdim      left = 0;
1915218822Sdim      break;
1916218822Sdim
1917218822Sdim    case O_symbol:
1918218822Sdim    case O_symbol_rva:
1919218822Sdim      if (!snapshot_symbol (&add_symbol, &left, &seg_left, &frag_left))
1920218822Sdim	return 0;
1921218822Sdim
1922218822Sdim      break;
1923218822Sdim
1924218822Sdim    case O_uminus:
1925218822Sdim    case O_bit_not:
1926218822Sdim    case O_logical_not:
1927218822Sdim      if (!snapshot_symbol (&add_symbol, &left, &seg_left, &frag_left))
1928218822Sdim	return 0;
1929218822Sdim
1930218822Sdim      if (seg_left != absolute_section)
1931218822Sdim	return 0;
1932218822Sdim
1933218822Sdim      if (op == O_logical_not)
1934218822Sdim	left = !left;
1935218822Sdim      else if (op == O_uminus)
1936218822Sdim	left = -left;
1937218822Sdim      else
1938218822Sdim	left = ~left;
1939218822Sdim      op = O_constant;
1940218822Sdim      break;
1941218822Sdim
1942218822Sdim    case O_multiply:
1943218822Sdim    case O_divide:
1944218822Sdim    case O_modulus:
1945218822Sdim    case O_left_shift:
1946218822Sdim    case O_right_shift:
1947218822Sdim    case O_bit_inclusive_or:
1948218822Sdim    case O_bit_or_not:
1949218822Sdim    case O_bit_exclusive_or:
1950218822Sdim    case O_bit_and:
1951218822Sdim    case O_add:
1952218822Sdim    case O_subtract:
1953218822Sdim    case O_eq:
1954218822Sdim    case O_ne:
1955218822Sdim    case O_lt:
1956218822Sdim    case O_le:
1957218822Sdim    case O_ge:
1958218822Sdim    case O_gt:
1959218822Sdim    case O_logical_and:
1960218822Sdim    case O_logical_or:
1961218822Sdim      if (!snapshot_symbol (&add_symbol, &left, &seg_left, &frag_left)
1962218822Sdim	  || !snapshot_symbol (&op_symbol, &right, &seg_right, &frag_right))
1963218822Sdim	return 0;
1964218822Sdim
1965218822Sdim      /* Simplify addition or subtraction of a constant by folding the
1966218822Sdim	 constant into X_add_number.  */
1967218822Sdim      if (op == O_add)
1968218822Sdim	{
1969218822Sdim	  if (seg_right == absolute_section)
1970218822Sdim	    {
1971218822Sdim	      final_val += right;
1972218822Sdim	      op = O_symbol;
1973218822Sdim	      break;
1974218822Sdim	    }
1975218822Sdim	  else if (seg_left == absolute_section)
1976218822Sdim	    {
1977218822Sdim	      final_val += left;
1978218822Sdim	      left = right;
1979218822Sdim	      seg_left = seg_right;
1980218822Sdim	      add_symbol = op_symbol;
1981218822Sdim	      op = O_symbol;
1982218822Sdim	      break;
1983218822Sdim	    }
1984218822Sdim	}
1985218822Sdim      else if (op == O_subtract)
1986218822Sdim	{
1987218822Sdim	  if (seg_right == absolute_section)
1988218822Sdim	    {
1989218822Sdim	      final_val -= right;
1990218822Sdim	      op = O_symbol;
1991218822Sdim	      break;
1992218822Sdim	    }
1993218822Sdim	}
1994218822Sdim
1995218822Sdim      /* Equality and non-equality tests are permitted on anything.
1996218822Sdim	 Subtraction, and other comparison operators are permitted if
1997218822Sdim	 both operands are in the same section.
1998218822Sdim	 Shifts by constant zero are permitted on anything.
1999218822Sdim	 Multiplies, bit-ors, and bit-ands with constant zero are
2000218822Sdim	 permitted on anything.
2001218822Sdim	 Multiplies and divides by constant one are permitted on
2002218822Sdim	 anything.
2003218822Sdim	 Binary operations with both operands being the same register
2004218822Sdim	 or undefined symbol are permitted if the result doesn't depend
2005218822Sdim	 on the input value.
2006218822Sdim	 Otherwise, both operands must be absolute.  We already handled
2007218822Sdim	 the case of addition or subtraction of a constant above.  */
2008218822Sdim      frag_off = 0;
2009218822Sdim      if (!(seg_left == absolute_section
2010218822Sdim	       && seg_right == absolute_section)
2011218822Sdim	  && !(op == O_eq || op == O_ne)
2012218822Sdim	  && !((op == O_subtract
2013218822Sdim		|| op == O_lt || op == O_le || op == O_ge || op == O_gt)
2014218822Sdim	       && seg_left == seg_right
2015218822Sdim	       && (finalize_syms
2016218822Sdim		   || frag_offset_fixed_p (frag_left, frag_right, &frag_off))
2017218822Sdim	       && (seg_left != reg_section || left == right)
2018218822Sdim	       && (seg_left != undefined_section || add_symbol == op_symbol)))
2019218822Sdim	{
2020218822Sdim	  if ((seg_left == absolute_section && left == 0)
2021218822Sdim	      || (seg_right == absolute_section && right == 0))
2022218822Sdim	    {
2023218822Sdim	      if (op == O_bit_exclusive_or || op == O_bit_inclusive_or)
2024218822Sdim		{
2025218822Sdim		  if (seg_right != absolute_section || right != 0)
2026218822Sdim		    {
2027218822Sdim		      seg_left = seg_right;
2028218822Sdim		      left = right;
2029218822Sdim		      add_symbol = op_symbol;
2030218822Sdim		    }
2031218822Sdim		  op = O_symbol;
2032218822Sdim		  break;
2033218822Sdim		}
2034218822Sdim	      else if (op == O_left_shift || op == O_right_shift)
2035218822Sdim		{
2036218822Sdim		  if (seg_left != absolute_section || left != 0)
2037218822Sdim		    {
2038218822Sdim		      op = O_symbol;
2039218822Sdim		      break;
2040218822Sdim		    }
2041218822Sdim		}
2042218822Sdim	      else if (op != O_multiply
2043218822Sdim		       && op != O_bit_or_not && op != O_bit_and)
2044218822Sdim	        return 0;
2045218822Sdim	    }
2046218822Sdim	  else if (op == O_multiply
2047218822Sdim		   && seg_left == absolute_section && left == 1)
2048218822Sdim	    {
2049218822Sdim	      seg_left = seg_right;
2050218822Sdim	      left = right;
2051218822Sdim	      add_symbol = op_symbol;
2052218822Sdim	      op = O_symbol;
2053218822Sdim	      break;
2054218822Sdim	    }
2055218822Sdim	  else if ((op == O_multiply || op == O_divide)
2056218822Sdim		   && seg_right == absolute_section && right == 1)
2057218822Sdim	    {
2058218822Sdim	      op = O_symbol;
2059218822Sdim	      break;
2060218822Sdim	    }
2061218822Sdim	  else if (left != right
2062218822Sdim		   || ((seg_left != reg_section || seg_right != reg_section)
2063218822Sdim		       && (seg_left != undefined_section
2064218822Sdim			   || seg_right != undefined_section
2065218822Sdim			   || add_symbol != op_symbol)))
2066218822Sdim	    return 0;
2067218822Sdim	  else if (op == O_bit_and || op == O_bit_inclusive_or)
2068218822Sdim	    {
2069218822Sdim	      op = O_symbol;
2070218822Sdim	      break;
2071218822Sdim	    }
2072218822Sdim	  else if (op != O_bit_exclusive_or && op != O_bit_or_not)
2073218822Sdim	    return 0;
2074218822Sdim	}
2075218822Sdim
2076218822Sdim      right += frag_off / OCTETS_PER_BYTE;
2077218822Sdim      switch (op)
2078218822Sdim	{
2079218822Sdim	case O_add:			left += right; break;
2080218822Sdim	case O_subtract:		left -= right; break;
2081218822Sdim	case O_multiply:		left *= right; break;
2082218822Sdim	case O_divide:
2083218822Sdim	  if (right == 0)
2084218822Sdim	    return 0;
2085218822Sdim	  left = (offsetT) left / (offsetT) right;
2086218822Sdim	  break;
2087218822Sdim	case O_modulus:
2088218822Sdim	  if (right == 0)
2089218822Sdim	    return 0;
2090218822Sdim	  left = (offsetT) left % (offsetT) right;
2091218822Sdim	  break;
2092218822Sdim	case O_left_shift:		left <<= right; break;
2093218822Sdim	case O_right_shift:		left >>= right; break;
2094218822Sdim	case O_bit_inclusive_or:	left |= right; break;
2095218822Sdim	case O_bit_or_not:		left |= ~right; break;
2096218822Sdim	case O_bit_exclusive_or:	left ^= right; break;
2097218822Sdim	case O_bit_and:			left &= right; break;
2098218822Sdim	case O_eq:
2099218822Sdim	case O_ne:
2100218822Sdim	  left = (left == right
2101218822Sdim		  && seg_left == seg_right
2102218822Sdim		  && (finalize_syms || frag_left == frag_right)
2103218822Sdim		  && (seg_left != undefined_section
2104218822Sdim		      || add_symbol == op_symbol)
2105218822Sdim		  ? ~ (valueT) 0 : 0);
2106218822Sdim	  if (op == O_ne)
2107218822Sdim	    left = ~left;
2108218822Sdim	  break;
2109218822Sdim	case O_lt:
2110218822Sdim	  left = (offsetT) left <  (offsetT) right ? ~ (valueT) 0 : 0;
2111218822Sdim	  break;
2112218822Sdim	case O_le:
2113218822Sdim	  left = (offsetT) left <= (offsetT) right ? ~ (valueT) 0 : 0;
2114218822Sdim	  break;
2115218822Sdim	case O_ge:
2116218822Sdim	  left = (offsetT) left >= (offsetT) right ? ~ (valueT) 0 : 0;
2117218822Sdim	  break;
2118218822Sdim	case O_gt:
2119218822Sdim	  left = (offsetT) left >  (offsetT) right ? ~ (valueT) 0 : 0;
2120218822Sdim	  break;
2121218822Sdim	case O_logical_and:	left = left && right; break;
2122218822Sdim	case O_logical_or:	left = left || right; break;
2123218822Sdim	default:		abort ();
2124218822Sdim	}
2125218822Sdim
2126218822Sdim      op = O_constant;
2127218822Sdim      break;
2128218822Sdim    }
2129218822Sdim
2130218822Sdim  if (op == O_symbol)
2131218822Sdim    {
2132218822Sdim      if (seg_left == absolute_section)
2133218822Sdim	op = O_constant;
2134218822Sdim      else if (seg_left == reg_section && final_val == 0)
2135218822Sdim	op = O_register;
2136218822Sdim      else if (add_symbol != expressionP->X_add_symbol)
2137218822Sdim	final_val += left;
2138218822Sdim      expressionP->X_add_symbol = add_symbol;
2139218822Sdim    }
2140218822Sdim  expressionP->X_op = op;
2141218822Sdim
2142218822Sdim  if (op == O_constant || op == O_register)
2143218822Sdim    final_val += left;
2144218822Sdim  expressionP->X_add_number = final_val;
2145218822Sdim
2146218822Sdim  return 1;
2147218822Sdim}
214833965Sjdp
214977298Sobrien/* This lives here because it belongs equally in expr.c & read.c.
215077298Sobrien   expr.c is just a branch office read.c anyway, and putting it
215177298Sobrien   here lessens the crowd at read.c.
215277298Sobrien
215377298Sobrien   Assume input_line_pointer is at start of symbol name.
215477298Sobrien   Advance input_line_pointer past symbol name.
215577298Sobrien   Turn that character into a '\0', returning its former value.
215677298Sobrien   This allows a string compare (RMS wants symbol names to be strings)
215777298Sobrien   of the symbol name.
215877298Sobrien   There will always be a char following symbol name, because all good
215977298Sobrien   lines end in end-of-line.  */
216077298Sobrien
216133965Sjdpchar
2162130561Sobrienget_symbol_end (void)
216333965Sjdp{
216433965Sjdp  char c;
216533965Sjdp
216633965Sjdp  /* We accept \001 in a name in case this is being called with a
216733965Sjdp     constructed string.  */
216833965Sjdp  if (is_name_beginner (c = *input_line_pointer++) || c == '\001')
216960484Sobrien    {
217060484Sobrien      while (is_part_of_name (c = *input_line_pointer++)
217160484Sobrien	     || c == '\001')
217260484Sobrien	;
217360484Sobrien      if (is_name_ender (c))
217460484Sobrien	c = *input_line_pointer++;
217560484Sobrien    }
217633965Sjdp  *--input_line_pointer = 0;
217733965Sjdp  return (c);
217833965Sjdp}
217933965Sjdp
218033965Sjdpunsigned int
2181130561Sobrienget_single_number (void)
218233965Sjdp{
218333965Sjdp  expressionS exp;
2184218822Sdim  operand (&exp, expr_normal);
218533965Sjdp  return exp.X_add_number;
218633965Sjdp}
2187