while trying to convert a bunch of bytes to lowercase more than one char at a time I came up with this algo:

result = char XOR '@'
dec result
IF result GT 19H THEN result=00H ELSE result=0FFH
result = result AND ('a'-'A')
c=c+result

I knew mmx was all about paralell data manipulation so I thought I try it.

this is what I came up with:



.data
str1 db "'PADD and PSUB are the base mmx addition and subtraction instructions AHH',0
str2 db "'PADD and PSUB are the base mmx addition and subtraction instructions AHH',0
str3 db "'PADD and PSUB are the base mmx addition and subtraction instructions AHH',0
NCHARS equ (sizeof gstr1 -1)
NQWORDS equ NCHARS/8
xormask dq 04040404040404040H ;
dec1 dq 00101010101010101H ;used to decrement xor result
us dq 07F7F7F7F7F7F7F7FH ;used to clear sign bit
maxval dq 01919191919191919H ;only uppercase characters will be greater
a dq 02020202020202020H ;convert uppercase to lowercase
.code
mmxtolower1 proc
mov eax,offset str1
xor ecx,ecx
movq mm1,a
movq mm2,xormask
movq mm3,dec1
movq mm4,us
movq mm5,maxval
.while ecx<NQWORDS
movq mm0,[eax+ecx*8]
pxor mm0,mm2
psubb mm0,mm3 ;subtract 1 from each byte(0-19H)
pand mm0,mm4 ;convert to unsigned values
pcmpgtb mm0,mm5 ;if byte pos >19H put 00 else put FF in byte pos (the reverse of what we want)
pandn mm0,mm1 ;first invert mm0 then perform the and
paddb mm0,[eax+ecx*8] ;add the original values,uppercase letters are now converted to lowercase. all other chars unchanged.
movq [eax+ecx*8],mm0
inc ecx
.endw
emms
ret
mmxtolower1 endp


it proved not so straight forward in mmx I had to add a few steps in the mmx version

this is the test version so I've left in the .while construct. Can anyone do it any quicker? (without removing the .while construct)?

These routines do the same thing tolower is the non mmx version of the above algo and tolower2 is the standard version:
tolower proc

mov ecx,offset str2
mov dh,'@'
add ecx,NCHARS
mov dl,'a'-'A'
.while ecx>offset str2
dec ecx
mov al,[ecx]
mov ah,al
xor al,dh ;result = char xor '@'
dec al ;dec result
cmp al,19H ;
ja greaterthan
mov al,0FFH ;if result <19H result=0FFH
jmp @f
greaterthan:
mov al,0H ;else result= 00H
@@:
and al,dl ;result = result AND 'a'-'A'
add al,ah ;result =result + char
mov [ecx],al
not_capital:
.endw
ret
tolower endp

tolower2 proc
mov ecx,offset str3
add ecx,NCHARS
xor edx,edx
mov ax,'ZA'
.while ecx>offset str3
dec ecx
mov dl,[ecx]
cmp dl,ah
ja not_capital
cmp dl,al
jb not_capital
add dl,'a'-'A'
mov [ecx],dl
not_capital:
.endw
ret
tolower2 endp


and these are my results(athlon 1800XP):
string length=72 chars
mmxtolower :260 cyclecs
tolower :554 cycles
tolower2 :524 cycles
Posted on 2003-03-02 10:42:19 by MArtial_Code
It is dont work for Armenian strings ;)
Posted on 2003-03-02 11:19:23 by Nexo
Here is another way using fewer constants:
a	dq 02020202020202020h ;convert uppercase to lowercase


MMX_a dq 06060606060606060h
MMX_z db "zzzzzzzz"


.while ecx < NQWORDS
movq mm0, [eax+ecx*8]
movq mm1, mm0
pcmpgtb mm0, QWORD PTR MMX_a
pcmpgtb mm1, QWORD PTR MMX_z
pandn mm1, mm0
pand mm1, a
pxor mm1, [eax+ecx*8]
movq [eax+ecx*8], mm1
inc ecx
.endw
Posted on 2003-03-02 11:34:14 by bitRAKE
xor is transitive operation (a xor b = b xor a)
so instead of
pxor mm1,
movq , mm1
you can just:
pxor ,mm1
Posted on 2003-03-02 12:03:33 by The Svin

xor is transitive operation (a xor b = b xor a)
so instead of
pxor mm1,
movq , mm1
you can just:
pxor ,mm1


You need create thread "Opcode MMX #0" ;)
Posted on 2003-03-02 12:19:06 by Nexo
It's rather about boolean algebra than opcode
construction :)
Posted on 2003-03-02 13:49:32 by The Svin
Svin, "pxor ,mm1" is not a valid instruction.
Posted on 2003-03-02 14:02:32 by bitRAKE
Understood, bitRake, after Nexo post.
Just jocking :)
Posted on 2003-03-02 14:34:08 by The Svin
Thanks all.
Bitrake the code you posted converts to upper case but it should be simple to reverse it.
Posted on 2003-03-03 03:51:56 by MArtial_Code

Bitrake the code you posted converts to upper case but it should be simple to reverse it.
Yep. :)
MMX_a	db "@@@@@@@@"

MMX_z db "ZZZZZZZZ"
Posted on 2003-03-03 09:11:04 by bitRAKE