* 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}
function strpas(p:pchar):shortstring;[public,alias:'FPC_PCHAR_TO_SHORTSTR'];
begin
asm
cld
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
asm
movl p,%esi
movl __RESULT,%edi
notb %al
decl %eax
stosb
cmpl $7,%eax
jl .LStrPas2
movl %edi,%ecx { Align on 32bits }
negl %ecx
andl $3,%ecx
subl %ecx,%eax
rep
movsb
movl %eax,%ecx
andl $3,%eax
shrl $2,%ecx
rep
movsl
.LStrPas2:
movl %eax,%ecx
rep
movsb
end ['ECX','EAX','ESI','EDI'];
leal 3(%esi),%edx
movl $1,%ecx
andl $-4,%edx
// skip length byte
incl %edi
subl %esi,%edx
jz .LStrPasAligned
// align source to multiple of 4 (not dest, because we can't read past
// the end of the source, since that may be past the end of the heap
// -> sigsegv!!)
.LStrPasAlignLoop:
movb (%esi),%al
incl %esi
testb %al,%al
jz .LStrPasDone
incl %edi
incb %cl
decb %dl
movb %al,-1(%edi)
jne .LStrPasAlignLoop
.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;
@ -1164,8 +1197,8 @@ procedure inclocked(var l : longint);assembler;
{
$Log$
Revision 1.6 2001-03-03 12:41:22 jonas
* simplified and optimized range checking code, FPC_BOUNDCHECK is no longer necessary
Revision 1.7 2001-03-04 17:31:34 jonas
* fixed all implementations of strpas
Revision 1.5 2000/11/12 23:23:34 florian
* interfaces basically running

View File

@ -61,13 +61,13 @@ asm
// 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
jz .LStrPasDone
jc .LStrPasDone
incl %ecx
shrl $8,%eax
jz .LStrPasDone
jc .LStrPasDone
incl %ecx
shrl $8,%eax
jz .LStrPasDone
jc .LStrPasDone
incl %ecx
jmp .LStrPasDone
.LStrPasPreEndLoop:
@ -106,7 +106,10 @@ end ['EDI','EAX','ECX'];
{
$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
Revision 1.3 2001/02/10 16:08:46 jonas