(Gast)
n/a Beiträge
|
Re: Bitte Assembler-Routine verbessern
23. Dez 2007, 20:30
Delphi-Quellcode:
function CharPos_JOH_SSE2_1_b(Ch : Char; const Str : AnsiString; aStart : Integer = 1) : Integer;
asm
test edx, edx
jz @@NullString
mov esi, ecx
dec esi
mov ecx, [edx-4]
cmp esi, ecx
jle @@Continue
xor eax, eax
ret
@@Continue:
add ecx, esi
add edx, esi
push ebx
mov ebx, eax
cmp ecx, 16
jl @@Small
@@NotSmall:
mov ah, al {Fill each Byte of XMM1 with AL}
movd xmm1, eax
pshuflw xmm1, xmm1, 0
pshufd xmm1, xmm1, 0
@@First16:
movups xmm0, [edx] {Unaligned}
pcmpeqb xmm0, xmm1 {Compare First 16 Characters}
pmovmskb eax, xmm0
test eax, eax
jnz @@FoundStart {Exit on any Match}
cmp ecx, 32
jl @@Medium {If Length(Str) < 32, Check Remainder}
@@Align:
sub ecx, 16 {Align Block Reads}
push ecx
mov eax, edx
neg eax
and eax, 15
add edx, ecx
neg ecx
add ecx, eax
@@Loop:
movaps xmm0, [edx+ecx] {Aligned}
pcmpeqb xmm0, xmm1 {Compare Next 16 Characters}
pmovmskb eax, xmm0
test eax, eax
jnz @@Found {Exit on any Match}
add ecx, 16
jle @@Loop
pop eax {Check Remaining Characters}
add edx, 16
add eax, ecx {Count from Last Loop End Position}
jmp dword ptr [@@JumpTable2-ecx*4]
nop
nop
@@NullString:
xor eax, eax {Result = 0}
ret
nop
@@FoundStart:
bsf eax, eax {Get Set Bit}
pop ebx
inc eax {Set Result}
ret
nop
nop
@@Found:
pop edx
bsf eax, eax {Get Set Bit}
add edx, ecx
pop ebx
lea eax, [eax+edx+1] {Set Result}
ret
@@Medium:
add edx, ecx {End of String}
mov eax, 16 {Count from 16}
jmp dword ptr [@@JumpTable1-64-ecx*4]
nop
nop
@@Small:
add edx, ecx {End of String}
xor eax, eax {Count from 0}
jmp dword ptr [@@JumpTable1-ecx*4]
nop
@@JumpTable1:
dd @@NotFound, @@01, @@02, @@03, @@04, @@05, @@06, @@07
dd @@08, @@09, @@10, @@11, @@12, @@13, @@14, @@15, @@16
@@JumpTable2:
dd @@16, @@15, @@14, @@13, @@12, @@11, @@10, @@09, @@08
dd @@07, @@06, @@05, @@04, @@03, @@02, @@01, @@NotFound
@@16:
add eax, 1
cmp bl, [edx-16]
je @@Done
@@15:
add eax, 1
cmp bl, [edx-15]
je @@Done
@@14:
add eax, 1
cmp bl, [edx-14]
je @@Done
@@13:
add eax, 1
cmp bl, [edx-13]
je @@Done
@@12:
add eax, 1
cmp bl, [edx-12]
je @@Done
@@11:
add eax, 1
cmp bl, [edx-11]
je @@Done
@@10:
add eax, 1
cmp bl, [edx-10]
je @@Done
@@09:
add eax, 1
cmp bl, [edx-9]
je @@Done
@@08:
add eax, 1
cmp bl, [edx-8]
je @@Done
@@07:
add eax, 1
cmp bl, [edx-7]
je @@Done
@@06:
add eax, 1
cmp bl, [edx-6]
je @@Done
@@05:
add eax, 1
cmp bl, [edx-5]
je @@Done
@@04:
add eax, 1
cmp bl, [edx-4]
je @@Done
@@03:
add eax, 1
cmp bl, [edx-3]
je @@Done
@@02:
add eax, 1
cmp bl, [edx-2]
je @@Done
@@01:
add eax, 1
cmp bl, [edx-1]
je @@Done
@@NotFound:
xor eax, eax
pop ebx
ret
@@Done:
pop ebx
end;
Ich hab kein Delphi, um es zu testen.. Aber ich vermute, dass es so läuft. Was ich hier tue, entspricht weitgehend deiner Vermutung: am Anfang sagen wir einfach, dass der String aStart Zeichen kürzer ist als tatsächlich und setzen den Anfang des Strings (für die Funktion) auf das Zeichen bei aStart.
|