* ldexp.c: Add LOG2CEIL() builtin function to linker script language
authorNick Clifton <nickc@redhat.com>
Thu, 15 Aug 2013 07:30:15 +0000 (07:30 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 15 Aug 2013 07:30:15 +0000 (07:30 +0000)
* ldgram.y: Likewise
* ldlex.l: Likewise
* NEWS: Mention the new feature.
* ld.texinfo: Document the new feature.

* ld-scripts/log2.exp: New: Run the new log2 test.
* ld-scripts/log2.s: Source for the new test.
* ld-scripts/log2.t: Linker script for new test.

ld/ChangeLog
ld/NEWS
ld/ld.texinfo
ld/ldexp.c
ld/ldgram.y
ld/ldlex.l
ld/testsuite/ChangeLog
ld/testsuite/ld-scripts/log2.exp [new file with mode: 0644]
ld/testsuite/ld-scripts/log2.s [new file with mode: 0644]
ld/testsuite/ld-scripts/log2.t [new file with mode: 0644]

index 4af9fca38d249eb32d5a611187a51d4e8e3bd275..eef4ca813dd5114ac88cd4984e70e71b3644875a 100644 (file)
@@ -1,3 +1,11 @@
+2013-08-14  Clemens Lang  <clemens.lang@fau.de>
+
+       * ldexp.c: Add LOG2CEIL() builtin function to linker script language
+       * ldgram.y: Likewise
+       * ldlex.l: Likewise
+       * NEWS: Mention the new feature.
+       * ld.texinfo: Document the new feature.
+
 2013-07-19  Sebastian Huber  <sebastian.huber@embedded-brains.de>
 
        * ldgram.y: Add ALIGN_WITH_INPUT output section attribute.
diff --git a/ld/NEWS b/ld/NEWS
index d79c78fae6cbb5e8b4a8cd81705af0b0ed547c92..512003692fc78f4823ff32aa02d3c256b73b6871 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,7 @@
 -*- text -*-
 
+* Add LOG2CEIL() builtin function to the linker script language
+
 * Add support for the Texas Instruments MSP430X processor.
 
 * Add support for Altera Nios II.
index 986194bbc1fcd597b2e3e5cfd94c23eeb24bc715..00a0fa4339df3db16f206ae5c439df4e4402ada4 100644 (file)
@@ -5947,6 +5947,11 @@ Return the length of the memory region named @var{memory}.
 Return the absolute LMA of the named @var{section}.  (@pxref{Output
 Section LMA}).
 
+@item LOG2CEIL(@var{exp})
+@kindex LOG2CEIL(@var{exp})
+Return the binary logarithm of @var{exp} rounded towards infinity.
+@code{LOG2CEIL(0)} returns 0.
+
 @kindex MAX
 @item MAX(@var{exp1}, @var{exp2})
 Returns the maximum of @var{exp1} and @var{exp2}.
index ae3919b5502a762d13cecd15f4b6d4678928b97e..49e7c65f4176f1d5990ec856a433e30fb978c385 100644 (file)
@@ -1,7 +1,5 @@
 /* This module handles expression trees.
-   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
-   Free Software Foundation, Inc.
+   Copyright 1991-2013 Free Software Foundation, Inc.
    Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
 
    This file is part of the GNU Binutils.
@@ -81,6 +79,7 @@ exp_print_token (token_code_type code, int infix_p)
     { GE, ">=" },
     { LSHIFT, "<<" },
     { RSHIFT, ">>" },
+    { LOG2CEIL, "LOG2CEIL" },
     { ALIGN_K, "ALIGN" },
     { BLOCK, "BLOCK" },
     { QUAD, "QUAD" },
@@ -134,6 +133,28 @@ exp_print_token (token_code_type code, int infix_p)
     fputc (' ', config.map_file);
 }
 
+static void
+make_log2ceil (void)
+{
+  bfd_vma value = expld.result.value;
+  bfd_vma result = -1;
+  bfd_boolean round_up = FALSE;
+
+  do
+    {
+      result++;
+      /* If more than one bit is set in the value we will need to round up.  */
+      if ((value > 1) && (value & 1))
+       round_up = TRUE;
+    }
+  while (value >>= 1);
+
+  if (round_up)
+    result += 1;
+  expld.result.section = NULL;
+  expld.result.value = result;
+}
+
 static void
 make_abs (void)
 {
@@ -242,6 +263,10 @@ fold_unary (etree_type *tree)
          make_abs ();
          break;
 
+       case LOG2CEIL:
+         make_log2ceil ();
+         break;
+
        case '~':
          expld.result.value = ~expld.result.value;
          break;
index 26cb6772995743224e17ae5601c332857ab77016..1ded4e730792ac6b05af56351040461e9e9270b9 100644 (file)
@@ -148,7 +148,7 @@ static int error_index;
 %type <token> assign_op atype attributes_opt sect_constraint opt_align_with_input
 %type <name>  filename
 %token CHIP LIST SECT ABSOLUTE  LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K
-%token FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
+%token LOG2CEIL FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL
 %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START
 %token <name> VERS_TAG VERS_IDENTIFIER
 %token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT
@@ -1010,6 +1010,8 @@ exp       :
                        { $$ = exp_nameop (ORIGIN, $3); }
        |       LENGTH '(' NAME ')'
                        { $$ = exp_nameop (LENGTH, $3); }
+       |       LOG2CEIL '(' exp ')'
+                       { $$ = exp_unop (LOG2CEIL, $3); }
        ;
 
 
index 75be86d7de1756d134c9c55cfe52d87d4b97495b..1695c278a46014212803422df73089f4f9f616b4 100644 (file)
@@ -257,6 +257,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
 <EXPRESSION,BOTH,SCRIPT>"ALIGNOF"      { RTOKEN(ALIGNOF); }
 <EXPRESSION,BOTH>"MAX"                 { RTOKEN(MAX_K); }
 <EXPRESSION,BOTH>"MIN"                 { RTOKEN(MIN_K); }
+<EXPRESSION,BOTH>"LOG2CEIL"            { RTOKEN(LOG2CEIL); }
 <EXPRESSION,BOTH,SCRIPT>"ASSERT"       { RTOKEN(ASSERT_K); }
 <BOTH,SCRIPT>"ENTRY"                   { RTOKEN(ENTRY);}
 <BOTH,SCRIPT,MRI>"EXTERN"              { RTOKEN(EXTERN);}
index 9d163ec6a2da2f2d56266a9b8c0884898ab9bf41..ecff1d35c0b0cb897ede268f3d2c4799422e519c 100644 (file)
@@ -1,3 +1,9 @@
+2013-08-14  Clemens Lang  <clemens.lang@fau.de>
+
+       * ld-scripts/log2.exp: New: Run the new log2 test.
+       * ld-scripts/log2.s: Source for the new test.
+       * ld-scripts/log2.t: Linker script for new test.
+
 2013-08-14  John Tytgat  <john@bass-software.com>
 
        PR ld/15787
diff --git a/ld/testsuite/ld-scripts/log2.exp b/ld/testsuite/ld-scripts/log2.exp
new file mode 100644 (file)
index 0000000..43827dc
--- /dev/null
@@ -0,0 +1,34 @@
+# Test LOG2() expression in linker script language.
+# By Clemens Lang
+#   Copyright 2013
+#   Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+set testname "binary logarithm"
+
+if {![ld_assemble $as $srcdir/$subdir/log2.s tmpdir/log2.o]} {
+       unresolved $testname
+       return
+}
+
+if {![ld_simple_link $ld tmpdir/log2 "-T $srcdir/$subdir/log2.t tmpdir/log2.o"]} {
+       fail $testname
+} else {
+       pass $testname
+}
diff --git a/ld/testsuite/ld-scripts/log2.s b/ld/testsuite/ld-scripts/log2.s
new file mode 100644 (file)
index 0000000..f3f74ab
--- /dev/null
@@ -0,0 +1 @@
+       .word 0
diff --git a/ld/testsuite/ld-scripts/log2.t b/ld/testsuite/ld-scripts/log2.t
new file mode 100644 (file)
index 0000000..abf73a9
--- /dev/null
@@ -0,0 +1,8 @@
+ASSERT(LOG2CEIL(0) == 0,      "LOG2CEIL(0) == 0");
+ASSERT(LOG2CEIL(1) == 0,      "LOG2CEIL(1) == 0");
+ASSERT(LOG2CEIL(2) == 1,      "LOG2CEIL(2) == 1");
+ASSERT(LOG2CEIL(3) == 2,      "LOG2CEIL(3) == 2");
+ASSERT(LOG2CEIL(4) == 2,      "LOG2CEIL(4) == 2");
+ASSERT(LOG2CEIL(0x0ff) == 8,  "LOG2CEIL(0x0ff) == 8");
+ASSERT(LOG2CEIL(0x100) == 8,  "LOG2CEIL(0x100) == 8");
+ASSERT(LOG2CEIL(0x1ff) == 9,  "LOG2CEIL(0x1ff) == 9");