Fix issue 20089: Handle extra case in fixresult_complex87#10247
Fix issue 20089: Handle extra case in fixresult_complex87#10247thewilsonator merged 3 commits intodlang:masterfrom
Conversation
|
Thanks for your pull request and interest in making D better, @marler8997! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla references
|
e65cc31 to
f5b2800
Compare
|
I recently noticed this too: https://issues.dlang.org/show_bug.cgi?id=20089 |
src/dmd/backend/cg87.d
Outdated
| pop87(); | ||
| cdb.genfltreg(ESC(MFfloat,1),BX,0); // FSTP floatreg | ||
| genfwait(cdb); | ||
| cdb.genfltreg(LOD, CX, 0); // MOV EAX,floatreg |
There was a problem hiding this comment.
I guess that cfloat is considered a struct, so it is passed in integer registers. But it fits into RCX, so I'd expect that one of the floats has to be packed into the upper half.
BTW: the comments show other registers.
There was a problem hiding this comment.
Yeah that's kinda what I gathered from the code. However, I don't really understand exactly how this code works or how to move the value into the upper part of the register.
Based on the function comment, we need to generate code to move the value from retregs to *pretregs. In this case, retregs is in ST01, but I'm not sure what ST01 means. From wikipedia It looks like there are 8 stack registers (ST1 - ST7) but what is ST01? And I don't see where in this code block the ST01 register is being referenced. I just wrote this code block based on one of the other cases that is moving the value from ST01. I see the comment floatreg so maybe that's what ST01 is?
In any case, this appears to fix test18772 (or at least workaround it), I even added some values in test18772.d to make sure the real part of the float still works. However, I'm using small values so the upper part may be getting lost.
There was a problem hiding this comment.
From wikipedia It looks like there are 8 stack registers (
ST1-ST7) but what isST01?
There are registers ST0-ST7, where ST0 is the one on top of the stack, ST1 is the one below, and so on. mST01 is probably the pair of ST0 and ST1 used for complex numbers.
6aeea9f to
4b28d85
Compare
2fa2686 to
2dd6ffe
Compare
|
The PR as is fixes the test, though, the solution is not fully implemented. The commented line I included in the test will pass once the full solution is implemented. I would be fine with integrating this partial solution as is and let someone more familiar with x86_64 assembly and DMD code generation to finish the solution. The last part is that the imaginary part of the complex number is getting zero'd in the second MOV instruction to |
Yes, |
Maybe it might be better to disable the test until a general fix is found (your patch is a good starting point). I did so in #10231 not expecting a solution soon. |
That was what I tried next but I couldn't figure out how to generate an OR instruction that worked with the 64-bit registers. The codegen api is pretty difficult to figure out. |
|
@marler8997 I pushed a version to your branch that should fix the imaginary part (instead of or-ing the results, it just places the two values to consecutive memory locations). It also covers other register targets. |
|
@rainers very nice, thanks alot for doing this! |
|
I've added a fix for the failing test case, but I'm not so confident this time. |
|
Ping, this good to go? |
…t, allow returning in other registers
|
I've fixed the merge conflicts, I would say it's ready, we'll see what @rainers says. |
|
Fine with me. |
Fix issue 20089, FPU stack not cleaned up properly
Note that this only occurs on windows 64-bit. It doesn't happen on windows 32 bit because it only occurs when the compiler tries to fit a cfloat into the RCX register. With help from @rainers, we added a new
ifblock to handle the case when a cfloat needs to be copied to the one of theR*Xregister.