set.inc 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  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. 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. { include file with procedures used for set operations }
  12. { these procedures should never be called directly }
  13. { the compiler calls them }
  14. { add the element b to the set pointed by p }
  15. procedure do_set(p : pointer;b : byte);
  16. [public,alias: 'SET_SET_BYTE'];
  17. begin
  18. asm
  19. pushl %eax
  20. movl p,%edi
  21. movb b,%al
  22. andl $0xf8,%eax
  23. shrl $3,%eax
  24. addl %eax,%edi
  25. movb b,%al
  26. andl $7,%eax
  27. btsl %eax,(%edi)
  28. popl %eax
  29. { own exit, the compiler generates a ret $8, IMHO }
  30. leave
  31. ret $6
  32. end;
  33. end;
  34. { bad implementation, but it's very seldom used }
  35. procedure do_set(p : pointer;l,h : byte);[public,alias: 'SET_SET_RANGE'];
  36. begin
  37. asm
  38. pushl %eax
  39. xorl %eax,%eax
  40. movb h,%al
  41. .LSET_SET_RANGE_LOOP:
  42. cmpb %al,l
  43. jb .LSET_SET_RANGE_EXIT
  44. pushw %ax
  45. pushl p
  46. call SET_SET_BYTE
  47. dec %al
  48. jmp .LSET_SET_RANGE_LOOP
  49. .LSET_SET_RANGE_EXIT:
  50. popl %eax
  51. end;
  52. end;
  53. { tests if the element b is in the set p }
  54. { the carryflag is set if it present }
  55. procedure do_in(p : pointer;b : byte);
  56. [public,alias: 'SET_IN_BYTE'];
  57. begin
  58. asm
  59. pushl %eax
  60. movl p,%edi
  61. movb b,%al
  62. andl $0xf8,%eax
  63. shrl $3,%eax
  64. addl %eax,%edi
  65. movb b,%al
  66. andl $7,%eax
  67. btl %eax,(%edi)
  68. popl %eax
  69. { own exit, the compiler generates a ret $8, IMHO }
  70. leave
  71. ret $6
  72. end;
  73. end;
  74. { adds set1 and set2 into set dest }
  75. procedure add_sets(set1,set2,dest : pointer);[public,alias: 'SET_ADD_SETS'];
  76. begin
  77. asm
  78. movl 8(%ebp),%esi
  79. movl 12(%ebp),%ebx
  80. movl 16(%ebp),%edi
  81. movl $8,%ecx
  82. .LMADDSETS1:
  83. lodsl
  84. orl (%ebx),%eax
  85. stosl
  86. addl $4,%ebx
  87. decl %ecx
  88. jnz .LMADDSETS1
  89. end;
  90. end;
  91. { multiplies (i.E. takes common elements of) set1 and set2 }
  92. { result put in dest }
  93. procedure mul_sets(set1,set2,dest : pointer);[public,alias: 'SET_MUL_SETS'];
  94. begin
  95. asm
  96. movl 8(%ebp),%esi
  97. movl 12(%ebp),%ebx
  98. movl 16(%ebp),%edi
  99. movl $8,%ecx
  100. .LMMULSETS1:
  101. lodsl
  102. andl (%ebx),%eax
  103. stosl
  104. addl $4,%ebx
  105. decl %ecx
  106. jnz .LMMULSETS1
  107. end;
  108. end;
  109. { computes the diff from set1 to set2 }
  110. { result in dest }
  111. procedure sub_sets(set1,set2,dest : pointer);[public,alias: 'SET_SUB_SETS'];
  112. begin
  113. asm
  114. movl 8(%ebp),%esi
  115. movl 12(%ebp),%ebx
  116. movl 16(%ebp),%edi
  117. movl $8,%ecx
  118. .LMSUBSETS1:
  119. lodsl
  120. movl (%ebx),%edx
  121. notl %edx
  122. andl %edx,%eax
  123. stosl
  124. addl $4,%ebx
  125. decl %ecx
  126. jnz .LMSUBSETS1
  127. end;
  128. end;
  129. { computes the symetric diff from set1 to set2 }
  130. { result in dest }
  131. procedure sym_sub_sets(set1,set2,dest : pointer);[public,alias: 'SET_SYMDIF_SETS'];
  132. begin
  133. asm
  134. movl 8(%ebp),%esi
  135. movl 12(%ebp),%ebx
  136. movl 16(%ebp),%edi
  137. movl $8,%ecx
  138. .LMSYMDIFSETS1:
  139. lodsl
  140. movl (%ebx),%edx
  141. xorl %edx,%eax
  142. stosl
  143. addl $4,%ebx
  144. decl %ecx
  145. jnz .LMSYMDIFSETS1
  146. end;
  147. end;
  148. { compares set1 and set2 }
  149. { zeroflag is set if they are equal }
  150. procedure comp_sets(set1,set2 : pointer);[public,alias: 'SET_COMP_SETS'];
  151. begin
  152. asm
  153. movl 8(%ebp),%esi
  154. movl 12(%ebp),%edi
  155. movl $8,%ecx
  156. .LMCOMPSETS1:
  157. lodsl
  158. movl (%edi),%edx
  159. cmpl %edx,%eax
  160. jne .LMCOMPSETEND
  161. addl $4,%edi
  162. decl %ecx
  163. jnz .LMCOMPSETS1
  164. // we are here only if the two sets are equal
  165. // we have zero flag set, and that what is expected
  166. cmpl %eax,%eax
  167. .LMCOMPSETEND:
  168. end;
  169. end;
  170. { sets the element b in set p }
  171. { works for sets larger than 256 elements }
  172. { not yet use by the compiler so }
  173. {$ifdef ver_above without the number }
  174. procedure do_set(p : pointer;b : word);[public,alias: 'SET_SET_WORD'];
  175. begin
  176. asm
  177. pushl %eax
  178. movl 8(%ebp),%edi
  179. movw 12(%ebp),%ax
  180. andl $0xfff8,%eax
  181. shrl $3,%eax
  182. addl %eax,%edi
  183. movb 12(%ebp),%al
  184. andl $7,%eax
  185. btsl %eax,(%edi)
  186. popl %eax
  187. end;
  188. end;
  189. { tests if the element b is in the set p }
  190. { the carryflag is set if it present }
  191. { works for sets larger than 256 elements }
  192. procedure do_in(p : pointer;b : word);[public,alias: 'SET_IN_WORD'];
  193. begin
  194. asm
  195. pushl %eax
  196. movl 8(%ebp),%edi
  197. movw 12(%ebp),%ax
  198. andl $0xfff8,%eax
  199. shrl $3,%eax
  200. addl %eax,%edi
  201. movb 12(%ebp),%al
  202. andl $7,%eax
  203. btl %eax,(%edi)
  204. popl %eax
  205. end;
  206. end;
  207. { adds set1 and set2 into set dest }
  208. { size is the number of bytes in the set }
  209. procedure add_sets(set1,set2,dest : pointer;size : longint);
  210. [public,alias: 'SET_ADD_SETS_SIZE'];
  211. begin
  212. asm
  213. movl 8(%ebp),%esi
  214. movl 12(%ebp),%ebx
  215. movl 16(%ebp),%edi
  216. movl 20(%ebp),%ecx
  217. .LMADDSETSIZES1:
  218. lodsl
  219. orl (%ebx),%eax
  220. stosl
  221. addl $4,%ebx
  222. decl %ecx
  223. jnz .LMADDSETSIZES1
  224. end;
  225. end;
  226. { multiplies (i.E. takes common elements of) set1 and set2 }
  227. { result put in dest }
  228. { size is the number of bytes in the set }
  229. procedure mul_sets(set1,set2,dest : pointer;size : longint);
  230. [public,alias: 'SET_MUL_SETS_SIZE'];
  231. begin
  232. asm
  233. movl 8(%ebp),%esi
  234. movl 12(%ebp),%ebx
  235. movl 16(%ebp),%edi
  236. movl 20(%ebp),%ecx
  237. .LMMULSETSIZES1:
  238. lodsl
  239. andl (%ebx),%eax
  240. stosl
  241. addl $4,%ebx
  242. decl %ecx
  243. jnz .LMMULSETSIZES1
  244. end;
  245. end;
  246. procedure sub_sets(set1,set2,dest : pointer;size : longint);[public,alias: 'SET_SUB_SETS_SIZE'];
  247. begin
  248. asm
  249. movl 8(%ebp),%esi
  250. movl 12(%ebp),%ebx
  251. movl 16(%ebp),%edi
  252. movl 20(%ebp),%ecx
  253. .LMSUBSETSIZES1:
  254. lodsl
  255. movl (%ebx),%edx
  256. notl %edx
  257. andl %edx,%eax
  258. stosl
  259. addl $4,%ebx
  260. decl %ecx
  261. jnz .LMSUBSETSIZES1
  262. end;
  263. end;
  264. { computes the symetric diff from set1 to set2 }
  265. { result in dest }
  266. procedure sym_sub_sets(set1,set2,dest : pointer;size : longint);[public,alias: 'SET_SYMDIF_SETS_SIZE'];
  267. begin
  268. asm
  269. movl 8(%ebp),%esi
  270. movl 12(%ebp),%ebx
  271. movl 16(%ebp),%edi
  272. movl 20(%ebp),%ecx
  273. .LMSYMDIFSETSIZE1:
  274. lodsl
  275. movl (%ebx),%edx
  276. xorl %edx,%eax
  277. stosl
  278. addl $4,%ebx
  279. decl %ecx
  280. jnz .LMSYMDIFSETSIZE1
  281. end;
  282. end;
  283. procedure comp_sets(set1,set2 : pointer;size : longint);[public,alias: 'SET_COMP_SETS_SIZE'];
  284. begin
  285. asm
  286. movl 8(%ebp),%esi
  287. movl 12(%ebp),%edi
  288. movl 16(%ebp),%ecx
  289. .LMCOMPSETSIZES1:
  290. lodsl
  291. movl (%edi),%edx
  292. cmpl %edx,%eax
  293. jne .LMCOMPSETSIZEEND
  294. addl $4,%edi
  295. decl %ecx
  296. jnz .LMCOMPSETSIZES1
  297. // we are here only if the two sets are equal
  298. // we have zero flag set, and that what is expected
  299. cmpl %eax,%eax
  300. .LMCOMPSETSIZEEND:
  301. end;
  302. end;
  303. {$endif ver_above without the number }
  304. {
  305. $Log$
  306. Revision 1.1 1998-03-25 11:18:42 root
  307. Initial revision
  308. Revision 1.7 1998/03/03 12:07:11 florian
  309. * undid the change of some procedures to plain assembler procedures
  310. Revision 1.6 1998/03/02 23:10:33 florian
  311. * SET_* are now assembler procedures
  312. Revision 1.5 1998/02/11 18:37:01 florian
  313. * stupid typing mistake fixed (I though it compiles, but the assembler
  314. wrote an error message)
  315. Revision 1.4 1998/02/11 16:17:45 florian
  316. + helper routine for "dynamic" set constructors with ranges added
  317. Revision 1.3 1998/01/26 11:59:09 michael
  318. + Added log at the end
  319. Working file: rtl/i386/set.inc
  320. description:
  321. ----------------------------
  322. revision 1.2
  323. date: 1997/12/01 12:34:37; author: michael; state: Exp; lines: +11 -4
  324. + added copyright reference in header.
  325. ----------------------------
  326. revision 1.1
  327. date: 1997/11/27 08:33:48; author: michael; state: Exp;
  328. Initial revision
  329. ----------------------------
  330. revision 1.1.1.1
  331. date: 1997/11/27 08:33:48; author: michael; state: Exp; lines: +0 -0
  332. FPC RTL CVS start
  333. =============================================================================
  334. }