www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - 80 bit floating point emulation

reply Walter Bright <newshound2 digitalmars.com> writes:
In order for DMD to become a proper cross compiler, it needs to be able to 
emulate 80 bit floating point. The full x87 doesn't need to be emulated, just
add, sub, mul, div, cmp, neg, tst.

This is eminently doable, and isn't too hard. The 80 bit real format has a 64 
bit significand, meaning the emulation will need 128 bit integer arithmetic.
And 
lo, we already have that in druntime:

https://dlang.org/phobos/core_int128.html

which is one of the reasons I pushed for that.

For example, multiply consists of:

1. checking for special encodings (Nan, infinity)
2. multiplying the two 64 bit significands for a 128 bit result
3. correctly round it using guard and sticky bits
4. add the mantissas together
5. deal with overflow
6. re-encode the result

Anyone want to take up the flag and do this? As a side effect, you'll learn in 
detail how floating point works, which will serve you well in the future.

(We don't use other peoples' emulators because of licensing issues.)
Jul 08 2022
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
Certainly a good excuse for whoever wants to tackle this to buy The Art 
of Computer Programming!
Jul 08 2022
prev sibling next sibling parent reply IGotD- <nise nise.com> writes:
On Friday, 8 July 2022 at 22:04:38 UTC, Walter Bright wrote:
 In order for DMD to become a proper cross compiler, it needs to 
 be able to emulate 80 bit floating point. The full x87 doesn't 
 need to be emulated, just
 add, sub, mul, div, cmp, neg, tst.

 This is eminently doable, and isn't too hard. The 80 bit real 
 format has a 64 bit significand, meaning the emulation will 
 need 128 bit integer arithmetic. And lo, we already have that 
 in druntime:

 https://dlang.org/phobos/core_int128.html

 which is one of the reasons I pushed for that.

 For example, multiply consists of:

 1. checking for special encodings (Nan, infinity)
 2. multiplying the two 64 bit significands for a 128 bit result
 3. correctly round it using guard and sticky bits
 4. add the mantissas together
 5. deal with overflow
 6. re-encode the result

 Anyone want to take up the flag and do this? As a side effect, 
 you'll learn in detail how floating point works, which will 
 serve you well in the future.

 (We don't use other peoples' emulators because of licensing 
 issues.)
Is this something that is important? Now DMD has native support for the x87 80-bit floats but is this something worth porting and emulating with other architectures. It's something that I think is going to be hardly used so wouldn't be better to letting the compiler emit an error instead telling the user that 80-bit floats isn't supported? Keep in mind that the 80-bit float is like an one off in floating point history. Some other architectures supports 128-bit floats which is more common. I would much rather that we emulate 128-bit floats instead than the 80-bit float. Also, Intel themselves have more or less deprecated their own x87 in favor of the newer SSE floating point instructions. That leads to the question, shouldn't DMD do the same? Depreciate 80-bit floats?
Jul 08 2022
next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/8/2022 3:34 PM, IGotD- wrote:
 Is this something that is important?
For example, it'll get rid of all that ugly code in root/ and all the problems with VC's lack of support for 80 bits. It means dmd can be run on any platform. It makes 80 bits available to any D program that may need compatibility. All this for a rather minor investment in coding, half of which has already been done (128 bit arithmetic).
Jul 08 2022
prev sibling parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
On Fri, Jul 08, 2022 at 10:34:34PM +0000, IGotD- via Digitalmars-d wrote:
 On Friday, 8 July 2022 at 22:04:38 UTC, Walter Bright wrote:
 In order for DMD to become a proper cross compiler, it needs to be
 able to emulate 80 bit floating point. The full x87 doesn't need to
 be emulated, just add, sub, mul, div, cmp, neg, tst.
[...]
 Is this something that is important? Now DMD has native support for
 the x87 80-bit floats but is this something worth porting and
 emulating with other architectures. It's something that I think is
 going to be hardly used so wouldn't be better to letting the compiler
 emit an error instead telling the user that 80-bit floats isn't
 supported?
The keyword here is "cross compiler". Suppose you're compiling on a platform that doesn't have 80-bit floats, but you're targeting x86. You'd want your CTFE float values to match the behavior of 80-bit floats, 'cos otherwise there would be a mismatch between what the compiler computes at compile-time vs. what the program would have produced when run on the target x86 platform.
 Keep in mind that the 80-bit float is like an one off in floating
 point history. Some other architectures supports 128-bit floats which
 is more common. I would much rather that we emulate 128-bit floats
 instead than the 80-bit float.
 
 Also, Intel themselves have more or less deprecated their own x87 in
 favor of the newer SSE floating point instructions. That leads to the
 question, shouldn't DMD do the same? Depreciate 80-bit floats?
