Page 1 of 1
SSE floats to ints and vice versa?
Posted: Fri Nov 02, 2012 4:36 pm
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]
Re: SSE floats to ints and vice versa?
Posted: Fri Nov 02, 2012 5:05 pm
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 .
Re: SSE floats to ints and vice versa?
Posted: Fri Nov 02, 2012 5:14 pm
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
Re: SSE floats to ints and vice versa?
Posted: Fri Nov 02, 2012 5:50 pm
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 .
Re: SSE floats to ints and vice versa?
Posted: Sat Nov 03, 2012 5:50 pm
by flood
Thanks a lot wilbert
