From 290b4cb3a4d32ec8260e88b4e67fc968cf9adb5e Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Thu, 31 May 2012 10:25:37 -0700 Subject: [PATCH] eval: add general support for "integer functions" and add ilog2*() Add general support in the function parser for "integer functions" (actually implemented as special unary operators, then wrapped in macros) and implement a family of integer logarithms. The only difference is the behavior on a non-power-of-two argument: ilog2[e] -- throw an error ilog2w -- throw a warning ilog2f -- round down to power of 2 ilog2c -- round up to power of 2 This is useful for back-converting from masks to bit values. Signed-off-by: H. Peter Anvin --- eval.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- macros/ifunc.mac | 46 ++++++++++++++++++++++++++++++++++++++++++++++ nasm.h | 8 ++++++++ tokens.dat | 6 ++++++ 4 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 macros/ifunc.mac diff --git a/eval.c b/eval.c index e5267237..d7cf844e 100644 --- a/eval.c +++ b/eval.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2009 The NASM Authors - All Rights Reserved + * Copyright 1996-2012 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -274,7 +274,7 @@ static expr *segment_part(expr * e) * expr3 : expr4 [ {<<,>>} expr4...] * expr4 : expr5 [ {+,-} expr5...] * expr5 : expr6 [ {*,/,%,//,%%} expr6...] - * expr6 : { ~,+,-,SEG } expr6 + * expr6 : { ~,+,-,IFUNC,SEG } expr6 * | (bexpr) * | symbol * | $ @@ -732,6 +732,37 @@ static expr *eval_strfunc(enum strfunc type) return finishtemp(); } +static int64_t eval_ifunc(int64_t val, enum ifunc func) +{ + int errtype; + uint64_t uval = (uint64_t)val; + int64_t rv; + + switch (func) { + case IFUNC_ILOG2E: + case IFUNC_ILOG2W: + errtype = (func == IFUNC_ILOG2E) ? ERR_NONFATAL : ERR_WARNING; + + if ((!uval) | (uval & (uval-1))) + error(errtype, "ilog2 argument is not a power of two"); + /* fall through */ + case IFUNC_ILOG2F: + rv = ilog2_64(uval); + break; + + case IFUNC_ILOG2C: + rv = (uval < 2) ? 0 : ilog2_64(uval-1) + 1; + break; + + default: + error(ERR_PANIC, "invalid IFUNC token %d", func); + rv = 0; + break; + } + + return rv; +} + static expr *expr6(int critical) { int32_t type; @@ -782,6 +813,23 @@ static expr *expr6(int critical) } return scalarvect(!reloc_value(e)); + case TOKEN_IFUNC: + { + enum ifunc func = tokval->t_integer; + i = scan(scpriv, tokval); + e = expr6(critical); + if (!e) + return NULL; + if (is_just_unknown(e)) + return unknown_expr(); + else if (!is_simple(e)) { + error(ERR_NONFATAL, "function may only be applied to" + " scalar values"); + return NULL; + } + return scalarvect(eval_ifunc(reloc_value(e), func)); + } + case TOKEN_SEG: i = scan(scpriv, tokval); e = expr6(critical); diff --git a/macros/ifunc.mac b/macros/ifunc.mac new file mode 100644 index 00000000..fc0d313e --- /dev/null +++ b/macros/ifunc.mac @@ -0,0 +1,46 @@ +;; -------------------------------------------------------------------------- +;; +;; Copyright 2012 The NASM Authors - All Rights Reserved +;; See the file AUTHORS included with the NASM distribution for +;; the specific copyright holders. +;; +;; Redistribution and use in source and binary forms, with or without +;; modification, are permitted provided that the following +;; conditions are met: +;; +;; * Redistributions of source code must retain the above copyright +;; notice, this list of conditions and the following disclaimer. +;; * Redistributions in binary form must reproduce the above +;; copyright notice, this list of conditions and the following +;; disclaimer in the documentation and/or other materials provided +;; with the distribution. +;; +;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND +;; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +;; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +;; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +;; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +;; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +;; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +;; EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;; +;; -------------------------------------------------------------------------- + +;; +;; ifunc.mac +;; +;; Integer function utility macros +;; + +USE: ifunc + +%idefine ilog2(x) (__ilog2e__(x)) +%idefine ilog2e(x) (__ilog2e__(x)) +%idefine ilog2w(x) (__ilog2w__(x)) +%idefine ilog2f(x) (__ilog2f__(x)) +%idefine ilog2c(x) (__ilog2c__(x)) diff --git a/nasm.h b/nasm.h index f7dd0600..74226350 100644 --- a/nasm.h +++ b/nasm.h @@ -225,6 +225,7 @@ enum token_type { /* token types, other than chars */ TOKEN_WRT, /* WRT */ TOKEN_FLOATIZE, /* __floatX__ */ TOKEN_STRFUNC, /* __utf16*__, __utf32*__ */ + TOKEN_IFUNC, /* __ilog2*__ */ }; enum floatize { @@ -248,6 +249,13 @@ enum strfunc { STRFUNC_UTF32BE, }; +enum ifunc { + IFUNC_ILOG2E, + IFUNC_ILOG2W, + IFUNC_ILOG2F, + IFUNC_ILOG2C, +}; + size_t string_transform(char *, size_t, char **, enum strfunc); /* diff --git a/tokens.dat b/tokens.dat index bb5fccb0..c2df4699 100644 --- a/tokens.dat +++ b/tokens.dat @@ -97,6 +97,12 @@ __utf32__ __utf32le__ __utf32be__ +% TOKEN_IFUNC, 0, IFUNC_{__*__} +__ilog2e__ +__ilog2w__ +__ilog2f__ +__ilog2c__ + % TOKEN_*, 0, 0 seg wrt -- 2.11.4.GIT