From f6c9e65d4f906d0847ef747595de6495c92b9778 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 16 Oct 2007 14:40:27 -0700 Subject: [PATCH] Implement floating-point option control directive New directive [FLOAT] with associated standard macros; allows the setting to be saved and restored. --- doc/nasmdoc.src | 30 +++++++++++++++++++++++++++++- float.c | 31 +++++++++++++++++++++++++++++++ float.h | 1 + nasm.c | 13 ++++++++++--- standard.mac | 27 +++++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 4 deletions(-) diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src index f6616eb..66eaf10 100644 --- a/doc/nasmdoc.src +++ b/doc/nasmdoc.src @@ -3786,7 +3786,7 @@ Options are: \b\c{CPU WILLAMETTE} Same as P4 -\b\c{CPU PRESCOTT} Prescott instruction set +\b\c{CPU PRESCOTT} Prescott instruction set \b\c{CPU X64} x86-64 (x64/AMD64/EM64T) instruction set @@ -3797,6 +3797,34 @@ only if they apply to the selected CPU or lower. By default, all instructions are available. +\H{FLOAT} \i\c{FLOAT}: Handling of \I{floating-point, constants}floating-point constants + +By default, floating-point constants are rounded to nearest, and IEEE +denormals are supported. The following options can be set to alter +this behaviour: + +\b\c{FLOAT DAZ} Flush denormals to zero + +\b\c{FLOAT NODAZ} Do not flush denormals to zero (default) + +\b\c{FLOAT NEAR} Round to nearest (default) + +\b\c{FLOAT UP} Round up (toward +Infinity) + +\b\c{FLOAT DOWN} Round down (toward -Infinity) + +\b\c{FLOAT ZERO} Round toward zero + +\b\c{FLOAT DEFAULT} Restore default settings + +The standard macros \i\c{__FLOAT_DAZ__}, \i\c{__FLOAT_ROUND__}, and +\i\c{__FLOAT__} contain the current state, as long as the programmer +has avoided the use of the brackeded primitive form, (\c{[FLOAT]}). + +\c{__FLOAT__} contains the full set of floating-point settings; this +value can be saved away and invoked later to restore the setting. + + \C{outfmt} \i{Output Formats} NASM is a portable assembler, designed to be able to compile on any diff --git a/float.c b/float.c index 18156ef..ec37775 100644 --- a/float.c +++ b/float.c @@ -776,3 +776,34 @@ int float_const(const char *number, int32_t sign, uint8_t * result, return 0; } } + +/* Set floating-point options */ +int float_option(const char *option) +{ + if (!nasm_stricmp(option, "daz")) { + daz = true; + return 0; + } else if (!nasm_stricmp(option, "nodaz")) { + daz = false; + return 0; + } else if (!nasm_stricmp(option, "near")) { + rc = FLOAT_RC_NEAR; + return 0; + } else if (!nasm_stricmp(option, "down")) { + rc = FLOAT_RC_DOWN; + return 0; + } else if (!nasm_stricmp(option, "up")) { + rc = FLOAT_RC_UP; + return 0; + } else if (!nasm_stricmp(option, "zero")) { + rc = FLOAT_RC_ZERO; + return 0; + } else if (!nasm_stricmp(option, "default")) { + rc = FLOAT_RC_NEAR; + daz = false; + return 0; + } else { + return -1; /* Unknown option */ + } +} + diff --git a/float.h b/float.h index 430c464..04e9b17 100644 --- a/float.h +++ b/float.h @@ -19,5 +19,6 @@ enum float_round { int float_const(const char *string, int sign, uint8_t *result, int bytes, efunc error); +int float_option(const char *option); #endif diff --git a/nasm.c b/nasm.c index 04f4190..af2f0b3 100644 --- a/nasm.c +++ b/nasm.c @@ -18,6 +18,7 @@ #include "nasm.h" #include "nasmlib.h" +#include "float.h" #include "stdscan.h" #include "insns.h" #include "preproc.h" @@ -822,11 +823,11 @@ static void parse_cmdline(int argc, char **argv) /* List of directives */ enum directives { D_NONE, D_ABSOLUTE, D_BITS, D_COMMON, D_CPU, D_DEBUG, D_DEFAULT, - D_EXTERN, D_GLOBAL, D_LIST, D_SECTION, D_SEGMENT, D_WARNING + D_EXTERN, D_FLOAT, D_GLOBAL, D_LIST, D_SECTION, D_SEGMENT, D_WARNING }; static const char *directives[] = { "", "absolute", "bits", "common", "cpu", "debug", "default", - "extern", "global", "list", "section", "segment", "warning" + "extern", "float", "global", "list", "section", "segment", "warning" }; static enum directives getkw(char **directive, char **value); @@ -1143,6 +1144,13 @@ static void assemble_file(char *fname) err = 1; } break; + case D_FLOAT: + if (float_option(value)) { + report_error(pass1 == 1 ? ERR_NONFATAL : ERR_PANIC, + "unknown 'float' directive: %s", + value); + } + break; default: if (!ofmt->directive(directive, value, pass2)) report_error(pass1 == 1 ? ERR_NONFATAL : ERR_PANIC, @@ -1730,7 +1738,6 @@ static void no_pp_cleanup(int pass) static uint32_t get_cpu(char *value) { - if (!strcmp(value, "8086")) return IF_8086; if (!strcmp(value, "186")) diff --git a/standard.mac b/standard.mac index bfc2af0..e056352 100644 --- a/standard.mac +++ b/standard.mac @@ -111,6 +111,33 @@ __SECT__ [cpu %1] %endmacro +%define __FLOAT_DAZ__ nodaz +%define __FLOAT_ROUND__ near +; __FLOAT__ contains the whole floating-point configuration so it can +; be saved and restored +%define __FLOAT__ __FLOAT_DAZ__ __FLOAT_ROUND__ +%imacro float 1-*.nolist +%rep %0 +[float %1] +%ifidni %1,daz +%define __FLOAT_DAZ__ daz +%elifidni %1,nodaz +%define __FLOAT_DAZ__ nodaz +%elifidni %1,near +%define __FLOAT_ROUND__ near +%elifidni %1,up +%define __FLOAT_ROUND__ up +%elifidni %1,down +%define __FLOAT_ROUND__ down +%elifidni %1,zero +%define __FLOAT_ROUND__ zero +%elifidni %1,default +%define __FLOAT_DAZ__ nodaz +%define __FLOAT_ROUND__ near +%endif +%endrep +%endmacro + %imacro default 1+.nolist [default %1] %endmacro -- 2.7.4