xref: /openbsd/gnu/usr.bin/gcc/gcc/f/bit.c (revision c87b03e5)
1*c87b03e5Sespie /* bit.c -- Implementation File (module.c template V1.0)
2*c87b03e5Sespie    Copyright (C) 1995 Free Software Foundation, Inc.
3*c87b03e5Sespie    Contributed by James Craig Burley.
4*c87b03e5Sespie 
5*c87b03e5Sespie This file is part of GNU Fortran.
6*c87b03e5Sespie 
7*c87b03e5Sespie GNU Fortran is free software; you can redistribute it and/or modify
8*c87b03e5Sespie it under the terms of the GNU General Public License as published by
9*c87b03e5Sespie the Free Software Foundation; either version 2, or (at your option)
10*c87b03e5Sespie any later version.
11*c87b03e5Sespie 
12*c87b03e5Sespie GNU Fortran is distributed in the hope that it will be useful,
13*c87b03e5Sespie but WITHOUT ANY WARRANTY; without even the implied warranty of
14*c87b03e5Sespie MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*c87b03e5Sespie GNU General Public License for more details.
16*c87b03e5Sespie 
17*c87b03e5Sespie You should have received a copy of the GNU General Public License
18*c87b03e5Sespie along with GNU Fortran; see the file COPYING.  If not, write to
19*c87b03e5Sespie the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20*c87b03e5Sespie 02111-1307, USA.
21*c87b03e5Sespie 
22*c87b03e5Sespie    Related Modules:
23*c87b03e5Sespie       None
24*c87b03e5Sespie 
25*c87b03e5Sespie    Description:
26*c87b03e5Sespie       Tracks arrays of booleans in useful ways.
27*c87b03e5Sespie 
28*c87b03e5Sespie    Modifications:
29*c87b03e5Sespie */
30*c87b03e5Sespie 
31*c87b03e5Sespie /* Include files. */
32*c87b03e5Sespie 
33*c87b03e5Sespie #include "proj.h"
34*c87b03e5Sespie #include "bit.h"
35*c87b03e5Sespie #include "malloc.h"
36*c87b03e5Sespie 
37*c87b03e5Sespie /* Externals defined here. */
38*c87b03e5Sespie 
39*c87b03e5Sespie 
40*c87b03e5Sespie /* Simple definitions and enumerations. */
41*c87b03e5Sespie 
42*c87b03e5Sespie 
43*c87b03e5Sespie /* Internal typedefs. */
44*c87b03e5Sespie 
45*c87b03e5Sespie 
46*c87b03e5Sespie /* Private include files. */
47*c87b03e5Sespie 
48*c87b03e5Sespie 
49*c87b03e5Sespie /* Internal structure definitions. */
50*c87b03e5Sespie 
51*c87b03e5Sespie 
52*c87b03e5Sespie /* Static objects accessed by functions in this module. */
53*c87b03e5Sespie 
54*c87b03e5Sespie 
55*c87b03e5Sespie /* Static functions (internal). */
56*c87b03e5Sespie 
57*c87b03e5Sespie 
58*c87b03e5Sespie /* Internal macros. */
59*c87b03e5Sespie 
60*c87b03e5Sespie 
61*c87b03e5Sespie /* ffebit_count -- Count # of bits set a particular way
62*c87b03e5Sespie 
63*c87b03e5Sespie    ffebit b;  // the ffebit object
64*c87b03e5Sespie    ffebitCount offset;	// 0..size-1
65*c87b03e5Sespie    bool value;	// FALSE (0), TRUE (1)
66*c87b03e5Sespie    ffebitCount range;  // # bits to test
67*c87b03e5Sespie    ffebitCount number;	// # bits equal to value
68*c87b03e5Sespie    ffebit_count(b,offset,value,range,&number);
69*c87b03e5Sespie 
70*c87b03e5Sespie    Sets <number> to # bits at <offset> through <offset + range - 1> set to
71*c87b03e5Sespie    <value>.  If <range> is 0, <number> is set to 0.  */
72*c87b03e5Sespie 
73*c87b03e5Sespie void
ffebit_count(ffebit b,ffebitCount offset,bool value,ffebitCount range,ffebitCount * number)74*c87b03e5Sespie ffebit_count (ffebit b, ffebitCount offset, bool value, ffebitCount range,
75*c87b03e5Sespie 	      ffebitCount *number)
76*c87b03e5Sespie {
77*c87b03e5Sespie   ffebitCount element;
78*c87b03e5Sespie   ffebitCount bitno;
79*c87b03e5Sespie 
80*c87b03e5Sespie   assert (offset + range <= b->size);
81*c87b03e5Sespie 
82*c87b03e5Sespie   for (*number = 0; range != 0; --range, ++offset)
83*c87b03e5Sespie     {
84*c87b03e5Sespie       element = offset / CHAR_BIT;
85*c87b03e5Sespie       bitno = offset % CHAR_BIT;
86*c87b03e5Sespie       if (value
87*c87b03e5Sespie 	  == ((b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE))
88*c87b03e5Sespie 	++ * number;
89*c87b03e5Sespie     }
90*c87b03e5Sespie }
91*c87b03e5Sespie 
92*c87b03e5Sespie /* ffebit_new -- Create a new ffebit object
93*c87b03e5Sespie 
94*c87b03e5Sespie    ffebit b;
95*c87b03e5Sespie    ffebit_kill(b);
96*c87b03e5Sespie 
97*c87b03e5Sespie    Destroys an ffebit object obtained via ffebit_new.  */
98*c87b03e5Sespie 
99*c87b03e5Sespie void
ffebit_kill(ffebit b)100*c87b03e5Sespie ffebit_kill (ffebit b)
101*c87b03e5Sespie {
102*c87b03e5Sespie   malloc_kill_ks (b->pool, b,
103*c87b03e5Sespie 		  offsetof (struct _ffebit_, bits)
104*c87b03e5Sespie 		  + (b->size + CHAR_BIT - 1) / CHAR_BIT);
105*c87b03e5Sespie }
106*c87b03e5Sespie 
107*c87b03e5Sespie /* ffebit_new -- Create a new ffebit object
108*c87b03e5Sespie 
109*c87b03e5Sespie    ffebit b;
110*c87b03e5Sespie    mallocPool pool;
111*c87b03e5Sespie    ffebitCount size;
112*c87b03e5Sespie    b = ffebit_new(pool,size);
113*c87b03e5Sespie 
114*c87b03e5Sespie    Allocates an ffebit object that holds the values of <size> bits in pool
115*c87b03e5Sespie    <pool>.  */
116*c87b03e5Sespie 
117*c87b03e5Sespie ffebit
ffebit_new(mallocPool pool,ffebitCount size)118*c87b03e5Sespie ffebit_new (mallocPool pool, ffebitCount size)
119*c87b03e5Sespie {
120*c87b03e5Sespie   ffebit b;
121*c87b03e5Sespie 
122*c87b03e5Sespie   b = malloc_new_zks (pool, "ffebit",
123*c87b03e5Sespie 		      offsetof (struct _ffebit_, bits)
124*c87b03e5Sespie 		      + (size + CHAR_BIT - 1) / CHAR_BIT,
125*c87b03e5Sespie 		      0);
126*c87b03e5Sespie   b->pool = pool;
127*c87b03e5Sespie   b->size = size;
128*c87b03e5Sespie 
129*c87b03e5Sespie   return b;
130*c87b03e5Sespie }
131*c87b03e5Sespie 
132*c87b03e5Sespie /* ffebit_set -- Set value of # of bits
133*c87b03e5Sespie 
134*c87b03e5Sespie    ffebit b;  // the ffebit object
135*c87b03e5Sespie    ffebitCount offset;	// 0..size-1
136*c87b03e5Sespie    bool value;	// FALSE (0), TRUE (1)
137*c87b03e5Sespie    ffebitCount length;	// # bits to set starting at offset (usually 1)
138*c87b03e5Sespie    ffebit_set(b,offset,value,length);
139*c87b03e5Sespie 
140*c87b03e5Sespie    Sets bit #s <offset> through <offset + length - 1> to <value>.  */
141*c87b03e5Sespie 
142*c87b03e5Sespie void
ffebit_set(ffebit b,ffebitCount offset,bool value,ffebitCount length)143*c87b03e5Sespie ffebit_set (ffebit b, ffebitCount offset, bool value, ffebitCount length)
144*c87b03e5Sespie {
145*c87b03e5Sespie   ffebitCount i;
146*c87b03e5Sespie   ffebitCount element;
147*c87b03e5Sespie   ffebitCount bitno;
148*c87b03e5Sespie 
149*c87b03e5Sespie   assert (offset + length <= b->size);
150*c87b03e5Sespie 
151*c87b03e5Sespie   for (i = 0; i < length; ++i, ++offset)
152*c87b03e5Sespie     {
153*c87b03e5Sespie       element = offset / CHAR_BIT;
154*c87b03e5Sespie       bitno = offset % CHAR_BIT;
155*c87b03e5Sespie       b->bits[element] = (((unsigned char) (value ? 1 : 0)) << bitno)
156*c87b03e5Sespie 	| (b->bits[element] & ~((unsigned char) 1 << bitno));
157*c87b03e5Sespie     }
158*c87b03e5Sespie }
159*c87b03e5Sespie 
160*c87b03e5Sespie /* ffebit_test -- Test value of # of bits
161*c87b03e5Sespie 
162*c87b03e5Sespie    ffebit b;  // the ffebit object
163*c87b03e5Sespie    ffebitCount offset;	// 0..size-1
164*c87b03e5Sespie    bool value;	// FALSE (0), TRUE (1)
165*c87b03e5Sespie    ffebitCount length;	// # bits with same value
166*c87b03e5Sespie    ffebit_test(b,offset,&value,&length);
167*c87b03e5Sespie 
168*c87b03e5Sespie    Returns value of bits at <offset> through <offset + length - 1> in
169*c87b03e5Sespie    <value>.  If <offset> is already at the end of the bit array (if
170*c87b03e5Sespie    offset == ffebit_size(b)), <length> is set to 0 and <value> is
171*c87b03e5Sespie    undefined.  */
172*c87b03e5Sespie 
173*c87b03e5Sespie void
ffebit_test(ffebit b,ffebitCount offset,bool * value,ffebitCount * length)174*c87b03e5Sespie ffebit_test (ffebit b, ffebitCount offset, bool *value, ffebitCount *length)
175*c87b03e5Sespie {
176*c87b03e5Sespie   ffebitCount i;
177*c87b03e5Sespie   ffebitCount element;
178*c87b03e5Sespie   ffebitCount bitno;
179*c87b03e5Sespie 
180*c87b03e5Sespie   if (offset >= b->size)
181*c87b03e5Sespie     {
182*c87b03e5Sespie       assert (offset == b->size);
183*c87b03e5Sespie       *length = 0;
184*c87b03e5Sespie       return;
185*c87b03e5Sespie     }
186*c87b03e5Sespie 
187*c87b03e5Sespie   element = offset / CHAR_BIT;
188*c87b03e5Sespie   bitno = offset % CHAR_BIT;
189*c87b03e5Sespie   *value = (b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE;
190*c87b03e5Sespie   *length = 1;
191*c87b03e5Sespie 
192*c87b03e5Sespie   for (i = b->size - offset - 1, ++offset; i != 0; --i, ++offset, ++*length)
193*c87b03e5Sespie     {
194*c87b03e5Sespie       element = offset / CHAR_BIT;
195*c87b03e5Sespie       bitno = offset % CHAR_BIT;
196*c87b03e5Sespie       if (*value
197*c87b03e5Sespie 	  != ((b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE))
198*c87b03e5Sespie 	break;
199*c87b03e5Sespie     }
200*c87b03e5Sespie }
201