strpas.inc 2.9 KB

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