双字矢量在没有64位数据类型的旧Altivec上旋转

时间:2017-12-12 14:50:38

标签: c++ 64-bit intrinsics powerpc altivec

这与Power4和lack of vector long long有关。在Power7和Power8上我们可以执行:

typedef __vector unsigned long long uint64x2_p;
...

uint64x2_p val = {...};
uint64x2_p res = vec_rl(val, val, bits);

我需要找到缺少的64位矢量类型的解决方法,并在Power4上旋转。我认为有两种策略。首先,用C / C ++或者旋转;第二,使用32位向量类型。我猜测(2)是数据在向量寄存器中的更快策略。

我觉得很久以前这个问题就解决了,因为双字旋转没有什么特别之处。不幸的是,搜索没有返回有用的匹配:"power4" "doubleword" rotate

我认为我的基本算法包括三个LOAD,两个SHIFT,两个PERM和一个OR。但我不确定是否有更好的方法。

在没有双字旋转的Power4上工作时如何执行64位旋转?

typedef __vector unsigned int uint32x4_p;

template <unsigned int R>
inline uint32x4_p VecRotateLeft64(const uint32x4_p val)
{
    enum {LSHIFT = R%32};
    enum {RSHIFT = 32 - (R%32)};
    enum {PERMUTE = R > 32};

    const uint32x4_p lbits = {LSHIFT,LSHIFT,LSHIFT,LSHIFT};
    uint32x4_p left(vec_sl(val, lbits));

    const uint32x4_p rbits = {RSHIFT,RSHIFT,RSHIFT,RSHIFT};
    uint32x4_p right(vec_sr(val, rbits));

    const uint8x16_p mask = {4,5,6,7, 0,1,2,3, 12,13,14,15, 8,9,10,11};
    right = vec_perm(right, right, mask);
    uint32x4_p result = vec_or(left, right);

    // Permute left and right parts of 64-bit word as needed
    if (PERMUTE)
        result = vec_perm(result, result, mask);

    return result;
}

0 个答案:

没有答案