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.
This commit is contained in:
H. Peter Anvin 2007-09-24 12:30:54 -07:00
parent 5f77c031fa
commit dc467ba8af
8 changed files with 600 additions and 135 deletions

View File

@ -118,9 +118,14 @@ regs.h: regs.dat regs.pl
# Assembler token hash
tokhash.c: insns.dat regs.dat tokens.dat tokhash.pl perllib/phash.ph
$(PERL) $(srcdir)/tokhash.pl $(srcdir)/insns.dat $(srcdir)/regs.dat \
$(PERL) $(srcdir)/tokhash.pl c $(srcdir)/insns.dat $(srcdir)/regs.dat \
$(srcdir)/tokens.dat > tokhash.c
# Assembler token metadata
tokens.h: insns.dat regs.dat tokens.dat tokhash.pl perllib/phash.ph
$(PERL) $(srcdir)/tokhash.pl h $(srcdir)/insns.dat $(srcdir)/regs.dat \
$(srcdir)/tokens.dat > tokens.h
# Preprocessor token hash
pptok.h: pptok.dat pptok.pl perllib/phash.ph
$(PERL) $(srcdir)/pptok.pl h $(srcdir)/pptok.dat pptok.h
@ -130,7 +135,7 @@ pptok.c: pptok.dat pptok.pl perllib/phash.ph
# This target generates all files that require perl.
# This allows easier generation of distribution (see dist target).
PERLREQ = macros.c insnsa.c insnsd.c insnsi.h insnsn.c \
regs.c regs.h regflags.c regdis.c regvals.c tokhash.c \
regs.c regs.h regflags.c regdis.c regvals.c tokhash.c tokens.h \
version.h version.mac pptok.h pptok.c
perlreq: $(PERLREQ)
@ -210,12 +215,13 @@ alldeps: perlreq
# @path-separator: "/"
#-- Everything below is generated by mkdep.pl - do not edit --#
assemble.$(O): assemble.c assemble.h compiler.h config.h insns.h insnsi.h \
nasm.h nasmlib.h pptok.h preproc.h regflags.c regs.h regvals.c version.h
nasm.h nasmlib.h pptok.h preproc.h regflags.c regs.h regvals.c tokens.h \
version.h
crc64.$(O): crc64.c
disasm.$(O): disasm.c compiler.h config.h disasm.h insns.h insnsi.h insnsn.c \
names.c nasm.h nasmlib.h regdis.c regs.c regs.h sync.h version.h
eval.$(O): eval.c compiler.h config.h eval.h insnsi.h labels.h nasm.h \
nasmlib.h regs.h version.h
names.c nasm.h nasmlib.h regdis.c regs.c regs.h sync.h tokens.h version.h
eval.$(O): eval.c compiler.h config.h eval.h float.h insnsi.h labels.h \
nasm.h nasmlib.h regs.h version.h
exprlib.$(O): exprlib.c compiler.h config.h insnsi.h nasm.h nasmlib.h regs.h \
version.h
float.$(O): float.c compiler.h config.h insnsi.h nasm.h nasmlib.h regs.h \
@ -223,9 +229,9 @@ float.$(O): float.c compiler.h config.h insnsi.h nasm.h nasmlib.h regs.h \
hashtbl.$(O): hashtbl.c compiler.h config.h hashtbl.h insnsi.h nasm.h \
nasmlib.h regs.h version.h
insnsa.$(O): insnsa.c compiler.h config.h insns.h insnsi.h nasm.h nasmlib.h \
regs.h version.h
regs.h tokens.h version.h
insnsd.$(O): insnsd.c compiler.h config.h insns.h insnsi.h nasm.h nasmlib.h \
regs.h version.h
regs.h tokens.h version.h
insnsn.$(O): insnsn.c
labels.$(O): labels.c compiler.h config.h hashtbl.h insnsi.h nasm.h \
nasmlib.h regs.h version.h
@ -235,11 +241,11 @@ macros.$(O): macros.c
names.$(O): names.c insnsn.c regs.c
nasm.$(O): nasm.c assemble.h compiler.h config.h eval.h insns.h insnsi.h \
labels.h listing.h nasm.h nasmlib.h outform.h parser.h pptok.h preproc.h \
regs.h stdscan.h version.h
regs.h stdscan.h tokens.h version.h
nasmlib.$(O): nasmlib.c compiler.h config.h insns.h insnsi.h nasm.h \
nasmlib.h regs.h version.h
nasmlib.h regs.h tokens.h version.h
ndisasm.$(O): ndisasm.c compiler.h config.h disasm.h insns.h insnsi.h nasm.h \
nasmlib.h regs.h sync.h version.h
nasmlib.h regs.h sync.h tokens.h version.h
outform.$(O): outform.c compiler.h config.h insnsi.h nasm.h nasmlib.h \
outform.h regs.h version.h
output/outaout.$(O): output/outaout.c compiler.h config.h insnsi.h nasm.h \
@ -267,7 +273,7 @@ output/outrdf.$(O): output/outrdf.c compiler.h config.h insnsi.h nasm.h \
output/outrdf2.$(O): output/outrdf2.c compiler.h config.h insnsi.h nasm.h \
nasmlib.h outform.h rdoff/rdoff.h regs.h version.h
parser.$(O): parser.c compiler.h config.h float.h insns.h insnsi.h nasm.h \
nasmlib.h parser.h regflags.c regs.h stdscan.h version.h
nasmlib.h parser.h regflags.c regs.h stdscan.h tokens.h version.h
pptok.$(O): pptok.c compiler.h config.h nasmlib.h pptok.h preproc.h
preproc.$(O): preproc.c compiler.h config.h hashtbl.h insnsi.h macros.c \
nasm.h nasmlib.h pptok.h preproc.h regs.h version.h
@ -276,7 +282,7 @@ regflags.$(O): regflags.c
regs.$(O): regs.c
regvals.$(O): regvals.c
stdscan.$(O): stdscan.c compiler.h config.h insns.h insnsi.h nasm.h \
nasmlib.h regs.h stdscan.h version.h
nasmlib.h regs.h stdscan.h tokens.h version.h
sync.$(O): sync.c compiler.h config.h nasmlib.h sync.h
tokhash.$(O): tokhash.c compiler.h config.h insns.h insnsi.h nasm.h \
nasmlib.h regs.h version.h
nasmlib.h regs.h tokens.h version.h

