我已经阅读了一段时间了,但我似乎无法弄明白。我正在使用AMD64 ABI草案0.99.6,第18页,第3.32 Parameter Passing
部分以及以下文本:
类型__m256的参数被分成四个八字节块。最不重要的一个属于SSE类,所有其他属于SSEUP类。
我很困惑,因为它听起来像我使用三个SSEUP寄存器而只有一个SSE,但这似乎浪费了与SSEUP相关的其他两个SSE寄存器。我误读了吗?我可能甚至不会使用这种数据类型,但我已经对这段文字感到困惑了很长一段时间。有人可以举例说明这是如何工作的吗?我可能错过了一些明显的东西。
答案 0 :(得分:3)
第18页只包含一个定义列表,供以后讨论用于传递函数参数的算法。
特别是, SSE 类总是在新的向量寄存器中传递,第一个可用于%xmm0-%xmm7
。
请注意,这些名称是指寄存器的低128位部分,但最好根据可变大小向量寄存器%v0-%v7
来考虑它们。
SSEUP 类在下一个可用的 last 向量寄存器的64位(8字节)中传递。
__m256
寄存器在支持AVX的处理器中传递 %ymm
:低64位获取 SSE 类 - 因此新%v0
1}}寄存器 - 而其他三个64位块获得 SSEUP ,从而重用%v0
寄存器。
以下是该文件的相关引用:
- 如果类是SSE,则使用下一个可用的向量寄存器,即寄存器 按照从%xmm0到%xmm7的顺序进行。
- 如果类是SSEUP,则在下一个可用的8字节中传递8字节 最后使用的向量寄存器的块。
醇>
SSEUP 类是早先在ABI中引入的,现在仍然存在。
您可以快速查阅Version 0.9以查看差异:例如,_m256
和_m512
类型不存在。
对于不支持具有_m256
类型的新ABI的编译器,或者对于支持它而不支持AVX的目标处理器的编译器,该类型通常为an aggregate of two _m128
,因此通过后面描述的规则(特别是合并后的规则)将在内存中传递:
- 如果一个对象的大小大于两个八字节,或者在C ++中,是一个非POD结构或联合类型,或者包含未对齐的字段,它有类 记忆。
醇>对于使用旧ABI的编译器
如果聚合的大小超过两个八字节和前八个字节 不是SSE或任何其他八字节不是SSEUP,整个论点 在内存中传递。
对于使用新ABI的编译器
由于需要解决向后兼容问题,该标准确实令人困惑, SSE 和 SSEUP 分类是向量寄存器不断扩展的架构中的便捷分类。已有各种不同尺寸的产品。