代码之家  ›  专栏  ›  技术社区  ›  jww avp

vec\u sld endian是否敏感?

  •  5
  • jww avp  · 技术社区  · 7 年前

    下面的算法是 IBM blog article

    typedef __vector unsigned char  uint8x16_p8;
    uint8x64_p8 r0 = {0};
    
    r3 = vec_perm(r1, r1, r5);       /* line  1 */
    r6 = vec_sld(r0, r1, 12);        /* line  2 */
    r3 = vcipherlast(r3, r4);        /* line  3 */
    
    r1 = vec_xor(r1, r6);            /* line  4 */
    r6 = vec_sld(r0, r6, 12);        /* line  5 */
    r1 = vec_xor(r1, r6);            /* line  6 */
    r6 = vec_sld(r0, r6, 12);        /* line  7 */
    r1 = vec_xor(r1, r6);            /* line  8 */
    r4 = vec_add(r4, r4);            /* line  9 */
    
    // r1 is ready for next round
    r1 = vec_xor(r1, r3);            /* line 10 */
    

    进入函数后,大端和小端都有以下参数:

    (gdb) p r1
    $1 = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88,
      0x9, 0xcf, 0x4f, 0x3c}
    (gdb) p r5
    $2 = {0xd, 0xe, 0xf, 0xc, 0xd, 0xe, 0xf, 0xc, 0xd, 0xe, 0xf, 0xc, 0xd, 0xe,
      0xf, 0xc}
    

    然而,在执行第2行之后, r6 具有以下值:

    :

    (gdb) p r6
    $3 = {0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x9, 0xcf, 0x4f, 0x3c,
      0x0, 0x0, 0x0, 0x0}
    
    (gdb) p $vs0
    $3 = {uint128 = 0x8815f7aba6d2ae28000000003c4fcf09, v2_double = {
        4.9992689728788323e-315, -1.0395462025288474e-269}, v4_float = {
        0.0126836384, 0, -1.46188823e-15, -4.51291888e-34}, v4_int32 = {
        0x3c4fcf09, 0x0, 0xa6d2ae28, 0x8815f7ab}, v8_int16 = {0xcf09, 0x3c4f, 0x0,
        0x0, 0xae28, 0xa6d2, 0xf7ab, 0x8815}, v16_int8 = {0x9, 0xcf, 0x4f, 0x3c,
        0x0, 0x0, 0x0, 0x0, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88}}
    

    大端机

    (gdb) p r6
    $4 = {0x0, 0x0, 0x0, 0x0, 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
      0xab, 0xf7, 0x15, 0x88}
    

    注意little endian机器上的奇数旋转。

    当我在第2行执行后在little endian机器上拆解时:

     (gdb) disass $pc
     <skip multiple pages>
    
        0x0000000010000dc8 <+168>:   lxvd2x  vs12,r31,r9
        0x0000000010000dcc <+172>:   xxswapd vs12,vs12
        0x0000000010000dd0 <+176>:   xxlor   vs32,vs0,vs0
        0x0000000010000dd4 <+180>:   xxlor   vs33,vs12,vs12
        0x0000000010000dd8 <+184>:   vsldoi  v0,v0,v1,12
        0x0000000010000ddc <+188>:   xxlor   vs0,vs32,vs32
        0x0000000010000de0 <+192>:   xxswapd vs0,vs0
        0x0000000010000de4 <+196>:   li      r9,64
        0x0000000010000de8 <+200>:   stxvd2x vs0,r31,r9
     => 0x0000000010000dec <+204>:   li      r9,48
        0x0000000010000df0 <+208>:   lxvd2x  vs0,r31,r9
        0x0000000010000df4 <+212>:   xxswapd vs34,vs0
    
    (gdb) p $v0
    $5 = void
    
    (gdb) p $vs0
    $4 = {uint128 = 0x8815f7aba6d2ae28000000003c4fcf09, v2_double = {
        4.9992689728788323e-315, -1.0395462025288474e-269}, v4_float = {
        0.0126836384, 0, -1.46188823e-15, -4.51291888e-34}, v4_int32 = {
        0x3c4fcf09, 0x0, 0xa6d2ae28, 0x8815f7ab}, v8_int16 = {0xcf09, 0x3c4f, 0x0,
        0x0, 0xae28, 0xa6d2, 0xf7ab, 0x8815}, v16_int8 = {0x9, 0xcf, 0x4f, 0x3c,
        0x0, 0x0, 0x0, 0x0, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88}}
    

    r6 不是预期值。理想情况下,我会检查两台机器上的vsx寄存器。不幸的是,GDB在这两台机器上都有问题,所以我不能做反汇编和打印向量寄存器之类的事情。

    vec_sld endian敏感?还是有其他问题?

    1 回复  |  直到 7 年前
        1
  •  6
  •   Paul R    7 年前

    使用PowerPC/AltiVec的Little endian有时会有点让人费解-如果你需要让你的代码同时使用big和Little endian,那么它有助于定义一些可移植性宏,例如 vec_sld :

    #ifdef __BIG_ENDIAN__
      #define VEC_SLD(va, vb, shift) vec_sld(va, vb, shift)
    #else
      #define VEC_SLD(va, vb, shift) vec_sld(vb, va, 16 - (shift))
    #endif
    

    您可能会发现这对所有涉及水平/位置操作或缩小/扩大的内部函数都有帮助,例如。 vec_merge vec_pack , vec_unpack vec_perm , vec_mule vec_mulo , vec_splat , vec_lvsl vec_lvsr

    推荐文章