linux-mips.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC v2] MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking
@ 2016-05-14 17:10 Maciej W. Rozycki
  2016-05-14 17:10 ` Maciej W. Rozycki
  2016-05-16 14:21 ` Matthew Fortune
  0 siblings, 2 replies; 8+ messages in thread
From: Maciej W. Rozycki @ 2016-05-14 17:10 UTC (permalink / raw)
  To: linux-mips, libc-alpha, binutils, gcc; +Cc: Joseph Myers, Matthew Fortune

Dear fellow developers,

 Here is the second revision of the ABI extension specification previously 
posted, incorporating feedback received for the first revision.  Changes 
have been made to Section 4 "Implementation Notes", the remaining parts
have stayed the same.  The master copy of this document is available at:

<https://dmz-portal.mips.com/wiki/MIPS_ABI_-_NaN_Interlinking>

 Please let me know if you have any questions, comments or concerns about 
this updated version.  Otherwise I will wait a short while and then follow 
up with an updated implementation.

 Thanks to all of you who took time to read the first revision and comment 
on it, and especially Joseph Myers.

  Maciej

-------------------------------------------------------------------------- 
MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking

1. Introduction

 The MIPS architecture has supported IEEE Std 754 floating-point
arithmetic since its beginning in 1985.  Naturally as initial support was
for the original 1985 revision of the standard then particular choices
were made for the architecture where freedom was given by that revision.
This was the case with not-a-number (NaN) symbolic data and the bit
patterns chosen to represent them.  Later on this choice turned out to be
different from ones used by all other IEEE Std 754 implementers.  Hardware
implementing this original MIPS architecture definition and corresponding
software and ABIs will be referred across this document as legacy-NaN
hardware, software and ABIs respectively, and the NaN patterns themselves
as legacy NaN patterns.

 The patterns originally chosen had their advantage in the MIPS
architecture, however an updated revision of IEEE Std 754 released in 2008
made the NaN patterns chosen by other implementers preferred.  MIPS
architecture overseers decided to follow the recommendation and update the
architecture definition accordingly.  Consequently a set of amended ABIs
has been created to provide for software execution on hardware
implementing the updated architecture.  Such hardware, software and ABIs
will be referred across this document to as 2008-NaN hardware, software
and ABIs respectively, and the NaN patterns themselves as to 2008 NaN
patterns.

 The legacy and 2008 NaN patterns are not compatible with each other and
therefore the respective ABIs and software binaries are not.  To keep all
software compliant to IEEE Std 754 a decision was made to disallow mixing
legacy-NaN and 2008-NaN software modules in static linking and dynamic
loading, and at the OS level disallow execution of 2008-NaN software on
legacy-NaN hardware and vice versa.

2. Statement of the Problem

 The decisions made so far about the MIPS architecture and ABIs have led
to a situation where the large existing base of software binaries cannot
execute on current hardware.  And this applies regardless of whether it
relies on the use of NaN data or IEEE Std 754 arithmetic in the first
place.  Rebuilding all of the existing software for 2008-NaN hardware is
infeasible and additionally such software, rebuilt or new, will not run on
legacy-NaN hardware that is widely deployed, so maintaining two binary
versions of the same piece of software would often be required.

3. Solution

 The solution described here has been prepared with the Linux environment
in mind, although where applicable individual changes are also appropriate
for bare-metal environments.

 A number of changes are made at different levels to make the transition
to 2008-NaN hardware easier as well as long-term support for legacy-NaN
hardware that is undoubtedly going to stay around for a while.  They are
detailed from the hardware level up in the following sections.

3.1 Hardware and Operating System Interface

 The operating system tells legacy-NaN and 2008-NaN software apart by
examining the state of the EF_MIPS_NAN2008 flag in the ELF file header of
individual binaries requested for execution with the execve(2) system
call.  The value of `0' of the flag denotes legacy-NaN software and the
value of `1' denotes 2008-NaN software.

3.1.1 Floating-Point Emulation

 Where possible both legacy-NaN and 2008-NaN software will be supported.
The MIPS architecture itself makes it possible and therefore the FPU
emulator used on hardware that does not implement an FPU will set itself
to the right mode individually for every legacy-NaN or 2008-NaN program
executed.

 On Linux the FPU emulator can also be enabled unconditionally even on
hardware that does implement an FPU, with the use of the `nofpu' kernel
option.  In this case both legacy-NaN and 2008-NaN software will be
automatically supported, although at a performance loss compared to FPU
hardware.

3.1.2 Global IEEE Std 754 Compliance Mode

 A new `ieee754=' kernel option is provided for cases where strict IEEE
Std 754 compliance is not required.  This makes it possible to use
binaries from existing Linux distributions on new 2008-NaN hardware making
the transition easier.  At least two values are accepted on the right hand
side of this option, `strict' and `relaxed', to select between IEEE Std
754 compliance modes.  These modes shall only affect software that does
not make an explicit mode selection as noted in Section 3.1.3 below.

 In the `strict' mode, which is the default in the absence of an explicit
`ieee754=' option, only software compatible with the NaN patterns handled
by FPU hardware shall be accepted for execution, that is legacy-NaN
software on legacy-NaN hardware and 2008-NaN software on 2008-NaN
hardware.

 In the `relaxed' mode any software shall be accepted for execution,
regardless of whether it is compatible with FPU hardware.  Additionally,
in the `relaxed' mode, even if enabled with the FCSR.Enables.V bit, any
IEEE Std 754 Invalid Operation exceptions triggered with an sNaN
instruction operand shall not result in a SIGFPE signal being issued to
the originating process and a qNaN (encoded according to the current mode
set in the floating-point environment) shall be substituted and propagated
through the arithmetic operation requested as with a qNaN operand.

 Additionally, to make the dynamic loader aware that the `relaxed' IEEE
Std 754 compliance mode is in effect, bit #25 shall be set in the `a_val'
member of the AT_FLAGS entry of the auxiliary vector created by the
kernel on program execution for any program accepted for this mode.  This
bit is in the part of the flag word reserved for system semantic by the
MIPS psABI[1].  This bit shall be set to `0' in the `strict' mode and `1'
in the `relaxed' mode.

 Additional values may be accepted with the kernel option and consequently
modes provided now or in the future, but they are beyond the scope of this
document.

3.1.3 Per Program Individual IEEE Std 754 Compliance Mode

 Individual programs can select their required IEEE Std 754 compliance
mode regardless of the global mode.  Individual selection takes precedence
over the global selection.  Programs that select their individual mode
shall have a PT_MIPS_ABIFLAGS segment and shall have bit #1 set in its
`flags1' member.  The specific mode selected is then determined by the
value of bit #1 in this segment's `flags2' member, `0' for the `strict'
mode and `1' for the `relaxed' mode.

 The semantics of such individually selected IEEE Std 754 compliance
mode is the same as that of the corresponding global mode.  See Section
3.1.2 above for further details.

3.1.4 Dynamic IEEE Std 754 Compliance Mode Control

 A new request is provided via the prctl(2) system call to let a process
switch its own IEEE Std 754 compliance mode.  This is for example to let
a dynamic loader invoked manually set the compliance mode for an
executable requested as if the executable was run directly and its
compliance mode preset by the kernel.  The request shall be made as
follows:

  int result;
  result = prctl(PR_SET_IEEE754_MODE, mode, what);

 In this request `mode' shall be set to one of the following:

* PR_IEEE754_MODE_LEGACY -- to set the compliance mode used with programs
  which do not make an individual IEEE Std 754 compliance mode selection,

* PR_IEEE754_MODE_STRICT -- to set the `strict' compliance mode,

* PR_IEEE754_MODE_RELAXED -- to set the `relaxed' compliance mode,

and `what' shall be set to either of:

* PR_IEEE754_MODE_NAN_LEGACY -- to select the legacy-NaN encoding mode,

* PR_IEEE754_MODE_NAN_2008 -- to select the 2008-NaN encoding mode.

The kernel shall execute the request according to the rules set out in
Subsection 3.1.2 and Subsection 3.1.3 for the ELF file flag settings
corresponding to the respective IEEE Std 754 compliance and NaN encoding
modes requested.

 If the request is successful a non-negative value shall be assigned to
`result', in which bits 7:0 are set to a pattern that would be placed in
bits 31:24, in the same bit order, of the `a_val' member of the AT_FLAGS
entry of the auxiliary vector created by the kernel on program execution
for the mode selected.

3.2 Dynamic Loading

 The dynamic loader shall recognise IEEE Std 754 compliance modes and
resolve main executable's dependencies according to rules set below.  For
the purpose of these rules a main executable is the binary named in an
execve(2) call to the operating system, and a dependency is any dynamic
shared object additionally loaded, via any means including but not
necessarily limited to a DT_NEEDED dynamic segment entry, an LD_PRELOAD
environment variable or a dlopen(3) library call.

3.2.1 IEEE Std 754 Compliance Mode Selection

 Both executables and dynamic shared objects can select their required
