Re: Float values are wrong in union

2016-08-29 Thread Basile B. via Digitalmars-d-learn

On Monday, 22 August 2016 at 18:19:52 UTC, Engine Machine wrote:

On Monday, 22 August 2016 at 05:02:41 UTC, jkpl wrote:

On Monday, 22 August 2016 at 04:52:40 UTC, Cauterite wrote:

[...]


That's a 32 bit codegen issue then because DMD64 's disasm 
shows that SSE regs are used:

x86 give 7FF and x64 gives 7FB in win.


You can hack the ABI this way:

void loadInScratchReg(float[1] f...) {}

and pass a single float value.
However when you'll start to use the param (f[0]), loading in 
ST(0) will happen so you must write in iasm. (Not to mention an 
aggressive optimizer that would be able, I think, to replace the 
param type if no iasm is present).


example, usage of a tagged union to perform a safe bit cast:

https://github.com/BBasile/iz/blob/master/import/iz/sugar.d#L1176

Not tested yet...


Re: Float values are wrong in union

2016-08-22 Thread Engine Machine via Digitalmars-d-learn

On Monday, 22 August 2016 at 05:02:41 UTC, jkpl wrote:

On Monday, 22 August 2016 at 04:52:40 UTC, Cauterite wrote:

[...]


That's a 32 bit codegen issue then because DMD64 's disasm 
shows that SSE regs are used:



void foo()
{
union test { int i; float f; }
test t = { i : 0x7fb0};
float t2 = t.f;
test t3 = { f : t2 };
}
===

yields to

===
004586D0h  push rbp
004586D1h  mov rbp, rsp
004586D4h  sub rsp, 10h
004586D8h  mov dword ptr [rbp-10h], 7FB0h
004586DFh  movss xmm0, dword ptr [rbp-10h]
004586E4h  movss dword ptr [rbp-0Ch], xmm0
004586E9h  movss xmm1, dword ptr [rbp-0Ch]
004586EEh  movss dword ptr [rbp-08h], xmm1
004586F3h  leave
004586F4h  ret
===


x86 give 7FF and x64 gives 7FB in win.


Re: Float values are wrong in union

2016-08-21 Thread jkpl via Digitalmars-d-learn

On Monday, 22 August 2016 at 04:52:40 UTC, Cauterite wrote:

On Monday, 22 August 2016 at 04:37:50 UTC, stunaep wrote:
I made a union to convert between int bits and floats, but the 
values are coming out wrong sometimes.


I can already tell what this is going to be...
The problem is almost certainly nothing to do with your union, 
it's this line:

float t2 = t.f;
This will load 0x7fb0 into ST(0), which instantly converts 
it to 7FF0 because it's a signalling NaN, then store ST(0) 
in your float `t2`.


Signalling NaNs are an ongoing problem in D's codegen. See 
Don's remarks at this page: 
https://issues.dlang.org/show_bug.cgi?id=16105#c2


The reason it works in other languages is because they don't 
place floats in the floating point registers for non-arithmetic 
operations. I've been trying to patch DMD's backend to behave 
this way too, but it's much harder than I expected (difficult 
codebase to understand/navigate).


That's a 32 bit codegen issue then because DMD64 's disasm shows 
that SSE regs are used:



void foo()
{
union test { int i; float f; }
test t = { i : 0x7fb0};
float t2 = t.f;
test t3 = { f : t2 };
}
===

yields to

===
004586D0h  push rbp
004586D1h  mov rbp, rsp
004586D4h  sub rsp, 10h
004586D8h  mov dword ptr [rbp-10h], 7FB0h
004586DFh  movss xmm0, dword ptr [rbp-10h]
004586E4h  movss dword ptr [rbp-0Ch], xmm0
004586E9h  movss xmm1, dword ptr [rbp-0Ch]
004586EEh  movss dword ptr [rbp-08h], xmm1
004586F3h  leave
004586F4h  ret
===


Re: Float values are wrong in union

2016-08-21 Thread Cauterite via Digitalmars-d-learn

On Monday, 22 August 2016 at 04:37:50 UTC, stunaep wrote:
I made a union to convert between int bits and floats, but the 
values are coming out wrong sometimes.


I can already tell what this is going to be...
The problem is almost certainly nothing to do with your union, 
it's this line:

float t2 = t.f;
This will load 0x7fb0 into ST(0), which instantly converts it 
to 7FF0 because it's a signalling NaN, then store ST(0) in 
your float `t2`.


Signalling NaNs are an ongoing problem in D's codegen. See Don's 
remarks at this page: 
https://issues.dlang.org/show_bug.cgi?id=16105#c2


The reason it works in other languages is because they don't 
place floats in the floating point registers for non-arithmetic 
operations. I've been trying to patch DMD's backend to behave 
this way too, but it's much harder than I expected (difficult 
codebase to understand/navigate).


Re: Float values are wrong in union

2016-08-21 Thread jkpl via Digitalmars-d-learn

On Monday, 22 August 2016 at 04:37:50 UTC, stunaep wrote:
I made a union to convert between int bits and floats, but the 
values are coming out wrong sometimes. This is working without 
issue in other languages so I'm really stumped. Here's an 
example:



union test { int i; float f; }
test t = { i : 0x7fb0};
float t2 = t.f;//int bits 0x7fb0 as float
test t3 = { f : t2 };
writefln("%x", t3.i);//prints 7ff0 NOT 0x7fb0


Ok on linux, 0x7fb0 is written, I tested under linux x86_64 
with latest dmd beta, ldc and also gdc.


Which compiler and version do you use ?
Which OS and archi ?


Float values are wrong in union

2016-08-21 Thread stunaep via Digitalmars-d-learn
I made a union to convert between int bits and floats, but the 
values are coming out wrong sometimes. This is working without 
issue in other languages so I'm really stumped. Here's an example:



union test { int i; float f; }
test t = { i : 0x7fb0};
float t2 = t.f;//int bits 0x7fb0 as float
test t3 = { f : t2 };
writefln("%x", t3.i);//prints 7ff0 NOT 0x7fb0