替换x86 pshufb指令

现象描述

编译报错:unknown mnemonic 'pshufb' -- 'pshufb'。

问题原因

pshufb(Packed Shuffle Bytes),功能是根据第二个操作数指定的控制掩码对第一个操作数执行散列操作,产生一个组合数。它是x86平台的汇编指令,在鲲鹏平台上需要做替换。x86上的指令用法:

pshufb xmm1, xmm2/m128

处理步骤

pshufb指令对应的SSE intrinsic函数是_mm_shuffle_epi8,因此pshufb在鲲鹏上的替换可以分为两步:

  1. 将pshufb汇编指令替换成SSE intrinsic。

    x86上实现样例:
    __asm__("pshufb %1, %0" : "+x" (mmdesc) : "xm" (shuf_mask));
    鲲鹏上先替换成SSE intrinsic函数:
    _mm_shuffle_epi8(mmdesc, shuf_mask);

  2. 移植内联SSE函数_mm_shuffle_epi8。GCC目前没有提供对应的鲲鹏平台版本,需要实现对应函数。

    FORCE_INLINE __m128i _mm_shuffle_epi8(__m128i a, __m128i b)
    {
        uint8x16_t tbl = vreinterpretq_u8_m128i(a);
        uint8x16_t idx = vreinterpretq_u8_m128i(b);
        uint8_t __attribute__((aligned(16))) mask[16] = {0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F,
    0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F, 0x8F};
        uint8x16_t idx_masked = vandq_u8(idx, vld1q_u8(mask));
        return vreinterpretq_m128i_u8(vqtbl1q_u8(tbl, idx_masked));
    }