set.inc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  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. 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. {$define FPC_SYSTEM_HAS_FPC_SET_LOAD_SMALL}
  13. function fpc_set_load_small(l: fpc_small_set): fpc_normal_set;assembler;[public,alias:'FPC_SET_LOAD_SMALL']; {$ifdef hascompilerproc} compilerproc; {$endif}
  14. {
  15. load a normal set p from a smallset l
  16. }
  17. asm
  18. movl __RESULT,%edi
  19. movl l,%eax
  20. stosl
  21. xorl %eax,%eax
  22. movl $7,%ecx
  23. rep
  24. stosl
  25. end ['EAX','ECX','EDI'];
  26. {$define FPC_SYSTEM_HAS_FPC_SET_CREATE_ELEMENT}
  27. function fpc_set_create_element(b : byte): fpc_normal_set;assembler;[public,alias:'FPC_SET_CREATE_ELEMENT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  28. {
  29. create a new set in p from an element b
  30. }
  31. asm
  32. {$ifndef hascompilerproc}
  33. pushl %eax
  34. pushl %ecx
  35. {$endif not hascompilerproc}
  36. movl __RESULT,%edi
  37. xorl %eax,%eax
  38. movl $8,%ecx
  39. rep
  40. stosl
  41. leal -32(%edi),%eax
  42. movzbl b,%edi
  43. btsl %edi,(%eax)
  44. {$ifndef hascompilerproc}
  45. popl %ecx
  46. popl %eax
  47. {$endif hascompilerproc}
  48. end ['EAX','ECX','EDI'];
  49. {$define FPC_SYSTEM_HAS_FPC_SET_SET_BYTE}
  50. {$ifdef hascompilerproc}
  51. function fpc_set_set_byte(const source: fpc_normal_set; b : byte): fpc_normal_set;assembler; compilerproc;
  52. {
  53. add the element b to the set pointed by source
  54. }
  55. asm
  56. movl $8,%ecx
  57. movl source,%esi
  58. movl __RESULT,%edi
  59. rep
  60. movsl
  61. leal -32(%edi),%eax
  62. movzbl b,%edi
  63. btsl %edi,(%eax)
  64. end ['EAX','ECX','ESI','EDI'];
  65. {$else hascompilerproc}
  66. function fpc_set_set_byte(b : byte): fpc_normal_set;assembler;[public,alias:'FPC_SET_SET_BYTE'];
  67. {
  68. add the element b to the set pointed by p
  69. }
  70. asm
  71. pushl %eax
  72. movl __RESULT,%edi
  73. movb b,%al
  74. andl $0xf8,%eax
  75. shrl $3,%eax
  76. addl %eax,%edi
  77. movb b,%al
  78. andl $7,%eax
  79. btsl %eax,(%edi)
  80. popl %eax
  81. end;
  82. {$endif hascompilerproc}
  83. {$define FPC_SYSTEM_HAS_FPC_SET_UNSET_BYTE}
  84. {$ifdef hascompilerproc}
  85. function fpc_set_unset_byte(const source: fpc_normal_set; b : byte): fpc_normal_set;assembler; compilerproc;
  86. {
  87. add the element b to the set pointed by source
  88. }
  89. asm
  90. movl $8,%ecx
  91. movl source,%esi
  92. movl __RESULT,%edi
  93. rep
  94. movsl
  95. leal -32(%edi),%eax
  96. movzbl b,%edi
  97. btrl %edi,(%eax)
  98. end ['EAX','ECX','ESI','EDI'];
  99. {$else hascompilerproc}
  100. function fpc_set_unset_byte(b : byte): fpc_normal_set;assembler;[public,alias:'FPC_SET_UNSET_BYTE']; {$ifdef hascompilerproc} compilerproc; {$endif}
  101. {
  102. suppresses the element b to the set pointed by p
  103. used for exclude(set,element)
  104. }
  105. asm
  106. pushl %eax
  107. movl __RESULT,%edi
  108. movb b,%al
  109. andl $0xf8,%eax
  110. shrl $3,%eax
  111. addl %eax,%edi
  112. movb b,%al
  113. andl $7,%eax
  114. btrl %eax,(%edi)
  115. popl %eax
  116. end;
  117. {$endif hascompilerproc}
  118. {$define FPC_SYSTEM_HAS_FPC_SET_SET_RANGE}
  119. {$ifdef hascompilerproc}
  120. function fpc_set_set_range(const orgset: fpc_normal_set; l,h : byte): fpc_normal_set;assembler; compilerproc;
  121. {
  122. adds the range [l..h] to the set pointed to by p
  123. }
  124. asm
  125. movzbl l,%eax // lowest bit to be set in eax
  126. movzbl h,%ebx // highest in ebx
  127. movl $8,%ecx // we have to copy 32 bytes
  128. movl __RESULT,%edi // target set address in edi
  129. movl orgset, %esi // source set address in esi
  130. cmpl %eax,%ebx // high < low?
  131. rep // copy source to dest (it's possible to do the range
  132. movsl // setting and copying simultanuously of course, but
  133. // that would result in many more jumps and code)
  134. movl %eax,%ecx // lowest also in ecx
  135. jb .Lset_range_done // if high > low, then dest := source
  136. shrl $3,%eax // divide by 8 to get starting and ending byte
  137. shrl $3,%ebx // address
  138. andb $31,%cl // low five bits of lo determine start of bit mask
  139. andl $0x0fffffffc,%eax // clear two lowest bits to get start/end longint
  140. subl $32,%edi // get back to start of dest
  141. andl $0x0fffffffc,%ebx // address * 4
  142. movl $0x0ffffffff,%edx // edx = bitmask to be inserted
  143. shll %cl,%edx // shift bitmask to clear bits below lo
  144. addl %eax,%edi // go to starting pos in set
  145. subl %eax,%ebx // are bit lo and hi in the same longint?
  146. jz .Lset_range_hi // yes, keep current mask and adjust for hi bit
  147. orl %edx,(%edi) // no, store current mask
  148. movl $0x0ffffffff,%edx // new mask
  149. addl $4,%edi // next longint of set
  150. subl $4,%ebx // bit hi in this longint?
  151. jz .Lset_range_hi // yes, keep full mask and adjust for hi bit
  152. .Lset_range_loop:
  153. movl %edx,(%edi) // no, fill longints in between with full mask
  154. addl $4,%edi
  155. subl $4,%ebx
  156. jnz .Lset_range_loop
  157. .Lset_range_hi:
  158. movb h,%cl
  159. movl %edx,%ebx // save current bitmask
  160. andb $31,%cl
  161. subb $31,%cl // cl := (31 - (hi and 31)) = shift count to
  162. negb %cl // adjust bitmask for hi bit
  163. shrl %cl,%edx // shift bitmask to clear bits higher than hi
  164. andl %edx,%ebx // combine both bitmasks
  165. orl %ebx,(%edi) // store to set
  166. .Lset_range_done:
  167. end;
  168. {$else hascompilerproc}
  169. function fpc_set_set_range(l,h : byte): fpc_normal_set;assembler;[public,alias:'FPC_SET_SET_RANGE'];
  170. {
  171. adds the range [l..h] to the set pointed to by p
  172. }
  173. asm
  174. movzbl l,%eax // lowest bit to be set in eax
  175. movzbl h,%ebx // highest in ebx
  176. cmpl %eax,%ebx
  177. jb .Lset_range_done
  178. movl __RESULT,%edi // set address in edi
  179. movl %eax,%ecx // lowest also in ecx
  180. shrl $3,%eax // divide by 8 to get starting and ending byte
  181. shrl $3,%ebx // address
  182. andb $31,%cl // low five bits of lo determine start of bit mask
  183. movl $0x0ffffffff,%edx // edx = bitmask to be inserted
  184. andl $0x0fffffffc,%eax // clear two lowest bits to get start/end longint
  185. andl $0x0fffffffc,%ebx // address * 4
  186. shll %cl,%edx // shift bitmask to clear bits below lo
  187. addl %eax,%edi // go to starting pos in set
  188. subl %eax,%ebx // are bit lo and hi in the same longint?
  189. jz .Lset_range_hi // yes, keep current mask and adjust for hi bit
  190. orl %edx,(%edi) // no, store current mask
  191. movl $0x0ffffffff,%edx // new mask
  192. addl $4,%edi // next longint of set
  193. subl $4,%ebx // bit hi in this longint?
  194. jz .Lset_range_hi // yes, keep full mask and adjust for hi bit
  195. .Lset_range_loop:
  196. movl %edx,(%edi) // no, fill longints in between with full mask
  197. addl $4,%edi
  198. subl $4,%ebx
  199. jnz .Lset_range_loop
  200. .Lset_range_hi:
  201. movb h,%cl
  202. movl %edx,%ebx // save current bitmask
  203. andb $31,%cl
  204. subb $31,%cl // cl := (31 - (hi and 31)) = shift count to
  205. negb %cl // adjust bitmask for hi bit
  206. shrl %cl,%edx // shift bitmask to clear bits higher than hi
  207. andl %edx,%ebx // combine both bitmasks
  208. orl %ebx,(%edi) // store to set
  209. .Lset_range_done:
  210. end;
  211. {$endif hascompilerproc}
  212. {$define FPC_SYSTEM_HAS_FPC_SET_IN_BYTE}
  213. {$ifdef hascompilerproc}
  214. { it's inlined in the code generator }
  215. function fpc_set_in_byte(const p: fpc_normal_set; b: byte): boolean; compilerproc;
  216. begin
  217. { make sure we won't accidentally call it }
  218. runerror(216);
  219. end;
  220. {$endif hascompilerproc}
  221. function fpc_set_in_byte_i386(p: pointer; b : byte): boolean;assembler;[public,alias:'FPC_SET_IN_BYTE'];
  222. {
  223. tests if the element b is in the set p the carryflag is set if it present
  224. }
  225. asm
  226. { it's inlined in the code generator }
  227. {$ifndef hascompilerproc}
  228. pushl %eax
  229. movl p,%edi
  230. movzbl b,%eax
  231. btl %eax,(%edi)
  232. popl %eax
  233. {$endif not hascompilerproc}
  234. end;
  235. {$define FPC_SYSTEM_HAS_FPC_SET_ADD_SETS}
  236. {$ifdef hascompilerproc}
  237. function fpc_set_add_sets(const set1,set2: fpc_normal_set): fpc_normal_set;assembler;[public,alias:'FPC_SET_ADD_SETS']; compilerproc;
  238. {$else hascompilerproc}
  239. procedure fpc_set_add_sets(set1,set2,dest : pointer);assembler;[public,alias:'FPC_SET_ADD_SETS'];
  240. {$endif hascompilerproc}
  241. {
  242. adds set1 and set2 into set dest
  243. }
  244. asm
  245. movl set1,%esi
  246. movl set2,%ebx
  247. {$ifdef hascompilerproc}
  248. movl __RESULT,%edi
  249. {$else hascompilerproc}
  250. movl dest,%edi
  251. {$endif hascompilerproc}
  252. movl $8,%ecx
  253. .LMADDSETS1:
  254. lodsl
  255. orl (%ebx),%eax
  256. stosl
  257. addl $4,%ebx
  258. decl %ecx
  259. jnz .LMADDSETS1
  260. end;
  261. {$define FPC_SYSTEM_HAS_FPC_SET_MUL_SETS}
  262. {$ifdef hascompilerproc}
  263. function fpc_set_mul_sets(const set1,set2: fpc_normal_set): fpc_normal_set;assembler;[public,alias:'FPC_SET_MUL_SETS']; compilerproc;
  264. {$else hascompilerproc}
  265. procedure fpc_set_mul_sets(set1,set2,dest:pointer);assembler;[public,alias:'FPC_SET_MUL_SETS'];
  266. {$endif hascompilerproc}
  267. {
  268. multiplies (takes common elements of) set1 and set2 result put in dest
  269. }
  270. asm
  271. movl set1,%esi
  272. movl set2,%ebx
  273. {$ifdef hascompilerproc}
  274. movl __RESULT,%edi
  275. {$else hascompilerproc}
  276. movl dest,%edi
  277. {$endif hascompilerproc}
  278. movl $8,%ecx
  279. .LMMULSETS1:
  280. lodsl
  281. andl (%ebx),%eax
  282. stosl
  283. addl $4,%ebx
  284. decl %ecx
  285. jnz .LMMULSETS1
  286. end;
  287. {$define FPC_SYSTEM_HAS_FPC_SET_SUB_SETS}
  288. {$ifdef hascompilerproc}
  289. function fpc_set_sub_sets(const set1,set2: fpc_normal_set): fpc_normal_set;assembler;[public,alias:'FPC_SET_SUB_SETS']; compilerproc;
  290. {$else hascompilerproc}
  291. procedure fpc_set_sub_sets(set1,set2,dest:pointer);assembler;[public,alias:'FPC_SET_SUB_SETS'];
  292. {$endif hascompilerproc}
  293. {
  294. computes the diff from set1 to set2 result in dest
  295. }
  296. asm
  297. movl set1,%esi
  298. movl set2,%ebx
  299. {$ifdef hascompilerproc}
  300. movl __RESULT,%edi
  301. {$else hascompilerproc}
  302. movl dest,%edi
  303. {$endif hascompilerproc}
  304. movl $8,%ecx
  305. .LMSUBSETS1:
  306. lodsl
  307. movl (%ebx),%edx
  308. notl %edx
  309. andl %edx,%eax
  310. stosl
  311. addl $4,%ebx
  312. decl %ecx
  313. jnz .LMSUBSETS1
  314. end;
  315. {$define FPC_SYSTEM_HAS_FPC_SET_SYMDIF_SETS}
  316. {$ifdef hascompilerproc}
  317. function fpc_set_symdif_sets(const set1,set2: fpc_normal_set): fpc_normal_set;assembler;[public,alias:'FPC_SET_SYMDIF_SETS']; compilerproc;
  318. {$else hascompilerproc}
  319. procedure fpc_set_symdif_sets(set1,set2,dest:pointer);assembler;[public,alias:'FPC_SET_SYMDIF_SETS'];
  320. {$endif hascompilerproc}
  321. {
  322. computes the symetric diff from set1 to set2 result in dest
  323. }
  324. asm
  325. movl set1,%esi
  326. movl set2,%ebx
  327. {$ifdef hascompilerproc}
  328. movl __RESULT,%edi
  329. {$else hascompilerproc}
  330. movl dest,%edi
  331. {$endif hascompilerproc}
  332. movl $8,%ecx
  333. .LMSYMDIFSETS1:
  334. lodsl
  335. movl (%ebx),%edx
  336. xorl %edx,%eax
  337. stosl
  338. addl $4,%ebx
  339. decl %ecx
  340. jnz .LMSYMDIFSETS1
  341. end;
  342. {$define FPC_SYSTEM_HAS_FPC_SET_COMP_SETS}
  343. function fpc_set_comp_sets(const set1,set2: fpc_normal_set): boolean;assembler;[public,alias:'FPC_SET_COMP_SETS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  344. {
  345. compares set1 and set2 zeroflag is set if they are equal
  346. }
  347. asm
  348. movl set1,%esi
  349. movl set2,%edi
  350. movl $8,%ecx
  351. .LMCOMPSETS1:
  352. movl (%esi),%eax
  353. movl (%edi),%edx
  354. cmpl %edx,%eax
  355. jne .LMCOMPSETEND
  356. addl $4,%esi
  357. addl $4,%edi
  358. decl %ecx
  359. jnz .LMCOMPSETS1
  360. { we are here only if the two sets are equal
  361. we have zero flag set, and that what is expected }
  362. .LMCOMPSETEND:
  363. {$ifdef hascompilerproc}
  364. seteb %al
  365. {$endif hascompilerproc}
  366. end;
  367. {$define FPC_SYSTEM_HAS_FPC_SET_CONTAINS_SET}
  368. function fpc_set_contains_sets(const set1,set2: fpc_normal_set): boolean;assembler;[public,alias:'FPC_SET_CONTAINS_SETS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  369. {
  370. on exit, zero flag is set if set1 <= set2 (set2 contains set1)
  371. }
  372. asm
  373. movl set1,%esi
  374. movl set2,%edi
  375. movl $8,%ecx
  376. .LMCONTAINSSETS1:
  377. movl (%esi),%eax
  378. movl (%edi),%edx
  379. andl %eax,%edx
  380. cmpl %edx,%eax {set1 and set2 = set1?}
  381. jne .LMCONTAINSSETEND
  382. addl $4,%esi
  383. addl $4,%edi
  384. decl %ecx
  385. jnz .LMCONTAINSSETS1
  386. { we are here only if set2 contains set1
  387. we have zero flag set, and that what is expected }
  388. .LMCONTAINSSETEND:
  389. {$ifdef hascompilerproc}
  390. seteb %al
  391. {$endif hascompilerproc}
  392. end;
  393. {$ifdef LARGESETS}
  394. procedure fpc_largeset_set_word(p : pointer;b : word);assembler;[public,alias:'FPC_LARGESET_SET_WORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  395. {
  396. sets the element b in set p works for sets larger than 256 elements
  397. not yet use by the compiler so
  398. }
  399. asm
  400. pushl %eax
  401. movl p,%edi
  402. movw b,%ax
  403. andl $0xfff8,%eax
  404. shrl $3,%eax
  405. addl %eax,%edi
  406. movb 12(%ebp),%al
  407. andl $7,%eax
  408. btsl %eax,(%edi)
  409. popl %eax
  410. end;
  411. procedure fpc_largeset_in_word(p : pointer;b : word);assembler;[public,alias:'FPC_LARGESET_IN_WORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  412. {
  413. tests if the element b is in the set p the carryflag is set if it present
  414. works for sets larger than 256 elements
  415. }
  416. asm
  417. pushl %eax
  418. movl p,%edi
  419. movw b,%ax
  420. andl $0xfff8,%eax
  421. shrl $3,%eax
  422. addl %eax,%edi
  423. movb 12(%ebp),%al
  424. andl $7,%eax
  425. btl %eax,(%edi)
  426. popl %eax
  427. end;
  428. procedure fpc_largeset_add_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_LARGESET_ADD_SETS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  429. {
  430. adds set1 and set2 into set dest size is the number of bytes in the set
  431. }
  432. asm
  433. movl set1,%esi
  434. movl set2,%ebx
  435. movl dest,%edi
  436. movl size,%ecx
  437. .LMADDSETSIZES1:
  438. lodsl
  439. orl (%ebx),%eax
  440. stosl
  441. addl $4,%ebx
  442. decl %ecx
  443. jnz .LMADDSETSIZES1
  444. end;
  445. procedure fpc_largeset_mul_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_LARGESET_MUL_SETS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  446. {
  447. multiplies (i.E. takes common elements of) set1 and set2 result put in
  448. dest size is the number of bytes in the set
  449. }
  450. asm
  451. movl set1,%esi
  452. movl set2,%ebx
  453. movl dest,%edi
  454. movl size,%ecx
  455. .LMMULSETSIZES1:
  456. lodsl
  457. andl (%ebx),%eax
  458. stosl
  459. addl $4,%ebx
  460. decl %ecx
  461. jnz .LMMULSETSIZES1
  462. end;
  463. procedure fpc_largeset_sub_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_LARGESET_SUB_SETS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  464. asm
  465. movl set1,%esi
  466. movl set2,%ebx
  467. movl dest,%edi
  468. movl size,%ecx
  469. .LMSUBSETSIZES1:
  470. lodsl
  471. movl (%ebx),%edx
  472. notl %edx
  473. andl %edx,%eax
  474. stosl
  475. addl $4,%ebx
  476. decl %ecx
  477. jnz .LMSUBSETSIZES1
  478. end;
  479. procedure fpc_largeset_symdif_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_LARGESET_SYMDIF_SETS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  480. {
  481. computes the symetric diff from set1 to set2 result in dest
  482. }
  483. asm
  484. movl set1,%esi
  485. movl set2,%ebx
  486. movl dest,%edi
  487. movl size,%ecx
  488. .LMSYMDIFSETSIZE1:
  489. lodsl
  490. movl (%ebx),%edx
  491. xorl %edx,%eax
  492. stosl
  493. addl $4,%ebx
  494. decl %ecx
  495. jnz .LMSYMDIFSETSIZE1
  496. end;
  497. procedure fpc_largeset_comp_sets(set1,set2 : pointer;size : longint);assembler;[public,alias:'FPC_LARGESET_COMP_SETS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  498. asm
  499. movl set1,%esi
  500. movl set2,%edi
  501. movl size,%ecx
  502. .LMCOMPSETSIZES1:
  503. lodsl
  504. movl (%edi),%edx
  505. cmpl %edx,%eax
  506. jne .LMCOMPSETSIZEEND
  507. addl $4,%edi
  508. decl %ecx
  509. jnz .LMCOMPSETSIZES1
  510. { we are here only if the two sets are equal
  511. we have zero flag set, and that what is expected }
  512. .LMCOMPSETSIZEEND:
  513. end;
  514. procedure fpc_largeset_contains_sets(set1,set2 : pointer; size: longint);assembler;[public,alias:'FPC_LARGESET_CONTAINS_SETS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  515. {
  516. on exit, zero flag is set if set1 <= set2 (set2 contains set1)
  517. }
  518. asm
  519. movl set1,%esi
  520. movl set2,%edi
  521. movl size,%ecx
  522. .LMCONTAINSSETS2:
  523. movl (%esi),%eax
  524. movl (%edi),%edx
  525. andl %eax,%edx
  526. cmpl %edx,%eax {set1 and set2 = set1?}
  527. jne .LMCONTAINSSETEND2
  528. addl $4,%esi
  529. addl $4,%edi
  530. decl %ecx
  531. jnz .LMCONTAINSSETS2
  532. { we are here only if set2 contains set1
  533. we have zero flag set, and that what is expected }
  534. .LMCONTAINSSETEND2:
  535. end;
  536. {$endif LARGESET}
  537. {
  538. $Log$
  539. Revision 1.9 2002-09-07 16:01:19 peter
  540. * old logs removed and tabs fixed
  541. Revision 1.8 2002/03/29 20:15:44 peter
  542. * fixed load_smallset
  543. }