SIMD+signum+function

//by Richard Russell, 30th December 2014 (based on a [|blog post] by Raymond Chen)//

The **signum** function returns **-1** for all negative numbers, **+1** for all positive non-zero numbers and **zero** for an input of zero; it corresponds to the **SGN** function in BBC BASIC. There is no direct equivalent in assembly language, but the following code snippets illustrate how it may be calculated on multiple data values using MMX and SSE2 code. In all cases the **input** is in mm0 or xmm0 and the **output** is in mm1 or xmm1:

code format="asm" pxor   mm1, mm1 pxor   mm2, mm2 pcmpgtb mm1, mm0 ; mm1 = pcmpgt(0, x)     pcmpgtb mm0, mm2 ; mm0 = pcmpgt(x, 0) psubb  mm1, mm0 ; mm1 = signum code
 * Signum of eight 8-bit values**

code format="asm" pxor   mm1, mm1 pxor   mm2, mm2 pcmpgtw mm1, mm0 ; mm1 = pcmpgt(0, x)     pcmpgtw mm0, mm2 ; mm0 = pcmpgt(x, 0) psubw  mm1, mm0 ; mm1 = signum code
 * Signum of four 16-bit values**

code format="asm" pxor   mm1, mm1 pxor   mm2, mm2 pcmpgtd mm1, mm0 ; mm1 = pcmpgt(0, x)     pcmpgtd mm0, mm2 ; mm0 = pcmpgt(x, 0) psubd  mm1, mm0 ; mm1 = signum code
 * Signum of two 32-bit values**

code format="asm" pxor   xmm1, xmm1 pxor   xmm2, xmm2 pcmpgtb xmm1, xmm0 ; xmm1 = pcmpgt(0, x)     pcmpgtb xmm0, xmm2 ; xmm0 = pcmpgt(x, 0) psubb  xmm1, xmm0 ; xmm1 = signum code
 * Signum of sixteen 8-bit values (requires ASMLIB2 library)**

code format="asm" pxor   xmm1, xmm1 pxor   xmm2, xmm2 pcmpgtw xmm1, xmm0 ; xmm1 = pcmpgt(0, x)     pcmpgtw xmm0, xmm2 ; xmm0 = pcmpgt(x, 0) psubw  xmm1, xmm0 ; xmm1 = signum code
 * Signum of eight 16-bit values (requires ASMLIB2 library)**

code format="asm" pxor   xmm1, xmm1 pxor   xmm2, xmm2 pcmpgtd xmm1, xmm0 ; xmm1 = pcmpgt(0, x)     pcmpgtd xmm0, xmm2 ; xmm0 = pcmpgt(x, 0) psubd  xmm1, xmm0 ; xmm1 = signum code
 * Signum of four 32-bit values (requires ASMLIB2 library)**