aboutsummaryrefslogtreecommitdiff
path: root/ld/ldexp.c
diff options
context:
space:
mode:
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;