|
@@ -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
|