3 This file is part of the Free Pascal run time library.
4 Copyright (c) 1999-2000 by Carl-Eric Codere,
5 member of the Free Pascal development team.
7 See the file COPYING.FPC, included in this distribution,
8 for details about the copyright.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 **********************************************************************}
15 {*************************************************************************}
16 { Converted by Carl Eric Codere }
17 {*************************************************************************}
18 { This inc. implements low-level set operations for the motorola }
19 { 68000 familiy of processors. }
20 { Based on original code bt Florian Kl„mpfl for the 80x86. }
21 {*************************************************************************}
24 { add the element b to the set pointed by p }
26 { a0 = pointer to set }
27 { d0.b = element to add to the set }
28 { Registers destroyed: d0,a1,d6 }
29 procedure do_set;assembler;
33 { correct long position: }
34 { -> (value div 32)*4 = longint }
35 { (value shr 5)*shl 2 }
38 adda.l d6,a0 { correct offset from start address of set }
40 move.l d0,d6 { bit is now in here }
41 andi.l #31,d0 { bit number is = value mod 32 }
43 { now bit set the value }
44 move.l (a0),d0 { we must put bits into register }
45 bset.l d6,d0 { otherwise btst will be a byte }
46 { put result in carry flag } { operation. }
48 andi.b #$fe,ccr { clear carry flag }
51 ori.b #$01,ccr { set carry flag }
53 move.l d0,(a0) { restore the value at that location }
57 { Finds an element in a set }
58 { a0 = address of set }
59 { d0.b = value to compare with }
60 { CARRY SET IF FOUND ON EXIT }
61 { Registers destroyed: d0,a0,d6 }
62 procedure do_in; assembler;
63 { Returns Carry set then = in set , otherwise carry is cleared }
68 { correct long position: }
69 { -> (value div 32)*4 = longint }
70 { (value shr 5)*shl 2 }
73 adda.l d6,a0 { correct offset from start address of set }
75 move.l d0,d6 { bit is now in here }
76 andi.l #31,d0 { bit number is = value mod 32 }
78 move.l (a0),d0 { we must put bits into register }
79 btst.l d6,d0 { otherwise btst will be a byte }
80 { put result in carry flag } { operation. }
82 andi.b #$fe,ccr { clear carry flag }
85 ori.b #$01,ccr { set carry flag }
91 { vereinigt set1 und set2 und speichert das Ergebnis in dest }
93 procedure add_sets(set1,set2,dest : pointer);[public,alias: 'SET_ADD_SETS'];
96 destination = array[1..8] of longint;
98 destination(dest^)[i] := destination(set1^)[i] OR destination(set2^)[i];
102 { saved used register }
120 end ['d0','d6','a0','a1'];
123 { computes the symetric diff from set1 to set2 }
126 procedure sym_sub_sets(set1,set2,dest : pointer);[public,alias: 'SET_SYMDIF_SETS'];
130 { saved used register }
153 { bad implementation, but it's very seldom used }
154 procedure do_set(p : pointer;l,h : byte);[public,alias: 'SET_SET_RANGE'];
163 { adjust value to correct endian }
174 { bildet den Durchschnitt von set1 und set2 }
175 { und speichert das Ergebnis in dest }
177 procedure mul_sets(set1,set2,dest : pointer);[public,alias: 'SET_MUL_SETS'];
179 larray = array[0..7] of longint;
181 larray(dest^)[i] := larray(set1^)[i] AND larray(set2^)[i];
185 { saved used register }
202 end ['d0','d6','a0','a1'];
206 { bildet die Differenz von set1 und set2 }
207 { und speichert das Ergebnis in dest }
209 procedure sub_sets(set1,set2,dest : pointer);[public,alias: 'SET_SUB_SETS'];
211 larray = array[0..7] of longint;
214 larray(dest^)[i] := larray(set1^)[i] AND NOT (larray(set2^)[i]);
219 { saved used register }
237 end ['d0','d1','d6','a0','a1'];
240 { compare both sets }
241 { compares set1 and set2 }
242 { zeroflag is set if they are equal }
243 { on entry : a0 = pointer to first set }
244 { : a1 = pointer to second set }
245 procedure comp_sets; assembler;
258 { we are here only if the two sets are equal }
259 { we have zero flag set, and that what is expected }
264 procedure do_set(p : pointer;b : word);[public,alias: 'SET_SET_WORD'];
275 move.l (a0),d0 { we must put bits into register }
276 btst.l d6,d0 { otherwise btst will be a byte }
277 { put result in carry flag } { operation. }
279 andi.b #$fe,ccr { clear carry flag }
282 ori.b #$01,ccr { set carry flag }
284 end ['d0','a0','d6'];
287 { testet, ob das Element b in der Menge p vorhanden ist }
288 { und setzt das Carryflag entsprechend }
290 procedure do_in(p : pointer;b : word);[public,alias: 'SET_IN_WORD'];
297 adda.l d6,a0 { correct offset from start address of set }
302 move.l (a0),d0 { we must put bits into register }
303 btst.l d6,d0 { otherwise btst will be a byte }
304 { put result in carry flag } { operation. }
306 andi.b #$fe,ccr { clear carry flag }
309 ori.b #$01,ccr { set carry flag }
311 end ['d0','a0','d6'];
315 { vereinigt set1 und set2 und speichert das Ergebnis in dest }
316 { size is the number of bytes in the set }
318 procedure add_sets(set1,set2,dest : pointer;size : longint);[public,alias: 'SET_ADD_SETS_SIZE'];
321 { saved used register }
338 end ['d0','d6','a0','a1'];
342 procedure mul_sets(set1,set2,dest : pointer;size : longint);[public,alias: 'SET_MUL_SETS_SIZE'];
343 { bildet den Durchschnitt von set1 und set2 }
344 { und speichert das Ergebnis in dest }
345 { size is the number of bytes in the set }
348 { saved used register }
365 end ['d0','d6','a0','a1'];
369 { bildet die Differenz von set1 und set2 }
370 { und speichert das Ergebnis in dest }
371 { size is the number of bytes in the set }
373 procedure sub_sets(set1,set2,dest : pointer;size : longint);[public,alias: 'SET_SUB_SETS_SIZE'];
376 { saved used register }
394 end ['d0','d6','a0','a1'];
398 { vergleicht Mengen und setzt die Flags entsprechend }
400 procedure comp_sets(set1,set2 : pointer;size : longint);[public,alias: 'SET_COMP_SETS_SIZE'];
405 move.l 8(a6),a0 { set1 - esi}
406 move.l 12(a6),a1 { set2 - edi }
416 { we are here only if the two sets are equal }
417 { we have zero flag set, and that what is expected }
425 Revision 1.1 2002/02/19 08:25:43 sasu
428 Revision 1.1 2000/07/13 06:30:57 michael
431 Revision 1.8 2000/01/07 16:41:43 daniel
434 Revision 1.7 2000/01/07 16:32:29 daniel
435 * copyright 2000 added
437 Revision 1.6 1998/07/30 12:16:29 carl
438 * set_sub_sets bugfix, was not using correct operation
440 Revision 1.5 1998/07/01 14:27:13 carl
441 * set_set and set_in bugfix
443 Revision 1.2 1998/03/27 23:47:35 carl
444 * bugfix of FLAGS as return values for SET_IN_BYTE and SET_SET_BYTE
446 Revision 1.4 1998/01/26 12:01:42 michael
447 + Added log at the end
451 Working file: rtl/m68k/set.inc
453 ----------------------------
455 date: 1998/01/05 00:34:50; author: carl; state: Exp; lines: +349 -350
456 * Silly syntax errors fixed.
457 ----------------------------
459 date: 1997/12/01 12:37:22; author: michael; state: Exp; lines: +14 -0
460 + added copyright reference in header.
461 ----------------------------
463 date: 1997/11/28 16:51:20; author: carl; state: Exp;
464 + set routines for m68k.
465 =============================================================================