strpas.inc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team
  5. Processor specific implementation of strpas
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. var
  13. saveres,saveebx,saveesi,saveedi : longint;
  14. asm
  15. movl %ebx,saveebx
  16. movl %esi,saveesi
  17. movl %edi,saveedi
  18. {$ifdef regcall}
  19. movl p,%esi
  20. movl __RESULT,%edi
  21. movl %edi,saveres
  22. {$else}
  23. movl p,%esi
  24. {$endif}
  25. movl $1,%ecx
  26. testl %esi,%esi
  27. movl %esi,%eax
  28. jz .LStrPasDone
  29. {$ifndef REGCALL}
  30. movl __RESULT,%edi
  31. {$endif}
  32. leal 3(%esi),%edx
  33. andl $-4,%edx
  34. // skip length byte
  35. incl %edi
  36. subl %esi,%edx
  37. jz .LStrPasAligned
  38. // align source to multiple of 4 (not dest, because we can't read past
  39. // the end of the source, since that may be past the end of the heap
  40. // -> sigsegv!!)
  41. .LStrPasAlignLoop:
  42. movb (%esi),%al
  43. incl %esi
  44. testb %al,%al
  45. jz .LStrPasDone
  46. incl %edi
  47. incb %cl
  48. decb %dl
  49. movb %al,-1(%edi)
  50. jne .LStrPasAlignLoop
  51. .balign 16
  52. .LStrPasAligned:
  53. movl (%esi),%ebx
  54. addl $4,%edi
  55. leal 0x0fefefeff(%ebx),%eax
  56. movl %ebx,%edx
  57. addl $4,%esi
  58. notl %edx
  59. andl %edx,%eax
  60. addl $4,%ecx
  61. andl $0x080808080,%eax
  62. movl %ebx,-4(%edi)
  63. jnz .LStrPasEndFound
  64. cmpl $252,%ecx
  65. ja .LStrPasPreEndLoop
  66. jmp .LStrPasAligned
  67. .LStrPasEndFound:
  68. subl $4,%ecx
  69. // this won't overwrite data since the result = 255 char string
  70. // and we never process more than the first 255 chars of p
  71. shrl $8,%eax
  72. jc .LStrPasDone
  73. incl %ecx
  74. shrl $8,%eax
  75. jc .LStrPasDone
  76. incl %ecx
  77. shrl $8,%eax
  78. jc .LStrPasDone
  79. incl %ecx
  80. jmp .LStrPasDone
  81. .LStrPasPreEndLoop:
  82. testb %cl,%cl
  83. jz .LStrPasDone
  84. movl (%esi),%eax
  85. .LStrPasEndLoop:
  86. testb %al,%al
  87. jz .LStrPasDone
  88. movb %al,(%edi)
  89. shrl $8,%eax
  90. incl %edi
  91. incb %cl
  92. jnz .LStrPasEndLoop
  93. .LStrPasDone:
  94. {$ifdef REGCALL}
  95. movl saveres,%edi
  96. {$else}
  97. movl __RESULT,%edi
  98. {$endif}
  99. addb $255,%cl
  100. movb %cl,(%edi)
  101. movl saveesi,%esi
  102. movl saveedi,%edi
  103. movl saveebx,%ebx
  104. end;
  105. {
  106. $Log$
  107. Revision 1.5 2003-11-23 16:50:49 peter
  108. * register calling updates
  109. Revision 1.4 2003/11/19 16:58:44 peter
  110. * make strpas assembler function
  111. Revision 1.3 2003/11/11 21:08:17 peter
  112. * REGCALL define added
  113. Revision 1.2 2002/09/07 16:01:19 peter
  114. * old logs removed and tabs fixed
  115. }