github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/cmd/gc/bv.c (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  #include <u.h>
     6  #include <libc.h>
     7  #include "go.h"
     8  
     9  enum {
    10  	WORDSIZE = sizeof(uint32),
    11  	WORDBITS = 32,
    12  	WORDMASK = WORDBITS - 1,
    13  	WORDSHIFT = 5,
    14  };
    15  
    16  static uintptr
    17  bvsize(uintptr n)
    18  {
    19  	return ((n + WORDBITS - 1) / WORDBITS) * WORDSIZE;
    20  }
    21  
    22  int32
    23  bvbits(Bvec *bv)
    24  {
    25  	return bv->n;
    26  }
    27  
    28  int32
    29  bvwords(Bvec *bv)
    30  {
    31  	return (bv->n + WORDBITS - 1) / WORDBITS;
    32  }
    33  
    34  Bvec*
    35  bvalloc(int32 n)
    36  {
    37  	Bvec *bv;
    38  	uintptr nbytes;
    39  
    40  	if(n < 0)
    41  		fatal("bvalloc: initial size is negative\n");
    42  	nbytes = sizeof(Bvec) + bvsize(n);
    43  	bv = malloc(nbytes);
    44  	if(bv == nil)
    45  		fatal("bvalloc: malloc failed\n");
    46  	memset(bv, 0, nbytes);
    47  	bv->n = n;
    48  	return bv;
    49  }
    50  
    51  /* difference */
    52  void
    53  bvandnot(Bvec *dst, Bvec *src1, Bvec *src2)
    54  {
    55  	int32 i, w;
    56  
    57  	if(dst->n != src1->n || dst->n != src2->n)
    58  		fatal("bvand: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n);
    59  	for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++)
    60  		dst->b[w] = src1->b[w] & ~src2->b[w];
    61  }
    62  
    63  int
    64  bvcmp(Bvec *bv1, Bvec *bv2)
    65  {
    66  	uintptr nbytes;
    67  
    68  	if(bv1->n != bv2->n)
    69  		fatal("bvequal: lengths %d and %d are not equal", bv1->n, bv2->n);
    70  	nbytes = bvsize(bv1->n);
    71  	return memcmp(bv1->b, bv2->b, nbytes);
    72  }
    73  
    74  void
    75  bvcopy(Bvec *dst, Bvec *src)
    76  {
    77  	memmove(dst->b, src->b, bvsize(dst->n));
    78  }
    79  
    80  Bvec*
    81  bvconcat(Bvec *src1, Bvec *src2)
    82  {
    83  	Bvec *dst;
    84  	int32 i;
    85  
    86  	dst = bvalloc(src1->n + src2->n);
    87  	for(i = 0; i < src1->n; i++)
    88  		if(bvget(src1, i))
    89  			bvset(dst, i);
    90  	for(i = 0; i < src2->n; i++)
    91  		if(bvget(src2, i))
    92  			bvset(dst, i + src1->n);
    93  	return dst;
    94  }
    95  
    96  int
    97  bvget(Bvec *bv, int32 i)
    98  {
    99  	if(i < 0 || i >= bv->n)
   100  		fatal("bvget: index %d is out of bounds with length %d\n", i, bv->n);
   101  	return (bv->b[i>>WORDSHIFT] >> (i&WORDMASK)) & 1;
   102  }
   103  
   104  // bvnext returns the smallest index >= i for which bvget(bv, i) == 1.
   105  // If there is no such index, bvnext returns -1.
   106  int
   107  bvnext(Bvec *bv, int32 i)
   108  {
   109  	uint32 w;
   110  
   111  	if(i >= bv->n)
   112  		return -1;
   113  
   114  	// Jump i ahead to next word with bits.
   115  	if((bv->b[i>>WORDSHIFT]>>(i&WORDMASK)) == 0) {
   116  		i &= ~WORDMASK;
   117  		i += WORDBITS;
   118  		while(i < bv->n && bv->b[i>>WORDSHIFT] == 0)
   119  			i += WORDBITS;
   120  	}
   121  	if(i >= bv->n)
   122  		return -1;
   123  
   124  	// Find 1 bit.
   125  	w = bv->b[i>>WORDSHIFT]>>(i&WORDMASK);
   126  	while((w&1) == 0) {
   127  		w>>=1;
   128  		i++;
   129  	}
   130  	return i;
   131  }
   132  
   133  int
   134  bvisempty(Bvec *bv)
   135  {
   136  	int32 i;
   137  
   138  	for(i = 0; i < bv->n; i += WORDBITS)
   139  		if(bv->b[i>>WORDSHIFT] != 0)
   140  			return 0;
   141  	return 1;
   142  }
   143  
   144  void
   145  bvnot(Bvec *bv)
   146  {
   147  	int32 i, w;
   148  
   149  	for(i = 0, w = 0; i < bv->n; i += WORDBITS, w++)
   150  		bv->b[w] = ~bv->b[w];
   151  }
   152  
   153  /* union */
   154  void
   155  bvor(Bvec *dst, Bvec *src1, Bvec *src2)
   156  {
   157  	int32 i, w;
   158  
   159  	if(dst->n != src1->n || dst->n != src2->n)
   160  		fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n);
   161  	for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++)
   162  		dst->b[w] = src1->b[w] | src2->b[w];
   163  }
   164  
   165  /* intersection */
   166  void
   167  bvand(Bvec *dst, Bvec *src1, Bvec *src2)
   168  {
   169  	int32 i, w;
   170  
   171  	if(dst->n != src1->n || dst->n != src2->n)
   172  		fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n);
   173  	for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++)
   174  		dst->b[w] = src1->b[w] & src2->b[w];
   175  }
   176  
   177  void
   178  bvprint(Bvec *bv)
   179  {
   180  	int32 i;
   181  
   182  	print("#*");
   183  	for(i = 0; i < bv->n; i++)
   184  		print("%d", bvget(bv, i));
   185  }
   186  
   187  void
   188  bvreset(Bvec *bv, int32 i)
   189  {
   190  	uint32 mask;
   191  
   192  	if(i < 0 || i >= bv->n)
   193  		fatal("bvreset: index %d is out of bounds with length %d\n", i, bv->n);
   194  	mask = ~(1 << (i % WORDBITS));
   195  	bv->b[i / WORDBITS] &= mask;
   196  }
   197  
   198  void
   199  bvresetall(Bvec *bv)
   200  {
   201  	memset(bv->b, 0x00, bvsize(bv->n));
   202  }
   203  
   204  void
   205  bvset(Bvec *bv, int32 i)
   206  {
   207  	uint32 mask;
   208  
   209  	if(i < 0 || i >= bv->n)
   210  		fatal("bvset: index %d is out of bounds with length %d\n", i, bv->n);
   211  	mask = 1U << (i % WORDBITS);
   212  	bv->b[i / WORDBITS] |= mask;
   213  }