View File

@ -1,3 +1,5 @@
# -*- makefile -*-
#
# Makefile for building NASM using Microsoft Visual C++ and NMAKE.
# Tested on Microsoft Visual C++ 2005 Express Edition.
#
@ -95,9 +97,14 @@ regs.h: regs.dat regs.pl
# Assembler token hash
tokhash.c: insns.dat regs.dat tokens.dat tokhash.pl perllib/phash.ph
$(PERL) $(srcdir)/tokhash.pl $(srcdir)/insns.dat $(srcdir)/regs.dat \
$(PERL) $(srcdir)/tokhash.pl c $(srcdir)/insns.dat $(srcdir)/regs.dat \
$(srcdir)/tokens.dat > tokhash.c
# Assembler token metadata
tokens.h: insns.dat regs.dat tokens.dat tokhash.pl perllib/phash.ph
$(PERL) $(srcdir)/tokhash.pl h $(srcdir)/insns.dat $(srcdir)/regs.dat \
$(srcdir)/tokens.dat > tokens.h
# Preprocessor token hash
pptok.h: pptok.dat pptok.pl perllib/phash.ph
$(PERL) $(srcdir)/pptok.pl h $(srcdir)/pptok.dat pptok.h
@ -107,7 +114,7 @@ pptok.c: pptok.dat pptok.pl perllib/phash.ph
# This target generates all files that require perl.
# This allows easier generation of distribution (see dist target).
PERLREQ = macros.c insnsa.c insnsd.c insnsi.h insnsn.c \
regs.c regs.h regflags.c regdis.c regvals.c tokhash.c \
regs.c regs.h regflags.c regdis.c regvals.c tokhash.c tokens.h \
version.h version.mac pptok.h pptok.c
perlreq: $(PERLREQ)
@ -166,12 +173,13 @@ everything: all doc rdf
# @path-separator: "/"
#-- Everything below is generated by mkdep.pl - do not edit --#
assemble.$(O): assemble.c assemble.h compiler.h config.h insns.h insnsi.h \
nasm.h nasmlib.h pptok.h preproc.h regflags.c regs.h regvals.c version.h
nasm.h nasmlib.h pptok.h preproc.h regflags.c regs.h regvals.c tokens.h \
version.h
crc64.$(O): crc64.c
disasm.$(O): disasm.c compiler.h config.h disasm.h insns.h insnsi.h insnsn.c \
names.c nasm.h nasmlib.h regdis.c regs.c regs.h sync.h version.h
eval.$(O): eval.c compiler.h config.h eval.h insnsi.h labels.h nasm.h \
nasmlib.h regs.h version.h
names.c nasm.h nasmlib.h regdis.c regs.c regs.h sync.h tokens.h version.h
eval.$(O): eval.c compiler.h config.h eval.h float.h insnsi.h labels.h \
nasm.h nasmlib.h regs.h version.h
exprlib.$(O): exprlib.c compiler.h config.h insnsi.h nasm.h nasmlib.h regs.h \
version.h
float.$(O): float.c compiler.h config.h insnsi.h nasm.h nasmlib.h regs.h \
@ -179,9 +187,9 @@ float.$(O): float.c compiler.h config.h insnsi.h nasm.h nasmlib.h regs.h \
hashtbl.$(O): hashtbl.c compiler.h config.h hashtbl.h insnsi.h nasm.h \
nasmlib.h regs.h version.h
insnsa.$(O): insnsa.c compiler.h config.h insns.h insnsi.h nasm.h nasmlib.h \
regs.h version.h
regs.h tokens.h version.h
insnsd.$(O): insnsd.c compiler.h config.h insns.h insnsi.h nasm.h nasmlib.h \
regs.h version.h
regs.h tokens.h version.h
insnsn.$(O): insnsn.c
labels.$(O): labels.c compiler.h config.h hashtbl.h insnsi.h nasm.h \
nasmlib.h regs.h version.h
@ -191,11 +199,11 @@ macros.$(O): macros.c
names.$(O): names.c insnsn.c regs.c
nasm.$(O): nasm.c assemble.h compiler.h config.h eval.h insns.h insnsi.h \
labels.h listing.h nasm.h nasmlib.h outform.h parser.h pptok.h preproc.h \
regs.h stdscan.h version.h
regs.h stdscan.h tokens.h version.h
nasmlib.$(O): nasmlib.c compiler.h config.h insns.h insnsi.h nasm.h \
nasmlib.h regs.h version.h
nasmlib.h regs.h tokens.h version.h
ndisasm.$(O): ndisasm.c compiler.h config.h disasm.h insns.h insnsi.h nasm.h \
nasmlib.h regs.h sync.h version.h
nasmlib.h regs.h sync.h tokens.h version.h
outform.$(O): outform.c compiler.h config.h insnsi.h nasm.h nasmlib.h \
outform.h regs.h version.h
output/outaout.$(O): output/outaout.c compiler.h config.h insnsi.h nasm.h \
@ -223,7 +231,7 @@ output/outrdf.$(O): output/outrdf.c compiler.h config.h insnsi.h nasm.h \
output/outrdf2.$(O): output/outrdf2.c compiler.h config.h insnsi.h nasm.h \
nasmlib.h outform.h rdoff/rdoff.h regs.h version.h
parser.$(O): parser.c compiler.h config.h float.h insns.h insnsi.h nasm.h \
nasmlib.h parser.h regflags.c regs.h stdscan.h version.h
nasmlib.h parser.h regflags.c regs.h stdscan.h tokens.h version.h
pptok.$(O): pptok.c compiler.h config.h nasmlib.h pptok.h preproc.h
preproc.$(O): preproc.c compiler.h config.h hashtbl.h insnsi.h macros.c \
nasm.h nasmlib.h pptok.h preproc.h regs.h version.h
@ -232,7 +240,7 @@ regflags.$(O): regflags.c
regs.$(O): regs.c
regvals.$(O): regvals.c
stdscan.$(O): stdscan.c compiler.h config.h insns.h insnsi.h nasm.h \
nasmlib.h regs.h stdscan.h version.h
nasmlib.h regs.h stdscan.h tokens.h version.h
sync.$(O): sync.c compiler.h config.h nasmlib.h sync.h
tokhash.$(O): tokhash.c compiler.h config.h insns.h insnsi.h nasm.h \
nasmlib.h regs.h version.h
nasmlib.h regs.h tokens.h version.h

