News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

[SSE2]Make all bytes positive

Started by Farabi, December 21, 2012, 07:58:19 PM

Previous topic - Next topic

Farabi

http://farabidatacenter.url.ph/MySoftware/
My 3D Game Engine Demo.

Contact me at Whatsapp: 6283818314165

Farabi

Quote from: jj2007 on December 21, 2012, 08:26:06 PM
Something like this?

.code
whatever   db 123, -127, 99, 255, 128, 127, 0, 100, 123, -127, 99, 255, 128, 127, 0, 100
start:
   mov eax, 7f7f7f7fh
   movd xmm1, eax
   pshufd xmm1, xmm1, 0
   movups xmm0, oword ptr whatever
   andps xmm0, xmm1


JJ I think you just remove the positive sign bit, not change the value to a correct positive value.
http://farabidatacenter.url.ph/MySoftware/
My 3D Game Engine Demo.

Contact me at Whatsapp: 6283818314165

dedndave

maybe you can make an SSE equiv based on this concept
mov eax,n
cdq
xor eax,edx
sub eax,edx

the byte version would be
mov al,n
cbw
xor al,ah
sub al,ah



jj2007

Quote from: Farabi on December 22, 2012, 03:00:56 PM
JJ I think you just remove the positive sign bit,

Yes

Quotenot change the value to a correct positive value.

Until this point, you have not explained what the "correct positive value" would be. If your negative input byte is -123, is the "correct positive value" +123, or zero, or what? GIVE US A RULE.

We need more context. For example, how often will the negative value happen? You can detect it with a member of the pcmpGTb family (as mentioned by qWord), and then manipulate the bytes accordingly, either with "normal" or SSE instructions.

dedndave

i think what he's saying is...
if you remove the sign bit from a positive number, no adjustment is necessary (nothing happens)
if you remove the sign bit from a negative number, it needs adjustment

11111111 is = -1
01111111 is not = +1

jj2007

Dave, you can't remove the sign bit from a positive number :eusa_naughty:
Jokes apart, let's wait if Farabi can formulate a rule...

Farabi

I want -123 become 123. -1 become 1. THat is it.

I can simply use neg, but still it need another cycle for checking each bytes for negative. I though there are a single instruction for this.
http://farabidatacenter.url.ph/MySoftware/
My 3D Game Engine Demo.

Contact me at Whatsapp: 6283818314165

jj2007

Ok, now I understand. My idea was to go this road:

.data
whatever   db 123, -127, 99, 255, 128, 127, 0, 100, 123, -127, 99, 255, 128, 127, 0, 100
.code
        movups xmm0, oword ptr whatever
        movups xmm1, oword ptr whatever
        mov eax, 7f7f7f7fh
        movd xmm2, eax
        pshufd xmm2, xmm2, 0
        int 3
        pcmpgtb xmm1, xmm2
        pmovmskb eax, xmm1        ; set byte mask in eax

Status after pcmpgtb:
XMM0 64007F80 FF63817B 64007F80 FF63817B
XMM1 00000000 00000000 00000000 00000000
XMM2 7F7F7F7F 7F7F7F7F 7F7F7F7F 7F7F7F7F


Bad luck, I expected some bytes in Xmm1 set to FF. Right now I have no time to investigate further. Launch Olly and try your luck :icon14:

dedndave

MMX and SSE are not exactly my forte'
but - i wouldn't mind getting my feet wet   :P

not sure what the best way is to set an XMM register to all 0's
but, let's say XMM1 is all 0's

pcmpgtb xmm1,oword ptr whatever

this does the CBW for us (equivalent in this case - doesn't actually make them words)
for each byte in "whatever", the corresponding byte is XMM1 is all 1's if the source byte is negative
from there, you can do the same thing as i showed you earlier

you get the "whatever" bytes into XMM2 (again, not sure what the best way is)

then XOR xxm2,xmm1 (not sure what the instruction is)

then SUB (bytes) xxm2,xmm1 (not sure what the instruction is)

mov al,n
cbw
xor al,ah
sub al,ah

jj2007

I got it!

include \masm32\MasmBasic\MasmBasic.inc        ; download
.data
whatever   db 123, 99, 127, -127, 255, 128, 0, 100, 123, -127, 255, 128, 99, 127, 0, 100
        Init
        movups xmm0, oword ptr whatever
        movups xmm1, oword ptr whatever
        or eax, -1
        movd xmm2, eax
        pshufd xmm2, xmm2, 0
        pcmpgtb xmm1, xmm2
        pmovmskb eax, xmm1        ; set byte mask in eax
        Inkey Right$(Bin$(eax), 16)
        Exit
end start

Output (read from right to left):
1111000111000111

dedndave

i was close   :P
my first whack at SSE

dedndave

i don't know why this doesn't do anything - lol

;###############################################################################################

        .XCRef
        .NoList
        INCLUDE    \Masm32\Include\Masm32rt.inc
        .686p
        .MMX
        .XMM
        INCLUDE    \Masm32\Macros\Timers.asm
        .List

;###############################################################################################

        .DATA

oData   db 123,99,127,-127,-1,-128,0,100,123,-127,-1,-128,99,127,0,100

;###############################################################################################

        .CODE

;***********************************************************************************************

_main   PROC

        call    show16s
        movups  xmm0,oword ptr oData
        xorps   xmm1,xmm1
        pcmpgtb xmm1,xmm0
        xorps   xmm0,xmm1
        psubb   xmm0,xmm1
        movups  oword ptr oData,xmm0
        call    show16u

        inkey
        exit

_main   ENDP

;***********************************************************************************************

show16s PROC

        mov     esi,offset oData
        mov     ebx,16

sh16s0: movsx   eax,byte ptr [esi]
        print   str$(eax),44,32
        inc     esi
        dec     ebx
        jnz     sh16s0

        print   chr$(13,10)
        ret

show16s ENDP

;***********************************************************************************************

show16u PROC

        mov     esi,offset oData
        mov     ebx,16

sh16u0: movzx   eax,byte ptr [esi]
        print   ustr$(eax),44,32
        inc     esi
        dec     ebx
        jnz     sh16u0

        print   chr$(13,10)
        ret

show16u ENDP

;###############################################################################################

        END     _main

jj2007

Try my version :biggrin:
-123 +99 +127 -127 -1 -128 +0 +100 +123 -127 -1 -128 +99 +127 +0 -100
+123 +99 +127 +127 +1 +127 +0 +100 +123 +127 +1 +127 +99 +127 +0 +100


Besides, your code seems to produce exactly the same result :t

123, 99, 127, -127, -1, -128, 0, 100, 123, -127, -1, -128, 99, 127, 0, 100,
123, 99, 127, 127, 1, 128, 0, 100, 123, 127, 1, 128, 99, 127, 0, 100,


Well, almost. Is byte 128 positive?
;-)

dedndave

oops
i was using ML version 6.14
the PCMPGTB and PSUBB instructions were using MMX registers, not XMM registers   :biggrin:

that's my first SSE code   :eusa_dance:

what ? - you haven't compared timing ?
is that someone else using Jochen's ID ?????   :lol:

dedndave

oh - didn't see the question

the bit pattern 10000000 is -128 as a signed byte, +128 as an unsigned byte
it is a special case (like 0) because, to negate it, you do nothing   :P
of course, +128 is not in the range of signed byte values

Try my version :biggrin:
-123 +99 +127 -127 -1 -128 +0 +100 +123 -127 -1 -128 +99 +127 +0 -100
+123 +99 +127 +127 +1 +127 +0 +100 +123 +127 +1 +127 +99 +127 +0 +100