summaryrefslogtreecommitdiff
path: root/vendor/github.com/mmcloughlin/avo/reg/set.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mmcloughlin/avo/reg/set.go')
-rw-r--r--vendor/github.com/mmcloughlin/avo/reg/set.go112
1 files changed, 112 insertions, 0 deletions
diff --git a/vendor/github.com/mmcloughlin/avo/reg/set.go b/vendor/github.com/mmcloughlin/avo/reg/set.go
new file mode 100644
index 0000000..2cf8814
--- /dev/null
+++ b/vendor/github.com/mmcloughlin/avo/reg/set.go
@@ -0,0 +1,112 @@
+package reg
+
+// MaskSet maps register IDs to masks.
+type MaskSet map[ID]uint16
+
+// NewEmptyMaskSet builds an empty register mask set.
+func NewEmptyMaskSet() MaskSet {
+ return MaskSet{}
+}
+
+// NewMaskSetFromRegisters forms a mask set from the given register list.
+func NewMaskSetFromRegisters(rs []Register) MaskSet {
+ s := NewEmptyMaskSet()
+ for _, r := range rs {
+ s.AddRegister(r)
+ }
+ return s
+}
+
+// Clone returns a copy of s.
+func (s MaskSet) Clone() MaskSet {
+ c := NewEmptyMaskSet()
+ for id, mask := range s {
+ c.Add(id, mask)
+ }
+ return c
+}
+
+// Add mask to the given register ID.
+// Reports whether this made any change to the set.
+func (s MaskSet) Add(id ID, mask uint16) bool {
+ if (s[id] & mask) == mask {
+ return false
+ }
+ s[id] |= mask
+ return true
+}
+
+// AddRegister is a convenience for adding the register's (ID, mask) to the set.
+// Reports whether this made any change to the set.
+func (s MaskSet) AddRegister(r Register) bool {
+ return s.Add(r.ID(), r.Mask())
+}
+
+// Discard clears masked bits from register ID.
+// Reports whether this made any change to the set.
+func (s MaskSet) Discard(id ID, mask uint16) bool {
+ if curr, found := s[id]; !found || (curr&mask) == 0 {
+ return false
+ }
+ s[id] &^= mask
+ if s[id] == 0 {
+ delete(s, id)
+ }
+ return true
+}
+
+// DiscardRegister is a convenience for discarding the register's (ID, mask) from the set.
+// Reports whether this made any change to the set.
+func (s MaskSet) DiscardRegister(r Register) bool {
+ return s.Discard(r.ID(), r.Mask())
+}
+
+// Update adds masks in t to s.
+// Reports whether this made any change to the set.
+func (s MaskSet) Update(t MaskSet) bool {
+ change := false
+ for id, mask := range t {
+ change = s.Add(id, mask) || change
+ }
+ return change
+}
+
+// Difference returns the set of registers in s but not t.
+func (s MaskSet) Difference(t MaskSet) MaskSet {
+ d := s.Clone()
+ d.DifferenceUpdate(t)
+ return d
+}
+
+// DifferenceUpdate removes every element of t from s.
+func (s MaskSet) DifferenceUpdate(t MaskSet) bool {
+ change := false
+ for id, mask := range t {
+ change = s.Discard(id, mask) || change
+ }
+ return change
+}
+
+// Equals returns true if s and t contain the same masks.
+func (s MaskSet) Equals(t MaskSet) bool {
+ if len(s) != len(t) {
+ return false
+ }
+ for id, mask := range s {
+ if _, found := t[id]; !found || mask != t[id] {
+ return false
+ }
+ }
+ return true
+}
+
+// OfKind returns the set of elements of s with kind k.
+func (s MaskSet) OfKind(k Kind) MaskSet {
+ t := NewEmptyMaskSet()
+ for id, mask := range s {
+ if id.Kind() == k {
+ t.Add(id, mask)
+ }
+ }
+ return t
+}