* device/include/pic16/pic18f*.h: add bit aliases in INTCONbits_t
[fw/sdcc] / src / SDCCbitv.c
index 78b8f287a5fe391a4ae05808c1c2baad8215dd69..987d5bef26575bbca758de62655e4f927bff7870 100644 (file)
@@ -31,325 +31,443 @@ int bitVectDefault = 1024;
 /* genernal note about a bitvectors:
    bit vectors are stored from left to right i.e.
    bit position 0 is the MS bit of the first byte
-   this also means that bit positions must start from 0*/
+   this also means that bit positions must start from 0 */
 /*-----------------------------------------------------------------*/
 /* newBitVect - returns a new bitvector of size                    */
 /*-----------------------------------------------------------------*/
-bitVect *newBitVect (int size)
+bitVect *
+newBitVect (int size)
 {
-    bitVect *bvp;
-    int byteSize ;
+  bitVect *bvp;
+  int byteSize;
 
-    bvp = Safe_calloc(1,sizeof (bitVect));
+  bvp = Safe_calloc (1, sizeof (bitVect));
 
-    bvp->size = size;
-    bvp->bSize = byteSize = ( size / 8) + 1 ;
-    bvp->vect = Safe_calloc(1,byteSize);
-    return bvp;
+  bvp->size = size;
+  bvp->bSize = byteSize = (size / 8) + 1;
+  bvp->vect = Safe_calloc (1, byteSize);
+  return bvp;
 }
 
 /*-----------------------------------------------------------------*/
-/* bitVectResize - changes the size of a bit vector                */
+/* freeBitVect - frees the memory used by the bitVector            */
 /*-----------------------------------------------------------------*/
-bitVect *bitVectResize (bitVect *bvp, int size)
+void
+freeBitVect (bitVect * bvp)
 {
-    int bSize = ( size / 8) + 1  ;
+  if (!bvp)
+    return;
 
-    if (!bvp)
-  return newBitVect (size);
+  Safe_free (bvp->vect);
+  Safe_free (bvp);
+}
 
