Mult plus сдвиг влево, используя инструкции ассемблера MMX - PullRequest
1 голос
/ 27 июля 2011

Я ищу выполнение операции shl(mult(var1,var2),1), где mult умножает var1 и var2 (оба являются 16-разрядными целыми числами со знаком) и shl сдвигает влево арифметический результат умножения. Результат должен быть насыщенным, то есть int32 max или int32 min, если происходит переполнение или недостаточное заполнение, и mult(-32768,-32768)=2147483647.

Мне нужно сделать эту операцию для нескольких значений эффективным способом, для которого я думаю, используя набор инструкций MMX / SSE. Я думал о создании mult(sign_extesion(var1), shl(sign_extension(var2))), но я только что обнаружил, что не существует версии насыщения MMX mult(). Вы знаете какой-нибудь другой способ получить его?

1 Ответ

3 голосов
/ 27 июля 2011

Я думаю, что следующее должно работать для вас.Существует только один случай потенциального переполнения (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;
}
...