set.inc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1998-2000 by the Free Pascal development team
  5. Include file with set operations called by the compiler
  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. procedure do_load_small(p : pointer;l:longint);assembler;[public,alias:'FPC_SET_LOAD_SMALL'];
  13. {
  14. load a normal set p from a smallset l
  15. }
  16. asm
  17. movl p,%edi
  18. movl l,%eax
  19. movl %eax,(%edi)
  20. addl $4,%edi
  21. movl $7,%ecx
  22. xorl %eax,%eax
  23. rep
  24. stosl
  25. end;
  26. procedure do_create_element(p : pointer;b : byte);assembler;[public,alias:'FPC_SET_CREATE_ELEMENT'];
  27. {
  28. create a new set in p from an element b
  29. }
  30. asm
  31. pushl %eax
  32. pushl %ecx
  33. movl p,%edi
  34. xorl %eax,%eax
  35. movl $8,%ecx
  36. rep
  37. stosl
  38. movb b,%al
  39. movl p,%edi
  40. movl %eax,%ecx
  41. shrl $3,%eax
  42. andl $7,%ecx
  43. addl %eax,%edi
  44. btsl %ecx,(%edi)
  45. popl %ecx
  46. popl %eax
  47. end;
  48. procedure do_set_byte(p : pointer;b : byte);assembler;[public,alias:'FPC_SET_SET_BYTE'];
  49. {
  50. add the element b to the set pointed by p
  51. }
  52. asm
  53. pushl %eax
  54. movl p,%edi
  55. movb b,%al
  56. andl $0xf8,%eax
  57. shrl $3,%eax
  58. addl %eax,%edi
  59. movb b,%al
  60. andl $7,%eax
  61. btsl %eax,(%edi)
  62. popl %eax
  63. end;
  64. procedure do_unset_byte(p : pointer;b : byte);assembler;[public,alias:'FPC_SET_UNSET_BYTE'];
  65. {
  66. suppresses the element b to the set pointed by p
  67. used for exclude(set,element)
  68. }
  69. asm
  70. pushl %eax
  71. movl p,%edi
  72. movb b,%al
  73. andl $0xf8,%eax
  74. shrl $3,%eax
  75. addl %eax,%edi
  76. movb b,%al
  77. andl $7,%eax
  78. btrl %eax,(%edi)
  79. popl %eax
  80. end;
  81. procedure do_set_range(p : pointer;l,h : byte);assembler;[public,alias:'FPC_SET_SET_RANGE'];
  82. {
  83. bad implementation, but it's very seldom used
  84. }
  85. asm
  86. pushl %eax
  87. movl p,%edi
  88. xorl %eax,%eax
  89. xorl %ecx,%ecx
  90. movb h,%al
  91. movb l,%cl
  92. .LSET_SET_RANGE_LOOP:
  93. cmpl %ecx,%eax
  94. jl .LSET_SET_RANGE_EXIT
  95. movl %eax,%ebx
  96. movl %eax,%edx
  97. andl $0xf8,%ebx
  98. andl $7,%edx
  99. shrl $3,%ebx
  100. btsl %edx,(%edi,%ebx)
  101. dec %eax
  102. jmp .LSET_SET_RANGE_LOOP
  103. .LSET_SET_RANGE_EXIT:
  104. popl %eax
  105. end;
  106. procedure do_in_byte(p : pointer;b : byte);assembler;[public,alias:'FPC_SET_IN_BYTE'];
  107. {
  108. tests if the element b is in the set p the carryflag is set if it present
  109. }
  110. asm
  111. pushl %eax
  112. movl p,%edi
  113. movb b,%al
  114. andl $0xf8,%eax
  115. shrl $3,%eax
  116. addl %eax,%edi
  117. movb b,%al
  118. andl $7,%eax
  119. btl %eax,(%edi)
  120. popl %eax
  121. end;
  122. procedure do_add_sets(set1,set2,dest : pointer);assembler;[public,alias:'FPC_SET_ADD_SETS'];
  123. {
  124. adds set1 and set2 into set dest
  125. }
  126. asm
  127. movl set1,%esi
  128. movl set2,%ebx
  129. movl dest,%edi
  130. movl $8,%ecx
  131. .LMADDSETS1:
  132. lodsl
  133. orl (%ebx),%eax
  134. stosl
  135. addl $4,%ebx
  136. decl %ecx
  137. jnz .LMADDSETS1
  138. end;
  139. procedure do_mul_sets(set1,set2,dest:pointer);assembler;[public,alias:'FPC_SET_MUL_SETS'];
  140. {
  141. multiplies (takes common elements of) set1 and set2 result put in dest
  142. }
  143. asm
  144. movl set1,%esi
  145. movl set2,%ebx
  146. movl dest,%edi
  147. movl $8,%ecx
  148. .LMMULSETS1:
  149. lodsl
  150. andl (%ebx),%eax
  151. stosl
  152. addl $4,%ebx
  153. decl %ecx
  154. jnz .LMMULSETS1
  155. end;
  156. procedure do_sub_sets(set1,set2,dest:pointer);assembler;[public,alias:'FPC_SET_SUB_SETS'];
  157. {
  158. computes the diff from set1 to set2 result in dest
  159. }
  160. asm
  161. movl set1,%esi
  162. movl set2,%ebx
  163. movl dest,%edi
  164. movl $8,%ecx
  165. .LMSUBSETS1:
  166. lodsl
  167. movl (%ebx),%edx
  168. notl %edx
  169. andl %edx,%eax
  170. stosl
  171. addl $4,%ebx
  172. decl %ecx
  173. jnz .LMSUBSETS1
  174. end;
  175. procedure do_symdif_sets(set1,set2,dest:pointer);assembler;[public,alias:'FPC_SET_SYMDIF_SETS'];
  176. {
  177. computes the symetric diff from set1 to set2 result in dest
  178. }
  179. asm
  180. movl set1,%esi
  181. movl set2,%ebx
  182. movl dest,%edi
  183. movl $8,%ecx
  184. .LMSYMDIFSETS1:
  185. lodsl
  186. movl (%ebx),%edx
  187. xorl %edx,%eax
  188. stosl
  189. addl $4,%ebx
  190. decl %ecx
  191. jnz .LMSYMDIFSETS1
  192. end;
  193. procedure do_comp_sets(set1,set2 : pointer);assembler;[public,alias:'FPC_SET_COMP_SETS'];
  194. {
  195. compares set1 and set2 zeroflag is set if they are equal
  196. }
  197. asm
  198. movl set1,%esi
  199. movl set2,%edi
  200. movl $8,%ecx
  201. .LMCOMPSETS1:
  202. movl (%esi),%eax
  203. movl (%edi),%edx
  204. cmpl %edx,%eax
  205. jne .LMCOMPSETEND
  206. addl $4,%esi
  207. addl $4,%edi
  208. decl %ecx
  209. jnz .LMCOMPSETS1
  210. { we are here only if the two sets are equal
  211. we have zero flag set, and that what is expected }
  212. .LMCOMPSETEND:
  213. end;
  214. {$IfNDef NoSetInclusion}
  215. procedure do_contains_sets(set1,set2 : pointer);assembler;[public,alias:'FPC_SET_CONTAINS_SETS'];
  216. {
  217. on exit, zero flag is set if set1 <= set2 (set2 contains set1)
  218. }
  219. asm
  220. movl set1,%esi
  221. movl set2,%edi
  222. movl $8,%ecx
  223. .LMCONTAINSSETS1:
  224. movl (%esi),%eax
  225. movl (%edi),%edx
  226. andl %eax,%edx
  227. cmpl %edx,%eax {set1 and set2 = set1?}
  228. jne .LMCONTAINSSETEND
  229. addl $4,%esi
  230. addl $4,%edi
  231. decl %ecx
  232. jnz .LMCONTAINSSETS1
  233. { we are here only if set2 contains set1
  234. we have zero flag set, and that what is expected }
  235. .LMCONTAINSSETEND:
  236. end;
  237. {$EndIf SetInclusion}
  238. {$ifdef LARGESETS}
  239. procedure do_set(p : pointer;b : word);assembler;[public,alias:'FPC_SET_SET_WORD'];
  240. {
  241. sets the element b in set p works for sets larger than 256 elements
  242. not yet use by the compiler so
  243. }
  244. asm
  245. pushl %eax
  246. movl p,%edi
  247. movw b,%ax
  248. andl $0xfff8,%eax
  249. shrl $3,%eax
  250. addl %eax,%edi
  251. movb 12(%ebp),%al
  252. andl $7,%eax
  253. btsl %eax,(%edi)
  254. popl %eax
  255. end;
  256. procedure do_in(p : pointer;b : word);assembler;[public,alias:'FPC_SET_IN_WORD'];
  257. {
  258. tests if the element b is in the set p the carryflag is set if it present
  259. works for sets larger than 256 elements
  260. }
  261. asm
  262. pushl %eax
  263. movl p,%edi
  264. movw b,%ax
  265. andl $0xfff8,%eax
  266. shrl $3,%eax
  267. addl %eax,%edi
  268. movb 12(%ebp),%al
  269. andl $7,%eax
  270. btl %eax,(%edi)
  271. popl %eax
  272. end;
  273. procedure add_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_SET_ADD_SETS_SIZE'];
  274. {
  275. adds set1 and set2 into set dest size is the number of bytes in the set
  276. }
  277. asm
  278. movl set1,%esi
  279. movl set2,%ebx
  280. movl dest,%edi
  281. movl size,%ecx
  282. .LMADDSETSIZES1:
  283. lodsl
  284. orl (%ebx),%eax
  285. stosl
  286. addl $4,%ebx
  287. decl %ecx
  288. jnz .LMADDSETSIZES1
  289. end;
  290. procedure mul_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_SET_MUL_SETS_SIZE'];
  291. {
  292. multiplies (i.E. takes common elements of) set1 and set2 result put in
  293. dest size is the number of bytes in the set
  294. }
  295. asm
  296. movl set1,%esi
  297. movl set2,%ebx
  298. movl dest,%edi
  299. movl size,%ecx
  300. .LMMULSETSIZES1:
  301. lodsl
  302. andl (%ebx),%eax
  303. stosl
  304. addl $4,%ebx
  305. decl %ecx
  306. jnz .LMMULSETSIZES1
  307. end;
  308. procedure sub_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_SET_SUB_SETS_SIZE'];
  309. asm
  310. movl set1,%esi
  311. movl set2,%ebx
  312. movl dest,%edi
  313. movl size,%ecx
  314. .LMSUBSETSIZES1:
  315. lodsl
  316. movl (%ebx),%edx
  317. notl %edx
  318. andl %edx,%eax
  319. stosl
  320. addl $4,%ebx
  321. decl %ecx
  322. jnz .LMSUBSETSIZES1
  323. end;
  324. procedure sym_sub_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_SET_SYMDIF_SETS_SIZE'];
  325. {
  326. computes the symetric diff from set1 to set2 result in dest
  327. }
  328. asm
  329. movl set1,%esi
  330. movl set2,%ebx
  331. movl dest,%edi
  332. movl size,%ecx
  333. .LMSYMDIFSETSIZE1:
  334. lodsl
  335. movl (%ebx),%edx
  336. xorl %edx,%eax
  337. stosl
  338. addl $4,%ebx
  339. decl %ecx
  340. jnz .LMSYMDIFSETSIZE1
  341. end;
  342. procedure comp_sets(set1,set2 : pointer;size : longint);assembler;[public,alias:'FPC_SET_COMP_SETS_SIZE'];
  343. asm
  344. movl set1,%esi
  345. movl set2,%edi
  346. movl size,%ecx
  347. .LMCOMPSETSIZES1:
  348. lodsl
  349. movl (%edi),%edx
  350. cmpl %edx,%eax
  351. jne .LMCOMPSETSIZEEND
  352. addl $4,%edi
  353. decl %ecx
  354. jnz .LMCOMPSETSIZES1
  355. { we are here only if the two sets are equal
  356. we have zero flag set, and that what is expected }
  357. .LMCOMPSETSIZEEND:
  358. end;
  359. {$IfNDef NoSetInclusion}
  360. procedure contains_sets(set1,set2 : pointer; size: longint);assembler;[public,alias:'FPC_SET_CONTAINS_SETS'];
  361. {
  362. on exit, zero flag is set if set1 <= set2 (set2 contains set1)
  363. }
  364. asm
  365. movl set1,%esi
  366. movl set2,%edi
  367. movl size,%ecx
  368. .LMCONTAINSSETS2:
  369. movl (%esi),%eax
  370. movl (%edi),%edx
  371. andl %eax,%edx
  372. cmpl %edx,%eax {set1 and set2 = set1?}
  373. jne .LMCONTAINSSETEND2
  374. addl $4,%esi
  375. addl $4,%edi
  376. decl %ecx
  377. jnz .LMCONTAINSSETS2
  378. { we are here only if set2 contains set1
  379. we have zero flag set, and that what is expected }
  380. .LMCONTAINSSETEND2:
  381. end;
  382. {$EndIf NoSetInclusion}
  383. {$endif LARGESET}
  384. {
  385. $Log$
  386. Revision 1.11 2000-01-07 16:32:24 daniel
  387. * copyright 2000 added
  388. Revision 1.10 1999/03/01 15:40:59 peter
  389. * use external names
  390. * removed all direct assembler modes
  391. Revision 1.9 1999/01/20 17:48:02 jonas
  392. + fixed bug0163 (set1 <= set2 support)
  393. Revision 1.8 1998/12/15 22:43:00 peter
  394. * removed temp symbols
  395. Revision 1.7 1998/11/24 12:54:01 peter
  396. + FPC_SET_CREATE_ELEMENT
  397. Revision 1.6 1998/10/22 14:50:08 pierre
  398. + added FPC_SET_UNSET_BYTE for exclude of normsets
  399. Revision 1.5 1998/10/22 12:48:29 peter
  400. * fixed for stackaligment also on 4 bytes, never use 'ret $..' direct
  401. Revision 1.4 1998/09/14 10:48:12 peter
  402. * FPC_ names
  403. * Heap manager is now system independent
  404. Revision 1.3 1998/08/14 18:13:44 peter
  405. + set_load_small
  406. * fixed set_set_range
  407. Revision 1.2 1998/05/31 14:15:51 peter
  408. * force to use ATT or direct parsing
  409. }