// Do not edit. Bootstrap copy of /tmp/go/src/cmd/compile/internal/gc/bv.go

//line /tmp/go/src/cmd/compile/internal/gc/bv.go:1
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gc

import "fmt"

const (
	WORDSIZE  = 4
	WORDBITS  = 32
	WORDMASK  = WORDBITS - 1
	WORDSHIFT = 5
)

// A Bvec is a bit vector.
type Bvec struct {
	n int32    // number of bits in vector
	b []uint32 // words holding bits
}

func bvsize(n uint32) uint32 {
	return ((n + WORDBITS - 1) / WORDBITS) * WORDSIZE
}

func bvbits(bv Bvec) int32 {
	return bv.n
}

func bvwords(bv Bvec) int32 {
	return (bv.n + WORDBITS - 1) / WORDBITS
}

func bvalloc(n int32) Bvec {
	return Bvec{n, make([]uint32, bvsize(uint32(n))/4)}
}

type bulkBvec struct {
	words []uint32
	nbit  int32
	nword int32
}

func bvbulkalloc(nbit int32, count int32) bulkBvec {
	nword := (nbit + WORDBITS - 1) / WORDBITS
	return bulkBvec{
		words: make([]uint32, nword*count),
		nbit:  nbit,
		nword: nword,
	}
}

func (b *bulkBvec) next() Bvec {
	out := Bvec{b.nbit, b.words[:b.nword]}
	b.words = b.words[b.nword:]
	return out
}

/* difference */
func bvandnot(dst Bvec, src1 Bvec, src2 Bvec) {
	for i, x := range src1.b {
		dst.b[i] = x &^ src2.b[i]
	}
}

func bvcmp(bv1 Bvec, bv2 Bvec) int {
	if bv1.n != bv2.n {
		Fatal("bvequal: lengths %d and %d are not equal", bv1.n, bv2.n)
	}
	for i, x := range bv1.b {
		if x != bv2.b[i] {
			return 1
		}
	}
	return 0
}

func bvcopy(dst Bvec, src Bvec) {
	for i, x := range src.b {
		dst.b[i] = x
	}
}

func bvconcat(src1 Bvec, src2 Bvec) Bvec {
	dst := bvalloc(src1.n + src2.n)
	for i := int32(0); i < src1.n; i++ {
		if bvget(src1, i) != 0 {
			bvset(dst, i)
		}
	}
	for i := int32(0); i < src2.n; i++ {
		if bvget(src2, i) != 0 {
			bvset(dst, i+src1.n)
		}
	}
	return dst
}

func bvget(bv Bvec, i int32) int {
	if i < 0 || i >= bv.n {
		Fatal("bvget: index %d is out of bounds with length %d\n", i, bv.n)
	}
	return int((bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK)) & 1)
}

// bvnext returns the smallest index >= i for which bvget(bv, i) == 1.
// If there is no such index, bvnext returns -1.
func bvnext(bv Bvec, i int32) int {
	if i >= bv.n {
		return -1
	}

	// Jump i ahead to next word with bits.
	if bv.b[i>>WORDSHIFT]>>uint(i&WORDMASK) == 0 {
		i &^= WORDMASK
		i += WORDBITS
		for i < bv.n && bv.b[i>>WORDSHIFT] == 0 {
			i += WORDBITS
		}
	}

	if i >= bv.n {
		return -1
	}

	// Find 1 bit.
	w := bv.b[i>>WORDSHIFT] >> uint(i&WORDMASK)

	for w&1 == 0 {
		w >>= 1
		i++
	}

	return int(i)
}

func bvisempty(bv Bvec) bool {
	for i := int32(0); i < bv.n; i += WORDBITS {
		if bv.b[i>>WORDSHIFT] != 0 {
			return false
		}
	}
	return true
}

func bvnot(bv Bvec) {
	i := int32(0)
	w := int32(0)
	for ; i < bv.n; i, w = i+WORDBITS, w+1 {
		bv.b[w] = ^bv.b[w]
	}
}

/* union */
func bvor(dst Bvec, src1 Bvec, src2 Bvec) {
	for i, x := range src1.b {
		dst.b[i] = x | src2.b[i]
	}
}

/* intersection */
func bvand(dst Bvec, src1 Bvec, src2 Bvec) {
	for i, x := range src1.b {
		dst.b[i] = x & src2.b[i]
	}
}

func bvprint(bv Bvec) {
	fmt.Printf("#*")
	for i := int32(0); i < bv.n; i++ {
		fmt.Printf("%d", bvget(bv, i))
	}
}

func bvreset(bv Bvec, i int32) {
	if i < 0 || i >= bv.n {
		Fatal("bvreset: index %d is out of bounds with length %d\n", i, bv.n)
	}
	mask := uint32(^(1 << uint(i%WORDBITS)))
	bv.b[i/WORDBITS] &= mask
}

func bvresetall(bv Bvec) {
	for i := range bv.b {
		bv.b[i] = 0
	}
}

func bvset(bv Bvec, i int32) {
	if i < 0 || i >= bv.n {
		Fatal("bvset: index %d is out of bounds with length %d\n", i, bv.n)
	}
	mask := uint32(1 << uint(i%WORDBITS))
	bv.b[i/WORDBITS] |= mask
}
