• 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条指令运算的结果与目的寄存器没有关系。

  • 相关阅读:
    mongodb 的云数据库产品 mlab 的使用
    koa 项目实战(十一)验证登录和注册的 input
    koa 项目实战(十)使用 validator 验证表单
    koa 项目实战(九)passport验证token
    koa 项目实战(八)生成token
    koa 项目实战(七)登录接口
    koa 项目实战(六)注册接口加密
    koa 项目实战(五)全球公用头像的使用
    [C++] 用Xcode来写C++程序[4] 函数
    [控件] 将字符串转换成贝塞尔曲线并执行动画
  • 原文地址:https://www.cnblogs.com/celerychen/p/2987188.html
Copyright © 2020-2023  润新知