Support __float*__ for floating-point numbers in expressions
authorH. Peter Anvin <hpa@zytor.com>
Mon, 24 Sep 2007 19:30:54 +0000 (12:30 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Mon, 24 Sep 2007 19:30:54 +0000 (12:30 -0700)
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.

Makefile.in
Mkfiles/msvc.mak
eval.c
insns.h
nasm.h
test/floatexp.asm [new file with mode: 0644]
tokens.dat
tokhash.pl

index ab8973d..a7fa25b 100644 (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 $(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
index 96b5449..5871efb 100644 (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 $(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
diff --git a/eval.c b/eval.c
index 644929d..a75c5ba 100644 (file)
--- 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);
diff --git a/insns.h b/insns.h
index 33cf9f4..4e1b901 100644 (file)
--- a/insns.h
+++ b/insns.h
 #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" */
diff --git a/nasm.h b/nasm.h
index d3596de..a120ccd 100644 (file)
--- a/nasm.h
+++ b/nasm.h
@@ -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 {
diff --git a/test/floatexp.asm b/test/floatexp.asm
new file mode 100644 (file)
index 0000000..7e6a01c
--- /dev/null
@@ -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)
index e7c1cb2..eb7fa11 100644 (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
index f45d07d..739172c 100755 (executable)
@@ -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
+    #
 
-# 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";
+    $max_len = 0;
+    foreach $token (keys(%tokens)) {
+       if (length($token) > $max_len) {
+           $max_len = length($token);
+       }
+    }
 
-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";
+    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";
+    }
 
-printf "    static const struct tokendata tokendata[%d] = {\n", scalar(@tokendata);
-foreach $d (@tokendata) {
-    print "        { ", $d, " },\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";
 }
-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";