0

Arm Architecture Reference Manual for A-profile architecture (issue I.a) (emphases added):

DN, bit [25]

Default NaN use for NaN propagation.

0b0 NaN operands propagate through to the output of a floating-point operation.

0b1 Any operation involving one or more NaNs returns the Default NaN.

This bit has no effect on the output of FABS, FMAX*, FMIN*, and FNEG instructions, and a default NaN is never returned as a result of these instructions.

A simple question: what is the rationale for the emphasized text?

What are the obstacles to return a default NaN from these instructions?

pmor
  • 5,392
  • 4
  • 17
  • 36
  • well those operations cant make a number worse than it already is. it is not pushing the number toward something that cant be represented. arm could have just left that comment out... – old_timer May 29 '23 at 16:20
  • @old_timer: No, it does make a difference. With the DN bit clear, if for instance you add two NaN's with different payloads, you get one of them as your result. With it set, you get a default NaN instead (which may not agree with either one). You might therefore expect that applying FNEG to a NaN with a specific payload would get you a default NaN. The comment specifies that this does not happen, and instead you get the NaN with the same payload as the input, and opposite sign bit. – Nate Eldredge May 29 '23 at 16:31
  • @old_timer: I can't say I understand exactly *why* the DN behavior would be useful, but at least it is precisely specified. – Nate Eldredge May 29 '23 at 16:34

1 Answers1

2

FNEG normally has a very simple implementation: just flip the sign bit. In order to provide "default NaN" behavior, it would have to include a test for NaN to trigger special handling, making it possibly less efficient. Most other instructions already need special handling for NaN to get correct mathematical results, in which case it isn't so bad to change that handling when DN is set.

FABS is similar, in that it can be implemented by unconditionally clearing the sign bit.

For FMAX/FMIN, they are usually defined to have behavior like x > y ? x : y, where the result is always one of the two inputs, and this property is considered rather fundamental. Replacing a NaN result with a default NaN would break it.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • Assuming that behavior, this contradicts "a default NaN is *never* returned as a result of these instructions" (but this might just be an inaccuracy in their documentation). – chtz May 30 '23 at 10:21
  • Re: "very simple implementation" (FNEG and FABS): IEEE 754-2008 in 5.5.1 Sign bit operations says: "These operations may propagate non-canonical encodings". What does the "propagate non-canonical encodings" mean exactly? Does it mean that IEEE 754-2008 allows to return a default NaN? Why it is not required to "propagate non-canonical encodings"? – pmor May 30 '23 at 12:35
  • Re: "a default NaN is never returned": then what is the result of `FMAX(default_NaN, default_NaN)`? – pmor May 30 '23 at 12:38
  • @chtz About `FMAX/FMIN`: in `shared_pseudocode.html` (ISA_A64_xml_A_profile-2023-03) I see that `FPMax` calls `FPProcessNaNs`, which calls `FPProcessNaN`, which calls `FPDefaultNaN` if `fpcr.DN == '1'`. The similar sequence for `FPMax`. Hence, per `shared_pseudocode.html` FMAX/FMIN _can_ return the default NaN. Is that correct? Any comments? – pmor May 30 '23 at 14:07
  • This [code](https://godbolt.org/z/f5d7jbcTq) compiled and executed as `gcc t1.c -DDN=0 && ./a.out` prints `-nan ffffffff` (expected), while compiled and executed as `gcc t1.c -DDN=1 && ./a.out` prints `nan 7fc00000` (unexpected). Here we see that `FMAX` returns the default NaN (`7fc00000`) under `DN=1`, which contradicts with the emphasized text (see the question). Any comments? – pmor May 30 '23 at 14:52
  • 2
    I think "a default NaN is never returned" is just slightly imprecise wording. What they mean is "a NaN result is never *replaced* by a default NaN". – Nate Eldredge May 30 '23 at 16:56
  • @pmor: Regarding "propagate non-canonical encoding", I assume that simply means that if you take a non-canonical encoding and feed it to FNEG, you may get back the same encoding with only the sign bit flipped, which is again non-canonical. As opposed to other operations which would always return a canonical result, even with non-canonical inputs. – Nate Eldredge May 30 '23 at 17:08
  • @pmor: For FMAX/FMIN, it does seem on its face like an inconsistency. I will try to look at it when I have more time. – Nate Eldredge May 30 '23 at 17:11
  • @NateEldredge Also: in "FMAX*" what does the * means exactly? The wildcard character? There are "FMAX (vector)" and "FMAX (scalar)". However, there are also "FABS (vector)" and "FABS (scalar)", but "FABS" is listed (in the emphasized text) w/o the `*`. Confused. Perhaps the * is some kind of footnote (e.g. in format "* "), however, I could not find the "* ". – pmor May 31 '23 at 11:16
  • Re: "propagate non-canonical encoding": thanks! I assume the same. – pmor May 31 '23 at 12:59
  • I think the `*` means that this text applies to all instructions beginning with `FMAX`, such as `FMAXP`, `FMAXV`, `FMAXNM`, etc., as well as all forms of `FMAX` itself. So yes, like a wildcard. – Nate Eldredge May 31 '23 at 15:27