if (symp->sy_value.X_add_number == 0) copy_symbol_attributes (symp, symp->sy_value.X_add_symbol);  S_SET_VALUE (symp, (symp->sy_value.X_add_number + symp->sy_frag->fr_address + S_GET_VALUE (symp->sy_value.X_add_symbol))); if (S_GET_SEGMENT (symp) == expr_section || S_GET_SEGMENT (symp) == undefined_section) S_SET_SEGMENT (symp, S_GET_SEGMENT (symp->sy_value.X_add_symbol));   if (! S_IS_DEFINED (symp) || S_IS_COMMON (symp)) symp->sy_value.X_op = O_symbol;
resolve_symbol_value (symp)     symbolS *symp;{  int resolved;  if (symp->sy_resolved)    return;  resolved = 0;  if (symp->sy_resolving)    {      as_bad ("Symbol definition loop encountered at %s",	      S_GET_NAME (symp));      S_SET_VALUE (symp, (valueT) 0);      resolved = 1;    }  else    {      offsetT left, right, val;      segT seg_left, seg_right;      symp->sy_resolving = 1;    reduce:      switch (symp->sy_value.X_op)	{	case O_absent:	  S_SET_VALUE (symp, 0);	  /* Fall through.  */	case O_constant:	  S_SET_VALUE (symp, S_GET_VALUE (symp) + symp->sy_frag->fr_address);	  if (S_GET_SEGMENT (symp) == expr_section)	    S_SET_SEGMENT (symp, absolute_section);	  resolved = 1;	  break;	case O_symbol:	  resolve_symbol_value (symp->sy_value.X_add_symbol);	  if (symp->sy_mri_common)	    {	      /* This is a symbol inside an MRI common section.  The                 relocation routines are going to handle it specially.                 Don't change the value.  */	      S_SET_VALUE (symp, symp->sy_value.X_add_number);	      resolved = symp->sy_value.X_add_symbol->sy_resolved;	      break;	    }#if 0 /* I thought this was needed for some of the i386-svr4 PIC	 support, but it appears I was wrong, and it breaks rs6000	 support.  */	  if (S_GET_SEGMENT (symp->sy_value.X_add_symbol) != undefined_section	      && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section)#endif	    {	      if (symp->sy_value.X_add_number == 0)		copy_symbol_attributes (symp, symp->sy_value.X_add_symbol);	      S_SET_VALUE (symp,			   (symp->sy_value.X_add_number			    + symp->sy_frag->fr_address			    + S_GET_VALUE (symp->sy_value.X_add_symbol)));	      if (S_GET_SEGMENT (symp) == expr_section		  || S_GET_SEGMENT (symp) == undefined_section)		S_SET_SEGMENT (symp,			       S_GET_SEGMENT (symp->sy_value.X_add_symbol));	    }	  resolved = symp->sy_value.X_add_symbol->sy_resolved;	  break;	case O_uminus:	case O_bit_not:	  resolve_symbol_value (symp->sy_value.X_add_symbol);	  if (symp->sy_value.X_op == O_uminus)	    val = - S_GET_VALUE (symp->sy_value.X_add_symbol);	  else	    val = ~ S_GET_VALUE (symp->sy_value.X_add_symbol);	  S_SET_VALUE (symp,		       (val			+ symp->sy_value.X_add_number			+ symp->sy_frag->fr_address));	  if (S_GET_SEGMENT (symp) == expr_section	      || S_GET_SEGMENT (symp) == undefined_section)	    S_SET_SEGMENT (symp, absolute_section);	  resolved = symp->sy_value.X_add_symbol->sy_resolved;	  break;	case O_add:	  resolve_symbol_value (symp->sy_value.X_add_symbol);	  resolve_symbol_value (symp->sy_value.X_op_symbol);	  seg_left = S_GET_SEGMENT (symp->sy_value.X_add_symbol);	  seg_right = S_GET_SEGMENT (symp->sy_value.X_op_symbol);	  /* This case comes up with PIC support.  */	  {	    symbolS *s_left = symp->sy_value.X_add_symbol;	    symbolS *s_right = symp->sy_value.X_op_symbol;	    if (seg_left == absolute_section)	      {		symbolS *t;		segT ts;		t = s_left;		s_left = s_right;		s_right = t;		ts = seg_left;		seg_left = seg_right;		seg_right = ts;	      }	    if (seg_right == absolute_section		&& s_right->sy_resolved)	      {		symp->sy_value.X_add_number += S_GET_VALUE (s_right);		symp->sy_value.X_op_symbol = 0;		symp->sy_value.X_add_symbol = s_left;		symp->sy_value.X_op = O_symbol;		goto reduce;	      }	  }	  /* fall through */	case O_multiply:	case O_divide:	case O_modulus:	case O_left_shift:	case O_right_shift:	case O_bit_inclusive_or:	case O_bit_or_not:	case O_bit_exclusive_or:	case O_bit_and:	case O_subtract:	case O_eq:	case O_ne:	case O_lt:	case O_le:	case O_ge:	case O_gt:	case O_logical_and:	case O_logical_or:	  resolve_symbol_value (symp->sy_value.X_add_symbol);	  resolve_symbol_value (symp->sy_value.X_op_symbol);	  seg_left = S_GET_SEGMENT (symp->sy_value.X_add_symbol);	  seg_right = S_GET_SEGMENT (symp->sy_value.X_op_symbol);	  if (seg_left != seg_right	      && seg_left != undefined_section	      && seg_right != undefined_section)	    as_bad ("%s is operation on symbols in different sections",		    S_GET_NAME (symp));	  if ((S_GET_SEGMENT (symp->sy_value.X_add_symbol)	       != absolute_section)	      && symp->sy_value.X_op != O_subtract)	    as_bad ("%s is illegal operation on non-absolute symbols",		    S_GET_NAME (symp));	  left = S_GET_VALUE (symp->sy_value.X_add_symbol);	  right = S_GET_VALUE (symp->sy_value.X_op_symbol);	  switch (symp->sy_value.X_op)	    {	    case O_multiply:		val = left * right; break;	    case O_divide:		val = left / right; break;	    case O_modulus:		val = left % right; break;	    case O_left_shift:		val = left << right; break;	    case O_right_shift:		val = left >> right; break;	    case O_bit_inclusive_or:	val = left | right; break;	    case O_bit_or_not:		val = left |~ right; break;	    case O_bit_exclusive_or:	val = left ^ right; break;	    case O_bit_and:		val = left & right; break;	    case O_add:			val = left + right; break;	    case O_subtract:		val = left - right; break;	    case O_eq:		val = left == right ? ~ (offsetT) 0 : 0;	    case O_ne:		val = left != right ? ~ (offsetT) 0 : 0;	    case O_lt:		val = left <  right ? ~ (offsetT) 0 : 0;	    case O_le:		val = left <= right ? ~ (offsetT) 0 : 0;	    case O_ge:		val = left >= right ? ~ (offsetT) 0 : 0;	    case O_gt:		val = left >  right ? ~ (offsetT) 0 : 0;	    case O_logical_and:	val = left && right; break;	    case O_logical_or:	val = left || right; break;	    default:			abort ();	    }	  S_SET_VALUE (symp,		       (symp->sy_value.X_add_number			+ symp->sy_frag->fr_address			+ val));	  if (S_GET_SEGMENT (symp) == expr_section	      || S_GET_SEGMENT (symp) == undefined_section)	    S_SET_SEGMENT (symp, absolute_section);	  resolved = (symp->sy_value.X_add_symbol->sy_resolved		      && symp->sy_value.X_op_symbol->sy_resolved);   	  break;	case O_register:	case O_big:	case O_illegal:	  /* Give an error (below) if not in expr_section.  We don't	     want to worry about expr_section symbols, because they	     are fictional (they are created as part of expression	     resolution), and any problems may not actually mean	     anything.  */	  break;	}    }  /* Don't worry if we can't resolve an expr_section symbol.  */  if (resolved)    symp->sy_resolved = 1;  else if (S_GET_SEGMENT (symp) != expr_section)    {      as_bad ("can't resolve value for symbol \"%s\"", S_GET_NAME (symp));      symp->sy_resolved = 1;    }}