使用 MMX 汇编指令的乘法加左移操作

发布于 11-26 13:32 字数 449 浏览 9 评论 0原文

我正在寻找进行 shl(mult(var1,var2),1) 操作,其中 mult 乘以 var1var2(均为 16 位有符号整数)和 shl 对乘法结果进行算术左移。如果发生上溢或下溢且 mult(-32768,-32768)=2147483647,结果必须是饱和的,即 int32 max 或 int32 min。

我需要以一种有效的方式对多个值进行此操作,我认为使用 MMX/SSE 指令集。我想制作 mult(sign_extension(var1), shl(sign_extension(var2))) 但我刚刚发现没有 MMX mult() 存在饱和版本。你知道还有其他方法可以得到它吗?

I am looking for doing shl(mult(var1,var2),1) operation, where mult multiplies var1 and var2 (both are 16-bit signed integers) and shl shifts left arithmetically the multiplication result. Result must be saturated, i.e., int32 max or int32 min if overflow or underflow occurs and mult(-32768,-32768)=2147483647.

I need to make this op for multiple values in an efficient way for which I think using MMX/SSE instruction set. I though about making mult(sign_extesion(var1), shl(sign_extension(var2))) but I've just discovered no MMX mult() saturation version exists. Do you know any other way to get it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

菩提树下叶撕阳。2024-12-03 13:32:12

我认为以下内容应该适合您。只有一种潜在的溢出情况 (SHRT_MIN * SHRT_MIN),它会显式处理这种情况:

#include <limits.h>
#include <mmintrin.h>

int main(void)
{        
    __m64 v1 = _mm_set_pi16(0, SHRT_MAX, 0, SHRT_MIN);
    __m64 v2 = _mm_set_pi16(0, SHRT_MIN, 0, SHRT_MIN);
    __m64 v = _mm_madd_pi16(v1, v2); // 16 x 16 signed multiply
    v = _mm_slli_pi32(v, 1);         // shift left by 1 bit to get full range
    __m64 vcmp = _mm_cmpeq_pi32(v, _mm_set1_pi32(INT_MIN));
                                     // test for SHRT_MIN * SHRT_MIN overflow
    v = _mm_add_pi32(v, vcmp);       // and correct if needed

    return 0;
}

I think the following should work for you. There is only one potential overflow case (SHRT_MIN * SHRT_MIN) and it handles this explicitly:

#include <limits.h>
#include <mmintrin.h>

int main(void)
{        
    __m64 v1 = _mm_set_pi16(0, SHRT_MAX, 0, SHRT_MIN);
    __m64 v2 = _mm_set_pi16(0, SHRT_MIN, 0, SHRT_MIN);
    __m64 v = _mm_madd_pi16(v1, v2); // 16 x 16 signed multiply
    v = _mm_slli_pi32(v, 1);         // shift left by 1 bit to get full range
    __m64 vcmp = _mm_cmpeq_pi32(v, _mm_set1_pi32(INT_MIN));
                                     // test for SHRT_MIN * SHRT_MIN overflow
    v = _mm_add_pi32(v, vcmp);       // and correct if needed

    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文