59
eval.c
View File

@ -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);

View File

@ -10,13 +10,7 @@
#define NASM_INSNS_H
#include "nasm.h"
/* max length of any instruction, register name etc. */
#if MAX_INSLEN > 12 /* MAX_INSLEN defined in insnsi.h */
#define MAX_KEYWORD MAX_INSLEN
#else
#define MAX_KEYWORD 12
#endif
#include "tokens.h"
struct itemplate {
enum opcode opcode; /* the token, passed from "parser.c" */

13
nasm.h
View File

@ -175,7 +175,18 @@ enum { /* token types, other than chars */
TOKEN_GE, TOKEN_LE, TOKEN_NE, /* >=, <= and <> (!= is same as <>) */
TOKEN_DBL_AND, TOKEN_DBL_OR, TOKEN_DBL_XOR, /* &&, || and ^^ */
TOKEN_SEG, TOKEN_WRT, /* SEG and WRT */
TOKEN_FLOAT /* floating-point constant */
TOKEN_FLOAT, /* floating-point constant */
TOKEN_FLOATIZE, /* __floatX__ */
};
enum floatize {
FLOAT_16,
FLOAT_32,
FLOAT_64,
FLOAT_80M,
FLOAT_80E,
FLOAT_128L,
FLOAT_128H,
};
typedef struct {

353
test/floatexp.asm Normal file
View File

@ -0,0 +1,353 @@
bits 64
;
; Test of floating-point formats
;
; 16-bit
mov ax,__float16__(1.0)
mov ax,__float16__(+1.0)
mov ax,__float16__(-1.0)
mov ax,__float16__(0.0)
mov ax,__float16__(+0.0)
mov ax,__float16__(-0.0)
mov ax,__float16__(1.83203125)
mov ax,__float16__(+1.83203125)
mov ax,__float16__(-1.83203125)
mov ax,__float16__(1.83203125e3)
mov ax,__float16__(+1.83203125e3)
mov ax,__float16__(-1.83203125e3)
mov ax,__float16__(1.83203125e-3)
mov ax,__float16__(+1.83203125e-3)
mov ax,__float16__(-1.83203125e-3)
mov ax,__float16__(1.83203125e-6) ; Denormal!
mov ax,__float16__(+1.83203125e-6) ; Denormal!
mov ax,__float16__(-1.83203125e-6) ; Denormal!
mov ax,__float16__(__Infinity__)
mov ax,__float16__(+__Infinity__)
mov ax,__float16__(-__Infinity__)
mov ax,__float16__(__NaN__)
mov ax,__float16__(__QNaN__)
mov ax,__float16__(__SNaN__)
; 32-bit
mov eax,__float32__(1.0)
mov eax,__float32__(+1.0)
mov eax,__float32__(-1.0)
mov eax,__float32__(0.0)
mov eax,__float32__(+0.0)
mov eax,__float32__(-0.0)
mov eax,__float32__(1.83203125)
mov eax,__float32__(+1.83203125)
mov eax,__float32__(-1.83203125)
mov eax,__float32__(1.83203125e15)
mov eax,__float32__(+1.83203125e15)
mov eax,__float32__(-1.83203125e15)
mov eax,__float32__(1.83203125e-15)
mov eax,__float32__(+1.83203125e-15)
mov eax,__float32__(-1.83203125e-15)
mov eax,__float32__(1.83203125e-40) ; Denormal!
mov eax,__float32__(+1.83203125e-40) ; Denormal!
mov eax,__float32__(-1.83203125e-40) ; Denormal!
mov eax,__float32__(__Infinity__)
mov eax,__float32__(+__Infinity__)
mov eax,__float32__(-__Infinity__)
mov eax,__float32__(__NaN__)
mov eax,__float32__(__QNaN__)
mov eax,__float32__(__SNaN__)
; 64-bit
mov rax,__float64__(1.0)
mov rax,__float64__(+1.0)
mov rax,__float64__(-1.0)
mov rax,__float64__(0.0)
mov rax,__float64__(+0.0)
mov rax,__float64__(-0.0)
mov rax,__float64__(1.83203125)
mov rax,__float64__(+1.83203125)
mov rax,__float64__(-1.83203125)
mov rax,__float64__(1.83203125e300)
mov rax,__float64__(+1.83203125e300)
mov rax,__float64__(-1.83203125e300)
mov rax,__float64__(1.83203125e-300)
mov rax,__float64__(+1.83203125e-300)
mov rax,__float64__(-1.83203125e-300)
mov rax,__float64__(1.83203125e-320) ; Denormal!
mov rax,__float64__(+1.83203125e-320) ; Denormal!
mov rax,__float64__(-1.83203125e-320) ; Denormal!
mov rax,__float64__(__Infinity__)
mov rax,__float64__(+__Infinity__)
mov rax,__float64__(-__Infinity__)
mov rax,__float64__(__NaN__)
mov rax,__float64__(__QNaN__)
mov rax,__float64__(__SNaN__)
; 80-bit
mov rax,__float80m__(1.0)
mov ax,__float80e__(1.0)
mov rax,__float80m__(+1.0)
mov ax,__float80e__(+1.0)
mov rax,__float80m__(-1.0)
mov ax,__float80e__(-1.0)
mov rax,__float80m__(0.0)
mov ax,__float80e__(0.0)
mov rax,__float80m__(+0.0)
mov ax,__float80e__(+0.0)
mov rax,__float80m__(-0.0)
mov ax,__float80e__(-0.0)
mov rax,__float80m__(1.83203125)
mov ax,__float80e__(1.83203125)
mov rax,__float80m__(+1.83203125)
mov ax,__float80e__(+1.83203125)
mov rax,__float80m__(-1.83203125)
mov ax,__float80e__(-1.83203125)
mov rax,__float80m__(1.83203125e+4000)
mov ax,__float80e__(1.83203125e+4000)
mov rax,__float80m__(+1.83203125e+4000)
mov ax,__float80e__(+1.83203125e+4000)
mov rax,__float80m__(-1.83203125e+4000)
mov ax,__float80e__(-1.83203125e+4000)
mov rax,__float80m__(1.83203125e-4000)
mov ax,__float80e__(1.83203125e-4000)
mov rax,__float80m__(+1.83203125e-4000)
mov ax,__float80e__(+1.83203125e-4000)
mov rax,__float80m__(-1.83203125e-4000)
mov ax,__float80e__(-1.83203125e-4000)
mov rax,__float80m__(1.83203125e-4940) ; Denormal!
mov ax,__float80e__(1.83203125e-4940) ; Denormal!
mov rax,__float80m__(+1.83203125e-4940) ; Denormal!
mov ax,__float80e__(+1.83203125e-4940) ; Denormal!
mov rax,__float80m__(-1.83203125e-4940) ; Denormal!
mov ax,__float80e__(-1.83203125e-4940) ; Denormal!
mov rax,__float80m__(__Infinity__)
mov ax,__float80e__(__Infinity__)
mov rax,__float80m__(+__Infinity__)
mov ax,__float80e__(+__Infinity__)
mov rax,__float80m__(-__Infinity__)
mov ax,__float80e__(-__Infinity__)
mov rax,__float80m__(__NaN__)
mov ax,__float80e__(__NaN__)
mov rax,__float80m__(__QNaN__)
mov ax,__float80e__(__QNaN__)
mov rax,__float80m__(__SNaN__)
mov ax,__float80e__(__SNaN__)
; 128-bit
mov rax,__float128l__(1.0)
mov rax,__float128h__(1.0)
mov rax,__float128l__(+1.0)
mov rax,__float128h__(+1.0)
mov rax,__float128l__(-1.0)
mov rax,__float128h__(-1.0)
mov rax,__float128l__(0.0)
mov rax,__float128h__(0.0)
mov rax,__float128l__(+0.0)
mov rax,__float128h__(+0.0)
mov rax,__float128l__(-0.0)
mov rax,__float128h__(-0.0)
mov rax,__float128l__(1.83203125)
mov rax,__float128h__(1.83203125)
mov rax,__float128l__(+1.83203125)
mov rax,__float128h__(+1.83203125)
mov rax,__float128l__(-1.83203125)
mov rax,__float128h__(-1.83203125)
mov rax,__float128l__(1.83203125e+4000)
mov rax,__float128h__(1.83203125e+4000)
mov rax,__float128l__(+1.83203125e+4000)
mov rax,__float128h__(+1.83203125e+4000)
mov rax,__float128l__(-1.83203125e+4000)
mov rax,__float128h__(-1.83203125e+4000)
mov rax,__float128l__(1.83203125e-4000)
mov rax,__float128h__(1.83203125e-4000)
mov rax,__float128l__(+1.83203125e-4000)
mov rax,__float128h__(+1.83203125e-4000)
mov rax,__float128l__(-1.83203125e-4000)
mov rax,__float128h__(-1.83203125e-4000)
mov rax,__float128l__(1.83203125e-4940) ; Denormal!
mov rax,__float128h__(1.83203125e-4940) ; Denormal!
mov rax,__float128l__(+1.83203125e-4940) ; Denormal!
mov rax,__float128h__(+1.83203125e-4940) ; Denormal!
mov rax,__float128l__(-1.83203125e-4940) ; Denormal!
mov rax,__float128h__(-1.83203125e-4940) ; Denormal!
mov rax,__float128l__(__Infinity__)
mov rax,__float128h__(__Infinity__)
mov rax,__float128l__(+__Infinity__)
mov rax,__float128h__(+__Infinity__)
mov rax,__float128l__(-__Infinity__)
mov rax,__float128h__(-__Infinity__)
mov rax,__float128l__(__NaN__)
mov rax,__float128h__(__NaN__)
mov rax,__float128l__(__QNaN__)
mov rax,__float128h__(__QNaN__)
mov rax,__float128l__(__SNaN__)
mov rax,__float128h__(__SNaN__)
;
; Test hexadecimal floating-point numbers
;
; 16-bit
mov ax,__float16__(1.0)
mov ax,__float16__(0x1.0)
mov ax,__float16__(2.0)
mov ax,__float16__(0x2.0)
mov ax,__float16__(0x1.0p+1)
mov ax,__float16__(0x1.0p-1)
mov ax,__float16__(0x0.0)
mov ax,__float16__(0x1.23456789)
mov ax,__float16__(0x0.123456789)
mov ax,__float16__(0x0.0000123456789)
mov ax,__float16__(0x1.23456789p10)
mov ax,__float16__(0x1.23456789p+10)
mov ax,__float16__(0x1.23456789p-10)
mov ax,__float16__(0x0.123456789p10)
mov ax,__float16__(0x0.123456789p+10)
mov ax,__float16__(0x0.123456789abcdef0123456789abcdef012345p-10)
mov ax,__float16__(0x0.0000123456789)
mov ax,__float16__(0x0.0000123456789p+10)
mov ax,__float16__(0x0.0000123456789p-10)
; 32-bit
mov eax,__float32__(1.0)
mov eax,__float32__(0x1.0)
mov eax,__float32__(2.0)
mov eax,__float32__(0x2.0)
mov eax,__float32__(0x1.0p+1)
mov eax,__float32__(0x1.0p-1)
mov eax,__float32__(0x0.0)
mov eax,__float32__(0x1.23456789)
mov eax,__float32__(0x0.123456789)
mov eax,__float32__(0x0.0000123456789)
mov eax,__float32__(0x1.23456789p10)
mov eax,__float32__(0x1.23456789p+10)
mov eax,__float32__(0x1.23456789p-10)
mov eax,__float32__(0x0.123456789p10)
mov eax,__float32__(0x0.123456789p+10)
mov eax,__float32__(0x0.123456789abcdef0123456789abcdef012345p-10)
mov eax,__float32__(0x0.0000123456789)
mov eax,__float32__(0x0.0000123456789p+10)
mov eax,__float32__(0x0.0000123456789p-10)
mov eax,__float32__(0x123456789.0)
mov eax,__float32__(0x0000123456789.0)
mov eax,__float32__(0x123456789.0p+0)
mov eax,__float32__(0x123456789.0p+64)
; 64-bit
mov rax,__float64__(1.0)
mov rax,__float64__(0x1.0)
mov rax,__float64__(2.0)
mov rax,__float64__(0x2.0)
mov rax,__float64__(0x1.0p+1)
mov rax,__float64__(0x1.0p-1)
mov rax,__float64__(0x0.0)
mov rax,__float64__(0x1.23456789)
mov rax,__float64__(0x0.123456789)
mov rax,__float64__(0x0.0000123456789)
mov rax,__float64__(0x1.23456789p10)
mov rax,__float64__(0x1.23456789p+10)
mov rax,__float64__(0x1.23456789p-10)
mov rax,__float64__(0x0.123456789p10)
mov rax,__float64__(0x0.123456789p+10)
mov rax,__float64__(0x0.123456789abcdef0123456789abcdef012345p-10)
mov rax,__float64__(0x0.0000123456789)
mov rax,__float64__(0x0.0000123456789p+10)
mov rax,__float64__(0x0.0000123456789p-10)
mov rax,__float64__(0x123456789.0)
mov rax,__float64__(0x0000123456789.0)
mov rax,__float64__(0x123456789.0p+0)
mov rax,__float64__(0x123456789.0p+300)
; 80-bit
mov rax,__float80m__(1.0)
mov ax,__float80e__(1.0)
mov rax,__float80m__(0x1.0)
mov ax,__float80e__(0x1.0)
mov rax,__float80m__(2.0)
mov ax,__float80e__(2.0)
mov rax,__float80m__(0x2.0)
mov ax,__float80e__(0x2.0)
mov rax,__float80m__(0x1.0p+1)
mov ax,__float80e__(0x1.0p+1)
mov rax,__float80m__(0x1.0p-1)
mov ax,__float80e__(0x1.0p-1)
mov rax,__float80m__(0x0.0)
mov ax,__float80e__(0x0.0)
mov rax,__float80m__(0x1.23456789)
mov ax,__float80e__(0x1.23456789)
mov rax,__float80m__(0x0.123456789)
mov ax,__float80e__(0x0.123456789)
mov rax,__float80m__(0x0.0000123456789)
mov ax,__float80e__(0x0.0000123456789)
mov rax,__float80m__(0x1.23456789p10)
mov ax,__float80e__(0x1.23456789p10)
mov rax,__float80m__(0x1.23456789p+10)
mov ax,__float80e__(0x1.23456789p+10)
mov rax,__float80m__(0x1.23456789p-10)
mov ax,__float80e__(0x1.23456789p-10)
mov rax,__float80m__(0x0.123456789p10)
mov ax,__float80e__(0x0.123456789p10)
mov rax,__float80m__(0x0.123456789p+10)
mov ax,__float80e__(0x0.123456789p+10)
mov rax,__float80m__(0x0.123456789abcdef0123456789abcdef012345p-10)
mov ax,__float80e__(0x0.123456789abcdef0123456789abcdef012345p-10)
mov rax,__float80m__(0x0.0000123456789)
mov ax,__float80e__(0x0.0000123456789)
mov rax,__float80m__(0x0.0000123456789p+10)
mov ax,__float80e__(0x0.0000123456789p+10)
mov rax,__float80m__(0x0.0000123456789p-10)
mov ax,__float80e__(0x0.0000123456789p-10)
mov rax,__float80m__(0x123456789.0)
mov ax,__float80e__(0x123456789.0)
mov rax,__float80m__(0x0000123456789.0)
mov ax,__float80e__(0x0000123456789.0)
mov rax,__float80m__(0x123456789.0p+0)
mov ax,__float80e__(0x123456789.0p+0)
mov rax,__float80m__(0x123456789.0p+1024)
mov ax,__float80e__(0x123456789.0p+1024)
; 128-bit
mov rax,__float128l__(1.0)
mov rax,__float128h__(1.0)
mov rax,__float128l__(0x1.0)
mov rax,__float128h__(0x1.0)
mov rax,__float128l__(2.0)
mov rax,__float128h__(2.0)
mov rax,__float128l__(0x2.0)
mov rax,__float128h__(0x2.0)
mov rax,__float128l__(0x1.0p+1)
mov rax,__float128h__(0x1.0p+1)
mov rax,__float128l__(0x1.0p-1)
mov rax,__float128h__(0x1.0p-1)
mov rax,__float128l__(0x0.0)
mov rax,__float128h__(0x0.0)
mov rax,__float128l__(0x1.23456789)
mov rax,__float128h__(0x1.23456789)
mov rax,__float128l__(0x0.123456789)
mov rax,__float128h__(0x0.123456789)
mov rax,__float128l__(0x0.0000123456789)
mov rax,__float128h__(0x0.0000123456789)
mov rax,__float128l__(0x1.23456789p10)
mov rax,__float128h__(0x1.23456789p10)
mov rax,__float128l__(0x1.23456789p+10)
mov rax,__float128h__(0x1.23456789p+10)
mov rax,__float128l__(0x1.23456789p-10)
mov rax,__float128h__(0x1.23456789p-10)
mov rax,__float128l__(0x0.123456789p10)
mov rax,__float128h__(0x0.123456789p10)
mov rax,__float128l__(0x0.123456789p+10)
mov rax,__float128h__(0x0.123456789p+10)
mov rax,__float128l__(0x0.123456789abcdef0123456789abcdef012345p-10)
mov rax,__float128h__(0x0.123456789abcdef0123456789abcdef012345p-10)
mov rax,__float128l__(0x0.0000123456789)
mov rax,__float128h__(0x0.0000123456789)
mov rax,__float128l__(0x0.0000123456789p+10)
mov rax,__float128h__(0x0.0000123456789p+10)
mov rax,__float128l__(0x0.0000123456789p-10)
mov rax,__float128h__(0x0.0000123456789p-10)
mov rax,__float128l__(0x123456789.0)
mov rax,__float128h__(0x123456789.0)
mov rax,__float128l__(0x0000123456789.0)
mov rax,__float128h__(0x0000123456789.0)
mov rax,__float128l__(0x123456789.0p+0)
mov rax,__float128h__(0x123456789.0p+0)
mov rax,__float128l__(0x123456789.0p+1024)
mov rax,__float128h__(0x123456789.0p+1024)

View File

@ -38,6 +38,15 @@ __nan__
__qnan__
__snan__
% TOKEN_FLOATIZE, 0, FLOAT_{__float*__}
__float16__
__float32__
__float64__
__float80m__
__float80e__
__float128l__
__float128h__
% TOKEN_*, 0, 0
seg
wrt

View File

@ -7,7 +7,7 @@
require 'phash.ph';
my($insns_dat, $regs_dat, $tokens_dat) = @ARGV;
my($output, $insns_dat, $regs_dat, $tokens_dat) = @ARGV;
%tokens = ();
@tokendata = ();
@ -120,102 +120,127 @@ while (defined($line = <TD>)) {
}
close(TD);
#
# Actually generate the hash
#
@hashinfo = gen_perfect_hash(\%tokens);
if (!defined(@hashinfo)) {
die "$0: no hash found\n";
if ($output eq 'h') {
#
# keywords.h
#
$max_len = 0;
foreach $token (keys(%tokens)) {
if (length($token) > $max_len) {
$max_len = length($token);
}
}
print "/*\n";
print " * This file is generated from insns.dat, regs.dat and token.dat\n";
print " * by tokhash.pl; do not edit.\n";
print " */\n";
print "\n";
print "#ifndef NASM_TOKENS_H\n";
print "#define NASM_TOKENS_H\n";
print "\n";
print "#define MAX_KEYWORD $max_len /* length of longest keyword */\n";
print "\n";
print "#endif /* NASM_TOKENS_H */\n";
} elsif ($output eq 'c') {
#
# tokhash.c
#
@hashinfo = gen_perfect_hash(\%tokens);
if (!defined(@hashinfo)) {
die "$0: no hash found\n";
}
# Paranoia...
verify_hash_table(\%tokens, \@hashinfo);
($n, $sv, $g) = @hashinfo;
$sv2 = $sv+2;
die if ($n & ($n-1));
print "/*\n";
print " * This file is generated from insns.dat, regs.dat and token.dat\n";
print " * by tokhash.pl; do not edit.\n";
print " */\n";
print "\n";
print "#include <string.h>\n";
print "#include \"nasm.h\"\n";
print "#include \"insns.h\"\n";
print "\n";
print "#define rot(x,y) (((uint32_t)(x) << (y))+((uint32_t)(x) >> (32-(y))))\n";
print "\n";
# These somewhat odd sizes and ordering thereof are due to the
# relative ranges of the types; this makes it fit in 16 bytes on
# 64-bit machines and 12 bytes on 32-bit machines.
print "struct tokendata {\n";
print " const char *string;\n";
print " int16_t tokentype;\n";
print " int16_t aux;\n";
print " int32_t num;\n";
print "};\n";
print "\n";
print "int nasm_token_hash(const char *token, struct tokenval *tv)\n";
print "{\n";
# Put a large value in unused slots. This makes it extremely unlikely
# that any combination that involves unused slot will pass the range test.
# This speeds up rejection of unrecognized tokens, i.e. identifiers.
print "#define UNUSED 16383\n";
print " static const int16_t hash1[$n] = {\n";
for ($i = 0; $i < $n; $i++) {
my $h = ${$g}[$i*2+0];
print " ", defined($h) ? $h : 'UNUSED', ",\n";
}
print " };\n";
print " static const int16_t hash2[$n] = {\n";
for ($i = 0; $i < $n; $i++) {
my $h = ${$g}[$i*2+1];
print " ", defined($h) ? $h : 'UNUSED', ",\n";
}
print " };\n";
printf " static const struct tokendata tokendata[%d] = {\n", scalar(@tokendata);
foreach $d (@tokendata) {
print " { ", $d, " },\n";
}
print " };\n";
print " uint32_t k1 = 0, k2 = 0;\n";
print " uint8_t c;\n";
# For correct overflow behavior, "ix" should be unsigned of the same
# width as the hash arrays.
print " uint16_t ix;\n";
print " const struct tokendata *data;\n";
print " const char *p = token;\n";
print "\n";
print " while ((c = *p++) != 0) {\n";
printf " uint32_t kn1 = rot(k1,%2d)^(rot(k2,%2d) + c);\n", ${$sv}[0], ${$sv}[1];
printf " uint32_t kn2 = rot(k2,%2d)^(rot(k1,%2d) + c);\n", ${$sv}[2], ${$sv}[3];
print " k1 = kn1; k2 = kn2;\n";
print " }\n";
print "\n";
printf " ix = hash1[k1 & 0x%x] + hash2[k2 & 0x%x];\n", $n-1, $n-1;
printf " if (ix >= %d)\n", scalar(@tokendata);
print " return tv->t_type = TOKEN_ID;\n";
print "\n";
print " data = &tokendata[ix];\n";
print " if (strcmp(data->string, token))\n";
print " return tv->t_type = TOKEN_ID;\n";
print "\n";
print " tv->t_integer = data->num;\n";
print " tv->t_inttwo = data->aux;\n";
print " return tv->t_type = data->tokentype;\n";
print "}\n";
}
# Paranoia...
verify_hash_table(\%tokens, \@hashinfo);
($n, $sv, $g) = @hashinfo;
$sv2 = $sv+2;
die if ($n & ($n-1));
print "/*\n";
print " * This file is generated from insns.dat, regs.dat and token.dat\n";
print " * by tokhash.pl; do not edit.\n";
print " */\n";
print "\n";
print "#include <string.h>\n";
print "#include \"nasm.h\"\n";
print "#include \"insns.h\"\n";
print "\n";
print "#define rot(x,y) (((uint32_t)(x) << (y))+((uint32_t)(x) >> (32-(y))))\n";
print "\n";
# These somewhat odd sizes and ordering thereof are due to the
# relative ranges of the types; this makes it fit in 16 bytes on
# 64-bit machines and 12 bytes on 32-bit machines.
print "struct tokendata {\n";
print " const char *string;\n";
print " int16_t tokentype;\n";
print " int16_t aux;\n";
print " int32_t num;\n";
print "};\n";
print "\n";
print "int nasm_token_hash(const char *token, struct tokenval *tv)\n";
print "{\n";
# Put a large value in unused slots. This makes it extremely unlikely
# that any combination that involves unused slot will pass the range test.
# This speeds up rejection of unrecognized tokens, i.e. identifiers.
print "#define UNUSED 16383\n";
print " static const int16_t hash1[$n] = {\n";
for ($i = 0; $i < $n; $i++) {
my $h = ${$g}[$i*2+0];
print " ", defined($h) ? $h : 'UNUSED', ",\n";
}
print " };\n";
print " static const int16_t hash2[$n] = {\n";
for ($i = 0; $i < $n; $i++) {
my $h = ${$g}[$i*2+1];
print " ", defined($h) ? $h : 'UNUSED', ",\n";
}
print " };\n";
printf " static const struct tokendata tokendata[%d] = {\n", scalar(@tokendata);
foreach $d (@tokendata) {
print " { ", $d, " },\n";
}
print " };\n";
print " uint32_t k1 = 0, k2 = 0;\n";
print " uint8_t c;\n";
# For correct overflow behavior, "ix" should be unsigned of the same
# width as the hash arrays.
print " uint16_t ix;\n";
print " const struct tokendata *data;\n";
print " const char *p = token;\n";
print "\n";
print " while ((c = *p++) != 0) {\n";
printf " uint32_t kn1 = rot(k1,%2d)^(rot(k2,%2d) + c);\n", ${$sv}[0], ${$sv}[1];
printf " uint32_t kn2 = rot(k2,%2d)^(rot(k1,%2d) + c);\n", ${$sv}[2], ${$sv}[3];
print " k1 = kn1; k2 = kn2;\n";
print " }\n";
print "\n";
printf " ix = hash1[k1 & 0x%x] + hash2[k2 & 0x%x];\n", $n-1, $n-1;
printf " if (ix >= %d)\n", scalar(@tokendata);
print " return tv->t_type = TOKEN_ID;\n";
print "\n";
print " data = &tokendata[ix];\n";
# print " fprintf(stderr, \"Looked for: %s found: %s\\n\", token, data->string);\n\n";
print " if (strcmp(data->string, token))\n";
print " return tv->t_type = TOKEN_ID;\n";
print "\n";
print " tv->t_integer = data->num;\n";
print " tv->t_inttwo = data->aux;\n";
print " return tv->t_type = data->tokentype;\n";
print "}\n";