summaryrefslogtreecommitdiff
path: root/src/SDCCbitv.c
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /src/SDCCbitv.c
downloadsdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'src/SDCCbitv.c')
-rw-r--r--src/SDCCbitv.c541
1 files changed, 541 insertions, 0 deletions
diff --git a/src/SDCCbitv.c b/src/SDCCbitv.c
new file mode 100644
index 0000000..7b2f8a6
--- /dev/null
+++ b/src/SDCCbitv.c
@@ -0,0 +1,541 @@
+/*-----------------------------------------------------------------
+ SDCCbitv.c - contains support routines for bitvectors
+
+ Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
+
+ This program 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.
+
+ 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. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+
+#include "common.h"
+
+#include "newalloc.h"
+
+int bitVectDefault = 1024;
+
+#define BYTE_SIZEOF_ELEMENT (sizeof(unsigned int))
+#define BIT_SIZEOF_ELEMENT (BYTE_SIZEOF_ELEMENT*8)
+
+/* genernal note about a bitvectors:
+ bit positions must start from 0 */
+/*-----------------------------------------------------------------*/
+/* newBitVect - returns a new bitvector of size */
+/*-----------------------------------------------------------------*/
+bitVect *
+newBitVect (int size)
+{
+ bitVect *bvp;
+
+ bvp = Safe_calloc (1, sizeof (bitVect));
+
+ bvp->size = size;
+ bvp->allocSize = (size+BIT_SIZEOF_ELEMENT-1) / BIT_SIZEOF_ELEMENT;
+ bvp->vect = Safe_calloc (BYTE_SIZEOF_ELEMENT, bvp->allocSize);
+ return bvp;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* freeBitVect - frees the memory used by the bitVector */
+/*-----------------------------------------------------------------*/
+void
+freeBitVect (bitVect * bvp)
+{
+ if (!bvp)
+ return;
+
+ Safe_free (bvp->vect);
+ Safe_free (bvp);
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectResize - changes the size of a bit vector */
+/*-----------------------------------------------------------------*/
+bitVect *
+bitVectResize (bitVect * bvp, int size)
+{
+ int allocSize;
+
+ if (!bvp)
+ return newBitVect (size);
+
+ allocSize = (size+BIT_SIZEOF_ELEMENT-1) / BIT_SIZEOF_ELEMENT;
+
+ /* if we already have enough space */
+ if (bvp->allocSize >= allocSize)
+ {
+ if (size > bvp->size)
+ bvp->size = size;
+ return bvp;
+ }
+
+ bvp->vect = Clear_realloc (bvp->vect, bvp->allocSize*BYTE_SIZEOF_ELEMENT, allocSize*BYTE_SIZEOF_ELEMENT);
+ bvp->size = size;
+ bvp->allocSize = allocSize;
+
+ return bvp;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectSetBit - sets a given bit in the bit vector */
+/*-----------------------------------------------------------------*/
+bitVect *
+bitVectSetBit (bitVect * bvp, int pos)
+{
+ unsigned int index;
+ unsigned int bitofs;
+
+ assert (pos>=0);
+ /* if set is null then allocate it */
+ if (!bvp)
+ bvp = newBitVect (bitVectDefault); /* allocate for twice the size */
+
+ if (bvp->size <= pos)
+ bvp = bitVectResize (bvp, pos + 2); /* conservatively resize */
+
+ index = pos / BIT_SIZEOF_ELEMENT;
+ bitofs = pos % BIT_SIZEOF_ELEMENT;
+ bvp->vect[index] |= 1u << bitofs;
+ return bvp;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectUnSetBit - unsets the value of a bit in a bitvector */
+/*-----------------------------------------------------------------*/
+void
+bitVectUnSetBit (const bitVect *bvp, int pos)
+{
+ unsigned int index;
+ unsigned int bitofs;
+
+ assert (pos>=0);
+ if (!bvp)
+ return;
+
+ if (bvp->size <= pos)
+ return;
+
+ index = pos / BIT_SIZEOF_ELEMENT;
+ bitofs = pos % BIT_SIZEOF_ELEMENT;
+ bvp->vect[index] &= ~(1u << bitofs);
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectBitValue - returns value value at bit position */
+/*-----------------------------------------------------------------*/
+int
+bitVectBitValue (const bitVect *bvp, int pos)
+{
+ unsigned int index;
+ unsigned int bitofs;
+
+ assert (pos>=0);
+ if (!bvp)
+ return 0;
+
+ index = pos / BIT_SIZEOF_ELEMENT;
+ bitofs = pos % BIT_SIZEOF_ELEMENT;
+
+ if (bvp->size <= pos)
+ return 0;
+
+
+ return (bvp->vect[index] >> bitofs) & 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectUnion - unions two bitvectors */
+/*-----------------------------------------------------------------*/
+bitVect *
+bitVectUnion (bitVect * bvp1, bitVect * bvp2)
+{
+ bitVect *newBvp;
+ unsigned int *pn, *p1, *p2;
+ int elements;
+
+ /* if both null */
+ if (!bvp1 && !bvp2)
+ return NULL;
+
+ /* if one of them null then return the other */
+ if (!bvp1 && bvp2)
+ return bitVectCopy (bvp2);
+
+ if (bvp1 && !bvp2)
+ return bitVectCopy (bvp1);
+
+ /* if they are not the same size */
+ /* make them the same size */
+ if (bvp1->size < bvp2->size)
+ bvp1 = bitVectResize (bvp1, bvp2->size);
+ else if (bvp2->size < bvp1->size)
+ bvp2 = bitVectResize (bvp2, bvp1->size);
+
+ newBvp = newBitVect (bvp1->size);
+ elements = bvp1->allocSize;
+
+ pn = newBvp->vect;
+ p1 = bvp1->vect;
+ p2 = bvp2->vect;
+
+ while (elements--)
+ {
+ *pn++ = *p1++ | *p2++;
+ }
+
+ return newBvp;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectInplaceUnion - unions two bitvectors */
+/*-----------------------------------------------------------------*/
+bitVect *
+bitVectInplaceUnion (bitVect * bvp1, bitVect * bvp2)
+{
+ unsigned int *p1, *p2;
+ int elements;
+
+ /* if both null */
+ if (!bvp1 && !bvp2)
+ return NULL;
+
+ /* if one of them null then return the other */
+ if (!bvp1 && bvp2)
+ return bitVectCopy (bvp2);
+
+ if (bvp1 && !bvp2)
+ return bvp1;
+
+ /* if they are not the same size */
+ /* make them the same size */
+ if (bvp1->size < bvp2->size)
+ bvp1 = bitVectResize (bvp1, bvp2->size);
+ else if (bvp2->size < bvp1->size)
+ bvp2 = bitVectResize (bvp2, bvp1->size);
+
+ elements = bvp1->allocSize;
+
+ p1 = bvp1->vect;
+ p2 = bvp2->vect;
+
+ while (elements--)
+ {
+ *p1 |= *p2;
+ p1++; p2++;
+ }
+
+ return bvp1;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* bitVectIntersect - intersect two bitvectors */
+/*-----------------------------------------------------------------*/
+bitVect *
+bitVectIntersect (bitVect * bvp1, bitVect * bvp2)
+{
+ bitVect *newBvp;
+ unsigned int *pn, *p1, *p2;
+ int elements;
+
+ if (!bvp2 || !bvp1)
+ return NULL;
+
+ /* if they are not the same size */
+ /* make them the same size */
+ if (bvp1->size < bvp2->size)
+ bvp1 = bitVectResize (bvp1, bvp2->size);
+ else if (bvp2->size < bvp1->size)
+ bvp2 = bitVectResize (bvp2, bvp1->size);
+
+ newBvp = newBitVect (bvp1->size);
+ elements = bvp1->allocSize;
+
+ pn = newBvp->vect;
+ p1 = bvp1->vect;
+ p2 = bvp2->vect;
+
+ while (elements--)
+ {
+ *pn++ = *p1++ & *p2++;
+ }
+
+ return newBvp;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectInplaceIntersect - intersect two bitvectors */
+/*-----------------------------------------------------------------*/
+bitVect *
+bitVectInplaceIntersect (bitVect * bvp1, bitVect * bvp2)
+{
+ unsigned int *p1, *p2;
+ int elements;
+
+ if (!bvp2 || !bvp1)
+ return NULL;
+
+ /* if they are not the same size */
+ /* make them the same size */
+ if (bvp1->size < bvp2->size)
+ bvp1 = bitVectResize (bvp1, bvp2->size);
+ else if (bvp2->size < bvp1->size)
+ bvp2 = bitVectResize (bvp2, bvp1->size);
+
+ elements = bvp1->allocSize;
+
+ p1 = bvp1->vect;
+ p2 = bvp2->vect;
+
+ while (elements--)
+ {
+ *p1 &= *p2;
+ p1++; p2++;
+ }
+
+ return bvp1;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectBitsInCommon - special case of intersection determines */
+/* if the vectors have any common bits set */
+/*-----------------------------------------------------------------*/
+int
+bitVectBitsInCommon (const bitVect * bvp1, const bitVect * bvp2)
+{
+ int elements;
+ unsigned int *p1, *p2;
+
+ if (!bvp1 || !bvp2)
+ return 0;
+
+ elements = min (bvp1->allocSize, bvp2->allocSize);
+
+ p1 = bvp1->vect;
+ p2 = bvp2->vect;
+
+ while (elements--)
+ {
+ if (*p1 & *p2)
+ return 1;
+ p1++; p2++;
+ }
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectCplAnd - complement the second & and it with the first */
+/*-----------------------------------------------------------------*/
+bitVect *
+bitVectCplAnd (bitVect * bvp1, bitVect * bvp2)
+{
+ unsigned int *p1, *p2;
+ int elements;
+
+ if (!bvp2)
+ return bvp1;
+
+ if (!bvp1)
+ return bvp1;
+
+ /* if they are not the same size */
+ /* make them the same size */
+ if (bvp1->size < bvp2->size)
+ bvp1 = bitVectResize (bvp1, bvp2->size);
+ else if (bvp2->size < bvp1->size)
+ bvp2 = bitVectResize (bvp2, bvp1->size);
+
+ elements = bvp1->allocSize;
+ p1 = bvp1->vect;
+ p2 = bvp2->vect;
+
+ while (elements--)
+ {
+ *p1 = *p1 & ~ *p2;
+ p2++; p1++;
+ }
+
+ return bvp1;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectIsZero - bit vector has all bits turned off */
+/*-----------------------------------------------------------------*/
+int
+bitVectIsZero (const bitVect * bvp)
+{
+ int i;
+
+ if (!bvp)
+ return 1;
+
+ for (i = 0; i < bvp->allocSize; i++)
+ if (bvp->vect[i] != 0)
+ return 0;
+
+ return 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectsEqual - returns 1 if the two bit vectors are equal */
+/*-----------------------------------------------------------------*/
+int
+bitVectEqual (bitVect * bvp1, bitVect * bvp2)
+{
+ int i;
+ int elements;
+
+ if (!bvp1 || !bvp2)
+ return 0;
+
+ if (bvp1 == bvp2)
+ return 1;
+
+ /* elements common to both allocations must match */
+ elements = min (bvp1->allocSize, bvp2->allocSize);
+ for (i = 0; i < elements; i++)
+ if (bvp1->vect[i] != bvp2->vect[i])
+ return 0;
+
+ /* any extra elements allocated must be 0 */
+ if (bvp1->allocSize > elements)
+ {
+ for (i = elements; i < bvp1->allocSize; i++)
+ if (bvp1->vect[i])
+ return 0;
+ }
+ if (bvp2->allocSize > elements)
+ {
+ for (i = elements; i < bvp2->allocSize; i++)
+ if (bvp2->vect[i])
+ return 0;
+ }
+
+ return 1;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectCopy - creates a bitvector from another bit Vector */
+/*-----------------------------------------------------------------*/
+bitVect *
+bitVectCopy (const bitVect * bvp)
+{
+ bitVect *newBvp;
+ int i;
+
+ if (!bvp)
+ return NULL;
+
+ newBvp = newBitVect (bvp->size);
+ for (i = 0; i < bvp->allocSize; i++)
+ newBvp->vect[i] = bvp->vect[i];
+
+ return newBvp;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectnBitsOn - returns the number of bits that are on */
+/*-----------------------------------------------------------------*/
+int
+bitVectnBitsOn (const bitVect * bvp)
+{
+ int count = 0;
+ unsigned int *p1;
+ int elements;
+
+ if (!bvp)
+ return 0;
+
+ p1 = bvp->vect;
+ elements = bvp->allocSize;
+
+ while (elements--)
+ {
+ unsigned int word = *p1++;
+ while (word)
+ {
+ count++;
+ word &= word-1;
+ }
+ }
+
+ return count;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectFirstBit - returns the key for the first bit that is on */
+/*-----------------------------------------------------------------*/
+int
+bitVectFirstBit (const bitVect * bvp)
+{
+ int i;
+ int index;
+
+ if (!bvp)
+ return -1;
+
+ for (i = 0, index = 0; i < bvp->size; i+=BIT_SIZEOF_ELEMENT, index++)
+ if (bvp->vect[index])
+ break;
+
+ for (; i < bvp->size; i++)
+ if (bitVectBitValue (bvp, i))
+ return i;
+
+ return -1;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectClear - clear all bits */
+/*-----------------------------------------------------------------*/
+void
+bitVectClear (bitVect *bvp)
+{
+ int i;
+
+ if (!bvp)
+ return;
+
+ for (i = 0; i < bvp->allocSize; i++)
+ bvp->vect[i] = 0;
+}
+
+/*-----------------------------------------------------------------*/
+/* bitVectDebugOn - prints bits that are on */
+/*-----------------------------------------------------------------*/
+void
+bitVectDebugOn (bitVect * bvp, FILE * of)
+{
+ int i;
+
+ if (of == NULL)
+ of = stdout;
+ if (!bvp)
+ return;
+
+ fprintf (of, "bitvector Size = %d allocSize = %d\n", bvp->size, bvp->allocSize);
+ fprintf (of, "Bits on { ");
+ for (i = 0; i < bvp->size; i++)
+ {
+ if (bitVectBitValue (bvp, i))
+ fprintf (of, "(%d) ", i);
+ }
+ fprintf (of, "}\n");
+}
+