\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
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
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 */
+ }
+}
+
int float_const(const char *string, int sign, uint8_t *result, int bytes,
efunc error);
+int float_option(const char *option);
#endif
#include "nasm.h"
#include "nasmlib.h"
+#include "float.h"
#include "stdscan.h"
#include "insns.h"
#include "preproc.h"
/* 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);
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,
static uint32_t get_cpu(char *value)
{
-
if (!strcmp(value, "8086"))
return IF_8086;
if (!strcmp(value, "186"))
[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