expr.c revision 60484
133965Sjdp/* expr.c -operands, expressions-
260484Sobrien   Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000
333965Sjdp   Free Software Foundation, Inc.
433965Sjdp
533965Sjdp   This file is part of GAS, the GNU Assembler.
633965Sjdp
733965Sjdp   GAS is free software; you can redistribute it and/or modify
833965Sjdp   it under the terms of the GNU General Public License as published by
933965Sjdp   the Free Software Foundation; either version 2, or (at your option)
1033965Sjdp   any later version.
1133965Sjdp
1233965Sjdp   GAS is distributed in the hope that it will be useful,
1333965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1433965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1533965Sjdp   GNU General Public License for more details.
1633965Sjdp
1733965Sjdp   You should have received a copy of the GNU General Public License
1833965Sjdp   along with GAS; see the file COPYING.  If not, write to the Free
1933965Sjdp   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2033965Sjdp   02111-1307, USA. */
2133965Sjdp
2233965Sjdp/*
2333965Sjdp * This is really a branch office of as-read.c. I split it out to clearly
2433965Sjdp * distinguish the world of expressions from the world of statements.
2533965Sjdp * (It also gives smaller files to re-compile.)
2633965Sjdp * Here, "operand"s are of expressions, not instructions.
2733965Sjdp */
2833965Sjdp
2933965Sjdp#include <ctype.h>
3033965Sjdp#include <string.h>
3138889Sjdp#define min(a, b)       ((a) < (b) ? (a) : (b))
3233965Sjdp
3333965Sjdp#include "as.h"
3433965Sjdp#include "obstack.h"
3533965Sjdp
3633965Sjdpstatic void floating_constant PARAMS ((expressionS * expressionP));
3760484Sobrienstatic valueT generic_bignum_to_int32 PARAMS ((void));
3860484Sobrien#ifdef BFD64
3960484Sobrienstatic valueT generic_bignum_to_int64 PARAMS ((void));
4060484Sobrien#endif
4133965Sjdpstatic void integer_constant PARAMS ((int radix, expressionS * expressionP));
4233965Sjdpstatic void mri_char_constant PARAMS ((expressionS *));
4333965Sjdpstatic void current_location PARAMS ((expressionS *));
4433965Sjdpstatic void clean_up_expression PARAMS ((expressionS * expressionP));
4533965Sjdpstatic segT operand PARAMS ((expressionS *));
4633965Sjdpstatic operatorT operator PARAMS ((void));
4733965Sjdp
4833965Sjdpextern const char EXP_CHARS[], FLT_CHARS[];
4933965Sjdp
5033965Sjdp/* We keep a mapping of expression symbols to file positions, so that
5133965Sjdp   we can provide better error messages.  */
5233965Sjdp
5333965Sjdpstruct expr_symbol_line
5433965Sjdp{
5533965Sjdp  struct expr_symbol_line *next;
5633965Sjdp  symbolS *sym;
5733965Sjdp  char *file;
5833965Sjdp  unsigned int line;
5933965Sjdp};
6033965Sjdp
6133965Sjdpstatic struct expr_symbol_line *expr_symbol_lines;
6233965Sjdp
6333965Sjdp/* Build a dummy symbol to hold a complex expression.  This is how we
6433965Sjdp   build expressions up out of other expressions.  The symbol is put
6533965Sjdp   into the fake section expr_section.  */
6633965Sjdp
6733965SjdpsymbolS *
6833965Sjdpmake_expr_symbol (expressionP)
6933965Sjdp     expressionS *expressionP;
7033965Sjdp{
7160484Sobrien  expressionS zero;
7233965Sjdp  const char *fake;
7333965Sjdp  symbolS *symbolP;
7433965Sjdp  struct expr_symbol_line *n;
7533965Sjdp
7633965Sjdp  if (expressionP->X_op == O_symbol
7733965Sjdp      && expressionP->X_add_number == 0)
7833965Sjdp    return expressionP->X_add_symbol;
7933965Sjdp
8060484Sobrien  if (expressionP->X_op == O_big)
8160484Sobrien    {
8260484Sobrien      /* This won't work, because the actual value is stored in
8360484Sobrien         generic_floating_point_number or generic_bignum, and we are
8460484Sobrien         going to lose it if we haven't already.  */
8560484Sobrien      if (expressionP->X_add_number > 0)
8660484Sobrien	as_bad (_("bignum invalid; zero assumed"));
8760484Sobrien      else
8860484Sobrien	as_bad (_("floating point number invalid; zero assumed"));
8960484Sobrien      zero.X_op = O_constant;
9060484Sobrien      zero.X_add_number = 0;
9160484Sobrien      zero.X_unsigned = 0;
9260484Sobrien      clean_up_expression (&zero);
9360484Sobrien      expressionP = &zero;
9460484Sobrien    }
9560484Sobrien
9633965Sjdp  fake = FAKE_LABEL_NAME;
9733965Sjdp
9833965Sjdp  /* Putting constant symbols in absolute_section rather than
9933965Sjdp     expr_section is convenient for the old a.out code, for which
10033965Sjdp     S_GET_SEGMENT does not always retrieve the value put in by
10133965Sjdp     S_SET_SEGMENT.  */
10233965Sjdp  symbolP = symbol_create (fake,
10333965Sjdp			   (expressionP->X_op == O_constant
10433965Sjdp			    ? absolute_section
10533965Sjdp			    : expr_section),
10633965Sjdp			   0, &zero_address_frag);
10760484Sobrien  symbol_set_value_expression (symbolP, expressionP);
10833965Sjdp
10933965Sjdp  if (expressionP->X_op == O_constant)
11038889Sjdp    resolve_symbol_value (symbolP, 1);
11133965Sjdp
11233965Sjdp  n = (struct expr_symbol_line *) xmalloc (sizeof *n);
11333965Sjdp  n->sym = symbolP;
11433965Sjdp  as_where (&n->file, &n->line);
11533965Sjdp  n->next = expr_symbol_lines;
11633965Sjdp  expr_symbol_lines = n;
11733965Sjdp
11833965Sjdp  return symbolP;
11933965Sjdp}
12033965Sjdp
12133965Sjdp/* Return the file and line number for an expr symbol.  Return
12233965Sjdp   non-zero if something was found, 0 if no information is known for
12333965Sjdp   the symbol.  */
12433965Sjdp
12533965Sjdpint
12633965Sjdpexpr_symbol_where (sym, pfile, pline)
12733965Sjdp     symbolS *sym;
12833965Sjdp     char **pfile;
12933965Sjdp     unsigned int *pline;
13033965Sjdp{
13133965Sjdp  register struct expr_symbol_line *l;
13233965Sjdp
13333965Sjdp  for (l = expr_symbol_lines; l != NULL; l = l->next)
13433965Sjdp    {
13533965Sjdp      if (l->sym == sym)
13633965Sjdp	{
13733965Sjdp	  *pfile = l->file;
13833965Sjdp	  *pline = l->line;
13933965Sjdp	  return 1;
14033965Sjdp	}
14133965Sjdp    }
14233965Sjdp
14333965Sjdp  return 0;
14433965Sjdp}
14533965Sjdp
14638889Sjdp/* Utilities for building expressions.
14738889Sjdp   Since complex expressions are recorded as symbols for use in other
14838889Sjdp   expressions these return a symbolS * and not an expressionS *.
14938889Sjdp   These explicitly do not take an "add_number" argument.  */
15038889Sjdp/* ??? For completeness' sake one might want expr_build_symbol.
15138889Sjdp   It would just return its argument.  */
15238889Sjdp
15338889Sjdp/* Build an expression for an unsigned constant.
15438889Sjdp   The corresponding one for signed constants is missing because
15538889Sjdp   there's currently no need for it.  One could add an unsigned_p flag
15638889Sjdp   but that seems more clumsy.  */
15738889Sjdp
15838889SjdpsymbolS *
15938889Sjdpexpr_build_uconstant (value)
16038889Sjdp     offsetT value;
16138889Sjdp{
16238889Sjdp  expressionS e;
16338889Sjdp
16438889Sjdp  e.X_op = O_constant;
16538889Sjdp  e.X_add_number = value;
16638889Sjdp  e.X_unsigned = 1;
16738889Sjdp  return make_expr_symbol (&e);
16838889Sjdp}
16938889Sjdp
17038889Sjdp/* Build an expression for OP s1.  */
17138889Sjdp
17238889SjdpsymbolS *
17338889Sjdpexpr_build_unary (op, s1)
17438889Sjdp     operatorT op;
17538889Sjdp     symbolS *s1;
17638889Sjdp{
17738889Sjdp  expressionS e;
17838889Sjdp
17938889Sjdp  e.X_op = op;
18038889Sjdp  e.X_add_symbol = s1;
18138889Sjdp  e.X_add_number = 0;
18238889Sjdp  return make_expr_symbol (&e);
18338889Sjdp}
18438889Sjdp
18538889Sjdp/* Build an expression for s1 OP s2.  */
18638889Sjdp
18738889SjdpsymbolS *
18838889Sjdpexpr_build_binary (op, s1, s2)
18938889Sjdp     operatorT op;
19038889Sjdp     symbolS *s1;
19138889Sjdp     symbolS *s2;
19238889Sjdp{
19338889Sjdp  expressionS e;
19438889Sjdp
19538889Sjdp  e.X_op = op;
19638889Sjdp  e.X_add_symbol = s1;
19738889Sjdp  e.X_op_symbol = s2;
19838889Sjdp  e.X_add_number = 0;
19938889Sjdp  return make_expr_symbol (&e);
20038889Sjdp}
20160484Sobrien
20260484Sobrien/* Build an expression for the current location ('.').  */
20360484Sobrien
20460484SobriensymbolS *
20560484Sobrienexpr_build_dot ()
20660484Sobrien{
20760484Sobrien  expressionS e;
20860484Sobrien
20960484Sobrien  current_location (&e);
21060484Sobrien  return make_expr_symbol (&e);
21160484Sobrien}
21238889Sjdp
21333965Sjdp/*
21433965Sjdp * Build any floating-point literal here.
21533965Sjdp * Also build any bignum literal here.
21633965Sjdp */
21733965Sjdp
21833965Sjdp/* Seems atof_machine can backscan through generic_bignum and hit whatever
21933965Sjdp   happens to be loaded before it in memory.  And its way too complicated
22033965Sjdp   for me to fix right.  Thus a hack.  JF:  Just make generic_bignum bigger,
22133965Sjdp   and never write into the early words, thus they'll always be zero.
22233965Sjdp   I hate Dean's floating-point code.  Bleh.  */
22333965SjdpLITTLENUM_TYPE generic_bignum[SIZE_OF_LARGE_NUMBER + 6];
22433965SjdpFLONUM_TYPE generic_floating_point_number =
22533965Sjdp{
22633965Sjdp  &generic_bignum[6],		/* low (JF: Was 0) */
22733965Sjdp  &generic_bignum[SIZE_OF_LARGE_NUMBER + 6 - 1], /* high JF: (added +6) */
22833965Sjdp  0,				/* leader */
22933965Sjdp  0,				/* exponent */
23033965Sjdp  0				/* sign */
23133965Sjdp};
23233965Sjdp/* If nonzero, we've been asked to assemble nan, +inf or -inf */
23333965Sjdpint generic_floating_point_magic;
23433965Sjdp
23533965Sjdpstatic void
23633965Sjdpfloating_constant (expressionP)
23733965Sjdp     expressionS *expressionP;
23833965Sjdp{
23933965Sjdp  /* input_line_pointer->*/
24033965Sjdp  /* floating-point constant. */
24133965Sjdp  int error_code;
24233965Sjdp
24333965Sjdp  error_code = atof_generic (&input_line_pointer, ".", EXP_CHARS,
24433965Sjdp			     &generic_floating_point_number);
24533965Sjdp
24633965Sjdp  if (error_code)
24733965Sjdp    {
24833965Sjdp      if (error_code == ERROR_EXPONENT_OVERFLOW)
24933965Sjdp	{
25060484Sobrien	  as_bad (_("bad floating-point constant: exponent overflow, probably assembling junk"));
25133965Sjdp	}
25233965Sjdp      else
25333965Sjdp	{
25460484Sobrien	  as_bad (_("bad floating-point constant: unknown error code=%d."), error_code);
25533965Sjdp	}
25633965Sjdp    }
25733965Sjdp  expressionP->X_op = O_big;
25833965Sjdp  /* input_line_pointer->just after constant, */
25933965Sjdp  /* which may point to whitespace. */
26033965Sjdp  expressionP->X_add_number = -1;
26133965Sjdp}
26233965Sjdp
26338889Sjdpstatic valueT
26438889Sjdpgeneric_bignum_to_int32 ()
26538889Sjdp{
26638889Sjdp  valueT number =
26738889Sjdp	   ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
26838889Sjdp	   | (generic_bignum[0] & LITTLENUM_MASK);
26938889Sjdp  number &= 0xffffffff;
27038889Sjdp  return number;
27138889Sjdp}
27238889Sjdp
27338889Sjdp#ifdef BFD64
27438889Sjdpstatic valueT
27538889Sjdpgeneric_bignum_to_int64 ()
27638889Sjdp{
27738889Sjdp  valueT number =
27838889Sjdp	   ((((((((valueT) generic_bignum[3] & LITTLENUM_MASK)
27938889Sjdp		 << LITTLENUM_NUMBER_OF_BITS)
28038889Sjdp	        | ((valueT) generic_bignum[2] & LITTLENUM_MASK))
28138889Sjdp	       << LITTLENUM_NUMBER_OF_BITS)
28238889Sjdp	      | ((valueT) generic_bignum[1] & LITTLENUM_MASK))
28338889Sjdp	     << LITTLENUM_NUMBER_OF_BITS)
28438889Sjdp	    | ((valueT) generic_bignum[0] & LITTLENUM_MASK));
28538889Sjdp  return number;
28638889Sjdp}
28738889Sjdp#endif
28838889Sjdp
28933965Sjdpstatic void
29033965Sjdpinteger_constant (radix, expressionP)
29133965Sjdp     int radix;
29233965Sjdp     expressionS *expressionP;
29333965Sjdp{
29433965Sjdp  char *start;		/* start of number. */
29533965Sjdp  char *suffix = NULL;
29633965Sjdp  char c;
29733965Sjdp  valueT number;	/* offset or (absolute) value */
29833965Sjdp  short int digit;	/* value of next digit in current radix */
29933965Sjdp  short int maxdig = 0;/* highest permitted digit value. */
30033965Sjdp  int too_many_digits = 0;	/* if we see >= this number of */
30133965Sjdp  char *name;		/* points to name of symbol */
30233965Sjdp  symbolS *symbolP;	/* points to symbol */
30333965Sjdp
30433965Sjdp  int small;			/* true if fits in 32 bits. */
30533965Sjdp
30633965Sjdp  /* May be bignum, or may fit in 32 bits. */
30733965Sjdp  /* Most numbers fit into 32 bits, and we want this case to be fast.
30833965Sjdp     so we pretend it will fit into 32 bits.  If, after making up a 32
30933965Sjdp     bit number, we realise that we have scanned more digits than
31033965Sjdp     comfortably fit into 32 bits, we re-scan the digits coding them
31133965Sjdp     into a bignum.  For decimal and octal numbers we are
31233965Sjdp     conservative: Some numbers may be assumed bignums when in fact
31333965Sjdp     they do fit into 32 bits.  Numbers of any radix can have excess
31433965Sjdp     leading zeros: We strive to recognise this and cast them back
31533965Sjdp     into 32 bits.  We must check that the bignum really is more than
31633965Sjdp     32 bits, and change it back to a 32-bit number if it fits.  The
31733965Sjdp     number we are looking for is expected to be positive, but if it
31833965Sjdp     fits into 32 bits as an unsigned number, we let it be a 32-bit
31933965Sjdp     number.  The cavalier approach is for speed in ordinary cases. */
32033965Sjdp  /* This has been extended for 64 bits.  We blindly assume that if
32133965Sjdp     you're compiling in 64-bit mode, the target is a 64-bit machine.
32233965Sjdp     This should be cleaned up.  */
32333965Sjdp
32433965Sjdp#ifdef BFD64
32533965Sjdp#define valuesize 64
32633965Sjdp#else /* includes non-bfd case, mostly */
32733965Sjdp#define valuesize 32
32833965Sjdp#endif
32933965Sjdp
33060484Sobrien  if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri) && radix == 0)
33133965Sjdp    {
33233965Sjdp      int flt = 0;
33333965Sjdp
33433965Sjdp      /* In MRI mode, the number may have a suffix indicating the
33533965Sjdp         radix.  For that matter, it might actually be a floating
33633965Sjdp         point constant.  */
33738889Sjdp      for (suffix = input_line_pointer;
33838889Sjdp	   isalnum ((unsigned char) *suffix);
33938889Sjdp	   suffix++)
34033965Sjdp	{
34133965Sjdp	  if (*suffix == 'e' || *suffix == 'E')
34233965Sjdp	    flt = 1;
34333965Sjdp	}
34433965Sjdp
34533965Sjdp      if (suffix == input_line_pointer)
34633965Sjdp	{
34733965Sjdp	  radix = 10;
34833965Sjdp	  suffix = NULL;
34933965Sjdp	}
35033965Sjdp      else
35133965Sjdp	{
35233965Sjdp	  c = *--suffix;
35338889Sjdp	  if (islower ((unsigned char) c))
35433965Sjdp	    c = toupper (c);
35533965Sjdp	  if (c == 'B')
35633965Sjdp	    radix = 2;
35733965Sjdp	  else if (c == 'D')
35833965Sjdp	    radix = 10;
35933965Sjdp	  else if (c == 'O' || c == 'Q')
36033965Sjdp	    radix = 8;
36133965Sjdp	  else if (c == 'H')
36233965Sjdp	    radix = 16;
36333965Sjdp	  else if (suffix[1] == '.' || c == 'E' || flt)
36433965Sjdp	    {
36533965Sjdp	      floating_constant (expressionP);
36633965Sjdp	      return;
36733965Sjdp	    }
36833965Sjdp	  else
36933965Sjdp	    {
37033965Sjdp	      radix = 10;
37133965Sjdp	      suffix = NULL;
37233965Sjdp	    }
37333965Sjdp	}
37433965Sjdp    }
37533965Sjdp
37633965Sjdp  switch (radix)
37733965Sjdp    {
37833965Sjdp    case 2:
37933965Sjdp      maxdig = 2;
38033965Sjdp      too_many_digits = valuesize + 1;
38133965Sjdp      break;
38233965Sjdp    case 8:
38333965Sjdp      maxdig = radix = 8;
38433965Sjdp      too_many_digits = (valuesize + 2) / 3 + 1;
38533965Sjdp      break;
38633965Sjdp    case 16:
38733965Sjdp      maxdig = radix = 16;
38833965Sjdp      too_many_digits = (valuesize + 3) / 4 + 1;
38933965Sjdp      break;
39033965Sjdp    case 10:
39133965Sjdp      maxdig = radix = 10;
39260484Sobrien      too_many_digits = (valuesize + 11) / 4; /* very rough */
39333965Sjdp    }
39433965Sjdp#undef valuesize
39533965Sjdp  start = input_line_pointer;
39633965Sjdp  c = *input_line_pointer++;
39733965Sjdp  for (number = 0;
39833965Sjdp       (digit = hex_value (c)) < maxdig;
39933965Sjdp       c = *input_line_pointer++)
40033965Sjdp    {
40133965Sjdp      number = number * radix + digit;
40233965Sjdp    }
40333965Sjdp  /* c contains character after number. */
40433965Sjdp  /* input_line_pointer->char after c. */
40533965Sjdp  small = (input_line_pointer - start - 1) < too_many_digits;
40638889Sjdp
40738889Sjdp  if (radix == 16 && c == '_')
40833965Sjdp    {
40938889Sjdp      /* This is literal of the form 0x333_0_12345678_1.
41038889Sjdp         This example is equivalent to 0x00000333000000001234567800000001.  */
41138889Sjdp
41238889Sjdp      int num_little_digits = 0;
41338889Sjdp      int i;
41438889Sjdp      input_line_pointer = start;	/*->1st digit. */
41538889Sjdp
41638889Sjdp      know (LITTLENUM_NUMBER_OF_BITS == 16);
41738889Sjdp
41838889Sjdp      for (c = '_'; c == '_'; num_little_digits+=2)
41938889Sjdp	{
42038889Sjdp
42138889Sjdp	  /* Convert one 64-bit word. */
42238889Sjdp	  int ndigit = 0;
42338889Sjdp	  number = 0;
42438889Sjdp	  for (c = *input_line_pointer++;
42538889Sjdp	       (digit = hex_value (c)) < maxdig;
42638889Sjdp	       c = *(input_line_pointer++))
42738889Sjdp	    {
42838889Sjdp	      number = number * radix + digit;
42938889Sjdp	      ndigit++;
43038889Sjdp	    }
43138889Sjdp
43238889Sjdp	  /* Check for 8 digit per word max.  */
43338889Sjdp	  if (ndigit > 8)
43460484Sobrien	    as_bad (_("A bignum with underscores may not have more than 8 hex digits in any word."));
43538889Sjdp
43638889Sjdp	  /* Add this chunk to the bignum.  Shift things down 2 little digits.*/
43738889Sjdp	  know (LITTLENUM_NUMBER_OF_BITS == 16);
43838889Sjdp	  for (i = min (num_little_digits + 1, SIZE_OF_LARGE_NUMBER - 1); i >= 2; i--)
43938889Sjdp	    generic_bignum[i] = generic_bignum[i-2];
44038889Sjdp
44138889Sjdp	  /* Add the new digits as the least significant new ones. */
44238889Sjdp	  generic_bignum[0] = number & 0xffffffff;
44338889Sjdp	  generic_bignum[1] = number >> 16;
44438889Sjdp	}
44538889Sjdp
44638889Sjdp      /* Again, c is char after number, input_line_pointer->after c. */
44738889Sjdp
44838889Sjdp      if (num_little_digits > SIZE_OF_LARGE_NUMBER - 1)
44938889Sjdp	num_little_digits = SIZE_OF_LARGE_NUMBER - 1;
45038889Sjdp
45138889Sjdp      assert (num_little_digits >= 4);
45238889Sjdp
45338889Sjdp      if (num_little_digits != 8)
45460484Sobrien	as_bad (_("A bignum with underscores must have exactly 4 words."));
45538889Sjdp
45638889Sjdp      /* We might have some leading zeros.  These can be trimmed to give
45738889Sjdp       * us a change to fit this constant into a small number.
45838889Sjdp       */
45938889Sjdp      while (generic_bignum[num_little_digits-1] == 0 && num_little_digits > 1)
46038889Sjdp	num_little_digits--;
46138889Sjdp
46238889Sjdp      if (num_little_digits <= 2)
46338889Sjdp	{
46438889Sjdp	  /* will fit into 32 bits. */
46538889Sjdp	  number = generic_bignum_to_int32 ();
46638889Sjdp	  small = 1;
46738889Sjdp	}
46838889Sjdp#ifdef BFD64
46938889Sjdp      else if (num_little_digits <= 4)
47038889Sjdp	{
47138889Sjdp	  /* Will fit into 64 bits.  */
47238889Sjdp	  number = generic_bignum_to_int64 ();
47338889Sjdp	  small = 1;
47438889Sjdp	}
47538889Sjdp#endif
47638889Sjdp      else
47738889Sjdp	{
47838889Sjdp	  small = 0;
47938889Sjdp	  number = num_little_digits; /* number of littlenums in the bignum. */
48038889Sjdp	}
48138889Sjdp    }
48238889Sjdp  else if (!small)
48338889Sjdp    {
48433965Sjdp      /*
48533965Sjdp       * we saw a lot of digits. manufacture a bignum the hard way.
48633965Sjdp       */
48733965Sjdp      LITTLENUM_TYPE *leader;	/*->high order littlenum of the bignum. */
48833965Sjdp      LITTLENUM_TYPE *pointer;	/*->littlenum we are frobbing now. */
48933965Sjdp      long carry;
49033965Sjdp
49133965Sjdp      leader = generic_bignum;
49233965Sjdp      generic_bignum[0] = 0;
49333965Sjdp      generic_bignum[1] = 0;
49438889Sjdp      generic_bignum[2] = 0;
49538889Sjdp      generic_bignum[3] = 0;
49633965Sjdp      input_line_pointer = start;	/*->1st digit. */
49733965Sjdp      c = *input_line_pointer++;
49833965Sjdp      for (;
49933965Sjdp	   (carry = hex_value (c)) < maxdig;
50033965Sjdp	   c = *input_line_pointer++)
50133965Sjdp	{
50233965Sjdp	  for (pointer = generic_bignum;
50333965Sjdp	       pointer <= leader;
50433965Sjdp	       pointer++)
50533965Sjdp	    {
50633965Sjdp	      long work;
50733965Sjdp
50833965Sjdp	      work = carry + radix * *pointer;
50933965Sjdp	      *pointer = work & LITTLENUM_MASK;
51033965Sjdp	      carry = work >> LITTLENUM_NUMBER_OF_BITS;
51133965Sjdp	    }
51233965Sjdp	  if (carry)
51333965Sjdp	    {
51433965Sjdp	      if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1)
51533965Sjdp		{
51633965Sjdp		  /* room to grow a longer bignum. */
51733965Sjdp		  *++leader = carry;
51833965Sjdp		}
51933965Sjdp	    }
52033965Sjdp	}
52133965Sjdp      /* again, c is char after number, */
52233965Sjdp      /* input_line_pointer->after c. */
52333965Sjdp      know (LITTLENUM_NUMBER_OF_BITS == 16);
52433965Sjdp      if (leader < generic_bignum + 2)
52533965Sjdp	{
52633965Sjdp	  /* will fit into 32 bits. */
52738889Sjdp	  number = generic_bignum_to_int32 ();
52833965Sjdp	  small = 1;
52933965Sjdp	}
53038889Sjdp#ifdef BFD64
53138889Sjdp      else if (leader < generic_bignum + 4)
53238889Sjdp	{
53338889Sjdp	  /* Will fit into 64 bits.  */
53438889Sjdp	  number = generic_bignum_to_int64 ();
53538889Sjdp	  small = 1;
53638889Sjdp	}
53738889Sjdp#endif
53833965Sjdp      else
53933965Sjdp	{
54033965Sjdp	  number = leader - generic_bignum + 1;	/* number of littlenums in the bignum. */
54133965Sjdp	}
54233965Sjdp    }
54333965Sjdp
54460484Sobrien  if ((NUMBERS_WITH_SUFFIX || flag_m68k_mri)
54560484Sobrien      && suffix != NULL
54660484Sobrien      && input_line_pointer - 1 == suffix)
54733965Sjdp    c = *input_line_pointer++;
54833965Sjdp
54933965Sjdp  if (small)
55033965Sjdp    {
55133965Sjdp      /*
55233965Sjdp       * here with number, in correct radix. c is the next char.
55333965Sjdp       * note that unlike un*x, we allow "011f" "0x9f" to
55433965Sjdp       * both mean the same as the (conventional) "9f". this is simply easier
55533965Sjdp       * than checking for strict canonical form. syntax sux!
55633965Sjdp       */
55733965Sjdp
55833965Sjdp      if (LOCAL_LABELS_FB && c == 'b')
55933965Sjdp	{
56033965Sjdp	  /*
56133965Sjdp	   * backward ref to local label.
56233965Sjdp	   * because it is backward, expect it to be defined.
56333965Sjdp	   */
56433965Sjdp	  /* Construct a local label.  */
56533965Sjdp	  name = fb_label_name ((int) number, 0);
56633965Sjdp
56733965Sjdp	  /* seen before, or symbol is defined: ok */
56833965Sjdp	  symbolP = symbol_find (name);
56933965Sjdp	  if ((symbolP != NULL) && (S_IS_DEFINED (symbolP)))
57033965Sjdp	    {
57133965Sjdp	      /* local labels are never absolute. don't waste time
57233965Sjdp		 checking absoluteness. */
57333965Sjdp	      know (SEG_NORMAL (S_GET_SEGMENT (symbolP)));
57433965Sjdp
57533965Sjdp	      expressionP->X_op = O_symbol;
57633965Sjdp	      expressionP->X_add_symbol = symbolP;
57733965Sjdp	    }
57833965Sjdp	  else
57933965Sjdp	    {
58033965Sjdp	      /* either not seen or not defined. */
58133965Sjdp	      /* @@ Should print out the original string instead of
58233965Sjdp		 the parsed number.  */
58360484Sobrien	      as_bad (_("backw. ref to unknown label \"%d:\", 0 assumed."),
58433965Sjdp		      (int) number);
58533965Sjdp	      expressionP->X_op = O_constant;
58633965Sjdp	    }
58733965Sjdp
58833965Sjdp	  expressionP->X_add_number = 0;
58933965Sjdp	}			/* case 'b' */
59033965Sjdp      else if (LOCAL_LABELS_FB && c == 'f')
59133965Sjdp	{
59233965Sjdp	  /*
59333965Sjdp	   * forward reference. expect symbol to be undefined or
59433965Sjdp	   * unknown. undefined: seen it before. unknown: never seen
59533965Sjdp	   * it before.
59633965Sjdp	   * construct a local label name, then an undefined symbol.
59733965Sjdp	   * don't create a xseg frag for it: caller may do that.
59833965Sjdp	   * just return it as never seen before.
59933965Sjdp	   */
60033965Sjdp	  name = fb_label_name ((int) number, 1);
60133965Sjdp	  symbolP = symbol_find_or_make (name);
60233965Sjdp	  /* we have no need to check symbol properties. */
60333965Sjdp#ifndef many_segments
60433965Sjdp	  /* since "know" puts its arg into a "string", we
60533965Sjdp	     can't have newlines in the argument.  */
60633965Sjdp	  know (S_GET_SEGMENT (symbolP) == undefined_section || S_GET_SEGMENT (symbolP) == text_section || S_GET_SEGMENT (symbolP) == data_section);
60733965Sjdp#endif
60833965Sjdp	  expressionP->X_op = O_symbol;
60933965Sjdp	  expressionP->X_add_symbol = symbolP;
61033965Sjdp	  expressionP->X_add_number = 0;
61133965Sjdp	}			/* case 'f' */
61233965Sjdp      else if (LOCAL_LABELS_DOLLAR && c == '$')
61333965Sjdp	{
61433965Sjdp	  /* If the dollar label is *currently* defined, then this is just
61533965Sjdp	     another reference to it.  If it is not *currently* defined,
61633965Sjdp	     then this is a fresh instantiation of that number, so create
61733965Sjdp	     it.  */
61833965Sjdp
61933965Sjdp	  if (dollar_label_defined ((long) number))
62033965Sjdp	    {
62133965Sjdp	      name = dollar_label_name ((long) number, 0);
62233965Sjdp	      symbolP = symbol_find (name);
62333965Sjdp	      know (symbolP != NULL);
62433965Sjdp	    }
62533965Sjdp	  else
62633965Sjdp	    {
62733965Sjdp	      name = dollar_label_name ((long) number, 1);
62833965Sjdp	      symbolP = symbol_find_or_make (name);
62933965Sjdp	    }
63033965Sjdp
63133965Sjdp	  expressionP->X_op = O_symbol;
63233965Sjdp	  expressionP->X_add_symbol = symbolP;
63333965Sjdp	  expressionP->X_add_number = 0;
63433965Sjdp	}			/* case '$' */
63533965Sjdp      else
63633965Sjdp	{
63733965Sjdp	  expressionP->X_op = O_constant;
63833965Sjdp#ifdef TARGET_WORD_SIZE
63933965Sjdp	  /* Sign extend NUMBER.  */
64033965Sjdp	  number |= (-(number >> (TARGET_WORD_SIZE - 1))) << (TARGET_WORD_SIZE - 1);
64133965Sjdp#endif
64233965Sjdp	  expressionP->X_add_number = number;
64333965Sjdp	  input_line_pointer--;	/* restore following character. */
64433965Sjdp	}			/* really just a number */
64533965Sjdp    }
64633965Sjdp  else
64733965Sjdp    {
64833965Sjdp      /* not a small number */
64933965Sjdp      expressionP->X_op = O_big;
65033965Sjdp      expressionP->X_add_number = number;	/* number of littlenums */
65133965Sjdp      input_line_pointer--;	/*->char following number. */
65233965Sjdp    }
65333965Sjdp}
65433965Sjdp
65533965Sjdp/* Parse an MRI multi character constant.  */
65633965Sjdp
65733965Sjdpstatic void
65833965Sjdpmri_char_constant (expressionP)
65933965Sjdp     expressionS *expressionP;
66033965Sjdp{
66133965Sjdp  int i;
66233965Sjdp
66333965Sjdp  if (*input_line_pointer == '\''
66433965Sjdp      && input_line_pointer[1] != '\'')
66533965Sjdp    {
66633965Sjdp      expressionP->X_op = O_constant;
66733965Sjdp      expressionP->X_add_number = 0;
66833965Sjdp      return;
66933965Sjdp    }
67033965Sjdp
67133965Sjdp  /* In order to get the correct byte ordering, we must build the
67233965Sjdp     number in reverse.  */
67333965Sjdp  for (i = SIZE_OF_LARGE_NUMBER - 1; i >= 0; i--)
67433965Sjdp    {
67533965Sjdp      int j;
67633965Sjdp
67733965Sjdp      generic_bignum[i] = 0;
67833965Sjdp      for (j = 0; j < CHARS_PER_LITTLENUM; j++)
67933965Sjdp	{
68033965Sjdp	  if (*input_line_pointer == '\'')
68133965Sjdp	    {
68233965Sjdp	      if (input_line_pointer[1] != '\'')
68333965Sjdp		break;
68433965Sjdp	      ++input_line_pointer;
68533965Sjdp	    }
68633965Sjdp	  generic_bignum[i] <<= 8;
68733965Sjdp	  generic_bignum[i] += *input_line_pointer;
68833965Sjdp	  ++input_line_pointer;
68933965Sjdp	}
69033965Sjdp
69133965Sjdp      if (i < SIZE_OF_LARGE_NUMBER - 1)
69233965Sjdp	{
69333965Sjdp	  /* If there is more than one littlenum, left justify the
69433965Sjdp             last one to make it match the earlier ones.  If there is
69533965Sjdp             only one, we can just use the value directly.  */
69633965Sjdp	  for (; j < CHARS_PER_LITTLENUM; j++)
69733965Sjdp	    generic_bignum[i] <<= 8;
69833965Sjdp	}
69933965Sjdp
70033965Sjdp      if (*input_line_pointer == '\''
70133965Sjdp	  && input_line_pointer[1] != '\'')
70233965Sjdp	break;
70333965Sjdp    }
70433965Sjdp
70533965Sjdp  if (i < 0)
70633965Sjdp    {
70760484Sobrien      as_bad (_("Character constant too large"));
70833965Sjdp      i = 0;
70933965Sjdp    }
71033965Sjdp
71133965Sjdp  if (i > 0)
71233965Sjdp    {
71333965Sjdp      int c;
71433965Sjdp      int j;
71533965Sjdp
71633965Sjdp      c = SIZE_OF_LARGE_NUMBER - i;
71733965Sjdp      for (j = 0; j < c; j++)
71833965Sjdp	generic_bignum[j] = generic_bignum[i + j];
71933965Sjdp      i = c;
72033965Sjdp    }
72133965Sjdp
72233965Sjdp  know (LITTLENUM_NUMBER_OF_BITS == 16);
72333965Sjdp  if (i > 2)
72433965Sjdp    {
72533965Sjdp      expressionP->X_op = O_big;
72633965Sjdp      expressionP->X_add_number = i;
72733965Sjdp    }
72833965Sjdp  else
72933965Sjdp    {
73033965Sjdp      expressionP->X_op = O_constant;
73133965Sjdp      if (i < 2)
73233965Sjdp	expressionP->X_add_number = generic_bignum[0] & LITTLENUM_MASK;
73333965Sjdp      else
73433965Sjdp	expressionP->X_add_number =
73533965Sjdp	  (((generic_bignum[1] & LITTLENUM_MASK)
73633965Sjdp	    << LITTLENUM_NUMBER_OF_BITS)
73733965Sjdp	   | (generic_bignum[0] & LITTLENUM_MASK));
73833965Sjdp    }
73933965Sjdp
74033965Sjdp  /* Skip the final closing quote.  */
74133965Sjdp  ++input_line_pointer;
74233965Sjdp}
74333965Sjdp
74433965Sjdp/* Return an expression representing the current location.  This
74533965Sjdp   handles the magic symbol `.'.  */
74633965Sjdp
74733965Sjdpstatic void
74833965Sjdpcurrent_location (expressionp)
74933965Sjdp     expressionS *expressionp;
75033965Sjdp{
75133965Sjdp  if (now_seg == absolute_section)
75233965Sjdp    {
75333965Sjdp      expressionp->X_op = O_constant;
75433965Sjdp      expressionp->X_add_number = abs_section_offset;
75533965Sjdp    }
75633965Sjdp  else
75733965Sjdp    {
75833965Sjdp      symbolS *symbolp;
75933965Sjdp
76033965Sjdp      symbolp = symbol_new (FAKE_LABEL_NAME, now_seg,
76133965Sjdp			    (valueT) frag_now_fix (),
76233965Sjdp			    frag_now);
76333965Sjdp      expressionp->X_op = O_symbol;
76433965Sjdp      expressionp->X_add_symbol = symbolp;
76533965Sjdp      expressionp->X_add_number = 0;
76633965Sjdp    }
76733965Sjdp}
76833965Sjdp
76933965Sjdp/*
77033965Sjdp * Summary of operand().
77133965Sjdp *
77233965Sjdp * in:	Input_line_pointer points to 1st char of operand, which may
77333965Sjdp *	be a space.
77433965Sjdp *
77533965Sjdp * out:	A expressionS.
77633965Sjdp *	The operand may have been empty: in this case X_op == O_absent.
77733965Sjdp *	Input_line_pointer->(next non-blank) char after operand.
77833965Sjdp */
77933965Sjdp
78033965Sjdpstatic segT
78133965Sjdpoperand (expressionP)
78233965Sjdp     expressionS *expressionP;
78333965Sjdp{
78433965Sjdp  char c;
78533965Sjdp  symbolS *symbolP;	/* points to symbol */
78633965Sjdp  char *name;		/* points to name of symbol */
78733965Sjdp  segT segment;
78833965Sjdp
78933965Sjdp  /* All integers are regarded as unsigned unless they are negated.
79033965Sjdp     This is because the only thing which cares whether a number is
79133965Sjdp     unsigned is the code in emit_expr which extends constants into
79233965Sjdp     bignums.  It should only sign extend negative numbers, so that
79333965Sjdp     something like ``.quad 0x80000000'' is not sign extended even
79433965Sjdp     though it appears negative if valueT is 32 bits.  */
79533965Sjdp  expressionP->X_unsigned = 1;
79633965Sjdp
79733965Sjdp  /* digits, assume it is a bignum. */
79833965Sjdp
79933965Sjdp  SKIP_WHITESPACE ();		/* leading whitespace is part of operand. */
80033965Sjdp  c = *input_line_pointer++;	/* input_line_pointer->past char in c. */
80133965Sjdp
80233965Sjdp  switch (c)
80333965Sjdp    {
80433965Sjdp    case '1':
80533965Sjdp    case '2':
80633965Sjdp    case '3':
80733965Sjdp    case '4':
80833965Sjdp    case '5':
80933965Sjdp    case '6':
81033965Sjdp    case '7':
81133965Sjdp    case '8':
81233965Sjdp    case '9':
81333965Sjdp      input_line_pointer--;
81433965Sjdp
81560484Sobrien      integer_constant ((NUMBERS_WITH_SUFFIX || flag_m68k_mri)
81660484Sobrien                        ? 0 : 10,
81760484Sobrien                        expressionP);
81833965Sjdp      break;
81933965Sjdp
82033965Sjdp    case '0':
82133965Sjdp      /* non-decimal radix */
82233965Sjdp
82360484Sobrien      if (NUMBERS_WITH_SUFFIX || flag_m68k_mri)
82433965Sjdp	{
82533965Sjdp	  char *s;
82633965Sjdp
82733965Sjdp	  /* Check for a hex constant.  */
82833965Sjdp	  for (s = input_line_pointer; hex_p (*s); s++)
82933965Sjdp	    ;
83033965Sjdp	  if (*s == 'h' || *s == 'H')
83133965Sjdp	    {
83233965Sjdp	      --input_line_pointer;
83333965Sjdp	      integer_constant (0, expressionP);
83433965Sjdp	      break;
83533965Sjdp	    }
83660484Sobrien        }
83733965Sjdp      c = *input_line_pointer;
83833965Sjdp      switch (c)
83933965Sjdp	{
84033965Sjdp	case 'o':
84133965Sjdp	case 'O':
84233965Sjdp	case 'q':
84333965Sjdp	case 'Q':
84433965Sjdp	case '8':
84533965Sjdp	case '9':
84660484Sobrien	  if (NUMBERS_WITH_SUFFIX || flag_m68k_mri)
84733965Sjdp	    {
84833965Sjdp	      integer_constant (0, expressionP);
84933965Sjdp	      break;
85033965Sjdp	    }
85133965Sjdp	  /* Fall through.  */
85233965Sjdp	default:
85333965Sjdp	default_case:
85433965Sjdp	  if (c && strchr (FLT_CHARS, c))
85533965Sjdp	    {
85633965Sjdp	      input_line_pointer++;
85733965Sjdp	      floating_constant (expressionP);
85838889Sjdp	      expressionP->X_add_number =
85938889Sjdp		- (isupper ((unsigned char) c) ? tolower (c) : c);
86033965Sjdp	    }
86133965Sjdp	  else
86233965Sjdp	    {
86333965Sjdp	      /* The string was only zero */
86433965Sjdp	      expressionP->X_op = O_constant;
86533965Sjdp	      expressionP->X_add_number = 0;
86633965Sjdp	    }
86733965Sjdp
86833965Sjdp	  break;
86933965Sjdp
87033965Sjdp	case 'x':
87133965Sjdp	case 'X':
87233965Sjdp	  if (flag_m68k_mri)
87333965Sjdp	    goto default_case;
87433965Sjdp	  input_line_pointer++;
87533965Sjdp	  integer_constant (16, expressionP);
87633965Sjdp	  break;
87733965Sjdp
87833965Sjdp	case 'b':
87960484Sobrien	  if (LOCAL_LABELS_FB && ! (flag_m68k_mri || NUMBERS_WITH_SUFFIX))
88033965Sjdp	    {
88133965Sjdp	      /* This code used to check for '+' and '-' here, and, in
88233965Sjdp		 some conditions, fall through to call
88333965Sjdp		 integer_constant.  However, that didn't make sense,
88433965Sjdp		 as integer_constant only accepts digits.  */
88533965Sjdp	      /* Some of our code elsewhere does permit digits greater
88633965Sjdp		 than the expected base; for consistency, do the same
88733965Sjdp		 here.  */
88833965Sjdp	      if (input_line_pointer[1] < '0'
88933965Sjdp		  || input_line_pointer[1] > '9')
89033965Sjdp		{
89133965Sjdp		  /* Parse this as a back reference to label 0.  */
89233965Sjdp		  input_line_pointer--;
89333965Sjdp		  integer_constant (10, expressionP);
89433965Sjdp		  break;
89533965Sjdp		}
89633965Sjdp	      /* Otherwise, parse this as a binary number.  */
89733965Sjdp	    }
89833965Sjdp	  /* Fall through.  */
89933965Sjdp	case 'B':
90033965Sjdp	  input_line_pointer++;
90160484Sobrien	  if (flag_m68k_mri || NUMBERS_WITH_SUFFIX)
90233965Sjdp	    goto default_case;
90333965Sjdp	  integer_constant (2, expressionP);
90433965Sjdp	  break;
90533965Sjdp
90633965Sjdp	case '0':
90733965Sjdp	case '1':
90833965Sjdp	case '2':
90933965Sjdp	case '3':
91033965Sjdp	case '4':
91133965Sjdp	case '5':
91233965Sjdp	case '6':
91333965Sjdp	case '7':
91460484Sobrien	  integer_constant ((flag_m68k_mri || NUMBERS_WITH_SUFFIX)
91560484Sobrien                            ? 0 : 8,
91660484Sobrien                            expressionP);
91733965Sjdp	  break;
91833965Sjdp
91933965Sjdp	case 'f':
92033965Sjdp	  if (LOCAL_LABELS_FB)
92133965Sjdp	    {
92233965Sjdp	      /* If it says "0f" and it could possibly be a floating point
92333965Sjdp		 number, make it one.  Otherwise, make it a local label,
92433965Sjdp		 and try to deal with parsing the rest later.  */
92533965Sjdp	      if (!input_line_pointer[1]
92660484Sobrien		  || (is_end_of_line[0xff & input_line_pointer[1]])
92760484Sobrien		  || strchr (FLT_CHARS, 'f') == NULL)
92833965Sjdp		goto is_0f_label;
92933965Sjdp	      {
93033965Sjdp		char *cp = input_line_pointer + 1;
93133965Sjdp		int r = atof_generic (&cp, ".", EXP_CHARS,
93233965Sjdp				      &generic_floating_point_number);
93333965Sjdp		switch (r)
93433965Sjdp		  {
93533965Sjdp		  case 0:
93633965Sjdp		  case ERROR_EXPONENT_OVERFLOW:
93733965Sjdp		    if (*cp == 'f' || *cp == 'b')
93833965Sjdp		      /* looks like a difference expression */
93933965Sjdp		      goto is_0f_label;
94060484Sobrien		    else if (cp == input_line_pointer + 1)
94160484Sobrien		      /* No characters has been accepted -- looks like
94260484Sobrien                         end of operand. */
94360484Sobrien		      goto is_0f_label;
94433965Sjdp		    else
94533965Sjdp		      goto is_0f_float;
94633965Sjdp		  default:
94760484Sobrien		    as_fatal (_("expr.c(operand): bad atof_generic return val %d"),
94833965Sjdp			      r);
94933965Sjdp		  }
95033965Sjdp	      }
95133965Sjdp
95233965Sjdp	      /* Okay, now we've sorted it out.  We resume at one of these
95333965Sjdp		 two labels, depending on what we've decided we're probably
95433965Sjdp		 looking at.  */
95533965Sjdp	    is_0f_label:
95633965Sjdp	      input_line_pointer--;
95733965Sjdp	      integer_constant (10, expressionP);
95833965Sjdp	      break;
95933965Sjdp
96033965Sjdp	    is_0f_float:
96133965Sjdp	      /* fall through */
96233965Sjdp	      ;
96333965Sjdp	    }
96433965Sjdp
96533965Sjdp	case 'd':
96633965Sjdp	case 'D':
96760484Sobrien	  if (flag_m68k_mri || NUMBERS_WITH_SUFFIX)
96833965Sjdp	    {
96933965Sjdp	      integer_constant (0, expressionP);
97033965Sjdp	      break;
97133965Sjdp	    }
97233965Sjdp	  /* Fall through.  */
97333965Sjdp	case 'F':
97433965Sjdp	case 'r':
97533965Sjdp	case 'e':
97633965Sjdp	case 'E':
97733965Sjdp	case 'g':
97833965Sjdp	case 'G':
97933965Sjdp	  input_line_pointer++;
98033965Sjdp	  floating_constant (expressionP);
98138889Sjdp	  expressionP->X_add_number =
98238889Sjdp	    - (isupper ((unsigned char) c) ? tolower (c) : c);
98333965Sjdp	  break;
98433965Sjdp
98533965Sjdp	case '$':
98633965Sjdp	  if (LOCAL_LABELS_DOLLAR)
98733965Sjdp	    {
98833965Sjdp	      integer_constant (10, expressionP);
98933965Sjdp	      break;
99033965Sjdp	    }
99133965Sjdp	  else
99233965Sjdp	    goto default_case;
99333965Sjdp	}
99433965Sjdp
99533965Sjdp      break;
99633965Sjdp
99733965Sjdp    case '(':
99860484Sobrien#ifndef NEED_INDEX_OPERATOR
99933965Sjdp    case '[':
100060484Sobrien#endif
100133965Sjdp      /* didn't begin with digit & not a name */
100233965Sjdp      segment = expression (expressionP);
100333965Sjdp      /* Expression() will pass trailing whitespace */
100433965Sjdp      if ((c == '(' && *input_line_pointer++ != ')')
100533965Sjdp	  || (c == '[' && *input_line_pointer++ != ']'))
100633965Sjdp	{
100760484Sobrien	  as_bad (_("Missing ')' assumed"));
100833965Sjdp	  input_line_pointer--;
100933965Sjdp	}
101033965Sjdp      SKIP_WHITESPACE ();
101133965Sjdp      /* here with input_line_pointer->char after "(...)" */
101233965Sjdp      return segment;
101333965Sjdp
101460484Sobrien#ifdef TC_M68K
101533965Sjdp    case 'E':
101633965Sjdp      if (! flag_m68k_mri || *input_line_pointer != '\'')
101733965Sjdp	goto de_fault;
101860484Sobrien      as_bad (_("EBCDIC constants are not supported"));
101933965Sjdp      /* Fall through.  */
102033965Sjdp    case 'A':
102133965Sjdp      if (! flag_m68k_mri || *input_line_pointer != '\'')
102233965Sjdp	goto de_fault;
102333965Sjdp      ++input_line_pointer;
102433965Sjdp      /* Fall through.  */
102560484Sobrien#endif
102633965Sjdp    case '\'':
102733965Sjdp      if (! flag_m68k_mri)
102833965Sjdp	{
102933965Sjdp	  /* Warning: to conform to other people's assemblers NO
103033965Sjdp	     ESCAPEMENT is permitted for a single quote. The next
103133965Sjdp	     character, parity errors and all, is taken as the value
103233965Sjdp	     of the operand. VERY KINKY.  */
103333965Sjdp	  expressionP->X_op = O_constant;
103433965Sjdp	  expressionP->X_add_number = *input_line_pointer++;
103533965Sjdp	  break;
103633965Sjdp	}
103733965Sjdp
103833965Sjdp      mri_char_constant (expressionP);
103933965Sjdp      break;
104033965Sjdp
104133965Sjdp    case '+':
104233965Sjdp      (void) operand (expressionP);
104333965Sjdp      break;
104433965Sjdp
104560484Sobrien#ifdef TC_M68K
104633965Sjdp    case '"':
104733965Sjdp      /* Double quote is the bitwise not operator in MRI mode.  */
104833965Sjdp      if (! flag_m68k_mri)
104933965Sjdp	goto de_fault;
105033965Sjdp      /* Fall through.  */
105160484Sobrien#endif
105233965Sjdp    case '~':
105333965Sjdp      /* ~ is permitted to start a label on the Delta.  */
105433965Sjdp      if (is_name_beginner (c))
105533965Sjdp	goto isname;
105633965Sjdp    case '!':
105733965Sjdp    case '-':
105833965Sjdp      {
105933965Sjdp	operand (expressionP);
106033965Sjdp	if (expressionP->X_op == O_constant)
106133965Sjdp	  {
106233965Sjdp	    /* input_line_pointer -> char after operand */
106333965Sjdp	    if (c == '-')
106433965Sjdp	      {
106533965Sjdp		expressionP->X_add_number = - expressionP->X_add_number;
106633965Sjdp		/* Notice: '-' may overflow: no warning is given. This is
106733965Sjdp		   compatible with other people's assemblers. Sigh.  */
106833965Sjdp		expressionP->X_unsigned = 0;
106933965Sjdp	      }
107033965Sjdp	    else if (c == '~' || c == '"')
107133965Sjdp	      expressionP->X_add_number = ~ expressionP->X_add_number;
107233965Sjdp	    else
107333965Sjdp	      expressionP->X_add_number = ! expressionP->X_add_number;
107433965Sjdp	  }
107533965Sjdp	else if (expressionP->X_op != O_illegal
107633965Sjdp		 && expressionP->X_op != O_absent)
107733965Sjdp	  {
107833965Sjdp	    expressionP->X_add_symbol = make_expr_symbol (expressionP);
107933965Sjdp	    if (c == '-')
108033965Sjdp	      expressionP->X_op = O_uminus;
108133965Sjdp	    else if (c == '~' || c == '"')
108233965Sjdp	      expressionP->X_op = O_bit_not;
108333965Sjdp	    else
108433965Sjdp	      expressionP->X_op = O_logical_not;
108533965Sjdp	    expressionP->X_add_number = 0;
108633965Sjdp	  }
108733965Sjdp	else
108860484Sobrien	  as_warn (_("Unary operator %c ignored because bad operand follows"),
108933965Sjdp		   c);
109033965Sjdp      }
109133965Sjdp      break;
109233965Sjdp
109360484Sobrien#if defined (DOLLAR_DOT) || defined (TC_M68K)
109433965Sjdp    case '$':
109533965Sjdp      /* $ is the program counter when in MRI mode, or when DOLLAR_DOT
109633965Sjdp         is defined.  */
109733965Sjdp#ifndef DOLLAR_DOT
109833965Sjdp      if (! flag_m68k_mri)
109933965Sjdp	goto de_fault;
110033965Sjdp#endif
110133965Sjdp      if (flag_m68k_mri && hex_p (*input_line_pointer))
110233965Sjdp	{
110333965Sjdp	  /* In MRI mode, $ is also used as the prefix for a
110433965Sjdp             hexadecimal constant.  */
110533965Sjdp	  integer_constant (16, expressionP);
110633965Sjdp	  break;
110733965Sjdp	}
110833965Sjdp
110933965Sjdp      if (is_part_of_name (*input_line_pointer))
111033965Sjdp	goto isname;
111133965Sjdp
111233965Sjdp      current_location (expressionP);
111333965Sjdp      break;
111460484Sobrien#endif
111533965Sjdp
111633965Sjdp    case '.':
111733965Sjdp      if (!is_part_of_name (*input_line_pointer))
111833965Sjdp	{
111933965Sjdp	  current_location (expressionP);
112033965Sjdp	  break;
112133965Sjdp	}
112233965Sjdp      else if ((strncasecmp (input_line_pointer, "startof.", 8) == 0
112333965Sjdp		&& ! is_part_of_name (input_line_pointer[8]))
112433965Sjdp	       || (strncasecmp (input_line_pointer, "sizeof.", 7) == 0
112533965Sjdp		   && ! is_part_of_name (input_line_pointer[7])))
112633965Sjdp	{
112733965Sjdp	  int start;
112833965Sjdp
112933965Sjdp	  start = (input_line_pointer[1] == 't'
113033965Sjdp		   || input_line_pointer[1] == 'T');
113133965Sjdp	  input_line_pointer += start ? 8 : 7;
113233965Sjdp	  SKIP_WHITESPACE ();
113333965Sjdp	  if (*input_line_pointer != '(')
113460484Sobrien	    as_bad (_("syntax error in .startof. or .sizeof."));
113533965Sjdp	  else
113633965Sjdp	    {
113733965Sjdp	      char *buf;
113833965Sjdp
113933965Sjdp	      ++input_line_pointer;
114033965Sjdp	      SKIP_WHITESPACE ();
114133965Sjdp	      name = input_line_pointer;
114233965Sjdp	      c = get_symbol_end ();
114333965Sjdp
114433965Sjdp	      buf = (char *) xmalloc (strlen (name) + 10);
114533965Sjdp	      if (start)
114633965Sjdp		sprintf (buf, ".startof.%s", name);
114733965Sjdp	      else
114833965Sjdp		sprintf (buf, ".sizeof.%s", name);
114933965Sjdp	      symbolP = symbol_make (buf);
115033965Sjdp	      free (buf);
115133965Sjdp
115233965Sjdp	      expressionP->X_op = O_symbol;
115333965Sjdp	      expressionP->X_add_symbol = symbolP;
115433965Sjdp	      expressionP->X_add_number = 0;
115533965Sjdp
115633965Sjdp	      *input_line_pointer = c;
115733965Sjdp	      SKIP_WHITESPACE ();
115833965Sjdp	      if (*input_line_pointer != ')')
115960484Sobrien		as_bad (_("syntax error in .startof. or .sizeof."));
116033965Sjdp	      else
116133965Sjdp		++input_line_pointer;
116233965Sjdp	    }
116333965Sjdp	  break;
116433965Sjdp	}
116533965Sjdp      else
116633965Sjdp	{
116733965Sjdp	  goto isname;
116833965Sjdp	}
116933965Sjdp    case ',':
117033965Sjdp    case '\n':
117133965Sjdp    case '\0':
117233965Sjdp    eol:
117333965Sjdp      /* can't imagine any other kind of operand */
117433965Sjdp      expressionP->X_op = O_absent;
117533965Sjdp      input_line_pointer--;
117633965Sjdp      break;
117733965Sjdp
117860484Sobrien#ifdef TC_M68K
117933965Sjdp    case '%':
118033965Sjdp      if (! flag_m68k_mri)
118133965Sjdp	goto de_fault;
118233965Sjdp      integer_constant (2, expressionP);
118333965Sjdp      break;
118433965Sjdp
118533965Sjdp    case '@':
118633965Sjdp      if (! flag_m68k_mri)
118733965Sjdp	goto de_fault;
118833965Sjdp      integer_constant (8, expressionP);
118933965Sjdp      break;
119033965Sjdp
119133965Sjdp    case ':':
119233965Sjdp      if (! flag_m68k_mri)
119333965Sjdp	goto de_fault;
119433965Sjdp
119533965Sjdp      /* In MRI mode, this is a floating point constant represented
119633965Sjdp         using hexadecimal digits.  */
119733965Sjdp
119833965Sjdp      ++input_line_pointer;
119933965Sjdp      integer_constant (16, expressionP);
120033965Sjdp      break;
120133965Sjdp
120233965Sjdp    case '*':
120333965Sjdp      if (! flag_m68k_mri || is_part_of_name (*input_line_pointer))
120433965Sjdp	goto de_fault;
120533965Sjdp
120633965Sjdp      current_location (expressionP);
120733965Sjdp      break;
120860484Sobrien#endif
120933965Sjdp
121033965Sjdp    default:
121160484Sobrien#ifdef TC_M68K
121233965Sjdp    de_fault:
121360484Sobrien#endif
121433965Sjdp      if (is_end_of_line[(unsigned char) c])
121533965Sjdp	goto eol;
121633965Sjdp      if (is_name_beginner (c))	/* here if did not begin with a digit */
121733965Sjdp	{
121833965Sjdp	  /*
121933965Sjdp	   * Identifier begins here.
122033965Sjdp	   * This is kludged for speed, so code is repeated.
122133965Sjdp	   */
122233965Sjdp	isname:
122333965Sjdp	  name = --input_line_pointer;
122433965Sjdp	  c = get_symbol_end ();
122533965Sjdp
122633965Sjdp#ifdef md_parse_name
122733965Sjdp	  /* This is a hook for the backend to parse certain names
122833965Sjdp             specially in certain contexts.  If a name always has a
122933965Sjdp             specific value, it can often be handled by simply
123033965Sjdp             entering it in the symbol table.  */
123133965Sjdp	  if (md_parse_name (name, expressionP))
123233965Sjdp	    {
123333965Sjdp	      *input_line_pointer = c;
123433965Sjdp	      break;
123533965Sjdp	    }
123633965Sjdp#endif
123733965Sjdp
123833965Sjdp#ifdef TC_I960
123933965Sjdp	  /* The MRI i960 assembler permits
124033965Sjdp	         lda sizeof code,g13
124133965Sjdp	     FIXME: This should use md_parse_name.  */
124233965Sjdp	  if (flag_mri
124333965Sjdp	      && (strcasecmp (name, "sizeof") == 0
124433965Sjdp		  || strcasecmp (name, "startof") == 0))
124533965Sjdp	    {
124633965Sjdp	      int start;
124733965Sjdp	      char *buf;
124833965Sjdp
124933965Sjdp	      start = (name[1] == 't'
125033965Sjdp		       || name[1] == 'T');
125133965Sjdp
125233965Sjdp	      *input_line_pointer = c;
125333965Sjdp	      SKIP_WHITESPACE ();
125433965Sjdp
125533965Sjdp	      name = input_line_pointer;
125633965Sjdp	      c = get_symbol_end ();
125733965Sjdp
125833965Sjdp	      buf = (char *) xmalloc (strlen (name) + 10);
125933965Sjdp	      if (start)
126033965Sjdp		sprintf (buf, ".startof.%s", name);
126133965Sjdp	      else
126233965Sjdp		sprintf (buf, ".sizeof.%s", name);
126333965Sjdp	      symbolP = symbol_make (buf);
126433965Sjdp	      free (buf);
126533965Sjdp
126633965Sjdp	      expressionP->X_op = O_symbol;
126733965Sjdp	      expressionP->X_add_symbol = symbolP;
126833965Sjdp	      expressionP->X_add_number = 0;
126933965Sjdp
127033965Sjdp	      *input_line_pointer = c;
127133965Sjdp	      SKIP_WHITESPACE ();
127233965Sjdp
127333965Sjdp	      break;
127433965Sjdp	    }
127533965Sjdp#endif
127633965Sjdp
127733965Sjdp	  symbolP = symbol_find_or_make (name);
127833965Sjdp
127933965Sjdp	  /* If we have an absolute symbol or a reg, then we know its
128033965Sjdp	     value now.  */
128133965Sjdp	  segment = S_GET_SEGMENT (symbolP);
128233965Sjdp	  if (segment == absolute_section)
128333965Sjdp	    {
128433965Sjdp	      expressionP->X_op = O_constant;
128533965Sjdp	      expressionP->X_add_number = S_GET_VALUE (symbolP);
128633965Sjdp	    }
128733965Sjdp	  else if (segment == reg_section)
128833965Sjdp	    {
128933965Sjdp	      expressionP->X_op = O_register;
129033965Sjdp	      expressionP->X_add_number = S_GET_VALUE (symbolP);
129133965Sjdp	    }
129233965Sjdp	  else
129333965Sjdp	    {
129433965Sjdp	      expressionP->X_op = O_symbol;
129533965Sjdp	      expressionP->X_add_symbol = symbolP;
129633965Sjdp	      expressionP->X_add_number = 0;
129733965Sjdp	    }
129833965Sjdp	  *input_line_pointer = c;
129933965Sjdp	}
130033965Sjdp      else
130133965Sjdp	{
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
130433965Sjdp	     input_line_pointer passed 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;
131260484Sobrien	      as_bad (_("Bad expression"));
131333965Sjdp	      expressionP->X_op = O_constant;
131433965Sjdp	      expressionP->X_add_number = 0;
131533965Sjdp	    }
131633965Sjdp	}
131733965Sjdp      break;
131833965Sjdp    }
131933965Sjdp
132033965Sjdp  /*
132133965Sjdp   * It is more 'efficient' to clean up the expressionS when they are created.
132233965Sjdp   * Doing it here saves lines of code.
132333965Sjdp   */
132433965Sjdp  clean_up_expression (expressionP);
132533965Sjdp  SKIP_WHITESPACE ();		/*->1st char after operand. */
132633965Sjdp  know (*input_line_pointer != ' ');
132733965Sjdp
132833965Sjdp  /* The PA port needs this information.  */
132933965Sjdp  if (expressionP->X_add_symbol)
133060484Sobrien    symbol_mark_used (expressionP->X_add_symbol);
133133965Sjdp
133233965Sjdp  switch (expressionP->X_op)
133333965Sjdp    {
133433965Sjdp    default:
133533965Sjdp      return absolute_section;
133633965Sjdp    case O_symbol:
133733965Sjdp      return S_GET_SEGMENT (expressionP->X_add_symbol);
133833965Sjdp    case O_register:
133933965Sjdp      return reg_section;
134033965Sjdp    }
134133965Sjdp}				/* operand() */
134233965Sjdp
134333965Sjdp/* Internal. Simplify a struct expression for use by expr() */
134433965Sjdp
134533965Sjdp/*
134633965Sjdp * In:	address of a expressionS.
134733965Sjdp *	The X_op field of the expressionS may only take certain values.
134833965Sjdp *	Elsewise we waste time special-case testing. Sigh. Ditto SEG_ABSENT.
134933965Sjdp * Out:	expressionS may have been modified:
135033965Sjdp *	'foo-foo' symbol references cancelled to 0,
135133965Sjdp *		which changes X_op from O_subtract to O_constant.
135233965Sjdp *	Unused fields zeroed to help expr().
135333965Sjdp */
135433965Sjdp
135533965Sjdpstatic void
135633965Sjdpclean_up_expression (expressionP)
135733965Sjdp     expressionS *expressionP;
135833965Sjdp{
135933965Sjdp  switch (expressionP->X_op)
136033965Sjdp    {
136133965Sjdp    case O_illegal:
136233965Sjdp    case O_absent:
136333965Sjdp      expressionP->X_add_number = 0;
136433965Sjdp      /* Fall through.  */
136533965Sjdp    case O_big:
136633965Sjdp    case O_constant:
136733965Sjdp    case O_register:
136833965Sjdp      expressionP->X_add_symbol = NULL;
136933965Sjdp      /* Fall through.  */
137033965Sjdp    case O_symbol:
137133965Sjdp    case O_uminus:
137233965Sjdp    case O_bit_not:
137333965Sjdp      expressionP->X_op_symbol = NULL;
137433965Sjdp      break;
137533965Sjdp    case O_subtract:
137633965Sjdp      if (expressionP->X_op_symbol == expressionP->X_add_symbol
137760484Sobrien	  || ((symbol_get_frag (expressionP->X_op_symbol)
137860484Sobrien	       == symbol_get_frag (expressionP->X_add_symbol))
137933965Sjdp	      && SEG_NORMAL (S_GET_SEGMENT (expressionP->X_add_symbol))
138033965Sjdp	      && (S_GET_VALUE (expressionP->X_op_symbol)
138133965Sjdp		  == S_GET_VALUE (expressionP->X_add_symbol))))
138233965Sjdp	{
138333965Sjdp	  addressT diff = (S_GET_VALUE (expressionP->X_add_symbol)
138433965Sjdp			   - S_GET_VALUE (expressionP->X_op_symbol));
138533965Sjdp
138633965Sjdp	  expressionP->X_op = O_constant;
138733965Sjdp	  expressionP->X_add_symbol = NULL;
138833965Sjdp	  expressionP->X_op_symbol = NULL;
138933965Sjdp	  expressionP->X_add_number += diff;
139033965Sjdp	}
139133965Sjdp      break;
139233965Sjdp    default:
139333965Sjdp      break;
139433965Sjdp    }
139533965Sjdp}
139633965Sjdp
139733965Sjdp/* Expression parser. */
139833965Sjdp
139933965Sjdp/*
140033965Sjdp * We allow an empty expression, and just assume (absolute,0) silently.
140133965Sjdp * Unary operators and parenthetical expressions are treated as operands.
140233965Sjdp * As usual, Q==quantity==operand, O==operator, X==expression mnemonics.
140333965Sjdp *
140433965Sjdp * We used to do a aho/ullman shift-reduce parser, but the logic got so
140533965Sjdp * warped that I flushed it and wrote a recursive-descent parser instead.
140633965Sjdp * Now things are stable, would anybody like to write a fast parser?
140733965Sjdp * Most expressions are either register (which does not even reach here)
140833965Sjdp * or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common.
140933965Sjdp * So I guess it doesn't really matter how inefficient more complex expressions
141033965Sjdp * are parsed.
141133965Sjdp *
141233965Sjdp * After expr(RANK,resultP) input_line_pointer->operator of rank <= RANK.
141333965Sjdp * Also, we have consumed any leading or trailing spaces (operand does that)
141433965Sjdp * and done all intervening operators.
141533965Sjdp *
141633965Sjdp * This returns the segment of the result, which will be
141733965Sjdp * absolute_section or the segment of a symbol.
141833965Sjdp */
141933965Sjdp
142033965Sjdp#undef __
142133965Sjdp#define __ O_illegal
142233965Sjdp
142360484Sobrienstatic const operatorT op_encoding[256] =
142433965Sjdp{				/* maps ASCII->operators */
142533965Sjdp
142633965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142733965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
142833965Sjdp
142933965Sjdp  __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __,
143033965Sjdp  __, __, O_multiply, O_add, __, O_subtract, __, O_divide,
143133965Sjdp  __, __, __, __, __, __, __, __,
143233965Sjdp  __, __, __, __, O_lt, __, O_gt, __,
143333965Sjdp  __, __, __, __, __, __, __, __,
143433965Sjdp  __, __, __, __, __, __, __, __,
143533965Sjdp  __, __, __, __, __, __, __, __,
143660484Sobrien  __, __, __,
143760484Sobrien#ifdef NEED_INDEX_OPERATOR
143860484Sobrien  O_index,
143960484Sobrien#else
144060484Sobrien  __,
144160484Sobrien#endif
144260484Sobrien  __, __, O_bit_exclusive_or, __,
144333965Sjdp  __, __, __, __, __, __, __, __,
144433965Sjdp  __, __, __, __, __, __, __, __,
144533965Sjdp  __, __, __, __, __, __, __, __,
144633965Sjdp  __, __, __, __, O_bit_inclusive_or, __, __, __,
144733965Sjdp
144833965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
144933965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
145033965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
145133965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
145233965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
145333965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
145433965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
145533965Sjdp  __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
145633965Sjdp};
145733965Sjdp
145833965Sjdp
145933965Sjdp/*
146033965Sjdp *	Rank	Examples
146133965Sjdp *	0	operand, (expression)
146233965Sjdp *	1	||
146333965Sjdp *	2	&&
146433965Sjdp *	3	= <> < <= >= >
146533965Sjdp *	4	+ -
146633965Sjdp *	5	used for * / % in MRI mode
146733965Sjdp *	6	& ^ ! |
146833965Sjdp *	7	* / % << >>
146933965Sjdp *	8	unary - unary ~
147033965Sjdp */
147133965Sjdpstatic operator_rankT op_rank[] =
147233965Sjdp{
147333965Sjdp  0,	/* O_illegal */
147433965Sjdp  0,	/* O_absent */
147533965Sjdp  0,	/* O_constant */
147633965Sjdp  0,	/* O_symbol */
147733965Sjdp  0,	/* O_symbol_rva */
147833965Sjdp  0,	/* O_register */
147933965Sjdp  0,	/* O_bit */
148060484Sobrien  9,	/* O_uminus */
148160484Sobrien  9,	/* O_bit_not */
148260484Sobrien  9,	/* O_logical_not */
148360484Sobrien  8,	/* O_multiply */
148460484Sobrien  8,	/* O_divide */
148560484Sobrien  8,	/* O_modulus */
148660484Sobrien  8,	/* O_left_shift */
148760484Sobrien  8,	/* O_right_shift */
148860484Sobrien  7,	/* O_bit_inclusive_or */
148960484Sobrien  7,	/* O_bit_or_not */
149060484Sobrien  7,	/* O_bit_exclusive_or */
149160484Sobrien  7,	/* O_bit_and */
149260484Sobrien  5,	/* O_add */
149360484Sobrien  5,	/* O_subtract */
149460484Sobrien  4,	/* O_eq */
149560484Sobrien  4,	/* O_ne */
149660484Sobrien  4,	/* O_lt */
149760484Sobrien  4,	/* O_le */
149860484Sobrien  4,	/* O_ge */
149960484Sobrien  4,	/* O_gt */
150060484Sobrien  3,	/* O_logical_and */
150160484Sobrien  2,	/* O_logical_or */
150260484Sobrien  1,	/* O_index */
150360484Sobrien  0,	/* O_md1 */
150460484Sobrien  0,	/* O_md2 */
150560484Sobrien  0,	/* O_md3 */
150660484Sobrien  0,	/* O_md4 */
150760484Sobrien  0,	/* O_md5 */
150860484Sobrien  0,	/* O_md6 */
150960484Sobrien  0,	/* O_md7 */
151060484Sobrien  0,	/* O_md8 */
151160484Sobrien  0,	/* O_md9 */
151260484Sobrien  0,	/* O_md10 */
151360484Sobrien  0,	/* O_md11 */
151460484Sobrien  0,	/* O_md12 */
151560484Sobrien  0,	/* O_md13 */
151660484Sobrien  0,	/* O_md14 */
151760484Sobrien  0,	/* O_md15 */
151860484Sobrien  0,	/* O_md16 */
151933965Sjdp};
152033965Sjdp
152160484Sobrien/* Unfortunately, in MRI mode for the m68k, multiplication and
152260484Sobrien   division have lower precedence than the bit wise operators.  This
152360484Sobrien   function sets the operator precedences correctly for the current
152460484Sobrien   mode.  Also, MRI uses a different bit_not operator, and this fixes
152560484Sobrien   that as well.  */
152633965Sjdp
152760484Sobrien#define STANDARD_MUL_PRECEDENCE (7)
152860484Sobrien#define MRI_MUL_PRECEDENCE (5)
152960484Sobrien
153033965Sjdpvoid
153160484Sobrienexpr_set_precedence ()
153233965Sjdp{
153333965Sjdp  if (flag_m68k_mri)
153433965Sjdp    {
153560484Sobrien      op_rank[O_multiply] = MRI_MUL_PRECEDENCE;
153660484Sobrien      op_rank[O_divide] = MRI_MUL_PRECEDENCE;
153760484Sobrien      op_rank[O_modulus] = MRI_MUL_PRECEDENCE;
153833965Sjdp    }
153960484Sobrien  else
154060484Sobrien    {
154160484Sobrien      op_rank[O_multiply] = STANDARD_MUL_PRECEDENCE;
154260484Sobrien      op_rank[O_divide] = STANDARD_MUL_PRECEDENCE;
154360484Sobrien      op_rank[O_modulus] = STANDARD_MUL_PRECEDENCE;
154460484Sobrien    }
154560484Sobrien}
154633965Sjdp
154760484Sobrien/* Initialize the expression parser.  */
154860484Sobrien
154960484Sobrienvoid
155060484Sobrienexpr_begin ()
155160484Sobrien{
155260484Sobrien  expr_set_precedence ();
155360484Sobrien
155433965Sjdp  /* Verify that X_op field is wide enough.  */
155533965Sjdp  {
155633965Sjdp    expressionS e;
155733965Sjdp    e.X_op = O_max;
155833965Sjdp    assert (e.X_op == O_max);
155933965Sjdp  }
156033965Sjdp}
156133965Sjdp
156233965Sjdp/* Return the encoding for the operator at INPUT_LINE_POINTER.
156333965Sjdp   Advance INPUT_LINE_POINTER to the last character in the operator
156433965Sjdp   (i.e., don't change it for a single character operator).  */
156533965Sjdp
156633965Sjdpstatic inline operatorT
156733965Sjdpoperator ()
156833965Sjdp{
156933965Sjdp  int c;
157033965Sjdp  operatorT ret;
157133965Sjdp
157260484Sobrien  c = *input_line_pointer & 0xff;
157333965Sjdp
157433965Sjdp  switch (c)
157533965Sjdp    {
157633965Sjdp    default:
157733965Sjdp      return op_encoding[c];
157833965Sjdp
157933965Sjdp    case '<':
158033965Sjdp      switch (input_line_pointer[1])
158133965Sjdp	{
158233965Sjdp	default:
158333965Sjdp	  return op_encoding[c];
158433965Sjdp	case '<':
158533965Sjdp	  ret = O_left_shift;
158633965Sjdp	  break;
158733965Sjdp	case '>':
158833965Sjdp	  ret = O_ne;
158933965Sjdp	  break;
159033965Sjdp	case '=':
159133965Sjdp	  ret = O_le;
159233965Sjdp	  break;
159333965Sjdp	}
159433965Sjdp      ++input_line_pointer;
159533965Sjdp      return ret;
159633965Sjdp
159738889Sjdp    case '=':
159838889Sjdp      if (input_line_pointer[1] != '=')
159938889Sjdp	return op_encoding[c];
160038889Sjdp
160138889Sjdp      ++input_line_pointer;
160238889Sjdp      return O_eq;
160338889Sjdp
160433965Sjdp    case '>':
160533965Sjdp      switch (input_line_pointer[1])
160633965Sjdp	{
160733965Sjdp	default:
160833965Sjdp	  return op_encoding[c];
160933965Sjdp	case '>':
161033965Sjdp	  ret = O_right_shift;
161133965Sjdp	  break;
161233965Sjdp	case '=':
161333965Sjdp	  ret = O_ge;
161433965Sjdp	  break;
161533965Sjdp	}
161633965Sjdp      ++input_line_pointer;
161733965Sjdp      return ret;
161833965Sjdp
161933965Sjdp    case '!':
162033965Sjdp      /* We accept !! as equivalent to ^ for MRI compatibility.  */
162133965Sjdp      if (input_line_pointer[1] != '!')
162233965Sjdp	{
162333965Sjdp	  if (flag_m68k_mri)
162433965Sjdp	    return O_bit_inclusive_or;
162533965Sjdp	  return op_encoding[c];
162633965Sjdp	}
162733965Sjdp      ++input_line_pointer;
162833965Sjdp      return O_bit_exclusive_or;
162933965Sjdp
163033965Sjdp    case '|':
163133965Sjdp      if (input_line_pointer[1] != '|')
163233965Sjdp	return op_encoding[c];
163333965Sjdp
163433965Sjdp      ++input_line_pointer;
163533965Sjdp      return O_logical_or;
163633965Sjdp
163733965Sjdp    case '&':
163833965Sjdp      if (input_line_pointer[1] != '&')
163933965Sjdp	return op_encoding[c];
164033965Sjdp
164133965Sjdp      ++input_line_pointer;
164233965Sjdp      return O_logical_and;
164333965Sjdp    }
164433965Sjdp
164533965Sjdp  /*NOTREACHED*/
164638889Sjdp}
164733965Sjdp
164833965Sjdp/* Parse an expression.  */
164933965Sjdp
165033965SjdpsegT
165160484Sobrienexpr (rankarg, resultP)
165260484Sobrien     int rankarg;	/* Larger # is higher rank. */
165333965Sjdp     expressionS *resultP;	/* Deliver result here. */
165433965Sjdp{
165560484Sobrien  operator_rankT rank = (operator_rankT) rankarg;
165633965Sjdp  segT retval;
165733965Sjdp  expressionS right;
165833965Sjdp  operatorT op_left;
165933965Sjdp  operatorT op_right;
166033965Sjdp
166133965Sjdp  know (rank >= 0);
166233965Sjdp
166333965Sjdp  retval = operand (resultP);
166433965Sjdp
166533965Sjdp  know (*input_line_pointer != ' ');	/* Operand() gobbles spaces. */
166633965Sjdp
166733965Sjdp  op_left = operator ();
166833965Sjdp  while (op_left != O_illegal && op_rank[(int) op_left] > rank)
166933965Sjdp    {
167033965Sjdp      segT rightseg;
167133965Sjdp
167233965Sjdp      input_line_pointer++;	/*->after 1st character of operator. */
167333965Sjdp
167433965Sjdp      rightseg = expr (op_rank[(int) op_left], &right);
167533965Sjdp      if (right.X_op == O_absent)
167633965Sjdp	{
167760484Sobrien	  as_warn (_("missing operand; zero assumed"));
167833965Sjdp	  right.X_op = O_constant;
167933965Sjdp	  right.X_add_number = 0;
168033965Sjdp	  right.X_add_symbol = NULL;
168133965Sjdp	  right.X_op_symbol = NULL;
168233965Sjdp	}
168333965Sjdp
168433965Sjdp      know (*input_line_pointer != ' ');
168533965Sjdp
168660484Sobrien      if (op_left == O_index)
168760484Sobrien	{
168860484Sobrien	  if (*input_line_pointer != ']')
168960484Sobrien	    as_bad ("missing right bracket");
169060484Sobrien	  else
169160484Sobrien	    {
169260484Sobrien	      ++input_line_pointer;
169360484Sobrien	      SKIP_WHITESPACE ();
169460484Sobrien	    }
169560484Sobrien	}
169660484Sobrien
169733965Sjdp      if (retval == undefined_section)
169833965Sjdp	{
169933965Sjdp	  if (SEG_NORMAL (rightseg))
170033965Sjdp	    retval = rightseg;
170133965Sjdp	}
170233965Sjdp      else if (! SEG_NORMAL (retval))
170333965Sjdp	retval = rightseg;
170433965Sjdp      else if (SEG_NORMAL (rightseg)
170533965Sjdp	       && retval != rightseg
170633965Sjdp#ifdef DIFF_EXPR_OK
170733965Sjdp	       && op_left != O_subtract
170833965Sjdp#endif
170933965Sjdp	       )
171060484Sobrien	as_bad (_("operation combines symbols in different segments"));
171133965Sjdp
171233965Sjdp      op_right = operator ();
171333965Sjdp
171433965Sjdp      know (op_right == O_illegal || op_rank[(int) op_right] <= op_rank[(int) op_left]);
171533965Sjdp      know ((int) op_left >= (int) O_multiply
171633965Sjdp	    && (int) op_left <= (int) O_logical_or);
171733965Sjdp
171833965Sjdp      /* input_line_pointer->after right-hand quantity. */
171933965Sjdp      /* left-hand quantity in resultP */
172033965Sjdp      /* right-hand quantity in right. */
172133965Sjdp      /* operator in op_left. */
172233965Sjdp
172333965Sjdp      if (resultP->X_op == O_big)
172433965Sjdp	{
172560484Sobrien	  if (resultP->X_add_number > 0)
172660484Sobrien	    as_warn (_("left operand is a bignum; integer 0 assumed"));
172760484Sobrien	  else
172860484Sobrien	    as_warn (_("left operand is a float; integer 0 assumed"));
172933965Sjdp	  resultP->X_op = O_constant;
173033965Sjdp	  resultP->X_add_number = 0;
173133965Sjdp	  resultP->X_add_symbol = NULL;
173233965Sjdp	  resultP->X_op_symbol = NULL;
173333965Sjdp	}
173433965Sjdp      if (right.X_op == O_big)
173533965Sjdp	{
173660484Sobrien	  if (right.X_add_number > 0)
173760484Sobrien	    as_warn (_("right operand is a bignum; integer 0 assumed"));
173860484Sobrien	  else
173960484Sobrien	    as_warn (_("right operand is a float; integer 0 assumed"));
174033965Sjdp	  right.X_op = O_constant;
174133965Sjdp	  right.X_add_number = 0;
174233965Sjdp	  right.X_add_symbol = NULL;
174333965Sjdp	  right.X_op_symbol = NULL;
174433965Sjdp	}
174533965Sjdp
174633965Sjdp      /* Optimize common cases.  */
174733965Sjdp      if (op_left == O_add && right.X_op == O_constant)
174833965Sjdp	{
174933965Sjdp	  /* X + constant.  */
175033965Sjdp	  resultP->X_add_number += right.X_add_number;
175133965Sjdp	}
175233965Sjdp      /* This case comes up in PIC code.  */
175333965Sjdp      else if (op_left == O_subtract
175433965Sjdp	       && right.X_op == O_symbol
175533965Sjdp	       && resultP->X_op == O_symbol
175660484Sobrien	       && (symbol_get_frag (right.X_add_symbol)
175760484Sobrien		   == symbol_get_frag (resultP->X_add_symbol))
175833965Sjdp	       && SEG_NORMAL (S_GET_SEGMENT (right.X_add_symbol)))
175933965Sjdp
176033965Sjdp	{
176133965Sjdp	  resultP->X_add_number -= right.X_add_number;
176233965Sjdp	  resultP->X_add_number += (S_GET_VALUE (resultP->X_add_symbol)
176333965Sjdp				    - S_GET_VALUE (right.X_add_symbol));
176433965Sjdp	  resultP->X_op = O_constant;
176533965Sjdp	  resultP->X_add_symbol = 0;
176633965Sjdp	}
176733965Sjdp      else if (op_left == O_subtract && right.X_op == O_constant)
176833965Sjdp	{
176933965Sjdp	  /* X - constant.  */
177033965Sjdp	  resultP->X_add_number -= right.X_add_number;
177133965Sjdp	}
177233965Sjdp      else if (op_left == O_add && resultP->X_op == O_constant)
177333965Sjdp	{
177433965Sjdp	  /* Constant + X.  */
177533965Sjdp	  resultP->X_op = right.X_op;
177633965Sjdp	  resultP->X_add_symbol = right.X_add_symbol;
177733965Sjdp	  resultP->X_op_symbol = right.X_op_symbol;
177833965Sjdp	  resultP->X_add_number += right.X_add_number;
177933965Sjdp	  retval = rightseg;
178033965Sjdp	}
178133965Sjdp      else if (resultP->X_op == O_constant && right.X_op == O_constant)
178233965Sjdp	{
178333965Sjdp	  /* Constant OP constant.  */
178433965Sjdp	  offsetT v = right.X_add_number;
178533965Sjdp	  if (v == 0 && (op_left == O_divide || op_left == O_modulus))
178633965Sjdp	    {
178760484Sobrien	      as_warn (_("division by zero"));
178833965Sjdp	      v = 1;
178933965Sjdp	    }
179033965Sjdp	  switch (op_left)
179133965Sjdp	    {
179233965Sjdp	    default:			abort ();
179333965Sjdp	    case O_multiply:		resultP->X_add_number *= v; break;
179433965Sjdp	    case O_divide:		resultP->X_add_number /= v; break;
179533965Sjdp	    case O_modulus:		resultP->X_add_number %= v; break;
179633965Sjdp	    case O_left_shift:		resultP->X_add_number <<= v; break;
179733965Sjdp	    case O_right_shift:
179833965Sjdp	      /* We always use unsigned shifts, to avoid relying on
179933965Sjdp                 characteristics of the compiler used to compile gas.  */
180033965Sjdp	      resultP->X_add_number =
180133965Sjdp		(offsetT) ((valueT) resultP->X_add_number >> (valueT) v);
180233965Sjdp	      break;
180333965Sjdp	    case O_bit_inclusive_or:	resultP->X_add_number |= v; break;
180433965Sjdp	    case O_bit_or_not:		resultP->X_add_number |= ~v; break;
180533965Sjdp	    case O_bit_exclusive_or:	resultP->X_add_number ^= v; break;
180633965Sjdp	    case O_bit_and:		resultP->X_add_number &= v; break;
180733965Sjdp	    case O_add:			resultP->X_add_number += v; break;
180833965Sjdp	    case O_subtract:		resultP->X_add_number -= v; break;
180933965Sjdp	    case O_eq:
181033965Sjdp	      resultP->X_add_number =
181133965Sjdp		resultP->X_add_number == v ? ~ (offsetT) 0 : 0;
181233965Sjdp	      break;
181333965Sjdp	    case O_ne:
181433965Sjdp	      resultP->X_add_number =
181533965Sjdp		resultP->X_add_number != v ? ~ (offsetT) 0 : 0;
181633965Sjdp	      break;
181733965Sjdp	    case O_lt:
181833965Sjdp	      resultP->X_add_number =
181933965Sjdp		resultP->X_add_number <  v ? ~ (offsetT) 0 : 0;
182033965Sjdp	      break;
182133965Sjdp	    case O_le:
182233965Sjdp	      resultP->X_add_number =
182333965Sjdp		resultP->X_add_number <= v ? ~ (offsetT) 0 : 0;
182433965Sjdp	      break;
182533965Sjdp	    case O_ge:
182633965Sjdp	      resultP->X_add_number =
182733965Sjdp		resultP->X_add_number >= v ? ~ (offsetT) 0 : 0;
182833965Sjdp	      break;
182933965Sjdp	    case O_gt:
183033965Sjdp	      resultP->X_add_number =
183133965Sjdp		resultP->X_add_number >  v ? ~ (offsetT) 0 : 0;
183233965Sjdp	      break;
183333965Sjdp	    case O_logical_and:
183433965Sjdp	      resultP->X_add_number = resultP->X_add_number && v;
183533965Sjdp	      break;
183633965Sjdp	    case O_logical_or:
183733965Sjdp	      resultP->X_add_number = resultP->X_add_number || v;
183833965Sjdp	      break;
183933965Sjdp	    }
184033965Sjdp	}
184133965Sjdp      else if (resultP->X_op == O_symbol
184233965Sjdp	       && right.X_op == O_symbol
184333965Sjdp	       && (op_left == O_add
184433965Sjdp		   || op_left == O_subtract
184533965Sjdp		   || (resultP->X_add_number == 0
184633965Sjdp		       && right.X_add_number == 0)))
184733965Sjdp	{
184833965Sjdp	  /* Symbol OP symbol.  */
184933965Sjdp	  resultP->X_op = op_left;
185033965Sjdp	  resultP->X_op_symbol = right.X_add_symbol;
185133965Sjdp	  if (op_left == O_add)
185233965Sjdp	    resultP->X_add_number += right.X_add_number;
185333965Sjdp	  else if (op_left == O_subtract)
185433965Sjdp	    resultP->X_add_number -= right.X_add_number;
185533965Sjdp	}
185633965Sjdp      else
185733965Sjdp	{
185833965Sjdp	  /* The general case.  */
185933965Sjdp	  resultP->X_add_symbol = make_expr_symbol (resultP);
186033965Sjdp	  resultP->X_op_symbol = make_expr_symbol (&right);
186133965Sjdp	  resultP->X_op = op_left;
186233965Sjdp	  resultP->X_add_number = 0;
186333965Sjdp	  resultP->X_unsigned = 1;
186433965Sjdp	}
186533965Sjdp
186633965Sjdp      op_left = op_right;
186733965Sjdp    }				/* While next operator is >= this rank. */
186833965Sjdp
186933965Sjdp  /* The PA port needs this information.  */
187033965Sjdp  if (resultP->X_add_symbol)
187160484Sobrien    symbol_mark_used (resultP->X_add_symbol);
187233965Sjdp
187333965Sjdp  return resultP->X_op == O_constant ? absolute_section : retval;
187433965Sjdp}
187533965Sjdp
187633965Sjdp/*
187733965Sjdp *			get_symbol_end()
187833965Sjdp *
187933965Sjdp * This lives here because it belongs equally in expr.c & read.c.
188033965Sjdp * Expr.c is just a branch office read.c anyway, and putting it
188133965Sjdp * here lessens the crowd at read.c.
188233965Sjdp *
188333965Sjdp * Assume input_line_pointer is at start of symbol name.
188433965Sjdp * Advance input_line_pointer past symbol name.
188533965Sjdp * Turn that character into a '\0', returning its former value.
188633965Sjdp * This allows a string compare (RMS wants symbol names to be strings)
188733965Sjdp * of the symbol name.
188833965Sjdp * There will always be a char following symbol name, because all good
188933965Sjdp * lines end in end-of-line.
189033965Sjdp */
189133965Sjdpchar
189233965Sjdpget_symbol_end ()
189333965Sjdp{
189433965Sjdp  char c;
189533965Sjdp
189633965Sjdp  /* We accept \001 in a name in case this is being called with a
189733965Sjdp     constructed string.  */
189833965Sjdp  if (is_name_beginner (c = *input_line_pointer++) || c == '\001')
189960484Sobrien    {
190060484Sobrien      while (is_part_of_name (c = *input_line_pointer++)
190160484Sobrien	     || c == '\001')
190260484Sobrien	;
190360484Sobrien      if (is_name_ender (c))
190460484Sobrien	c = *input_line_pointer++;
190560484Sobrien    }
190633965Sjdp  *--input_line_pointer = 0;
190733965Sjdp  return (c);
190833965Sjdp}
190933965Sjdp
191033965Sjdp
191133965Sjdpunsigned int
191233965Sjdpget_single_number ()
191333965Sjdp{
191433965Sjdp  expressionS exp;
191533965Sjdp  operand (&exp);
191633965Sjdp  return exp.X_add_number;
191733965Sjdp
191833965Sjdp}
191933965Sjdp
192033965Sjdp/* end of expr.c */
1921