【问题标题】:Storing two x86 32 bit registers into 128 bit xmm register将两个 x86 32 位寄存器存储到 128 位 xmm 寄存器中
【发布时间】:2011-01-14 23:00:47
【问题描述】:

有没有更快的方法将两个 x86 32 位寄存器存储在一个 128 位 xmm 寄存器中?

movd  xmm0, edx
movd  xmm1, eax
pshufd xmm0, xmm0, $1
por   xmm0, xmm1 

所以如果 EAX 是 0x12345678 而 EDX 是 0x87654321,那么 xmm0 中的结果必须是 0x8765432112345678

【问题讨论】:

  • 哇!那是一个很酷的汇编程序...我上次看到的是 32 位...不知道你可以买一台 128 位的电脑... :P :)
  • 流式 SIMD 扩展 (SSE) 是 x86 架构的 SIMD 指令集扩展,由英特尔设计并于 1999 年推出。
  • SSE 指令集版本最高允许多少?
  • @PhiS 尽可能低。 :) 嗯……至少 5 年前,SSE2 还不错。

标签: assembly x86 simd sse


【解决方案1】:

我对 MMX 了解不多,但也许你想要 PACKSSDW 指令。

PACKSSDW 指令采用两个 源操作数中的双字和 中的两个双字 目标操作数并转换这些 通过饱和到四个有符号的单词。 指令包了这四个字 一起并将结果存储在 目标 MMX 寄存器。

(来自http://webster.cs.ucr.edu/AoA/Windows/HTML/TheMMXInstructionSeta2.html

编辑:我刚刚意识到那些是 SSE 寄存器。哦,好吧。

【讨论】:

  • 我喜欢 xmm 寄存器而不是 mmx(64 位),因为它们在使用后不需要 'emms' 指令。
【解决方案2】:

使用 SSE 4.1,您可以使用 movd xmm0, eax / pinsrd xmm0, edx, 1 并在 2 条指令中完成。

对于较旧的 CPU,您可以使用 2 x movd 然后 punpckldq 总共 3 条指令:

movd xmm0, edx
movd xmm1, eax
punpckldq xmm0, xmm1

【讨论】:

  • 谢谢。但这是相对较新的扩展集,自 2007 年以来,速度和代码大小几乎相同。
  • OK - 现在为 SSE2/SSE3 添加了 3 个指令序列。
  • 超级...这就是我需要的!谢谢。
  • 对于 SSE4.1,第一条指令仍应为 movd。写pinsrd x,r, 0 的唯一原因是当你真的想合并 与旧值,而不是零扩展到整个寄存器以打破对旧值的依赖。 pinsrd 在 Intel CPU 上解码为 2 微指令:int->xmm 和 shuffle,因此它更紧凑,不需要暂存寄存器,但在大多数 CPU 上基本运行与 SSE2 版本相同。
  • 内在函数不必担心这一点,因为编译器知道在可能的情况下使用movd。 (更多地出现在提取中,其中_mm_extract_epi32(v, 0) 编译为movd。pinsrd 内在函数需要一个额外的源向量,希望能让大多数人意识到他们不应该使用它。)
猜你喜欢
  • 2019-11-16
  • 1970-01-01
  • 2017-10-16
  • 2012-06-28
  • 2020-11-21
  • 1970-01-01
  • 2014-11-18
  • 1970-01-01
相关资源
最近更新 更多