This patch ensure same output for sleb128 with large number.
authorTristan Gingold <gingold@adacore.com>
Mon, 9 Jan 2017 14:50:32 +0000 (15:50 +0100)
committerTristan Gingold <gingold@adacore.com>
Tue, 10 Jan 2017 09:23:23 +0000 (10:23 +0100)
gas/
* read.c (emit_leb128_expr): Extended unsigned big number for
sleb128.
* testsuite/gas/all/gas.exp (test_cond): Add sleb128-8 test.
* testsuite/gas/all/sleb128.d: New test.
* testsuite/gas/all/sleb128.s: New test source.

gas/ChangeLog
gas/read.c
gas/testsuite/gas/all/gas.exp
gas/testsuite/gas/all/sleb128-8.d [new file with mode: 0644]
gas/testsuite/gas/all/sleb128-8.s [new file with mode: 0644]

index 0fab5fb..4d364ab 100644 (file)
@@ -1,3 +1,11 @@
+2017-01-10  Tristan Gingold  <gingold@adacore.com>
+
+       * read.c (emit_leb128_expr): Extended unsigned big number for
+       sleb128.
+       * testsuite/gas/all/gas.exp (test_cond): Add sleb128-8 test.
+       * testsuite/gas/all/sleb128.d: New test.
+       * testsuite/gas/all/sleb128.s: New test source.
+
 2017-01-09  Andrew Waterman <andrew@sifive.com>
 
        * config/tc-riscv.c (append_insn): Don't eagerly apply relocations
index 5c0d320..3669b28 100644 (file)
@@ -5344,13 +5344,21 @@ emit_leb128_expr (expressionS *exp, int sign)
   else if (op == O_big)
     {
       /* O_big is a different sort of constant.  */
-
+      int nbr_digits = exp->X_add_number;
       unsigned int size;
       char *p;
 
-      size = output_big_leb128 (NULL, generic_bignum, exp->X_add_number, sign);
+      /* If the leading littenum is 0xffff, prepend a 0 to avoid confusion with
+        a signed number.  Unary operators like - or ~ always extend the
+        bignum to its largest size.  */
+      if (exp->X_unsigned
+         && nbr_digits < SIZE_OF_LARGE_NUMBER
+         && generic_bignum[nbr_digits - 1] == LITTLENUM_MASK)
+       generic_bignum[nbr_digits++] = 0;
+
+      size = output_big_leb128 (NULL, generic_bignum, nbr_digits, sign);
       p = frag_more (size);
-      if (output_big_leb128 (p, generic_bignum, exp->X_add_number, sign) > size)
+      if (output_big_leb128 (p, generic_bignum, nbr_digits, sign) > size)
        abort ();
     }
   else
index 8f97ed8..6b5aec0 100644 (file)
@@ -393,6 +393,7 @@ run_dump_test sleb128-5
 if { ![istarget "tic4x*-*-*"] && ![istarget "tic54x*-*-*"] } {
     run_dump_test sleb128-7
 }
+run_dump_test sleb128-8
 
 # .byte is 32 bits on tic4x, and .p2align isn't supported on tic54x
 # .space is different on hppa*-hpux.
diff --git a/gas/testsuite/gas/all/sleb128-8.d b/gas/testsuite/gas/all/sleb128-8.d
new file mode 100644 (file)
index 0000000..793337c
--- /dev/null
@@ -0,0 +1,7 @@
+#objdump : -s -j .data -j "\$DATA\$"
+#name : .sleb128 tests (8)
+
+.*: .*
+
+Contents of section (\.data|\$DATA\$):
+ 0000 ffffffff ffff3f .*
diff --git a/gas/testsuite/gas/all/sleb128-8.s b/gas/testsuite/gas/all/sleb128-8.s
new file mode 100644 (file)
index 0000000..ab3e785
--- /dev/null
@@ -0,0 +1,2 @@
+       .data
+       .sleb128 281474976710655