MMX指令集系列之三----数据饱和压缩与重排指令

6. 数据压缩指令

    packuswb MM,MM/m64

   把目的寄存器按字有符号数压缩为饱和字节无符号数放入目的寄存器低32位,
   把源寄存器字有符号数压缩为饱和字节无符号数放入目的寄存器高32位。

   简单的说,就是16位有符号压缩为饱和8位无符号数

                     高32位  | 低32位
  目的寄存器:                  a0 | a1 | a2 | a3
  源寄存器:                     b0 | b1 | b2 | b3
  目的寄存器压缩结果:    b0|b1| b2|b3| a0|a1|a2|a3
  例:
  当MM0 == 0x  7fff 8000 1234 00ae,

         MM1== 0x 00ad 0123 80ff 0100,

  执行packuswb MM0,MM1,则MM0 = 0x ad ff 00 ff ff 00 ff ae.

 

  packsswb MM,MM/m64
  把目的寄存器按字有符号数压缩为字节有符号数放入目的寄存器低32位
  把源寄存器按字有符号数压缩为字节有符号数放入目的寄存器高32位
  压缩时小于-128负数变为80h,大于127的正数变为7fh.

        简单的说,就是16位有符号压缩为饱和8位有符号数
                   高32位 | 低32位
  目的寄存器:        a0 | a1 | a2 | a3
  源寄存器:           b0 | b1 | b2 | b3
  目的寄存器压缩结果:        b0|b1| b2|b3| a0|a1|a2|a3
  例:
  当MM0 == 0x 0fff   ff06 0080 0012,

        MM1 == 0x 0001 8000 ffff  7fff ,

   执行packsswb MM0,MM1,则 MM0 = 0x 01 80 ff 7f 7f 80 7f 12

  packssdw MM,MM/m64
  把目的寄存器按双字有符号数压缩为单字有符号数放入目的寄存器低32位
  把源寄存器按双字有符号数压缩为单字有符号数放入目的寄存器高32位
  压缩时小于-32768负数变为8000h,大于32767的正数变为7fffh.
          高32位 | 低32位
  目的寄存器:      a0 | a1
  源寄存器 :      b0 | b1
  目的寄存器压缩结果:  b0 | b1 | a0 | a1


      简单的说,就是32位有符号压缩为饱和16位有符号数

 

7.  数据重排指令

   punpcklbw MM,MM/m64

  把目的寄存器与源寄存器的低32位按字节交错排列放入目的寄存器
                  高32位 | 低32位
  目的寄存器: a0 | a1| a2  | a3 | a4 | a5 | a6 |a7
  源寄存器:    b0 | b1| b2 | b3 | b4 | b5 | b6 |b7
  目的寄存器结果: b4|a4|b5|a5|b6|a6|b7|a7
  例:
  当MM0 == 0x 01 02 03 04 05 06 07 08,

        MM1 == 0x 09 0a 0b 0c 0d 0e 0f 00
  执行punpcklbw MM0,MM1,

        则MM0 = 0x 0d 05 0e 06 0f 07 00 08

  punpcklwd MM,MM/m64
  把目的寄存器与源寄存器的低32位按交错排列放入目的寄存器
         高32位 | 低32位
  目的寄存器:  a0  | a1  | a2 | a3
  源寄存器:     b0  | b1 | b2 | b3
  目的寄存器结果: b2 | a2 | b3 | a3

 

  punpckldq MM,MM/m64
  把目的寄存器与源寄存器的低32位按双字交错排列放入目的寄存器
          高32位 | 低32位
  目的寄存器:      a0 | a1
  源寄存器:       b0 | b1
  目的寄存器结果:       b1 | a1

 

  punpckhbw MM,MM/m64
  把目的寄存器与源寄存器的高32位按字节交错排列放入目的寄存器
                       高32位 | 低32位
  目的寄存器:      a0 |a1|a2|a3|a4|a5|a6|a7
  源寄存器:         b0|b1|b2|b3|b4|b5|b6|b7
  目的寄存器结果:    b0|a0|b1|a1|b2|a2|b3|a3
  例:
  当  MM0 == 0x 01 02 03 04 05 06 07 08,

              MM1 == 0x 09 0a 0b 0c 0d 0e 0f  00
  执行punpcklbw MM0,MM1,

           则MM0 = 0x 09 01 0a 02 0b 03 0c 04

  punpckhwd MM,MM/m64
  把目的寄存器与源寄存器的高32位交错排列放入目的寄存器
             高32位 | 低32位
  目的寄存器:      a0 | a1 | a2 | a3
  源寄存器:     b0 | b1 | b2 | b3
  目的寄存器结果:   b0 | a0 | b1 | a1

  punpckhdq MM,MM/m64
  把目的寄存器与源寄存器的高32位按双字交错排列放入目的寄存器
        高32位 | 低32位
  目的寄存器:    a0 | a1
  源寄存器:     b0 | b1
  目的寄存器结果:  b0 | a0

 

小结:

   1. 数据压缩指令和NEON窄指令相类似,所生成的元素是源操作数位宽的一半。

   2. 数据重排指令与NEON指令VZIP有类似之处,具体请参考NOEN相关指令集说明。

 

8.  位运算指令


    PXORMM,MM/m64/imm8  

    POR MM,MM/m64/imm8

    PAND MM,MM/m64/imm8

    PANDN  MM,MM/m64/imm8

  

   两个MMX寄存器,

    MMX寄存器与64位内存变量,

    MMX寄存器与一个8位立即数常量, 分别进行

   按位逻辑异或运算

   按位逻辑或运算

   按位逻辑与运算

   按位逻辑与非运算

    与非操作的C语言解释如下:

    Dest = (^Dest)&Src;

    即目的操作数先取非操作,再与源操作数进行逻辑与运算,得到的结果赋给目的操作数。


9.   比较指令

   9.1 并行字节相等比较指令


        PCMPEQB  MM,MM/m64

        
       
如果相等,目标寄存器所有对应为1,即0xFF,否则为0x00


 
 9.2 并行字节大于比较指令
       

         PCMPGTB  MM,MM/m64
    
  
   9.3 并行字相等比较指令
       

         PCMPEQW  MM,MM/m64
        
        如果相等,目标寄存器所有对应为1,即0xFF,否则为0x00


   9.4 并行字大于比较指令

 
        PCMPGTW MM,MM/m64


   9.5 并行双字相等比较指令

 
        PCMPEQD  MM,MM/m64
        
        如果相等,目标寄存器所有对应为1,即0xFF,否则为0x00


 
 9.6 并行双字大于比较指令

 
         PCMPGTD MM,MM/m64




 

posted @ 2013-04-23 12:22  celerychen  阅读(561)  评论(0编辑  收藏  举报