set.inc 7.4 KB

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