set.inc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 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. {$ASMMODE ATT}
  13. procedure do_load_small(p : pointer;l:longint);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_LOAD_SMALL'];
  14. {
  15. load a set from an
  16. }
  17. begin
  18. asm
  19. movl p,%edi
  20. movl l,%eax
  21. movl %eax,(%edi)
  22. addl $4,%edi
  23. movl $7,%ecx
  24. xorl %eax,%eax
  25. rep
  26. stosl
  27. end;
  28. end;
  29. procedure do_set_byte(p : pointer;b : byte); [public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_SET_BYTE'];
  30. {
  31. add the element b to the set pointed by p
  32. }
  33. begin
  34. asm
  35. pushl %eax
  36. movl p,%edi
  37. movb b,%al
  38. andl $0xf8,%eax
  39. shrl $3,%eax
  40. addl %eax,%edi
  41. movb b,%al
  42. andl $7,%eax
  43. btsl %eax,(%edi)
  44. popl %eax
  45. { own exit, the compiler generates a ret $8, IMHO }
  46. leave
  47. ret $6
  48. end;
  49. end;
  50. procedure do_set_range(p : pointer;l,h : byte);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_SET_RANGE'];
  51. {
  52. bad implementation, but it's very seldom used
  53. }
  54. begin
  55. asm
  56. pushl %eax
  57. movl p,%edi
  58. xorl %eax,%eax
  59. xorl %ecx,%ecx
  60. movb h,%al
  61. movb l,%cl
  62. .LSET_SET_RANGE_LOOP:
  63. cmpl %ecx,%eax
  64. jl .LSET_SET_RANGE_EXIT
  65. movl %eax,%ebx
  66. movl %eax,%edx
  67. andl $0xf8,%ebx
  68. andl $7,%edx
  69. shrl $3,%ebx
  70. btsl %edx,(%edi,%ebx)
  71. dec %eax
  72. jmp .LSET_SET_RANGE_LOOP
  73. .LSET_SET_RANGE_EXIT:
  74. popl %eax
  75. end;
  76. end;
  77. procedure do_in_byte(p : pointer;b : byte);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_IN_BYTE'];
  78. {
  79. tests if the element b is in the set p the carryflag is set if it present
  80. }
  81. begin
  82. asm
  83. pushl %eax
  84. movl p,%edi
  85. movb b,%al
  86. andl $0xf8,%eax
  87. shrl $3,%eax
  88. addl %eax,%edi
  89. movb b,%al
  90. andl $7,%eax
  91. btl %eax,(%edi)
  92. popl %eax
  93. { own exit, the compiler generates a ret $8, IMHO }
  94. leave
  95. ret $6
  96. end;
  97. end;
  98. procedure do_add_sets(set1,set2,dest : pointer);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_ADD_SETS'];
  99. {
  100. adds set1 and set2 into set dest
  101. }
  102. begin
  103. asm
  104. movl 8(%ebp),%esi
  105. movl 12(%ebp),%ebx
  106. movl 16(%ebp),%edi
  107. movl $8,%ecx
  108. .LMADDSETS1:
  109. lodsl
  110. orl (%ebx),%eax
  111. stosl
  112. addl $4,%ebx
  113. decl %ecx
  114. jnz .LMADDSETS1
  115. end;
  116. end;
  117. { multiplies (i.E. takes common elements of) set1 and set2 }
  118. { result put in dest }
  119. procedure do_mul_sets(set1,set2,dest : pointer);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_MUL_SETS'];
  120. begin
  121. asm
  122. movl 8(%ebp),%esi
  123. movl 12(%ebp),%ebx
  124. movl 16(%ebp),%edi
  125. movl $8,%ecx
  126. .LMMULSETS1:
  127. lodsl
  128. andl (%ebx),%eax
  129. stosl
  130. addl $4,%ebx
  131. decl %ecx
  132. jnz .LMMULSETS1
  133. end;
  134. end;
  135. procedure do_sub_sets(set1,set2,dest : pointer);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_SUB_SETS'];
  136. {
  137. computes the diff from set1 to set2 result in dest
  138. }
  139. begin
  140. asm
  141. movl 8(%ebp),%esi
  142. movl 12(%ebp),%ebx
  143. movl 16(%ebp),%edi
  144. movl $8,%ecx
  145. .LMSUBSETS1:
  146. lodsl
  147. movl (%ebx),%edx
  148. notl %edx
  149. andl %edx,%eax
  150. stosl
  151. addl $4,%ebx
  152. decl %ecx
  153. jnz .LMSUBSETS1
  154. end;
  155. end;
  156. procedure do_symdif_sets(set1,set2,dest : pointer);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_SYMDIF_SETS'];
  157. {
  158. computes the symetric diff from set1 to set2 result in dest
  159. }
  160. begin
  161. asm
  162. movl 8(%ebp),%esi
  163. movl 12(%ebp),%ebx
  164. movl 16(%ebp),%edi
  165. movl $8,%ecx
  166. .LMSYMDIFSETS1:
  167. lodsl
  168. movl (%ebx),%edx
  169. xorl %edx,%eax
  170. stosl
  171. addl $4,%ebx
  172. decl %ecx
  173. jnz .LMSYMDIFSETS1
  174. end;
  175. end;
  176. procedure do_comp_sets(set1,set2 : pointer);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_COMP_SETS'];
  177. {
  178. compares set1 and set2 zeroflag is set if they are equal
  179. }
  180. begin
  181. asm
  182. movl 8(%ebp),%esi
  183. movl 12(%ebp),%edi
  184. movl $8,%ecx
  185. .LMCOMPSETS1:
  186. lodsl
  187. movl (%edi),%edx
  188. cmpl %edx,%eax
  189. jne .LMCOMPSETEND
  190. addl $4,%edi
  191. decl %ecx
  192. jnz .LMCOMPSETS1
  193. { we are here only if the two sets are equal
  194. we have zero flag set, and that what is expected }
  195. cmpl %eax,%eax
  196. .LMCOMPSETEND:
  197. end;
  198. end;
  199. {$ifdef LARGESETS}
  200. procedure do_set(p : pointer;b : word);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_SET_WORD'];
  201. {
  202. sets the element b in set p works for sets larger than 256 elements
  203. not yet use by the compiler so
  204. }
  205. begin
  206. asm
  207. pushl %eax
  208. movl 8(%ebp),%edi
  209. movw 12(%ebp),%ax
  210. andl $0xfff8,%eax
  211. shrl $3,%eax
  212. addl %eax,%edi
  213. movb 12(%ebp),%al
  214. andl $7,%eax
  215. btsl %eax,(%edi)
  216. popl %eax
  217. end;
  218. end;
  219. procedure do_in(p : pointer;b : word);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_IN_WORD'];
  220. {
  221. tests if the element b is in the set p the carryflag is set if it present
  222. works for sets larger than 256 elements
  223. }
  224. begin
  225. asm
  226. pushl %eax
  227. movl 8(%ebp),%edi
  228. movw 12(%ebp),%ax
  229. andl $0xfff8,%eax
  230. shrl $3,%eax
  231. addl %eax,%edi
  232. movb 12(%ebp),%al
  233. andl $7,%eax
  234. btl %eax,(%edi)
  235. popl %eax
  236. end;
  237. end;
  238. procedure add_sets(set1,set2,dest : pointer;size : longint);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_ADD_SETS_SIZE'];
  239. {
  240. adds set1 and set2 into set dest size is the number of bytes in the set
  241. }
  242. begin
  243. asm
  244. movl 8(%ebp),%esi
  245. movl 12(%ebp),%ebx
  246. movl 16(%ebp),%edi
  247. movl 20(%ebp),%ecx
  248. .LMADDSETSIZES1:
  249. lodsl
  250. orl (%ebx),%eax
  251. stosl
  252. addl $4,%ebx
  253. decl %ecx
  254. jnz .LMADDSETSIZES1
  255. end;
  256. end;
  257. procedure mul_sets(set1,set2,dest : pointer;size : longint);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_MUL_SETS_SIZE'];
  258. {
  259. multiplies (i.E. takes common elements of) set1 and set2 result put in
  260. dest size is the number of bytes in the set
  261. }
  262. begin
  263. asm
  264. movl 8(%ebp),%esi
  265. movl 12(%ebp),%ebx
  266. movl 16(%ebp),%edi
  267. movl 20(%ebp),%ecx
  268. .LMMULSETSIZES1:
  269. lodsl
  270. andl (%ebx),%eax
  271. stosl
  272. addl $4,%ebx
  273. decl %ecx
  274. jnz .LMMULSETSIZES1
  275. end;
  276. end;
  277. procedure sub_sets(set1,set2,dest : pointer;size : longint);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_SUB_SETS_SIZE'];
  278. begin
  279. asm
  280. movl 8(%ebp),%esi
  281. movl 12(%ebp),%ebx
  282. movl 16(%ebp),%edi
  283. movl 20(%ebp),%ecx
  284. .LMSUBSETSIZES1:
  285. lodsl
  286. movl (%ebx),%edx
  287. notl %edx
  288. andl %edx,%eax
  289. stosl
  290. addl $4,%ebx
  291. decl %ecx
  292. jnz .LMSUBSETSIZES1
  293. end;
  294. end;
  295. procedure sym_sub_sets(set1,set2,dest : pointer;size : longint);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_SYMDIF_SETS_SIZE'];
  296. {
  297. computes the symetric diff from set1 to set2 result in dest
  298. }
  299. begin
  300. asm
  301. movl 8(%ebp),%esi
  302. movl 12(%ebp),%ebx
  303. movl 16(%ebp),%edi
  304. movl 20(%ebp),%ecx
  305. .LMSYMDIFSETSIZE1:
  306. lodsl
  307. movl (%ebx),%edx
  308. xorl %edx,%eax
  309. stosl
  310. addl $4,%ebx
  311. decl %ecx
  312. jnz .LMSYMDIFSETSIZE1
  313. end;
  314. end;
  315. procedure comp_sets(set1,set2 : pointer;size : longint);[public,alias: {$ifdef FPCNAMES}'FPC_'+{$endif}'SET_COMP_SETS_SIZE'];
  316. begin
  317. asm
  318. movl 8(%ebp),%esi
  319. movl 12(%ebp),%edi
  320. movl 16(%ebp),%ecx
  321. .LMCOMPSETSIZES1:
  322. lodsl
  323. movl (%edi),%edx
  324. cmpl %edx,%eax
  325. jne .LMCOMPSETSIZEEND
  326. addl $4,%edi
  327. decl %ecx
  328. jnz .LMCOMPSETSIZES1
  329. { we are here only if the two sets are equal
  330. we have zero flag set, and that what is expected }
  331. cmpl %eax,%eax
  332. .LMCOMPSETSIZEEND:
  333. end;
  334. end;
  335. {$endif LARGESET}
  336. {
  337. $Log$
  338. Revision 1.4 1998-09-14 10:48:12 peter
  339. * FPC_ names
  340. * Heap manager is now system independent
  341. Revision 1.3 1998/08/14 18:13:44 peter
  342. + set_load_small
  343. * fixed set_set_range
  344. Revision 1.2 1998/05/31 14:15:51 peter
  345. * force to use ATT or direct parsing
  346. }