mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 01:49:20 +02:00
* fixed all implementations of strpas
This commit is contained in:
parent
8efd8814cf
commit
18de59f50c
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user