-    /* if we already have enough space */
-    if (bvp->bSize >= bSize ) {
-  if (size > bvp->size)
-      bvp->size = size ;
-  return bvp;
+/*-----------------------------------------------------------------*/
+/* bitVectResize - changes the size of a bit vector                */
+/*-----------------------------------------------------------------*/
+bitVect *
+bitVectResize (bitVect * bvp, int size)
+{
+  int bSize = (size / 8) + 1;
+
+  if (!bvp)
+    return newBitVect (size);
+
+  /* if we already have enough space */
+  if (bvp->bSize >= bSize)
+    {
+      if (size > bvp->size)
+       bvp->size = size;
+      return bvp;
     }
 
-    bvp->vect = Clear_realloc(bvp->vect, bvp -> bSize, bSize);
-    bvp->size = size;
-    bvp->bSize= bSize;
+  bvp->vect = Clear_realloc (bvp->vect, bvp->bSize, bSize);
+  bvp->size = size;
+  bvp->bSize = bSize;
 
-    return bvp;
+  return bvp;
 }
 
 /*-----------------------------------------------------------------*/
 /* bitVectSetBit - sets a given bit in the bit vector              */
 /*-----------------------------------------------------------------*/
-bitVect *bitVectSetBit (bitVect *bvp, int pos)
+bitVect *
+bitVectSetBit (bitVect * bvp, int pos)
 {
-    int byteSize;
-    int offset ;
+  int byteSize;
+  int offset;
 
-    /* if set is null then allocate it */
-    if (!bvp)
-  bvp = newBitVect(bitVectDefault) ; /* allocate for twice the size */
+  /* 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 */
+  if (bvp->size <= pos)
+    bvp = bitVectResize (bvp, pos + 2);                /* conservatively resize */
 
-    byteSize = pos / 8 ;
-    offset = pos % 8;
-    bvp->vect[byteSize] |= (((unsigned char)1) <<
-          (7 - offset));
-    return bvp;
+  byteSize = pos / 8;
+  offset = pos % 8;
+  bvp->vect[byteSize] |= (((unsigned char) 1) <<
+                         (7 - offset));
+  return bvp;
 }
 
 /*-----------------------------------------------------------------*/
 /* bitVectUnSetBit - unsets the value of a bit in a bitvector      */
 /*-----------------------------------------------------------------*/
-void bitVectUnSetBit (bitVect *bvp, int pos)
+void 
+bitVectUnSetBit (bitVect * bvp, int pos)
 {
-    int byteSize ;
-    int offset ;
+  int byteSize;
+  int offset;
 
-    if (! bvp)
-  return ;
+  if (!bvp)
+    return;
 
-    byteSize = pos /8;
-    if (bvp->bSize <= byteSize)
-  return ;
+  byteSize = pos / 8;
+  if (bvp->bSize <= byteSize)
+    return;
 
-    offset = pos % 8 ;
+  offset = pos % 8;
 
-    bvp->vect[byteSize] &= ~ (((unsigned char)1) <<
-            (7 - offset));
+  bvp->vect[byteSize] &= ~(((unsigned char) 1) <<
+                          (7 - offset));
 }
 
 /*-----------------------------------------------------------------*/
 /* bitVectBitValue - returns value value at bit position           */
 /*-----------------------------------------------------------------*/
-int bitVectBitValue (bitVect *bvp, int pos)
+int 
+bitVectBitValue (bitVect * bvp, int pos)
 {
-    int byteSize;
-    int offset ;
+  int byteSize;
+  int offset;
 
-    if (! bvp)
-  return 0;
+  if (!bvp)
+    return 0;
 
-    byteSize = pos /8;
+  byteSize = pos / 8;
 
-    if ( bvp->bSize <= byteSize )
-  return 0;
+  if (bvp->bSize <= byteSize)
+    return 0;
 
-    offset = pos % 8 ;
+  offset = pos % 8;
 
-    return ((bvp->vect[byteSize] >> (7-offset)) & ((unsigned char)1) );
+  return ((bvp->vect[byteSize] >> (7 - offset)) & ((unsigned char) 1));
 
 }
 
 /*-----------------------------------------------------------------*/
 /* bitVectUnion - unions two bitvectors                            */
 /*-----------------------------------------------------------------*/
-bitVect *bitVectUnion ( bitVect *bvp1, bitVect *bvp2)
+bitVect *
+bitVectUnion (bitVect * bvp1, bitVect * bvp2)
 {
-    int i;
-    bitVect *newBvp;
-
-    /* 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->bSize < bvp2->bSize)
-  bvp1 = bitVectResize (bvp1,bvp2->size);
-    else
-  if (bvp2->bSize < bvp1->bSize)
-      bvp2 = bitVectResize (bvp2,bvp1->size);
-
-    newBvp = newBitVect(bvp1->size);
+  int i;
+  bitVect *newBvp;
+  unsigned int *pn, *p1, *p2;
+  int nbits;
+
+  /* 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->bSize < bvp2->bSize)
+    bvp1 = bitVectResize (bvp1, bvp2->size);
+  else if (bvp2->bSize < bvp1->bSize)
+    bvp2 = bitVectResize (bvp2, bvp1->size);
+
+  newBvp = newBitVect (bvp1->size);
+  nbits = bvp1->bSize;
+  i = 0;
+
+  pn = (unsigned int *)newBvp->vect; 
+  p1 = (unsigned int *)bvp1->vect;
+  p2 = (unsigned int *)bvp2->vect;
+
+  while ((nbits - i) >= sizeof(*pn))
+    {
+      *pn++ = *p1++ | *p2++;
+      i += sizeof(*pn);
+    }
 
-    for ( i = 0 ; i < bvp1->bSize ;i++)
-  newBvp->vect[i] = bvp1->vect[i] | bvp2->vect[i];
+  for (; i < nbits; i++)
+    newBvp->vect[i] = bvp1->vect[i] | bvp2->vect[i];
 
 
-    return newBvp;
+  return newBvp;
 }
 
 /*-----------------------------------------------------------------*/
 /* bitVectIntersect - intersect  two bitvectors                    */
 /*-----------------------------------------------------------------*/
-bitVect *bitVectIntersect ( bitVect *bvp1, bitVect *bvp2)
+bitVect *
+bitVectIntersect (bitVect * bvp1, bitVect * bvp2)
 {
-    int i;
-    bitVect *newBvp;
-
-    if (! bvp2 || ! bvp1 )
-  return NULL ;
-
-    /* if they are not the same size */
-    /* make them the same size */
-    if (bvp1->bSize < bvp2->bSize)
-  bvp1 = bitVectResize (bvp1,bvp2->bSize);
-    else
-  if (bvp2->size < bvp1->size)
-      bvp2 = bitVectResize (bvp2,bvp1->size);
-
-    newBvp = newBitVect(bvp1->size);
+  int i;
+  bitVect *newBvp;
+  unsigned int *pn, *p1, *p2;
+  int nbits;
+
+  if (!bvp2 || !bvp1)
+    return NULL;
+
+  /* if they are not the same size */
+  /* make them the same size */
+  if (bvp1->bSize < bvp2->bSize)
+    bvp1 = bitVectResize (bvp1, bvp2->bSize);
+  else if (bvp2->size < bvp1->size)
+    bvp2 = bitVectResize (bvp2, bvp1->size);
+
+  newBvp = newBitVect (bvp1->size);
+  nbits = bvp1->bSize;
+  i = 0;
+
+  pn = (unsigned int *)newBvp->vect; 
+  p1 = (unsigned int *)bvp1->vect;
+  p2 = (unsigned int *)bvp2->vect;
+
+  while ((nbits - i) >= sizeof(*pn))
+    {
+      *pn++ = *p1++ & *p2++;
+      i += sizeof(*pn);
+    }
 
-    for ( i = 0 ; i < bvp1->bSize ;i++)
-  newBvp->vect[i] = bvp1->vect[i] & bvp2->vect[i];
+  for (; i < nbits; i++)
+    newBvp->vect[i] = bvp1->vect[i] & bvp2->vect[i];
 
-    return newBvp;
+  return newBvp;
 }
 
 /*-----------------------------------------------------------------*/
 /* bitVectBitsInCommon - special case of intersection determines   */
 /*                       if the vectors have any common bits set   */
 /*-----------------------------------------------------------------*/
-int bitVectBitsInCommon ( bitVect *bvp1, bitVect *bvp2 )
+int 
+bitVectBitsInCommon (bitVect * bvp1, bitVect * bvp2)
 {
-    int i ;
+  int i;
+  int nbits;
+  unsigned int *p1, *p2;
 
-    if ( ! bvp1 || ! bvp2 )
-  return 0;
+  if (!bvp1 || !bvp2)
+    return 0;
+
+  nbits = min (bvp1->bSize, bvp2->bSize);
+  i = 0;
+
+  p1 = (unsigned int *)bvp1->vect;
+  p2 = (unsigned int *)bvp2->vect;
+
+  while ((nbits-i) >= sizeof(*p1))
+    {
+      if (*p1 & *p2)
+        return 1;
+      p1++; p2++;
+      i += sizeof(*p1);
+    }
 
-    for ( i = 0 ; i < min(bvp1->bSize,bvp2->bSize) ; i ++ )
-  if ( bvp1->vect[i] & bvp2->vect[i] )
+  for (; i < nbits; i++)
+    if (bvp1->vect[i] & bvp2->vect[i])
       return 1;
 
-    return 0;
+  return 0;
 }
 
 /*-----------------------------------------------------------------*/
 /* bitVectCplAnd - complement the second & and it with the first   */
 /*-----------------------------------------------------------------*/
-bitVect *bitVectCplAnd ( bitVect *bvp1, bitVect *bvp2)
+bitVect *
+bitVectCplAnd (bitVect * bvp1, bitVect * bvp2)
 {
-    int i;
+  int i;
+  unsigned int *p1, *p2;
+  int nbits;
 
-    if ( ! bvp2 )
-  return bvp1 ;
+  if (!bvp2)
+    return bvp1;
 
-    if ( ! bvp1 )
-  return bvp1 ;
+  if (!bvp1)
+    return bvp1;
 
-    /* if they are not the same size */
-    /* make them the same size */
-    if (bvp1->bSize < bvp2->bSize)
-  bvp1 = bitVectResize (bvp1,bvp2->bSize);
-    else
-  if (bvp2->size < bvp1->size)
-      bvp2 = bitVectResize (bvp2,bvp1->size);
+  /* if they are not the same size */
+  /* make them the same size */
+  if (bvp1->bSize < bvp2->bSize)
+    bvp1 = bitVectResize (bvp1, bvp2->bSize);
+  else if (bvp2->size < bvp1->size)
+    bvp2 = bitVectResize (bvp2, bvp1->size);
 
-    for ( i = 0 ; i < bvp1->bSize ;i++)
-  bvp1->vect[i] = bvp1->vect[i] & (~ bvp2->vect[i]);
+  nbits = bvp1->bSize;
+  i = 0;
 
-    return bvp1;
+  p1 = (unsigned int *)bvp1->vect;
+  p2 = (unsigned int *)bvp2->vect;
+
+  while ((nbits - i) >= sizeof(*p1))
+    {
+      *p1 = *p1 & (~*p2);
+      p2++; p1++;
+      i += sizeof(*p1);
+    }
+
+  for (; i < nbits; i++)
+    bvp1->vect[i] = bvp1->vect[i] & (~bvp2->vect[i]);
+
+  return bvp1;
 }
 
 /*-----------------------------------------------------------------*/
 /* bitVectIsZero - bit vector has all bits turned off              */
 /*-----------------------------------------------------------------*/
-int bitVectIsZero (bitVect *bvp)
+int 
+bitVectIsZero (bitVect * bvp)
 {
-    int i ;
+  int i;
 
-    if (!bvp)
-  return 1;
+  if (!bvp)
+    return 1;
 
-    for ( i = 0 ; i < bvp->bSize ; i++ )
-  if (bvp->vect[i] != 0)
+  for (i = 0; i < bvp->bSize; i++)
+    if (bvp->vect[i] != 0)
       return 0;
 
-    return 1;
+  return 1;
 }
 
 /*-----------------------------------------------------------------*/
 /* bitVectsEqual - returns 1 if the two bit vectors are equal      */
 /*-----------------------------------------------------------------*/
-int bitVectEqual ( bitVect *bvp1, bitVect *bvp2)
+int 
+bitVectEqual (bitVect * bvp1, bitVect * bvp2)
 {
-    int i ;
+  int i;
 
-    if ( !bvp1 || !bvp1)
-  return 0;
+  if (!bvp1 || !bvp1)
+    return 0;
 
-    if (bvp1 == bvp2)
-  return 1;
+  if (bvp1 == bvp2)
+    return 1;
 
-    if (bvp1->bSize != bvp2->bSize)
-  return 0;
+  if (bvp1->bSize != bvp2->bSize)
+    return 0;
 
-    for (i = 0 ; i < bvp1->bSize ; i++ )
-  if ( bvp1->vect[i] != bvp2->vect[i] )
+  for (i = 0; i < bvp1->bSize; i++)
+    if (bvp1->vect[i] != bvp2->vect[i])
       return 0;
 
-    return 1;
+  return 1;
 }
 
 /*-----------------------------------------------------------------*/
 /* bitVectCopy - creates a bitvector from another bit Vector       */
 /*-----------------------------------------------------------------*/
-bitVect *bitVectCopy (bitVect *bvp)
+bitVect *
+bitVectCopy (bitVect * bvp)
 {
-    bitVect *newBvp;
-    int i;
+  bitVect *newBvp;
+  int i;
 
-    if (!bvp)
-  return NULL;
+  if (!bvp)
+    return NULL;
 
-    newBvp = newBitVect(bvp->size);
-    for ( i = 0 ; i < bvp->bSize; i++ )
-  newBvp->vect[i] = bvp->vect[i];
+  newBvp = newBitVect (bvp->size);
+  for (i = 0; i < bvp->bSize; i++)
+    newBvp->vect[i] = bvp->vect[i];
 
-    return newBvp;
+  return newBvp;
 }
 
 /*-----------------------------------------------------------------*/
 /* bitVectnBitsOn - returns the number of bits that are on         */
 /*-----------------------------------------------------------------*/
-int bitVectnBitsOn (bitVect *bvp)
+int 
+bitVectnBitsOn (bitVect * bvp)
 {
-    int i, j, k;
-    unsigned char byte;
-    int count = 0 ;
+  int i, j;
+  unsigned char byte;
+  int count = 0;
+  unsigned int *p1;
 
-    if (!bvp)
-  return 0;
+  /* The bit vector is highest to lowest.  Interesting. */
+  unsigned int mask[] = {
+    0, 128, 128+64, 128+64+32, 128+64+32+16,
+    128+64+32+16+8, 128+64+32+16+8+4, 128+64+32+16+8+4+2
+  };
+
+  if (!bvp)
+    return 0;
 
-   /* rip through most of the data in byte sized chunks */
-   j = (bvp->size)/8;
-   for (i = 0 ; i < j; i++) {
-       byte = bvp->vect[i];
-       for (k=0; k<8; k++) { count += byte&1; byte = byte>>1; }
-   }
+  /* j is the number of bytes in the bitvect */
+  j = (bvp->size+7) / 8;
 
-   /* finish up the last fractional byte, if any */
-   for (i = j*8 ; i < bvp->size; i++)
-       count += bitVectBitValue(bvp,i);
+  /* Fix up the highest bits in the top byte so that we can iterate over
+     all of them. */
+  if (bvp->size%8 != 0)
+    {
+      bvp->vect[j-1] &= mask[bvp->size&7];
+    }
 
-   return count;
+  /* Take care of things in machine word chunks if possible.  As we
+     are only counting bits it does not matter which order they are
+     counted in.
+  */
+  i = 0;
+  p1 = (unsigned int *)bvp->vect;
+
+  while ((j-i) >= sizeof(*p1))
+    {
+      unsigned int word = *p1++;
+      while (word)
+        {
+          count++;
+          word &= word-1;
+        }
+      i += sizeof(*p1);
+    }
 
+  /* Take care of the rest of the bitvect. */
+  for (; i < j; i++)
+    {
+      byte = bvp->vect[i];
+      while (byte)
+        {
+          count++;
+          byte &= byte-1;
+        }
+    }
+  return count;
 }
 
 /*-----------------------------------------------------------------*/
 /* bitVectFirstBit - returns the key for the first bit that is on  */
 /*-----------------------------------------------------------------*/
-int bitVectFirstBit (bitVect *bvp)
+int 
+bitVectFirstBit (bitVect * bvp)
 {
-    int i;
+  int i;
 
-    if (!bvp)
-  return -1;
-    for (i = 0; i < bvp->size ; i++ )
-  if (bitVectBitValue(bvp,i))
+  if (!bvp)
+    return -1;
+  for (i = 0; i < bvp->size; i++)
+    if (bitVectBitValue (bvp, i))
       return i;
 
-    return -1;
+  return -1;
 }
 
 /*-----------------------------------------------------------------*/
 /* bitVectDebugOn - prints bits that are on                        */
 /*-----------------------------------------------------------------*/
-void bitVectDebugOn (bitVect *bvp, FILE *of)
+void 
+bitVectDebugOn (bitVect * bvp, FILE * of)
 {
   int i;
 
@@ -358,11 +476,12 @@ void bitVectDebugOn (bitVect *bvp, FILE *of)
   if (!bvp)
     return;
 
-  fprintf(of,"bitvector Size = %d bSize = %d\n",bvp->size,bvp->bSize);
-  fprintf(of,"Bits on { ");
-  for (i = 0 ; i < bvp->size ; i++) {
-    if (bitVectBitValue(bvp,i))
-      fprintf(of,"(%d) ",i);
-  }
-  fprintf(of,"}\n");
+  fprintf (of, "bitvector Size = %d bSize = %d\n", bvp->size, bvp->bSize);
+  fprintf (of, "Bits on { ");
+  for (i = 0; i < bvp->size; i++)
+    {
+      if (bitVectBitValue (bvp, i))
+       fprintf (of, "(%d) ", i);
+    }
+  fprintf (of, "}\n");
 }