zoukankan      html  css  js  c++  java
  • SSE特殊指令集系列之一

    实际上,搞汇编优化的很多时间是在处理如何有效的组织数据,以适应并行计算指令的数据结构。

    本小结描述的是数据混洗指令,这类指令使用起来相当的灵活。具体如下:

       1.  shufps  XMM,XMM/m128,imm8(0~255)

           描述:

               从指令后缀来看,这是一条SSE1指令。

               该指令把源存储器与目的寄存器按双字32位划分, 由立即数imm8八个二进制位(00~11,00^11,00~11,00~11)指定排列,

               目的寄存器高64位放源存储器被指定数,目的寄存器低64位放目的寄存器被指定数。内存变量地址必须对齐16字节

               imm8的高4位选的是源存储器,低4位选的是目的寄存器。

                          高64位 | 低64位

            目的寄存器:         a(11) | a(10) | a(01) | a(00)
            源寄存器:          b(11) | b(10) | b(01) | b(00)
            目的寄存器排列结果:       b(00~11) | b(00~11) | a(00~11) | a(00~11)
            目的寄存器压缩结果中的值由imm8对应的两位二进制位指定.

          例:
             ( 11 ) ( 10 ) ( 01 ) ( 00 ) ( 11 ) ( 10 ) ( 01 ) ( 00 )
          当    XMM0 = 0x 090a0b0c 0d0e0f11 01020304 05060708,

                            XMM1 = 0x 0aabbccdd eeff1234 22334455 66778899,

                  mm8  ══> (XMM1 10) (XMM1 01) (XMM0 11) (XMM0 00)

             执行shufps XMM0,XMM1,10 01 11 00 b(二进制),

                             则XMM0 = 0x 0eeff1234 22334455 090a0b0c 05060708

                      

             假如,shufps XMM0,XMM1,10 10 10 10 b,那么结果为:    XMM0 = 0x 0eeff1234 eeff1234 0d0e0f11 0d0e0f11

                          该指令一个常用用法如下:

                          float f = 0.5f;

            __asm

            {

                          movss   xmm2, f                         // xmm2[0] = 2.8
                          shufps  xmm2, xmm2, 0                   // xmm2[1, 2, 3] = xmm2[0]

            .....

            }

                           

     2.   shufpd XMM,XMM/m128,imm8(0~255) 

            描述:

             从指令后缀来看,这是一条SSE2指令。

             imm8(操作值) = imm8(输入值) mod 4

       把源存储器与目的寄存器按四字64位划分,由imm8(立即数)4个二进制位(0~1,0~1,0~1,0~1)指定排列,
       内存变量地址必须对齐16字节.目的寄存器高64位放源存储器被指定数,目的寄存器低64位放目的寄存器被指定数.
                        高64位 | 低64位
           目的寄存器:          a(1) | a(0)
           源寄存器:           b(1) | b(0)
           目的寄存器排列结果:      b(0~1) | a(0~1)
        例:
          当    XMM0 = 0x 1111111122222222 3333333344444444
             XMM1 = 0x 5555555566666666 aaaaaaaacccccccc,

                       执行 shufpd XMM0,XMM1,101001 1 0 b

            因为 101001 1 0 b mod 4 (101001 1 0 b & 11b), 得到操作值为1 0b,  

            高位 1 选择源寄存器 XMM1 的第1位  5555555566666666,

                       低位 0 选择目的寄存器XMM0的第0位   3333333344444444.


             则 XMM0 = 5555555566666666 3333333344444444 h
          

     3.  pshuflw XMM,XMM/m128,imm8(0~255)

          描述:  

      先把源存储器的高64位内容送入目的寄存器的高64位,然后用imm8将源存储器的低64位4个字选入
      目的寄存器的低64位,内存变量必须对齐内存16字节.

                                低64位
          源寄存器低64位:          b(11) | b(10) | b(01) | b(00)
          目的寄存器低64位排列结果:   b(00~11) | b(00~11) | b(00~11) | b(00~11)

      例:
      当 XMM0 = 0x 1111111122222222 3333 4444 5555 6666
        XMM1 = 0x 5555555566666666 7777 8888 9999 cccc ,

        执行 pshuflw XMM0,XMM1,10 10 01 10 b
      则  XMM0 = 0x 5555555566666666 8888 8888 9999 8888

    4.  pshufhw XMM,XMM/m128,imm8(0~255)

      描述:

          先把源存储器的低64位内容送入目的寄存器的低64位,然后用imm8将源存储器的高64位4个字选入
      目的寄存器的高64位,内存变量必须对齐内存16字节.
                          高64位
      源寄存器高64位:           b(11) | b(10) | b(01) | b(00)
      目的寄存器高64位排列结果:  b(00~11) | b(00~11) | b(00~11) | b(00~11)
      例:
      当 XMM0 = 0x 3333 4444 5555 6666 1111111122222222
          XMM1 = 0x 7777 8888 9999 cccc 5555555566666666,

         执行 pshufhw XMM0,XMM1,10 10 01 10 b
      则  XMM0 = 0x 8888 8888 9999 8888 5555555566666666

    5.  pshufd XMM,XMM/m128,imm8(0~255)

      描述:

      将源存储器的4个双字由imm8指定选入目的寄存器,内存变量必须对齐内存16字节.
                    高64位 | 低64位
      源寄存器:          (11) | b(10) | b(01) | b(00)
      目的寄存器排列结果: b(00~11) | b(00~11) | b(00~11) | b(00~11)
      例:
      当 XMM1 = 0x 11111111 22222222 33333333 44444444,

         执行 pshufd XMM0,XMM1,11 01 01 10b
      则 XMM0 = 0x 11111111 33333333 33333333 22222222

     小结:

        1. SHUFPS和SHUFPD指令运算的结果与源寄存器和目的寄存器有关

          2.  pshuflw、pshufhw、pshufd这3条指令运算的结果与目的寄存器没有关系。

  • 相关阅读:
    Eclipse插件
    Android res文件夹下新建layout文件夹出错:invalid resource directory name
    Java笔记一:斐波那契数列
    Android应用的启动界面
    android短信系列之实现发送短信,并获得发送报告与接收报告
    转:android 使用html5作布局文件
    ubuntu10.10 全自动安装微软雅黑字体
    gcswf32.dll已停用
    Android连接真机之中兴
    在Servlet中连接Access
  • 原文地址:https://www.cnblogs.com/celerychen/p/2987188.html
Copyright © 2011-2022 走看看