Conversation
|
Thanks for your pull request, @rainers! Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + dmd#8169" |
e5d598f to
f081a26
Compare
src/dmd/root/longdouble.d
Outdated
| */ | ||
|
|
||
| // 80 bit floating point value implementation for LDC compiler targetting MSVC | ||
| // 80-bit floating point value implementation if the C/D compiler do not support them natively |
| { | ||
| nothrow: | ||
| nothrow @nogc: | ||
| ulong mantissa = 0xC000000000000001UL; // default to snan |
There was a problem hiding this comment.
I gave up on snan a while ago. Nothing supports it, and it just causes problems when people compare nan bits. Use qnan instead.
src/dmd/root/longdouble.d
Outdated
| longdouble opMul(longdouble rhs) const { return this.ld_mul(rhs); } | ||
| longdouble opDiv(longdouble rhs) const { return this.ld_div(rhs); } | ||
| longdouble opMod(longdouble rhs) const { return this.ld_mod(rhs); } | ||
| bool opEquals(const longdouble_soft rhs) const { return this.ld_cmpe(rhs); } |
There was a problem hiding this comment.
hmm, on this rhs is const, but not so for the other functions.
There was a problem hiding this comment.
Removed const for consistency as the argumets are passed by value anyway. I abuse the non-constness in some operations to avoid RVO ignoring the asm modifications.
There was a problem hiding this comment.
RVO ignoring the asm modifications.
Please file a bug report about that.
There was a problem hiding this comment.
Please file a bug report about that.
| version(CRuntime_Microsoft): | ||
| extern(C++): | ||
| nothrow: | ||
| @nogc: |
There was a problem hiding this comment.
Investigate using pure and @safe as much as practical.
There was a problem hiding this comment.
Added pure and @safe, but it has pure @trusted has to be verified manually on all the asm.
Or I just ignore it completely as neither ctfloat.d nor longdouble.d is shareable code. :-) By all means I suppose the implementation could be submitted here. |
|
I used the "Paranoia" test suite to make the DMC soft implementation of floating point arithmetic correct. It lives up to its name, you have to get it right for Paranoia to pass! |
The Paranoia test only seems to fail for the overflow detection (using SIGFPE signals), but I guess we don't need that. |
5b0ce1b to
e1f92ec
Compare
It's great news that Paranoia is working! Perhaps add it to the test suite? Maintenance on longdouble may accidentally break it. Did you translate it to D? I know we don't need the signals, but is there a way to get it to pass anyway? |
Are you testing compile time or runtime here? |
No, I just added these definitions instead of the float/double versions: and adjusted a couple of explicit conversions from double constants.
Not sure. Maybe it just needs enabling approriate FPU exceptions... |
paranoia tests the C++ interface linked with the D implementation of longdouble, so I'd consider it a test of the compile time evaluation of dmd, but not some D operator overloads. |
|
Unfortunately the tests fail because LDC translates all types of FPU instructions to 64-bit, so are all the same. |
So it could be part of the c++ test source then. Or it could be converted into a ctfe test for the testsuite. In any case, @WalterBright no chance of supporting all the paranoia tests because there is no fpu at compile time. |
The point of paranoia is to test the "no fpu" soft float implementation. I'm not understanding your comment. |
8c04fe6 to
a5f4836
Compare
|
Why would it raise a signal if floating point is emulated? |
a5f4836 to
33b14f4
Compare
That's a bug I introduced a while back, thanks for reporting => ldc-developers/ldc#2653. |
I was wrong about the actual problem due to the rather confusing output: the actual "DEFECT" was an inaccuracy of the pow function, so pretty expected because we are just using the double version. I then noticed that the FPU precision hasn't been changed at all because I missed to call initFPU() :-/ With that I get 1 "failure" and 3 "defects". Quite ok when compared to dmc (1 failure, 1 serious defect, 6 defects) and gcc (2 failures, 1 serious defect, 6 defects). The latter is rather old, but version 4.9.1 is the latest I found on my system. Edit: all issues seem to be related to |
Thanks for the quick action. While trying to workaround I noticed
|
Thx => ldc-developers/ldc#2654
I'm not too familiar with the DMD-style inline asm parser code, so I don't know if that would be possible. |
It seems it is almost there, but currently commented out: https://github.com/ldc-developers/ldc/blob/master/gen/asm-x86.h#L3888
Thanks. |
Because an emulator should emulate the real thing. |
This is good news, it means the underlying arithmetic is sound. It would be a good idea to make a bugzilla issue of all the paranoia failures. It'd still be grand to convert paranoia to D! |
68a4668 to
6bd854e
Compare
6bd854e to
8b35cb4
Compare
|
What's the status with this? @rainers, are you still working on this, or is it ready to go in your opinion? Are there any outstanding issues? What are they? |
I think it's ready to go. A possible complication is that the backend now depends on D code which might make linking a bit more troublesome on non-Windows-platforms (though not used there for now). |
We are about to start converting the backend to D soon hopefully anyhow, so this shouldn't be a big problem. |
src/dmd/root/longdouble.d
Outdated
| version(D_InlineAsm_X86_64) | ||
| { | ||
| // set precision to 64-bit mantissa and rounding control to nearest | ||
| asm nothrow @nogc pure |
There was a problem hiding this comment.
nothrow and @nogc are already declared above. Is this redundant? If so, I suggest choosing a coding style: either add the attributes explicitly at each declaration, or group them under one attribution, but don't mix the two styles.
There was a problem hiding this comment.
Not confident enough for @trusted?
There was a problem hiding this comment.
nothrow and @nogc are already declared above. Is this redundant?
These attributes have to be repeated for each asm statement. otherwise the compiler errors out.
There was a problem hiding this comment.
Before dmd 2.067, you couldn't write asm in pure/safe code: https://dlang.org/changelog/2.067.0.html#asm-attributes
JinShil
left a comment
There was a problem hiding this comment.
It's quite beyond me to verify the semantics of this code, but the craftsmanship and translation looks good. Nice work!
src/dmd/root/longdouble.d
Outdated
| else version(D_InlineAsm_X86) | ||
| { | ||
| // set precision to 64-bit mantissa and rounding control to nearest | ||
| asm nothrow @nogc |
There was a problem hiding this comment.
Not pure like the one above?
There was a problem hiding this comment.
pure is wrong above, the FPU control word is changed. I'll remove that.
|
@adamdruppe I understand you're quite good with Intel ASM. Care to lend your expertise here, perhaps even verifying safety and purity? |
src/dmd/root/longdouble.d
Outdated
| { | ||
| version(AsmX86) | ||
| { | ||
| asm nothrow @nogc pure @trusted |
There was a problem hiding this comment.
I probably wouldn't call this pure since it explicitly is clearing flags; if this function were optimized out it would probably be wrong most times.
There was a problem hiding this comment.
I'm way out of my league here but if we're talking about floating point flags the spec says [1]:
As a concession to practicality, a pure function can also:
- read and write the floating point exception flags
- read and write the floating point mode flags, as long as those flags are restored to their initial state upon function entry
|
So I'm not in love with making Resetting flag registers while calling it pure rubs me more the wrong way though. I guess it would pass the test if they are pushed and popped inside a pure function, but I don't think they consistently are. For the |
|
Thanks @adamdruppe for review. Indeed, ld_clearfpu() is not pure, so the asm inside should also not be marked that way. I've also added BTW: there is little new about the asm, it was already there with ldfpu.asm (for Win64) and longdouble.d (for Win32), but sure, merging them might have introduced regressions. Appveyor tests both versions, though. |
|
@WalterBright I think we are ready to merge to this. Do you have anything to add? |
This gets rid of the split implementation in C and D and asm.
Unfortunately, I had to introduce another name for the software implementation, because we now have to cover the case where D code is compiled with dmd using native reals, but needs to supply symbols for the backend that is compiled with VC.
The respective type name aliases are now:
VisualC backend compiler:
targ_ldoubletypedefslongdoubletypedefslongdouble_softother C backend compilers:
targ_ldoubletypedefslongdoubletypedefslong doubledmd frontend:
real_taliaseslongdoublealiasesrealLDC/win frontend:
real_taliaseslongdoublealiaseslongdouble_softThe GDC frontend can replace longdouble_soft with a complete software emulation.