Naked return value

General FreeBASIC programming questions.
Post Reply
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Naked return value

Post by deltarho[1859] »

I read somewhere that we can return a Naked double via xmm0, but I cannot find the statement now.

Code: Select all

Function foo Naked cdecl ( ByVal x As Ulong ) As Double
  Asm
    mov edx, Dword Ptr [esp+4]
    cvtsi2sd xmm0, edx
    ret
  End Asm
End Function
 
Print foo(66)
 
Sleep
I was hoping to get 66 but get -1.#IND
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Naked return value

Post by jj2007 »

Indeed, you can return a "naked" double via xmm0, and your code puts the double 66 correctly in xmm0, but FB print expects its double on the FPU:

Code: Select all

Function foo Naked cdecl ( ByVal x As Ulong ) As Double
  Asm
'     mov edx, Dword Ptr [esp+4]
'     cvtsi2sd xmm0, edx
    fild Dword Ptr [esp+4]
    ret
  End Asm
End Function
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Naked return value

Post by deltarho[1859] »

Thanks Jochen.

Suppose after a few lines of code we get a scalar double result in xmm0 how do we put xmm0 into the FPU?
marcov
Posts: 3462
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Naked return value

Post by marcov »

On Windows, XMM for FPU is default for 64-bit, not for 32-bit.
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Naked return value

Post by deltarho[1859] »

I would like to stay on topic.
jj2007 wrote:Indeed, you can return a "naked" double via xmm0
How?
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Naked return value

Post by jj2007 »

deltarho[1859] wrote:Suppose after a few lines of code we get a scalar double result in xmm0 how do we put xmm0 into the FPU?

Code: Select all

Function foo1 Naked cdecl ( ByVal x As Ulong ) As Double
  Asm
    fild Dword Ptr [esp+4]	' simple...
    ret
  End Asm
End Function

Function foo2 Naked cdecl ( ByVal x As Ulong ) As Double
  Asm
    cvtsi2sd xmm0, dword Ptr [esp+4]	' get value as integer, convert to double
    sub esp, 8								' create a qword slot
    movlps qword ptr [esp], xmm0		' load double into memory
    fld qword ptr [esp]					' transfer to the FPU
    add esp, 8								' correct the stack
    ret
  End Asm
End Function

Print "directly to the FPU:", foo1(12345)
Print "with acrobatics:", foo2(12345)
Sleep
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Naked return value

Post by deltarho[1859] »

Thanks Jochen.

foo2 solves the opening post perfectly.

What would be nice is 'fld xmm0' but the FPU architecture hasn't seen any work on it for years.

Code: Select all

#macro fld_xmm0
  sub esp, 8                        ' create a qword slot
  movlps qword ptr [esp], xmm0      ' load double into memory
  fld qword ptr [esp]               ' transfer to the FPU
  add esp, 8
#endmacro
 
Function foo2 Naked cdecl ( ByVal x As Ulong ) As Double
  Asm
    cvtsi2sd xmm0, dword Ptr [esp+4]
    fld_xmm0
    ret
  End Asm
End Function
So, given some work where xmm0 is a scalar double we simply use

Code: Select all

fld_xmm0
ret
where the Naked return is Double.

fxm may like to add to the Wiki again because all the examples have Naked returning Longs only and no mention of a Double return involves the FPU.
SARG
Posts: 1764
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Naked return value

Post by SARG »

With 64bit it's shorter.

Code: Select all

Function foo2 Naked ( ByVal x As Ulong ) As double
  Asm
	cvtsi2sd xmm0, ecx
	ret
  End Asm
End Function
print foo2(57897897)
sleep
deltarho[1859]
Posts: 4308
Joined: Jan 02, 2017 0:34
Location: UK
Contact:

Re: Naked return value

Post by deltarho[1859] »

Ah, I wondered what marcov was getting at.

So, 'Compiler Option: -fpu' is incomplete.

We need to do a platform check to test whether my fld_xmm0 macro is needed. Life is getting too complicated - one step forward, two steps back.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Naked return value

Post by jj2007 »

SARG wrote:With 64bit it's shorter.
Codesize-wise, it's identical:

Code: Select all

Function foo Naked cdecl ( ByVal x As Ulong ) As Double
  Asm
  int 3
  #ifdef __FB_64BIT__
	cvtsi2sd xmm0, ecx
  #else
	fild Dword Ptr [esp+4]
	ret
  #endif
  nop
  End Asm
End Function

Dim as double my123
asm int 3
my123=foo(1234567)
asm nop
asm nop
Print "here it is: ";my123
Sleep
Tested with standard GAS for 32 bits and SARG's version for 64 bits. One interesting point is that the 64-bit compiler inserts the ret for you - 32-bit Gas doesn't.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Naked return value

Post by jj2007 »

marcov wrote:On Windows, XMM for FPU is default for 64-bit, not for 32-bit.
deltarho[1859] wrote:Ah, I wondered what marcov was getting at.
What he actually meant is "On Windows, XMM for returning doubles is default for 64-bit". The OS uses xmmregs for doubles. As a coder, you can use the fpu for whatever you like, though.
SARG
Posts: 1764
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Naked return value

Post by SARG »

jj2007 wrote:Codesize-wise, it's identical:
I agree.
I compared only foo2 functions :-)


@deltarho[1859]
XMM for returning doubles and singles on Windows and Linux.
Post Reply