* 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.
This commit is contained in:
Nick Clifton 2013-08-15 07:30:15 +00:00
parent dbdf691ab9
commit 2e53f7d601
10 changed files with 96 additions and 4 deletions

View 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.

View File

@ -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.

View 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}.

View 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;

View 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); }
;

View 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);}

View 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

View File

@ -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
}

View File

@ -0,0 +1 @@
.word 0

View File

@ -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");