IEEE Std 754 compliance mode.  A binary requiring a specific compliance
mode shall have a PT_MIPS_ABIFLAGS segment and shall have its contents
set according to rules set out in Section 3.1.3.  Such a binary will
be referred to as `strict' or `relaxed'.  Binaries that have no
PT_MIPS_ABIFLAGS segment or have one that does not request a specific
compliance mode will be referred to as `legacy'.

3.2.2 Dynamic Dependency Acceptance Rules

 The IEEE Std 754 compliance mode requested is determined by the main
executable.  Any dynamic shared objects loaded in addition shall respect
the mode according to the rules set below.

 For `strict' executables all the dynamic shared objects shall follow the
same legacy-NaN or 2008-NaN ABI, as denoted by the EF_MIPS_NAN2008 flag
described in Section 3.1.  The value of the flag shall be the same across
the executable and all the dynamic shared objects loaded together.  Both
`strict' and `legacy' dynamic shared objects shall be accepted, however
`relaxed' ones shall be rejected regardless of the value of their
EF_MIPS_NAN2008 flag.

 For `relaxed' executables any dynamic shared objects shall be accepted,
`strict', `relaxed' and `legacy' alike, regardless of the value of their
EF_MIPS_NAN2008 flag.

 For `legacy' executables the compliance mode is determined by the value
of bit #25 in the `a_val' member of the AT_FLAGS entry of the auxiliary
vector received from the kernel.  The value of `0' shall make the dynamic
loader follow the rules for `strict' executables.  The value of `1' shall
make the dynamic loader follow the rules for `relaxed' executables.

3.2.3 Dynamic Loading Compatibility Considerations

 The encoding for the PT_MIPS_ABIFLAGS segment has been selected such that
old versions of the dynamic loader will reject `relaxed' binaries because
of an unknown `flags2' bit set.  This is to prevent execution in an
environment that does not follow the rules set out in this specification
and to signify the need to upgrade.  Both `strict' and `legacy' binaries
will run correctly as they follow the rules defined for old versions of
the dynamic loader.

 Older versions of the dynamic loader will not process a PT_MIPS_ABIFLAGS
segment and will only examine the EF_MIPS_NAN2008 flag.  Very old versions
of the dynamic loader will not even process the flag.  It is therefore not
possible to guarantee that the rules set out here will be followed or an
error triggered with older systems.

3.3 Static Linking

 The static linker shall recognise IEEE Std 754 compliance modes and
enforce the rules set below for all static links, both final ones that
produce an executable or a dynamic shared object and incremental ones
that produce a relocatable object.

3.3.1 IEEE Std 754 Compliance Mode Selection

 All relocatable objects can select their required IEEE Std 754 compliance
mode.  An object requiring a specific compliance mode shall have an
SHT_MIPS_ABIFLAGS section called `.MIPS.abiflags' and shall have its
contents set according to rules set out for the PT_MIPS_ABIFLAGS segment
in Section 3.1.3.  Such an object will be referred to as `strict' or
`relaxed'.  Objects that have no SHT_MIPS_ABIFLAGS section or have one
that does not request a specific compliance mode will be referred to as
`legacy'.  On making an executable or a dynamic shared object the linker  
shall map an SHT_MIPS_ABIFLAGS section to a PT_MIPS_ABIFLAGS segment.

3.3.2 Static Linking Object Acceptance Rules

 The static linker shall follow the user selection as to the linking mode
used, either of `strict' and `relaxed'.  The selection will be made
according to the usual way assumed for the environment used, which may be
a command-line option, a property setting, etc.

 In the `strict' linking mode both `strict' and `legacy' objects can be
linked together.  All shall follow the same legacy-NaN or 2008-NaN ABI, as
denoted by the EF_MIPS_NAN2008 flag described in Section 3.1.  The value
of the flag shall be the same across all the objects linked together.  The
output of a link involving any `strict' objects shall be marked as
`strict'.  No `relaxed' objects shall be allowed in the same link.

 In the `relaxed' linking mode any `strict', `relaxed' and `legacy'
objects can be linked together, regardless of the value of their
EF_MIPS_NAN2008 flag.  If the flag has the same value across all objects
linked, then the value shall be propagated to the binary produced.  The
output shall be marked as `relaxed'.  It is recommended that the linker
provides a way to warn the user whenever a `relaxed' link is made of
`strict' and `legacy' objects only.

3.3.3 Static Linking Compliance Mode Warnings

