Normalization with SSE
Hi!
Another question :)
The code:
void inline Normailze()
{
__declspec(align(16)) static float A[4];
A[0] = Data[0];
A[1] = Data[1];
A[2] = Data[2];
A[3] = 1.0f;
__asm // SSE ASM
{
movaps xmm0, A
movaps xmm2, xmm0
mulps xmm0, xmm0
movaps xmm1, xmm0
shufps xmm1, xmm0, 0xc9
addps xmm0, xmm1
shufps xmm1, xmm1, 0xc9
addps xmm0, xmm1
rsqrtps xmm1, xmm0
mulps xmm2, xmm1
movaps A, xmm2
}
Data[0] = A[0];
Data[1] = A[1];
Data[2] = A[2];
};
I've got a struct (or class) called Vector3D:
struct Vector3D
{
union
{
float Data[4];
struct
{
float x;
float y;
float z;
//float w;
};
};
...
Normalize()
...
}
The C++ and ASM code above contains a variable "A".
Version #2:
__asm // SSE ASM, WRONG
{
movaps xmm0, Data
movaps xmm2, xmm0
mulps xmm0, xmm0
movaps xmm1, xmm0
shufps xmm1, xmm0, 0xc9
addps xmm0, xmm1
shufps xmm1, xmm1, 0xc9
addps xmm0, xmm1
rsqrtps xmm1, xmm0
mulps xmm2, xmm1
movaps Data, xmm2
};
If I try not to use the array "A" (I used the Data array, Data array is 16 bytes long) I get the error:
error C2415: improper operand type
So, I can't use the "Data" array. But why? And how can I solve this problem?
Please, help.
THX.
You need to align the vector to 16 bytes. The float data[4] doesn't say anything about alignment. For arrays you need to 16 bytes align the thing and in this case try to change the float array to
union
{
__m128 data;
struct
{
f32 x,y,z,w;
};
};
union
{
__m128 data;
struct
{
f32 x,y,z,w;
};
};
It works correctly. The problem is not the alignation. I tried povups too.
this works correctly(when I locally create the array in the member function):
...
float Data2[4] = {1,2,3,4};
__asm // SSE ASM
{
movups xmm0, Data2
...
But don't works with the "Data" element (it is defined in the Vector3D struct, without union the compiler writes the same: improper operand type), and I don't know why.
this works correctly(when I locally create the array in the member function):
...
float Data2[4] = {1,2,3,4};
__asm // SSE ASM
{
movups xmm0, Data2
...
But don't works with the "Data" element (it is defined in the Vector3D struct, without union the compiler writes the same: improper operand type), and I don't know why.
Quote:If I try not to use the array "A" (I used the Data array, Data array is 16 bytes long) I get the error:
error C2415: improper operand type
So, I can't use the "Data" array. But why? And how can I solve this problem?
That's because Data is not 16-byte aligned like A is.
Why don't you do this:
void inline Normailze(Vector3D &A) { __asm { mov eax, DWORD PTR [A] movaps xmm0,XMMWORD PTR [eax] //... movaps XMMWORD PTR [eax],xmm2 } }
Then somewhere else you call the Normailze() function as follows:
{ __declspec(align(16)) Vector3D Data = {1.0f, 2.0f, 3.0f, 1.0f}; Normailze(Data); }
It's obviously the this->Data (as member variable), that it doesn't want to eat.
I'm not an assembly expert, so I won't give you the right way to do this, but putting this alone should go through.
movaps xmm0, this Data
And it should work the same as the original.
EDIT:
Nope, it doesn't work. It crashes.
But if I do:
mov eax, this
movaps xmm0, xmmword ptr [eax]
it works perfectly fine. But it's not what OP wants, heh. I give up, then
[Edited by - deffer on September 17, 2006 6:13:40 PM]
I'm not an assembly expert, so I won't give you the right way to do this, but putting this alone should go through.
movaps xmm0, this Data
And it should work the same as the original.
EDIT:
Nope, it doesn't work. It crashes.
But if I do:
mov eax, this
movaps xmm0, xmmword ptr [eax]
it works perfectly fine. But it's not what OP wants, heh. I give up, then
[Edited by - deffer on September 17, 2006 6:13:40 PM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement