mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-04 13:47:23 +01:00
* moved implementations of strlen and strpas to separate include files
(they were duplicated in i386.inc and strings.inc/stringss.inc)
* strpas supports 'nil' pchars again (returns an empty string)
(both merged)
This commit is contained in:
parent
18de59f50c
commit
ab2ea0a472
@ -846,79 +846,11 @@ end;
|
||||
|
||||
{$define FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
|
||||
function strpas(p:pchar):shortstring;[public,alias:'FPC_PCHAR_TO_SHORTSTR'];
|
||||
begin
|
||||
asm
|
||||
movl p,%esi
|
||||
movl __RESULT,%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;
|
||||
{$include strpas.inc}
|
||||
|
||||
{$define FPC_SYSTEM_HAS_STRLEN}
|
||||
function strlen(p:pchar):longint;assembler;
|
||||
{$include strlen.inc}
|
||||
|
||||
{$define FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
|
||||
function strchararray(p:pchar; l : longint):shortstring;[public,alias:'FPC_CHARARRAY_TO_SHORTSTR'];
|
||||
@ -955,24 +887,6 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
{$define FPC_SYSTEM_HAS_STRLEN}
|
||||
function strlen(p:pchar):longint;assembler;
|
||||
asm
|
||||
movl p,%edi
|
||||
movl $0xffffffff,%ecx
|
||||
xorl %eax,%eax
|
||||
cld
|
||||
repne
|
||||
scasb
|
||||
movl $0xfffffffe,%eax
|
||||
subl %ecx,%eax
|
||||
end ['EDI','ECX','EAX'];
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
Caller/StackFrame Helpers
|
||||
****************************************************************************}
|
||||
|
||||
{$define FPC_SYSTEM_HAS_GET_FRAME}
|
||||
function get_frame:longint;assembler;
|
||||
asm
|
||||
@ -1197,7 +1111,13 @@ procedure inclocked(var l : longint);assembler;
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.7 2001-03-04 17:31:34 jonas
|
||||
Revision 1.8 2001-03-05 17:10:04 jonas
|
||||
* moved implementations of strlen and strpas to separate include files
|
||||
(they were duplicated in i386.inc and strings.inc/stringss.inc)
|
||||
* strpas supports 'nil' pchars again (returns an empty string)
|
||||
(both merged)
|
||||
|
||||
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
|
||||
|
||||
@ -124,19 +124,7 @@ end ['EAX','ECX','ESI','EDI'];
|
||||
|
||||
|
||||
function strlen(p : pchar) : longint;assembler;
|
||||
asm
|
||||
cld
|
||||
xorl %eax,%eax
|
||||
movl p,%edi
|
||||
orl %edi,%edi
|
||||
jz .LNil
|
||||
movl $0xffffffff,%ecx
|
||||
repne
|
||||
scasb
|
||||
movl $0xfffffffe,%eax
|
||||
subl %ecx,%eax
|
||||
.LNil:
|
||||
end ['EDI','ECX','EAX'];
|
||||
{$i strlen.inc}
|
||||
|
||||
|
||||
function strend(p : pchar) : pchar;assembler;
|
||||
@ -463,7 +451,13 @@ end ['EAX','ESI','EDI'];
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.5 2001-02-17 11:34:00 jonas
|
||||
Revision 1.6 2001-03-05 17:10:04 jonas
|
||||
* moved implementations of strlen and strpas to separate include files
|
||||
(they were duplicated in i386.inc and strings.inc/stringss.inc)
|
||||
* strpas supports 'nil' pchars again (returns an empty string)
|
||||
(both merged)
|
||||
|
||||
Revision 1.5 2001/02/17 11:34:00 jonas
|
||||
* fixed bug in strscan (returned nil instead of strend for #0) and made it 40% faster
|
||||
|
||||
Revision 1.4 2001/02/10 16:08:46 jonas
|
||||
|
||||
@ -16,78 +16,7 @@
|
||||
**********************************************************************}
|
||||
|
||||
function strpas(p : pchar) : string;
|
||||
begin
|
||||
asm
|
||||
movl p,%esi
|
||||
movl __RESULT,%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;
|
||||
{$i strpas.inc}
|
||||
|
||||
function strpcopy(d : pchar;const s : string) : pchar;assembler;
|
||||
asm
|
||||
@ -106,7 +35,13 @@ end ['EDI','EAX','ECX'];
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.5 2001-03-04 17:31:35 jonas
|
||||
Revision 1.6 2001-03-05 17:10:04 jonas
|
||||
* moved implementations of strlen and strpas to separate include files
|
||||
(they were duplicated in i386.inc and strings.inc/stringss.inc)
|
||||
* strpas supports 'nil' pchars again (returns an empty string)
|
||||
(both merged)
|
||||
|
||||
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
|
||||
|
||||
42
rtl/i386/strlen.inc
Normal file
42
rtl/i386/strlen.inc
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
$Id$
|
||||
This file is part of the Free Pascal run time library.
|
||||
Copyright (c) 1999-2000 by the Free Pascal development team
|
||||
|
||||
Processor specific implementation of strlen
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
asm
|
||||
movl p,%edi
|
||||
movl $0xffffffff,%ecx
|
||||
xorl %eax,%eax
|
||||
cld
|
||||
repne
|
||||
scasb
|
||||
movl $0xfffffffe,%eax
|
||||
subl %ecx,%eax
|
||||
end ['EDI','ECX','EAX'];
|
||||
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.2 2001-03-05 17:10:04 jonas
|
||||
* moved implementations of strlen and strpas to separate include files
|
||||
(they were duplicated in i386.inc and strings.inc/stringss.inc)
|
||||
* strpas supports 'nil' pchars again (returns an empty string)
|
||||
(both merged)
|
||||
|
||||
Revision 1.1.2.1 2001/03/05 16:56:01 jonas
|
||||
* moved implementations of strlen and strpas to separate include files
|
||||
(they were duplicated in i386.inc and strings.inc/stringss.inc)
|
||||
* strpas supports 'nil' pchars again (returns an empty string)
|
||||
|
||||
}
|
||||
101
rtl/i386/strpas.inc
Normal file
101
rtl/i386/strpas.inc
Normal file
@ -0,0 +1,101 @@
|
||||
{
|
||||
$Id$
|
||||
This file is part of the Free Pascal run time library.
|
||||
Copyright (c) 1999-2000 by the Free Pascal development team
|
||||
|
||||
Processor specific implementation of strpas
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************}
|
||||
begin
|
||||
asm
|
||||
movl p,%esi
|
||||
movl $1,%ecx
|
||||
testl %esi,%esi
|
||||
movl %esi,%eax
|
||||
jz .LStrPasDone
|
||||
movl __RESULT,%edi
|
||||
leal 3(%esi),%edx
|
||||
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;
|
||||
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.1 2001-03-05 17:10:04 jonas
|
||||
* moved implementations of strlen and strpas to separate include files
|
||||
(they were duplicated in i386.inc and strings.inc/stringss.inc)
|
||||
* strpas supports 'nil' pchars again (returns an empty string)
|
||||
(both merged)
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user