SSE floats to ints and vice versa?

Bare metal programming in PureBasic, for experienced users
flood
User
User
Posts: 31
Joined: Sun Aug 14, 2011 10:32 pm

SSE floats to ints and vice versa?

Post by flood »

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: Select all

 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: Select all

    
  sse\float1 = r
  sse\float2 = g
  sse\float3 = b
  !movups xmm0,[p.v_sse]
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: SSE floats to ints and vice versa?

Post by wilbert »

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 .
flood
User
User
Posts: 31
Joined: Sun Aug 14, 2011 10:32 pm

Re: SSE floats to ints and vice versa?

Post by flood »

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
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: SSE floats to ints and vice versa?

Post by wilbert »

I was thinking about something like this (SSE2)

Code: Select all

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: Select all

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 .
flood
User
User
Posts: 31
Joined: Sun Aug 14, 2011 10:32 pm

Re: SSE floats to ints and vice versa?

Post by flood »

Thanks a lot wilbert :)
Post Reply