PureBasic Forum
http://forums.purebasic.com/english/

SSE floats to ints and vice versa?
http://forums.purebasic.com/english/viewtopic.php?f=35&t=51965
Page 1 of 1

Author:  flood [ Fri Nov 02, 2012 4:36 pm ]
Post subject:  SSE floats to ints and vice versa?

Hey guys. Is there a fast way of converting 3/4 sse floats into 3 dword ints? I'm not too experienced with ASM, so this is still a learning experience for me.

This is what I'm currently doing:
Code:
 Protected r,g,b

 !cvtss2si eax,xmm0
 !MOV [p.v_r],eax

 !shufps xmm0,xmm0,0x65 
 !cvtss2si eax,xmm0
 !MOV [p.v_g],eax

 !shufps xmm0,xmm0,0x82
 !cvtss2si eax,xmm0
 !MOV [p.v_b],eax


Also, is there a faster way of doing the following without using the structure?
Code:
   
  sse\float1 = r
  sse\float2 = g
  sse\float3 = b
  !movups xmm0,[p.v_sse]

Author:  wilbert [ Fri Nov 02, 2012 5:05 pm ]
Post subject:  Re: SSE floats to ints and vice versa?

From float to int, you might want to use CVTPS2DQ .
I would also recommend to use 16 byte aligned memory so you can use MOVDQA or MOVAPS .

Author:  flood [ Fri Nov 02, 2012 5:14 pm ]
Post subject:  Re: SSE floats to ints and vice versa?

wilbert wrote:
From float to int, you might want to use CVTPS2DQ .
I would also recommend to use 16 byte aligned memory so you can use MOVDQA or MOVAPS .


Can you explain that a little further for me? Thanks

Author:  wilbert [ Fri Nov 02, 2012 5:50 pm ]
Post subject:  Re: SSE floats to ints and vice versa?

I was thinking about something like this (SSE2)
Code:
Structure RegSSE
  StructureUnion
    f.f[4]
    l.l[4]
  EndStructureUnion
EndStructure

Procedure Float4ToLong4(*RegAligned.RegSSE)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    !mov rax, [p.p_RegAligned]
    !cvtps2dq xmm0, [rax]
    !movdqa [rax], xmm0
  CompilerElse
    !mov eax, [p.p_RegAligned]
    !cvtps2dq xmm0, [eax]
    !movdqa [eax], xmm0
  CompilerEndIf
EndProcedure

Procedure Long4ToFloat4(*RegAligned.RegSSE)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    !mov rax, [p.p_RegAligned]
    !cvtdq2ps xmm0, [rax]
    !movdqa [rax], xmm0
  CompilerElse
    !mov eax, [p.p_RegAligned]
    !cvtdq2ps xmm0, [eax]
    !movdqa [eax], xmm0
  CompilerEndIf
EndProcedure


*Mem = AllocateMemory(32)
*MemAligned = (*Mem + 15) & -16

*Reg.RegSSE = *MemAligned

*Reg\f[0] = 25.5
*Reg\f[1] = 125
*Reg\f[2] = 98

Float4ToLong4(*Reg)

Debug *Reg\l[0]
Debug *Reg\l[1]
Debug *Reg\l[2]

But if you are not going to call it millions of times, using unaligned memory like you did is probably easier
Code:
Structure RegSSE
  StructureUnion
    f.f[4]
    l.l[4]
  EndStructureUnion
EndStructure

Procedure Float4ToLong4(*Reg.RegSSE)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    !mov rax, [p.p_Reg]
    !movdqu xmm0, [rax]
    !cvtps2dq xmm0, xmm0
    !movdqu [rax], xmm0
  CompilerElse
    !mov eax, [p.p_Reg]
    !movdqu xmm0, [eax]
    !cvtps2dq xmm0, xmm0
    !movdqu [eax], xmm0
  CompilerEndIf
EndProcedure

Procedure Long4ToFloat4(*Reg.RegSSE)
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    !mov rax, [p.p_Reg]
    !movdqu xmm0, [rax]
    !cvtdq2ps xmm0, xmm0
    !movdqu [rax], xmm0
  CompilerElse
    !mov eax, [p.p_Reg]
    !movdqu xmm0, [eax]
    !cvtdq2ps xmm0, xmm0
    !movdqu [eax], xmm0
  CompilerEndIf
EndProcedure


Reg.RegSSE

Reg\f[0] = 25.5
Reg\f[1] = 125
Reg\f[2] = 98

Float4ToLong4(@Reg)

Debug Reg\l[0]
Debug Reg\l[1]
Debug Reg\l[2]

If you prefer truncation when converting to long, you can use CVTTPS2DQ .

Author:  flood [ Sat Nov 03, 2012 5:50 pm ]
Post subject:  Re: SSE floats to ints and vice versa?

Thanks a lot wilbert :)

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/