aboutsummaryrefslogtreecommitdiff
path: root/ld/ldexp.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2013-08-15 07:30:15 +0000
committerNick Clifton <nickc@redhat.com>2013-08-15 07:30:15 +0000
commit2e53f7d6010d59f1ea82d55dbe3ba41e5c460ae3 (patch)
tree510c2984267e3a436846b3634a33fc9cb5268b38 /ld/ldexp.c
parentdbdf691ab9456824b7650f56186e1569335c6235 (diff)
downloadgdb-2e53f7d6010d59f1ea82d55dbe3ba41e5c460ae3.zip
gdb-2e53f7d6010d59f1ea82d55dbe3ba41e5c460ae3.tar.gz
gdb-2e53f7d6010d59f1ea82d55dbe3ba41e5c460ae3.tar.bz2
* 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.
Diffstat (limited to 'ld/ldexp.c')
-rw-r--r--ld/ldexp.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/ld/ldexp.c b/ld/ldexp.c
index ae3919b..49e7c65 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 <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" },
@@ -135,6 +134,28 @@ exp_print_token (token_code_type code, int infix_p)
}
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)
{
if (expld.result.section != NULL)
@@ -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;