123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- {
- 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.
- **********************************************************************}
- var
- saveres,saveebx,saveesi,saveedi : longint;
- asm
- movl %ebx,saveebx
- movl %esi,saveesi
- movl %edi,saveedi
- {$ifdef regcall}
- movl p,%esi
- movl __RESULT,%edi
- movl %edi,saveres
- {$else}
- movl p,%esi
- {$endif}
- movl $1,%ecx
- testl %esi,%esi
- movl %esi,%eax
- jz .LStrPasDone
- {$ifndef REGCALL}
- movl __RESULT,%edi
- {$endif}
- 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:
- {$ifdef REGCALL}
- movl saveres,%edi
- {$else}
- movl __RESULT,%edi
- {$endif}
- addb $255,%cl
- movb %cl,(%edi)
- movl saveesi,%esi
- movl saveedi,%edi
- movl saveebx,%ebx
- end;
|