SSE代码移植Neon:mm_madd_epi16与mm_maddubs_epi16等价指令查询
SSE
_mm_madd_epi16 与 _mm_maddubs_epi16 的Neon适配方案 _mm_madd_epi16 实现
原SSE函数功能:输入两个128位的有符号16位整数向量,对应元素相乘后将相邻两个乘积求和,输出4个有符号32位整数组成的128位向量。
Neon等价实现:
#include <arm_neon.h> inline int32x4_t neon_madd_epi16(int16x8_t a, int16x8_t b) { // 分别计算高低半区16位元素的乘积,扩展为32位 int32x4_t mul_low = vmull_s16(vget_low_s16(a), vget_low_s16(b)); int32x4_t mul_high = vmull_s16(vget_high_s16(a), vget_high_s16(b)); // 相邻元素成对相加,得到最终4个32位结果 return vpaddq_s32(mul_low, mul_high); }
_mm_maddubs_epi16 实现
原SSE函数功能:第一个输入为128位无符号8位整数向量,第二个为128位有符号8位整数向量,对应元素相乘后将相邻两个乘积求和,输出8个有符号16位整数组成的128位向量。
Neon等价实现:
#include <arm_neon.h> inline int16x8_t neon_maddubs_epi16(uint8x16_t a, int8x16_t b) { // 完成无符号8位与有符号8位的乘法,扩展为16位 int16x8_t mul_res = vmull_s8(vreinterpretq_s8_u8(a), b); // 修正无符号数强转有符号带来的偏移误差 int16x8_t offset = vshll_n_u8(a, 7); mul_res = vsubq_s16(mul_res, offset); // 相邻元素成对相加,得到最终8个16位结果 return vpaddq_s16(mul_res, mul_res); }
验证说明
上述两种实现完全对齐SSE原版函数的运算规则、溢出处理逻辑,可直接在移植代码中替换使用,仅需注意入参出参的向量类型对应即可。
内容的提问来源于stack exchange,提问作者sunmoon
相关产品推荐
相关产品推荐

