summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-09-24 12:30:54 -0700
committerH. Peter Anvin <hpa@zytor.com>2007-09-24 12:30:54 -0700
commitdc467ba8af91f21994e10bedd133f4423e14862b (patch)
tree6cd105090380ba3b7011a21bcf6329b26aaddd6c /eval.c
parent5f77c031fa39bb96ce2240fbfd1c5465e1208e09 (diff)
downloadnasm-dc467ba8af91f21994e10bedd133f4423e14862b.tar.gz
nasm-dc467ba8af91f21994e10bedd133f4423e14862b.tar.bz2
nasm-dc467ba8af91f21994e10bedd133f4423e14862b.zip
Support __float*__ for floating-point numbers in expressions
Add special operators to allow the use of floating-point constants in contexts other than DW/DD/DQ/DT/DO. As part of this checkin, make MAX_KEYWORD generated by tokhash.pl, since it knows what all the keywords are so it can tell which one is the longest.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/eval.c b/eval.c
index 644929d..a75c5ba 100644
--- a/eval.c
+++ b/eval.c
@@ -19,6 +19,7 @@
#include "nasmlib.h"
#include "eval.h"
#include "labels.h"
+#include "float.h"
#define TEMPEXPRS_DELTA 128
#define TEMPEXPR_DELTA 8
@@ -603,6 +604,61 @@ static expr *expr5(int critical)
return e;
}
+static expr *eval_floatize(enum floatize type)
+{
+ uint8_t result[16], *p; /* Up to 128 bits */
+ static const struct {
+ int bytes, start, len;
+ } formats[] = {
+ { 2, 0, 2 }, /* FLOAT_16 */
+ { 4, 0, 4 }, /* FLOAT_32 */
+ { 8, 0, 8 }, /* FLOAT_64 */
+ { 10, 0, 8 }, /* FLOAT_80M */
+ { 10, 8, 2 }, /* FLOAT_80E */
+ { 16, 0, 8 }, /* FLOAT_128L */
+ { 16, 8, 8 }, /* FLOAT_128H */
+ };
+ int sign = 1;
+ int64_t val;
+ int j;
+
+ i = scan(scpriv, tokval);
+ if (i != '(') {
+ error(ERR_NONFATAL, "expecting `('");
+ return NULL;
+ }
+ i = scan(scpriv, tokval);
+ if (i == '-' || i == '+') {
+ sign = (i == '-') ? -1 : 1;
+ i = scan(scpriv, tokval);
+ }
+ if (i != TOKEN_FLOAT) {
+ error(ERR_NONFATAL, "expecting floating-point number");
+ return NULL;
+ }
+ if (!float_const(tokval->t_charptr, sign, result,
+ formats[type].bytes, error))
+ return NULL;
+ i = scan(scpriv, tokval);
+ if (i != ')') {
+ error(ERR_NONFATAL, "expecting `)'");
+ return NULL;
+ }
+
+ p = result+formats[type].start+formats[type].len;
+ val = 0;
+ for (j = formats[type].len; j; j--) {
+ p--;
+ val = (val << 8) + *p;
+ }
+
+ begintemp();
+ addtotemp(EXPR_SIMPLE, val);
+
+ i = scan(scpriv, tokval);
+ return finishtemp();
+}
+
static expr *expr6(int critical)
{
int32_t type;
@@ -664,6 +720,9 @@ static expr *expr6(int critical)
}
return e;
+ case TOKEN_FLOATIZE:
+ return eval_floatize(tokval->t_integer);
+
case '(':
i = scan(scpriv, tokval);
e = bexpr(critical);