diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /src/SDCCbitv.c | |
| download | sdcc-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.c | 541 |
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"); +} + |
