if (! flag_mri)
if (! flag_m68k_mri)
operand (expressionP)     expressionS *expressionP;{  char c;  symbolS *symbolP;	/* points to symbol */  char *name;		/* points to name of symbol */  segT segment;  /* All integers are regarded as unsigned unless they are negated.     This is because the only thing which cares whether a number is     unsigned is the code in emit_expr which extends constants into     bignums.  It should only sign extend negative numbers, so that     something like ``.quad 0x80000000'' is not sign extended even     though it appears negative if valueT is 32 bits.  */  expressionP->X_unsigned = 1;  /* digits, assume it is a bignum. */  SKIP_WHITESPACE ();		/* leading whitespace is part of operand. */  c = *input_line_pointer++;	/* input_line_pointer->past char in c. */  switch (c)    {    case '1':    case '2':    case '3':    case '4':    case '5':    case '6':    case '7':    case '8':    case '9':      input_line_pointer--;      integer_constant (flag_mri ? 0 : 10, expressionP);      break;    case '0':      /* non-decimal radix */      if (flag_mri)	{	  char *s;	  /* Check for a hex constant.  */	  for (s = input_line_pointer; hex_p (*s); s++)	    ;	  if (*s == 'h' || *s == 'H')	    {	      --input_line_pointer;	      integer_constant (0, expressionP);	      break;	    }	}      c = *input_line_pointer;      switch (c)	{	case '8':	case '9':	  if (flag_mri)	    {	      integer_constant (0, expressionP);	      break;	    }	  /* Fall through.  */	default:	default_case:	  if (c && strchr (FLT_CHARS, c))	    {	      input_line_pointer++;	      floating_constant (expressionP);	      expressionP->X_add_number = -(isupper (c) ? tolower (c) : c);	    }	  else	    {	      /* The string was only zero */	      expressionP->X_op = O_constant;	      expressionP->X_add_number = 0;	    }	  break;	case 'x':	case 'X':	  if (flag_mri)	    goto default_case;	  input_line_pointer++;	  integer_constant (16, expressionP);	  break;	case 'b':	  if (LOCAL_LABELS_FB)	    {	      switch (input_line_pointer[1])		{		case '+':		case '-':		  /* If unambiguously a difference expression, treat		     it as one by indicating a label; otherwise, it's		     always a binary number.  */		  {		    char *cp = input_line_pointer + 1;		    while (strchr ("0123456789", *++cp))		      ;		    if (*cp == 'b' || *cp == 'f')		      goto is_0b_label;		  }		  goto is_0b_binary;		case '0':    case '1':		  /* Some of our code elsewhere does permit digits		     greater than the expected base; for consistency,		     do the same here.  */		case '2':    case '3':    case '4':    case '5':		case '6':    case '7':    case '8':    case '9':		  goto is_0b_binary;		case 0:		  goto is_0b_label;		default:		  goto is_0b_label;		}	    is_0b_label:	      input_line_pointer--;	      integer_constant (10, expressionP);	      break;	    is_0b_binary:	      ;	    }	case 'B':	  input_line_pointer++;	  if (flag_mri)	    goto default_case;	  integer_constant (2, expressionP);	  break;	case '0':	case '1':	case '2':	case '3':	case '4':	case '5':	case '6':	case '7':	  integer_constant (flag_mri ? 0 : 8, expressionP);	  break;	case 'f':	  if (LOCAL_LABELS_FB)	    {	      /* If it says "0f" and it could possibly be a floating point		 number, make it one.  Otherwise, make it a local label,		 and try to deal with parsing the rest later.  */	      if (!input_line_pointer[1]		  || (is_end_of_line[0xff & input_line_pointer[1]]))		goto is_0f_label;	      {		char *cp = input_line_pointer + 1;		int r = atof_generic (&cp, ".", EXP_CHARS,				      &generic_floating_point_number);		switch (r)		  {		  case 0:		  case ERROR_EXPONENT_OVERFLOW:		    if (*cp == 'f' || *cp == 'b')		      /* looks like a difference expression */		      goto is_0f_label;		    else		      goto is_0f_float;		  default:		    as_fatal ("expr.c(operand): bad atof_generic return val %d",			      r);		  }	      }	      /* Okay, now we've sorted it out.  We resume at one of these		 two labels, depending on what we've decided we're probably		 looking at.  */	    is_0f_label:	      input_line_pointer--;	      integer_constant (10, expressionP);	      break;	    is_0f_float:	      /* fall through */	      ;	    }	case 'd':	case 'D':	case 'F':	case 'r':	case 'e':	case 'E':	case 'g':	case 'G':	  input_line_pointer++;	  floating_constant (expressionP);	  expressionP->X_add_number = -(isupper (c) ? tolower (c) : c);	  break;	case '$':	  if (LOCAL_LABELS_DOLLAR)	    {	      integer_constant (10, expressionP);	      break;	    }	  else	    goto default_case;	}      break;    case '(':    case '[':      /* didn't begin with digit & not a name */      segment = expression (expressionP);      /* Expression() will pass trailing whitespace */      if ((c == '(' && *input_line_pointer++ != ')')	  || (c == '[' && *input_line_pointer++ != ']'))	{	  as_bad ("Missing ')' assumed");	  input_line_pointer--;	}      /* here with input_line_pointer->char after "(...)" */      return segment;    case 'E':      if (! flag_mri || *input_line_pointer != '\'')	goto de_fault;      as_bad ("EBCDIC constants are not supported");      /* Fall through.  */    case 'A':      if (! flag_mri || *input_line_pointer != '\'')	goto de_fault;      ++input_line_pointer;      /* Fall through.  */    case '\'':      if (! flag_mri)	{	  /* Warning: to conform to other people's assemblers NO	     ESCAPEMENT is permitted for a single quote. The next	     character, parity errors and all, is taken as the value	     of the operand. VERY KINKY.  */	  expressionP->X_op = O_constant;	  expressionP->X_add_number = *input_line_pointer++;	  break;	}      mri_char_constant (expressionP);      break;    case '+':      (void) operand (expressionP);      break;    case '"':      /* Double quote is the bitwise not operator in MRI mode.  */      if (! flag_mri)	goto de_fault;      /* Fall through.  */    case '!':    case '~':    case '-':      {	operand (expressionP);	if (expressionP->X_op == O_constant)	  {	    /* input_line_pointer -> char after operand */	    if (c == '-')	      {		expressionP->X_add_number = - expressionP->X_add_number;		/* Notice: '-' may overflow: no warning is given. This is		   compatible with other people's assemblers. Sigh.  */		expressionP->X_unsigned = 0;	      }	    else if (c == '~' || c == '"')	      expressionP->X_add_number = ~ expressionP->X_add_number;	    else	      expressionP->X_add_number = ! expressionP->X_add_number;	  }	else if (expressionP->X_op != O_illegal		 && expressionP->X_op != O_absent)	  {	    expressionP->X_add_symbol = make_expr_symbol (expressionP);	    if (c == '-')	      expressionP->X_op = O_uminus;	    else if (c == '~' || c == '"')	      expressionP->X_op = O_bit_not;	    else	      expressionP->X_op = O_logical_not;	    expressionP->X_add_number = 0;	  }	else	  as_warn ("Unary operator %c ignored because bad operand follows",		   c);      }      break;    case '$':      /* $ is the program counter when in MRI mode, or when DOLLAR_DOT         is defined.  */#ifndef DOLLAR_DOT      if (! flag_mri)	goto de_fault;#endif      if (flag_mri && hex_p (*input_line_pointer))	{	  /* In MRI mode, $ is also used as the prefix for a             hexadecimal constant.  */	  integer_constant (16, expressionP);	  break;	}      if (is_part_of_name (*input_line_pointer))	goto isname;      current_location (expressionP);      break;    case '.':      if (!is_part_of_name (*input_line_pointer))	{	  current_location (expressionP);	  break;	}      else if ((strncasecmp (input_line_pointer, "startof.", 8) == 0		&& ! is_part_of_name (input_line_pointer[8]))	       || (strncasecmp (input_line_pointer, "sizeof.", 7) == 0		   && ! is_part_of_name (input_line_pointer[7])))	{	  int start;	  start = (input_line_pointer[1] == 't'		   || input_line_pointer[1] == 'T');	  input_line_pointer += start ? 8 : 7;	  SKIP_WHITESPACE ();	  if (*input_line_pointer != '(')	    as_bad ("syntax error in .startof. or .sizeof.");	  else	    {	      char *buf;	      ++input_line_pointer;	      SKIP_WHITESPACE ();	      name = input_line_pointer;	      c = get_symbol_end ();	      buf = (char *) xmalloc (strlen (name) + 10);	      if (start)		sprintf (buf, ".startof.%s", name);	      else		sprintf (buf, ".sizeof.%s", name);	      symbolP = symbol_make (buf);	      free (buf);	      expressionP->X_op = O_symbol;	      expressionP->X_add_symbol = symbolP;	      expressionP->X_add_number = 0;	      *input_line_pointer = c;	      SKIP_WHITESPACE ();	      if (*input_line_pointer != ')')		as_bad ("syntax error in .startof. or .sizeof.");	      else		++input_line_pointer;	    }	  break;	}      else	{	  goto isname;	}    case ',':    case '\n':    case '\0':    eol:      /* can't imagine any other kind of operand */      expressionP->X_op = O_absent;      input_line_pointer--;      break;    case '%':      if (! flag_mri)	goto de_fault;      integer_constant (2, expressionP);      break;    case '@':      if (! flag_mri)	goto de_fault;      integer_constant (8, expressionP);      break;    case ':':      if (! flag_mri)	goto de_fault;      /* In MRI mode, this is a floating point constant represented         using hexadecimal digits.  */      ++input_line_pointer;      integer_constant (16, expressionP);      break;    case '*':      if (! flag_mri || is_part_of_name (*input_line_pointer))	goto de_fault;      current_location (expressionP);      break;    default:    de_fault:      if (is_end_of_line[(unsigned char) c])	goto eol;      if (is_name_beginner (c))	/* here if did not begin with a digit */	{	  /*	   * Identifier begins here.	   * This is kludged for speed, so code is repeated.	   */	isname:	  name = --input_line_pointer;	  c = get_symbol_end ();#ifdef TC_I960	  /* The MRI i960 assemblers permits	         lda sizeof code,g13	     */	  if (flag_mri	      && (strcasecmp (name, "sizeof") == 0		  || strcasecmp (name, "startof") == 0))	    {	      int start;	      char *buf;	      start = (name[1] == 't'		       || name[1] == 'T');	      *input_line_pointer = c;	      SKIP_WHITESPACE ();	      name = input_line_pointer;	      c = get_symbol_end ();	      buf = (char *) xmalloc (strlen (name) + 10);	      if (start)		sprintf (buf, ".startof.%s", name);	      else		sprintf (buf, ".sizeof.%s", name);	      symbolP = symbol_make (buf);	      free (buf);	      expressionP->X_op = O_symbol;	      expressionP->X_add_symbol = symbolP;	      expressionP->X_add_number = 0;	      *input_line_pointer = c;	      SKIP_WHITESPACE ();	      break;	    }	      #endif	  symbolP = symbol_find_or_make (name);	  /* If we have an absolute symbol or a reg, then we know its	     value now.  */	  segment = S_GET_SEGMENT (symbolP);	  if (segment == absolute_section)	    {	      expressionP->X_op = O_constant;	      expressionP->X_add_number = S_GET_VALUE (symbolP);	    }	  else if (segment == reg_section)	    {	      expressionP->X_op = O_register;	      expressionP->X_add_number = S_GET_VALUE (symbolP);	    }	  else	    {	      expressionP->X_op = O_symbol;	      expressionP->X_add_symbol = symbolP;	      expressionP->X_add_number = 0;	    }	  *input_line_pointer = c;	}      else	{	  /* Let the target try to parse it.  Success is indicated by changing	     the X_op field to something other than O_absent and pointing	     input_line_pointer passed the expression.  If it can't parse the	     expression, X_op and input_line_pointer should be unchanged.  */	  expressionP->X_op = O_absent;	  --input_line_pointer;	  md_operand (expressionP);	  if (expressionP->X_op == O_absent)	    {	      ++input_line_pointer;	      as_bad ("Bad expression");	      expressionP->X_op = O_constant;	      expressionP->X_add_number = 0;	    }	}      break;    }  /*   * It is more 'efficient' to clean up the expressionS when they are created.   * Doing it here saves lines of code.   */  clean_up_expression (expressionP);  SKIP_WHITESPACE ();		/*->1st char after operand. */  know (*input_line_pointer != ' ');  /* The PA port needs this information.  */  if (expressionP->X_add_symbol)    expressionP->X_add_symbol->sy_used = 1;  switch (expressionP->X_op)    {    default:      return absolute_section;    case O_symbol:      return S_GET_SEGMENT (expressionP->X_add_symbol);    case O_register:      return reg_section;    }}				/* operand() */