A flag shall be defined in bit #0 of the `flags2' member of the
PT_MIPS_ABIFLAGS section, determining the warning mode for IEEE Std 754
compliance in static linking.  This bit shall be set to `0' to enable
the warning mode (`warn' mode) and `1' to disable it (`nowarn' mode).  The
bit shall propagate through an incremental static link in an
implementation-defined manner, however it shall be set to `0' in a final
static link.

3.3.4 Static Linking Compatibility Considerations

 The encoding for the SHT_MIPS_ABIFLAGS section has been selected such
that old versions of the static linker will reject `relaxed' binaries
because of an unknown `flags2' bit set.  This is to prevent incorrectly
annotated objects from being produced that would not guarantee IEEE Std
754 compliance.

 The encoding has also been selected such that old versions of the static
linker will merge the `flags1' bit used to tell `legacy' objects and
`strict'/`relaxed' ones apart, automatically marking the output of links
involving any `strict' objects as `strict' as well.

 Older versions of the static linker will not process an SHT_MIPS_ABIFLAGS
section and will only examine the EF_MIPS_NAN2008 flag.  Consequently they
may allow `relaxed' objects in a single link with `strict' and `legacy'
ones.

3.4 Relocatable Object Generation

 Tools that produce relocatable objects such as the assembler shall always
produce a SHT_MIPS_ABIFLAGS section according to the IEEE Std 754
compliance mode selected.  In the absence of any explicit user
instructions the `strict' mode shall be assumed.  No new `legacy' objects
shall be produced.

3.5 No-float Modules

 Certain modules used in dynamic loading or static linking may be marked
as containing no floating-point code, in a way defined by a separate
specification.  Such modules shall always be accepted for dynamic loading
and static linking, and for the purpose of IEEE Std 754 compliance checks
treated as if absent.

3.6 Definitions

 The following macros shall be defined for the flags introduced by this
document:

/* `flags1' member of the PT_MIPS_ABIFLAGS/SHT_MIPS_ABIFLAGS structure.  */
#define MIPS_AFL_FLAGS1_IEEE    2       /* IEEE Std 754 mode defined.  */

/* `flags2' members of the PT_MIPS_ABIFLAGS/SHT_MIPS_ABIFLAGS structure.  */
#define MIPS_AFL_FLAGS2_NOWARN  1       /* Suppress IEEE Std 754 warnings.  */
#define MIPS_AFL_FLAGS2_RELAXED 2       /* Relaxed IEEE Std 754 mode.  */

/* `a_val' member of the AT_FLAGS entry.  */
#define AV_FLAGS_MIPS_RELAXED   (1 << 25) /* Relaxed IEEE Std 754 mode.  */

It is unspecified at this time whether the bits referred to with
MIPS_AFL_FLAGS2_RELAXED and AV_FLAGS_MIPS_RELAXED are single-bit bitfields
or the least significant bits of a larger enumeration, to be defined
later.

 The following macros shall be defined for the prctl(2) interface
introduced by this document:

/* Control MIPS IEEE 754 compliance modes.  */
#define PR_SET_IEEE754_MODE             TBA

#define PR_IEEE754_MODE_LEGACY          0       /* Legacy mode.  */
#define PR_IEEE754_MODE_STRICT          1       /* Strict mode.  */
#define PR_IEEE754_MODE_RELAXED         2       /* Relaxed mode.  */

#define PR_IEEE754_MODE_NAN_LEGACY      0       /* Set legacy NaN encoding.  */
#define PR_IEEE754_MODE_NAN_2008        1       /* Set 2008 NaN encoding.  */

4. Implementation Notes

 For the GNU linker the command-line options to select between the
`strict' and the `relaxed' IEEE Std 754 compliance modes will be
`--ieee=strict' and `--ieee=relaxed', respectively.  The latter will issue
a compliance warning in the case where all input objects were either
`strict' and `warn' or `legacy' mode, unless a `--ieee=nowarn' option has
also been used.  There will be a `--ieee=warn' option as well to revert
the effect of the former option.

 For the GNU assembler the directives to select between the `strict' and
the `relaxed' IEEE Std 754 compliance modes will be `.ieee strict' and
`.ieee relaxed', respectively.  Equivalent command-line options will be
present, `-mieee=strict' and `-mieee=relaxed', respectively.  There will
be `.ieee nowarn' and `.ieee warn' directives as well to set and clear
the IEEE Std 754 warning flag respectively in the SHT_MIPS_ABIFLAGS
section.  Their corresponding command-line options will be `-mieee=nowarn'
and `-mieee=warn' respectively.

 For the GNU Compiler Collection (GCC) the following target-specific
command-line options will be accepted:

* `-mieee=strict', making the toolchain produce `strict' binaries,

* `-mieee=relaxed-exec', making the toolchain produce `strict' shared
  libraries and `relaxed' executables,

* `-mieee=relaxed', making the toolchain produce `relaxed' binaries,

* `-mieee=force-relaxed', making the toolchain produce `relaxed' binaries,
  while suppressing IEEE Std 754 static linking warnings.

Any or all of these options may have target-specific effects beyond
propagating the IEEE Std 754 compliance mode down to the assembler and the
linker.

 It is expected that `-mieee=strict' and `-mieee=relaxed-exec' options
will be set by appropriate generic `-fieee' options, to be defined, which
will be also available for selection as configuration defaults at the GCC
build time.  It is also expected that along `-mieee=strict' the relevant
`-fieee' option and its corresponding configuration default will set the
compiler into a mode in which it will produce strictly compliant code,
which in the context of this specification is defined as: following IEEE
Std 754 as closely as the programming language binding to the standard
(defined in the relevant language standard), the compiler implementation
and target hardware permit.  This means that the use of `-fieee' options
may affect code produced in ways beyond NaN representation only.

 There may be further GCC options to control IEEE Std 754 compliance, to
be defined.

5. Future Considerations

 While at the time of this writing the `strict' and `relaxed' IEEE Std 754
compliance modes only apply to NaN representation patterns, it is possible
that in the future other IEEE Std 754 compliance matters may require
communicating through linking and loading down to the operating system
kernel.  Therefore a decision has been made to use generic names for the
modes, macros, directives and option names defined here.  If such a need
arises in the future, then the meaning of these names may be extended to
cover other compliance aspects and further modes can be added that are
intermediate between `strict' and `relaxed', to be used with the `.ieee'
directive and the `-mieee=' command-line options.

References:

[1] "SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor
    Supplement, 3rd Edition", Section "Process Stack", pp. 3-33, 3-34

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [RFC v2] MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking
  2016-05-14 17:10 [RFC v2] MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking Maciej W. Rozycki
@ 2016-05-14 17:10 ` Maciej W. Rozycki
  2016-05-16 14:21 ` Matthew Fortune
  1 sibling, 0 replies; 8+ messages in thread
From: Maciej W. Rozycki @ 2016-05-14 17:10 UTC (permalink / raw)
  To: linux-mips, libc-alpha, binutils, gcc; +Cc: Joseph Myers, Matthew Fortune

Dear fellow developers,

 Here is the second revision of the ABI extension specification previously 
posted, incorporating feedback received for the first revision.  Changes 
have been made to Section 4 "Implementation Notes", the remaining parts
have stayed the same.  The master copy of this document is available at:

<https://dmz-portal.mips.com/wiki/MIPS_ABI_-_NaN_Interlinking>

 Please let me know if you have any questions, comments or concerns about 
this updated version.  Otherwise I will wait a short while and then follow 
up with an updated implementation.

 Thanks to all of you who took time to read the first revision and comment 
on it, and especially Joseph Myers.

  Maciej

-------------------------------------------------------------------------- 
MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking

1. Introduction

 The MIPS architecture has supported IEEE Std 754 floating-point
arithmetic since its beginning in 1985.  Naturally as initial support was
for the original 1985 revision of the standard then particular choices
were made for the architecture where freedom was given by that revision.
This was the case with not-a-number (NaN) symbolic data and the bit
patterns chosen to represent them.  Later on this choice turned out to be
different from ones used by all other IEEE Std 754 implementers.  Hardware
implementing this original MIPS architecture definition and corresponding
software and ABIs will be referred across this document as legacy-NaN
hardware, software and ABIs respectively, and the NaN patterns themselves
as legacy NaN patterns.

 The patterns originally chosen had their advantage in the MIPS
architecture, however an updated revision of IEEE Std 754 released in 2008
made the NaN patterns chosen by other implementers preferred.  MIPS
architecture overseers decided to follow the recommendation and update the
architecture definition accordingly.  Consequently a set of amended ABIs
has been created to provide for software execution on hardware
implementing the updated architecture.  Such hardware, software and ABIs
will be referred across this document to as 2008-NaN hardware, software
and ABIs respectively, and the NaN patterns themselves as to 2008 NaN
patterns.

 The legacy and 2008 NaN patterns are not compatible with each other and
therefore the respective ABIs and software binaries are not.  To keep all
software compliant to IEEE Std 754 a decision was made to disallow mixing
legacy-NaN and 2008-NaN software modules in static linking and dynamic
loading, and at the OS level disallow execution of 2008-NaN software on
legacy-NaN hardware and vice versa.

2. Statement of the Problem

 The decisions made so far about the MIPS architecture and ABIs have led
to a situation where the large existing base of software binaries cannot
execute on current hardware.  And this applies regardless of whether it
relies on the use of NaN data or IEEE Std 754 arithmetic in the first
place.  Rebuilding all of the existing software for 2008-NaN hardware is
infeasible and additionally such software, rebuilt or new, will not run on
legacy-NaN hardware that is widely deployed, so maintaining two binary
versions of the same piece of software would often be required.

3. Solution

 The solution described here has been prepared with the Linux environment
in mind, although where applicable individual changes are also appropriate
for bare-metal environments.

 A number of changes are made at different levels to make the transition
to 2008-NaN hardware easier as well as long-term support for legacy-NaN
hardware that is undoubtedly going to stay around for a while.  They are
detailed from the hardware level up in the following sections.

3.1 Hardware and Operating System Interface

 The operating system tells legacy-NaN and 2008-NaN software apart by
examining the state of the EF_MIPS_NAN2008 flag in the ELF file header of
individual binaries requested for execution with the execve(2) system
call.  The value of `0' of the flag denotes legacy-NaN software and the
value of `1' denotes 2008-NaN software.

3.1.1 Floating-Point Emulation

 Where possible both legacy-NaN and 2008-NaN software will be supported.
The MIPS architecture itself makes it possible and therefore the FPU
emulator used on hardware that does not implement an FPU will set itself
to the right mode individually for every legacy-NaN or 2008-NaN program
executed.

 On Linux the FPU emulator can also be enabled unconditionally even on
hardware that does implement an FPU, with the use of the `nofpu' kernel
option.  In this case both legacy-NaN and 2008-NaN software will be
automatically supported, although at a performance loss compared to FPU
hardware.

3.1.2 Global IEEE Std 754 Compliance Mode

 A new `ieee754=' kernel option is provided for cases where strict IEEE
Std 754 compliance is not required.  This makes it possible to use
binaries from existing Linux distributions on new 2008-NaN hardware making
the transition easier.  At least two values are accepted on the right hand
side of this option, `strict' and `relaxed', to select between IEEE Std
754 compliance modes.  These modes shall only affect software that does
not make an explicit mode selection as noted in Section 3.1.3 below.

 In the `strict' mode, which is the default in the absence of an explicit
`ieee754=' option, only software compatible with the NaN patterns handled
by FPU hardware shall be accepted for execution, that is legacy-NaN
software on legacy-NaN hardware and 2008-NaN software on 2008-NaN
hardware.

 In the `relaxed' mode any software shall be accepted for execution,
regardless of whether it is compatible with FPU hardware.  Additionally,
in the `relaxed' mode, even if enabled with the FCSR.Enables.V bit, any
IEEE Std 754 Invalid Operation exceptions triggered with an sNaN
instruction operand shall not result in a SIGFPE signal being issued to
the originating process and a qNaN (encoded according to the current mode
set in the floating-point environment) shall be substituted and propagated
through the arithmetic operation requested as with a qNaN operand.

 Additionally, to make the dynamic loader aware that the `relaxed' IEEE
Std 754 compliance mode is in effect, bit #25 shall be set in the `a_val'
member of the AT_FLAGS entry of the auxiliary vector created by the
kernel on program execution for any program accepted for this mode.  This
bit is in the part of the flag word reserved for system semantic by the
MIPS psABI[1].  This bit shall be set to `0' in the `strict' mode and `1'
in the `relaxed' mode.

 Additional values may be accepted with the kernel option and consequently
modes provided now or in the future, but they are beyond the scope of this
document.

3.1.3 Per Program Individual IEEE Std 754 Compliance Mode

 Individual programs can select their required IEEE Std 754 compliance
mode regardless of the global mode.  Individual selection takes precedence
over the global selection.  Programs that select their individual mode
shall have a PT_MIPS_ABIFLAGS segment and shall have bit #1 set in its
`flags1' member.  The specific mode selected is then determined by the
value of bit #1 in this segment's `flags2' member, `0' for the `strict'
mode and `1' for the `relaxed' mode.

 The semantics of such individually selected IEEE Std 754 compliance
mode is the same as that of the corresponding global mode.  See Section
3.1.2 above for further details.

3.1.4 Dynamic IEEE Std 754 Compliance Mode Control

 A new request is provided via the prctl(2) system call to let a process
switch its own IEEE Std 754 compliance mode.  This is for example to let
a dynamic loader invoked manually set the compliance mode for an
executable requested as if the executable was run directly and its
compliance mode preset by the kernel.  The request shall be made as
follows:

  int result;
  result = prctl(PR_SET_IEEE754_MODE, mode, what);

 In this request `mode' shall be set to one of the following:

* PR_IEEE754_MODE_LEGACY -- to set the compliance mode used with programs
  which do not make an individual IEEE Std 754 compliance mode selection,

* PR_IEEE754_MODE_STRICT -- to set the `strict' compliance mode,

* PR_IEEE754_MODE_RELAXED -- to set the `relaxed' compliance mode,

and `what' shall be set to either of:

* PR_IEEE754_MODE_NAN_LEGACY -- to select the legacy-NaN encoding mode,

* PR_IEEE754_MODE_NAN_2008 -- to select the 2008-NaN encoding mode.

The kernel shall execute the request according to the rules set out in
Subsection 3.1.2 and Subsection 3.1.3 for the ELF file flag settings
corresponding to the respective IEEE Std 754 compliance and NaN encoding
modes requested.

 If the request is successful a non-negative value shall be assigned to
`result', in which bits 7:0 are set to a pattern that would be placed in
bits 31:24, in the same bit order, of the `a_val' member of the AT_FLAGS
entry of the auxiliary vector created by the kernel on program execution
for the mode selected.

3.2 Dynamic Loading

 The dynamic loader shall recognise IEEE Std 754 compliance modes and
resolve main executable's dependencies according to rules set below.  For
the purpose of these rules a main executable is the binary named in an
execve(2) call to the operating system, and a dependency is any dynamic
shared object additionally loaded, via any means including but not
necessarily limited to a DT_NEEDED dynamic segment entry, an LD_PRELOAD
environment variable or a dlopen(3) library call.

3.2.1 IEEE Std 754 Compliance Mode Selection

 Both executables and dynamic shared objects can select their required
IEEE Std 754 compliance mode.  A binary requiring a specific compliance
mode shall have a PT_MIPS_ABIFLAGS segment and shall have its contents
set according to rules set out in Section 3.1.3.  Such a binary will
be referred to as `strict' or `relaxed'.  Binaries that have no
PT_MIPS_ABIFLAGS segment or have one that does not request a specific
compliance mode will be referred to as `legacy'.

3.2.2 Dynamic Dependency Acceptance Rules

 The IEEE Std 754 compliance mode requested is determined by the main
executable.  Any dynamic shared objects loaded in addition shall respect
the mode according to the rules set below.

 For `strict' executables all the dynamic shared objects shall follow the
same legacy-NaN or 2008-NaN ABI, as denoted by the EF_MIPS_NAN2008 flag
described in Section 3.1.  The value of the flag shall be the same across
the executable and all the dynamic shared objects loaded together.  Both
`strict' and `legacy' dynamic shared objects shall be accepted, however
`relaxed' ones shall be rejected regardless of the value of their
EF_MIPS_NAN2008 flag.

 For `relaxed' executables any dynamic shared objects shall be accepted,
`strict', `relaxed' and `legacy' alike, regardless of the value of their
EF_MIPS_NAN2008 flag.

 For `legacy' executables the compliance mode is determined by the value
of bit #25 in the `a_val' member of the AT_FLAGS entry of the auxiliary
vector received from the kernel.  The value of `0' shall make the dynamic
loader follow the rules for `strict' executables.  The value of `1' shall
make the dynamic loader follow the rules for `relaxed' executables.

3.2.3 Dynamic Loading Compatibility Considerations

 The encoding for the PT_MIPS_ABIFLAGS segment has been selected such that
old versions of the dynamic loader will reject `relaxed' binaries because
of an unknown `flags2' bit set.  This is to prevent execution in an
environment that does not follow the rules set out in this specification
and to signify the need to upgrade.  Both `strict' and `legacy' binaries
will run correctly as they follow the rules defined for old versions of
the dynamic loader.

 Older versions of the dynamic loader will not process a PT_MIPS_ABIFLAGS
segment and will only examine the EF_MIPS_NAN2008 flag.  Very old versions
of the dynamic loader will not even process the flag.  It is therefore not
possible to guarantee that the rules set out here will be followed or an
error triggered with older systems.

3.3 Static Linking

 The static linker shall recognise IEEE Std 754 compliance modes and
enforce the rules set below for all static links, both final ones that
produce an executable or a dynamic shared object and incremental ones
that produce a relocatable object.

3.3.1 IEEE Std 754 Compliance Mode Selection

 All relocatable objects can select their required IEEE Std 754 compliance
mode.  An object requiring a specific compliance mode shall have an
SHT_MIPS_ABIFLAGS section called `.MIPS.abiflags' and shall have its
contents set according to rules set out for the PT_MIPS_ABIFLAGS segment
in Section 3.1.3.  Such an object will be referred to as `strict' or
`relaxed'.  Objects that have no SHT_MIPS_ABIFLAGS section or have one
that does not request a specific compliance mode will be referred to as
`legacy'.  On making an executable or a dynamic shared object the linker  
shall map an SHT_MIPS_ABIFLAGS section to a PT_MIPS_ABIFLAGS segment.

3.3.2 Static Linking Object Acceptance Rules

 The static linker shall follow the user selection as to the linking mode
used, either of `strict' and `relaxed'.  The selection will be made
according to the usual way assumed for the environment used, which may be
a command-line option, a property setting, etc.

 In the `strict' linking mode both `strict' and `legacy' objects can be
linked together.  All shall follow the same legacy-NaN or 2008-NaN ABI, as
denoted by the EF_MIPS_NAN2008 flag described in Section 3.1.  The value
of the flag shall be the same across all the objects linked together.  The
output of a link involving any `strict' objects shall be marked as
`strict'.  No `relaxed' objects shall be allowed in the same link.

 In the `relaxed' linking mode any `strict', `relaxed' and `legacy'
objects can be linked together, regardless of the value of their
EF_MIPS_NAN2008 flag.  If the flag has the same value across all objects
linked, then the value shall be propagated to the binary produced.  The
output shall be marked as `relaxed'.  It is recommended that the linker
provides a way to warn the user whenever a `relaxed' link is made of
`strict' and `legacy' objects only.

3.3.3 Static Linking Compliance Mode Warnings

A flag shall be defined in bit #0 of the `flags2' member of the
PT_MIPS_ABIFLAGS section, determining the warning mode for IEEE Std 754
compliance in static linking.  This bit shall be set to `0' to enable
the warning mode (`warn' mode) and `1' to disable it (`nowarn' mode).  The
bit shall propagate through an incremental static link in an
implementation-defined manner, however it shall be set to `0' in a final
static link.

3.3.4 Static Linking Compatibility Considerations

 The encoding for the SHT_MIPS_ABIFLAGS section has been selected such
that old versions of the static linker will reject `relaxed' binaries
because of an unknown `flags2' bit set.  This is to prevent incorrectly
annotated objects from being produced that would not guarantee IEEE Std
754 compliance.

 The encoding has also been selected such that old versions of the static
linker will merge the `flags1' bit used to tell `legacy' objects and
`strict'/`relaxed' ones apart, automatically marking the output of links
involving any `strict' objects as `strict' as well.

 Older versions of the static linker will not process an SHT_MIPS_ABIFLAGS
section and will only examine the EF_MIPS_NAN2008 flag.  Consequently they
may allow `relaxed' objects in a single link with `strict' and `legacy'
ones.

3.4 Relocatable Object Generation

 Tools that produce relocatable objects such as the assembler shall always
produce a SHT_MIPS_ABIFLAGS section according to the IEEE Std 754
compliance mode selected.  In the absence of any explicit user
instructions the `strict' mode shall be assumed.  No new `legacy' objects
shall be produced.

3.5 No-float Modules

 Certain modules used in dynamic loading or static linking may be marked
as containing no floating-point code, in a way defined by a separate
specification.  Such modules shall always be accepted for dynamic loading
and static linking, and for the purpose of IEEE Std 754 compliance checks
treated as if absent.

3.6 Definitions

 The following macros shall be defined for the flags introduced by this
document:

/* `flags1' member of the PT_MIPS_ABIFLAGS/SHT_MIPS_ABIFLAGS structure.  */
#define MIPS_AFL_FLAGS1_IEEE    2       /* IEEE Std 754 mode defined.  */

/* `flags2' members of the PT_MIPS_ABIFLAGS/SHT_MIPS_ABIFLAGS structure.  */
#define MIPS_AFL_FLAGS2_NOWARN  1       /* Suppress IEEE Std 754 warnings.  */
#define MIPS_AFL_FLAGS2_RELAXED 2       /* Relaxed IEEE Std 754 mode.  */

/* `a_val' member of the AT_FLAGS entry.  */
#define AV_FLAGS_MIPS_RELAXED   (1 << 25) /* Relaxed IEEE Std 754 mode.  */

It is unspecified at this time whether the bits referred to with
MIPS_AFL_FLAGS2_RELAXED and AV_FLAGS_MIPS_RELAXED are single-bit bitfields
or the least significant bits of a larger enumeration, to be defined
later.

 The following macros shall be defined for the prctl(2) interface
introduced by this document:

/* Control MIPS IEEE 754 compliance modes.  */
#define PR_SET_IEEE754_MODE             TBA

#define PR_IEEE754_MODE_LEGACY          0       /* Legacy mode.  */
#define PR_IEEE754_MODE_STRICT          1       /* Strict mode.  */
#define PR_IEEE754_MODE_RELAXED         2       /* Relaxed mode.  */

#define PR_IEEE754_MODE_NAN_LEGACY      0       /* Set legacy NaN encoding.  */
#define PR_IEEE754_MODE_NAN_2008        1       /* Set 2008 NaN encoding.  */

4. Implementation Notes

 For the GNU linker the command-line options to select between the
`strict' and the `relaxed' IEEE Std 754 compliance modes will be
`--ieee=strict' and `--ieee=relaxed', respectively.  The latter will issue
a compliance warning in the case where all input objects were either
`strict' and `warn' or `legacy' mode, unless a `--ieee=nowarn' option has
also been used.  There will be a `--ieee=warn' option as well to revert
the effect of the former option.

 For the GNU assembler the directives to select between the `strict' and
the `relaxed' IEEE Std 754 compliance modes will be `.ieee strict' and
`.ieee relaxed', respectively.  Equivalent command-line options will be
present, `-mieee=strict' and `-mieee=relaxed', respectively.  There will
be `.ieee nowarn' and `.ieee warn' directives as well to set and clear
the IEEE Std 754 warning flag respectively in the SHT_MIPS_ABIFLAGS
section.  Their corresponding command-line options will be `-mieee=nowarn'
and `-mieee=warn' respectively.

 For the GNU Compiler Collection (GCC) the following target-specific
command-line options will be accepted:

* `-mieee=strict', making the toolchain produce `strict' binaries,

* `-mieee=relaxed-exec', making the toolchain produce `strict' shared
  libraries and `relaxed' executables,

* `-mieee=relaxed', making the toolchain produce `relaxed' binaries,

* `-mieee=force-relaxed', making the toolchain produce `relaxed' binaries,
  while suppressing IEEE Std 754 static linking warnings.

Any or all of these options may have target-specific effects beyond
propagating the IEEE Std 754 compliance mode down to the assembler and the
linker.

 It is expected that `-mieee=strict' and `-mieee=relaxed-exec' options
will be set by appropriate generic `-fieee' options, to be defined, which
will be also available for selection as configuration defaults at the GCC
build time.  It is also expected that along `-mieee=strict' the relevant
`-fieee' option and its corresponding configuration default will set the
compiler into a mode in which it will produce strictly compliant code,
which in the context of this specification is defined as: following IEEE
Std 754 as closely as the programming language binding to the standard
(defined in the relevant language standard), the compiler implementation
and target hardware permit.  This means that the use of `-fieee' options
may affect code produced in ways beyond NaN representation only.

 There may be further GCC options to control IEEE Std 754 compliance, to
be defined.

5. Future Considerations

 While at the time of this writing the `strict' and `relaxed' IEEE Std 754
compliance modes only apply to NaN representation patterns, it is possible
that in the future other IEEE Std 754 compliance matters may require
communicating through linking and loading down to the operating system
kernel.  Therefore a decision has been made to use generic names for the
modes, macros, directives and option names defined here.  If such a need
arises in the future, then the meaning of these names may be extended to
cover other compliance aspects and further modes can be added that are
intermediate between `strict' and `relaxed', to be used with the `.ieee'
directive and the `-mieee=' command-line options.

References:

[1] "SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor
    Supplement, 3rd Edition", Section "Process Stack", pp. 3-33, 3-34

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [RFC v2] MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking
  2016-05-14 17:10 [RFC v2] MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking Maciej W. Rozycki
  2016-05-14 17:10 ` Maciej W. Rozycki
@ 2016-05-16 14:21 ` Matthew Fortune
  2016-07-13 23:16   ` Maciej W. Rozycki
  1 sibling, 1 reply; 8+ messages in thread
From: Matthew Fortune @ 2016-05-16 14:21 UTC (permalink / raw)
  To: Maciej Rozycki, linux-mips, libc-alpha, binutils, gcc; +Cc: Joseph Myers

Hi Maciej,

Thanks for the update.  I've read through the whole proposal again and
it looks good.  I'd like to discuss legacy objects a bit more though...

Maciej Rozycki <Maciej.Rozycki@imgtec.com> writes:
> 3.4 Relocatable Object Generation
> 
>  Tools that produce relocatable objects such as the assembler shall
> always produce a SHT_MIPS_ABIFLAGS section according to the IEEE Std 754
> compliance mode selected.  In the absence of any explicit user
> instructions the `strict' mode shall be assumed.  No new `legacy'
> objects shall be produced.

Is it necessary to say that no new legacy objects can be created?

I think there is value in still being able to generate legacy objects because
of the fact that strict executables leave no room for override at runtime.
Apart from the fact that strict cannot be disabled there is otherwise no
difference between legacy and strict compliance modes.

I believe the strict option is really intended for conscious use so that
programmers who know they need it, can use it. Ordinary users still get the
casual safety they need as legacy objects are just as good as strict until
overridden. If we lose the ability to override then in some environments we
will accumulate lots of needlessly strict executables just because of a tools
upgrade whereas the old tools would have generated executables that were as
safe but also could be overridden by kernel options. 

Allowing legacy objects to be generated may also allow the linkage rules to
be tightened.  I.e. Forcing a relaxed mode at link time could simply fail
if confronted by a strict object instead only allowing legacy objects to
be relaxed.

A default build of GCC and binutils would therefore still generate legacy
objects until someone consciously updated the configure options or used
command line options.

Thanks,
Matthew

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [RFC v2] MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking
  2016-05-16 14:21 ` Matthew Fortune
@ 2016-07-13 23:16   ` Maciej W. Rozycki
  2016-07-25 15:49     ` Joseph Myers
  2016-11-11 10:23     ` Matthew Fortune
  0 siblings, 2 replies; 8+ messages in thread
From: Maciej W. Rozycki @ 2016-07-13 23:16 UTC (permalink / raw)
  To: Matthew Fortune, Joseph Myers; +Cc: linux-mips, libc-alpha, binutils, gcc

Hi Matthew,

 I'm back to this effort now, thanks for patience.

> Thanks for the update.  I've read through the whole proposal again and
> it looks good.  I'd like to discuss legacy objects a bit more though...

 Thanks for your review.

> > 3.4 Relocatable Object Generation
> > 
> >  Tools that produce relocatable objects such as the assembler shall
> > always produce a SHT_MIPS_ABIFLAGS section according to the IEEE Std 754
> > compliance mode selected.  In the absence of any explicit user
> > instructions the `strict' mode shall be assumed.  No new `legacy'
> > objects shall be produced.
> 
> Is it necessary to say that no new legacy objects can be created?

 It is of course not necessary in the sense that we are free to make a 
decision here rather than being constrained by hardware or another 
technical requirement.

 However I think only supporting the two explicit `strict' and `relaxed' 
modes makes the solution proposed consistent, and has indeed been the 
basis of my design.

 The principle I have followed here has been that it's the author of 
software who knows exactly what his code requires for correct operation, 
and sets the correct flags in the Makefile or whatever build system he 
uses.  Joseph's earlier proposal to have a generic `-fieee' option rather 
than a target one fits here very well in that the author can stick it in 
the build system without the exact knowledge of what target-specific 
constraints may be.  Such an option would preferably be placed such that 
it is not accidentally lost e.g. with an OS distribution packager's CFLAGS 
override, which is typically made in a system-wide automated way when a 
distribution is build.

 Still a distribution packager or another person building their piece of 
software of interest, perhaps individually, has control here, being able 
to change build options one way or another, at least by patching Makefiles 
if necessary.  So they can choose `strict' or `relaxed' as needed.

 Finally the system administrator configuring a system or the individual 
user running software has the least knowledge of the low-level 
requirements of individual pieces of software.

 So ideally we'd not even have these kernel override modes and 
unconditionally treat `legacy' binaries as `strict', under the principle 
of the least surprise.  Realistically however that would make the 
transition to R5/R6 very painful for people, requiring them to rebuild all 
software previously built for the legacy NaN encoding, even though only a 
small subset of software actually relies on the semantics of signalling 
NaNs.

 And this is exactly where the idea of a user-selectable kernel acceptance 
mode came from.  I expect that both existing and new installations on 
legacy-NaN hardware will continue operating with the `strict' conformance 
mode and won't ever have to switch that as any new software built for 
pre-R5 targets and with the 2008-NaN encoding in mind will be built as 
`relaxed' binaries.  Whereas virtually all R5/R6 installations will run in 
the `relaxed' conformance mode, permitting the use of any existing pre-R5 
`legacy' binaries, however with the risk of some of them producing the 
wrong results.

 Consequently allowing new tools to build more `legacy' binaries will just 
let the issue continue where the mode software being run in depends on the 
hardware configuration rather than a conscious choice of the software 
packager.  Whereas support for running `legacy' binaries in the `relaxed' 
mode is really there to help people transition.

> I think there is value in still being able to generate legacy objects because
> of the fact that strict executables leave no room for override at runtime.
> Apart from the fact that strict cannot be disabled there is otherwise no
> difference between legacy and strict compliance modes.

 Can you please be more specific?  Where's the value from letting people 
override the mode of software known to require signalling NaN support?

> I believe the strict option is really intended for conscious use so that
> programmers who know they need it, can use it. Ordinary users still get the
> casual safety they need as legacy objects are just as good as strict until
> overridden. If we lose the ability to override then in some environments we
> will accumulate lots of needlessly strict executables just because of a tools
> upgrade whereas the old tools would have generated executables that were as
> safe but also could be overridden by kernel options. 

 I think the casual safety is an illusion.

 As soon as a user gets an execution error from a legacy-NaN legacy binary 
on 2008-NaN hardware (or vice versa), they'll hit Google or discussion 
list archives for a solution, find the `ieee754=relaxed' kernel option, 
stick it into their bootloader configuration and forget about it, running 
all their software from the on in the `relaxed' mode anyway.

 Eventually distributions will probably do that as well even if they built 
their own packages as `relaxed', to reduce support noise from people 
running `legacy' third-party software built for the opposite NaN encoding.

 Now, assuming that their software is indeed safe for `relaxed' mode 
operation with the binary `strict'/`relaxed' choice available you have 
valuable information carried within binaries themselves -- they tell you 
whether they care about signalling NaN interpretation or not rather than 
maybe/maybe-not.

> Allowing legacy objects to be generated may also allow the linkage rules to
> be tightened.  I.e. Forcing a relaxed mode at link time could simply fail
> if confronted by a strict object instead only allowing legacy objects to
> be relaxed.

 We can still have a mode where a `strict' object is rejected in a static 
link.  Though I'm not sure if there's value in it.  If so, then perhaps we 
need a `never relax' flag instead.  Do you have a specific use case in 
mind?

> A default build of GCC and binutils would therefore still generate legacy
> objects until someone consciously updated the configure options or used
> command line options.
 
 As I've argued above I'm inconvinced that keeping the `legacy' mode 
supported for newly built binaries is a good idea.  If you're concerned 
about software being built as `strict' unnecessarily, then I think we have 
two solutions here:

1. We can default the toolchain configuration to the `relaxed' (or 
   strictly speaking the `relaxed-exec') mode.  This way someone upgrading 
   their OS from sources will not fall into a trap of building their 
   software as `strict' by the lone result of missing the required 
   newly-added configuration option, rather than a conscious decision.  I 
   think this would be a reasonably safe move, as a signalling NaN support
   requirement is I believe relatively uncommon across software.

2. An idea has been proposed to have objects marked by the assembler to 
   indicate whether they include an FP hardware instruction or not.  The 
   latters would automatically become don't-cares as far as NaN encoding
   is concerned and if all the objects were such in a given static link, 
   then the resulting executable would become NaN-encoding agnostic, 
   ignoring any `strict' or `relaxed' modes.  This would exclude a large
   amount of software from the checks discussed in this specification,
   although a question still remains open how shared libraries loaded by 
   such a program would be treated if they for a change did include FP
   hardware instructions.

Does either of the proposals address your concerns?  Is there anything I 
may have missed here?

 I will appreciate input from other people as well, so that it's not a 
discussion just between Matthew and myself.  Joseph, does your experience 
in this area give you any insights?

  Maciej

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [RFC v2] MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking
  2016-07-13 23:16   ` Maciej W. Rozycki
@ 2016-07-25 15:49     ` Joseph Myers
  2016-11-11 10:23     ` Matthew Fortune
  1 sibling, 0 replies; 8+ messages in thread
From: Joseph Myers @ 2016-07-25 15:49 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: Matthew Fortune, linux-mips, libc-alpha, binutils, gcc

On Thu, 14 Jul 2016, Maciej W. Rozycki wrote:

> 2. An idea has been proposed to have objects marked by the assembler to 
>    indicate whether they include an FP hardware instruction or not.  The 
>    latters would automatically become don't-cares as far as NaN encoding
>    is concerned and if all the objects were such in a given static link, 

I don't think presence of FP hardware instructions is much of a guide to 
whether code cares about NaN encodings.  I'd expect most code simply doing 
arithmetic not to care (that is, the same object code would work correctly 
on systems with either NaN encoding - given the right encodings for that 
system as inputs, it would produce the right encodings as outputs), while 
code using a NaN encoding explicitly (typically through __builtin_nan or 
folded 0.0 / 0.0 in a static initializer) cares even if that object does 
not use FP instructions.  (Formally, of course code knowing the ABI can 
creating encodings directly, implement issignaling itself, etc., but that 
should be rare.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [RFC v2] MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking
  2016-07-13 23:16   ` Maciej W. Rozycki
  2016-07-25 15:49     ` Joseph Myers
@ 2016-11-11 10:23     ` Matthew Fortune
  2017-08-24 15:34       ` Maciej W. Rozycki
  1 sibling, 1 reply; 8+ messages in thread
From: Matthew Fortune @ 2016-11-11 10:23 UTC (permalink / raw)
  To: Maciej Rozycki, Joseph Myers; +Cc: linux-mips, libc-alpha, binutils, gcc

Maciej Rozycki <Maciej.Rozycki@imgtec.com> writes:
>  I'm back to this effort now, thanks for patience.

Likewise, this thread got buried in email. At the risk of further delaying
this work I do still have issues with the design.

> > > 3.4 Relocatable Object Generation
> > >
> > >  Tools that produce relocatable objects such as the assembler shall
> > > always produce a SHT_MIPS_ABIFLAGS section according to the IEEE Std
> > > 754 compliance mode selected.  In the absence of any explicit user
> > > instructions the `strict' mode shall be assumed.  No new `legacy'
> > > objects shall be produced.
> >
> > Is it necessary to say that no new legacy objects can be created?
> 
>  It is of course not necessary in the sense that we are free to make a
> decision here rather than being constrained by hardware or another
> technical requirement.
> 
>  However I think only supporting the two explicit `strict' and `relaxed'
> modes makes the solution proposed consistent, and has indeed been the
> basis of my design.

This is the bit I think is actually less consistent than it seems on the
surface. The issue is that we have to punch holes in the design in order
to facilitate those users who don't care about ieee compliance and the
way it is done currently is that we allow the static linker to completely
override the 'strict'ness of an input object when using --ieee=relaxed.

This means that a user consciously creating an object that 'needs' ieee
compliance via use of -fieee=strict or -mieee=strict is thwarted by the
next user who builds the executable. This kind of scenario can occur with
a static library prepared by an expert in floating point and then someone
casually including that into a bigger application. Obviously a similar
issue is present with the rules around executable and shared libraries
where the executable's compliance mode can override a shared library
but at this level we are not losing any information and the executable
has either very specifically been set to 'relaxed' mode or the kernel
has set legacy to mean relaxed. The latter can at least be fixed by
changing the kernel. Losing information in a static link cannot be
fixed.

The assumption in the specification is that a user creating a final
executable is the one who should know about ieee compliance issues but
I am not convinced about this. I think it is at the compilation unit
level that issues of ieee compliance should be decided and that should
be a conscious act of the user (or toolchain packager if they want to
force all software to care). I.e. a strict object is strict without
exception throughout static linkage.

The point about not removing legacy objects is that it is an ideal
container for individual objects that don't care or don't yet know
they care about ieee compliance.

The relaxed variant then only becomes applicable when linking multiple
objects and a user has specifically asked to downgrade legacy to relaxed.
Given a legacy object could already be downgraded to relaxed under the
current spec then this does not affect the behaviour of a legacy object.

What this also means is that we can propagate 'legacy' objects through
relocatable links to still get a legacy object which is consistent with
respect to its nan encoding and only later at final link downgrade,
upgrade or retain the compliance level.

These rules combined also mean that a new toolchain that includes
support for these features will, by default, just continue to behave
as today which is the norm for new features. If a user or toolchain
packager decides to enforce stricter ieee checks then they can and
they can face the complexities of combining old and new software
packages as laid out in this spec.

The static linker rules would be almost the same as now but would
not allow strict to be downgraded to relaxed and the 'default' behaviour
could result in legacy objects if they were the only ones in the link.
The spec is currently a little vague on default linker behaviour when
no --ieee option is given but the rules for combining objects without
an override seem relatively obvious. Any 'relaxed' object leads to
a relaxed executable, any 'strict' object leads to a strict executable,
'strict' and 'relaxed' cannot mix, otherwise 'legacy'. This also
eliminates the need for 'nowarn/warn'.

>  The principle I have followed here has been that it's the author of
> software who knows exactly what his code requires for correct operation,
> and sets the correct flags in the Makefile or whatever build system he
> uses.  Joseph's earlier proposal to have a generic `-fieee' option
> rather than a target one fits here very well in that the author can
> stick it in the build system without the exact knowledge of what target-
> specific constraints may be.  Such an option would preferably be placed
> such that it is not accidentally lost e.g. with an OS distribution
> packager's CFLAGS override, which is typically made in a system-wide
> automated way when a distribution is build.
> 
>  Still a distribution packager or another person building their piece of
> software of interest, perhaps individually, has control here, being able
> to change build options one way or another, at least by patching
> Makefiles if necessary.  So they can choose `strict' or `relaxed' as
> needed.

Agreed but this is a per object issue not per executable hence the
proposal above.
 
>  Finally the system administrator configuring a system or the individual
> user running software has the least knowledge of the low-level
> requirements of individual pieces of software.

As above I believe this includes the person building an executable as
well.

>  So ideally we'd not even have these kernel override modes and
> unconditionally treat `legacy' binaries as `strict', under the principle
> of the least surprise.  Realistically however that would make the
> transition to R5/R6 very painful for people, requiring them to rebuild
> all software previously built for the legacy NaN encoding, even though
> only a small subset of software actually relies on the semantics of
> signalling NaNs.
> 
>  And this is exactly where the idea of a user-selectable kernel
> acceptance mode came from.  I expect that both existing and new
> installations on legacy-NaN hardware will continue operating with the
> `strict' conformance mode and won't ever have to switch that as any new
> software built for
> pre-R5 targets and with the 2008-NaN encoding in mind will be built as
> `relaxed' binaries.  Whereas virtually all R5/R6 installations will run
> in the `relaxed' conformance mode, permitting the use of any existing
> pre-R5 `legacy' binaries, however with the risk of some of them
> producing the wrong results.

I have no objections to any of the kernel level support. I think it safely
covers all the requirements.
 
>  Consequently allowing new tools to build more `legacy' binaries will
> just let the issue continue where the mode software being run in depends
> on the hardware configuration rather than a conscious choice of the
> software packager.  Whereas support for running `legacy' binaries in the
> `relaxed'
> mode is really there to help people transition.

We don't need to make this choice for users though. They can make it
for themselves. It is not end users that will make the initial decision
anyway it is distribution maintainers. If those distro maintainers don't
care then we should not remove the tools to do what they want.
 
> > I think there is value in still being able to generate legacy objects
> > because of the fact that strict executables leave no room for override
> at runtime.
> > Apart from the fact that strict cannot be disabled there is otherwise
> > no difference between legacy and strict compliance modes.
> 
>  Can you please be more specific?  Where's the value from letting people
> override the mode of software known to require signalling NaN support?

As above the spec actually permits overriding software known to require
signalling NaN support currently which is the basis of my concerns. This
is the linker level --ieee=relaxed option which I expect would end up the
default in any general purpose distro.

Ref: section 3.3.2 third paragraph.

> > I believe the strict option is really intended for conscious use so
> > that programmers who know they need it, can use it. Ordinary users
> > still get the casual safety they need as legacy objects are just as
> > good as strict until overridden. If we lose the ability to override
> > then in some environments we will accumulate lots of needlessly strict
> > executables just because of a tools upgrade whereas the old tools
> > would have generated executables that were as safe but also could be
> overridden by kernel options.
> 
>  I think the casual safety is an illusion.
> 
>  As soon as a user gets an execution error from a legacy-NaN legacy
> binary on 2008-NaN hardware (or vice versa), they'll hit Google or
> discussion list archives for a solution, find the `ieee754=relaxed'
> kernel option, stick it into their bootloader configuration and forget
> about it, running all their software from the on in the `relaxed' mode
> anyway.
> 
>  Eventually distributions will probably do that as well even if they
> built their own packages as `relaxed', to reduce support noise from
> people running `legacy' third-party software built for the opposite NaN
> encoding.
> 
>  Now, assuming that their software is indeed safe for `relaxed' mode
> operation with the binary `strict'/`relaxed' choice available you have
> valuable information carried within binaries themselves -- they tell you
> whether they care about signalling NaN interpretation or not rather than
> maybe/maybe-not.

I think you took my comments to suggest I didn't agree with having strict
binaries at all. Quite the opposite, the new 'strict' mode is essential
similarly for relaxed albeit I don't find relaxed quite as important it
plays a part.
 
> > Allowing legacy objects to be generated may also allow the linkage
> > rules to be tightened.  I.e. Forcing a relaxed mode at link time could
> > simply fail if confronted by a strict object instead only allowing
> > legacy objects to be relaxed.
> 
>  We can still have a mode where a `strict' object is rejected in a
> static link.  Though I'm not sure if there's value in it.  If so, then
> perhaps we need a `never relax' flag instead.  Do you have a specific
> use case in mind?

I think I've covered this above. I do not believe we need to complicate
this any further to achieve the goals as legacy objects already have
a suitable definition to handle the case of
'strict-by-default-but-relaxable'
 
> > A default build of GCC and binutils would therefore still generate
> > legacy objects until someone consciously updated the configure options
> > or used command line options.
> 
>  As I've argued above I'm inconvinced that keeping the `legacy' mode
> supported for newly built binaries is a good idea.  If you're concerned
> about software being built as `strict' unnecessarily, then I think we
> have two solutions here:

No that is not my concern. My concern is that at static link time we
can disregard the strict flag.

> 1. We can default the toolchain configuration to the `relaxed' (or
>    strictly speaking the `relaxed-exec') mode.  This way someone
> upgrading
>    their OS from sources will not fall into a trap of building their
>    software as `strict' by the lone result of missing the required
>    newly-added configuration option, rather than a conscious decision.
> I
>    think this would be a reasonably safe move, as a signalling NaN
> support
>    requirement is I believe relatively uncommon across software.

Regardless of the detail of the spec I am absolutely certain that the
default options used for tools in debian and fedora will mean all
executables turn out as relaxed (or legacy) i.e. all compatible with both
HW nan encodings. It would actually be safer if the binaries came out
as legacy like today then relaxed because at least then we would still
know they have a consistent nan encoding and it is only the kernel that
is involved in deciding if they should be accepted on incompatible HW
or not. If we get relaxed by default then nobody can control whether they
are accepted on incompatible hardware.

> 2. An idea has been proposed to have objects marked by the assembler to
>    indicate whether they include an FP hardware instruction or not.  The
>    latters would automatically become don't-cares as far as NaN encoding
>    is concerned and if all the objects were such in a given static link,
>    then the resulting executable would become NaN-encoding agnostic,
>    ignoring any `strict' or `relaxed' modes.  This would exclude a large
>    amount of software from the checks discussed in this specification,
>    although a question still remains open how shared libraries loaded by
>    such a program would be treated if they for a change did include FP
>    hardware instructions.

Definitely need to work on attributing modules that truly don't care about
floating point but this issue does not reduce/increase my concerns about
the spec for the ieee compliance features.

> Does either of the proposals address your concerns?  Is there anything I
> may have missed here?

Sorry for all the proposed changes but I think we have got more complexity
than necessary so need to work through these issues more.

Thanks,
Matthew

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [RFC v2] MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking
  2016-11-11 10:23     ` Matthew Fortune
@ 2017-08-24 15:34       ` Maciej W. Rozycki
  2017-10-18 15:39         ` Matthew Fortune
  0 siblings, 1 reply; 8+ messages in thread
From: Maciej W. Rozycki @ 2017-08-24 15:34 UTC (permalink / raw)
  To: Matthew Fortune, Joseph Myers; +Cc: linux-mips, libc-alpha, binutils, gcc

Hi Matthew,

On Fri, 11 Nov 2016, Matthew Fortune wrote:

> This means that a user consciously creating an object that 'needs' ieee
> compliance via use of -fieee=strict or -mieee=strict is thwarted by the
> next user who builds the executable. This kind of scenario can occur with
> a static library prepared by an expert in floating point and then someone
> casually including that into a bigger application. Obviously a similar
> issue is present with the rules around executable and shared libraries
> where the executable's compliance mode can override a shared library
> but at this level we are not losing any information and the executable
> has either very specifically been set to 'relaxed' mode or the kernel
> has set legacy to mean relaxed. The latter can at least be fixed by
> changing the kernel. Losing information in a static link cannot be
> fixed.

 I think I can see your point and I admit I may have oversimplified the 
model, losing a piece of crucial information and consequently control.

 What I can propose is a changed model which requires three states at 
compilation/assembly, and then four states at link/load time automatically 
determined by the input objects, with a possible influence of linker 
command-line options to prevent certain transitions.  These are (names up 
to discussion):

1. Strict -- known to require the NaN encodings to match,

2. Unknown -- may or may not require the NaN encodings to match,

3. Unneeded -- known not to require the NaN encodings to match

-- at compilation/assembly and:

A. Strict -- enforcing matching NaN encodings -- built from strict, 
   unknown and unneeded objects of the matching NaN encoding,

B. Unknown -- matching the NaN encodings, but not enforcing it -- built 
   from unknown and unneeded objects of the matching NaN encoding,

C. Unneeded -- not requiring the NaN encodings to match -- built from only
   unneeded objects of the matching NaN encoding,

D. Relaxed -- known not to match either NaN encoding -- built from unknown 
   and unneeded objects of which at least one does not match the NaN 
   encoding of the remaining objects, or from at least one relaxed object.

-- at link/load time.  Any other object combinations would result in a 
link/load failure, e.g. you could not mix A with a D object, or any object 
not matching the NaN encoding.

 The difference between B and C is at the run time -- the treatment of B 
is controlled by the "ieee754=" kernel option, whereas C always ignores 
NaN compatibility of the hardware.  The difference between C and D is at 
the link/load time -- C can be upgraded to A or B, but D is inherently 
lost and remains at D.  At the ELF binary level B objects correspond to 
what I previously referred to as legacy objects, i.e. no extra annotation 
beyond the EF_MIPS_NAN2008 bit.  There could be a linker command-line 
option to prevent a transition from B to D from happening if not desired, 
causing a link failure.

 The states would be maintained at run-time, when a DSO is dlopen(3)ed.  
A would accept A, B or C if matching the NaN encoding, and stay at A.  B 
would accept B or C if matching the NaN encoding, and stay at B.  With the 
relaxed kernel configuration B would also accept B or C using the opposite 
NaN encoding or D, and switch to D.  C would accept C if matching the NaN 
encoding, and stay at C.  C would accept B if matching the NaN encoding, 
and switch to B.  C would accept B or C using the opposite NaN encoding or 
D, and switch to D.  Any other combinations would cause a dlopen(3) 
failure.

 In this model only the initial state is determined by the main executable 
and further transitions are possible as dynamic objects are added, making 
the use of prctl(3) to switch states more prominent.  One unfortunate 
consequence is that dlopen(3)ing an A DSO from a B or C executable 
switches its state to A permanently making it impossible to subsequently 
dlopen(3) a D DSO even though it would have be allowed beforehand.  
Perhaps it would be possible to track state transitions and restore the B 
or C state as appropriate when the A DSO is dlclose(3)d.  Likewise with B 
or C to D and C to B state transitions.

 In this model I think I would recommend distributions to have the 
compiler configured for 2 by default, so that user-built software comes 
out as B (with a link-time transition to D disallowed by default), however 
distributed software compiled as 3 and consequently linked as C, with any 
pieces identified as doing proper math compiled as 1 and consequently 
linked as A, for both NaN encodings if required.  The reason is I think we 
need to draw a line somewhere and conclude that while we can try to 
minimise the damage caused by the hardware peculiarities created by the 
architecture maintainers we cannot prevent all cases of bad software 
builds caused by gross incompetence.

 Does this model match your expectations?  If so, then I'll work on a 
specification update and a corresponding user interface change, and post 
the results.

  Maciej

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: [RFC v2] MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking
  2017-08-24 15:34       ` Maciej W. Rozycki
@ 2017-10-18 15:39         ` Matthew Fortune
  0 siblings, 0 replies; 8+ messages in thread
From: Matthew Fortune @ 2017-10-18 15:39 UTC (permalink / raw)
  To: Maciej Rozycki, Joseph Myers; +Cc: linux-mips, libc-alpha, binutils, gcc

Hi Maciej,

Slow thread, sorry for dragging it out further...

Maciej Rozycki <Maciej.Rozycki@imgtec.com> writes:
> On Fri, 11 Nov 2016, Matthew Fortune wrote:
> 
> > This means that a user consciously creating an object that 'needs'
> ieee
> > compliance via use of -fieee=strict or -mieee=strict is thwarted by
> the
> > next user who builds the executable. This kind of scenario can occur
> with
> > a static library prepared by an expert in floating point and then
> someone
> > casually including that into a bigger application. Obviously a similar
> > issue is present with the rules around executable and shared libraries
> > where the executable's compliance mode can override a shared library
> > but at this level we are not losing any information and the executable
> > has either very specifically been set to 'relaxed' mode or the kernel
> > has set legacy to mean relaxed. The latter can at least be fixed by
> > changing the kernel. Losing information in a static link cannot be
> > fixed.
> 
>  I think I can see your point and I admit I may have oversimplified the
> model, losing a piece of crucial information and consequently control.
> 
>  What I can propose is a changed model which requires three states at
> compilation/assembly, and then four states at link/load time
> automatically
> determined by the input objects, with a possible influence of linker
> command-line options to prevent certain transitions.  These are (names
> up
> to discussion):
> 
> 1. Strict -- known to require the NaN encodings to match,
> 
> 2. Unknown -- may or may not require the NaN encodings to match,
> 
> 3. Unneeded -- known not to require the NaN encodings to match

Am I right in thinking unneeded is not the same as no-float, it has
floating point in it but explicitly does not care about NaN encodings
because it was built with an option that said so?

> -- at compilation/assembly and:
> 
> A. Strict -- enforcing matching NaN encodings -- built from strict,
>    unknown and unneeded objects of the matching NaN encoding,

Must have at least one strict object?

> 
> B. Unknown -- matching the NaN encodings, but not enforcing it -- built
>    from unknown and unneeded objects of the matching NaN encoding,
> 
> C. Unneeded -- not requiring the NaN encodings to match -- built from
> only
>    unneeded objects of the matching NaN encoding,
> 
> D. Relaxed -- known not to match either NaN encoding -- built from
> unknown
>    and unneeded objects of which at least one does not match the NaN
>    encoding of the remaining objects, or from at least one relaxed
> object.
> 
> -- at link/load time.  Any other object combinations would result in a
> link/load failure, e.g. you could not mix A with a D object, or any
> object
> not matching the NaN encoding.
> 
>  The difference between B and C is at the run time -- the treatment of B
> is controlled by the "ieee754=" kernel option, whereas C always ignores
> NaN compatibility of the hardware.  The difference between C and D is at
> the link/load time -- C can be upgraded to A or B, but D is inherently
> lost and remains at D.  At the ELF binary level B objects correspond to
> what I previously referred to as legacy objects, i.e. no extra
> annotation
> beyond the EF_MIPS_NAN2008 bit.  There could be a linker command-line
> option to prevent a transition from B to D from happening if not
> desired,
> causing a link failure.
> 
>  The states would be maintained at run-time, when a DSO is dlopen(3)ed.
> A would accept A, B or C if matching the NaN encoding, and stay at A.  B
> would accept B or C if matching the NaN encoding, and stay at B.  With
> the
> relaxed kernel configuration B would also accept B or C using the
> opposite
> NaN encoding or D, and switch to D.  C would accept C if matching the
> NaN
> encoding, and stay at C.  C would accept B if matching the NaN encoding,
> and switch to B.  C would accept B or C using the opposite NaN encoding
> or
> D, and switch to D.  Any other combinations would cause a dlopen(3)
> failure.

I'm not entirely sure why 3 or C should care about nan encoding at all
because they should be totally independent of the concept. I.e. link
any combination, choose a NaN encoding for the resulting object at
random but disregard the NaN encoding coming from an unneeded object
when combining with others.

>  In this model only the initial state is determined by the main
> executable
> and further transitions are possible as dynamic objects are added,
> making
> the use of prctl(3) to switch states more prominent.  One unfortunate
> consequence is that dlopen(3)ing an A DSO from a B or C executable
> switches its state to A permanently making it impossible to subsequently
> dlopen(3) a D DSO even though it would have be allowed beforehand.
> Perhaps it would be possible to track state transitions and restore the
> B
> or C state as appropriate when the A DSO is dlclose(3)d.  Likewise with
> B
> or C to D and C to B state transitions.

The dynamic linker already does a scan of all loaded objects for the
purpose of FPXX mode calculations so I doubt it would cost much to
recalculate each time a module is loaded. You only need to handle it at
load time though not unload.
 
>  In this model I think I would recommend distributions to have the
> compiler configured for 2 by default, so that user-built software comes
> out as B (with a link-time transition to D disallowed by default),

Seems fine.

> however
> distributed software compiled as 3 and consequently linked as C, with

Not sure about this. Knowing that something does not care about NaN
encodings is just as hard as knowing something does care. Getting the
different build settings used for default user-builds and distribution
packages is also likely to be painful. I think you could safely get away
with just building as 2 for everything unless it is known to need
matching NaNs, i.e. strict.

> any
> pieces identified as doing proper math compiled as 1 and consequently
> linked as A, for both NaN encodings if required.  The reason is I think
> we
> need to draw a line somewhere and conclude that while we can try to
> minimise the damage caused by the hardware peculiarities created by the
> architecture maintainers we cannot prevent all cases of bad software
> builds caused by gross incompetence.
> 
>  Does this model match your expectations?  If so, then I'll work on a
> specification update and a corresponding user interface change, and post
> the results.

The new set of states look good. I think unneeded is the least likely to
be used in reality but it would form a basis for nofloat.

Thanks,
Matthew

>   Maciej

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-10-18 15:44 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-14 17:10 [RFC v2] MIPS ABI Extension for IEEE Std 754 Non-Compliant Interlinking Maciej W. Rozycki
2016-05-14 17:10 ` Maciej W. Rozycki
2016-05-16 14:21 ` Matthew Fortune
2016-07-13 23:16   ` Maciej W. Rozycki
2016-07-25 15:49     ` Joseph Myers
2016-11-11 10:23     ` Matthew Fortune
2017-08-24 15:34       ` Maciej W. Rozycki
2017-10-18 15:39         ` Matthew Fortune

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).