Author: pfg
Date: Wed Dec 31 04:52:32 2014
New Revision: 276449
URL: https://svnweb.freebsd.org/changeset/base/276449

Log:
  MFC   r276229:
  Backport fix for binutils 11867: .quad directive not assembled correctly
  
  Alan Modra (and Alan's employer) graciously permitted use of his patch
  under GPLv2.
  
  Obtained from:        OpenBSD

Modified:
  stable/9/contrib/binutils/gas/expr.c
  stable/9/contrib/binutils/gas/read.c
Directory Properties:
  stable/9/contrib/binutils/   (props changed)

Modified: stable/9/contrib/binutils/gas/expr.c
==============================================================================
--- stable/9/contrib/binutils/gas/expr.c        Wed Dec 31 04:51:09 2014        
(r276448)
+++ stable/9/contrib/binutils/gas/expr.c        Wed Dec 31 04:52:32 2014        
(r276449)
@@ -1040,6 +1040,15 @@ operand (expressionS *expressionP, enum 
              {
                for (i = 0; i < expressionP->X_add_number; ++i)
                  generic_bignum[i] = ~generic_bignum[i];
+
+               /* Extend the bignum to at least the size of .octa.  */
+               if (expressionP->X_add_number < SIZE_OF_LARGE_NUMBER)
+                 {
+                   expressionP->X_add_number = SIZE_OF_LARGE_NUMBER;
+                   for (; i < expressionP->X_add_number; ++i)
+                     generic_bignum[i] = ~(LITTLENUM_TYPE) 0;
+                 }
+
                if (c == '-')
                  for (i = 0; i < expressionP->X_add_number; ++i)
                    {
@@ -1050,14 +1059,12 @@ operand (expressionS *expressionP, enum 
              }
            else if (c == '!')
              {
-               int nonzero = 0;
                for (i = 0; i < expressionP->X_add_number; ++i)
-                 {
-                   if (generic_bignum[i])
-                     nonzero = 1;
-                   generic_bignum[i] = 0;
-                 }
-               generic_bignum[0] = nonzero;
+                 if (generic_bignum[i] != 0)
+                   break;
+               expressionP->X_add_number = i >= expressionP->X_add_number;
+               expressionP->X_op = O_constant;
+               expressionP->X_unsigned = 1;
              }
          }
        else if (expressionP->X_op != O_illegal

Modified: stable/9/contrib/binutils/gas/read.c
==============================================================================
--- stable/9/contrib/binutils/gas/read.c        Wed Dec 31 04:51:09 2014        
(r276448)
+++ stable/9/contrib/binutils/gas/read.c        Wed Dec 31 04:52:32 2014        
(r276449)
@@ -4117,15 +4117,32 @@ emit_expr (expressionS *exp, unsigned in
       unsigned int size;
       LITTLENUM_TYPE *nums;
 
-      know (nbytes % CHARS_PER_LITTLENUM == 0);
-
       size = exp->X_add_number * CHARS_PER_LITTLENUM;
       if (nbytes < size)
        {
-         as_warn (_("bignum truncated to %d bytes"), nbytes);
+         int i = nbytes / CHARS_PER_LITTLENUM;
+         if (i != 0)
+           {
+             LITTLENUM_TYPE sign = 0;
+             if ((generic_bignum[--i]
+                  & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) != 0)
+               sign = ~(LITTLENUM_TYPE) 0;
+             while (++i < exp->X_add_number)
+               if (generic_bignum[i] != sign)
+                 break;
+           }
+         if (i < exp->X_add_number)
+           as_warn (_("bignum truncated to %d bytes"), nbytes);
          size = nbytes;
        }
 
+      if (nbytes == 1)
+       {
+         md_number_to_chars (p, (valueT) generic_bignum[0], 1);
+         return;
+       }
+      know (nbytes % CHARS_PER_LITTLENUM == 0);
+
       if (target_big_endian)
        {
          while (nbytes > size)
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to