diff options
author | H. Peter Anvin <hpa@zytor.com> | 2007-09-24 12:30:54 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2007-09-24 12:30:54 -0700 |
commit | dc467ba8af91f21994e10bedd133f4423e14862b (patch) | |
tree | 6cd105090380ba3b7011a21bcf6329b26aaddd6c /eval.c | |
parent | 5f77c031fa39bb96ce2240fbfd1c5465e1208e09 (diff) | |
download | nasm-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.c | 59 |
1 files changed, 59 insertions, 0 deletions
@@ -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); |