public inbox for gas2@sourceware.org
 help / color / mirror / Atom feed
From: Ian Lance Taylor <ian@cygnus.com>
To: richard.earnshaw@armltd.co.uk
Cc: raeburn@cygnus.com, richard.earnshaw@armltd.co.uk, gas2@cygnus.com
Subject: Re: Inconsistent behaviour (in resolve_symbol_value?)
Date: Wed, 07 Aug 1996 12:34:00 -0000	[thread overview]
Message-ID: <199608071934.PAA24880@sanguine.cygnus.com> (raw)
In-Reply-To: <9608051502.AA02481@sun52.armltd>

   Date: Mon, 05 Aug 1996 16:02:35 +0100
   From: Richard Earnshaw <rearnsha@armltd.co.uk>

   The problem seems to be the code in resolve_symbol_value that handles
   various binary operations.  I'm not sure what the code is trying to check
   for so I'm not sure what the fix should be.  Both 'if' clauses involve
   checks for undefined sections, but the cases are very specific.  Further,
   after the logical operation has been performed the type of the node is
   changed to O_constant, so it is no-longer possible to recover the
   operation in the back end.


That code doesn't really make any sense to me either, even though I
wrote it.

I think I'll apply this patch.  It requires that both operands of an
arithmetic operator be absolute, except in the special cases of adding
or subtracting a constant, or subtracting two symbols in the same
section.  Please let me know if this seems to have any problems.

Ian

Index: symbols.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gas/symbols.c,v
retrieving revision 1.86
diff -u -r1.86 symbols.c
--- symbols.c	1996/07/26 15:58:57	1.86
+++ symbols.c	1996/08/07 19:32:08
@@ -639,7 +639,35 @@
 
       symp->sy_resolving = 1;
 
-    reduce:
+      /* Simplify addition or subtraction of a constant by folding the
+         constant into X_add_number.  */
+      if (symp->sy_value.X_op == O_add
+	  || symp->sy_value.X_op == O_subtract)
+	{
+	  resolve_symbol_value (symp->sy_value.X_add_symbol);
+	  resolve_symbol_value (symp->sy_value.X_op_symbol);
+	  if (S_GET_SEGMENT (symp->sy_value.X_op_symbol) == absolute_section)
+	    {
+	      right = S_GET_VALUE (symp->sy_value.X_op_symbol);
+	      if (symp->sy_value.X_op == O_add)
+		symp->sy_value.X_add_number += right;
+	      else
+		symp->sy_value.X_add_number -= right;
+	      symp->sy_value.X_op = O_symbol;
+	      symp->sy_value.X_op_symbol = NULL;
+	    }
+	  else if ((S_GET_SEGMENT (symp->sy_value.X_add_symbol)
+		    == absolute_section)
+		   && symp->sy_value.X_op == O_add)
+	    {
+	      left = S_GET_VALUE (symp->sy_value.X_add_symbol);
+	      symp->sy_value.X_add_symbol = symp->sy_value.X_op_symbol;
+	      symp->sy_value.X_add_number += left;
+	      symp->sy_value.X_op = O_symbol;
+	      symp->sy_value.X_op_symbol = NULL;
+	    }
+	}
+
       switch (symp->sy_value.X_op)
 	{
 	case O_absent:
@@ -708,39 +736,6 @@
 	  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:
@@ -750,6 +745,7 @@
 	case O_bit_or_not:
 	case O_bit_exclusive_or:
 	case O_bit_and:
+	case O_add:
 	case O_subtract:
 	case O_eq:
 	case O_ne:
@@ -763,38 +759,30 @@
 	  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)
-	    {
-	      char *file;
-	      unsigned int line;
+	  left = S_GET_VALUE (symp->sy_value.X_add_symbol);
+	  right = S_GET_VALUE (symp->sy_value.X_op_symbol);
 
-	      if (expr_symbol_where (symp, &file, &line))
-		as_bad_where
-		  (file, line,
-		   "illegal operation on symbols in different sections");
-	      else
-		as_bad
-		  ("%s set to illegal 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)
+	  /* Subtraction is permitted if both operands are in the same
+	     section.  Otherwise, both operands must be absolute.  We
+	     already handled the case of addition or subtraction of a
+	     constant above.  This will probably need to be changed
+	     for an object file format which supports arbitrary
+	     expressions, such as IEEE-695.  */
+	  if ((seg_left != absolute_section
+	       || seg_right != absolute_section)
+	      && (symp->sy_value.X_op != O_subtract
+		  || seg_left != seg_right))
 	    {
 	      char *file;
 	      unsigned int line;
 
 	      if (expr_symbol_where (symp, &file, &line))
-		as_bad_where (file, line,
-			      "illegal operation on non-absolute symbols");
+		as_bad_where (file, line, "invalid section for operation");
 	      else
-		as_bad ("%s set to illegal operation on non-absolute symbols",
+		as_bad ("invalid section for operation setting %s",
 			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;


      reply	other threads:[~1996-08-07 12:34 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1996-08-05  9:31 Richard Earnshaw
1996-08-07 12:34 ` Ian Lance Taylor [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=199608071934.PAA24880@sanguine.cygnus.com \
    --to=ian@cygnus.com \
    --cc=gas2@cygnus.com \
    --cc=raeburn@cygnus.com \
    --cc=richard.earnshaw@armltd.co.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).