summaryrefslogtreecommitdiff
path: root/gcc/f/bit.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/f/bit.c')
-rw-r--r--gcc/f/bit.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/gcc/f/bit.c b/gcc/f/bit.c
new file mode 100644
index 00000000000..00f064b1da2
--- /dev/null
+++ b/gcc/f/bit.c
@@ -0,0 +1,200 @@
+/* bit.c -- Implementation File (module.c template V1.0)
+ Copyright (C) 1995 Free Software Foundation, Inc.
+ Contributed by James Craig Burley.
+
+This file is part of GNU Fortran.
+
+GNU Fortran is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Fortran 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. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Fortran; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+
+ Related Modules:
+ None
+
+ Description:
+ Tracks arrays of booleans in useful ways.
+
+ Modifications:
+*/
+
+/* Include files. */
+
+#include "proj.h"
+#include "bit.h"
+#include "malloc.h"
+
+/* Externals defined here. */
+
+
+/* Simple definitions and enumerations. */
+
+
+/* Internal typedefs. */
+
+
+/* Private include files. */
+
+
+/* Internal structure definitions. */
+
+
+/* Static objects accessed by functions in this module. */
+
+
+/* Static functions (internal). */
+
+
+/* Internal macros. */
+
+
+/* ffebit_count -- Count # of bits set a particular way
+
+ ffebit b; // the ffebit object
+ ffebitCount offset; // 0..size-1
+ bool value; // FALSE (0), TRUE (1)
+ ffebitCount range; // # bits to test
+ ffebitCount number; // # bits equal to value
+ ffebit_count(b,offset,value,range,&number);
+
+ Sets <number> to # bits at <offset> through <offset + range - 1> set to
+ <value>. If <range> is 0, <number> is set to 0. */
+
+void
+ffebit_count (ffebit b, ffebitCount offset, bool value, ffebitCount range,
+ ffebitCount *number)
+{
+ ffebitCount element;
+ ffebitCount bitno;
+
+ assert (offset + range <= b->size);
+
+ for (*number = 0; range != 0; --range, ++offset)
+ {
+ element = offset / CHAR_BIT;
+ bitno = offset % CHAR_BIT;
+ if (value
+ == ((b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE))
+ ++ * number;
+ }
+}
+
+/* ffebit_new -- Create a new ffebit object
+
+ ffebit b;
+ ffebit_kill(b);
+
+ Destroys an ffebit object obtained via ffebit_new. */
+
+void
+ffebit_kill (ffebit b)
+{
+ malloc_kill_ks (b->pool, b,
+ offsetof (struct _ffebit_, bits)
+ + (b->size + CHAR_BIT - 1) / CHAR_BIT);
+}
+
+/* ffebit_new -- Create a new ffebit object
+
+ ffebit b;
+ mallocPool pool;
+ ffebitCount size;
+ b = ffebit_new(pool,size);
+
+ Allocates an ffebit object that holds the values of <size> bits in pool
+ <pool>. */
+
+ffebit
+ffebit_new (mallocPool pool, ffebitCount size)
+{
+ ffebit b;
+
+ b = malloc_new_zks (pool, "ffebit",
+ offsetof (struct _ffebit_, bits)
+ + (size + CHAR_BIT - 1) / CHAR_BIT,
+ 0);
+ b->pool = pool;
+ b->size = size;
+
+ return b;
+}
+
+/* ffebit_set -- Set value of # of bits
+
+ ffebit b; // the ffebit object
+ ffebitCount offset; // 0..size-1
+ bool value; // FALSE (0), TRUE (1)
+ ffebitCount length; // # bits to set starting at offset (usually 1)
+ ffebit_set(b,offset,value,length);
+
+ Sets bit #s <offset> through <offset + length - 1> to <value>. */
+
+void
+ffebit_set (ffebit b, ffebitCount offset, bool value, ffebitCount length)
+{
+ ffebitCount i;
+ ffebitCount element;
+ ffebitCount bitno;
+
+ assert (offset + length <= b->size);
+
+ for (i = 0; i < length; ++i, ++offset)
+ {
+ element = offset / CHAR_BIT;
+ bitno = offset % CHAR_BIT;
+ b->bits[element] = (((unsigned char) (value ? 1 : 0)) << bitno)
+ | (b->bits[element] & ~((unsigned char) 1 << bitno));
+ }
+}
+
+/* ffebit_test -- Test value of # of bits
+
+ ffebit b; // the ffebit object
+ ffebitCount offset; // 0..size-1
+ bool value; // FALSE (0), TRUE (1)
+ ffebitCount length; // # bits with same value
+ ffebit_test(b,offset,&value,&length);
+
+ Returns value of bits at <offset> through <offset + length - 1> in
+ <value>. If <offset> is already at the end of the bit array (if
+ offset == ffebit_size(b)), <length> is set to 0 and <value> is
+ undefined. */
+
+void
+ffebit_test (ffebit b, ffebitCount offset, bool *value, ffebitCount *length)
+{
+ ffebitCount i;
+ ffebitCount element;
+ ffebitCount bitno;
+
+ if (offset >= b->size)
+ {
+ assert (offset == b->size);
+ *length = 0;
+ return;
+ }
+
+ element = offset / CHAR_BIT;
+ bitno = offset % CHAR_BIT;
+ *value = (b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE;
+ *length = 1;
+
+ for (i = b->size - offset - 1, ++offset; i != 0; --i, ++offset, ++*length)
+ {
+ element = offset / CHAR_BIT;
+ bitno = offset % CHAR_BIT;
+ if (*value
+ != ((b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE))
+ break;
+ }
+}