github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/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  };
    13  
    14  static uintptr
    15  bvsize(uintptr n)
    16  {
    17  	return ((n + WORDBITS - 1) / WORDBITS) * WORDSIZE;
    18  }
    19  
    20  int32
    21  bvbits(Bvec *bv)
    22  {
    23  	return bv->n;
    24  }
    25  
    26  int32
    27  bvwords(Bvec *bv)
    28  {
    29  	return (bv->n + WORDBITS - 1) / WORDBITS;
    30  }
    31  
    32  Bvec*
    33  bvalloc(int32 n)
    34  {
    35  	Bvec *bv;
    36  	uintptr nbytes;
    37  
    38  	if(n < 0)
    39  		fatal("bvalloc: initial size is negative\n");
    40  	nbytes = sizeof(Bvec) + bvsize(n);
    41  	bv = malloc(nbytes);
    42  	if(bv == nil)
    43  		fatal("bvalloc: malloc failed\n");
    44  	memset(bv, 0, nbytes);
    45  	bv->n = n;
    46  	return bv;
    47  }
    48  
    49  /* difference */
    50  void
    51  bvandnot(Bvec *dst, Bvec *src1, Bvec *src2)
    52  {
    53  	int32 i, w;
    54  
    55  	if(dst->n != src1->n || dst->n != src2->n)
    56  		fatal("bvand: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n);
    57  	for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++)
    58  		dst->b[w] = src1->b[w] & ~src2->b[w];
    59  }
    60  
    61  int
    62  bvcmp(Bvec *bv1, Bvec *bv2)
    63  {
    64  	uintptr nbytes;
    65  
    66  	if(bv1->n != bv2->n)
    67  		fatal("bvequal: lengths %d and %d are not equal", bv1->n, bv2->n);
    68  	nbytes = bvsize(bv1->n);
    69  	return memcmp(bv1->b, bv2->b, nbytes);
    70  }
    71  
    72  void
    73  bvcopy(Bvec *dst, Bvec *src)
    74  {
    75  	memmove(dst->b, src->b, bvsize(dst->n));
    76  }
    77  
    78  Bvec*
    79  bvconcat(Bvec *src1, Bvec *src2)
    80  {
    81  	Bvec *dst;
    82  	int32 i;
    83  
    84  	dst = bvalloc(src1->n + src2->n);
    85  	for(i = 0; i < src1->n; i++)
    86  		if(bvget(src1, i))
    87  			bvset(dst, i);
    88  	for(i = 0; i < src2->n; i++)
    89  		if(bvget(src2, i))
    90  			bvset(dst, i + src1->n);
    91  	return dst;
    92  }
    93  
    94  int
    95  bvget(Bvec *bv, int32 i)
    96  {
    97  	uint32 mask, word;
    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  	mask = 1U << (i % WORDBITS);
   102  	word = bv->b[i / WORDBITS] & mask;
   103  	return word ? 1 : 0;
   104  }
   105  
   106  int
   107  bvisempty(Bvec *bv)
   108  {
   109  	int32 i;
   110  
   111  	for(i = 0; i < bv->n; i += WORDBITS)
   112  		if(bv->b[i / WORDBITS] != 0)
   113  			return 0;
   114  	return 1;
   115  }
   116  
   117  void
   118  bvnot(Bvec *bv)
   119  {
   120  	int32 i, w;
   121  
   122  	for(i = 0, w = 0; i < bv->n; i += WORDBITS, w++)
   123  		bv->b[w] = ~bv->b[w];
   124  }
   125  
   126  /* union */
   127  void
   128  bvor(Bvec *dst, Bvec *src1, Bvec *src2)
   129  {
   130  	int32 i, w;
   131  
   132  	if(dst->n != src1->n || dst->n != src2->n)
   133  		fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n);
   134  	for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++)
   135  		dst->b[w] = src1->b[w] | src2->b[w];
   136  }
   137  
   138  /* intersection */
   139  void
   140  bvand(Bvec *dst, Bvec *src1, Bvec *src2)
   141  {
   142  	int32 i, w;
   143  
   144  	if(dst->n != src1->n || dst->n != src2->n)
   145  		fatal("bvor: lengths %d, %d, and %d are not equal", dst->n, src1->n, src2->n);
   146  	for(i = 0, w = 0; i < dst->n; i += WORDBITS, w++)
   147  		dst->b[w] = src1->b[w] & src2->b[w];
   148  }
   149  
   150  void
   151  bvprint(Bvec *bv)
   152  {
   153  	int32 i;
   154  
   155  	print("#*");
   156  	for(i = 0; i < bv->n; i++)
   157  		print("%d", bvget(bv, i));
   158  }
   159  
   160  void
   161  bvreset(Bvec *bv, int32 i)
   162  {
   163  	uint32 mask;
   164  
   165  	if(i < 0 || i >= bv->n)
   166  		fatal("bvreset: index %d is out of bounds with length %d\n", i, bv->n);
   167  	mask = ~(1 << (i % WORDBITS));
   168  	bv->b[i / WORDBITS] &= mask;
   169  }
   170  
   171  void
   172  bvresetall(Bvec *bv)
   173  {
   174  	memset(bv->b, 0x00, bvsize(bv->n));
   175  }
   176  
   177  void
   178  bvset(Bvec *bv, int32 i)
   179  {
   180  	uint32 mask;
   181  
   182  	if(i < 0 || i >= bv->n)
   183  		fatal("bvset: index %d is out of bounds with length %d\n", i, bv->n);
   184  	mask = 1U << (i % WORDBITS);
   185  	bv->b[i / WORDBITS] |= mask;
   186  }