expr.c revision 130561
133965Sjdp/* expr.c -operands, expressions-
278828Sobrien   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3130561Sobrien   1999, 2000, 2001, 2002
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
2033965Sjdp   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2177298Sobrien   02111-1307, 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
2833965Sjdp#include <string.h>
2938889Sjdp#define min(a, b)       ((a) < (b) ? (a) : (b))
3033965Sjdp
3133965Sjdp#include "as.h"
3289857Sobrien#include "safe-ctype.h"
3333965Sjdp#include "obstack.h"
3433965Sjdp
35130561Sobrienstatic void floating_constant (expressionS * expressionP);
36130561Sobrienstatic valueT generic_bignum_to_int32 (void);
3760484Sobrien#ifdef BFD64
38130561Sobrienstatic valueT generic_bignum_to_int64 (void);
3960484Sobrien#endif
40130561Sobrienstatic void integer_constant (int radix, expressionS * expressionP);
41130561Sobrienstatic void mri_char_constant (expressionS *);
42130561Sobrienstatic void current_location (expressionS *);
43130561Sobrienstatic void clean_up_expression (expressionS * expressionP);
44130561Sobrienstatic segT operand (expressionS *);
45130561Sobrienstatic operatorT operator (int *);
4633965Sjdp
4733965Sjdpextern const char EXP_CHARS[], FLT_CHARS[];
4833965Sjdp
4933965Sjdp/* We keep a mapping of expression symbols to file positions, so that
5033965Sjdp   we can provide better error messages.  */
5133965Sjdp
5277298Sobrienstruct expr_symbol_line {
5333965Sjdp  struct expr_symbol_line *next;
5433965Sjdp  symbolS *sym;
5533965Sjdp  char *file;
5633965Sjdp  unsigned int line;
5733965Sjdp};
5833965Sjdp
5933965Sjdpstatic struct expr_symbol_line *expr_symbol_lines;
6033965Sjdp
6133965Sjdp/* Build a dummy symbol to hold a complex expression.  This is how we
6233965Sjdp   build expressions up out of other expressions.  The symbol is put
6333965Sjdp   into the fake section expr_section.  */
6433965Sjdp
6533965SjdpsymbolS *
66130561Sobrienmake_expr_symbol (expressionS *expressionP)
6733965Sjdp{
6860484Sobrien  expressionS zero;
6933965Sjdp  symbolS *symbolP;
7033965Sjdp  struct expr_symbol_line *n;
7133965Sjdp
7233965Sjdp  if (expressionP->X_op == O_symbol
7333965Sjdp      && expressionP->X_add_number == 0)
7433965Sjdp    return expressionP->X_add_symbol;
7533965Sjdp
7660484Sobrien  if (expressionP->X_op == O_big)
7760484Sobrien    {
7860484Sobrien      /* This won't work, because the actual value is stored in
79130561Sobrien	 generic_floating_point_number or generic_bignum, and we are
80130561Sobrien	 going to lose it if we haven't already.  */
8160484Sobrien      if (expressionP->X_add_number > 0)
8289857Sobrien	as_bad (_("bignum invalid"));
8360484Sobrien      else
8489857Sobrien	as_bad (_("floating point number invalid"));
8560484Sobrien      zero.X_op = O_constant;
8660484Sobrien      zero.X_add_number = 0;
8760484Sobrien      zero.X_unsigned = 0;
8860484Sobrien      clean_up_expression (&zero);
8960484Sobrien      expressionP = &zero;
9060484Sobrien    }
9160484Sobrien
9233965Sjdp  /* Putting constant symbols in absolute_section rather than
9333965Sjdp     expr_section is convenient for the old a.out code, for which
9433965Sjdp     S_GET_SEGMENT does not always retrieve the value put in by
9533965Sjdp     S_SET_SEGMENT.  */
96130561Sobrien  symbolP = symbol_create (FAKE_LABEL_NAME,
9733965Sjdp			   (expressionP->X_op == O_constant
9833965Sjdp			    ? absolute_section
9933965Sjdp			    : expr_section),
10033965Sjdp			   0, &zero_address_frag);
10160484Sobrien  symbol_set_value_expression (symbolP, expressionP);
10233965Sjdp
10333965Sjdp  if (expressionP->X_op == O_constant)
10489857Sobrien    resolve_symbol_value (symbolP);
10533965Sjdp
10633965Sjdp  n = (struct expr_symbol_line *) xmalloc (sizeof *n);
10733965Sjdp  n->sym = symbolP;
10833965Sjdp  as_where (&n->file, &n->line);
10933965Sjdp  n->next = expr_symbol_lines;
11033965Sjdp  expr_symbol_lines = n;
11133965Sjdp
11233965Sjdp  return symbolP;
11333965Sjdp}
11433965Sjdp
11533965Sjdp/* Return the file and line number for an expr symbol.  Return
11633965Sjdp   non-zero if something was found, 0 if no information is known for
11733965Sjdp   the symbol.  */
11833965Sjdp
11933965Sjdpint
120130561Sobrienexpr_symbol_where (symbolS *sym, char **pfile, unsigned int *pline)
12133965Sjdp{
12233965Sjdp  register struct expr_symbol_line *l;
12333965Sjdp
12433965Sjdp  for (l = expr_symbol_lines; l != NULL; l = l->next)
12533965Sjdp    {
12633965Sjdp      if (l->sym == sym)
12733965Sjdp	{
12833965Sjdp	  *pfile = l->file;
12933965Sjdp	  *pline = l->line;
13033965Sjdp	  return 1;
13133965Sjdp	}
13233965Sjdp    }
13333965Sjdp
13433965Sjdp  return 0;
13533965Sjdp}
13633965Sjdp
13738889Sjdp/* Utilities for building expressions.
13838889Sjdp   Since complex expressions are recorded as symbols for use in other
13938889Sjdp   expressions these return a symbolS * and not an expressionS *.
14038889Sjdp   These explicitly do not take an "add_number" argument.  */
14138889Sjdp/* ??? For completeness' sake one might want expr_build_symbol.
14238889Sjdp   It would just return its argument.  */
14338889Sjdp
14438889Sjdp/* Build an expression for an unsigned constant.
14538889Sjdp   The corresponding one for signed constants is missing because
14638889Sjdp   there's currently no need for it.  One could add an unsigned_p flag
14738889Sjdp   but that seems more clumsy.  */
14838889Sjdp
14938889SjdpsymbolS *
150130561Sobrienexpr_build_uconstant (offsetT value)
15138889Sjdp{
15238889Sjdp  expressionS e;
15338889Sjdp
15438889Sjdp  e.X_op = O_constant;
15538889Sjdp  e.X_add_number = value;
15638889Sjdp  e.X_unsigned = 1;
15738889Sjdp  return make_expr_symbol (&e);
15838889Sjdp}
15938889Sjdp
16038889Sjdp/* Build an expression for OP s1.  */
16138889Sjdp
16238889SjdpsymbolS *
163130561Sobrienexpr_build_unary (operatorT op, symbolS *s1)
16438889Sjdp{
16538889Sjdp  expressionS e;
16638889Sjdp
16738889Sjdp  e.X_op = op;
16838889Sjdp  e.X_add_symbol = s1;
16938889Sjdp  e.X_add_number = 0;
17038889Sjdp  return make_expr_symbol (&e);
17138889Sjdp}
17238889Sjdp
17338889Sjdp/* Build an expression for s1 OP s2.  */
17438889Sjdp
17538889SjdpsymbolS *
176130561Sobrienexpr_build_binary (operatorT op, symbolS *s1, symbolS *s2)
17738889Sjdp{
17838889Sjdp  expressionS e;
17938889Sjdp
18038889Sjdp  e.X_op = op;
18138889Sjdp  e.X_add_symbol = s1;
18238889Sjdp  e.X_op_symbol = s2;
18338889Sjdp  e.X_add_number = 0;
18438889Sjdp  return make_expr_symbol (&e);
18538889Sjdp}
18660484Sobrien
18760484Sobrien/* Build an expression for the current location ('.').  */
18860484Sobrien
18960484SobriensymbolS *
190130561Sobrienexpr_build_dot (void)
19160484Sobrien{
19260484Sobrien  expressionS e;
19360484Sobrien
19460484Sobrien  current_location (&e);
19560484Sobrien  return make_expr_symbol (&e);
19660484Sobrien}
19738889Sjdp
19877298Sobrien/* Build any floating-point literal here.
19977298Sobrien   Also build any bignum literal here.  */
20033965Sjdp
20133965Sjdp/* Seems atof_machine can backscan through generic_bignum and hit whatever
20233965Sjdp   happens to be loaded before it in memory.  And its way too complicated
20333965Sjdp   for me to fix right.  Thus a hack.  JF:  Just make generic_bignum bigger,
20433965Sjdp   and never write into the early words, thus they'll always be zero.
20533965Sjdp   I hate Dean's floating-point code.  Bleh.  */
20633965SjdpLITTLENUM_TYPE generic_bignum[SIZE_OF_LARGE_NUMBER + 6];
20777298Sobrien
20877298SobrienFLONUM_TYPE generic_floating_point_number = {
20977298Sobrien  &generic_bignum[6],		/* low.  (JF: Was 0)  */
21077298Sobrien  &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1], /* high.  JF: (added +6)  */
21177298Sobrien  0,				/* leader.  */
21277298Sobrien  0,				/* exponent.  */
21377298Sobrien  0				/* sign.  */
21433965Sjdp};
21577298Sobrien
21677298Sobrien/* If nonzero, we've been asked to assemble nan, +inf or -inf.  */
21733965Sjdpint generic_floating_point_magic;
21833965Sjdp
21933965Sjdpstatic void
220130561Sobrienfloating_constant (expressionS *expressionP)
22133965Sjdp{
22277298Sobrien  /* input_line_pointer -> floating-point constant.  */
22333965Sjdp  int error_code;
22433965Sjdp
22533965Sjdp  error_code = atof_generic (&input_line_pointer, ".", EXP_CHARS,
22633965Sjdp			     &generic_floating_point_number);
22733965Sjdp
22833965Sjdp  if (error_code)
22933965Sjdp    {
23033965Sjdp      if (error_code == ERROR_EXPONENT_OVERFLOW)
23133965Sjdp	{
23289857Sobrien	  as_bad (_("bad floating-point constant: exponent overflow"));
23333965Sjdp	}
23433965Sjdp      else
23533965Sjdp	{
23689857Sobrien	  as_bad (_("bad floating-point constant: unknown error code=%d"),
23789857Sobrien		  error_code);
23833965Sjdp	}
23933965Sjdp    }
24033965Sjdp  expressionP->X_op = O_big;
24177298Sobrien  /* input_line_pointer -> just after constant, which may point to
24277298Sobrien     whitespace.  */
24333965Sjdp  expressionP->X_add_number = -1;
24433965Sjdp}
24533965Sjdp
24677298Sobrienstatic valueT
247130561Sobriengeneric_bignum_to_int32 (void)
24838889Sjdp{
24938889Sjdp  valueT number =
25038889Sjdp	   ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
25138889Sjdp	   | (generic_bignum[0] & LITTLENUM_MASK);
25238889Sjdp  number &= 0xffffffff;
25338889Sjdp  return number;
25438889Sjdp}
25538889Sjdp
25638889Sjdp#ifdef BFD64
25777298Sobrienstatic valueT
258130561Sobriengeneric_bignum_to_int64 (void)
25938889Sjdp{
26077298Sobrien  valueT number =
26177298Sobrien    ((((((((valueT) generic_bignum[3] & LITTLENUM_MASK)
26277298Sobrien	  << LITTLENUM_NUMBER_OF_BITS)
26377298Sobrien	 | ((valueT) generic_bignum[2] & LITTLENUM_MASK))
26477298Sobrien	<< LITTLENUM_NUMBER_OF_BITS)
26577298Sobrien       | ((valueT) generic_bignum[1] & LITTLENUM_MASK))
26677298Sobrien      << LITTLENUM_NUMBER_OF_BITS)
26777298Sobrien     | ((valueT) generic_bignum[0] & LITTLENUM_MASK));
26838889Sjdp  return number;
26938889Sjdp}
27038889Sjdp#endif
27138889Sjdp
27233965Sjdpstatic void
273130561Sobrieninteger_constant (int radix, expressionS *expressionP)
27433965Sjdp{
27577298Sobrien  char *start;		/* Start of number.  */
27633965Sjdp  char *suffix = NULL;
27733965Sjdp  char c;
27877298Sobrien  valueT number;	/* Offset or (absolute) value.  */
27977298Sobrien  short int digit;	/* Value of next digit in current radix.  */
28077298Sobrien  short int maxdig = 0;	/* Highest permitted digit value.  */
28177298Sobrien  int too_many_digits = 0;	/* If we see >= this number of.  */
28277298Sobrien  char *name;		/* Points to name of symbol.  */
28377298Sobrien  symbolS *symbolP;	/* Points to symbol.  */
28433965Sjdp
28577298Sobrien  int small;			/* True if fits in 32 bits.  */
28633965Sjdp
28777298Sobrien  /* May be bignum, or may fit in 32 bits.  */
28833965Sjdp  /* Most numbers fit into 32 bits, and we want this case to be fast.
28933965Sjdp     so we pretend it will fit into 32 bits.  If, after making up a 32
29033965Sjdp     bit number, we realise that we have scanned more digits than
29133965Sjdp     comfortably fit into 32 bits, we re-scan the digits coding them
29233965Sjdp     into a bignum.  For decimal and octal numbers we are
29333965Sjdp     conservative: Some numbers may be assumed bignums when in fact
29433965Sjdp     they do fit into 32 bits.  Numbers of any radix can have excess
29533965Sjdp     leading zeros: We strive to recognise this and cast them back
29633965Sjdp     into 32 bits.  We must check that the bignum really is more than
29733965Sjdp     32 bits, and change it back to a 32-bit number if it fits.  The
29833965Sjdp     number we are looking for is expected to be positive, but if it
29933965Sjdp     fits into 32 bits as an unsigned number, we let it be a 32-bit
30077298Sobrien     number.  The cavalier approach is for speed in ordinary cases.  */
30133965Sjdp  /* This has been extended for 64 bits.  We blindly assume that if
30233965Sjdp     you're compiling in 64-bit mode, the target is a 64-bit machine.
30333965Sjdp     This should be cleaned up.  */
30433965Sjdp
30533965Sjdp#ifdef BFD64
30633965Sjdp#define valuesize 64
30733965Sjdp#else /* includes non-bfd case, mostly */
30833965Sjdp#define valuesize 32
30933965Sjdp#endif
31033965Sjdp
31160484Sobrien  if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) && radix == 0)
31233965Sjdp    {
31333965Sjdp      int flt = 0;
31433965Sjdp
31533965Sjdp      /* In MRI mode, the number may have a suffix indicating the
316130561Sobrien	 radix.  For that matter, it might actually be a floating
317130561Sobrien	 point constant.  */
31889857Sobrien      for (suffix = input_line_pointer; ISALNUM (*suffix); suffix++)
31933965Sjdp	{
32033965Sjdp	  if (*suffix == 'e' || *suffix == 'E')
32133965Sjdp	    flt = 1;
32233965Sjdp	}
32333965Sjdp
32433965Sjdp      if (suffix == input_line_pointer)
32533965Sjdp	{
32633965Sjdp	  radix = 10;
32733965Sjdp	  suffix = NULL;
32833965Sjdp	}
32933965Sjdp      else
33033965Sjdp	{
33133965Sjdp	  c = *--suffix;
33289857Sobrien	  c = TOUPPER (c);
33333965Sjdp	  if (c == 'B')
33433965Sjdp	    radix = 2;
33533965Sjdp	  else if (c == 'D')
33633965Sjdp	    radix = 10;
33733965Sjdp	  else if (c == 'O' || c == 'Q')
33833965Sjdp	    radix = 8;
33933965Sjdp	  else if (c == 'H')
34033965Sjdp	    radix = 16;
34133965Sjdp	  else if (suffix[1] == '.' || c == 'E' || flt)
34233965Sjdp	    {
34333965Sjdp	      floating_constant (expressionP);
34433965Sjdp	      return;
34533965Sjdp	    }
34633965Sjdp	  else
34733965Sjdp	    {
34833965Sjdp	      radix = 10;
34933965Sjdp	      suffix = NULL;
35033965Sjdp	    }
35133965Sjdp	}
35233965Sjdp    }
35333965Sjdp
35433965Sjdp  switch (radix)
35533965Sjdp    {
35633965Sjdp    case 2:
35733965Sjdp      maxdig = 2;
35833965Sjdp      too_many_digits = valuesize + 1;
35933965Sjdp      break;
36033965Sjdp    case 8:
36133965Sjdp      maxdig = radix = 8;
36233965Sjdp      too_many_digits = (valuesize + 2) / 3 + 1;
36333965Sjdp      break;
36433965Sjdp    case 16:
36533965Sjdp      maxdig = radix = 16;
36633965Sjdp      too_many_digits = (valuesize + 3) / 4 + 1;
36733965Sjdp      break;
36833965Sjdp    case 10:
36933965Sjdp      maxdig = radix = 10;
37077298Sobrien      too_many_digits = (valuesize + 11) / 4; /* Very rough.  */
37133965Sjdp    }
37233965Sjdp#undef valuesize
37333965Sjdp  start = input_line_pointer;
37433965Sjdp  c = *input_line_pointer++;
37533965Sjdp  for (number = 0;
37633965Sjdp       (digit = hex_value (c)) < maxdig;
37733965Sjdp       c = *input_line_pointer++)
37833965Sjdp    {
37933965Sjdp      number = number * radix + digit;
38033965Sjdp    }
38177298Sobrien  /* c contains character after number.  */
38277298Sobrien  /* input_line_pointer->char after c.  */
38333965Sjdp  small = (input_line_pointer - start - 1) < too_many_digits;
38438889Sjdp
38577298Sobrien  if (radix == 16 && c == '_')
38633965Sjdp    {
38738889Sjdp      /* This is literal of the form 0x333_0_12345678_1.
388130561Sobrien	 This example is equivalent to 0x00000333000000001234567800000001.  */
38938889Sjdp
39038889Sjdp      int num_little_digits = 0;
39138889Sjdp      int i;
39277298Sobrien      input_line_pointer = start;	/* -> 1st digit.  */
39338889Sjdp
39438889Sjdp      know (LITTLENUM_NUMBER_OF_BITS == 16);
39538889Sjdp
39677298Sobrien      for (c = '_'; c == '_'; num_little_digits += 2)
39738889Sjdp	{
39838889Sjdp
39977298Sobrien	  /* Convert one 64-bit word.  */
40077298Sobrien	  int ndigit = 0;
40138889Sjdp	  number = 0;
40238889Sjdp	  for (c = *input_line_pointer++;
40338889Sjdp	       (digit = hex_value (c)) < maxdig;
40438889Sjdp	       c = *(input_line_pointer++))
40538889Sjdp	    {
40638889Sjdp	      number = number * radix + digit;
40738889Sjdp	      ndigit++;
40838889Sjdp	    }
40938889Sjdp
41038889Sjdp	  /* Check for 8 digit per word max.  */
41177298Sobrien	  if (ndigit > 8)
41289857Sobrien	    as_bad (_("a bignum with underscores may not have more than 8 hex digits in any word"));
41338889Sjdp
41477298Sobrien	  /* Add this chunk to the bignum.
41577298Sobrien	     Shift things down 2 little digits.  */
41638889Sjdp	  know (LITTLENUM_NUMBER_OF_BITS == 16);
41777298Sobrien	  for (i = min (num_little_digits + 1, SIZE_OF_LARGE_NUMBER - 1);
41877298Sobrien	       i >= 2;
41977298Sobrien	       i--)
42077298Sobrien	    generic_bignum[i] = generic_bignum[i - 2];
42138889Sjdp
42277298Sobrien	  /* Add the new digits as the least significant new ones.  */
42338889Sjdp	  generic_bignum[0] = number & 0xffffffff;
42438889Sjdp	  generic_bignum[1] = number >> 16;
42538889Sjdp	}
42638889Sjdp
42777298Sobrien      /* Again, c is char after number, input_line_pointer->after c.  */
42838889Sjdp
42938889Sjdp      if (num_little_digits > SIZE_OF_LARGE_NUMBER - 1)
43038889Sjdp	num_little_digits = SIZE_OF_LARGE_NUMBER - 1;
43138889Sjdp
43238889Sjdp      assert (num_little_digits >= 4);
43338889Sjdp
43438889Sjdp      if (num_little_digits != 8)
43589857Sobrien	as_bad (_("a bignum with underscores must have exactly 4 words"));
43638889Sjdp
43738889Sjdp      /* We might have some leading zeros.  These can be trimmed to give
43877298Sobrien	 us a change to fit this constant into a small number.  */
43977298Sobrien      while (generic_bignum[num_little_digits - 1] == 0
44077298Sobrien	     && num_little_digits > 1)
44138889Sjdp	num_little_digits--;
44277298Sobrien
44338889Sjdp      if (num_little_digits <= 2)
44438889Sjdp	{
44577298Sobrien	  /* will fit into 32 bits.  */
44638889Sjdp	  number = generic_bignum_to_int32 ();
44738889Sjdp	  small = 1;
44838889Sjdp	}
44938889Sjdp#ifdef BFD64
45038889Sjdp      else if (num_little_digits <= 4)
45138889Sjdp	{
45238889Sjdp	  /* Will fit into 64 bits.  */
45338889Sjdp	  number = generic_bignum_to_int64 ();
45438889Sjdp	  small = 1;
45538889Sjdp	}
45638889Sjdp#endif
45738889Sjdp      else
45838889Sjdp	{
45938889Sjdp	  small = 0;
46077298Sobrien
46177298Sobrien	  /* Number of littlenums in the bignum.  */
46277298Sobrien	  number = num_little_digits;
46338889Sjdp	}
46438889Sjdp    }
46538889Sjdp  else if (!small)
46638889Sjdp    {
46777298Sobrien      /* We saw a lot of digits. manufacture a bignum the hard way.  */
46877298Sobrien      LITTLENUM_TYPE *leader;	/* -> high order littlenum of the bignum.  */
46977298Sobrien      LITTLENUM_TYPE *pointer;	/* -> littlenum we are frobbing now.  */
47033965Sjdp      long carry;
47133965Sjdp
47233965Sjdp      leader = generic_bignum;
47333965Sjdp      generic_bignum[0] = 0;
47433965Sjdp      generic_bignum[1] = 0;
47538889Sjdp      generic_bignum[2] = 0;
47638889Sjdp      generic_bignum[3] = 0;
47777298Sobrien      input_line_pointer = start;	/* -> 1st digit.  */
47833965Sjdp      c = *input_line_pointer++;
47977298Sobrien      for (; (carry = hex_value (c)) < maxdig; c = *input_line_pointer++)
48033965Sjdp	{
48177298Sobrien	  for (pointer = generic_bignum; pointer <= leader; pointer++)
48233965Sjdp	    {
48333965Sjdp	      long work;
48433965Sjdp
48533965Sjdp	      work = carry + radix * *pointer;
48633965Sjdp	      *pointer = work & LITTLENUM_MASK;
48733965Sjdp	      carry = work >> LITTLENUM_NUMBER_OF_BITS;
48833965Sjdp	    }
48933965Sjdp	  if (carry)
49033965Sjdp	    {
49133965Sjdp	      if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1)
49233965Sjdp		{
49377298Sobrien		  /* Room to grow a longer bignum.  */
49433965Sjdp		  *++leader = carry;
49533965Sjdp		}
49633965Sjdp	    }
49733965Sjdp	}
49877298Sobrien      /* Again, c is char after number.  */
49977298Sobrien      /* input_line_pointer -> after c.  */
50033965Sjdp      know (LITTLENUM_NUMBER_OF_BITS == 16);
50133965Sjdp      if (leader < generic_bignum + 2)
50233965Sjdp	{
50377298Sobrien	  /* Will fit into 32 bits.  */
50438889Sjdp	  number = generic_bignum_to_int32 ();
50533965Sjdp	  small = 1;
50633965Sjdp	}
50738889Sjdp#ifdef BFD64
50838889Sjdp      else if (leader < generic_bignum + 4)
50938889Sjdp	{
51038889Sjdp	  /* Will fit into 64 bits.  */
51138889Sjdp	  number = generic_bignum_to_int64 ();
51238889Sjdp	  small = 1;
51338889Sjdp	}
51438889Sjdp#endif
51533965Sjdp      else
51633965Sjdp	{
51777298Sobrien	  /* Number of littlenums in the bignum.  */
51877298Sobrien	  number = leader - generic_bignum + 1;
51933965Sjdp	}
52033965Sjdp    }
52133965Sjdp
52277298Sobrien  if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri)
52377298Sobrien      && suffix != NULL
52460484Sobrien      && input_line_pointer - 1 == suffix)
52533965Sjdp    c = *input_line_pointer++;
52633965Sjdp
52733965Sjdp  if (small)
52833965Sjdp    {
52977298Sobrien      /* Here with number, in correct radix. c is the next char.
53077298Sobrien	 Note that unlike un*x, we allow "011f" "0x9f" to both mean
53177298Sobrien	 the same as the (conventional) "9f".
53277298Sobrien	 This is simply easier than checking for strict canonical
53377298Sobrien	 form.  Syntax sux!  */
53433965Sjdp
53533965Sjdp      if (LOCAL_LABELS_FB && c == 'b')
53633965Sjdp	{
53777298Sobrien	  /* Backward ref to local label.
53877298Sobrien	     Because it is backward, expect it to be defined.  */
53933965Sjdp	  /* Construct a local label.  */
54033965Sjdp	  name = fb_label_name ((int) number, 0);
54133965Sjdp
54277298Sobrien	  /* Seen before, or symbol is defined: OK.  */
54333965Sjdp	  symbolP = symbol_find (name);
54433965Sjdp	  if ((symbolP != NULL) && (S_IS_DEFINED (symbolP)))
54533965Sjdp	    {
54677298Sobrien	      /* Local labels are never absolute.  Don't waste time
54777298Sobrien		 checking absoluteness.  */
54833965Sjdp	      know (SEG_NORMAL (S_GET_SEGMENT (symbolP)));
54933965Sjdp
55033965Sjdp	      expressionP->X_op = O_symbol;
55133965Sjdp	      expressionP->X_add_symbol = symbolP;
55233965Sjdp	    }
55333965Sjdp	  else
55433965Sjdp	    {
55577298Sobrien	      /* Either not seen or not defined.  */
55633965Sjdp	      /* @@ Should print out the original string instead of
55733965Sjdp		 the parsed number.  */
55889857Sobrien	      as_bad (_("backward ref to unknown label \"%d:\""),
55933965Sjdp		      (int) number);
56033965Sjdp	      expressionP->X_op = O_constant;
56133965Sjdp	    }
56233965Sjdp
56333965Sjdp	  expressionP->X_add_number = 0;
56433965Sjdp	}			/* case 'b' */
56533965Sjdp      else if (LOCAL_LABELS_FB && c == 'f')
56633965Sjdp	{
56777298Sobrien	  /* Forward reference.  Expect symbol to be undefined or
56877298Sobrien	     unknown.  undefined: seen it before.  unknown: never seen
56977298Sobrien	     it before.
57077298Sobrien
57177298Sobrien	     Construct a local label name, then an undefined symbol.
57277298Sobrien	     Don't create a xseg frag for it: caller may do that.
57377298Sobrien	     Just return it as never seen before.  */
57433965Sjdp	  name = fb_label_name ((int) number, 1);
57533965Sjdp	  symbolP = symbol_find_or_make (name);
57677298Sobrien	  /* We have no need to check symbol properties.  */
57733965Sjdp#ifndef many_segments
57877298Sobrien	  /* Since "know" puts its arg into a "string", we
57933965Sjdp	     can't have newlines in the argument.  */
58033965Sjdp	  know (S_GET_SEGMENT (symbolP) == undefined_section || S_GET_SEGMENT (symbolP) == text_section || S_GET_SEGMENT (symbolP) == data_section);
58133965Sjdp#endif
58233965Sjdp	  expressionP->X_op = O_symbol;
58333965Sjdp	  expressionP->X_add_symbol = symbolP;
58433965Sjdp	  expressionP->X_add_number = 0;
58533965Sjdp	}			/* case 'f' */
58633965Sjdp      else if (LOCAL_LABELS_DOLLAR && c == '$')
58733965Sjdp	{
58833965Sjdp	  /* If the dollar label is *currently* defined, then this is just
58933965Sjdp	     another reference to it.  If it is not *currently* defined,
59033965Sjdp	     then this is a fresh instantiation of that number, so create
59133965Sjdp	     it.  */
59233965Sjdp
59333965Sjdp	  if (dollar_label_defined ((long) number))
59433965Sjdp	    {
59533965Sjdp	      name = dollar_label_name ((long) number, 0);
59633965Sjdp	      symbolP = symbol_find (name);
59733965Sjdp	      know (symbolP != NULL);
59833965Sjdp	    }
59933965Sjdp	  else
60033965Sjdp	    {
60133965Sjdp	      name = dollar_label_name ((long) number, 1);
60233965Sjdp	      symbolP = symbol_find_or_make (name);
60333965Sjdp	    }
60433965Sjdp
60533965Sjdp	  expressionP->X_op = O_symbol;
60633965Sjdp	  expressionP->X_add_symbol = symbolP;
60733965Sjdp	  expressionP->X_add_number = 0;
60833965Sjdp	}			/* case '$' */
60933965Sjdp      else
61033965Sjdp	{
61133965Sjdp	  expressionP->X_op = O_constant;
61233965Sjdp#ifdef TARGET_WORD_SIZE
61333965Sjdp	  /* Sign extend NUMBER.  */
61433965Sjdp	  number |= (-(number >> (TARGET_WORD_SIZE - 1))) << (TARGET_WORD_SIZE - 1);
61533965Sjdp#endif
61633965Sjdp	  expressionP->X_add_number = number;
61777298Sobrien	  input_line_pointer--;	/* Restore following character.  */
61877298Sobrien	}			/* Really just a number.  */
61933965Sjdp    }
62033965Sjdp  else
62133965Sjdp    {
62277298Sobrien      /* Not a small number.  */
62333965Sjdp      expressionP->X_op = O_big;
62477298Sobrien      expressionP->X_add_number = number;	/* Number of littlenums.  */
62577298Sobrien      input_line_pointer--;	/* -> char following number.  */
62633965Sjdp    }
62733965Sjdp}
62833965Sjdp
62933965Sjdp/* Parse an MRI multi character constant.  */
63033965Sjdp
63133965Sjdpstatic void
632130561Sobrienmri_char_constant (expressionS *expressionP)
63333965Sjdp{
63433965Sjdp  int i;
63533965Sjdp
63633965Sjdp  if (*input_line_pointer == '\''
63733965Sjdp      && input_line_pointer[1] != '\'')
63833965Sjdp    {
63933965Sjdp      expressionP->X_op = O_constant;
64033965Sjdp      expressionP->X_add_number = 0;
64133965Sjdp      return;
64233965Sjdp    }
64333965Sjdp
64433965Sjdp  /* In order to get the correct byte ordering, we must build the
64533965Sjdp     number in reverse.  */
64633965Sjdp  for (i = SIZE_OF_LARGE_NUMBER - 1; i >= 0; i--)
64733965Sjdp    {
64833965Sjdp      int j;
64933965Sjdp
65033965Sjdp      generic_bignum[i] = 0;
65133965Sjdp      for (j = 0; j < CHARS_PER_LITTLENUM; j++)
65233965Sjdp	{
65333965Sjdp	  if (*input_line_pointer == '\'')
65433965Sjdp	    {
65533965Sjdp	      if (input_line_pointer[1] != '\'')
65633965Sjdp		break;
65733965Sjdp	      ++input_line_pointer;
65833965Sjdp	    }
65933965Sjdp	  generic_bignum[i] <<= 8;
66033965Sjdp	  generic_bignum[i] += *input_line_pointer;
66133965Sjdp	  ++input_line_pointer;
66233965Sjdp	}
66333965Sjdp
66433965Sjdp      if (i < SIZE_OF_LARGE_NUMBER - 1)
66533965Sjdp	{
66633965Sjdp	  /* If there is more than one littlenum, left justify the
667130561Sobrien	     last one to make it match the earlier ones.  If there is
668130561Sobrien	     only one, we can just use the value directly.  */
66933965Sjdp	  for (; j < CHARS_PER_LITTLENUM; j++)
67033965Sjdp	    generic_bignum[i] <<= 8;
67133965Sjdp	}
67233965Sjdp
67333965Sjdp      if (*input_line_pointer == '\''
67433965Sjdp	  && input_line_pointer[1] != '\'')
67533965Sjdp	break;
67633965Sjdp    }
67733965Sjdp
67833965Sjdp  if (i < 0)
67933965Sjdp    {
68089857Sobrien      as_bad (_("character constant too large"));
68133965Sjdp      i = 0;
68233965Sjdp    }
68333965Sjdp
68433965Sjdp  if (i > 0)
68533965Sjdp    {
68633965Sjdp      int c;
68733965Sjdp      int j;
68833965Sjdp
68933965Sjdp      c = SIZE_OF_LARGE_NUMBER - i;
69033965Sjdp      for (j = 0; j < c; j++)
69133965Sjdp	generic_bignum[j] = generic_bignum[i + j];
69233965Sjdp      i = c;
69333965Sjdp    }
69433965Sjdp
69533965Sjdp  know (LITTLENUM_NUMBER_OF_BITS == 16);
69633965Sjdp  if (i > 2)
69733965Sjdp    {
69833965Sjdp      expressionP->X_op = O_big;
69933965Sjdp      expressionP->X_add_number = i;
70033965Sjdp    }
70133965Sjdp  else
70233965Sjdp    {
70333965Sjdp      expressionP->X_op = O_constant;
70433965Sjdp      if (i < 2)
70533965Sjdp	expressionP->X_add_number = generic_bignum[0] & LITTLENUM_MASK;
70633965Sjdp      else
70733965Sjdp	expressionP->X_add_number =
70833965Sjdp	  (((generic_bignum[1] & LITTLENUM_MASK)
70933965Sjdp	    << LITTLENUM_NUMBER_OF_BITS)
71033965Sjdp	   | (generic_bignum[0] & LITTLENUM_MASK));
71133965Sjdp    }
71233965Sjdp
71333965Sjdp  /* Skip the final closing quote.  */
71433965Sjdp  ++input_line_pointer;
71533965Sjdp}
71633965Sjdp
71733965Sjdp/* Return an expression representing the current location.  This
71833965Sjdp   handles the magic symbol `.'.  */
71933965Sjdp
72033965Sjdpstatic void
721130561Sobriencurrent_location (expressionS *expressionp)
72233965Sjdp{
72333965Sjdp  if (now_seg == absolute_section)
72433965Sjdp    {
72533965Sjdp      expressionp->X_op = O_constant;
72633965Sjdp      expressionp->X_add_number = abs_section_offset;
72733965Sjdp    }
72833965Sjdp  else
72933965Sjdp    {
73033965Sjdp      expressionp->X_op = O_symbol;
731130561Sobrien      expressionp->X_add_symbol = symbol_temp_new_now ();
73233965Sjdp      expressionp->X_add_number = 0;
73333965Sjdp    }
73433965Sjdp}
73533965Sjdp
73677298Sobrien/* In:	Input_line_pointer points to 1st char of operand, which may
73777298Sobrien	be a space.
73833965Sjdp
73989857Sobrien   Out:	An expressionS.
74077298Sobrien	The operand may have been empty: in this case X_op == O_absent.
74177298Sobrien	Input_line_pointer->(next non-blank) char after operand.  */
74277298Sobrien
74333965Sjdpstatic segT
744130561Sobrienoperand (expressionS *expressionP)
74533965Sjdp{
74633965Sjdp  char c;
74777298Sobrien  symbolS *symbolP;	/* Points to symbol.  */
74877298Sobrien  char *name;		/* Points to name of symbol.  */
74933965Sjdp  segT segment;
75033965Sjdp
75133965Sjdp  /* All integers are regarded as unsigned unless they are negated.
75233965Sjdp     This is because the only thing which cares whether a number is
75333965Sjdp     unsigned is the code in emit_expr which extends constants into
75433965Sjdp     bignums.  It should only sign extend negative numbers, so that
75533965Sjdp     something like ``.quad 0x80000000'' is not sign extended even
75633965Sjdp     though it appears negative if valueT is 32 bits.  */
75733965Sjdp  expressionP->X_unsigned = 1;
75833965Sjdp
75977298Sobrien  /* Digits, assume it is a bignum.  */
76033965Sjdp
76177298Sobrien  SKIP_WHITESPACE ();		/* Leading whitespace is part of operand.  */
76277298Sobrien  c = *input_line_pointer++;	/* input_line_pointer -> past char in c.  */
76333965Sjdp
76477298Sobrien  if (is_end_of_line[(unsigned char) c])
76577298Sobrien    goto eol;
76677298Sobrien
76733965Sjdp  switch (c)
76833965Sjdp    {
76933965Sjdp    case '1':
77033965Sjdp    case '2':
77133965Sjdp    case '3':
77233965Sjdp    case '4':
77333965Sjdp    case '5':
77433965Sjdp    case '6':
77533965Sjdp    case '7':
77633965Sjdp    case '8':
77733965Sjdp    case '9':
77833965Sjdp      input_line_pointer--;
77933965Sjdp
78077298Sobrien      integer_constant ((NUMBERS_WITH_SUFFIX || flag_m68k_mri)
78177298Sobrien			? 0 : 10,
782104834Sobrien			expressionP);
78333965Sjdp      break;
78433965Sjdp
78577298Sobrien#ifdef LITERAL_PREFIXDOLLAR_HEX
78677298Sobrien    case '$':
78789857Sobrien      /* $L is the start of a local label, not a hex constant.  */
78889857Sobrien      if (* input_line_pointer == 'L')
78989857Sobrien      goto isname;
79077298Sobrien      integer_constant (16, expressionP);
79177298Sobrien      break;
79277298Sobrien#endif
79377298Sobrien
79477298Sobrien#ifdef LITERAL_PREFIXPERCENT_BIN
79577298Sobrien    case '%':
79677298Sobrien      integer_constant (2, expressionP);
79777298Sobrien      break;
79877298Sobrien#endif
79977298Sobrien
80033965Sjdp    case '0':
80177298Sobrien      /* Non-decimal radix.  */
80233965Sjdp
80360484Sobrien      if (NUMBERS_WITH_SUFFIX || flag_m68k_mri)
80433965Sjdp	{
80533965Sjdp	  char *s;
80633965Sjdp
807130561Sobrien	  /* Check for a hex or float constant.  */
80833965Sjdp	  for (s = input_line_pointer; hex_p (*s); s++)
80933965Sjdp	    ;
810130561Sobrien	  if (*s == 'h' || *s == 'H' || *input_line_pointer == '.')
81133965Sjdp	    {
81233965Sjdp	      --input_line_pointer;
81333965Sjdp	      integer_constant (0, expressionP);
81433965Sjdp	      break;
81533965Sjdp	    }
81677298Sobrien	}
81733965Sjdp      c = *input_line_pointer;
81833965Sjdp      switch (c)
81933965Sjdp	{
82033965Sjdp	case 'o':
82133965Sjdp	case 'O':
82233965Sjdp	case 'q':
82333965Sjdp	case 'Q':
82433965Sjdp	case '8':
82533965Sjdp	case '9':
82660484Sobrien	  if (NUMBERS_WITH_SUFFIX || flag_m68k_mri)
82733965Sjdp	    {
82833965Sjdp	      integer_constant (0, expressionP);
82933965Sjdp	      break;
83033965Sjdp	    }
83133965Sjdp	  /* Fall through.  */
83233965Sjdp	default:
83333965Sjdp	default_case:
83433965Sjdp	  if (c && strchr (FLT_CHARS, c))
83533965Sjdp	    {
83633965Sjdp	      input_line_pointer++;
83733965Sjdp	      floating_constant (expressionP);
83889857Sobrien	      expressionP->X_add_number = - TOLOWER (c);
83933965Sjdp	    }
84033965Sjdp	  else
84133965Sjdp	    {
84277298Sobrien	      /* The string was only zero.  */
84333965Sjdp	      expressionP->X_op = O_constant;
84433965Sjdp	      expressionP->X_add_number = 0;
84533965Sjdp	    }
84633965Sjdp
84733965Sjdp	  break;
84833965Sjdp
84933965Sjdp	case 'x':
85033965Sjdp	case 'X':
85133965Sjdp	  if (flag_m68k_mri)
85233965Sjdp	    goto default_case;
85333965Sjdp	  input_line_pointer++;
85433965Sjdp	  integer_constant (16, expressionP);
85533965Sjdp	  break;
85633965Sjdp
85733965Sjdp	case 'b':
85860484Sobrien	  if (LOCAL_LABELS_FB && ! (flag_m68k_mri || NUMBERS_WITH_SUFFIX))
85933965Sjdp	    {
86033965Sjdp	      /* This code used to check for '+' and '-' here, and, in
86133965Sjdp		 some conditions, fall through to call
86233965Sjdp		 integer_constant.  However, that didn't make sense,
86333965Sjdp		 as integer_constant only accepts digits.  */
86433965Sjdp	      /* Some of our code elsewhere does permit digits greater
86533965Sjdp		 than the expected base; for consistency, do the same
86633965Sjdp		 here.  */
86733965Sjdp	      if (input_line_pointer[1] < '0'
86833965Sjdp		  || input_line_pointer[1] > '9')
86933965Sjdp		{
87033965Sjdp		  /* Parse this as a back reference to label 0.  */
87133965Sjdp		  input_line_pointer--;
87233965Sjdp		  integer_constant (10, expressionP);
87333965Sjdp		  break;
87433965Sjdp		}
87533965Sjdp	      /* Otherwise, parse this as a binary number.  */
87633965Sjdp	    }
87733965Sjdp	  /* Fall through.  */
87833965Sjdp	case 'B':
87933965Sjdp	  input_line_pointer++;
88060484Sobrien	  if (flag_m68k_mri || NUMBERS_WITH_SUFFIX)
88133965Sjdp	    goto default_case;
88233965Sjdp	  integer_constant (2, expressionP);
88333965Sjdp	  break;
88433965Sjdp
88533965Sjdp	case '0':
88633965Sjdp	case '1':
88733965Sjdp	case '2':
88833965Sjdp	case '3':
88933965Sjdp	case '4':
89033965Sjdp	case '5':
89133965Sjdp	case '6':
89233965Sjdp	case '7':
89360484Sobrien	  integer_constant ((flag_m68k_mri || NUMBERS_WITH_SUFFIX)
89477298Sobrien			    ? 0 : 8,
89577298Sobrien			    expressionP);
89633965Sjdp	  break;
89733965Sjdp
89833965Sjdp	case 'f':
89933965Sjdp	  if (LOCAL_LABELS_FB)
90033965Sjdp	    {
90133965Sjdp	      /* If it says "0f" and it could possibly be a floating point
90233965Sjdp		 number, make it one.  Otherwise, make it a local label,
90333965Sjdp		 and try to deal with parsing the rest later.  */
90433965Sjdp	      if (!input_line_pointer[1]
90560484Sobrien		  || (is_end_of_line[0xff & input_line_pointer[1]])
90660484Sobrien		  || strchr (FLT_CHARS, 'f') == NULL)
90733965Sjdp		goto is_0f_label;
90833965Sjdp	      {
90933965Sjdp		char *cp = input_line_pointer + 1;
91033965Sjdp		int r = atof_generic (&cp, ".", EXP_CHARS,
91133965Sjdp				      &generic_floating_point_number);
91233965Sjdp		switch (r)
91333965Sjdp		  {
91433965Sjdp		  case 0:
91533965Sjdp		  case ERROR_EXPONENT_OVERFLOW:
91633965Sjdp		    if (*cp == 'f' || *cp == 'b')
91777298Sobrien		      /* Looks like a difference expression.  */
91833965Sjdp		      goto is_0f_label;
91960484Sobrien		    else if (cp == input_line_pointer + 1)
92060484Sobrien		      /* No characters has been accepted -- looks like
92177298Sobrien			 end of operand.  */
92260484Sobrien		      goto is_0f_label;
92333965Sjdp		    else
92433965Sjdp		      goto is_0f_float;
92533965Sjdp		  default:
92660484Sobrien		    as_fatal (_("expr.c(operand): bad atof_generic return val %d"),
92733965Sjdp			      r);
92833965Sjdp		  }
92933965Sjdp	      }
93033965Sjdp
93133965Sjdp	      /* Okay, now we've sorted it out.  We resume at one of these
93233965Sjdp		 two labels, depending on what we've decided we're probably
93333965Sjdp		 looking at.  */
93433965Sjdp	    is_0f_label:
93533965Sjdp	      input_line_pointer--;
93633965Sjdp	      integer_constant (10, expressionP);
93733965Sjdp	      break;
93833965Sjdp
93933965Sjdp	    is_0f_float:
94077298Sobrien	      /* Fall through.  */
94133965Sjdp	      ;
94233965Sjdp	    }
94333965Sjdp
94433965Sjdp	case 'd':
94533965Sjdp	case 'D':
94660484Sobrien	  if (flag_m68k_mri || NUMBERS_WITH_SUFFIX)
94733965Sjdp	    {
94833965Sjdp	      integer_constant (0, expressionP);
94933965Sjdp	      break;
95033965Sjdp	    }
95133965Sjdp	  /* Fall through.  */
95233965Sjdp	case 'F':
95333965Sjdp	case 'r':
95433965Sjdp	case 'e':
95533965Sjdp	case 'E':
95633965Sjdp	case 'g':
95733965Sjdp	case 'G':
95833965Sjdp	  input_line_pointer++;
95933965Sjdp	  floating_constant (expressionP);
96089857Sobrien	  expressionP->X_add_number = - TOLOWER (c);
96133965Sjdp	  break;
96233965Sjdp
96333965Sjdp	case '$':
96433965Sjdp	  if (LOCAL_LABELS_DOLLAR)
96533965Sjdp	    {
96633965Sjdp	      integer_constant (10, expressionP);
96733965Sjdp	      break;
96833965Sjdp	    }
96933965Sjdp	  else
97033965Sjdp	    goto default_case;
97133965Sjdp	}
97233965Sjdp
97333965Sjdp      break;
97433965Sjdp
97533965Sjdp    case '(':
97660484Sobrien#ifndef NEED_INDEX_OPERATOR
97733965Sjdp    case '[':
97860484Sobrien#endif
97977298Sobrien      /* Didn't begin with digit & not a name.  */
98033965Sjdp      segment = expression (expressionP);
98177298Sobrien      /* expression () will pass trailing whitespace.  */
98277298Sobrien      if ((c == '(' && *input_line_pointer != ')')
98377298Sobrien	  || (c == '[' && *input_line_pointer != ']'))
98433965Sjdp	{
98577298Sobrien#ifdef RELAX_PAREN_GROUPING
98677298Sobrien	  if (c != '(')
98777298Sobrien#endif
98889857Sobrien	    as_bad (_("missing '%c'"), c == '(' ? ')' : ']');
98933965Sjdp	}
99077298Sobrien      else
99177298Sobrien	input_line_pointer++;
99233965Sjdp      SKIP_WHITESPACE ();
99377298Sobrien      /* Here with input_line_pointer -> char after "(...)".  */
99433965Sjdp      return segment;
99533965Sjdp
99660484Sobrien#ifdef TC_M68K
99733965Sjdp    case 'E':
99833965Sjdp      if (! flag_m68k_mri || *input_line_pointer != '\'')
99933965Sjdp	goto de_fault;
100060484Sobrien      as_bad (_("EBCDIC constants are not supported"));
100133965Sjdp      /* Fall through.  */
100233965Sjdp    case 'A':
100333965Sjdp      if (! flag_m68k_mri || *input_line_pointer != '\'')
100433965Sjdp	goto de_fault;
100533965Sjdp      ++input_line_pointer;
100633965Sjdp      /* Fall through.  */
100760484Sobrien#endif
100833965Sjdp    case '\'':
100933965Sjdp      if (! flag_m68k_mri)
101033965Sjdp	{
101133965Sjdp	  /* Warning: to conform to other people's assemblers NO
101277298Sobrien	     ESCAPEMENT is permitted for a single quote.  The next
101333965Sjdp	     character, parity errors and all, is taken as the value
101477298Sobrien	     of the operand.  VERY KINKY.  */
101533965Sjdp	  expressionP->X_op = O_constant;
101633965Sjdp	  expressionP->X_add_number = *input_line_pointer++;
101733965Sjdp	  break;
101833965Sjdp	}
101933965Sjdp
102033965Sjdp      mri_char_constant (expressionP);
102133965Sjdp      break;
102233965Sjdp
102333965Sjdp    case '+':
1024130561Sobrien      /* Do not accept ++e as +(+e).
1025130561Sobrien	 Disabled, since the preprocessor removes whitespace.  */
1026130561Sobrien      if (0 && *input_line_pointer == '+')
1027130561Sobrien	goto target_op;
102833965Sjdp      (void) operand (expressionP);
102933965Sjdp      break;
103033965Sjdp
103160484Sobrien#ifdef TC_M68K
103233965Sjdp    case '"':
103333965Sjdp      /* Double quote is the bitwise not operator in MRI mode.  */
103433965Sjdp      if (! flag_m68k_mri)
103533965Sjdp	goto de_fault;
103633965Sjdp      /* Fall through.  */
103760484Sobrien#endif
103833965Sjdp    case '~':
103977298Sobrien      /* '~' is permitted to start a label on the Delta.  */
104033965Sjdp      if (is_name_beginner (c))
104133965Sjdp	goto isname;
104233965Sjdp    case '!':
104333965Sjdp    case '-':
104433965Sjdp      {
1045130561Sobrien        /* Do not accept --e as -(-e)
1046130561Sobrien	   Disabled, since the preprocessor removes whitespace.  */
1047130561Sobrien	if (0 && c == '-' && *input_line_pointer == '-')
1048130561Sobrien	  goto target_op;
1049130561Sobrien
105033965Sjdp	operand (expressionP);
105133965Sjdp	if (expressionP->X_op == O_constant)
105233965Sjdp	  {
105377298Sobrien	    /* input_line_pointer -> char after operand.  */
105433965Sjdp	    if (c == '-')
105533965Sjdp	      {
105633965Sjdp		expressionP->X_add_number = - expressionP->X_add_number;
105777298Sobrien		/* Notice: '-' may overflow: no warning is given.
105877298Sobrien		   This is compatible with other people's
105977298Sobrien		   assemblers.  Sigh.  */
106033965Sjdp		expressionP->X_unsigned = 0;
106133965Sjdp	      }
106233965Sjdp	    else if (c == '~' || c == '"')
106333965Sjdp	      expressionP->X_add_number = ~ expressionP->X_add_number;
106433965Sjdp	    else
106533965Sjdp	      expressionP->X_add_number = ! expressionP->X_add_number;
106633965Sjdp	  }
1067130561Sobrien	else if (expressionP->X_op == O_big
1068130561Sobrien		 && expressionP->X_add_number <= 0
1069130561Sobrien		 && c == '-'
1070130561Sobrien		 && (generic_floating_point_number.sign == '+'
1071130561Sobrien		     || generic_floating_point_number.sign == 'P'))
1072130561Sobrien	  {
1073130561Sobrien	    /* Negative flonum (eg, -1.000e0).  */
1074130561Sobrien	    if (generic_floating_point_number.sign == '+')
1075130561Sobrien	      generic_floating_point_number.sign = '-';
1076130561Sobrien	    else
1077130561Sobrien	      generic_floating_point_number.sign = 'N';
1078130561Sobrien	  }
107933965Sjdp	else if (expressionP->X_op != O_illegal
108033965Sjdp		 && expressionP->X_op != O_absent)
108133965Sjdp	  {
108233965Sjdp	    expressionP->X_add_symbol = make_expr_symbol (expressionP);
108333965Sjdp	    if (c == '-')
108433965Sjdp	      expressionP->X_op = O_uminus;
108533965Sjdp	    else if (c == '~' || c == '"')
108633965Sjdp	      expressionP->X_op = O_bit_not;
108733965Sjdp	    else
108833965Sjdp	      expressionP->X_op = O_logical_not;
108933965Sjdp	    expressionP->X_add_number = 0;
109033965Sjdp	  }
109133965Sjdp	else
109260484Sobrien	  as_warn (_("Unary operator %c ignored because bad operand follows"),
109333965Sjdp		   c);
109433965Sjdp      }
109533965Sjdp      break;
109633965Sjdp
109760484Sobrien#if defined (DOLLAR_DOT) || defined (TC_M68K)
109833965Sjdp    case '$':
109977298Sobrien      /* '$' is the program counter when in MRI mode, or when
1100130561Sobrien	 DOLLAR_DOT is defined.  */
110133965Sjdp#ifndef DOLLAR_DOT
110233965Sjdp      if (! flag_m68k_mri)
110333965Sjdp	goto de_fault;
110433965Sjdp#endif
110533965Sjdp      if (flag_m68k_mri && hex_p (*input_line_pointer))
110633965Sjdp	{
110777298Sobrien	  /* In MRI mode, '$' is also used as the prefix for a
1108130561Sobrien	     hexadecimal constant.  */
110933965Sjdp	  integer_constant (16, expressionP);
111033965Sjdp	  break;
111133965Sjdp	}
111233965Sjdp
111333965Sjdp      if (is_part_of_name (*input_line_pointer))
111433965Sjdp	goto isname;
111533965Sjdp
111633965Sjdp      current_location (expressionP);
111733965Sjdp      break;
111860484Sobrien#endif
111933965Sjdp
112033965Sjdp    case '.':
112133965Sjdp      if (!is_part_of_name (*input_line_pointer))
112233965Sjdp	{
112333965Sjdp	  current_location (expressionP);
112433965Sjdp	  break;
112533965Sjdp	}
112633965Sjdp      else if ((strncasecmp (input_line_pointer, "startof.", 8) == 0
112733965Sjdp		&& ! is_part_of_name (input_line_pointer[8]))
112833965Sjdp	       || (strncasecmp (input_line_pointer, "sizeof.", 7) == 0
112933965Sjdp		   && ! is_part_of_name (input_line_pointer[7])))
113033965Sjdp	{
113133965Sjdp	  int start;
113233965Sjdp
113333965Sjdp	  start = (input_line_pointer[1] == 't'
113433965Sjdp		   || input_line_pointer[1] == 'T');
113533965Sjdp	  input_line_pointer += start ? 8 : 7;
113633965Sjdp	  SKIP_WHITESPACE ();
113733965Sjdp	  if (*input_line_pointer != '(')
113860484Sobrien	    as_bad (_("syntax error in .startof. or .sizeof."));
113933965Sjdp	  else
114033965Sjdp	    {
114133965Sjdp	      char *buf;
114233965Sjdp
114333965Sjdp	      ++input_line_pointer;
114433965Sjdp	      SKIP_WHITESPACE ();
114533965Sjdp	      name = input_line_pointer;
114633965Sjdp	      c = get_symbol_end ();
114733965Sjdp
114833965Sjdp	      buf = (char *) xmalloc (strlen (name) + 10);
114933965Sjdp	      if (start)
115033965Sjdp		sprintf (buf, ".startof.%s", name);
115133965Sjdp	      else
115233965Sjdp		sprintf (buf, ".sizeof.%s", name);
115333965Sjdp	      symbolP = symbol_make (buf);
115433965Sjdp	      free (buf);
115533965Sjdp
115633965Sjdp	      expressionP->X_op = O_symbol;
115733965Sjdp	      expressionP->X_add_symbol = symbolP;
115833965Sjdp	      expressionP->X_add_number = 0;
115933965Sjdp
116033965Sjdp	      *input_line_pointer = c;
116133965Sjdp	      SKIP_WHITESPACE ();
116233965Sjdp	      if (*input_line_pointer != ')')
116360484Sobrien		as_bad (_("syntax error in .startof. or .sizeof."));
116433965Sjdp	      else
116533965Sjdp		++input_line_pointer;
116633965Sjdp	    }
116733965Sjdp	  break;
116833965Sjdp	}
116933965Sjdp      else
117033965Sjdp	{
117133965Sjdp	  goto isname;
117233965Sjdp	}
117377298Sobrien
117433965Sjdp    case ',':
117533965Sjdp    eol:
117677298Sobrien      /* Can't imagine any other kind of operand.  */
117733965Sjdp      expressionP->X_op = O_absent;
117833965Sjdp      input_line_pointer--;
117933965Sjdp      break;
118033965Sjdp
118160484Sobrien#ifdef TC_M68K
118233965Sjdp    case '%':
118333965Sjdp      if (! flag_m68k_mri)
118433965Sjdp	goto de_fault;
118533965Sjdp      integer_constant (2, expressionP);
118633965Sjdp      break;
118733965Sjdp
118833965Sjdp    case '@':
118933965Sjdp      if (! flag_m68k_mri)
119033965Sjdp	goto de_fault;
119133965Sjdp      integer_constant (8, expressionP);
119233965Sjdp      break;
119333965Sjdp
119433965Sjdp    case ':':
119533965Sjdp      if (! flag_m68k_mri)
119633965Sjdp	goto de_fault;
119733965Sjdp
119833965Sjdp      /* In MRI mode, this is a floating point constant represented
1199130561Sobrien	 using hexadecimal digits.  */
120033965Sjdp
120133965Sjdp      ++input_line_pointer;
120233965Sjdp      integer_constant (16, expressionP);
120333965Sjdp      break;
120433965Sjdp
120533965Sjdp    case '*':
120633965Sjdp      if (! flag_m68k_mri || is_part_of_name (*input_line_pointer))
120733965Sjdp	goto de_fault;
120833965Sjdp
120933965Sjdp      current_location (expressionP);
121033965Sjdp      break;
121160484Sobrien#endif
121233965Sjdp
121333965Sjdp    default:
121460484Sobrien#ifdef TC_M68K
121533965Sjdp    de_fault:
121660484Sobrien#endif
121777298Sobrien      if (is_name_beginner (c))	/* Here if did not begin with a digit.  */
121833965Sjdp	{
121977298Sobrien	  /* Identifier begins here.
122077298Sobrien	     This is kludged for speed, so code is repeated.  */
122133965Sjdp	isname:
122233965Sjdp	  name = --input_line_pointer;
122333965Sjdp	  c = get_symbol_end ();
122433965Sjdp
122533965Sjdp#ifdef md_parse_name
122633965Sjdp	  /* This is a hook for the backend to parse certain names
1227130561Sobrien	     specially in certain contexts.  If a name always has a
1228130561Sobrien	     specific value, it can often be handled by simply
1229130561Sobrien	     entering it in the symbol table.  */
123089857Sobrien	  if (md_parse_name (name, expressionP, &c))
123133965Sjdp	    {
123233965Sjdp	      *input_line_pointer = c;
123333965Sjdp	      break;
123433965Sjdp	    }
123533965Sjdp#endif
123633965Sjdp
123733965Sjdp#ifdef TC_I960
123833965Sjdp	  /* The MRI i960 assembler permits
123933965Sjdp	         lda sizeof code,g13
124033965Sjdp	     FIXME: This should use md_parse_name.  */
124133965Sjdp	  if (flag_mri
124233965Sjdp	      && (strcasecmp (name, "sizeof") == 0
124333965Sjdp		  || strcasecmp (name, "startof") == 0))
124433965Sjdp	    {
124533965Sjdp	      int start;
124633965Sjdp	      char *buf;
124733965Sjdp
124833965Sjdp	      start = (name[1] == 't'
124933965Sjdp		       || name[1] == 'T');
125033965Sjdp
125133965Sjdp	      *input_line_pointer = c;
125233965Sjdp	      SKIP_WHITESPACE ();
125333965Sjdp
125433965Sjdp	      name = input_line_pointer;
125533965Sjdp	      c = get_symbol_end ();
125633965Sjdp
125733965Sjdp	      buf = (char *) xmalloc (strlen (name) + 10);
125833965Sjdp	      if (start)
125933965Sjdp		sprintf (buf, ".startof.%s", name);
126033965Sjdp	      else
126133965Sjdp		sprintf (buf, ".sizeof.%s", name);
126233965Sjdp	      symbolP = symbol_make (buf);
126333965Sjdp	      free (buf);
126433965Sjdp
126533965Sjdp	      expressionP->X_op = O_symbol;
126633965Sjdp	      expressionP->X_add_symbol = symbolP;
126733965Sjdp	      expressionP->X_add_number = 0;
126833965Sjdp
126933965Sjdp	      *input_line_pointer = c;
127033965Sjdp	      SKIP_WHITESPACE ();
127133965Sjdp
127233965Sjdp	      break;
127377298Sobrien	    }
127433965Sjdp#endif
127533965Sjdp
127633965Sjdp	  symbolP = symbol_find_or_make (name);
127733965Sjdp
127833965Sjdp	  /* If we have an absolute symbol or a reg, then we know its
127933965Sjdp	     value now.  */
128033965Sjdp	  segment = S_GET_SEGMENT (symbolP);
128133965Sjdp	  if (segment == absolute_section)
128233965Sjdp	    {
128333965Sjdp	      expressionP->X_op = O_constant;
128433965Sjdp	      expressionP->X_add_number = S_GET_VALUE (symbolP);
128533965Sjdp	    }
128633965Sjdp	  else if (segment == reg_section)
128733965Sjdp	    {
128833965Sjdp	      expressionP->X_op = O_register;
128933965Sjdp	      expressionP->X_add_number = S_GET_VALUE (symbolP);
129033965Sjdp	    }
129133965Sjdp	  else
129233965Sjdp	    {
129333965Sjdp	      expressionP->X_op = O_symbol;
129433965Sjdp	      expressionP->X_add_symbol = symbolP;
129533965Sjdp	      expressionP->X_add_number = 0;
129633965Sjdp	    }
129733965Sjdp	  *input_line_pointer = c;
129833965Sjdp	}
129933965Sjdp      else
130033965Sjdp	{
1301130561Sobrien	target_op:
130233965Sjdp	  /* Let the target try to parse it.  Success is indicated by changing
130333965Sjdp	     the X_op field to something other than O_absent and pointing
130477298Sobrien	     input_line_pointer past the expression.  If it can't parse the
130533965Sjdp	     expression, X_op and input_line_pointer should be unchanged.  */
130633965Sjdp	  expressionP->X_op = O_absent;
130733965Sjdp	  --input_line_pointer;
130833965Sjdp	  md_operand (expressionP);
130933965Sjdp	  if (expressionP->X_op == O_absent)
131033965Sjdp	    {
131133965Sjdp	      ++input_line_pointer;
131289857Sobrien	      as_bad (_("bad expression"));
131333965Sjdp	      expressionP->X_op = O_constant;
131433965Sjdp	      expressionP->X_add_number = 0;
131533965Sjdp	    }
131633965Sjdp	}
131733965Sjdp      break;
131833965Sjdp    }
131933965Sjdp
132077298Sobrien  /* It is more 'efficient' to clean up the expressionS when they are
132177298Sobrien     created.  Doing it here saves lines of code.  */
132233965Sjdp  clean_up_expression (expressionP);
132377298Sobrien  SKIP_WHITESPACE ();		/* -> 1st char after operand.  */
132433965Sjdp  know (*input_line_pointer != ' ');
132533965Sjdp
132633965Sjdp  /* The PA port needs this information.  */
132733965Sjdp  if (expressionP->X_add_symbol)
132860484Sobrien    symbol_mark_used (expressionP->X_add_symbol);
132933965Sjdp
133033965Sjdp  switch (expressionP->X_op)
133133965Sjdp    {
133233965Sjdp    default:
133333965Sjdp      return absolute_section;
133433965Sjdp    case O_symbol:
133533965Sjdp      return S_GET_SEGMENT (expressionP->X_add_symbol);
133633965Sjdp    case O_register:
133733965Sjdp      return reg_section;
133833965Sjdp    }
133977298Sobrien}
134033965Sjdp
134177298Sobrien/* Internal.  Simplify a struct expression for use by expr ().  */
134233965Sjdp
134389857Sobrien/* In:	address of an expressionS.
134477298Sobrien	The X_op field of the expressionS may only take certain values.
134577298Sobrien	Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT.
134633965Sjdp
134777298Sobrien   Out:	expressionS may have been modified:
134877298Sobrien	Unused fields zeroed to help expr ().  */
134977298Sobrien
135033965Sjdpstatic void
1351130561Sobrienclean_up_expression (expressionS *expressionP)
135233965Sjdp{
135333965Sjdp  switch (expressionP->X_op)
135433965Sjdp    {
135533965Sjdp    case O_illegal:
135633965Sjdp    case O_absent:
135733965Sjdp      expressionP->X_add_number = 0;
135833965Sjdp      /* Fall through.  */
135933965Sjdp    case O_big:
136033965Sjdp    case O_constant:
136133965Sjdp    case O_register:
136233965Sjdp      expressionP->X_add_symbol = NULL;
136333965Sjdp      /* Fall through.  */
136433965Sjdp    case O_symbol:
136533965Sjdp    case O_uminus:
136633965Sjdp    case O_bit_not:
136733965Sjdp      expressionP->X_op_symbol = NULL;
136833965Sjdp      break;
136933965Sjdp    default:
137033965Sjdp      break;
137133965Sjdp    }
137233965Sjdp}
137333965Sjdp
137477298Sobrien/* Expression parser.  */
137533965Sjdp
137677298Sobrien/* We allow an empty expression, and just assume (absolute,0) silently.
137777298Sobrien   Unary operators and parenthetical expressions are treated as operands.
137877298Sobrien   As usual, Q==quantity==operand, O==operator, X==expression mnemonics.
137933965Sjdp
138089857Sobrien   We used to do an aho/ullman shift-reduce parser, but the logic got so
138177298Sobrien   warped that I flushed it and wrote a recursive-descent parser instead.
138277298Sobrien   Now things are stable, would anybody like to write a fast parser?
138377298Sobrien   Most expressions are either register (which does not even reach here)
138477298Sobrien   or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common.
138577298Sobrien   So I guess it doesn't really matter how inefficient more complex expressions
138677298Sobrien   are parsed.
138777298Sobrien
138877298Sobrien   After expr(RANK,resultP) input_line_pointer->operator of rank <= RANK.
138977298Sobrien   Also, we have consumed any leading or trailing spaces (operand does that)
139077298Sobrien   and done all intervening operators.
139177298Sobrien
139277298Sobrien   This returns the segment of the result, which will be
139377298Sobrien   absolute_section or the segment of a symbol.  */
139477298Sobrien
139533965Sjdp#undef __
139633965Sjdp#define __ O_illegal
139733965Sjdp
139877298Sobrien/* Maps ASCII -> operators.  */
139977298Sobrienstatic const operatorT op_encoding[256] = {
140033965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
140133965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
140233965Sjdp
140333965Sjdp  __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __,
140433965Sjdp  __, __, O_multiply, O_add, __, O_subtract, __, O_divide,
140533965Sjdp  __, __, __, __, __, __, __, __,
140633965Sjdp  __, __, __, __, O_lt, __, O_gt, __,
140733965Sjdp  __, __, __, __, __, __, __, __,
140833965Sjdp  __, __, __, __, __, __, __, __,
140933965Sjdp  __, __, __, __, __, __, __, __,
141060484Sobrien  __, __, __,
141160484Sobrien#ifdef NEED_INDEX_OPERATOR
141260484Sobrien  O_index,
141360484Sobrien#else
141460484Sobrien  __,
141560484Sobrien#endif
141660484Sobrien  __, __, O_bit_exclusive_or, __,
141733965Sjdp  __, __, __, __, __, __, __, __,
141833965Sjdp  __, __, __, __, __, __, __, __,
141933965Sjdp  __, __, __, __, __, __, __, __,
142033965Sjdp  __, __, __, __, O_bit_inclusive_or, __, __, __,
142133965Sjdp
142233965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142333965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142433965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142533965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142633965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142733965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142833965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142933965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
143033965Sjdp};
143133965Sjdp
143277298Sobrien/* Rank	Examples
143377298Sobrien   0	operand, (expression)
143477298Sobrien   1	||
143577298Sobrien   2	&&
143689857Sobrien   3	== <> < <= >= >
143777298Sobrien   4	+ -
143877298Sobrien   5	used for * / % in MRI mode
143977298Sobrien   6	& ^ ! |
144077298Sobrien   7	* / % << >>
144177298Sobrien   8	unary - unary ~
144277298Sobrien*/
144377298Sobrienstatic operator_rankT op_rank[] = {
144433965Sjdp  0,	/* O_illegal */
144533965Sjdp  0,	/* O_absent */
144633965Sjdp  0,	/* O_constant */
144733965Sjdp  0,	/* O_symbol */
144833965Sjdp  0,	/* O_symbol_rva */
144933965Sjdp  0,	/* O_register */
145077298Sobrien  0,	/* O_big */
145160484Sobrien  9,	/* O_uminus */
145260484Sobrien  9,	/* O_bit_not */
145360484Sobrien  9,	/* O_logical_not */
145460484Sobrien  8,	/* O_multiply */
145560484Sobrien  8,	/* O_divide */
145660484Sobrien  8,	/* O_modulus */
145760484Sobrien  8,	/* O_left_shift */
145860484Sobrien  8,	/* O_right_shift */
145960484Sobrien  7,	/* O_bit_inclusive_or */
146060484Sobrien  7,	/* O_bit_or_not */
146160484Sobrien  7,	/* O_bit_exclusive_or */
146260484Sobrien  7,	/* O_bit_and */
146360484Sobrien  5,	/* O_add */
146460484Sobrien  5,	/* O_subtract */
146560484Sobrien  4,	/* O_eq */
146660484Sobrien  4,	/* O_ne */
146760484Sobrien  4,	/* O_lt */
146860484Sobrien  4,	/* O_le */
146960484Sobrien  4,	/* O_ge */
147060484Sobrien  4,	/* O_gt */
147160484Sobrien  3,	/* O_logical_and */
147260484Sobrien  2,	/* O_logical_or */
147360484Sobrien  1,	/* O_index */
147460484Sobrien  0,	/* O_md1 */
147560484Sobrien  0,	/* O_md2 */
147660484Sobrien  0,	/* O_md3 */
147760484Sobrien  0,	/* O_md4 */
147860484Sobrien  0,	/* O_md5 */
147960484Sobrien  0,	/* O_md6 */
148060484Sobrien  0,	/* O_md7 */
148160484Sobrien  0,	/* O_md8 */
148260484Sobrien  0,	/* O_md9 */
148360484Sobrien  0,	/* O_md10 */
148460484Sobrien  0,	/* O_md11 */
148560484Sobrien  0,	/* O_md12 */
148660484Sobrien  0,	/* O_md13 */
148760484Sobrien  0,	/* O_md14 */
148860484Sobrien  0,	/* O_md15 */
148960484Sobrien  0,	/* O_md16 */
149033965Sjdp};
149133965Sjdp
149260484Sobrien/* Unfortunately, in MRI mode for the m68k, multiplication and
149360484Sobrien   division have lower precedence than the bit wise operators.  This
149460484Sobrien   function sets the operator precedences correctly for the current
149560484Sobrien   mode.  Also, MRI uses a different bit_not operator, and this fixes
149660484Sobrien   that as well.  */
149733965Sjdp
149877298Sobrien#define STANDARD_MUL_PRECEDENCE 8
149977298Sobrien#define MRI_MUL_PRECEDENCE 6
150060484Sobrien
150133965Sjdpvoid
1502130561Sobrienexpr_set_precedence (void)
150333965Sjdp{
150433965Sjdp  if (flag_m68k_mri)
150533965Sjdp    {
150660484Sobrien      op_rank[O_multiply] = MRI_MUL_PRECEDENCE;
150760484Sobrien      op_rank[O_divide] = MRI_MUL_PRECEDENCE;
150860484Sobrien      op_rank[O_modulus] = MRI_MUL_PRECEDENCE;
150933965Sjdp    }
151060484Sobrien  else
151160484Sobrien    {
151260484Sobrien      op_rank[O_multiply] = STANDARD_MUL_PRECEDENCE;
151360484Sobrien      op_rank[O_divide] = STANDARD_MUL_PRECEDENCE;
151460484Sobrien      op_rank[O_modulus] = STANDARD_MUL_PRECEDENCE;
151560484Sobrien    }
151660484Sobrien}
151733965Sjdp
151860484Sobrien/* Initialize the expression parser.  */
151960484Sobrien
152060484Sobrienvoid
1521130561Sobrienexpr_begin (void)
152260484Sobrien{
152360484Sobrien  expr_set_precedence ();
152460484Sobrien
152533965Sjdp  /* Verify that X_op field is wide enough.  */
152633965Sjdp  {
152733965Sjdp    expressionS e;
152833965Sjdp    e.X_op = O_max;
152933965Sjdp    assert (e.X_op == O_max);
153033965Sjdp  }
153133965Sjdp}
153233965Sjdp
153377298Sobrien/* Return the encoding for the operator at INPUT_LINE_POINTER, and
153477298Sobrien   sets NUM_CHARS to the number of characters in the operator.
153577298Sobrien   Does not advance INPUT_LINE_POINTER.  */
153633965Sjdp
153733965Sjdpstatic inline operatorT
1538130561Sobrienoperator (int *num_chars)
153933965Sjdp{
154033965Sjdp  int c;
154133965Sjdp  operatorT ret;
154233965Sjdp
154360484Sobrien  c = *input_line_pointer & 0xff;
154477298Sobrien  *num_chars = 1;
154533965Sjdp
154677298Sobrien  if (is_end_of_line[c])
154777298Sobrien    return O_illegal;
154877298Sobrien
154933965Sjdp  switch (c)
155033965Sjdp    {
155133965Sjdp    default:
155233965Sjdp      return op_encoding[c];
155333965Sjdp
1554130561Sobrien    case '+':
1555130561Sobrien    case '-':
1556130561Sobrien      /* Do not allow a++b and a--b to be a + (+b) and a - (-b)
1557130561Sobrien	 Disabled, since the preprocessor removes whitespace.  */
1558130561Sobrien      if (1 || input_line_pointer[1] != c)
1559130561Sobrien	return op_encoding[c];
1560130561Sobrien      return O_illegal;
1561130561Sobrien
156233965Sjdp    case '<':
156333965Sjdp      switch (input_line_pointer[1])
156433965Sjdp	{
156533965Sjdp	default:
156633965Sjdp	  return op_encoding[c];
156733965Sjdp	case '<':
156833965Sjdp	  ret = O_left_shift;
156933965Sjdp	  break;
157033965Sjdp	case '>':
157133965Sjdp	  ret = O_ne;
157233965Sjdp	  break;
157333965Sjdp	case '=':
157433965Sjdp	  ret = O_le;
157533965Sjdp	  break;
157633965Sjdp	}
157777298Sobrien      *num_chars = 2;
157833965Sjdp      return ret;
157933965Sjdp
158038889Sjdp    case '=':
158138889Sjdp      if (input_line_pointer[1] != '=')
158238889Sjdp	return op_encoding[c];
158338889Sjdp
158477298Sobrien      *num_chars = 2;
158538889Sjdp      return O_eq;
158638889Sjdp
158733965Sjdp    case '>':
158833965Sjdp      switch (input_line_pointer[1])
158933965Sjdp	{
159033965Sjdp	default:
159133965Sjdp	  return op_encoding[c];
159233965Sjdp	case '>':
159333965Sjdp	  ret = O_right_shift;
159433965Sjdp	  break;
159533965Sjdp	case '=':
159633965Sjdp	  ret = O_ge;
159733965Sjdp	  break;
159833965Sjdp	}
159977298Sobrien      *num_chars = 2;
160033965Sjdp      return ret;
160133965Sjdp
160233965Sjdp    case '!':
160333965Sjdp      /* We accept !! as equivalent to ^ for MRI compatibility.  */
160433965Sjdp      if (input_line_pointer[1] != '!')
160533965Sjdp	{
160633965Sjdp	  if (flag_m68k_mri)
160733965Sjdp	    return O_bit_inclusive_or;
160833965Sjdp	  return op_encoding[c];
160933965Sjdp	}
161077298Sobrien      *num_chars = 2;
161133965Sjdp      return O_bit_exclusive_or;
161233965Sjdp
161333965Sjdp    case '|':
161433965Sjdp      if (input_line_pointer[1] != '|')
161533965Sjdp	return op_encoding[c];
161633965Sjdp
161777298Sobrien      *num_chars = 2;
161833965Sjdp      return O_logical_or;
161933965Sjdp
162033965Sjdp    case '&':
162133965Sjdp      if (input_line_pointer[1] != '&')
162233965Sjdp	return op_encoding[c];
162333965Sjdp
162477298Sobrien      *num_chars = 2;
162533965Sjdp      return O_logical_and;
162633965Sjdp    }
162733965Sjdp
162877298Sobrien  /* NOTREACHED  */
162938889Sjdp}
163033965Sjdp
163133965Sjdp/* Parse an expression.  */
163233965Sjdp
163333965SjdpsegT
1634130561Sobrienexpr (int rankarg,		/* Larger # is higher rank.  */
1635130561Sobrien      expressionS *resultP	/* Deliver result here.  */)
163633965Sjdp{
163760484Sobrien  operator_rankT rank = (operator_rankT) rankarg;
163833965Sjdp  segT retval;
163933965Sjdp  expressionS right;
164033965Sjdp  operatorT op_left;
164133965Sjdp  operatorT op_right;
164277298Sobrien  int op_chars;
164333965Sjdp
164433965Sjdp  know (rank >= 0);
164533965Sjdp
1646130561Sobrien  /* Save the value of dot for the fixup code.  */
1647130561Sobrien  if (rank == 0)
1648130561Sobrien    dot_value = frag_now_fix ();
1649130561Sobrien
165033965Sjdp  retval = operand (resultP);
165133965Sjdp
165277298Sobrien  /* operand () gobbles spaces.  */
165377298Sobrien  know (*input_line_pointer != ' ');
165433965Sjdp
165577298Sobrien  op_left = operator (&op_chars);
165633965Sjdp  while (op_left != O_illegal && op_rank[(int) op_left] > rank)
165733965Sjdp    {
165833965Sjdp      segT rightseg;
165933965Sjdp
166077298Sobrien      input_line_pointer += op_chars;	/* -> after operator.  */
166133965Sjdp
166233965Sjdp      rightseg = expr (op_rank[(int) op_left], &right);
166333965Sjdp      if (right.X_op == O_absent)
166433965Sjdp	{
166560484Sobrien	  as_warn (_("missing operand; zero assumed"));
166633965Sjdp	  right.X_op = O_constant;
166733965Sjdp	  right.X_add_number = 0;
166833965Sjdp	  right.X_add_symbol = NULL;
166933965Sjdp	  right.X_op_symbol = NULL;
167033965Sjdp	}
167133965Sjdp
167233965Sjdp      know (*input_line_pointer != ' ');
167333965Sjdp
167460484Sobrien      if (op_left == O_index)
167560484Sobrien	{
167660484Sobrien	  if (*input_line_pointer != ']')
167760484Sobrien	    as_bad ("missing right bracket");
167860484Sobrien	  else
167960484Sobrien	    {
168060484Sobrien	      ++input_line_pointer;
168160484Sobrien	      SKIP_WHITESPACE ();
168260484Sobrien	    }
168360484Sobrien	}
168460484Sobrien
168577298Sobrien      op_right = operator (&op_chars);
168633965Sjdp
168777298Sobrien      know (op_right == O_illegal
168877298Sobrien	    || op_rank[(int) op_right] <= op_rank[(int) op_left]);
168933965Sjdp      know ((int) op_left >= (int) O_multiply
169033965Sjdp	    && (int) op_left <= (int) O_logical_or);
169133965Sjdp
169277298Sobrien      /* input_line_pointer->after right-hand quantity.  */
169377298Sobrien      /* left-hand quantity in resultP.  */
169477298Sobrien      /* right-hand quantity in right.  */
169577298Sobrien      /* operator in op_left.  */
169633965Sjdp
169733965Sjdp      if (resultP->X_op == O_big)
169833965Sjdp	{
169960484Sobrien	  if (resultP->X_add_number > 0)
170060484Sobrien	    as_warn (_("left operand is a bignum; integer 0 assumed"));
170160484Sobrien	  else
170260484Sobrien	    as_warn (_("left operand is a float; integer 0 assumed"));
170333965Sjdp	  resultP->X_op = O_constant;
170433965Sjdp	  resultP->X_add_number = 0;
170533965Sjdp	  resultP->X_add_symbol = NULL;
170633965Sjdp	  resultP->X_op_symbol = NULL;
170733965Sjdp	}
170833965Sjdp      if (right.X_op == O_big)
170933965Sjdp	{
171060484Sobrien	  if (right.X_add_number > 0)
171160484Sobrien	    as_warn (_("right operand is a bignum; integer 0 assumed"));
171260484Sobrien	  else
171360484Sobrien	    as_warn (_("right operand is a float; integer 0 assumed"));
171433965Sjdp	  right.X_op = O_constant;
171533965Sjdp	  right.X_add_number = 0;
171633965Sjdp	  right.X_add_symbol = NULL;
171733965Sjdp	  right.X_op_symbol = NULL;
171833965Sjdp	}
171933965Sjdp
172033965Sjdp      /* Optimize common cases.  */
172177298Sobrien#ifdef md_optimize_expr
172277298Sobrien      if (md_optimize_expr (resultP, op_left, &right))
172377298Sobrien	{
172477298Sobrien	  /* Skip.  */
172577298Sobrien	  ;
172677298Sobrien	}
172777298Sobrien      else
172877298Sobrien#endif
172933965Sjdp      if (op_left == O_add && right.X_op == O_constant)
173033965Sjdp	{
173133965Sjdp	  /* X + constant.  */
173233965Sjdp	  resultP->X_add_number += right.X_add_number;
173333965Sjdp	}
173433965Sjdp      /* This case comes up in PIC code.  */
173533965Sjdp      else if (op_left == O_subtract
173633965Sjdp	       && right.X_op == O_symbol
173733965Sjdp	       && resultP->X_op == O_symbol
173860484Sobrien	       && (symbol_get_frag (right.X_add_symbol)
173960484Sobrien		   == symbol_get_frag (resultP->X_add_symbol))
1740130561Sobrien	       && (SEG_NORMAL (rightseg)
1741130561Sobrien		   || right.X_add_symbol == resultP->X_add_symbol))
174233965Sjdp	{
174333965Sjdp	  resultP->X_add_number -= right.X_add_number;
174433965Sjdp	  resultP->X_add_number += (S_GET_VALUE (resultP->X_add_symbol)
174533965Sjdp				    - S_GET_VALUE (right.X_add_symbol));
174633965Sjdp	  resultP->X_op = O_constant;
174733965Sjdp	  resultP->X_add_symbol = 0;
174833965Sjdp	}
174933965Sjdp      else if (op_left == O_subtract && right.X_op == O_constant)
175033965Sjdp	{
175133965Sjdp	  /* X - constant.  */
175233965Sjdp	  resultP->X_add_number -= right.X_add_number;
175333965Sjdp	}
175433965Sjdp      else if (op_left == O_add && resultP->X_op == O_constant)
175533965Sjdp	{
175633965Sjdp	  /* Constant + X.  */
175733965Sjdp	  resultP->X_op = right.X_op;
175833965Sjdp	  resultP->X_add_symbol = right.X_add_symbol;
175933965Sjdp	  resultP->X_op_symbol = right.X_op_symbol;
176033965Sjdp	  resultP->X_add_number += right.X_add_number;
176133965Sjdp	  retval = rightseg;
176233965Sjdp	}
176333965Sjdp      else if (resultP->X_op == O_constant && right.X_op == O_constant)
176433965Sjdp	{
176533965Sjdp	  /* Constant OP constant.  */
176633965Sjdp	  offsetT v = right.X_add_number;
176733965Sjdp	  if (v == 0 && (op_left == O_divide || op_left == O_modulus))
176833965Sjdp	    {
176960484Sobrien	      as_warn (_("division by zero"));
177033965Sjdp	      v = 1;
177133965Sjdp	    }
177233965Sjdp	  switch (op_left)
177333965Sjdp	    {
177433965Sjdp	    default:			abort ();
177533965Sjdp	    case O_multiply:		resultP->X_add_number *= v; break;
177633965Sjdp	    case O_divide:		resultP->X_add_number /= v; break;
177733965Sjdp	    case O_modulus:		resultP->X_add_number %= v; break;
177833965Sjdp	    case O_left_shift:		resultP->X_add_number <<= v; break;
177933965Sjdp	    case O_right_shift:
178033965Sjdp	      /* We always use unsigned shifts, to avoid relying on
1781130561Sobrien		 characteristics of the compiler used to compile gas.  */
178233965Sjdp	      resultP->X_add_number =
178333965Sjdp		(offsetT) ((valueT) resultP->X_add_number >> (valueT) v);
178433965Sjdp	      break;
178533965Sjdp	    case O_bit_inclusive_or:	resultP->X_add_number |= v; break;
178633965Sjdp	    case O_bit_or_not:		resultP->X_add_number |= ~v; break;
178733965Sjdp	    case O_bit_exclusive_or:	resultP->X_add_number ^= v; break;
178833965Sjdp	    case O_bit_and:		resultP->X_add_number &= v; break;
178933965Sjdp	    case O_add:			resultP->X_add_number += v; break;
179033965Sjdp	    case O_subtract:		resultP->X_add_number -= v; break;
179133965Sjdp	    case O_eq:
179233965Sjdp	      resultP->X_add_number =
179333965Sjdp		resultP->X_add_number == v ? ~ (offsetT) 0 : 0;
179433965Sjdp	      break;
179533965Sjdp	    case O_ne:
179633965Sjdp	      resultP->X_add_number =
179733965Sjdp		resultP->X_add_number != v ? ~ (offsetT) 0 : 0;
179833965Sjdp	      break;
179933965Sjdp	    case O_lt:
180033965Sjdp	      resultP->X_add_number =
180133965Sjdp		resultP->X_add_number <  v ? ~ (offsetT) 0 : 0;
180233965Sjdp	      break;
180333965Sjdp	    case O_le:
180433965Sjdp	      resultP->X_add_number =
180533965Sjdp		resultP->X_add_number <= v ? ~ (offsetT) 0 : 0;
180633965Sjdp	      break;
180733965Sjdp	    case O_ge:
180833965Sjdp	      resultP->X_add_number =
180933965Sjdp		resultP->X_add_number >= v ? ~ (offsetT) 0 : 0;
181033965Sjdp	      break;
181133965Sjdp	    case O_gt:
181233965Sjdp	      resultP->X_add_number =
181333965Sjdp		resultP->X_add_number >  v ? ~ (offsetT) 0 : 0;
181433965Sjdp	      break;
181533965Sjdp	    case O_logical_and:
181633965Sjdp	      resultP->X_add_number = resultP->X_add_number && v;
181733965Sjdp	      break;
181833965Sjdp	    case O_logical_or:
181933965Sjdp	      resultP->X_add_number = resultP->X_add_number || v;
182033965Sjdp	      break;
182133965Sjdp	    }
182233965Sjdp	}
182333965Sjdp      else if (resultP->X_op == O_symbol
182433965Sjdp	       && right.X_op == O_symbol
182533965Sjdp	       && (op_left == O_add
182633965Sjdp		   || op_left == O_subtract
182733965Sjdp		   || (resultP->X_add_number == 0
182833965Sjdp		       && right.X_add_number == 0)))
182933965Sjdp	{
183033965Sjdp	  /* Symbol OP symbol.  */
183133965Sjdp	  resultP->X_op = op_left;
183233965Sjdp	  resultP->X_op_symbol = right.X_add_symbol;
183333965Sjdp	  if (op_left == O_add)
183433965Sjdp	    resultP->X_add_number += right.X_add_number;
183533965Sjdp	  else if (op_left == O_subtract)
183689857Sobrien	    {
183789857Sobrien	      resultP->X_add_number -= right.X_add_number;
183889857Sobrien	      if (retval == rightseg && SEG_NORMAL (retval))
183989857Sobrien		{
184089857Sobrien		  retval = absolute_section;
184189857Sobrien		  rightseg = absolute_section;
184289857Sobrien		}
184389857Sobrien	    }
184433965Sjdp	}
184533965Sjdp      else
184633965Sjdp	{
184733965Sjdp	  /* The general case.  */
184833965Sjdp	  resultP->X_add_symbol = make_expr_symbol (resultP);
184933965Sjdp	  resultP->X_op_symbol = make_expr_symbol (&right);
185033965Sjdp	  resultP->X_op = op_left;
185133965Sjdp	  resultP->X_add_number = 0;
185233965Sjdp	  resultP->X_unsigned = 1;
185333965Sjdp	}
185433965Sjdp
185589857Sobrien      if (retval != rightseg)
185689857Sobrien	{
185789857Sobrien	  if (! SEG_NORMAL (retval))
185889857Sobrien	    {
185989857Sobrien	      if (retval != undefined_section || SEG_NORMAL (rightseg))
186089857Sobrien		retval = rightseg;
186189857Sobrien	    }
186289857Sobrien	  else if (SEG_NORMAL (rightseg)
186389857Sobrien#ifdef DIFF_EXPR_OK
186489857Sobrien		   && op_left != O_subtract
186589857Sobrien#endif
186689857Sobrien		   )
186789857Sobrien	    as_bad (_("operation combines symbols in different segments"));
186889857Sobrien	}
186989857Sobrien
187033965Sjdp      op_left = op_right;
187177298Sobrien    }				/* While next operator is >= this rank.  */
187233965Sjdp
187333965Sjdp  /* The PA port needs this information.  */
187433965Sjdp  if (resultP->X_add_symbol)
187560484Sobrien    symbol_mark_used (resultP->X_add_symbol);
187633965Sjdp
187733965Sjdp  return resultP->X_op == O_constant ? absolute_section : retval;
187833965Sjdp}
187933965Sjdp
188077298Sobrien/* This lives here because it belongs equally in expr.c & read.c.
188177298Sobrien   expr.c is just a branch office read.c anyway, and putting it
188277298Sobrien   here lessens the crowd at read.c.
188377298Sobrien
188477298Sobrien   Assume input_line_pointer is at start of symbol name.
188577298Sobrien   Advance input_line_pointer past symbol name.
188677298Sobrien   Turn that character into a '\0', returning its former value.
188777298Sobrien   This allows a string compare (RMS wants symbol names to be strings)
188877298Sobrien   of the symbol name.
188977298Sobrien   There will always be a char following symbol name, because all good
189077298Sobrien   lines end in end-of-line.  */
189177298Sobrien
189233965Sjdpchar
1893130561Sobrienget_symbol_end (void)
189433965Sjdp{
189533965Sjdp  char c;
189633965Sjdp
189733965Sjdp  /* We accept \001 in a name in case this is being called with a
189833965Sjdp     constructed string.  */
189933965Sjdp  if (is_name_beginner (c = *input_line_pointer++) || c == '\001')
190060484Sobrien    {
190160484Sobrien      while (is_part_of_name (c = *input_line_pointer++)
190260484Sobrien	     || c == '\001')
190360484Sobrien	;
190460484Sobrien      if (is_name_ender (c))
190560484Sobrien	c = *input_line_pointer++;
190660484Sobrien    }
190733965Sjdp  *--input_line_pointer = 0;
190833965Sjdp  return (c);
190933965Sjdp}
191033965Sjdp
191133965Sjdpunsigned int
1912130561Sobrienget_single_number (void)
191333965Sjdp{
191433965Sjdp  expressionS exp;
191533965Sjdp  operand (&exp);
191633965Sjdp  return exp.X_add_number;
191733965Sjdp}
1918