mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-01-30 16:41:05 +08:00
Implement floating-point option control directive
New directive [FLOAT] with associated standard macros; allows the setting to be saved and restored.
This commit is contained in:
parent
fab3a6c9de
commit
f6c9e65d4f
@ -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
|
||||
|
31
float.c
31
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 */
|
||||
}
|
||||
}
|
||||
|
||||
|
1
float.h
1
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
|
||||
|
13
nasm.c
13
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"))
|
||||
|
27
standard.mac
27
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
|
||||
|
Loading…
Reference in New Issue
Block a user