123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- {
- $Id$
- This file is part of the Free Pascal run time library.
- Copyright (c) 1993,97 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.
- **********************************************************************}
- {$ASMMODE ATT}
- procedure do_set(p : pointer;b : byte); [public,alias: 'SET_SET_BYTE'];
- {
- add the element b to the set pointed by p
- }
- begin
- 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
- { own exit, the compiler generates a ret $8, IMHO }
- leave
- ret $6
- end;
- end;
- {$ASMMODE DIRECT}
- procedure do_set(p : pointer;l,h : byte);[public,alias: 'SET_SET_RANGE'];
- {
- bad implementation, but it's very seldom used
- }
- begin
- asm
- pushl %eax
- xorl %eax,%eax
- movb h,%al
- .LSET_SET_RANGE_LOOP:
- cmpb %al,l
- jb .LSET_SET_RANGE_EXIT
- pushw %ax
- pushl p
- call SET_SET_BYTE
- dec %al
- jmp .LSET_SET_RANGE_LOOP
- .LSET_SET_RANGE_EXIT:
- popl %eax
- end;
- end;
- {$ASMMODE ATT}
- procedure do_in(p : pointer;b : byte);[public,alias: 'SET_IN_BYTE'];
- {
- tests if the element b is in the set p the carryflag is set if it present
- }
- begin
- 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
- { own exit, the compiler generates a ret $8, IMHO }
- leave
- ret $6
- end;
- end;
- procedure add_sets(set1,set2,dest : pointer);[public,alias: 'SET_ADD_SETS'];
- {
- adds set1 and set2 into set dest
- }
- begin
- asm
- movl 8(%ebp),%esi
- movl 12(%ebp),%ebx
- movl 16(%ebp),%edi
- movl $8,%ecx
- .LMADDSETS1:
- lodsl
- orl (%ebx),%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMADDSETS1
- end;
- end;
- { multiplies (i.E. takes common elements of) set1 and set2 }
- { result put in dest }
- procedure mul_sets(set1,set2,dest : pointer);[public,alias: 'SET_MUL_SETS'];
- begin
- asm
- movl 8(%ebp),%esi
- movl 12(%ebp),%ebx
- movl 16(%ebp),%edi
- movl $8,%ecx
- .LMMULSETS1:
- lodsl
- andl (%ebx),%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMMULSETS1
- end;
- end;
- procedure sub_sets(set1,set2,dest : pointer);[public,alias: 'SET_SUB_SETS'];
- {
- computes the diff from set1 to set2 result in dest
- }
- begin
- asm
- movl 8(%ebp),%esi
- movl 12(%ebp),%ebx
- movl 16(%ebp),%edi
- movl $8,%ecx
- .LMSUBSETS1:
- lodsl
- movl (%ebx),%edx
- notl %edx
- andl %edx,%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMSUBSETS1
- end;
- end;
- procedure sym_sub_sets(set1,set2,dest : pointer);[public,alias: 'SET_SYMDIF_SETS'];
- {
- computes the symetric diff from set1 to set2 result in dest
- }
- begin
- asm
- movl 8(%ebp),%esi
- movl 12(%ebp),%ebx
- movl 16(%ebp),%edi
- movl $8,%ecx
- .LMSYMDIFSETS1:
- lodsl
- movl (%ebx),%edx
- xorl %edx,%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMSYMDIFSETS1
- end;
- end;
- procedure comp_sets(set1,set2 : pointer);[public,alias: 'SET_COMP_SETS'];
- {
- compares set1 and set2 zeroflag is set if they are equal
- }
- begin
- asm
- movl 8(%ebp),%esi
- movl 12(%ebp),%edi
- movl $8,%ecx
- .LMCOMPSETS1:
- lodsl
- movl (%edi),%edx
- cmpl %edx,%eax
- jne .LMCOMPSETEND
- 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 }
- cmpl %eax,%eax
- .LMCOMPSETEND:
- end;
- end;
- {$ifdef LARGESETS}
- procedure do_set(p : pointer;b : word);[public,alias: 'SET_SET_WORD'];
- {
- sets the element b in set p works for sets larger than 256 elements
- not yet use by the compiler so
- }
- begin
- asm
- pushl %eax
- movl 8(%ebp),%edi
- movw 12(%ebp),%ax
- andl $0xfff8,%eax
- shrl $3,%eax
- addl %eax,%edi
- movb 12(%ebp),%al
- andl $7,%eax
- btsl %eax,(%edi)
- popl %eax
- end;
- end;
- procedure do_in(p : pointer;b : word);[public,alias: '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
- }
- begin
- asm
- pushl %eax
- movl 8(%ebp),%edi
- movw 12(%ebp),%ax
- andl $0xfff8,%eax
- shrl $3,%eax
- addl %eax,%edi
- movb 12(%ebp),%al
- andl $7,%eax
- btl %eax,(%edi)
- popl %eax
- end;
- end;
- procedure add_sets(set1,set2,dest : pointer;size : longint);[public,alias: 'SET_ADD_SETS_SIZE'];
- {
- adds set1 and set2 into set dest size is the number of bytes in the set
- }
- begin
- asm
- movl 8(%ebp),%esi
- movl 12(%ebp),%ebx
- movl 16(%ebp),%edi
- movl 20(%ebp),%ecx
- .LMADDSETSIZES1:
- lodsl
- orl (%ebx),%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMADDSETSIZES1
- end;
- end;
- procedure mul_sets(set1,set2,dest : pointer;size : longint);[public,alias: '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
- }
- begin
- asm
- movl 8(%ebp),%esi
- movl 12(%ebp),%ebx
- movl 16(%ebp),%edi
- movl 20(%ebp),%ecx
- .LMMULSETSIZES1:
- lodsl
- andl (%ebx),%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMMULSETSIZES1
- end;
- end;
- procedure sub_sets(set1,set2,dest : pointer;size : longint);[public,alias: 'SET_SUB_SETS_SIZE'];
- begin
- asm
- movl 8(%ebp),%esi
- movl 12(%ebp),%ebx
- movl 16(%ebp),%edi
- movl 20(%ebp),%ecx
- .LMSUBSETSIZES1:
- lodsl
- movl (%ebx),%edx
- notl %edx
- andl %edx,%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMSUBSETSIZES1
- end;
- end;
- procedure sym_sub_sets(set1,set2,dest : pointer;size : longint);[public,alias: 'SET_SYMDIF_SETS_SIZE'];
- {
- computes the symetric diff from set1 to set2 result in dest
- }
- begin
- asm
- movl 8(%ebp),%esi
- movl 12(%ebp),%ebx
- movl 16(%ebp),%edi
- movl 20(%ebp),%ecx
- .LMSYMDIFSETSIZE1:
- lodsl
- movl (%ebx),%edx
- xorl %edx,%eax
- stosl
- addl $4,%ebx
- decl %ecx
- jnz .LMSYMDIFSETSIZE1
- end;
- end;
- procedure comp_sets(set1,set2 : pointer;size : longint);[public,alias: 'SET_COMP_SETS_SIZE'];
- begin
- asm
- movl 8(%ebp),%esi
- movl 12(%ebp),%edi
- movl 16(%ebp),%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 }
- cmpl %eax,%eax
- .LMCOMPSETSIZEEND:
- end;
- end;
- {$endif LARGESET}
- {
- $Log$
- Revision 1.2 1998-05-31 14:15:51 peter
- * force to use ATT or direct parsing
- }
|