Visual c++ x86上的SSE,堆栈对齐

Visual c++ x86上的SSE,堆栈对齐,visual-c++,gcc,sse,Visual C++,Gcc,Sse,我得到的SSE代码是为x64编写的,其中堆栈是对齐的。已在x86上请求优化的代码路径(适用于MSVC/Windows和GCC/Linux)。先在MSVC上运行 现在,除了一些接受了3个以上的m128参数的内联线,它拒绝编译这些参数(通过生成一个const ref并希望编译器将其优化来修复),一切似乎都正常工作 //error C2719: 'd': formal parameter with __declspec(align('16')) won't be aligned inline __m1

我得到的SSE代码是为x64编写的,其中堆栈是对齐的。已在x86上请求优化的代码路径(适用于MSVC/Windows和GCC/Linux)。先在MSVC上运行

现在,除了一些接受了3个以上的m128参数的内联线,它拒绝编译这些参数(通过生成一个const ref并希望编译器将其优化来修复),一切似乎都正常工作

//error C2719: 'd': formal parameter with __declspec(align('16')) won't be aligned
inline __m128i foo(__m128i a, __m128i b, __m128i c, __m128i d) {...}
然而,我的印象是,x86上的堆栈不是16字节对齐的。然而,堆栈上的一些uu declspec(align(16))数组甚至没有收到警告,我确信它一定是在推送和弹出uu m128(我记得在x64上需要12个寄存器,即使这样,它也将一些寄存器移到了堆栈中,它一点也不需要,并且做了自己的事情)

我甚至在数组内存地址上添加了一些断言(并关闭了NDEBUG),它们似乎都通过了

__declspec(align(16)) uint32_t blocks[64];
assert(((uintptr_t)blocks) % 16 == 0);

__m128i a = ...;
__m128i b = ...;
__m128i c = ...;
__m128i d = ...;
__m128i e = ...;
__m128i f = ...;
__m128i g = ...;
//do other stuff, which surely means there is not enough registers on x86
我是真的很幸运,还是有什么魔法在这里重新排列堆栈?这是便携式的吗?我肯定记得,当我在VS2008上使用D3D9时,在x86上使用D3DX时遇到了一些问题

但是有一件事我确实收到了很多警告,那就是uum128->uuum128&转换是非标准的。某些确实支持SSE的编译器是否真的不支持这一点?如何避免它(例如,输出为u m128的内联线,或超过3个参数的内联线)

另外,快速查看表明MS本身以某种方式打破了这些规则(例如,XMMatrixTransformation需要6个SSE对象,我能看到的唯一区别是在结构中包装)


如果需要获得所需的对齐方式,大多数ABI都会插入填充,因此,如果堆栈仅对齐8字节,那么对于需要16字节对齐方式的数据类型,它们仍然会做正确的事情。我希望MS在WIN32中也能做同样的事情(如果他们不这样做的话,生活会很困难!)。这取决于你使用的编译器版本。VS2012当然会生成与16对齐的堆栈地址,它大量使用SSE2,因为它是自己的代码生成器。
XMMATRIX XMMatrixTransformation(
  [in]  XMVECTOR ScalingOrigin,
  [in]  XMVECTOR ScalingOrientationQuaternion,
  [in]  XMVECTOR Scaling,
  [in]  XMVECTOR RotationOrigin,
  [in]  XMVECTOR RotationQuaternion,
  [in]  XMVECTOR Translation
);