PR gas/11867
authorAlan Modra <amodra@gmail.com>
Mon, 2 Aug 2010 13:19:44 +0000 (13:19 +0000)
committerAlan Modra <amodra@gmail.com>
Mon, 2 Aug 2010 13:19:44 +0000 (13:19 +0000)
* expr.c (operand <'-' and '~'>): Widen bignums.
(operand <'!'>): Correct bignum result and convert to O_constant.
* read.c (emit_expr): Don't assert on .byte bignum.  Don't display
bignum truncated warning for sign extended bignums.

gas/ChangeLog
gas/expr.c
gas/read.c

index 7a76619..ccab9d3 100644 (file)
@@ -1,5 +1,13 @@
 2010-08-02  Alan Modra  <amodra@gmail.com>
 
+       PR gas/11867
+       * expr.c (operand <'-' and '~'>): Widen bignums.
+       (operand <'!'>): Correct bignum result and convert to O_constant.
+       * read.c (emit_expr): Don't assert on .byte bignum.  Don't display
+       bignum truncated warning for sign extended bignums.
+
+2010-08-02  Alan Modra  <amodra@gmail.com>
+
        * config/tc-v850.c (md_assemble): Always pass format string to
        as_warn.
        (md_apply_fix): Similarly for as_warn_where.
index a6910bf..53952b5 100644 (file)
@@ -1056,6 +1056,15 @@ operand (expressionS *expressionP, enum expr_mode mode)
              {
                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)
                    {
@@ -1066,14 +1075,12 @@ operand (expressionS *expressionP, enum expr_mode mode)
              }
            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
index 92371b7..bd3fa58 100644 (file)
@@ -4263,15 +4263,32 @@ emit_expr (expressionS *exp, unsigned int nbytes)
       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)