123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464 |
- {
- $Id$
- This file is part of the Free Pascal run time library.
- Copyright (c) 1998-2000 by the Free Pascal development team
- Include file with set operations called by the compiler
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- procedure do_load_small(p : pointer;l:longint);assembler;[public,alias:'FPC_SET_LOAD_SMALL'];
- {
- load a normal set p from a smallset l
- }
- asm
- movl p,%edi
- movl l,%eax
- movl %eax,(%edi)
- addl $4,%edi
- movl $7,%ecx
- xorl %eax,%eax
- rep
- stosl
- end;
- procedure do_create_element(p : pointer;b : byte);assembler;[public,alias:'FPC_SET_CREATE_ELEMENT'];
- {
- create a new set in p from an element b
- }
- asm
- pushl %eax
- pushl %ecx
- movl p,%edi
- xorl %eax,%eax
- movl $8,%ecx
- rep
- stosl
- movb b,%al
- movl p,%edi
- movl %eax,%ecx
- shrl $3,%eax
- andl $7,%ecx
- addl %eax,%edi
- btsl %ecx,(%edi)
- popl %ecx
- popl %eax
- end;
- procedure do_set_byte(p : pointer;b : byte);assembler;[public,alias:'FPC_SET_SET_BYTE'];
- {
- add the element b to the set pointed by p
- }
- asm
- pushl %eax
- movl p,%edi
- movb b,%al
- andl $0xf8,%eax
- shrl $3,%eax
- addl %eax,%edi
- movb b,%al
- andl $7,%eax
- btsl %eax,(%edi)
- popl %eax
- end;
- procedure do_unset_byte(p : pointer;b : byte);assembler;[public,alias:'FPC_SET_UNSET_BYTE'];
- {
- suppresses the element b to the set pointed by p
- used for exclude(set,element)
- }
- asm
- pushl %eax
- movl p,%edi
- movb b,%al
- andl $0xf8,%eax
- shrl $3,%eax
- addl %eax,%edi
- movb b,%al
- andl $7,%eax
- btrl %eax,(%edi)
- popl %eax
- end;
- procedure do_set_range(p : pointer;l,h : byte);assembler;[public,alias:'FPC_SET_SET_RANGE'];
- {
- bad implementation, but it's very seldom used
- }
- asm
- pushl %eax
- movl p,%edi
- xorl %eax,%eax
- xorl %ecx,%ecx
- movb h,%al
- movb l,%cl
- .LSET_SET_RANGE_LOOP:
- cmpl %ecx,%eax
- jl .LSET_SET_RANGE_EXIT
- movl %eax,%ebx
- movl %eax,%edx
- andl $0xf8,%ebx
- andl $7,%edx
- shrl $3,%ebx
- btsl %edx,(%edi,%ebx)
- dec %eax
- jmp .LSET_SET_RANGE_LOOP
- .LSET_SET_RANGE_EXIT:
- popl %eax
- end;
- procedure do_in_byte(p : pointer;b : byte);assembler;[public,alias:'FPC_SET_IN_BYTE'];
- {
- tests if the element b is in the set p the carryflag is set if it present
- }
- asm
- pushl %eax
- movl p,%edi
- movb b,%al
- andl $0xf8,%eax
- shrl $3,%eax
- addl %eax,%edi
- movb b,%al
- andl $7,%eax
- btl %eax,(%edi)
- popl %eax
- end;
- procedure do_add_sets(set1,set2,dest : pointer);assembler;[public,alias:'FPC_SET_ADD_SETS'];
- {
- adds set1 and set2 into set dest
- }
- asm
- movl set1,%esi
- movl set2,%ebx
- movl dest,%edi
- movl $8,%ecx
- .LMADDSETS1:
- lodsl
- orl (%ebx),%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMADDSETS1
- end;
- procedure do_mul_sets(set1,set2,dest:pointer);assembler;[public,alias:'FPC_SET_MUL_SETS'];
- {
- multiplies (takes common elements of) set1 and set2 result put in dest
- }
- asm
- movl set1,%esi
- movl set2,%ebx
- movl dest,%edi
- movl $8,%ecx
- .LMMULSETS1:
- lodsl
- andl (%ebx),%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMMULSETS1
- end;
- procedure do_sub_sets(set1,set2,dest:pointer);assembler;[public,alias:'FPC_SET_SUB_SETS'];
- {
- computes the diff from set1 to set2 result in dest
- }
- asm
- movl set1,%esi
- movl set2,%ebx
- movl dest,%edi
- movl $8,%ecx
- .LMSUBSETS1:
- lodsl
- movl (%ebx),%edx
- notl %edx
- andl %edx,%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMSUBSETS1
- end;
- procedure do_symdif_sets(set1,set2,dest:pointer);assembler;[public,alias:'FPC_SET_SYMDIF_SETS'];
- {
- computes the symetric diff from set1 to set2 result in dest
- }
- asm
- movl set1,%esi
- movl set2,%ebx
- movl dest,%edi
- movl $8,%ecx
- .LMSYMDIFSETS1:
- lodsl
- movl (%ebx),%edx
- xorl %edx,%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMSYMDIFSETS1
- end;
- procedure do_comp_sets(set1,set2 : pointer);assembler;[public,alias:'FPC_SET_COMP_SETS'];
- {
- compares set1 and set2 zeroflag is set if they are equal
- }
- asm
- movl set1,%esi
- movl set2,%edi
- movl $8,%ecx
- .LMCOMPSETS1:
- movl (%esi),%eax
- movl (%edi),%edx
- cmpl %edx,%eax
- jne .LMCOMPSETEND
- addl $4,%esi
- addl $4,%edi
- decl %ecx
- jnz .LMCOMPSETS1
- { we are here only if the two sets are equal
- we have zero flag set, and that what is expected }
- .LMCOMPSETEND:
- end;
- {$IfNDef NoSetInclusion}
- procedure do_contains_sets(set1,set2 : pointer);assembler;[public,alias:'FPC_SET_CONTAINS_SETS'];
- {
- on exit, zero flag is set if set1 <= set2 (set2 contains set1)
- }
- asm
- movl set1,%esi
- movl set2,%edi
- movl $8,%ecx
- .LMCONTAINSSETS1:
- movl (%esi),%eax
- movl (%edi),%edx
- andl %eax,%edx
- cmpl %edx,%eax {set1 and set2 = set1?}
- jne .LMCONTAINSSETEND
- addl $4,%esi
- addl $4,%edi
- decl %ecx
- jnz .LMCONTAINSSETS1
- { we are here only if set2 contains set1
- we have zero flag set, and that what is expected }
- .LMCONTAINSSETEND:
- end;
- {$EndIf SetInclusion}
- {$ifdef LARGESETS}
- procedure do_set(p : pointer;b : word);assembler;[public,alias:'FPC_SET_SET_WORD'];
- {
- sets the element b in set p works for sets larger than 256 elements
- not yet use by the compiler so
- }
- asm
- pushl %eax
- movl p,%edi
- movw b,%ax
- andl $0xfff8,%eax
- shrl $3,%eax
- addl %eax,%edi
- movb 12(%ebp),%al
- andl $7,%eax
- btsl %eax,(%edi)
- popl %eax
- end;
- procedure do_in(p : pointer;b : word);assembler;[public,alias:'FPC_SET_IN_WORD'];
- {
- tests if the element b is in the set p the carryflag is set if it present
- works for sets larger than 256 elements
- }
- asm
- pushl %eax
- movl p,%edi
- movw b,%ax
- andl $0xfff8,%eax
- shrl $3,%eax
- addl %eax,%edi
- movb 12(%ebp),%al
- andl $7,%eax
- btl %eax,(%edi)
- popl %eax
- end;
- procedure add_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_SET_ADD_SETS_SIZE'];
- {
- adds set1 and set2 into set dest size is the number of bytes in the set
- }
- asm
- movl set1,%esi
- movl set2,%ebx
- movl dest,%edi
- movl size,%ecx
- .LMADDSETSIZES1:
- lodsl
- orl (%ebx),%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMADDSETSIZES1
- end;
- procedure mul_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_SET_MUL_SETS_SIZE'];
- {
- multiplies (i.E. takes common elements of) set1 and set2 result put in
- dest size is the number of bytes in the set
- }
- asm
- movl set1,%esi
- movl set2,%ebx
- movl dest,%edi
- movl size,%ecx
- .LMMULSETSIZES1:
- lodsl
- andl (%ebx),%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMMULSETSIZES1
- end;
- procedure sub_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_SET_SUB_SETS_SIZE'];
- asm
- movl set1,%esi
- movl set2,%ebx
- movl dest,%edi
- movl size,%ecx
- .LMSUBSETSIZES1:
- lodsl
- movl (%ebx),%edx
- notl %edx
- andl %edx,%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMSUBSETSIZES1
- end;
- procedure sym_sub_sets(set1,set2,dest : pointer;size : longint);assembler;[public,alias:'FPC_SET_SYMDIF_SETS_SIZE'];
- {
- computes the symetric diff from set1 to set2 result in dest
- }
- asm
- movl set1,%esi
- movl set2,%ebx
- movl dest,%edi
- movl size,%ecx
- .LMSYMDIFSETSIZE1:
- lodsl
- movl (%ebx),%edx
- xorl %edx,%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMSYMDIFSETSIZE1
- end;
- procedure comp_sets(set1,set2 : pointer;size : longint);assembler;[public,alias:'FPC_SET_COMP_SETS_SIZE'];
- asm
- movl set1,%esi
- movl set2,%edi
- movl size,%ecx
- .LMCOMPSETSIZES1:
- lodsl
- movl (%edi),%edx
- cmpl %edx,%eax
- jne .LMCOMPSETSIZEEND
- addl $4,%edi
- decl %ecx
- jnz .LMCOMPSETSIZES1
- { we are here only if the two sets are equal
- we have zero flag set, and that what is expected }
- .LMCOMPSETSIZEEND:
- end;
- {$IfNDef NoSetInclusion}
- procedure contains_sets(set1,set2 : pointer; size: longint);assembler;[public,alias:'FPC_SET_CONTAINS_SETS'];
- {
- on exit, zero flag is set if set1 <= set2 (set2 contains set1)
- }
- asm
- movl set1,%esi
- movl set2,%edi
- movl size,%ecx
- .LMCONTAINSSETS2:
- movl (%esi),%eax
- movl (%edi),%edx
- andl %eax,%edx
- cmpl %edx,%eax {set1 and set2 = set1?}
- jne .LMCONTAINSSETEND2
- addl $4,%esi
- addl $4,%edi
- decl %ecx
- jnz .LMCONTAINSSETS2
- { we are here only if set2 contains set1
- we have zero flag set, and that what is expected }
- .LMCONTAINSSETEND2:
- end;
- {$EndIf NoSetInclusion}
- {$endif LARGESET}
- {
- $Log$
- Revision 1.11 2000-01-07 16:32:24 daniel
- * copyright 2000 added
- Revision 1.10 1999/03/01 15:40:59 peter
- * use external names
- * removed all direct assembler modes
- Revision 1.9 1999/01/20 17:48:02 jonas
- + fixed bug0163 (set1 <= set2 support)
- Revision 1.8 1998/12/15 22:43:00 peter
- * removed temp symbols
- Revision 1.7 1998/11/24 12:54:01 peter
- + FPC_SET_CREATE_ELEMENT
- Revision 1.6 1998/10/22 14:50:08 pierre
- + added FPC_SET_UNSET_BYTE for exclude of normsets
- Revision 1.5 1998/10/22 12:48:29 peter
- * fixed for stackaligment also on 4 bytes, never use 'ret $..' direct
- Revision 1.4 1998/09/14 10:48:12 peter
- * FPC_ names
- * Heap manager is now system independent
- Revision 1.3 1998/08/14 18:13:44 peter
- + set_load_small
- * fixed set_set_range
- Revision 1.2 1998/05/31 14:15:51 peter
- * force to use ATT or direct parsing
- }
|