* new fixed and faster strpas (previous version only returned the first

254 chars when the pchar was aligned on a 4 byte boundary and was >=
    255 chars)
This commit is contained in:
Jonas Maebe 2000-06-12 08:33:26 +00:00
parent 9cf6b9f89d
commit 93f4c7a312

View File

@ -18,43 +18,76 @@
function strpas(p : pchar) : string; function strpas(p : pchar) : string;
begin begin
{$ifndef NEWATT} {$ifndef NEWATT}
strpas:=''; strpasopt:='';
{$endif} {$endif}
asm asm
cld
movl p,%edi
movl $0xff,%ecx
xorl %eax,%eax
movl %edi,%esi
repne
scasb
movl %ecx,%eax
{$ifdef NEWATT} {$ifdef NEWATT}
movl __RESULT,%edi movl __RESULT,%edi
{$else} {$else}
movl 8(%ebp),%edi movl 8(%ebp),%edi
{$endif} {$endif}
notb %al movl p,%esi
decl %eax // at the end, add 255 to cl to get the string length (byte(1+255) = 0)
stosb movb $1,%cl
cmpl $7,%eax // skip length byte -> align dest to multiple of 4
jl .LStrPas2 movl (%esi),%eax
movl %edi,%ecx // Align on 32bits testl $0x0ff,%eax
negl %ecx jz .LStrPasDone
andl $3,%ecx // we only need the first 3 chars currently
subl %ecx,%eax shll $8,%eax
rep incb %cl
movsb addl $3,%esi
movl %eax,%ecx // Store everything already, since the temp string = 255 chars anyway
andl $3,%eax // The length byte will contain zero this way, but it will be
shrl $2,%ecx // overwritten at the end, so it doesn't matter
rep movl %eax,(%edi)
movsl // test the second char (we shifted left 8 bits)
.LStrPas2: testl $0x0ff0000,%eax
movl %eax,%ecx jz .LStrPasDone
rep // for pairing, add 4 to edi here already
movsb addl $4,%edi
end ['ECX','EAX','ESI','EDI']; incb %cl
// test the third char (we shifted left 8 bits)
testl $0x0ff000000,%eax
jz .LStrPasDone
incb %cl
.align 16
.LStrPasLoop:
movl (%esi),%eax
addl $4,%esi
// this won't overwrite data since the result = 255 char string
movl %eax,(%edi)
testl $0x0ff,%eax
jz .LStrPasDone
testl $0x0ff00,%eax
jz .LStrPasByte
testl $0x0ff0000,%eax
jz .LStrPasWord
testl $0x0ff000000,%eax
jz .LStrPas3Bytes
addl $4,%edi
addb $4,%cl
// since cl = 4 at the start of the loop, it will always count
// upto exactly 0
jnz .LStrPasLoop
jmp .LStrPasDone
.LStrPas3Bytes:
addb $3,%cl
jmp .LStrPasDone
.LStrPasWord:
addb $2,%cl
jmp .LStrPasDone
.LStrPasByte:
incb %cl
.LStrPasDone:
{$ifdef NEWATT}
movl __RESULT,%edi
{$else}
movl 8(%ebp),%edi
{$endif}
addb $255,%cl
movb %cl,(%edi)
end ['EAX','ECX','ESI','EDI'];
end; end;
@ -76,7 +109,12 @@ end ['EDI','EAX','ECX'];
{ {
$Log$ $Log$
Revision 1.10 2000-03-28 11:14:33 jonas Revision 1.11 2000-06-12 08:33:26 jonas
* new fixed and faster strpas (previous version only returned the first
254 chars when the pchar was aligned on a 4 byte boundary and was >=
255 chars)
Revision 1.10 2000/03/28 11:14:33 jonas
* added missing register that is destroyed by strecopy * added missing register that is destroyed by strecopy
+ some destroyed register lists for procedures that didn't have one yet + some destroyed register lists for procedures that didn't have one yet