summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eval.c52
-rw-r--r--macros/ifunc.mac46
-rw-r--r--nasm.h8
-rw-r--r--tokens.dat6
4 files changed, 110 insertions, 2 deletions
diff --git a/eval.c b/eval.c
index e526723..d7cf844 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 0000000..fc0d313
--- /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 f7dd060..7422635 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 bb5fccb..c2df469 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