This is also a valid point. :-P I've also been shying away from 80-bit floats recently because they are slow (80-bit hardware hasn't been improved since decades ago, 'cos nobody is invested in continuing to develop it anymore), and also non-standard (only useful for intermediate computations, not useful for transmission because the target system may not support it -- also, results are peculiar to x86 CPUs and differ from results obtained on other CPUs). T -- Time flies like an arrow. Fruit flies like a banana.
Jul 08 2022
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 7/8/22 8:23 PM, H. S. Teoh wrote:
 
 The keyword here is "cross compiler".  Suppose you're compiling on a
 platform that doesn't have 80-bit floats, but you're targeting x86.
 You'd want your CTFE float values to match the behavior of 80-bit
 floats, 'cos otherwise there would be a mismatch between what the
 compiler computes at compile-time vs. what the program would have
 produced when run on the target x86 platform.
Wait, so you think that the ultimate path here is that DMD becomes able to emulate 80-bit floats, *and then* is ported to another problem with the purpose of cross-compiling to x86? I'm far from being the one to determine what path DMD development should take, but this strikes me as something nobody is asking for. -Steve
Jul 08 2022
parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/8/2022 8:41 PM, Steven Schveighoffer wrote:
 I'm far from being the one to determine what path DMD development should take, 
 but this strikes me as something nobody is asking for.
Ideally, the compiler should produce the same results regardless of the platform it is hosted on.
Jul 08 2022
prev sibling next sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Friday, 8 July 2022 at 22:04:38 UTC, Walter Bright wrote:
 In order for DMD to become a proper cross compiler


 (We don't use other peoples' emulators because of licensing 
 issues.)
Does ldc have an emulator you don't use for licensing? or does it manage to be a usable cross compiler without 80 bit reals?
Jul 08 2022
parent reply Daniel N <no public.email> writes:
On Saturday, 9 July 2022 at 00:05:07 UTC, Adam D Ruppe wrote:
 On Friday, 8 July 2022 at 22:04:38 UTC, Walter Bright wrote:
 In order for DMD to become a proper cross compiler


 (We don't use other peoples' emulators because of licensing 
 issues.)
Does ldc have an emulator you don't use for licensing? or does it manage to be a usable cross compiler without 80 bit reals?
LDC always uses 64-bit double for real, no 80 bit support anywhere afaik.
Jul 08 2022
next sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Saturday, 9 July 2022 at 06:56:25 UTC, Daniel N wrote:
 LDC always uses 64-bit double for real, no 80 bit support 
 anywhere afaik.
Hmmm, so we have a proper cross compiler that doesn't use an 80 bit fp emulator? And it generates faster numeric code too?! Fascinating.
Jul 09 2022
parent jmh530 <john.michael.hall gmail.com> writes:
On Saturday, 9 July 2022 at 11:53:32 UTC, Adam D Ruppe wrote:
 [snip]

 Hmmm, so we have a proper cross compiler that doesn't use an 80 
 bit fp emulator? And it generates faster numeric code too?!

 Fascinating.
Well the reason to use 80bit FP isn't to produce faster code...
Jul 09 2022
prev sibling parent reply Bruce Carneal <bcarneal gmail.com> writes:
On Saturday, 9 July 2022 at 06:56:25 UTC, Daniel N wrote:
 On Saturday, 9 July 2022 at 00:05:07 UTC, Adam D Ruppe wrote:
 On Friday, 8 July 2022 at 22:04:38 UTC, Walter Bright wrote:
 In order for DMD to become a proper cross compiler


 (We don't use other peoples' emulators because of licensing 
 issues.)
Does ldc have an emulator you don't use for licensing? or does it manage to be a usable cross compiler without 80 bit reals?
LDC always uses 64-bit double for real, no 80 bit support anywhere afaik.
A quick scan of LLVM code reveals support for a small menagerie of floating point types: f16, bf16, f32, f64, f128 and f80 for x86 targets. I imagine LDC could support code generation for any subset of these relatively easily. I'd be surprised if gdc could not. Which of these types should be supported at CT is an open question. I'd suggest all of them or just {f32, f64}. A related question is how we might improve multi-target programming. Standardized introspection wrt target HW capabilities would be a good first step. There are others.
Jul 09 2022
parent reply Iain Buclaw <ibuclaw gdcproject.org> writes:
On Saturday, 9 July 2022 at 13:50:12 UTC, Bruce Carneal wrote:
 On Saturday, 9 July 2022 at 06:56:25 UTC, Daniel N wrote:
 On Saturday, 9 July 2022 at 00:05:07 UTC, Adam D Ruppe wrote:
 On Friday, 8 July 2022 at 22:04:38 UTC, Walter Bright wrote:
 In order for DMD to become a proper cross compiler


 (We don't use other peoples' emulators because of licensing 
 issues.)
