From 2e53f7d6010d59f1ea82d55dbe3ba41e5c460ae3 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 15 Aug 2013 07:30:15 +0000 Subject: [PATCH] * 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. * 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 | 8 ++++++++ ld/NEWS | 2 ++ ld/ld.texinfo | 5 +++++ ld/ldexp.c | 31 ++++++++++++++++++++++++++--- ld/ldgram.y | 4 +++- ld/ldlex.l | 1 + ld/testsuite/ChangeLog | 6 ++++++ ld/testsuite/ld-scripts/log2.exp | 34 ++++++++++++++++++++++++++++++++ ld/testsuite/ld-scripts/log2.s | 1 + ld/testsuite/ld-scripts/log2.t | 8 ++++++++ 10 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 ld/testsuite/ld-scripts/log2.exp create mode 100644 ld/testsuite/ld-scripts/log2.s create mode 100644 ld/testsuite/ld-scripts/log2.t diff --git a/ld/ChangeLog b/ld/ChangeLog index 4af9fca38d2..eef4ca813dd 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2013-08-14 Clemens Lang + + * 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 * ldgram.y: Add ALIGN_WITH_INPUT output section attribute. diff --git a/ld/NEWS b/ld/NEWS index d79c78fae6c..512003692fc 100644 --- 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. diff --git a/ld/ld.texinfo b/ld/ld.texinfo index 986194bbc1f..00a0fa4339d 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -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}. diff --git a/ld/ldexp.c b/ld/ldexp.c index ae3919b5502..49e7c65f417 100644 --- a/ld/ldexp.c +++ b/ld/ldexp.c @@ -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 . 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; diff --git a/ld/ldgram.y b/ld/ldgram.y index 26cb6772995..1ded4e73079 100644 --- a/ld/ldgram.y +++ b/ld/ldgram.y @@ -148,7 +148,7 @@ static int error_index; %type assign_op atype attributes_opt sect_constraint opt_align_with_input %type 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 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); } ; diff --git a/ld/ldlex.l b/ld/ldlex.l index 75be86d7de1..1695c278a46 100644 --- a/ld/ldlex.l +++ b/ld/ldlex.l @@ -257,6 +257,7 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* "ALIGNOF" { RTOKEN(ALIGNOF); } "MAX" { RTOKEN(MAX_K); } "MIN" { RTOKEN(MIN_K); } +"LOG2CEIL" { RTOKEN(LOG2CEIL); } "ASSERT" { RTOKEN(ASSERT_K); } "ENTRY" { RTOKEN(ENTRY);} "EXTERN" { RTOKEN(EXTERN);} diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 9d163ec6a2d..ecff1d35c0b 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-08-14 Clemens Lang + + * 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 PR ld/15787 diff --git a/ld/testsuite/ld-scripts/log2.exp b/ld/testsuite/ld-scripts/log2.exp new file mode 100644 index 00000000000..43827dce3b4 --- /dev/null +++ b/ld/testsuite/ld-scripts/log2.exp @@ -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 index 00000000000..f3f74ab685a --- /dev/null +++ b/ld/testsuite/ld-scripts/log2.s @@ -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 index 00000000000..abf73a9a47e --- /dev/null +++ b/ld/testsuite/ld-scripts/log2.t @@ -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"); -- 2.30.2