expr.c revision 218822
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];
1043218822Sdim		if (c == '-')
1044218822Sdim		  for (i = 0; i < expressionP->X_add_number; ++i)
1045218822Sdim		    {
1046218822Sdim		      generic_bignum[i] += 1;
1047218822Sdim		      if (generic_bignum[i])
1048218822Sdim			break;
1049218822Sdim		    }
1050218822Sdim	      }
1051218822Sdim	    else if (c == '!')
1052218822Sdim	      {
1053218822Sdim		int nonzero = 0;
1054218822Sdim		for (i = 0; i < expressionP->X_add_number; ++i)
1055218822Sdim		  {
1056218822Sdim		    if (generic_bignum[i])
1057218822Sdim		      nonzero = 1;
1058218822Sdim		    generic_bignum[i] = 0;
1059218822Sdim		  }
1060218822Sdim		generic_bignum[0] = nonzero;
1061218822Sdim	      }
1062218822Sdim	  }
106333965Sjdp	else if (expressionP->X_op != O_illegal
106433965Sjdp		 && expressionP->X_op != O_absent)
106533965Sjdp	  {
1066218822Sdim	    if (c != '+')
1067218822Sdim	      {
1068218822Sdim		expressionP->X_add_symbol = make_expr_symbol (expressionP);
1069218822Sdim		if (c == '-')
1070218822Sdim		  expressionP->X_op = O_uminus;
1071218822Sdim		else if (c == '~' || c == '"')
1072218822Sdim		  expressionP->X_op = O_bit_not;
1073218822Sdim		else
1074218822Sdim		  expressionP->X_op = O_logical_not;
1075218822Sdim		expressionP->X_add_number = 0;
1076218822Sdim	      }
107733965Sjdp	  }
107833965Sjdp	else
107960484Sobrien	  as_warn (_("Unary operator %c ignored because bad operand follows"),
108033965Sjdp		   c);
108133965Sjdp      }
108233965Sjdp      break;
108333965Sjdp
108460484Sobrien#if defined (DOLLAR_DOT) || defined (TC_M68K)
108533965Sjdp    case '$':
108677298Sobrien      /* '$' is the program counter when in MRI mode, or when
1087130561Sobrien	 DOLLAR_DOT is defined.  */
108833965Sjdp#ifndef DOLLAR_DOT
108933965Sjdp      if (! flag_m68k_mri)
109033965Sjdp	goto de_fault;
109133965Sjdp#endif
1092218822Sdim      if (DOLLAR_AMBIGU && hex_p (*input_line_pointer))
109333965Sjdp	{
1094218822Sdim	  /* In MRI mode and on Z80, '$' is also used as the prefix
1095218822Sdim	     for a hexadecimal constant.  */
109633965Sjdp	  integer_constant (16, expressionP);
109733965Sjdp	  break;
109833965Sjdp	}
109933965Sjdp
110033965Sjdp      if (is_part_of_name (*input_line_pointer))
110133965Sjdp	goto isname;
110233965Sjdp
110333965Sjdp      current_location (expressionP);
110433965Sjdp      break;
110560484Sobrien#endif
110633965Sjdp
110733965Sjdp    case '.':
110833965Sjdp      if (!is_part_of_name (*input_line_pointer))
110933965Sjdp	{
111033965Sjdp	  current_location (expressionP);
111133965Sjdp	  break;
111233965Sjdp	}
111333965Sjdp      else if ((strncasecmp (input_line_pointer, "startof.", 8) == 0
111433965Sjdp		&& ! is_part_of_name (input_line_pointer[8]))
111533965Sjdp	       || (strncasecmp (input_line_pointer, "sizeof.", 7) == 0
111633965Sjdp		   && ! is_part_of_name (input_line_pointer[7])))
111733965Sjdp	{
111833965Sjdp	  int start;
111933965Sjdp
112033965Sjdp	  start = (input_line_pointer[1] == 't'
112133965Sjdp		   || input_line_pointer[1] == 'T');
112233965Sjdp	  input_line_pointer += start ? 8 : 7;
112333965Sjdp	  SKIP_WHITESPACE ();
112433965Sjdp	  if (*input_line_pointer != '(')
112560484Sobrien	    as_bad (_("syntax error in .startof. or .sizeof."));
112633965Sjdp	  else
112733965Sjdp	    {
112833965Sjdp	      char *buf;
112933965Sjdp
113033965Sjdp	      ++input_line_pointer;
113133965Sjdp	      SKIP_WHITESPACE ();
113233965Sjdp	      name = input_line_pointer;
113333965Sjdp	      c = get_symbol_end ();
113433965Sjdp
113533965Sjdp	      buf = (char *) xmalloc (strlen (name) + 10);
113633965Sjdp	      if (start)
113733965Sjdp		sprintf (buf, ".startof.%s", name);
113833965Sjdp	      else
113933965Sjdp		sprintf (buf, ".sizeof.%s", name);
114033965Sjdp	      symbolP = symbol_make (buf);
114133965Sjdp	      free (buf);
114233965Sjdp
114333965Sjdp	      expressionP->X_op = O_symbol;
114433965Sjdp	      expressionP->X_add_symbol = symbolP;
114533965Sjdp	      expressionP->X_add_number = 0;
114633965Sjdp
114733965Sjdp	      *input_line_pointer = c;
114833965Sjdp	      SKIP_WHITESPACE ();
114933965Sjdp	      if (*input_line_pointer != ')')
115060484Sobrien		as_bad (_("syntax error in .startof. or .sizeof."));
115133965Sjdp	      else
115233965Sjdp		++input_line_pointer;
115333965Sjdp	    }
115433965Sjdp	  break;
115533965Sjdp	}
115633965Sjdp      else
115733965Sjdp	{
115833965Sjdp	  goto isname;
115933965Sjdp	}
116077298Sobrien
116133965Sjdp    case ',':
116233965Sjdp    eol:
116377298Sobrien      /* Can't imagine any other kind of operand.  */
116433965Sjdp      expressionP->X_op = O_absent;
116533965Sjdp      input_line_pointer--;
116633965Sjdp      break;
116733965Sjdp
116860484Sobrien#ifdef TC_M68K
116933965Sjdp    case '%':
117033965Sjdp      if (! flag_m68k_mri)
117133965Sjdp	goto de_fault;
117233965Sjdp      integer_constant (2, expressionP);
117333965Sjdp      break;
117433965Sjdp
117533965Sjdp    case '@':
117633965Sjdp      if (! flag_m68k_mri)
117733965Sjdp	goto de_fault;
117833965Sjdp      integer_constant (8, expressionP);
117933965Sjdp      break;
118033965Sjdp
118133965Sjdp    case ':':
118233965Sjdp      if (! flag_m68k_mri)
118333965Sjdp	goto de_fault;
118433965Sjdp
118533965Sjdp      /* In MRI mode, this is a floating point constant represented
1186130561Sobrien	 using hexadecimal digits.  */
118733965Sjdp
118833965Sjdp      ++input_line_pointer;
118933965Sjdp      integer_constant (16, expressionP);
119033965Sjdp      break;
119133965Sjdp
119233965Sjdp    case '*':
119333965Sjdp      if (! flag_m68k_mri || is_part_of_name (*input_line_pointer))
119433965Sjdp	goto de_fault;
119533965Sjdp
119633965Sjdp      current_location (expressionP);
119733965Sjdp      break;
119860484Sobrien#endif
119933965Sjdp
120033965Sjdp    default:
120160484Sobrien#ifdef TC_M68K
120233965Sjdp    de_fault:
120360484Sobrien#endif
120477298Sobrien      if (is_name_beginner (c))	/* Here if did not begin with a digit.  */
120533965Sjdp	{
120677298Sobrien	  /* Identifier begins here.
120777298Sobrien	     This is kludged for speed, so code is repeated.  */
120833965Sjdp	isname:
120933965Sjdp	  name = --input_line_pointer;
121033965Sjdp	  c = get_symbol_end ();
121133965Sjdp
121233965Sjdp#ifdef md_parse_name
121333965Sjdp	  /* This is a hook for the backend to parse certain names
1214130561Sobrien	     specially in certain contexts.  If a name always has a
1215130561Sobrien	     specific value, it can often be handled by simply
1216130561Sobrien	     entering it in the symbol table.  */
1217218822Sdim	  if (md_parse_name (name, expressionP, mode, &c))
121833965Sjdp	    {
121933965Sjdp	      *input_line_pointer = c;
122033965Sjdp	      break;
122133965Sjdp	    }
122233965Sjdp#endif
122333965Sjdp
122433965Sjdp#ifdef TC_I960
122533965Sjdp	  /* The MRI i960 assembler permits
122633965Sjdp	         lda sizeof code,g13
122733965Sjdp	     FIXME: This should use md_parse_name.  */
122833965Sjdp	  if (flag_mri
122933965Sjdp	      && (strcasecmp (name, "sizeof") == 0
123033965Sjdp		  || strcasecmp (name, "startof") == 0))
123133965Sjdp	    {
123233965Sjdp	      int start;
123333965Sjdp	      char *buf;
123433965Sjdp
123533965Sjdp	      start = (name[1] == 't'
123633965Sjdp		       || name[1] == 'T');
123733965Sjdp
123833965Sjdp	      *input_line_pointer = c;
123933965Sjdp	      SKIP_WHITESPACE ();
124033965Sjdp
124133965Sjdp	      name = input_line_pointer;
124233965Sjdp	      c = get_symbol_end ();
124333965Sjdp
124433965Sjdp	      buf = (char *) xmalloc (strlen (name) + 10);
124533965Sjdp	      if (start)
124633965Sjdp		sprintf (buf, ".startof.%s", name);
124733965Sjdp	      else
124833965Sjdp		sprintf (buf, ".sizeof.%s", name);
124933965Sjdp	      symbolP = symbol_make (buf);
125033965Sjdp	      free (buf);
125133965Sjdp
125233965Sjdp	      expressionP->X_op = O_symbol;
125333965Sjdp	      expressionP->X_add_symbol = symbolP;
125433965Sjdp	      expressionP->X_add_number = 0;
125533965Sjdp
125633965Sjdp	      *input_line_pointer = c;
125733965Sjdp	      SKIP_WHITESPACE ();
125833965Sjdp
125933965Sjdp	      break;
126077298Sobrien	    }
126133965Sjdp#endif
126233965Sjdp
126333965Sjdp	  symbolP = symbol_find_or_make (name);
126433965Sjdp
126533965Sjdp	  /* If we have an absolute symbol or a reg, then we know its
126633965Sjdp	     value now.  */
126733965Sjdp	  segment = S_GET_SEGMENT (symbolP);
1268218822Sdim	  if (mode != expr_defer && segment == absolute_section)
126933965Sjdp	    {
127033965Sjdp	      expressionP->X_op = O_constant;
127133965Sjdp	      expressionP->X_add_number = S_GET_VALUE (symbolP);
127233965Sjdp	    }
1273218822Sdim	  else if (mode != expr_defer && segment == reg_section)
127433965Sjdp	    {
127533965Sjdp	      expressionP->X_op = O_register;
127633965Sjdp	      expressionP->X_add_number = S_GET_VALUE (symbolP);
127733965Sjdp	    }
127833965Sjdp	  else
127933965Sjdp	    {
128033965Sjdp	      expressionP->X_op = O_symbol;
128133965Sjdp	      expressionP->X_add_symbol = symbolP;
128233965Sjdp	      expressionP->X_add_number = 0;
128333965Sjdp	    }
128433965Sjdp	  *input_line_pointer = c;
128533965Sjdp	}
128633965Sjdp      else
128733965Sjdp	{
128833965Sjdp	  /* Let the target try to parse it.  Success is indicated by changing
128933965Sjdp	     the X_op field to something other than O_absent and pointing
129077298Sobrien	     input_line_pointer past the expression.  If it can't parse the
129133965Sjdp	     expression, X_op and input_line_pointer should be unchanged.  */
129233965Sjdp	  expressionP->X_op = O_absent;
129333965Sjdp	  --input_line_pointer;
129433965Sjdp	  md_operand (expressionP);
129533965Sjdp	  if (expressionP->X_op == O_absent)
129633965Sjdp	    {
129733965Sjdp	      ++input_line_pointer;
129889857Sobrien	      as_bad (_("bad expression"));
129933965Sjdp	      expressionP->X_op = O_constant;
130033965Sjdp	      expressionP->X_add_number = 0;
130133965Sjdp	    }
130233965Sjdp	}
130333965Sjdp      break;
130433965Sjdp    }
130533965Sjdp
130677298Sobrien  /* It is more 'efficient' to clean up the expressionS when they are
130777298Sobrien     created.  Doing it here saves lines of code.  */
130833965Sjdp  clean_up_expression (expressionP);
130977298Sobrien  SKIP_WHITESPACE ();		/* -> 1st char after operand.  */
131033965Sjdp  know (*input_line_pointer != ' ');
131133965Sjdp
131233965Sjdp  /* The PA port needs this information.  */
131333965Sjdp  if (expressionP->X_add_symbol)
131460484Sobrien    symbol_mark_used (expressionP->X_add_symbol);
131533965Sjdp
1316218822Sdim  expressionP->X_add_symbol = symbol_clone_if_forward_ref (expressionP->X_add_symbol);
1317218822Sdim  expressionP->X_op_symbol = symbol_clone_if_forward_ref (expressionP->X_op_symbol);
1318218822Sdim
131933965Sjdp  switch (expressionP->X_op)
132033965Sjdp    {
132133965Sjdp    default:
132233965Sjdp      return absolute_section;
132333965Sjdp    case O_symbol:
132433965Sjdp      return S_GET_SEGMENT (expressionP->X_add_symbol);
132533965Sjdp    case O_register:
132633965Sjdp      return reg_section;
132733965Sjdp    }
132877298Sobrien}
132933965Sjdp
133077298Sobrien/* Internal.  Simplify a struct expression for use by expr ().  */
133133965Sjdp
133289857Sobrien/* In:	address of an expressionS.
133377298Sobrien	The X_op field of the expressionS may only take certain values.
133477298Sobrien	Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT.
133533965Sjdp
133677298Sobrien   Out:	expressionS may have been modified:
133777298Sobrien	Unused fields zeroed to help expr ().  */
133877298Sobrien
133933965Sjdpstatic void
1340130561Sobrienclean_up_expression (expressionS *expressionP)
134133965Sjdp{
134233965Sjdp  switch (expressionP->X_op)
134333965Sjdp    {
134433965Sjdp    case O_illegal:
134533965Sjdp    case O_absent:
134633965Sjdp      expressionP->X_add_number = 0;
134733965Sjdp      /* Fall through.  */
134833965Sjdp    case O_big:
134933965Sjdp    case O_constant:
135033965Sjdp    case O_register:
135133965Sjdp      expressionP->X_add_symbol = NULL;
135233965Sjdp      /* Fall through.  */
135333965Sjdp    case O_symbol:
135433965Sjdp    case O_uminus:
135533965Sjdp    case O_bit_not:
135633965Sjdp      expressionP->X_op_symbol = NULL;
135733965Sjdp      break;
135833965Sjdp    default:
135933965Sjdp      break;
136033965Sjdp    }
136133965Sjdp}
136233965Sjdp
136377298Sobrien/* Expression parser.  */
136433965Sjdp
136577298Sobrien/* We allow an empty expression, and just assume (absolute,0) silently.
136677298Sobrien   Unary operators and parenthetical expressions are treated as operands.
136777298Sobrien   As usual, Q==quantity==operand, O==operator, X==expression mnemonics.
136833965Sjdp
136989857Sobrien   We used to do an aho/ullman shift-reduce parser, but the logic got so
137077298Sobrien   warped that I flushed it and wrote a recursive-descent parser instead.
137177298Sobrien   Now things are stable, would anybody like to write a fast parser?
137277298Sobrien   Most expressions are either register (which does not even reach here)
137377298Sobrien   or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common.
137477298Sobrien   So I guess it doesn't really matter how inefficient more complex expressions
137577298Sobrien   are parsed.
137677298Sobrien
137777298Sobrien   After expr(RANK,resultP) input_line_pointer->operator of rank <= RANK.
137877298Sobrien   Also, we have consumed any leading or trailing spaces (operand does that)
137977298Sobrien   and done all intervening operators.
138077298Sobrien
138177298Sobrien   This returns the segment of the result, which will be
138277298Sobrien   absolute_section or the segment of a symbol.  */
138377298Sobrien
138433965Sjdp#undef __
138533965Sjdp#define __ O_illegal
1386218822Sdim#ifndef O_SINGLE_EQ
1387218822Sdim#define O_SINGLE_EQ O_illegal
1388218822Sdim#endif
138933965Sjdp
139077298Sobrien/* Maps ASCII -> operators.  */
139177298Sobrienstatic const operatorT op_encoding[256] = {
139233965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
139333965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
139433965Sjdp
139533965Sjdp  __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __,
139633965Sjdp  __, __, O_multiply, O_add, __, O_subtract, __, O_divide,
139733965Sjdp  __, __, __, __, __, __, __, __,
1398218822Sdim  __, __, __, __, O_lt, O_SINGLE_EQ, O_gt, __,
139933965Sjdp  __, __, __, __, __, __, __, __,
140033965Sjdp  __, __, __, __, __, __, __, __,
140133965Sjdp  __, __, __, __, __, __, __, __,
140260484Sobrien  __, __, __,
140360484Sobrien#ifdef NEED_INDEX_OPERATOR
140460484Sobrien  O_index,
140560484Sobrien#else
140660484Sobrien  __,
140760484Sobrien#endif
140860484Sobrien  __, __, O_bit_exclusive_or, __,
140933965Sjdp  __, __, __, __, __, __, __, __,
141033965Sjdp  __, __, __, __, __, __, __, __,
141133965Sjdp  __, __, __, __, __, __, __, __,
141233965Sjdp  __, __, __, __, O_bit_inclusive_or, __, __, __,
141333965Sjdp
141433965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
141533965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
141633965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
141733965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
141833965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
141933965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142033965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142133965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
142233965Sjdp};
142333965Sjdp
142477298Sobrien/* Rank	Examples
142577298Sobrien   0	operand, (expression)
142677298Sobrien   1	||
142777298Sobrien   2	&&
142889857Sobrien   3	== <> < <= >= >
142977298Sobrien   4	+ -
143077298Sobrien   5	used for * / % in MRI mode
143177298Sobrien   6	& ^ ! |
143277298Sobrien   7	* / % << >>
143377298Sobrien   8	unary - unary ~
143477298Sobrien*/
143577298Sobrienstatic operator_rankT op_rank[] = {
143633965Sjdp  0,	/* O_illegal */
143733965Sjdp  0,	/* O_absent */
143833965Sjdp  0,	/* O_constant */
143933965Sjdp  0,	/* O_symbol */
144033965Sjdp  0,	/* O_symbol_rva */
144133965Sjdp  0,	/* O_register */
144277298Sobrien  0,	/* O_big */
144360484Sobrien  9,	/* O_uminus */
144460484Sobrien  9,	/* O_bit_not */
144560484Sobrien  9,	/* O_logical_not */
144660484Sobrien  8,	/* O_multiply */
144760484Sobrien  8,	/* O_divide */
144860484Sobrien  8,	/* O_modulus */
144960484Sobrien  8,	/* O_left_shift */
145060484Sobrien  8,	/* O_right_shift */
145160484Sobrien  7,	/* O_bit_inclusive_or */
145260484Sobrien  7,	/* O_bit_or_not */
145360484Sobrien  7,	/* O_bit_exclusive_or */
145460484Sobrien  7,	/* O_bit_and */
145560484Sobrien  5,	/* O_add */
145660484Sobrien  5,	/* O_subtract */
145760484Sobrien  4,	/* O_eq */
145860484Sobrien  4,	/* O_ne */
145960484Sobrien  4,	/* O_lt */
146060484Sobrien  4,	/* O_le */
146160484Sobrien  4,	/* O_ge */
146260484Sobrien  4,	/* O_gt */
146360484Sobrien  3,	/* O_logical_and */
146460484Sobrien  2,	/* O_logical_or */
146560484Sobrien  1,	/* O_index */
146660484Sobrien  0,	/* O_md1 */
146760484Sobrien  0,	/* O_md2 */
146860484Sobrien  0,	/* O_md3 */
146960484Sobrien  0,	/* O_md4 */
147060484Sobrien  0,	/* O_md5 */
147160484Sobrien  0,	/* O_md6 */
147260484Sobrien  0,	/* O_md7 */
147360484Sobrien  0,	/* O_md8 */
147460484Sobrien  0,	/* O_md9 */
147560484Sobrien  0,	/* O_md10 */
147660484Sobrien  0,	/* O_md11 */
147760484Sobrien  0,	/* O_md12 */
147860484Sobrien  0,	/* O_md13 */
147960484Sobrien  0,	/* O_md14 */
148060484Sobrien  0,	/* O_md15 */
148160484Sobrien  0,	/* O_md16 */
148233965Sjdp};
148333965Sjdp
148460484Sobrien/* Unfortunately, in MRI mode for the m68k, multiplication and
148560484Sobrien   division have lower precedence than the bit wise operators.  This
148660484Sobrien   function sets the operator precedences correctly for the current
148760484Sobrien   mode.  Also, MRI uses a different bit_not operator, and this fixes
148860484Sobrien   that as well.  */
148933965Sjdp
149077298Sobrien#define STANDARD_MUL_PRECEDENCE 8
149177298Sobrien#define MRI_MUL_PRECEDENCE 6
149260484Sobrien
149333965Sjdpvoid
1494130561Sobrienexpr_set_precedence (void)
149533965Sjdp{
149633965Sjdp  if (flag_m68k_mri)
149733965Sjdp    {
149860484Sobrien      op_rank[O_multiply] = MRI_MUL_PRECEDENCE;
149960484Sobrien      op_rank[O_divide] = MRI_MUL_PRECEDENCE;
150060484Sobrien      op_rank[O_modulus] = MRI_MUL_PRECEDENCE;
150133965Sjdp    }
150260484Sobrien  else
150360484Sobrien    {
150460484Sobrien      op_rank[O_multiply] = STANDARD_MUL_PRECEDENCE;
150560484Sobrien      op_rank[O_divide] = STANDARD_MUL_PRECEDENCE;
150660484Sobrien      op_rank[O_modulus] = STANDARD_MUL_PRECEDENCE;
150760484Sobrien    }
150860484Sobrien}
150933965Sjdp
151060484Sobrien/* Initialize the expression parser.  */
151160484Sobrien
151260484Sobrienvoid
1513130561Sobrienexpr_begin (void)
151460484Sobrien{
151560484Sobrien  expr_set_precedence ();
151660484Sobrien
151733965Sjdp  /* Verify that X_op field is wide enough.  */
151833965Sjdp  {
151933965Sjdp    expressionS e;
152033965Sjdp    e.X_op = O_max;
152133965Sjdp    assert (e.X_op == O_max);
152233965Sjdp  }
152333965Sjdp}
152433965Sjdp
152577298Sobrien/* Return the encoding for the operator at INPUT_LINE_POINTER, and
152677298Sobrien   sets NUM_CHARS to the number of characters in the operator.
152777298Sobrien   Does not advance INPUT_LINE_POINTER.  */
152833965Sjdp
152933965Sjdpstatic inline operatorT
1530130561Sobrienoperator (int *num_chars)
153133965Sjdp{
153233965Sjdp  int c;
153333965Sjdp  operatorT ret;
153433965Sjdp
153560484Sobrien  c = *input_line_pointer & 0xff;
153677298Sobrien  *num_chars = 1;
153733965Sjdp
153877298Sobrien  if (is_end_of_line[c])
153977298Sobrien    return O_illegal;
154077298Sobrien
154133965Sjdp  switch (c)
154233965Sjdp    {
154333965Sjdp    default:
154433965Sjdp      return op_encoding[c];
154533965Sjdp
1546130561Sobrien    case '+':
1547130561Sobrien    case '-':
1548218822Sdim      return op_encoding[c];
1549130561Sobrien
155033965Sjdp    case '<':
155133965Sjdp      switch (input_line_pointer[1])
155233965Sjdp	{
155333965Sjdp	default:
155433965Sjdp	  return op_encoding[c];
155533965Sjdp	case '<':
155633965Sjdp	  ret = O_left_shift;
155733965Sjdp	  break;
155833965Sjdp	case '>':
155933965Sjdp	  ret = O_ne;
156033965Sjdp	  break;
156133965Sjdp	case '=':
156233965Sjdp	  ret = O_le;
156333965Sjdp	  break;
156433965Sjdp	}
156577298Sobrien      *num_chars = 2;
156633965Sjdp      return ret;
156733965Sjdp
156838889Sjdp    case '=':
156938889Sjdp      if (input_line_pointer[1] != '=')
157038889Sjdp	return op_encoding[c];
157138889Sjdp
157277298Sobrien      *num_chars = 2;
157338889Sjdp      return O_eq;
157438889Sjdp
157533965Sjdp    case '>':
157633965Sjdp      switch (input_line_pointer[1])
157733965Sjdp	{
157833965Sjdp	default:
157933965Sjdp	  return op_encoding[c];
158033965Sjdp	case '>':
158133965Sjdp	  ret = O_right_shift;
158233965Sjdp	  break;
158333965Sjdp	case '=':
158433965Sjdp	  ret = O_ge;
158533965Sjdp	  break;
158633965Sjdp	}
158777298Sobrien      *num_chars = 2;
158833965Sjdp      return ret;
158933965Sjdp
159033965Sjdp    case '!':
1591218822Sdim      switch (input_line_pointer[1])
159233965Sjdp	{
1593218822Sdim	case '!':
1594218822Sdim	  /* We accept !! as equivalent to ^ for MRI compatibility. */
1595218822Sdim	  *num_chars = 2;
1596218822Sdim	  return O_bit_exclusive_or;
1597218822Sdim	case '=':
1598218822Sdim	  /* We accept != as equivalent to <>.  */
1599218822Sdim	  *num_chars = 2;
1600218822Sdim	  return O_ne;
1601218822Sdim	default:
160233965Sjdp	  if (flag_m68k_mri)
160333965Sjdp	    return O_bit_inclusive_or;
160433965Sjdp	  return op_encoding[c];
160533965Sjdp	}
160633965Sjdp
160733965Sjdp    case '|':
160833965Sjdp      if (input_line_pointer[1] != '|')
160933965Sjdp	return op_encoding[c];
161033965Sjdp
161177298Sobrien      *num_chars = 2;
161233965Sjdp      return O_logical_or;
161333965Sjdp
161433965Sjdp    case '&':
161533965Sjdp      if (input_line_pointer[1] != '&')
161633965Sjdp	return op_encoding[c];
161733965Sjdp
161877298Sobrien      *num_chars = 2;
161933965Sjdp      return O_logical_and;
162033965Sjdp    }
162133965Sjdp
162277298Sobrien  /* NOTREACHED  */
162338889Sjdp}
162433965Sjdp
162533965Sjdp/* Parse an expression.  */
162633965Sjdp
162733965SjdpsegT
1628130561Sobrienexpr (int rankarg,		/* Larger # is higher rank.  */
1629218822Sdim      expressionS *resultP,	/* Deliver result here.  */
1630218822Sdim      enum expr_mode mode	/* Controls behavior.  */)
163133965Sjdp{
163260484Sobrien  operator_rankT rank = (operator_rankT) rankarg;
163333965Sjdp  segT retval;
163433965Sjdp  expressionS right;
163533965Sjdp  operatorT op_left;
163633965Sjdp  operatorT op_right;
163777298Sobrien  int op_chars;
163833965Sjdp
1639218822Sdim  know (rankarg >= 0);
164033965Sjdp
1641130561Sobrien  /* Save the value of dot for the fixup code.  */
1642130561Sobrien  if (rank == 0)
1643130561Sobrien    dot_value = frag_now_fix ();
1644130561Sobrien
1645218822Sdim  retval = operand (resultP, mode);
164633965Sjdp
164777298Sobrien  /* operand () gobbles spaces.  */
164877298Sobrien  know (*input_line_pointer != ' ');
164933965Sjdp
165077298Sobrien  op_left = operator (&op_chars);
165133965Sjdp  while (op_left != O_illegal && op_rank[(int) op_left] > rank)
165233965Sjdp    {
165333965Sjdp      segT rightseg;
1654218822Sdim      bfd_vma frag_off;
165533965Sjdp
165677298Sobrien      input_line_pointer += op_chars;	/* -> after operator.  */
165733965Sjdp
1658218822Sdim      rightseg = expr (op_rank[(int) op_left], &right, mode);
165933965Sjdp      if (right.X_op == O_absent)
166033965Sjdp	{
166160484Sobrien	  as_warn (_("missing operand; zero assumed"));
166233965Sjdp	  right.X_op = O_constant;
166333965Sjdp	  right.X_add_number = 0;
166433965Sjdp	  right.X_add_symbol = NULL;
166533965Sjdp	  right.X_op_symbol = NULL;
166633965Sjdp	}
166733965Sjdp
166833965Sjdp      know (*input_line_pointer != ' ');
166933965Sjdp
167060484Sobrien      if (op_left == O_index)
167160484Sobrien	{
167260484Sobrien	  if (*input_line_pointer != ']')
167360484Sobrien	    as_bad ("missing right bracket");
167460484Sobrien	  else
167560484Sobrien	    {
167660484Sobrien	      ++input_line_pointer;
167760484Sobrien	      SKIP_WHITESPACE ();
167860484Sobrien	    }
167960484Sobrien	}
168060484Sobrien
168177298Sobrien      op_right = operator (&op_chars);
168233965Sjdp
168377298Sobrien      know (op_right == O_illegal
168477298Sobrien	    || op_rank[(int) op_right] <= op_rank[(int) op_left]);
168533965Sjdp      know ((int) op_left >= (int) O_multiply
1686218822Sdim	    && (int) op_left <= (int) O_index);
168733965Sjdp
168877298Sobrien      /* input_line_pointer->after right-hand quantity.  */
168977298Sobrien      /* left-hand quantity in resultP.  */
169077298Sobrien      /* right-hand quantity in right.  */
169177298Sobrien      /* operator in op_left.  */
169233965Sjdp
169333965Sjdp      if (resultP->X_op == O_big)
169433965Sjdp	{
169560484Sobrien	  if (resultP->X_add_number > 0)
169660484Sobrien	    as_warn (_("left operand is a bignum; integer 0 assumed"));
169760484Sobrien	  else
169860484Sobrien	    as_warn (_("left operand is a float; integer 0 assumed"));
169933965Sjdp	  resultP->X_op = O_constant;
170033965Sjdp	  resultP->X_add_number = 0;
170133965Sjdp	  resultP->X_add_symbol = NULL;
170233965Sjdp	  resultP->X_op_symbol = NULL;
170333965Sjdp	}
170433965Sjdp      if (right.X_op == O_big)
170533965Sjdp	{
170660484Sobrien	  if (right.X_add_number > 0)
170760484Sobrien	    as_warn (_("right operand is a bignum; integer 0 assumed"));
170860484Sobrien	  else
170960484Sobrien	    as_warn (_("right operand is a float; integer 0 assumed"));
171033965Sjdp	  right.X_op = O_constant;
171133965Sjdp	  right.X_add_number = 0;
171233965Sjdp	  right.X_add_symbol = NULL;
171333965Sjdp	  right.X_op_symbol = NULL;
171433965Sjdp	}
171533965Sjdp
171633965Sjdp      /* Optimize common cases.  */
171777298Sobrien#ifdef md_optimize_expr
171877298Sobrien      if (md_optimize_expr (resultP, op_left, &right))
171977298Sobrien	{
172077298Sobrien	  /* Skip.  */
172177298Sobrien	  ;
172277298Sobrien	}
172377298Sobrien      else
172477298Sobrien#endif
172533965Sjdp      if (op_left == O_add && right.X_op == O_constant)
172633965Sjdp	{
172733965Sjdp	  /* X + constant.  */
172833965Sjdp	  resultP->X_add_number += right.X_add_number;
172933965Sjdp	}
173033965Sjdp      /* This case comes up in PIC code.  */
173133965Sjdp      else if (op_left == O_subtract
173233965Sjdp	       && right.X_op == O_symbol
173333965Sjdp	       && resultP->X_op == O_symbol
1734218822Sdim	       && retval == rightseg
1735130561Sobrien	       && (SEG_NORMAL (rightseg)
1736218822Sdim		   || right.X_add_symbol == resultP->X_add_symbol)
1737218822Sdim	       && frag_offset_fixed_p (symbol_get_frag (resultP->X_add_symbol),
1738218822Sdim				       symbol_get_frag (right.X_add_symbol),
1739218822Sdim				       &frag_off))
174033965Sjdp	{
174133965Sjdp	  resultP->X_add_number -= right.X_add_number;
1742218822Sdim	  resultP->X_add_number -= frag_off / OCTETS_PER_BYTE;
174333965Sjdp	  resultP->X_add_number += (S_GET_VALUE (resultP->X_add_symbol)
174433965Sjdp				    - S_GET_VALUE (right.X_add_symbol));
174533965Sjdp	  resultP->X_op = O_constant;
174633965Sjdp	  resultP->X_add_symbol = 0;
174733965Sjdp	}
174833965Sjdp      else if (op_left == O_subtract && right.X_op == O_constant)
174933965Sjdp	{
175033965Sjdp	  /* X - constant.  */
175133965Sjdp	  resultP->X_add_number -= right.X_add_number;
175233965Sjdp	}
175333965Sjdp      else if (op_left == O_add && resultP->X_op == O_constant)
175433965Sjdp	{
175533965Sjdp	  /* Constant + X.  */
175633965Sjdp	  resultP->X_op = right.X_op;
175733965Sjdp	  resultP->X_add_symbol = right.X_add_symbol;
175833965Sjdp	  resultP->X_op_symbol = right.X_op_symbol;
175933965Sjdp	  resultP->X_add_number += right.X_add_number;
176033965Sjdp	  retval = rightseg;
176133965Sjdp	}
176233965Sjdp      else if (resultP->X_op == O_constant && right.X_op == O_constant)
176333965Sjdp	{
176433965Sjdp	  /* Constant OP constant.  */
176533965Sjdp	  offsetT v = right.X_add_number;
176633965Sjdp	  if (v == 0 && (op_left == O_divide || op_left == O_modulus))
176733965Sjdp	    {
176860484Sobrien	      as_warn (_("division by zero"));
176933965Sjdp	      v = 1;
177033965Sjdp	    }
177133965Sjdp	  switch (op_left)
177233965Sjdp	    {
177333965Sjdp	    default:			abort ();
177433965Sjdp	    case O_multiply:		resultP->X_add_number *= v; break;
177533965Sjdp	    case O_divide:		resultP->X_add_number /= v; break;
177633965Sjdp	    case O_modulus:		resultP->X_add_number %= v; break;
177733965Sjdp	    case O_left_shift:		resultP->X_add_number <<= v; break;
177833965Sjdp	    case O_right_shift:
177933965Sjdp	      /* We always use unsigned shifts, to avoid relying on
1780130561Sobrien		 characteristics of the compiler used to compile gas.  */
178133965Sjdp	      resultP->X_add_number =
178233965Sjdp		(offsetT) ((valueT) resultP->X_add_number >> (valueT) v);
178333965Sjdp	      break;
178433965Sjdp	    case O_bit_inclusive_or:	resultP->X_add_number |= v; break;
178533965Sjdp	    case O_bit_or_not:		resultP->X_add_number |= ~v; break;
178633965Sjdp	    case O_bit_exclusive_or:	resultP->X_add_number ^= v; break;
178733965Sjdp	    case O_bit_and:		resultP->X_add_number &= v; break;
1788218822Sdim	      /* Constant + constant (O_add) is handled by the
1789218822Sdim		 previous if statement for constant + X, so is omitted
1790218822Sdim		 here.  */
179133965Sjdp	    case O_subtract:		resultP->X_add_number -= v; break;
179233965Sjdp	    case O_eq:
179333965Sjdp	      resultP->X_add_number =
179433965Sjdp		resultP->X_add_number == v ? ~ (offsetT) 0 : 0;
179533965Sjdp	      break;
179633965Sjdp	    case O_ne:
179733965Sjdp	      resultP->X_add_number =
179833965Sjdp		resultP->X_add_number != v ? ~ (offsetT) 0 : 0;
179933965Sjdp	      break;
180033965Sjdp	    case O_lt:
180133965Sjdp	      resultP->X_add_number =
180233965Sjdp		resultP->X_add_number <  v ? ~ (offsetT) 0 : 0;
180333965Sjdp	      break;
180433965Sjdp	    case O_le:
180533965Sjdp	      resultP->X_add_number =
180633965Sjdp		resultP->X_add_number <= v ? ~ (offsetT) 0 : 0;
180733965Sjdp	      break;
180833965Sjdp	    case O_ge:
180933965Sjdp	      resultP->X_add_number =
181033965Sjdp		resultP->X_add_number >= v ? ~ (offsetT) 0 : 0;
181133965Sjdp	      break;
181233965Sjdp	    case O_gt:
181333965Sjdp	      resultP->X_add_number =
181433965Sjdp		resultP->X_add_number >  v ? ~ (offsetT) 0 : 0;
181533965Sjdp	      break;
181633965Sjdp	    case O_logical_and:
181733965Sjdp	      resultP->X_add_number = resultP->X_add_number && v;
181833965Sjdp	      break;
181933965Sjdp	    case O_logical_or:
182033965Sjdp	      resultP->X_add_number = resultP->X_add_number || v;
182133965Sjdp	      break;
182233965Sjdp	    }
182333965Sjdp	}
182433965Sjdp      else if (resultP->X_op == O_symbol
182533965Sjdp	       && right.X_op == O_symbol
182633965Sjdp	       && (op_left == O_add
182733965Sjdp		   || op_left == O_subtract
182833965Sjdp		   || (resultP->X_add_number == 0
182933965Sjdp		       && right.X_add_number == 0)))
183033965Sjdp	{
183133965Sjdp	  /* Symbol OP symbol.  */
183233965Sjdp	  resultP->X_op = op_left;
183333965Sjdp	  resultP->X_op_symbol = right.X_add_symbol;
183433965Sjdp	  if (op_left == O_add)
183533965Sjdp	    resultP->X_add_number += right.X_add_number;
183633965Sjdp	  else if (op_left == O_subtract)
183789857Sobrien	    {
183889857Sobrien	      resultP->X_add_number -= right.X_add_number;
183989857Sobrien	      if (retval == rightseg && SEG_NORMAL (retval))
184089857Sobrien		{
184189857Sobrien		  retval = absolute_section;
184289857Sobrien		  rightseg = absolute_section;
184389857Sobrien		}
184489857Sobrien	    }
184533965Sjdp	}
184633965Sjdp      else
184733965Sjdp	{
184833965Sjdp	  /* The general case.  */
184933965Sjdp	  resultP->X_add_symbol = make_expr_symbol (resultP);
185033965Sjdp	  resultP->X_op_symbol = make_expr_symbol (&right);
185133965Sjdp	  resultP->X_op = op_left;
185233965Sjdp	  resultP->X_add_number = 0;
185333965Sjdp	  resultP->X_unsigned = 1;
185433965Sjdp	}
185533965Sjdp
185689857Sobrien      if (retval != rightseg)
185789857Sobrien	{
185889857Sobrien	  if (! SEG_NORMAL (retval))
185989857Sobrien	    {
186089857Sobrien	      if (retval != undefined_section || SEG_NORMAL (rightseg))
186189857Sobrien		retval = rightseg;
186289857Sobrien	    }
186389857Sobrien	  else if (SEG_NORMAL (rightseg)
186489857Sobrien#ifdef DIFF_EXPR_OK
186589857Sobrien		   && op_left != O_subtract
186689857Sobrien#endif
186789857Sobrien		   )
186889857Sobrien	    as_bad (_("operation combines symbols in different segments"));
186989857Sobrien	}
187089857Sobrien
187133965Sjdp      op_left = op_right;
187277298Sobrien    }				/* While next operator is >= this rank.  */
187333965Sjdp
187433965Sjdp  /* The PA port needs this information.  */
187533965Sjdp  if (resultP->X_add_symbol)
187660484Sobrien    symbol_mark_used (resultP->X_add_symbol);
187733965Sjdp
1878218822Sdim  if (rank == 0 && mode == expr_evaluate)
1879218822Sdim    resolve_expression (resultP);
1880218822Sdim
188133965Sjdp  return resultP->X_op == O_constant ? absolute_section : retval;
188233965Sjdp}
1883218822Sdim
1884218822Sdim/* Resolve an expression without changing any symbols/sub-expressions
1885218822Sdim   used.  */
1886218822Sdim
1887218822Sdimint
1888218822Sdimresolve_expression (expressionS *expressionP)
1889218822Sdim{
1890218822Sdim  /* Help out with CSE.  */
1891218822Sdim  valueT final_val = expressionP->X_add_number;
1892218822Sdim  symbolS *add_symbol = expressionP->X_add_symbol;
1893218822Sdim  symbolS *op_symbol = expressionP->X_op_symbol;
1894218822Sdim  operatorT op = expressionP->X_op;
1895218822Sdim  valueT left, right;
1896218822Sdim  segT seg_left, seg_right;
1897218822Sdim  fragS *frag_left, *frag_right;
1898218822Sdim  bfd_vma frag_off;
1899218822Sdim
1900218822Sdim  switch (op)
1901218822Sdim    {
1902218822Sdim    default:
1903218822Sdim      return 0;
1904218822Sdim
1905218822Sdim    case O_constant:
1906218822Sdim    case O_register:
1907218822Sdim      left = 0;
1908218822Sdim      break;
1909218822Sdim
1910218822Sdim    case O_symbol:
1911218822Sdim    case O_symbol_rva:
1912218822Sdim      if (!snapshot_symbol (&add_symbol, &left, &seg_left, &frag_left))
1913218822Sdim	return 0;
1914218822Sdim
1915218822Sdim      break;
1916218822Sdim
1917218822Sdim    case O_uminus:
1918218822Sdim    case O_bit_not:
1919218822Sdim    case O_logical_not:
1920218822Sdim      if (!snapshot_symbol (&add_symbol, &left, &seg_left, &frag_left))
1921218822Sdim	return 0;
1922218822Sdim
1923218822Sdim      if (seg_left != absolute_section)
1924218822Sdim	return 0;
1925218822Sdim
1926218822Sdim      if (op == O_logical_not)
1927218822Sdim	left = !left;
1928218822Sdim      else if (op == O_uminus)
1929218822Sdim	left = -left;
1930218822Sdim      else
1931218822Sdim	left = ~left;
1932218822Sdim      op = O_constant;
1933218822Sdim      break;
1934218822Sdim
1935218822Sdim    case O_multiply:
1936218822Sdim    case O_divide:
1937218822Sdim    case O_modulus:
1938218822Sdim    case O_left_shift:
1939218822Sdim    case O_right_shift:
1940218822Sdim    case O_bit_inclusive_or:
1941218822Sdim    case O_bit_or_not:
1942218822Sdim    case O_bit_exclusive_or:
1943218822Sdim    case O_bit_and:
1944218822Sdim    case O_add:
1945218822Sdim    case O_subtract:
1946218822Sdim    case O_eq:
1947218822Sdim    case O_ne:
1948218822Sdim    case O_lt:
1949218822Sdim    case O_le:
1950218822Sdim    case O_ge:
1951218822Sdim    case O_gt:
1952218822Sdim    case O_logical_and:
1953218822Sdim    case O_logical_or:
1954218822Sdim      if (!snapshot_symbol (&add_symbol, &left, &seg_left, &frag_left)
1955218822Sdim	  || !snapshot_symbol (&op_symbol, &right, &seg_right, &frag_right))
1956218822Sdim	return 0;
1957218822Sdim
1958218822Sdim      /* Simplify addition or subtraction of a constant by folding the
1959218822Sdim	 constant into X_add_number.  */
1960218822Sdim      if (op == O_add)
1961218822Sdim	{
1962218822Sdim	  if (seg_right == absolute_section)
1963218822Sdim	    {
1964218822Sdim	      final_val += right;
1965218822Sdim	      op = O_symbol;
1966218822Sdim	      break;
1967218822Sdim	    }
1968218822Sdim	  else if (seg_left == absolute_section)
1969218822Sdim	    {
1970218822Sdim	      final_val += left;
1971218822Sdim	      left = right;
1972218822Sdim	      seg_left = seg_right;
1973218822Sdim	      add_symbol = op_symbol;
1974218822Sdim	      op = O_symbol;
1975218822Sdim	      break;
1976218822Sdim	    }
1977218822Sdim	}
1978218822Sdim      else if (op == O_subtract)
1979218822Sdim	{
1980218822Sdim	  if (seg_right == absolute_section)
1981218822Sdim	    {
1982218822Sdim	      final_val -= right;
1983218822Sdim	      op = O_symbol;
1984218822Sdim	      break;
1985218822Sdim	    }
1986218822Sdim	}
1987218822Sdim
1988218822Sdim      /* Equality and non-equality tests are permitted on anything.
1989218822Sdim	 Subtraction, and other comparison operators are permitted if
1990218822Sdim	 both operands are in the same section.
1991218822Sdim	 Shifts by constant zero are permitted on anything.
1992218822Sdim	 Multiplies, bit-ors, and bit-ands with constant zero are
1993218822Sdim	 permitted on anything.
1994218822Sdim	 Multiplies and divides by constant one are permitted on
1995218822Sdim	 anything.
1996218822Sdim	 Binary operations with both operands being the same register
1997218822Sdim	 or undefined symbol are permitted if the result doesn't depend
1998218822Sdim	 on the input value.
1999218822Sdim	 Otherwise, both operands must be absolute.  We already handled
2000218822Sdim	 the case of addition or subtraction of a constant above.  */
2001218822Sdim      frag_off = 0;
2002218822Sdim      if (!(seg_left == absolute_section
2003218822Sdim	       && seg_right == absolute_section)
2004218822Sdim	  && !(op == O_eq || op == O_ne)
2005218822Sdim	  && !((op == O_subtract
2006218822Sdim		|| op == O_lt || op == O_le || op == O_ge || op == O_gt)
2007218822Sdim	       && seg_left == seg_right
2008218822Sdim	       && (finalize_syms
2009218822Sdim		   || frag_offset_fixed_p (frag_left, frag_right, &frag_off))
2010218822Sdim	       && (seg_left != reg_section || left == right)
2011218822Sdim	       && (seg_left != undefined_section || add_symbol == op_symbol)))
2012218822Sdim	{
2013218822Sdim	  if ((seg_left == absolute_section && left == 0)
2014218822Sdim	      || (seg_right == absolute_section && right == 0))
2015218822Sdim	    {
2016218822Sdim	      if (op == O_bit_exclusive_or || op == O_bit_inclusive_or)
2017218822Sdim		{
2018218822Sdim		  if (seg_right != absolute_section || right != 0)
2019218822Sdim		    {
2020218822Sdim		      seg_left = seg_right;
2021218822Sdim		      left = right;
2022218822Sdim		      add_symbol = op_symbol;
2023218822Sdim		    }
2024218822Sdim		  op = O_symbol;
2025218822Sdim		  break;
2026218822Sdim		}
2027218822Sdim	      else if (op == O_left_shift || op == O_right_shift)
2028218822Sdim		{
2029218822Sdim		  if (seg_left != absolute_section || left != 0)
2030218822Sdim		    {
2031218822Sdim		      op = O_symbol;
2032218822Sdim		      break;
2033218822Sdim		    }
2034218822Sdim		}
2035218822Sdim	      else if (op != O_multiply
2036218822Sdim		       && op != O_bit_or_not && op != O_bit_and)
2037218822Sdim	        return 0;
2038218822Sdim	    }
2039218822Sdim	  else if (op == O_multiply
2040218822Sdim		   && seg_left == absolute_section && left == 1)
2041218822Sdim	    {
2042218822Sdim	      seg_left = seg_right;
2043218822Sdim	      left = right;
2044218822Sdim	      add_symbol = op_symbol;
2045218822Sdim	      op = O_symbol;
2046218822Sdim	      break;
2047218822Sdim	    }
2048218822Sdim	  else if ((op == O_multiply || op == O_divide)
2049218822Sdim		   && seg_right == absolute_section && right == 1)
2050218822Sdim	    {
2051218822Sdim	      op = O_symbol;
2052218822Sdim	      break;
2053218822Sdim	    }
2054218822Sdim	  else if (left != right
2055218822Sdim		   || ((seg_left != reg_section || seg_right != reg_section)
2056218822Sdim		       && (seg_left != undefined_section
2057218822Sdim			   || seg_right != undefined_section
2058218822Sdim			   || add_symbol != op_symbol)))
2059218822Sdim	    return 0;
2060218822Sdim	  else if (op == O_bit_and || op == O_bit_inclusive_or)
2061218822Sdim	    {
2062218822Sdim	      op = O_symbol;
2063218822Sdim	      break;
2064218822Sdim	    }
2065218822Sdim	  else if (op != O_bit_exclusive_or && op != O_bit_or_not)
2066218822Sdim	    return 0;
2067218822Sdim	}
2068218822Sdim
2069218822Sdim      right += frag_off / OCTETS_PER_BYTE;
2070218822Sdim      switch (op)
2071218822Sdim	{
2072218822Sdim	case O_add:			left += right; break;
2073218822Sdim	case O_subtract:		left -= right; break;
2074218822Sdim	case O_multiply:		left *= right; break;
2075218822Sdim	case O_divide:
2076218822Sdim	  if (right == 0)
2077218822Sdim	    return 0;
2078218822Sdim	  left = (offsetT) left / (offsetT) right;
2079218822Sdim	  break;
2080218822Sdim	case O_modulus:
2081218822Sdim	  if (right == 0)
2082218822Sdim	    return 0;
2083218822Sdim	  left = (offsetT) left % (offsetT) right;
2084218822Sdim	  break;
2085218822Sdim	case O_left_shift:		left <<= right; break;
2086218822Sdim	case O_right_shift:		left >>= right; break;
2087218822Sdim	case O_bit_inclusive_or:	left |= right; break;
2088218822Sdim	case O_bit_or_not:		left |= ~right; break;
2089218822Sdim	case O_bit_exclusive_or:	left ^= right; break;
2090218822Sdim	case O_bit_and:			left &= right; break;
2091218822Sdim	case O_eq:
2092218822Sdim	case O_ne:
2093218822Sdim	  left = (left == right
2094218822Sdim		  && seg_left == seg_right
2095218822Sdim		  && (finalize_syms || frag_left == frag_right)
2096218822Sdim		  && (seg_left != undefined_section
2097218822Sdim		      || add_symbol == op_symbol)
2098218822Sdim		  ? ~ (valueT) 0 : 0);
2099218822Sdim	  if (op == O_ne)
2100218822Sdim	    left = ~left;
2101218822Sdim	  break;
2102218822Sdim	case O_lt:
2103218822Sdim	  left = (offsetT) left <  (offsetT) right ? ~ (valueT) 0 : 0;
2104218822Sdim	  break;
2105218822Sdim	case O_le:
2106218822Sdim	  left = (offsetT) left <= (offsetT) right ? ~ (valueT) 0 : 0;
2107218822Sdim	  break;
2108218822Sdim	case O_ge:
2109218822Sdim	  left = (offsetT) left >= (offsetT) right ? ~ (valueT) 0 : 0;
2110218822Sdim	  break;
2111218822Sdim	case O_gt:
2112218822Sdim	  left = (offsetT) left >  (offsetT) right ? ~ (valueT) 0 : 0;
2113218822Sdim	  break;
2114218822Sdim	case O_logical_and:	left = left && right; break;
2115218822Sdim	case O_logical_or:	left = left || right; break;
2116218822Sdim	default:		abort ();
2117218822Sdim	}
2118218822Sdim
2119218822Sdim      op = O_constant;
2120218822Sdim      break;
2121218822Sdim    }
2122218822Sdim
2123218822Sdim  if (op == O_symbol)
2124218822Sdim    {
2125218822Sdim      if (seg_left == absolute_section)
2126218822Sdim	op = O_constant;
2127218822Sdim      else if (seg_left == reg_section && final_val == 0)
2128218822Sdim	op = O_register;
2129218822Sdim      else if (add_symbol != expressionP->X_add_symbol)
2130218822Sdim	final_val += left;
2131218822Sdim      expressionP->X_add_symbol = add_symbol;
2132218822Sdim    }
2133218822Sdim  expressionP->X_op = op;
2134218822Sdim
2135218822Sdim  if (op == O_constant || op == O_register)
2136218822Sdim    final_val += left;
2137218822Sdim  expressionP->X_add_number = final_val;
2138218822Sdim
2139218822Sdim  return 1;
2140218822Sdim}
214133965Sjdp
214277298Sobrien/* This lives here because it belongs equally in expr.c & read.c.
214377298Sobrien   expr.c is just a branch office read.c anyway, and putting it
214477298Sobrien   here lessens the crowd at read.c.
214577298Sobrien
214677298Sobrien   Assume input_line_pointer is at start of symbol name.
214777298Sobrien   Advance input_line_pointer past symbol name.
214877298Sobrien   Turn that character into a '\0', returning its former value.
214977298Sobrien   This allows a string compare (RMS wants symbol names to be strings)
215077298Sobrien   of the symbol name.
215177298Sobrien   There will always be a char following symbol name, because all good
215277298Sobrien   lines end in end-of-line.  */
215377298Sobrien
215433965Sjdpchar
2155130561Sobrienget_symbol_end (void)
215633965Sjdp{
215733965Sjdp  char c;
215833965Sjdp
215933965Sjdp  /* We accept \001 in a name in case this is being called with a
216033965Sjdp     constructed string.  */
216133965Sjdp  if (is_name_beginner (c = *input_line_pointer++) || c == '\001')
216260484Sobrien    {
216360484Sobrien      while (is_part_of_name (c = *input_line_pointer++)
216460484Sobrien	     || c == '\001')
216560484Sobrien	;
216660484Sobrien      if (is_name_ender (c))
216760484Sobrien	c = *input_line_pointer++;
216860484Sobrien    }
216933965Sjdp  *--input_line_pointer = 0;
217033965Sjdp  return (c);
217133965Sjdp}
217233965Sjdp
217333965Sjdpunsigned int
2174130561Sobrienget_single_number (void)
217533965Sjdp{
217633965Sjdp  expressionS exp;
2177218822Sdim  operand (&exp, expr_normal);
217833965Sjdp  return exp.X_add_number;
217933965Sjdp}
2180