Does ldc have an emulator you don't use for licensing? or does it manage to be a usable cross compiler without 80 bit reals?
LDC always uses 64-bit double for real, no 80 bit support anywhere afaik.
A quick scan of LLVM code reveals support for a small menagerie of floating point types: f16, bf16, f32, f64, f128 and f80 for x86 targets. I imagine LDC could support code generation for any subset of these relatively easily. I'd be surprised if gdc could not.
GDC does software emulation for all floating point operations in the D compiler, it emulates the target platform by default, but it's written as such that it could support emulating native float with a 160-bit mantissa, and 26-bit exponent.
Jul 09 2022
parent Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 9 July 2022 at 15:38:42 UTC, Iain Buclaw wrote:
 GDC does software emulation for all floating point operations 
 in the D compiler, it emulates the target platform by default, 
 but it's written as such that it could support emulating native 
 float with a 160-bit mantissa, and 26-bit exponent.
That's the fascinating thing... I hope you succeed! SDB 79
Jul 09 2022
prev sibling next sibling parent reply JG <someone simewhere.com> writes:
On Friday, 8 July 2022 at 22:04:38 UTC, Walter Bright wrote:
 In order for DMD to become a proper cross compiler, it needs to 
 be able to emulate 80 bit floating point. The full x87 doesn't 
 need to be emulated, just
 add, sub, mul, div, cmp, neg, tst.

 [...]
Thinking of spending a few hours later to get an idea of how long it will take to do. Any specification to work from?
Jul 09 2022
next sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 9 July 2022 at 09:47:36 UTC, JG wrote:
 On Friday, 8 July 2022 at 22:04:38 UTC, Walter Bright wrote:
 In order for DMD to become a proper cross compiler, it needs 
 to be able to emulate 80 bit floating point. The full x87 
 doesn't need to be emulated, just
 add, sub, mul, div, cmp, neg, tst.

 [...]
Thinking of spending a few hours later to get an idea of how long it will take to do. Any specification to work from?
https://github.com/dlang/phobos/pull/8426/commits/60f5bfa45a4e14038d48d8489b9304923d463867?file-filters%5B%5D=.d&show-viewed-files=true#diff-ef198448dbb3bdace117f346640e1d06f0ada2a0867f995f31b6795a225eb9d7
Jul 09 2022
parent Salih Dincer <salihdb hotmail.com> writes:
On Saturday, 9 July 2022 at 11:00:31 UTC, Salih Dincer wrote:
 On Saturday, 9 July 2022 at 09:47:36 UTC, JG wrote:
 On Friday, 8 July 2022 at 22:04:38 UTC, Walter Bright wrote:
 In order for DMD to become a proper cross compiler, it needs 
 to be able to emulate 80 bit floating point. The full x87 
 doesn't need to be emulated, just
 add, sub, mul, div, cmp, neg, tst.

 [...]
Thinking of spending a few hours later to get an idea of how long it will take to do. Any specification to work from?
Opps! Link of the file (int128.d): https://github.com/WalterBright/phobos/blob/60f5bfa45a4e14038d48d8489b9304923d463867/std/int128.d SDB 79
Jul 09 2022
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 7/9/2022 2:47 AM, JG wrote:
 On Friday, 8 July 2022 at 22:04:38 UTC, Walter Bright wrote:
 In order for DMD to become a proper cross compiler, it needs to be able to 
 emulate 80 bit floating point. The full x87 doesn't need to be emulated, just
 add, sub, mul, div, cmp, neg, tst.

 [...]
Thinking of spending a few hours later to get an idea of how long it will take to do. Any specification to work from?
It's IEEE748 You'll mainly need to be aware of sticky bits, guard bits, and unnormals.
Jul 09 2022
next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/9/2022 11:48 AM, Walter Bright wrote:
 It's IEEE748
Oops. IEEE 754 https://en.wikipedia.org/wiki/IEEE_754
Jul 09 2022
prev sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 7/9/22 11:48, Walter Bright wrote:

 and unnormals.
Subnormals. :) Ali
Jul 09 2022
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
This shows how rounding, sticky bits, and guard bits work:

https://github.com/DigitalMars/sargon/blob/master/src/sargon/halffloat.d
Jul 14 2022
parent reply max haughton <maxhaton gmail.com> writes:
On Thursday, 14 July 2022 at 07:35:51 UTC, Walter Bright wrote:
 This shows how rounding, sticky bits, and guard bits work:

 https://github.com/DigitalMars/sargon/blob/master/src/sargon/halffloat.d
I multiplied a float, onwards to addition (and rounding bugs!)
Jul 14 2022
parent Walter Bright <newshound2 digitalmars.com> writes:
On 7/14/2022 10:50 PM, max haughton wrote:
 I multiplied a float, onwards to addition (and rounding bugs!)
good!
Jul 15 2022