strings.inc 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  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 dependent part of strings.pp, that can be shared with
  6. sysutils unit.
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. {$ASMMODE ATT}
  14. function strcopy(dest,source : pchar) : pchar;assembler;
  15. asm
  16. movl source,%edi
  17. testl %edi,%edi
  18. jz .LStrCopyDone
  19. movl %edi,%ecx
  20. andl $0x0fffffff8,%edi
  21. movl source,%esi
  22. subl %edi,%ecx
  23. movl dest,%edi
  24. jz .LStrCopyAligned
  25. .LStrCopyAlignLoop:
  26. movb (%esi),%al
  27. incl %edi
  28. incl %esi
  29. testb %al,%al
  30. movb %al,-1(%edi)
  31. jz .LStrCopyDone
  32. decl %ecx
  33. jnz .LStrCopyAlignLoop
  34. .balign 16
  35. .LStrCopyAligned:
  36. movl (%esi),%eax
  37. addl $4,%esi
  38. testl $0x0ff,%eax
  39. jz .LStrCopyByte
  40. testl $0x0ff00,%eax
  41. jz .LStrCopyWord
  42. testl $0x0ff0000,%eax
  43. jz .LStrCopy3Bytes
  44. movl %eax,(%edi)
  45. testl $0x0ff000000,%eax
  46. jz .LStrCopyDone
  47. addl $4,%edi
  48. jmp .LStrCopyAligned
  49. .LStrCopy3Bytes:
  50. movw %ax,(%edi)
  51. xorl %eax,%eax
  52. addl $2,%edi
  53. jmp .LStrCopyByte
  54. .LStrCopyWord:
  55. movw %ax,(%edi)
  56. jmp .LStrCopyDone
  57. .LStrCopyByte:
  58. movb %al,(%edi)
  59. .LStrCopyDone:
  60. movl dest,%eax
  61. end ['EAX','ECX','ESI','EDI'];
  62. function strecopy(dest,source : pchar) : pchar;assembler;
  63. asm
  64. cld
  65. movl source,%edi
  66. movl $0xffffffff,%ecx
  67. xorl %eax,%eax
  68. repne
  69. scasb
  70. not %ecx
  71. movl dest,%edi
  72. movl source,%esi
  73. movl %ecx,%eax
  74. shrl $2,%ecx
  75. rep
  76. movsl
  77. movl %eax,%ecx
  78. andl $3,%ecx
  79. rep
  80. movsb
  81. movl dest,%eax
  82. decl %edi
  83. movl %edi,%eax
  84. end ['EAX','ECX','ESI','EDI'];
  85. function strlcopy(dest,source : pchar;maxlen : longint) : pchar;assembler;
  86. asm
  87. movl source,%esi
  88. movl maxlen,%ecx
  89. movl dest,%edi
  90. orl %ecx,%ecx
  91. jz .LSTRLCOPY2
  92. cld
  93. .LSTRLCOPY1:
  94. lodsb
  95. stosb
  96. decl %ecx // Lower maximum
  97. jz .LSTRLCOPY2 // 0 reached ends
  98. orb %al,%al
  99. jnz .LSTRLCOPY1
  100. jmp .LSTRLCOPY3
  101. .LSTRLCOPY2:
  102. xorb %al,%al // If cutted
  103. stosb // add a #0
  104. .LSTRLCOPY3:
  105. movl dest,%eax
  106. end ['EAX','ECX','ESI','EDI'];
  107. function strlen(p : pchar) : longint;assembler;
  108. asm
  109. cld
  110. xorl %eax,%eax
  111. movl p,%edi
  112. orl %edi,%edi
  113. jz .LNil
  114. movl $0xffffffff,%ecx
  115. repne
  116. scasb
  117. movl $0xfffffffe,%eax
  118. subl %ecx,%eax
  119. .LNil:
  120. end ['EDI','ECX','EAX'];
  121. function strend(p : pchar) : pchar;assembler;
  122. asm
  123. cld
  124. xorl %eax,%eax
  125. movl p,%edi
  126. orl %edi,%edi
  127. jz .LStrEndNil
  128. movl $0xffffffff,%ecx
  129. xorl %eax,%eax
  130. repne
  131. scasb
  132. movl %edi,%eax
  133. decl %eax
  134. .LStrEndNil:
  135. end ['EDI','ECX','EAX'];
  136. function strcomp(str1,str2 : pchar) : longint;assembler;
  137. asm
  138. movl str2,%edi
  139. movl $0xffffffff,%ecx
  140. cld
  141. xorl %eax,%eax
  142. repne
  143. scasb
  144. not %ecx
  145. movl str2,%edi
  146. movl str1,%esi
  147. repe
  148. cmpsb
  149. movb -1(%esi),%al
  150. movzbl -1(%edi),%ecx
  151. subl %ecx,%eax
  152. end ['EAX','ECX','ESI','EDI'];
  153. function strlcomp(str1,str2 : pchar;l : longint) : longint;assembler;
  154. asm
  155. movl str2,%edi
  156. movl $0xffffffff,%ecx
  157. cld
  158. xorl %eax,%eax
  159. repne
  160. scasb
  161. not %ecx
  162. cmpl l,%ecx
  163. jl .LSTRLCOMP1
  164. movl l,%ecx
  165. .LSTRLCOMP1:
  166. movl str2,%edi
  167. movl str1,%esi
  168. repe
  169. cmpsb
  170. movb -1(%esi),%al
  171. movzbl -1(%edi),%ecx
  172. subl %ecx,%eax
  173. end ['EAX','ECX','ESI','EDI'];
  174. function stricomp(str1,str2 : pchar) : longint;assembler;
  175. asm
  176. movl str2,%edi
  177. movl $0xffffffff,%ecx
  178. cld
  179. xorl %eax,%eax
  180. repne
  181. scasb
  182. not %ecx
  183. movl str2,%edi
  184. movl str1,%esi
  185. .LSTRICOMP2:
  186. repe
  187. cmpsb
  188. jz .LSTRICOMP3 // If last reached then exit
  189. movzbl -1(%esi),%eax
  190. movzbl -1(%edi),%ebx
  191. cmpb $97,%al
  192. jb .LSTRICOMP1
  193. cmpb $122,%al
  194. ja .LSTRICOMP1
  195. subb $0x20,%al
  196. .LSTRICOMP1:
  197. cmpb $97,%bl
  198. jb .LSTRICOMP4
  199. cmpb $122,%bl
  200. ja .LSTRICOMP4
  201. subb $0x20,%bl
  202. .LSTRICOMP4:
  203. subl %ebx,%eax
  204. jz .LSTRICOMP2 // If still equal, compare again
  205. .LSTRICOMP3:
  206. end ['EAX','ECX','ESI','EDI'];
  207. function strlicomp(str1,str2 : pchar;l : longint) : longint;assembler;
  208. asm
  209. movl str2,%edi
  210. movl $0xffffffff,%ecx
  211. cld
  212. xorl %eax,%eax
  213. repne
  214. scasb
  215. not %ecx
  216. cmpl l,%ecx
  217. jl .LSTRLICOMP5
  218. movl l,%ecx
  219. .LSTRLICOMP5:
  220. movl str2,%edi
  221. movl str1,%esi
  222. .LSTRLICOMP2:
  223. repe
  224. cmpsb
  225. jz .LSTRLICOMP3 // If last reached, exit
  226. movzbl -1(%esi),%eax
  227. movzbl -1(%edi),%ebx
  228. cmpb $97,%al
  229. jb .LSTRLICOMP1
  230. cmpb $122,%al
  231. ja .LSTRLICOMP1
  232. subb $0x20,%al
  233. .LSTRLICOMP1:
  234. cmpb $97,%bl
  235. jb .LSTRLICOMP4
  236. cmpb $122,%bl
  237. ja .LSTRLICOMP4
  238. subb $0x20,%bl
  239. .LSTRLICOMP4:
  240. subl %ebx,%eax
  241. jz .LSTRLICOMP2
  242. .LSTRLICOMP3:
  243. end ['EAX','ECX','ESI','EDI'];
  244. function strscan(p : pchar;c : char) : pchar;assembler;
  245. asm
  246. movl p,%eax
  247. xorl %ecx,%ecx
  248. testl %eax,%eax
  249. jz .LSTRSCAN
  250. // align
  251. movb c,%cl
  252. movl %eax,%esi
  253. andl $0xfffffff8,%eax
  254. movl $0xff,%edx
  255. movl p,%edi
  256. subl %eax,%esi
  257. jz .LSTRSCANLOOP
  258. xorl %eax,%eax
  259. .LSTRSCANALIGNLOOP:
  260. movb (%edi),%al
  261. // at .LSTRSCANFOUND, one is substracted from edi to calculate the position,
  262. // so add 1 here already (not after .LSTRSCAN, because then the test/jz and
  263. // cmp/je can't be paired)
  264. incl %edi
  265. testb %al,%al
  266. jz .LSTRSCAN
  267. cmpb %cl,%al
  268. je .LSTRSCANFOUND
  269. decl %esi
  270. jnz .LSTRSCANALIGNLOOP
  271. jmp .LSTRSCANLOOP
  272. .balign 16
  273. .LSTRSCANLOOP:
  274. movl (%edi),%eax
  275. movl %eax,%esi
  276. // first char
  277. andl %edx,%eax
  278. // end of string -> stop
  279. jz .LSTRSCAN
  280. shrl $8,%esi
  281. cmpl %ecx,%eax
  282. movl %esi,%eax
  283. je .LSTRSCANFOUND1
  284. // second char
  285. andl %edx,%eax
  286. jz .LSTRSCAN
  287. shrl $8,%esi
  288. cmpl %ecx,%eax
  289. movl %esi,%eax
  290. je .LSTRSCANFOUND2
  291. // third char
  292. andl %edx,%eax
  293. jz .LSTRSCAN
  294. shrl $8,%esi
  295. cmpl %ecx,%eax
  296. movl %esi,%eax
  297. je .LSTRSCANFOUND3
  298. // fourth char
  299. // all upper bits have already been cleared
  300. testl %eax,%eax
  301. jz .LSTRSCAN
  302. addl $4,%edi
  303. cmpl %ecx,%eax
  304. je .LSTRSCANFOUND
  305. jmp .LSTRSCANLOOP
  306. .LSTRSCANFOUND3:
  307. leal 2(%edi),%eax
  308. jmp .LSTRSCAN
  309. .LSTRSCANFOUND2:
  310. leal 1(%edi),%eax
  311. jmp .LSTRSCAN
  312. .LSTRSCANFOUND1:
  313. movl %edi,%eax
  314. jmp .LSTRSCAN
  315. .LSTRSCANFOUND:
  316. leal -1(%edi),%eax
  317. .LSTRSCAN:
  318. end ['EAX','ECX','ESI','EDI','EDX'];
  319. function strrscan(p : pchar;c : char) : pchar;assembler;
  320. asm
  321. xorl %eax,%eax
  322. movl p,%edi
  323. orl %edi,%edi
  324. jz .LSTRRSCAN
  325. movl $0xffffffff,%ecx
  326. cld
  327. xorb %al,%al
  328. repne
  329. scasb
  330. not %ecx
  331. movb c,%al
  332. movl p,%edi
  333. addl %ecx,%edi
  334. decl %edi
  335. std
  336. repne
  337. scasb
  338. cld
  339. movl $0,%eax
  340. jnz .LSTRRSCAN
  341. movl %edi,%eax
  342. incl %eax
  343. .LSTRRSCAN:
  344. end ['EAX','ECX','EDI'];
  345. function strupper(p : pchar) : pchar;assembler;
  346. asm
  347. movl p,%esi
  348. orl %esi,%esi
  349. jz .LStrUpperNil
  350. movl %esi,%edi
  351. .LSTRUPPER1:
  352. lodsb
  353. cmpb $97,%al
  354. jb .LSTRUPPER3
  355. cmpb $122,%al
  356. ja .LSTRUPPER3
  357. subb $0x20,%al
  358. .LSTRUPPER3:
  359. stosb
  360. orb %al,%al
  361. jnz .LSTRUPPER1
  362. .LStrUpperNil:
  363. movl p,%eax
  364. end ['EAX','ESI','EDI'];
  365. function strlower(p : pchar) : pchar;assembler;
  366. asm
  367. movl p,%esi
  368. orl %esi,%esi
  369. jz .LStrLowerNil
  370. movl %esi,%edi
  371. .LSTRLOWER1:
  372. lodsb
  373. cmpb $65,%al
  374. jb .LSTRLOWER3
  375. cmpb $90,%al
  376. ja .LSTRLOWER3
  377. addb $0x20,%al
  378. .LSTRLOWER3:
  379. stosb
  380. orb %al,%al
  381. jnz .LSTRLOWER1
  382. .LStrLowerNil:
  383. movl p,%eax
  384. end ['EAX','ESI','EDI'];
  385. {
  386. $Log$
  387. Revision 1.2 2000-07-13 11:33:42 michael
  388. + removed logs
  389. }