* fixed all implementations of strpas

This commit is contained in:
Jonas Maebe 2001-03-04 17:31:34 +00:00
parent 8efd8814cf
commit 18de59f50c
2 changed files with 78 additions and 42 deletions

View File

@ -847,43 +847,76 @@ end;
{$define FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR} {$define FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
function strpas(p:pchar):shortstring;[public,alias:'FPC_PCHAR_TO_SHORTSTR']; function strpas(p:pchar):shortstring;[public,alias:'FPC_PCHAR_TO_SHORTSTR'];
begin begin
asm asm
cld movl p,%esi
movl p,%edi
movl $0xff,%ecx
orl %edi,%edi
jnz .LStrPasNotNil
decl %ecx
jmp .LStrPasNil
.LStrPasNotNil:
xorl %eax,%eax
movl %edi,%esi
repne
scasb
.LStrPasNil:
movl %ecx,%eax
movl __RESULT,%edi movl __RESULT,%edi
notb %al leal 3(%esi),%edx
decl %eax movl $1,%ecx
stosb andl $-4,%edx
cmpl $7,%eax // skip length byte
jl .LStrPas2 incl %edi
movl %edi,%ecx { Align on 32bits } subl %esi,%edx
negl %ecx jz .LStrPasAligned
andl $3,%ecx // align source to multiple of 4 (not dest, because we can't read past
subl %ecx,%eax // the end of the source, since that may be past the end of the heap
rep // -> sigsegv!!)
movsb .LStrPasAlignLoop:
movl %eax,%ecx movb (%esi),%al
andl $3,%eax incl %esi
shrl $2,%ecx testb %al,%al
rep jz .LStrPasDone
movsl incl %edi
.LStrPas2: incb %cl
movl %eax,%ecx decb %dl
rep movb %al,-1(%edi)
movsb jne .LStrPasAlignLoop
end ['ECX','EAX','ESI','EDI']; .balign 16
.LStrPasAligned:
movl (%esi),%ebx
addl $4,%edi
leal 0x0fefefeff(%ebx),%eax
movl %ebx,%edx
addl $4,%esi
notl %edx
andl %edx,%eax
addl $4,%ecx
andl $0x080808080,%eax
movl %ebx,-4(%edi)
jnz .LStrPasEndFound
cmpl $252,%ecx
ja .LStrPasPreEndLoop
jmp .LStrPasAligned
.LStrPasEndFound:
subl $4,%ecx
// this won't overwrite data since the result = 255 char string
// and we never process more than the first 255 chars of p
shrl $8,%eax
jc .LStrPasDone
incl %ecx
shrl $8,%eax
jc .LStrPasDone
incl %ecx
shrl $8,%eax
jc .LStrPasDone
incl %ecx
jmp .LStrPasDone
.LStrPasPreEndLoop:
testb %cl,%cl
jz .LStrPasDone
movl (%esi),%eax
.LStrPasEndLoop:
testb %al,%al
jz .LStrPasDone
movb %al,(%edi)
shrl $8,%eax
incl %edi
incb %cl
jnz .LStrPasEndLoop
.LStrPasDone:
movl __RESULT,%edi
addb $255,%cl
movb %cl,(%edi)
end ['EAX','EBX','ECX','EDX','ESI','EDI'];
end; end;
@ -1164,8 +1197,8 @@ procedure inclocked(var l : longint);assembler;
{ {
$Log$ $Log$
Revision 1.6 2001-03-03 12:41:22 jonas Revision 1.7 2001-03-04 17:31:34 jonas
* simplified and optimized range checking code, FPC_BOUNDCHECK is no longer necessary * fixed all implementations of strpas
Revision 1.5 2000/11/12 23:23:34 florian Revision 1.5 2000/11/12 23:23:34 florian
* interfaces basically running * interfaces basically running

View File

@ -61,13 +61,13 @@ asm
// this won't overwrite data since the result = 255 char string // this won't overwrite data since the result = 255 char string
// and we never process more than the first 255 chars of p // and we never process more than the first 255 chars of p
shrl $8,%eax shrl $8,%eax
jz .LStrPasDone jc .LStrPasDone
incl %ecx incl %ecx
shrl $8,%eax shrl $8,%eax
jz .LStrPasDone jc .LStrPasDone
incl %ecx incl %ecx
shrl $8,%eax shrl $8,%eax
jz .LStrPasDone jc .LStrPasDone
incl %ecx incl %ecx
jmp .LStrPasDone jmp .LStrPasDone
.LStrPasPreEndLoop: .LStrPasPreEndLoop:
@ -106,7 +106,10 @@ end ['EDI','EAX','ECX'];
{ {
$Log$ $Log$
Revision 1.4 2001-03-04 12:42:18 jonas Revision 1.5 2001-03-04 17:31:35 jonas
* fixed all implementations of strpas
Revision 1.4 2001/03/04 12:42:18 jonas
* fixed strpas (was limited to 254 chars) and made it overall slightly faster * fixed strpas (was limited to 254 chars) and made it overall slightly faster
Revision 1.3 2001/02/10 16:08:46 jonas Revision 1.3 2001/02/10 16:08:46 jonas