MultiMedia eXtensions - MMX:第一套应用于英特尔 80x86 指令集的 SIMD 扩展
Posted rtoax
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MultiMedia eXtensions - MMX:第一套应用于英特尔 80x86 指令集的 SIMD 扩展相关的知识,希望对你有一定的参考价值。
https://softpixel.com/~cwright/programming/simd/mmx.php
目录
MMX — An Overview
MMX 是第一套应用于英特尔 80x86 指令集的 SIMD 扩展。 它于 1997 年推出。 MMX 引入了许多新指令,可以同时操作单个 64 位数量、2 个 32 位数量、4 个 16 位数量或 8 个 8 位数量。 它使用与 FPU 相同的寄存器空间,因此不能同时使用 MMX 和浮点运算。 它为编程器提供了 8 个通用寄存器,全部为 64 位宽 (MM0 - MM7)。 除了 emms、movd 和 movq,所有 MMX 指令都以字母“p”开头。
Sometimes, MMX is referred to as Matrix Math eXtensions
.
MMX — The Registers
如上所述,MMX 为程序员提供了 8 个 64 位通用寄存器。这些称为 的寄存器MM0 - MM7
可以以多种方式使用。它们可以用作单个 64 位数量、双 32 位数量、4 个 16 位数量或 8 个 8 位数量。当对 MMX 寄存器执行任何操作时,它会同时应用于寄存器的所有元素。这使软件的运行速度提高了 8 倍(尽管在现实生活中这从未发生过)。
Register | 79 - 64 | 63 - 0 |
ST0 | xx | MM0 |
ST1 | xx | MM1 |
ST2 | xx | MM2 |
ST3 | xx | MM3 |
ST4 | xx | MM4 |
ST5 | xx | MM5 |
ST6 | xx | MM6 |
ST7 | xx | MM7 |
请注意每个 80 位 FPU 寄存器的前 16 位如何在 MMX 模式下未使用。
Register | Description | ||||||||||||||||
| A Single 64-bit Quadword | ||||||||||||||||
| 2 32-bit Doublewords | ||||||||||||||||
| 4 16-bit Words | ||||||||||||||||
| 8 8-bit Bytes |
MMX — State Management
由于 MMX 和 FPU 寄存器占用相同的空间,因此当您尝试同时使用浮点代码和 MMX 代码时就会出现问题。当CPU处于 MMX 模式时,它将未使用的 fpu 位设置为无效值,这将导致任何浮点指令行为异常。进入 MMX 模式相当简单;只需执行一条 MMX 指令。退出 MMX 并不那么简单。我们使用emms
指令来执行此操作。
emms
emms
不带参数,可以随时执行。它恢复了fpu,使其可以正常运行。emms
如果随后要运行浮点代码,则所有 MMX 代码都应在完成时调用 。 emms
代表空 MMX 状态。
MMX — Data Movement
MMX 为我们提供了一些新mov
指令,以方便将数据传入和传出 MMX 寄存器。这些新指令是 movd
和movq
。
movd
(MOVe Doubleword) 可以将 32 位寄存器或内存位置移入或移出 MMX 寄存器的底部 32 位。当数据移入时,MMX 寄存器的前 32 位设置为零。movq
(MOVe Quadword) 在存储器和 MMX 寄存器之间或两个 MMX 寄存器之间移动 64 位数量。
MMX — Boolean Logic
MMX 仅支持整数,因此它提供正常的布尔逻辑运算是有意义的。这些都很容易掌握。
pxor
可以异或 (XOR) 任何两个 MMX 寄存器,一个 MMX 寄存器和内存,或者一个 MMX 寄存器和一个常量。por
可以按位或 (OR) 任意两个 MMX 寄存器、一个 MMX 寄存器和内存,或一个 MMX 寄存器和一个常量。pand
可以按位与 (AND) 任何两个 MMX 寄存器、一个 MMX 寄存器和存储器,或一个 MMX 寄存器和一个常量。pandn
可以按位非与 (NAND) 任何两个 MMX 寄存器、一个 MMX 寄存器和内存,或一个 MMX 寄存器和一个常量。
无论数据在寄存器中如何排列(无论是 64 位值还是 8 个 8 位值),这些指令的操作都是相同的。毕竟,这就是布尔逻辑的本质。
MMX 中还提供了许多移位操作。
psllw
将指定的寄存器左移一定数量的位,对字(16 位)进行操作。pslld
将指定的寄存器左移一定数量的位,对双字(32 位)进行操作。psllq
将指定的寄存器左移一定数量的位,对四字(64 位)进行操作。psrlw
将指定的寄存器右移一定数量的位,对字(16 位)进行操作。这是一个逻辑移位,而不是算术。psrld
将指定的寄存器右移一定数量的位,对双字(32 位)进行操作。这是一个逻辑移位,而不是算术。psrlq
将指定的寄存器右移一定数量的位,对四字(64 位)进行操作。这是一个逻辑移位,而不是算术。psraw
将指定的寄存器左移一定数量的位,对字(16 位)进行操作。这是算术,这意味着新的最高位是原始最高位(符号位)的副本。psrad
将指定的寄存器左移一定数量的位,对双字(32 位)进行操作。这也是算术。
移位操作确实区分了寄存器的各种大小。这是保持一个值中的位不影响相邻值所必需的。
MMX — Math
MMX 包含了许多基本的数学运算。
paddb
添加一个 MMX 寄存器和另一个 MMX 寄存器或存储器作为无符号 8 位字节。paddsb
就像paddb
,除了字节有符号并且值饱和而不是环绕。该指令在 127 (0x7f) 或 -128 (0x80) 处饱和。paddusb
就像paddsb
但带有无符号字节。该指令在 255 (0xff) 处饱和。paddw
添加一个 MMX 寄存器和另一个寄存器或存储器作为无符号 16 位字。paddsw
就像paddsb
除了它使用 16 位字而不是 8 位字节。该指令在 32767 (0x7fff) 或 -32768 (0x8000) 处饱和。paddusw
添加无符号字,并在 65535 (0xffff) 处饱和。paddd
将一个寄存器和另一个寄存器或内存位置添加为无符号 32 位双字。psubb
从另一个寄存器中减去一个内存位置或 MMX 寄存器,对无符号 8 位字节进行操作。psubsb
使用有符号字节从另一个寄存器中减去一个寄存器或内存位置,并在 -128 (0x80) 或 127 (0x7f) 处饱和。psubusb
用饱和减去无符号字节,类似于psubsb
. 该指令在 0 (0x00) 处饱和。psubw
减去无符号的 16 位字。psubsw
减去有符号的 16 位字,并在 32767 0x7fff) 或 -32768 (0x8000) 处饱和。psubusb
减去无符号的 16 位字,在 0 (0x0000) 处饱和。psubd
使用无符号 32 位双字从另一个寄存器中减去一个寄存器或内存位置。
MMX 还提供了一些乘法指令。
pmulhw
使用带符号的 16 位字将一个寄存器与另一个寄存器或内存位置相乘。然后它存储每个 32 位结果的高 16 位。pmullw
乘法就像pmulhw
除了它存储每个 16 位结果的低 16 位。pmaddwd
将有符号的 16 位字相乘并加上 32 位结果。它将一个 MMX 寄存器和另一个寄存器或内存位置相乘。
MMX — Comparasons
MMX 提供了一系列用于执行各种大小比较的指令。
pcmpeqb
比较 MMX 寄存器和另一个寄存器或内存位置之间的 8 位相等性。对于相等的对,结果为全 1 (0xff),否则为 0 (0x00)。pcmpgtb
以与 相同的方式执行“大于”8 位值比较pcmpeqb
。对于较大的值,结果为全 1 (0xff),否则为 0 (0x00)。pcmpeqw
比较 16 位字的相等性,就像pcmpeqb
.pcmpgtw
是 16 位的等价物pcmpgtb
。pcmpeqd
比较 32 位双字是否相等。pcmpgtd
比较 32 位双字的大小,就像pcmpgtw
对单词一样。
MMX — Data Packing
MMX 提供了几种用于数据打包的指令。这些指令通常对值进行符号或零扩展、交错值和截断值。
packssdw
获取一个寄存器和另一个寄存器或内存位置,并将 32 位双字饱和为 16 位字。双字和字结果是有符号的。packsswb
获取一个寄存器和另一个寄存器或内存位置,并将两者中的 16 位有符号字饱和为第一个寄存器中的有符号 8 位字节。packuswb
类似于packsswb
,源字和结果字节是无符号的而不是有符号的。punpckhbw
将 2 个 MMX 寄存器或一个寄存器和一个内存位置的前 32 位解包到目标 MMX 寄存器中。的数据被交织在8位块,用2次操作数将顶半部和1第一操作数将底半部。punpckhdq
类似于punpckhbw
,除了它使用 32 位块而不是 8 位块。在1日操作数的上半部分去目的地的下半部分和2次操作的顶部进入到上半部分。punpckhwd
也类似于punpckhbw
,但使用 16 位块而不是 8 位块。1第一操作数进行到顶部半部分,和2个第二操作数进到下半部。punpcklbw
就像punpckhbw
,但不是从源的上半部分获取数据,而是从底部获取数据。punpckldq
就好像punpckhdq
,但它使用底部 32 位块而不是顶部 32 位块。punpcklwd
就像punpckhwd
,但它使用源的底部而不是顶部。
Trademark Information
MMX 是英特尔公司或其子公司在美国和其他国家/地区的注册商标。
以上是关于MultiMedia eXtensions - MMX:第一套应用于英特尔 80x86 指令集的 SIMD 扩展的主要内容,如果未能解决你的问题,请参考以下文章
QT中的 multimedia模块问题?如何添加.dll文件?
iOS technical support for Private multimedia