2011-08-20 16 views
2

您是否知道使用MMX/SSE彙編程序指令添加飽和度32位帶符號字的任何方式?我可以找到8/16位版本,但沒有32位版本。添加具有飽和度的32位字

問候

+0

請參閱[Agner Fog的矢量類庫](http://www.agner.org/optimize/#vectorclass),瞭解使用C++內在函數進行加法和減法的實現。 GPLed源代碼的副本[https://github.com/pcordes/vectorclass/blob/77522287e64da5e887d69659e144d2caa5d3a4f1/vectori128.h#L2189],使用異或來檢查相同/不同的符號,並將/ PANDN/PADDD以確定結果。 –

回答

1

可以模擬飽和簽名添加由執行以下步驟:

int saturated_add(int a, int b) 
{ 
    int sum = a + b; 
    if (a >= 0 && b >= 0) 
     return sum > 0 ? sum : INT32_MAX;  // catch positive wraparound 
    else if (a < 0 && b < 0) 
     return sum > 0 ? INT32_MIN : sum;  // catch negative wraparound 
    else 
     return sum;       // sum of pos + neg always fits 
} 

無符號,它更簡單,看this stackoverflow posting

在SSE2,上述映射到的序列並行比較和AND/ANDN操作。不幸的是,沒有單一的操作

1

飽和無符號減法,是很容易的,因爲對於一個` - = B」,我們可以做

asm (
     "pmaxud %1, %0\n\t" // a = max (a,b) 
     "psubd %1, %0" // a -= b 
     : "+x" (a) 
     : "xm" (b) 
    ); 

與SSE。

我正在尋找無符號的加法,但可能唯一的辦法是轉換爲飽和的無符號減法,執行它並轉換回來。相同的簽名變體。

編輯:與無符號的加法,你得到min (a, ~b) + b這種方式,這當然有效。使用帶符號的加法和減法,您有兩個飽和邊界,這使事情變得複雜。