/src/binutils-gdb/opcodes/cgen-bitset.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* CGEN generic opcode support. |
2 | | Copyright (C) 2002-2025 Free Software Foundation, Inc. |
3 | | |
4 | | This file is part of libopcodes. |
5 | | |
6 | | This library is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU General Public License as published by |
8 | | the Free Software Foundation; either version 3, or (at your option) |
9 | | any later version. |
10 | | |
11 | | It is distributed in the hope that it will be useful, but WITHOUT |
12 | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
13 | | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
14 | | License for more details. |
15 | | |
16 | | You should have received a copy of the GNU General Public License along |
17 | | with this program; if not, write to the Free Software Foundation, Inc., |
18 | | 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ |
19 | | |
20 | | /* Functions for manipulating CGEN_BITSET. */ |
21 | | |
22 | | #include "libiberty.h" |
23 | | #include "cgen/bitset.h" |
24 | | #include <string.h> |
25 | | |
26 | | /* Create a bit mask. */ |
27 | | |
28 | | CGEN_BITSET * |
29 | | cgen_bitset_create (unsigned bit_count) |
30 | 914 | { |
31 | 914 | CGEN_BITSET * mask = xmalloc (sizeof (* mask)); |
32 | 914 | cgen_bitset_init (mask, bit_count); |
33 | 914 | return mask; |
34 | 914 | } |
35 | | |
36 | | /* Initialize an existing bit mask. */ |
37 | | |
38 | | void |
39 | | cgen_bitset_init (CGEN_BITSET * mask, unsigned bit_count) |
40 | 914 | { |
41 | 914 | if (! mask) |
42 | 0 | return; |
43 | 914 | mask->length = (bit_count / 8) + 1; |
44 | 914 | mask->bits = xmalloc (mask->length); |
45 | 914 | cgen_bitset_clear (mask); |
46 | 914 | } |
47 | | |
48 | | /* Clear the bits of a bit mask. */ |
49 | | |
50 | | void |
51 | | cgen_bitset_clear (CGEN_BITSET * mask) |
52 | 1.82k | { |
53 | 1.82k | unsigned i; |
54 | | |
55 | 1.82k | if (! mask) |
56 | 0 | return; |
57 | | |
58 | 3.64k | for (i = 0; i < mask->length; ++i) |
59 | 1.82k | mask->bits[i] = 0; |
60 | 1.82k | } |
61 | | |
62 | | /* Add a bit to a bit mask. */ |
63 | | |
64 | | void |
65 | | cgen_bitset_add (CGEN_BITSET * mask, unsigned bit_num) |
66 | 906 | { |
67 | 906 | int byte_ix, bit_ix; |
68 | 906 | int bit_mask; |
69 | | |
70 | 906 | if (! mask) |
71 | 0 | return; |
72 | 906 | byte_ix = bit_num / 8; |
73 | 906 | bit_ix = bit_num % 8; |
74 | 906 | bit_mask = 1 << (7 - bit_ix); |
75 | 906 | mask->bits[byte_ix] |= bit_mask; |
76 | 906 | } |
77 | | |
78 | | /* Set a bit mask. */ |
79 | | |
80 | | void |
81 | | cgen_bitset_set (CGEN_BITSET * mask, unsigned bit_num) |
82 | 906 | { |
83 | 906 | if (! mask) |
84 | 0 | return; |
85 | 906 | cgen_bitset_clear (mask); |
86 | 906 | cgen_bitset_add (mask, bit_num); |
87 | 906 | } |
88 | | |
89 | | /* Test for a bit in a bit mask. |
90 | | Returns 1 if the bit is found */ |
91 | | |
92 | | int |
93 | | cgen_bitset_contains (CGEN_BITSET * mask, unsigned bit_num) |
94 | 89 | { |
95 | 89 | int byte_ix, bit_ix; |
96 | 89 | int bit_mask; |
97 | | |
98 | 89 | if (! mask) |
99 | 83 | return 1; /* No bit restrictions. */ |
100 | | |
101 | 6 | byte_ix = bit_num / 8; |
102 | 6 | bit_ix = 7 - (bit_num % 8); |
103 | 6 | bit_mask = 1 << bit_ix; |
104 | 6 | return (mask->bits[byte_ix] & bit_mask) >> bit_ix; |
105 | 89 | } |
106 | | |
107 | | /* Compare two bit masks for equality. |
108 | | Returns 0 if they are equal. */ |
109 | | |
110 | | int |
111 | | cgen_bitset_compare (CGEN_BITSET * mask1, CGEN_BITSET * mask2) |
112 | 5.11M | { |
113 | 5.11M | if (mask1 == mask2) |
114 | 3.84M | return 0; |
115 | 1.27M | if (! mask1 || ! mask2) |
116 | 0 | return 1; |
117 | 1.27M | if (mask1->length != mask2->length) |
118 | 0 | return 1; |
119 | 1.27M | return memcmp (mask1->bits, mask2->bits, mask1->length); |
120 | 1.27M | } |
121 | | |
122 | | /* Test two bit masks for common bits. |
123 | | Returns 1 if a common bit is found. */ |
124 | | |
125 | | int |
126 | | cgen_bitset_intersect_p (CGEN_BITSET * mask1, CGEN_BITSET * mask2) |
127 | 4.02G | { |
128 | 4.02G | unsigned i, limit; |
129 | | |
130 | 4.02G | if (mask1 == mask2) |
131 | 0 | return 1; |
132 | 4.02G | if (! mask1 || ! mask2) |
133 | 70.2M | return 0; |
134 | 3.95G | limit = mask1->length < mask2->length ? mask1->length : mask2->length; |
135 | | |
136 | 5.47G | for (i = 0; i < limit; ++i) |
137 | 3.95G | if ((mask1->bits[i] & mask2->bits[i])) |
138 | 2.43G | return 1; |
139 | | |
140 | 1.51G | return 0; |
141 | 3.95G | } |
142 | | |
143 | | /* Make a copy of a bit mask. */ |
144 | | |
145 | | CGEN_BITSET * |
146 | | cgen_bitset_copy (CGEN_BITSET * mask) |
147 | 102 | { |
148 | 102 | CGEN_BITSET* newmask; |
149 | | |
150 | 102 | if (! mask) |
151 | 96 | return NULL; |
152 | 6 | newmask = cgen_bitset_create ((mask->length * 8) - 1); |
153 | 6 | memcpy (newmask->bits, mask->bits, mask->length); |
154 | 6 | return newmask; |
155 | 102 | } |
156 | | |
157 | | /* Combine two bit masks. */ |
158 | | |
159 | | void |
160 | | cgen_bitset_union (CGEN_BITSET * mask1, CGEN_BITSET * mask2, |
161 | | CGEN_BITSET * result) |
162 | 0 | { |
163 | 0 | unsigned i; |
164 | |
|
165 | 0 | if (! mask1 || ! mask2 || ! result |
166 | 0 | || mask1->length != mask2->length |
167 | 0 | || mask1->length != result->length) |
168 | 0 | return; |
169 | | |
170 | 0 | for (i = 0; i < result->length; ++i) |
171 | 0 | result->bits[i] = mask1->bits[i] | mask2->bits[i]; |
172 | 0 | } |