Stop print_hex from printing bits above the precision
authorRichard Sandiford <richard.sandiford@linaro.org>
Thu, 26 Oct 2017 16:09:17 +0000 (16:09 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 26 Oct 2017 16:09:17 +0000 (16:09 +0000)
2017-10-26  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
* wide-int-print.cc (print_hex): Loop based on extract_uhwi.
Don't print any bits outside the precision of the value.
* wide-int.cc (test_printing): Add some new tests.

From-SVN: r254109

gcc/ChangeLog
gcc/wide-int-print.cc
gcc/wide-int.cc

index 95d9e39a43e34f8662a756126f1c627ac6a002ed..9cf528c433592b43dde37ac8cfa50a1fbd3ce13c 100644 (file)
@@ -1,3 +1,9 @@
+2017-10-26  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * wide-int-print.cc (print_hex): Loop based on extract_uhwi.
+       Don't print any bits outside the precision of the value.
+       * wide-int.cc (test_printing): Add some new tests.
+
 2017-10-26  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * configure.ac (gcc_cv_as_ix86_xbrace_comment): Check if assembler
index 36d8ad863f5192767c68700fe03609647bf281fb..8874e81968516c694cd747b384dfa29416d54055 100644 (file)
@@ -103,30 +103,28 @@ print_decu (const wide_int_ref &wi, FILE *file)
 }
 
 void
-print_hex (const wide_int_ref &wi, char *buf)
+print_hex (const wide_int_ref &val, char *buf)
 {
-  int i = wi.get_len ();
-
-  if (wi == 0)
+  if (val == 0)
     buf += sprintf (buf, "0x0");
   else
     {
-      if (wi::neg_p (wi))
+      buf += sprintf (buf, "0x");
+      int start = ROUND_DOWN (val.get_precision (), HOST_BITS_PER_WIDE_INT);
+      int width = val.get_precision () - start;
+      bool first_p = true;
+      for (int i = start; i >= 0; i -= HOST_BITS_PER_WIDE_INT)
        {
-         int j;
-         /* If the number is negative, we may need to pad value with
-            0xFFF...  because the leading elements may be missing and
-            we do not print a '-' with hex.  */
-         buf += sprintf (buf, "0x");
-         for (j = BLOCKS_NEEDED (wi.get_precision ()); j > i; j--)
-           buf += sprintf (buf, HOST_WIDE_INT_PRINT_PADDED_HEX, HOST_WIDE_INT_M1);
-
+         unsigned HOST_WIDE_INT uhwi = wi::extract_uhwi (val, i, width);
+         if (!first_p)
+           buf += sprintf (buf, HOST_WIDE_INT_PRINT_PADDED_HEX, uhwi);
+         else if (uhwi != 0)
+           {
+             buf += sprintf (buf, HOST_WIDE_INT_PRINT_HEX_PURE, uhwi);
+             first_p = false;
+           }
+         width = HOST_BITS_PER_WIDE_INT;
        }
-      else
-       buf += sprintf (buf, "0x" HOST_WIDE_INT_PRINT_HEX_PURE, wi.elt (--i));
-
-      while (--i >= 0)
-       buf += sprintf (buf, HOST_WIDE_INT_PRINT_PADDED_HEX, wi.elt (i));
     }
 }
 
index 1a1a68c19436c0b41f280af96f8702e61d0c3b60..ba0fd25b093fdf688e19c5f8583ed0189206ba23 100644 (file)
@@ -2253,6 +2253,17 @@ test_printing ()
   VALUE_TYPE a = from_int<VALUE_TYPE> (42);
   assert_deceq ("42", a, SIGNED);
   assert_hexeq ("0x2a", a);
+  assert_hexeq ("0x1fffffffffffffffff", wi::shwi (-1, 69));
+  assert_hexeq ("0xffffffffffffffff", wi::mask (64, false, 69));
+  assert_hexeq ("0xffffffffffffffff", wi::mask <widest_int> (64, false));
+  if (WIDE_INT_MAX_PRECISION > 128)
+    {
+      assert_hexeq ("0x20000000000000000fffffffffffffffe",
+                   wi::lshift (1, 129) + wi::lshift (1, 64) - 2);
+      assert_hexeq ("0x200000000000004000123456789abcdef",
+                   wi::lshift (1, 129) + wi::lshift (1, 74)
+                   + wi::lshift (0x1234567, 32) + 0x89abcdef);
+    }
 }
 
 /* Verify that various operations work correctly for VALUE_TYPE,