blob: 7cdf87865fe539505ee8003803927123d0b274fd [file] [log] [blame]
bartbedfd232009-03-26 19:07:15 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
sewardjaf44c822007-11-25 14:01:38 +00002/*
bart86562bd2009-02-16 19:43:56 +00003 This file is part of drd, a thread error detector.
sewardjaf44c822007-11-25 14:01:38 +00004
bart86562bd2009-02-16 19:43:56 +00005 Copyright (C) 2006-2009 Bart Van Assche <bart.vanassche@gmail.com>.
sewardjaf44c822007-11-25 14:01:38 +00006
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307, USA.
21
22 The GNU General Public License is contained in the file COPYING.
23*/
24
25
bart39934d62009-02-15 16:18:03 +000026#include "drd_basics.h" /* DRD_() */
sewardjaf44c822007-11-25 14:01:38 +000027#include "drd_bitmap.h"
28#include "drd_error.h"
29#include "drd_suppression.h"
bart39934d62009-02-15 16:18:03 +000030#include "pub_drd_bitmap.h"
31#include "pub_tool_basics.h" /* Addr, SizeT */
32#include "pub_tool_debuginfo.h" /* VG_(get_objname)() */
33#include "pub_tool_libcassert.h" /* tl_assert() */
34#include "pub_tool_libcbase.h" /* VG_(memset) */
35#include "pub_tool_libcprint.h" /* VG_(printf) */
36#include "pub_tool_machine.h" /* VG_(get_IP)() */
37#include "pub_tool_mallocfree.h" /* VG_(malloc), VG_(free) */
sewardjaf44c822007-11-25 14:01:38 +000038
39
bartf647d342008-03-24 19:12:12 +000040/* Local function declarations. */
sewardjaf44c822007-11-25 14:01:38 +000041
42static void bm2_merge(struct bitmap2* const bm2l,
43 const struct bitmap2* const bm2r);
bart7b706b32009-05-10 06:55:39 +000044static void bm2_print(const struct bitmap2* const bm2);
sewardjaf44c822007-11-25 14:01:38 +000045
46
bart99edb292009-02-15 15:59:20 +000047/* Local variables. */
bartf647d342008-03-24 19:12:12 +000048
49static ULong s_bitmap_creation_count;
bart7b706b32009-05-10 06:55:39 +000050static ULong s_bitmap_merge_count;
51static ULong s_bitmap2_merge_count;
bartf647d342008-03-24 19:12:12 +000052
53
54/* Function definitions. */
sewardjaf44c822007-11-25 14:01:38 +000055
bart99edb292009-02-15 15:59:20 +000056struct bitmap* DRD_(bm_new)()
sewardjaf44c822007-11-25 14:01:38 +000057{
bartbedfd232009-03-26 19:07:15 +000058 struct bitmap* bm;
sewardjaf44c822007-11-25 14:01:38 +000059
bartbedfd232009-03-26 19:07:15 +000060 /* If this assert fails, fix the definition of BITS_PER_BITS_PER_UWORD */
61 /* in drd_bitmap.h. */
62 tl_assert((1 << BITS_PER_BITS_PER_UWORD) == BITS_PER_UWORD);
sewardjaf44c822007-11-25 14:01:38 +000063
bartbedfd232009-03-26 19:07:15 +000064 bm = VG_(malloc)("drd.bitmap.bn.1", sizeof(*bm));
bart8f822af2009-06-08 18:20:42 +000065 DRD_(bm_init)(bm);
sewardjaf44c822007-11-25 14:01:38 +000066
bartbedfd232009-03-26 19:07:15 +000067 return bm;
sewardjaf44c822007-11-25 14:01:38 +000068}
69
bart99edb292009-02-15 15:59:20 +000070void DRD_(bm_delete)(struct bitmap* const bm)
sewardjaf44c822007-11-25 14:01:38 +000071{
bartbedfd232009-03-26 19:07:15 +000072 tl_assert(bm);
bartf647d342008-03-24 19:12:12 +000073
bart8f822af2009-06-08 18:20:42 +000074 DRD_(bm_cleanup)(bm);
bartbedfd232009-03-26 19:07:15 +000075 VG_(free)(bm);
sewardjaf44c822007-11-25 14:01:38 +000076}
77
bart8f822af2009-06-08 18:20:42 +000078/** Initialize *bm. */
79void DRD_(bm_init)(struct bitmap* const bm)
80{
81 unsigned i;
82
83 tl_assert(bm);
bart9f617a82009-06-21 18:08:31 +000084 /*
85 * Cache initialization. a1 is initialized with a value that never can
bart8f822af2009-06-08 18:20:42 +000086 * match any valid address: the upper (ADDR_LSB_BITS + ADDR_IGNORED_BITS)
87 * bits of a1 are always zero for a valid cache entry.
88 */
89 for (i = 0; i < DRD_BITMAP_N_CACHE_ELEM; i++)
90 {
91 bm->cache[i].a1 = ~(UWord)1;
92 bm->cache[i].bm2 = 0;
93 }
bart6584b692009-06-21 10:11:15 +000094 bm->oset = VG_(OSetGen_Create)(0, 0, DRD_(bm2_alloc_node),
95 "drd.bitmap.bn.2", DRD_(bm2_free_node));
bart9f617a82009-06-21 18:08:31 +000096
97 s_bitmap_creation_count++;
bart8f822af2009-06-08 18:20:42 +000098}
99
100/** Free the memory allocated by DRD_(bm_init)(). */
101void DRD_(bm_cleanup)(struct bitmap* const bm)
102{
103 VG_(OSetGen_Destroy)(bm->oset);
104}
105
sewardjaf44c822007-11-25 14:01:38 +0000106/**
bart36556122008-03-13 19:24:30 +0000107 * Record an access of type access_type at addresses a .. a + size - 1 in
sewardjaf44c822007-11-25 14:01:38 +0000108 * bitmap bm.
bart7b706b32009-05-10 06:55:39 +0000109 *
110 * @note The current implementation of bm_access_range does not work for the
111 * highest addresses in the address range. At least on Linux this is
112 * not a problem since the upper part of the address space is reserved
113 * for the kernel.
sewardjaf44c822007-11-25 14:01:38 +0000114 */
bart99edb292009-02-15 15:59:20 +0000115void DRD_(bm_access_range)(struct bitmap* const bm,
116 const Addr a1, const Addr a2,
117 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000118{
barte6e86c52009-04-25 06:53:00 +0000119 tl_assert(access_type == eLoad || access_type == eStore);
120
121 if (access_type == eLoad)
122 return DRD_(bm_access_range_load)(bm, a1, a2);
123 else
124 return DRD_(bm_access_range_store)(bm, a1, a2);
125}
126
bart7b706b32009-05-10 06:55:39 +0000127void DRD_(bm_access_range_load)(struct bitmap* const bm, Addr a1, Addr a2)
barte6e86c52009-04-25 06:53:00 +0000128{
bartbedfd232009-03-26 19:07:15 +0000129 Addr b, b_next;
bart36556122008-03-13 19:24:30 +0000130
bartbedfd232009-03-26 19:07:15 +0000131 tl_assert(bm);
132 tl_assert(a1 < a2);
bart7b706b32009-05-10 06:55:39 +0000133 tl_assert(a2 < first_address_with_higher_msb(a2));
134 tl_assert(a1 == first_address_with_same_lsb(a1));
135 tl_assert(a2 == first_address_with_same_lsb(a2));
sewardjaf44c822007-11-25 14:01:38 +0000136
bartbedfd232009-03-26 19:07:15 +0000137 for (b = a1; b < a2; b = b_next)
138 {
139 Addr b_start;
140 Addr b_end;
141 struct bitmap2* bm2;
bart7b706b32009-05-10 06:55:39 +0000142 UWord b0;
bart36556122008-03-13 19:24:30 +0000143
bart7b706b32009-05-10 06:55:39 +0000144 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000145 if (b_next > a2)
146 {
147 b_next = a2;
148 }
bart36556122008-03-13 19:24:30 +0000149
bart7b706b32009-05-10 06:55:39 +0000150 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(b));
bartbedfd232009-03-26 19:07:15 +0000151 tl_assert(bm2);
bart36556122008-03-13 19:24:30 +0000152
bart7b706b32009-05-10 06:55:39 +0000153 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000154 b_start = a1;
bart36556122008-03-13 19:24:30 +0000155 else
bart7b706b32009-05-10 06:55:39 +0000156 if (make_address(bm2->addr, 0) < a2)
157 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000158 else
159 break;
bart36556122008-03-13 19:24:30 +0000160
bart7b706b32009-05-10 06:55:39 +0000161 if (make_address(bm2->addr + 1, 0) < a2)
162 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000163 else
164 b_end = a2;
bartf43b1772009-04-25 08:08:33 +0000165
166 tl_assert(a1 <= b_start && b_start < b_end && b_end && b_end <= a2);
bart7b706b32009-05-10 06:55:39 +0000167 tl_assert(address_msb(b_start) == address_msb(b_end - 1));
168 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bartf43b1772009-04-25 08:08:33 +0000169
bart7b706b32009-05-10 06:55:39 +0000170 if (address_lsb(b_start) == 0 && address_lsb(b_end) == 0)
bart36556122008-03-13 19:24:30 +0000171 {
bartf43b1772009-04-25 08:08:33 +0000172 unsigned k;
173
174 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
175 {
176 bm2->bm1.bm0_r[k] = ~(UWord)0;
177 }
178 }
179 else
180 {
bart7b706b32009-05-10 06:55:39 +0000181 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartf43b1772009-04-25 08:08:33 +0000182 {
183 bm0_set(bm2->bm1.bm0_r, b0);
184 }
bart3772a982008-03-15 08:11:03 +0000185 }
bartbedfd232009-03-26 19:07:15 +0000186 }
sewardjaf44c822007-11-25 14:01:38 +0000187}
188
bart99edb292009-02-15 15:59:20 +0000189void DRD_(bm_access_load_1)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000190{
bartbedfd232009-03-26 19:07:15 +0000191 bm_access_aligned_load(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000192}
193
bart99edb292009-02-15 15:59:20 +0000194void DRD_(bm_access_load_2)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000195{
bartbedfd232009-03-26 19:07:15 +0000196 if ((a1 & 1) == 0)
197 bm_access_aligned_load(bm, a1, 2);
198 else
199 DRD_(bm_access_range)(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000200}
201
bart99edb292009-02-15 15:59:20 +0000202void DRD_(bm_access_load_4)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000203{
bartbedfd232009-03-26 19:07:15 +0000204 if ((a1 & 3) == 0)
205 bm_access_aligned_load(bm, a1, 4);
206 else
207 DRD_(bm_access_range)(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000208}
209
bart99edb292009-02-15 15:59:20 +0000210void DRD_(bm_access_load_8)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000211{
bartbedfd232009-03-26 19:07:15 +0000212 if ((a1 & 7) == 0)
213 bm_access_aligned_load(bm, a1, 8);
214 else if ((a1 & 3) == 0)
215 {
216 bm_access_aligned_load(bm, a1 + 0, 4);
217 bm_access_aligned_load(bm, a1 + 4, 4);
218 }
219 else
220 DRD_(bm_access_range)(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000221}
222
bart99edb292009-02-15 15:59:20 +0000223void DRD_(bm_access_range_store)(struct bitmap* const bm,
224 const Addr a1, const Addr a2)
bartf5acbbc2008-05-10 08:22:20 +0000225{
barte6e86c52009-04-25 06:53:00 +0000226 Addr b, b_next;
227
228 tl_assert(bm);
229 tl_assert(a1 < a2);
bart7b706b32009-05-10 06:55:39 +0000230 tl_assert(a2 < first_address_with_higher_msb(a2));
231 tl_assert(a1 == first_address_with_same_lsb(a1));
232 tl_assert(a2 == first_address_with_same_lsb(a2));
barte6e86c52009-04-25 06:53:00 +0000233
234 for (b = a1; b < a2; b = b_next)
235 {
236 Addr b_start;
237 Addr b_end;
238 struct bitmap2* bm2;
bart7b706b32009-05-10 06:55:39 +0000239 UWord b0;
barte6e86c52009-04-25 06:53:00 +0000240
bart7b706b32009-05-10 06:55:39 +0000241 b_next = first_address_with_higher_msb(b);
barte6e86c52009-04-25 06:53:00 +0000242 if (b_next > a2)
243 {
244 b_next = a2;
245 }
246
bart7b706b32009-05-10 06:55:39 +0000247 bm2 = bm2_lookup_or_insert_exclusive(bm, address_msb(b));
barte6e86c52009-04-25 06:53:00 +0000248 tl_assert(bm2);
249
bart7b706b32009-05-10 06:55:39 +0000250 if (make_address(bm2->addr, 0) < a1)
barte6e86c52009-04-25 06:53:00 +0000251 b_start = a1;
252 else
bart7b706b32009-05-10 06:55:39 +0000253 if (make_address(bm2->addr, 0) < a2)
254 b_start = make_address(bm2->addr, 0);
barte6e86c52009-04-25 06:53:00 +0000255 else
256 break;
barte6e86c52009-04-25 06:53:00 +0000257
bart7b706b32009-05-10 06:55:39 +0000258 if (make_address(bm2->addr + 1, 0) < a2)
259 b_end = make_address(bm2->addr + 1, 0);
barte6e86c52009-04-25 06:53:00 +0000260 else
261 b_end = a2;
bartf43b1772009-04-25 08:08:33 +0000262
263 tl_assert(a1 <= b_start && b_start < b_end && b_end && b_end <= a2);
bart7b706b32009-05-10 06:55:39 +0000264 tl_assert(address_msb(b_start) == address_msb(b_end - 1));
265 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bartf43b1772009-04-25 08:08:33 +0000266
bart7b706b32009-05-10 06:55:39 +0000267 if (address_lsb(b_start) == 0 && address_lsb(b_end) == 0)
barte6e86c52009-04-25 06:53:00 +0000268 {
bartf43b1772009-04-25 08:08:33 +0000269 unsigned k;
270
271 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
272 {
273 bm2->bm1.bm0_w[k] = ~(UWord)0;
274 }
275 }
276 else
277 {
bart7b706b32009-05-10 06:55:39 +0000278 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartf43b1772009-04-25 08:08:33 +0000279 {
280 bm0_set(bm2->bm1.bm0_w, b0);
281 }
barte6e86c52009-04-25 06:53:00 +0000282 }
283 }
bartf5acbbc2008-05-10 08:22:20 +0000284}
285
bart99edb292009-02-15 15:59:20 +0000286void DRD_(bm_access_store_1)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000287{
bartbedfd232009-03-26 19:07:15 +0000288 bm_access_aligned_store(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000289}
290
bart99edb292009-02-15 15:59:20 +0000291void DRD_(bm_access_store_2)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000292{
bartbedfd232009-03-26 19:07:15 +0000293 if ((a1 & 1) == 0)
294 bm_access_aligned_store(bm, a1, 2);
295 else
296 DRD_(bm_access_range)(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000297}
298
bart99edb292009-02-15 15:59:20 +0000299void DRD_(bm_access_store_4)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000300{
bartbedfd232009-03-26 19:07:15 +0000301 if ((a1 & 3) == 0)
302 bm_access_aligned_store(bm, a1, 4);
303 else
304 DRD_(bm_access_range)(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000305}
306
bart99edb292009-02-15 15:59:20 +0000307void DRD_(bm_access_store_8)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000308{
bartbedfd232009-03-26 19:07:15 +0000309 if ((a1 & 7) == 0)
310 bm_access_aligned_store(bm, a1, 8);
311 else if ((a1 & 3) == 0)
312 {
313 bm_access_aligned_store(bm, a1 + 0, 4);
314 bm_access_aligned_store(bm, a1 + 4, 4);
315 }
316 else
317 DRD_(bm_access_range)(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000318}
319
bart99edb292009-02-15 15:59:20 +0000320Bool DRD_(bm_has)(struct bitmap* const bm, const Addr a1, const Addr a2,
321 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000322{
bartda3a77b2009-04-23 20:07:23 +0000323 tl_assert(access_type == eLoad || access_type == eStore);
bartda3a77b2009-04-23 20:07:23 +0000324
325 if (access_type == eLoad)
326 return DRD_(bm_has_any_load)(bm, a1, a2);
327 else
328 return DRD_(bm_has_any_store)(bm, a1, a2);
sewardjaf44c822007-11-25 14:01:38 +0000329}
330
bart99edb292009-02-15 15:59:20 +0000331Bool
332DRD_(bm_has_any_load)(struct bitmap* const bm, const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000333{
bartbedfd232009-03-26 19:07:15 +0000334 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000335
bartbedfd232009-03-26 19:07:15 +0000336 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000337
bartbedfd232009-03-26 19:07:15 +0000338 for (b = a1; b < a2; b = b_next)
339 {
bart7b706b32009-05-10 06:55:39 +0000340 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
bartd4907072008-03-30 18:41:07 +0000341
bart7b706b32009-05-10 06:55:39 +0000342 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000343 if (b_next > a2)
bartd4907072008-03-30 18:41:07 +0000344 {
bartbedfd232009-03-26 19:07:15 +0000345 b_next = a2;
bartd4907072008-03-30 18:41:07 +0000346 }
bartbedfd232009-03-26 19:07:15 +0000347
348 if (bm2)
349 {
350 Addr b_start;
351 Addr b_end;
352 UWord b0;
353 const struct bitmap1* const p1 = &bm2->bm1;
354
bart7b706b32009-05-10 06:55:39 +0000355 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000356 b_start = a1;
357 else
bart7b706b32009-05-10 06:55:39 +0000358 if (make_address(bm2->addr, 0) < a2)
359 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000360 else
361 break;
362 tl_assert(a1 <= b_start && b_start <= a2);
363
bart7b706b32009-05-10 06:55:39 +0000364 if (make_address(bm2->addr + 1, 0) < a2)
365 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000366 else
367 b_end = a2;
368 tl_assert(a1 <= b_end && b_end <= a2);
369 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000370 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bart31b983d2010-02-21 14:52:59 +0000371
bart7b706b32009-05-10 06:55:39 +0000372 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000373 {
374 if (bm0_is_set(p1->bm0_r, b0))
375 {
376 return True;
377 }
378 }
379 }
380 }
381 return 0;
bartd4907072008-03-30 18:41:07 +0000382}
383
bart99edb292009-02-15 15:59:20 +0000384Bool DRD_(bm_has_any_store)(struct bitmap* const bm,
385 const Addr a1, const Addr a2)
bartd4907072008-03-30 18:41:07 +0000386{
bartbedfd232009-03-26 19:07:15 +0000387 Addr b, b_next;
bartd4907072008-03-30 18:41:07 +0000388
bartbedfd232009-03-26 19:07:15 +0000389 tl_assert(bm);
bartd4907072008-03-30 18:41:07 +0000390
bartbedfd232009-03-26 19:07:15 +0000391 for (b = a1; b < a2; b = b_next)
392 {
bart7b706b32009-05-10 06:55:39 +0000393 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
bartd4907072008-03-30 18:41:07 +0000394
bart7b706b32009-05-10 06:55:39 +0000395 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000396 if (b_next > a2)
bartd4907072008-03-30 18:41:07 +0000397 {
bartbedfd232009-03-26 19:07:15 +0000398 b_next = a2;
bartd4907072008-03-30 18:41:07 +0000399 }
bartbedfd232009-03-26 19:07:15 +0000400
401 if (bm2)
402 {
403 Addr b_start;
404 Addr b_end;
405 UWord b0;
406 const struct bitmap1* const p1 = &bm2->bm1;
407
bart7b706b32009-05-10 06:55:39 +0000408 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000409 b_start = a1;
410 else
bart7b706b32009-05-10 06:55:39 +0000411 if (make_address(bm2->addr, 0) < a2)
412 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000413 else
414 break;
415 tl_assert(a1 <= b_start && b_start <= a2);
416
bart7b706b32009-05-10 06:55:39 +0000417 if (make_address(bm2->addr + 1, 0) < a2)
418 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000419 else
420 b_end = a2;
421 tl_assert(a1 <= b_end && b_end <= a2);
422 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000423 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bart31b983d2010-02-21 14:52:59 +0000424
bart7b706b32009-05-10 06:55:39 +0000425 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000426 {
427 if (bm0_is_set(p1->bm0_w, b0))
428 {
429 return True;
430 }
431 }
432 }
433 }
434 return 0;
sewardjaf44c822007-11-25 14:01:38 +0000435}
436
bartc2c81db2008-05-10 11:19:10 +0000437/* Return True if there is a read access, write access or both */
438/* to any of the addresses in the range [ a1, a2 [ in bitmap bm. */
bart99edb292009-02-15 15:59:20 +0000439Bool DRD_(bm_has_any_access)(struct bitmap* const bm,
440 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000441{
bartbedfd232009-03-26 19:07:15 +0000442 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000443
bartbedfd232009-03-26 19:07:15 +0000444 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000445
bartbedfd232009-03-26 19:07:15 +0000446 for (b = a1; b < a2; b = b_next)
447 {
bart7b706b32009-05-10 06:55:39 +0000448 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
sewardjaf44c822007-11-25 14:01:38 +0000449
bart7b706b32009-05-10 06:55:39 +0000450 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000451 if (b_next > a2)
bart3772a982008-03-15 08:11:03 +0000452 {
bartbedfd232009-03-26 19:07:15 +0000453 b_next = a2;
sewardjaf44c822007-11-25 14:01:38 +0000454 }
bartbedfd232009-03-26 19:07:15 +0000455
456 if (bm2)
457 {
458 Addr b_start;
459 Addr b_end;
460 UWord b0;
461 const struct bitmap1* const p1 = &bm2->bm1;
462
bart7b706b32009-05-10 06:55:39 +0000463 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000464 b_start = a1;
465 else
bart7b706b32009-05-10 06:55:39 +0000466 if (make_address(bm2->addr, 0) < a2)
467 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000468 else
469 break;
470 tl_assert(a1 <= b_start && b_start <= a2);
471
bart7b706b32009-05-10 06:55:39 +0000472 if (make_address(bm2->addr + 1, 0) < a2)
473 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000474 else
475 b_end = a2;
476 tl_assert(a1 <= b_end && b_end <= a2);
477 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000478 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bart31b983d2010-02-21 14:52:59 +0000479
bart7b706b32009-05-10 06:55:39 +0000480 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000481 {
bart8f822af2009-06-08 18:20:42 +0000482 /*
483 * Note: the statement below uses a binary or instead of a logical
484 * or on purpose.
485 */
bartbedfd232009-03-26 19:07:15 +0000486 if (bm0_is_set(p1->bm0_r, b0) | bm0_is_set(p1->bm0_w, b0))
487 {
488 return True;
489 }
490 }
491 }
492 }
493 return False;
sewardjaf44c822007-11-25 14:01:38 +0000494}
495
bart99edb292009-02-15 15:59:20 +0000496/**
497 * Report whether an access of type access_type at address a is recorded in
498 * bitmap bm.
sewardjaf44c822007-11-25 14:01:38 +0000499 */
bart99edb292009-02-15 15:59:20 +0000500Bool DRD_(bm_has_1)(struct bitmap* const bm,
501 const Addr a, const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000502{
bartbedfd232009-03-26 19:07:15 +0000503 const struct bitmap2* p2;
504 const struct bitmap1* p1;
505 const UWord* p0;
bart7b706b32009-05-10 06:55:39 +0000506 const UWord a0 = address_lsb(a);
sewardjaf44c822007-11-25 14:01:38 +0000507
bartbedfd232009-03-26 19:07:15 +0000508 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000509
bart7b706b32009-05-10 06:55:39 +0000510 p2 = bm2_lookup(bm, address_msb(a));
bartbedfd232009-03-26 19:07:15 +0000511 if (p2)
512 {
513 p1 = &p2->bm1;
514 p0 = (access_type == eLoad) ? p1->bm0_r : p1->bm0_w;
515 return bm0_is_set(p0, a0) ? True : False;
516 }
517 return False;
sewardjaf44c822007-11-25 14:01:38 +0000518}
519
bart7b706b32009-05-10 06:55:39 +0000520void DRD_(bm_clear)(struct bitmap* const bm, Addr a1, Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000521{
bartbedfd232009-03-26 19:07:15 +0000522 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000523
bartbedfd232009-03-26 19:07:15 +0000524 tl_assert(bm);
525 tl_assert(a1);
526 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000527 tl_assert(a1 == first_address_with_same_lsb(a1));
528 tl_assert(a2 == first_address_with_same_lsb(a2));
sewardjaf44c822007-11-25 14:01:38 +0000529
bartbedfd232009-03-26 19:07:15 +0000530 for (b = a1; b < a2; b = b_next)
531 {
bart578eeb42009-04-23 15:42:27 +0000532 struct bitmap2* p2;
533 Addr c;
534
535#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
536 tl_assert(a1 <= b && b < a2);
537#endif
538
bart7b706b32009-05-10 06:55:39 +0000539 p2 = bm2_lookup_exclusive(bm, address_msb(b));
sewardjaf44c822007-11-25 14:01:38 +0000540
bart7b706b32009-05-10 06:55:39 +0000541 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000542 if (b_next > a2)
sewardjaf44c822007-11-25 14:01:38 +0000543 {
bartbedfd232009-03-26 19:07:15 +0000544 b_next = a2;
sewardjaf44c822007-11-25 14:01:38 +0000545 }
bartbedfd232009-03-26 19:07:15 +0000546
barte2c7e672009-04-23 19:23:09 +0000547 if (p2 == 0)
548 continue;
549
bart578eeb42009-04-23 15:42:27 +0000550 c = b;
551 /* If the first address in the bitmap that must be cleared does not */
552 /* start on an UWord boundary, start clearing the first addresses. */
bart7b706b32009-05-10 06:55:39 +0000553 if (uword_lsb(address_lsb(c)))
sewardjaf44c822007-11-25 14:01:38 +0000554 {
bart7b706b32009-05-10 06:55:39 +0000555 Addr c_next = first_address_with_higher_uword_msb(c);
bart25a439a2009-04-24 14:49:50 +0000556 if (c_next > b_next)
557 c_next = b_next;
558#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
559 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
560 && b_next <= a2);
561#endif
bart7b706b32009-05-10 06:55:39 +0000562 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(c_next - c));
563 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(c_next - c));
bart25a439a2009-04-24 14:49:50 +0000564 c = c_next;
bart578eeb42009-04-23 15:42:27 +0000565 }
566 /* If some UWords have to be cleared entirely, do this now. */
bart7b706b32009-05-10 06:55:39 +0000567 if (uword_lsb(address_lsb(c)) == 0)
bart578eeb42009-04-23 15:42:27 +0000568 {
bart7b706b32009-05-10 06:55:39 +0000569 Addr c_next = first_address_with_same_uword_lsb(b_next);
bart578eeb42009-04-23 15:42:27 +0000570#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart7b706b32009-05-10 06:55:39 +0000571 tl_assert(uword_lsb(address_lsb(c)) == 0);
572 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
bart25a439a2009-04-24 14:49:50 +0000573 tl_assert(c_next <= b_next);
bart578eeb42009-04-23 15:42:27 +0000574#endif
bart25a439a2009-04-24 14:49:50 +0000575 if (c_next > c)
576 {
bart7b706b32009-05-10 06:55:39 +0000577 UWord idx = uword_msb(address_lsb(c));
578 VG_(memset)(&p2->bm1.bm0_r[idx], 0, SCALED_SIZE((c_next - c) / 8));
579 VG_(memset)(&p2->bm1.bm0_w[idx], 0, SCALED_SIZE((c_next - c) / 8));
bart25a439a2009-04-24 14:49:50 +0000580 c = c_next;
581 }
bart578eeb42009-04-23 15:42:27 +0000582 }
583 /* If the last address in the bitmap that must be cleared does not */
584 /* fall on an UWord boundary, clear the last addresses. */
bart25a439a2009-04-24 14:49:50 +0000585#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
586 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
587#endif
bart7b706b32009-05-10 06:55:39 +0000588 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(b_next - c));
589 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(b_next - c));
bartbedfd232009-03-26 19:07:15 +0000590 }
sewardjaf44c822007-11-25 14:01:38 +0000591}
sewardjaf44c822007-11-25 14:01:38 +0000592
bart99edb292009-02-15 15:59:20 +0000593/**
594 * Clear all references to loads in bitmap bm starting at address a1 and
595 * up to but not including address a2.
bart9c4224c2008-03-29 14:40:08 +0000596 */
bart7b706b32009-05-10 06:55:39 +0000597void DRD_(bm_clear_load)(struct bitmap* const bm, Addr a1, Addr a2)
bart9c4224c2008-03-29 14:40:08 +0000598{
bart578eeb42009-04-23 15:42:27 +0000599 Addr b, b_next;
bart9c4224c2008-03-29 14:40:08 +0000600
bart578eeb42009-04-23 15:42:27 +0000601 tl_assert(bm);
602 tl_assert(a1);
603 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000604 tl_assert(a1 == first_address_with_same_lsb(a1));
605 tl_assert(a2 == first_address_with_same_lsb(a2));
bart578eeb42009-04-23 15:42:27 +0000606
607 for (b = a1; b < a2; b = b_next)
bartbedfd232009-03-26 19:07:15 +0000608 {
bart578eeb42009-04-23 15:42:27 +0000609 struct bitmap2* p2;
610 Addr c;
611
612#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
613 tl_assert(a1 <= b && b < a2);
614#endif
615
bart7b706b32009-05-10 06:55:39 +0000616 p2 = bm2_lookup_exclusive(bm, address_msb(b));
bart578eeb42009-04-23 15:42:27 +0000617
bart7b706b32009-05-10 06:55:39 +0000618 b_next = first_address_with_higher_msb(b);
bart578eeb42009-04-23 15:42:27 +0000619 if (b_next > a2)
bartbedfd232009-03-26 19:07:15 +0000620 {
bart578eeb42009-04-23 15:42:27 +0000621 b_next = a2;
622 }
623
barte2c7e672009-04-23 19:23:09 +0000624 if (p2 == 0)
625 continue;
626
bart578eeb42009-04-23 15:42:27 +0000627 c = b;
628 /* If the first address in the bitmap that must be cleared does not */
629 /* start on an UWord boundary, start clearing the first addresses. */
630#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
631 tl_assert(a1 <= b && b <= c && c < b_next && b_next <= a2);
632#endif
bart7b706b32009-05-10 06:55:39 +0000633 if (uword_lsb(address_lsb(c)))
bart578eeb42009-04-23 15:42:27 +0000634 {
bart7b706b32009-05-10 06:55:39 +0000635 Addr c_next = first_address_with_higher_uword_msb(c);
bart25a439a2009-04-24 14:49:50 +0000636 if (c_next > b_next)
637 c_next = b_next;
bart578eeb42009-04-23 15:42:27 +0000638#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart25a439a2009-04-24 14:49:50 +0000639 tl_assert(a1 <= b && b <= c && c < c_next && c_next <= b_next
640 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000641#endif
bart7b706b32009-05-10 06:55:39 +0000642 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(c_next - c));
bart25a439a2009-04-24 14:49:50 +0000643 c = c_next;
bart578eeb42009-04-23 15:42:27 +0000644 }
645 /* If some UWords have to be cleared entirely, do this now. */
646#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
647 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
648#endif
bart7b706b32009-05-10 06:55:39 +0000649 if (uword_lsb(address_lsb(c)) == 0)
bart578eeb42009-04-23 15:42:27 +0000650 {
bart7b706b32009-05-10 06:55:39 +0000651 Addr c_next = first_address_with_same_uword_lsb(b_next);
bart578eeb42009-04-23 15:42:27 +0000652#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart7b706b32009-05-10 06:55:39 +0000653 tl_assert(uword_lsb(address_lsb(c)) == 0);
654 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
bart25a439a2009-04-24 14:49:50 +0000655 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
656 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000657#endif
bart25a439a2009-04-24 14:49:50 +0000658 if (c_next > c)
659 {
bart7b706b32009-05-10 06:55:39 +0000660 UWord idx = uword_msb(address_lsb(c));
661 VG_(memset)(&p2->bm1.bm0_r[idx], 0, SCALED_SIZE((c_next - c) / 8));
bart25a439a2009-04-24 14:49:50 +0000662 c = c_next;
663 }
bart578eeb42009-04-23 15:42:27 +0000664 }
665 /* If the last address in the bitmap that must be cleared does not */
666 /* fall on an UWord boundary, clear the last addresses. */
667#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
668 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
669#endif
bart7b706b32009-05-10 06:55:39 +0000670 bm0_clear_range(p2->bm1.bm0_r, address_lsb(c), SCALED_SIZE(b_next - c));
bartbedfd232009-03-26 19:07:15 +0000671 }
bart9c4224c2008-03-29 14:40:08 +0000672}
673
bart99edb292009-02-15 15:59:20 +0000674/**
675 * Clear all references to stores in bitmap bm starting at address a1 and
676 * up to but not including address a2.
bart9c4224c2008-03-29 14:40:08 +0000677 */
bart99edb292009-02-15 15:59:20 +0000678void DRD_(bm_clear_store)(struct bitmap* const bm,
679 const Addr a1, const Addr a2)
bart9c4224c2008-03-29 14:40:08 +0000680{
bart578eeb42009-04-23 15:42:27 +0000681 Addr b, b_next;
bart9c4224c2008-03-29 14:40:08 +0000682
bart578eeb42009-04-23 15:42:27 +0000683 tl_assert(bm);
684 tl_assert(a1);
685 tl_assert(a1 <= a2);
bart7b706b32009-05-10 06:55:39 +0000686 tl_assert(a1 == first_address_with_same_lsb(a1));
687 tl_assert(a2 == first_address_with_same_lsb(a2));
bart578eeb42009-04-23 15:42:27 +0000688
689 for (b = a1; b < a2; b = b_next)
bartbedfd232009-03-26 19:07:15 +0000690 {
bart578eeb42009-04-23 15:42:27 +0000691 struct bitmap2* p2;
692 Addr c;
693
694#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
695 tl_assert(a1 <= b && b < a2);
696#endif
697
bart7b706b32009-05-10 06:55:39 +0000698 p2 = bm2_lookup_exclusive(bm, address_msb(b));
bart578eeb42009-04-23 15:42:27 +0000699
bart7b706b32009-05-10 06:55:39 +0000700 b_next = first_address_with_higher_msb(b);
bart578eeb42009-04-23 15:42:27 +0000701 if (b_next > a2)
bartbedfd232009-03-26 19:07:15 +0000702 {
barte6e86c52009-04-25 06:53:00 +0000703 b_next = a2;
bart578eeb42009-04-23 15:42:27 +0000704 }
705
barte2c7e672009-04-23 19:23:09 +0000706 if (p2 == 0)
707 continue;
708
bart578eeb42009-04-23 15:42:27 +0000709 c = b;
710 /* If the first address in the bitmap that must be cleared does not */
711 /* start on an UWord boundary, start clearing the first addresses. */
712#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
713 tl_assert(a1 <= b && b <= c && c < b_next && b_next <= a2);
714#endif
bart7b706b32009-05-10 06:55:39 +0000715 if (uword_lsb(address_lsb(c)))
bart578eeb42009-04-23 15:42:27 +0000716 {
bart7b706b32009-05-10 06:55:39 +0000717 Addr c_next = first_address_with_higher_uword_msb(c);
barte6e86c52009-04-25 06:53:00 +0000718 if (c_next > b_next)
719 c_next = b_next;
bart578eeb42009-04-23 15:42:27 +0000720#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
barte6e86c52009-04-25 06:53:00 +0000721 tl_assert(a1 <= b && b <= c && c < c_next && c_next <= b_next
722 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000723#endif
bart7b706b32009-05-10 06:55:39 +0000724 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(c_next - c));
barte6e86c52009-04-25 06:53:00 +0000725 c = c_next;
bart578eeb42009-04-23 15:42:27 +0000726 }
727 /* If some UWords have to be cleared entirely, do this now. */
728#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
729 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
730#endif
bart7b706b32009-05-10 06:55:39 +0000731 if (uword_lsb(address_lsb(c)) == 0)
bart578eeb42009-04-23 15:42:27 +0000732 {
bart7b706b32009-05-10 06:55:39 +0000733 Addr c_next = first_address_with_same_uword_lsb(b_next);
bart578eeb42009-04-23 15:42:27 +0000734#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
bart7b706b32009-05-10 06:55:39 +0000735 tl_assert(uword_lsb(address_lsb(c)) == 0);
736 tl_assert(uword_lsb(address_lsb(c_next)) == 0);
barte6e86c52009-04-25 06:53:00 +0000737 tl_assert(a1 <= b && b <= c && c <= c_next && c_next <= b_next
738 && b_next <= a2);
bart578eeb42009-04-23 15:42:27 +0000739#endif
barte6e86c52009-04-25 06:53:00 +0000740 if (c_next > c)
741 {
bart7b706b32009-05-10 06:55:39 +0000742 UWord idx = uword_msb(address_lsb(c));
743 VG_(memset)(&p2->bm1.bm0_w[idx], 0, SCALED_SIZE((c_next - c) / 8));
barte6e86c52009-04-25 06:53:00 +0000744 c = c_next;
745 }
bart578eeb42009-04-23 15:42:27 +0000746 }
747 /* If the last address in the bitmap that must be cleared does not */
748 /* fall on an UWord boundary, clear the last addresses. */
749#ifdef ENABLE_DRD_CONSISTENCY_CHECKS
750 tl_assert(a1 <= b && b <= c && c <= b_next && b_next <= a2);
751#endif
bart7b706b32009-05-10 06:55:39 +0000752 bm0_clear_range(p2->bm1.bm0_w, address_lsb(c), SCALED_SIZE(b_next - c));
bartbedfd232009-03-26 19:07:15 +0000753 }
bart9c4224c2008-03-29 14:40:08 +0000754}
755
bart99edb292009-02-15 15:59:20 +0000756/**
757 * Clear bitmap bm starting at address a1 and up to but not including address
758 * a2. Return True if and only if any of the addresses was set before
759 * clearing.
bart8bf2f8b2008-03-30 17:56:43 +0000760 */
bart99edb292009-02-15 15:59:20 +0000761Bool DRD_(bm_test_and_clear)(struct bitmap* const bm,
762 const Addr a1, const Addr a2)
bart8bf2f8b2008-03-30 17:56:43 +0000763{
bartbedfd232009-03-26 19:07:15 +0000764 Bool result;
bart8bf2f8b2008-03-30 17:56:43 +0000765
bartbedfd232009-03-26 19:07:15 +0000766 result = DRD_(bm_has_any_access)(bm, a1, a2) != 0;
767 DRD_(bm_clear)(bm, a1, a2);
768 return result;
bart8bf2f8b2008-03-30 17:56:43 +0000769}
770
bart99edb292009-02-15 15:59:20 +0000771Bool DRD_(bm_has_conflict_with)(struct bitmap* const bm,
772 const Addr a1, const Addr a2,
773 const BmAccessTypeT access_type)
sewardjaf44c822007-11-25 14:01:38 +0000774{
bartbedfd232009-03-26 19:07:15 +0000775 Addr b, b_next;
sewardjaf44c822007-11-25 14:01:38 +0000776
bartbedfd232009-03-26 19:07:15 +0000777 tl_assert(bm);
sewardjaf44c822007-11-25 14:01:38 +0000778
bartbedfd232009-03-26 19:07:15 +0000779 for (b = a1; b < a2; b = b_next)
780 {
bart7b706b32009-05-10 06:55:39 +0000781 const struct bitmap2* bm2 = bm2_lookup(bm, address_msb(b));
bart36556122008-03-13 19:24:30 +0000782
bart7b706b32009-05-10 06:55:39 +0000783 b_next = first_address_with_higher_msb(b);
bartbedfd232009-03-26 19:07:15 +0000784 if (b_next > a2)
bart3772a982008-03-15 08:11:03 +0000785 {
bartbedfd232009-03-26 19:07:15 +0000786 b_next = a2;
sewardjaf44c822007-11-25 14:01:38 +0000787 }
bartbedfd232009-03-26 19:07:15 +0000788
789 if (bm2)
790 {
791 Addr b_start;
792 Addr b_end;
793 UWord b0;
794 const struct bitmap1* const p1 = &bm2->bm1;
795
bart7b706b32009-05-10 06:55:39 +0000796 if (make_address(bm2->addr, 0) < a1)
bartbedfd232009-03-26 19:07:15 +0000797 b_start = a1;
798 else
bart7b706b32009-05-10 06:55:39 +0000799 if (make_address(bm2->addr, 0) < a2)
800 b_start = make_address(bm2->addr, 0);
bartbedfd232009-03-26 19:07:15 +0000801 else
802 break;
803 tl_assert(a1 <= b_start && b_start <= a2);
804
bart7b706b32009-05-10 06:55:39 +0000805 if (make_address(bm2->addr + 1, 0) < a2)
806 b_end = make_address(bm2->addr + 1, 0);
bartbedfd232009-03-26 19:07:15 +0000807 else
808 b_end = a2;
809 tl_assert(a1 <= b_end && b_end <= a2);
810 tl_assert(b_start < b_end);
bart7b706b32009-05-10 06:55:39 +0000811 tl_assert(address_lsb(b_start) <= address_lsb(b_end - 1));
bart31b983d2010-02-21 14:52:59 +0000812
bart7b706b32009-05-10 06:55:39 +0000813 for (b0 = address_lsb(b_start); b0 <= address_lsb(b_end - 1); b0++)
bartbedfd232009-03-26 19:07:15 +0000814 {
815 if (access_type == eLoad)
816 {
817 if (bm0_is_set(p1->bm0_w, b0))
818 {
819 return True;
820 }
821 }
822 else
823 {
824 tl_assert(access_type == eStore);
825 if (bm0_is_set(p1->bm0_r, b0)
826 | bm0_is_set(p1->bm0_w, b0))
827 {
828 return True;
829 }
830 }
831 }
832 }
833 }
834 return False;
sewardjaf44c822007-11-25 14:01:38 +0000835}
836
bart99edb292009-02-15 15:59:20 +0000837Bool DRD_(bm_load_has_conflict_with)(struct bitmap* const bm,
838 const Addr a1, const Addr a2)
sewardjaf44c822007-11-25 14:01:38 +0000839{
bartbedfd232009-03-26 19:07:15 +0000840 return DRD_(bm_has_conflict_with)(bm, a1, a2, eLoad);
bart36556122008-03-13 19:24:30 +0000841}
842
bart99edb292009-02-15 15:59:20 +0000843Bool DRD_(bm_load_1_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000844{
bartbedfd232009-03-26 19:07:15 +0000845 return bm_aligned_load_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000846}
847
bart99edb292009-02-15 15:59:20 +0000848Bool DRD_(bm_load_2_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000849{
bartbedfd232009-03-26 19:07:15 +0000850 if ((a1 & 1) == 0)
851 return bm_aligned_load_has_conflict_with(bm, a1, 2);
852 else
853 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 2, eLoad);
barta79df6e2008-03-14 17:07:51 +0000854}
855
bart99edb292009-02-15 15:59:20 +0000856Bool DRD_(bm_load_4_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000857{
bartbedfd232009-03-26 19:07:15 +0000858 if ((a1 & 3) == 0)
859 return bm_aligned_load_has_conflict_with(bm, a1, 4);
860 else
861 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 4, eLoad);
barta79df6e2008-03-14 17:07:51 +0000862}
863
bart99edb292009-02-15 15:59:20 +0000864Bool DRD_(bm_load_8_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000865{
bartbedfd232009-03-26 19:07:15 +0000866 if ((a1 & 7) == 0)
867 return bm_aligned_load_has_conflict_with(bm, a1, 8);
868 else
869 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 8, eLoad);
barta79df6e2008-03-14 17:07:51 +0000870}
871
bart99edb292009-02-15 15:59:20 +0000872Bool DRD_(bm_store_1_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000873{
bartbedfd232009-03-26 19:07:15 +0000874 return bm_aligned_store_has_conflict_with(bm, a1, 1);
barta79df6e2008-03-14 17:07:51 +0000875}
876
bart99edb292009-02-15 15:59:20 +0000877Bool DRD_(bm_store_2_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000878{
bartbedfd232009-03-26 19:07:15 +0000879 if ((a1 & 1) == 0)
880 return bm_aligned_store_has_conflict_with(bm, a1, 2);
881 else
882 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 2, eStore);
barta79df6e2008-03-14 17:07:51 +0000883}
884
bart99edb292009-02-15 15:59:20 +0000885Bool DRD_(bm_store_4_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000886{
bartbedfd232009-03-26 19:07:15 +0000887 if ((a1 & 3) == 0)
888 return bm_aligned_store_has_conflict_with(bm, a1, 4);
889 else
890 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 4, eStore);
barta79df6e2008-03-14 17:07:51 +0000891}
892
bart99edb292009-02-15 15:59:20 +0000893Bool DRD_(bm_store_8_has_conflict_with)(struct bitmap* const bm, const Addr a1)
barta79df6e2008-03-14 17:07:51 +0000894{
bartbedfd232009-03-26 19:07:15 +0000895 if ((a1 & 7) == 0)
896 return bm_aligned_store_has_conflict_with(bm, a1, 8);
897 else
898 return DRD_(bm_has_conflict_with)(bm, a1, a1 + 8, eStore);
barta79df6e2008-03-14 17:07:51 +0000899}
900
bart99edb292009-02-15 15:59:20 +0000901Bool DRD_(bm_store_has_conflict_with)(struct bitmap* const bm,
902 const Addr a1, const Addr a2)
bart36556122008-03-13 19:24:30 +0000903{
bartbedfd232009-03-26 19:07:15 +0000904 return DRD_(bm_has_conflict_with)(bm, a1, a2, eStore);
sewardjaf44c822007-11-25 14:01:38 +0000905}
906
bart99edb292009-02-15 15:59:20 +0000907/**
908 * Return True if the two bitmaps *lhs and *rhs are identical, and false
909 * if not.
bart7cd7d7f2008-04-14 16:10:01 +0000910 */
bart99edb292009-02-15 15:59:20 +0000911Bool DRD_(bm_equal)(struct bitmap* const lhs, struct bitmap* const rhs)
bart7cd7d7f2008-04-14 16:10:01 +0000912{
bartbedfd232009-03-26 19:07:15 +0000913 struct bitmap2* bm2l;
bartbedfd232009-03-26 19:07:15 +0000914 struct bitmap2* bm2r;
bart7cd7d7f2008-04-14 16:10:01 +0000915
bartbedfd232009-03-26 19:07:15 +0000916 /* It's not possible to have two independent iterators over the same OSet, */
917 /* so complain if lhs == rhs. */
918 tl_assert(lhs != rhs);
barta3f61092008-05-04 07:46:20 +0000919
bartbedfd232009-03-26 19:07:15 +0000920 VG_(OSetGen_ResetIter)(lhs->oset);
921 VG_(OSetGen_ResetIter)(rhs->oset);
bart7cd7d7f2008-04-14 16:10:01 +0000922
bart7b706b32009-05-10 06:55:39 +0000923 for ( ; (bm2l = VG_(OSetGen_Next)(lhs->oset)) != 0; )
bartbedfd232009-03-26 19:07:15 +0000924 {
bart7b706b32009-05-10 06:55:39 +0000925 while (bm2l
bartbedfd232009-03-26 19:07:15 +0000926 && ! DRD_(bm_has_any_access)(lhs,
bart7b706b32009-05-10 06:55:39 +0000927 make_address(bm2l->addr, 0),
928 make_address(bm2l->addr + 1, 0)))
bartbedfd232009-03-26 19:07:15 +0000929 {
bart7b706b32009-05-10 06:55:39 +0000930 bm2l = VG_(OSetGen_Next)(lhs->oset);
bartbedfd232009-03-26 19:07:15 +0000931 }
bart7b706b32009-05-10 06:55:39 +0000932 if (bm2l == 0)
bartbedfd232009-03-26 19:07:15 +0000933 break;
934 tl_assert(bm2l);
barta3f61092008-05-04 07:46:20 +0000935
bartb634b5d2009-04-26 14:42:33 +0000936 do
bartbedfd232009-03-26 19:07:15 +0000937 {
bart7b706b32009-05-10 06:55:39 +0000938 bm2r = VG_(OSetGen_Next)(rhs->oset);
939 if (bm2r == 0)
bartb634b5d2009-04-26 14:42:33 +0000940 return False;
bartbedfd232009-03-26 19:07:15 +0000941 }
bartb634b5d2009-04-26 14:42:33 +0000942 while (! DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +0000943 make_address(bm2r->addr, 0),
944 make_address(bm2r->addr + 1, 0)));
bartb634b5d2009-04-26 14:42:33 +0000945
bartbedfd232009-03-26 19:07:15 +0000946 tl_assert(bm2r);
947 tl_assert(DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +0000948 make_address(bm2r->addr, 0),
949 make_address(bm2r->addr + 1, 0)));
barta3f61092008-05-04 07:46:20 +0000950
bartbedfd232009-03-26 19:07:15 +0000951 if (bm2l != bm2r
952 && (bm2l->addr != bm2r->addr
953 || VG_(memcmp)(&bm2l->bm1, &bm2r->bm1, sizeof(bm2l->bm1)) != 0))
954 {
bartbedfd232009-03-26 19:07:15 +0000955 return False;
956 }
957 }
bartb634b5d2009-04-26 14:42:33 +0000958
959 do
960 {
961 bm2r = VG_(OSetGen_Next)(rhs->oset);
962 } while (bm2r && ! DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +0000963 make_address(bm2r->addr, 0),
964 make_address(bm2r->addr + 1, 0)));
bartbedfd232009-03-26 19:07:15 +0000965 if (bm2r)
966 {
967 tl_assert(DRD_(bm_has_any_access)(rhs,
bart7b706b32009-05-10 06:55:39 +0000968 make_address(bm2r->addr, 0),
969 make_address(bm2r->addr + 1, 0)));
bart7cd7d7f2008-04-14 16:10:01 +0000970 return False;
bartbedfd232009-03-26 19:07:15 +0000971 }
972 return True;
bart7cd7d7f2008-04-14 16:10:01 +0000973}
974
bart99edb292009-02-15 15:59:20 +0000975void DRD_(bm_swap)(struct bitmap* const bm1, struct bitmap* const bm2)
sewardjaf44c822007-11-25 14:01:38 +0000976{
bartbedfd232009-03-26 19:07:15 +0000977 OSet* const tmp = bm1->oset;
978 bm1->oset = bm2->oset;
979 bm2->oset = tmp;
sewardjaf44c822007-11-25 14:01:38 +0000980}
981
bartf647d342008-03-24 19:12:12 +0000982/** Merge bitmaps *lhs and *rhs into *lhs. */
bart8f822af2009-06-08 18:20:42 +0000983void DRD_(bm_merge2)(struct bitmap* const lhs, struct bitmap* const rhs)
sewardjaf44c822007-11-25 14:01:38 +0000984{
bartbedfd232009-03-26 19:07:15 +0000985 struct bitmap2* bm2l;
bartbedfd232009-03-26 19:07:15 +0000986 struct bitmap2* bm2r;
bart7b706b32009-05-10 06:55:39 +0000987
bart8f822af2009-06-08 18:20:42 +0000988 /*
989 * It's not possible to have two independent iterators over the same OSet,
990 * so complain if lhs == rhs.
991 */
bart7b706b32009-05-10 06:55:39 +0000992 tl_assert(lhs != rhs);
993
994 s_bitmap_merge_count++;
sewardjaf44c822007-11-25 14:01:38 +0000995
bartbedfd232009-03-26 19:07:15 +0000996 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +0000997
bart7b706b32009-05-10 06:55:39 +0000998 for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
bartbedfd232009-03-26 19:07:15 +0000999 {
bart7b706b32009-05-10 06:55:39 +00001000 bm2l = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
1001 if (bm2l)
bartf647d342008-03-24 19:12:12 +00001002 {
bart7b706b32009-05-10 06:55:39 +00001003 tl_assert(bm2l != bm2r);
1004 bm2_merge(bm2l, bm2r);
bartf647d342008-03-24 19:12:12 +00001005 }
bartbedfd232009-03-26 19:07:15 +00001006 else
1007 {
bart7b706b32009-05-10 06:55:39 +00001008 bm2_insert_copy(lhs, bm2r);
bartbedfd232009-03-26 19:07:15 +00001009 }
1010 }
sewardjaf44c822007-11-25 14:01:38 +00001011}
1012
bart8f822af2009-06-08 18:20:42 +00001013/** Clear bitmap2::recalc. */
1014void DRD_(bm_unmark)(struct bitmap* bm)
1015{
1016 struct bitmap2* bm2;
1017
1018 for (VG_(OSetGen_ResetIter)(bm->oset);
1019 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1020 )
1021 {
1022 bm2->recalc = False;
1023 }
1024}
1025
1026/**
1027 * Report whether bitmap2::recalc has been set for the second level bitmap
1028 * corresponding to address a.
1029 */
1030Bool DRD_(bm_is_marked)(struct bitmap* bm, const Addr a)
1031{
1032 const struct bitmap2* bm2;
1033
1034 bm2 = bm2_lookup(bm, a);
1035 return bm2 && bm2->recalc;
1036}
1037
1038/**
1039 * Set bitmap2::recalc in bml for each second level bitmap in bmr that contains
1040 * at least one access.
1041 *
1042 * @note Any new second-level bitmaps inserted in bml by this function are
1043 * uninitialized.
1044 */
1045void DRD_(bm_mark)(struct bitmap* bml, struct bitmap* bmr)
1046{
1047 struct bitmap2* bm2l;
1048 struct bitmap2* bm2r;
1049
1050 for (VG_(OSetGen_ResetIter)(bmr->oset);
1051 (bm2r = VG_(OSetGen_Next)(bmr->oset)) != 0;
1052 )
1053 {
1054 /*if (DRD_(bm_has_any_access(bmr, make_address(bm2r->addr, 0),
1055 make_address(bm2r->addr + 1, 0))))*/
1056 {
1057 bm2l = bm2_lookup_or_insert(bml, bm2r->addr);
1058 bm2l->recalc = True;
1059 }
1060 }
1061}
1062
1063/** Clear all second-level bitmaps for which bitmap2::recalc == True. */
1064void DRD_(bm_clear_marked)(struct bitmap* bm)
1065{
1066 struct bitmap2* bm2;
1067
1068 for (VG_(OSetGen_ResetIter)(bm->oset);
1069 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1070 )
1071 {
1072 if (bm2->recalc)
1073 bm2_clear(bm2);
1074 }
1075}
1076
1077/** Merge the second level bitmaps from *rhs into *lhs for which recalc == True. */
1078void DRD_(bm_merge2_marked)(struct bitmap* const lhs, struct bitmap* const rhs)
1079{
1080 struct bitmap2* bm2l;
1081 struct bitmap2* bm2r;
1082
1083 tl_assert(lhs != rhs);
1084
1085 /*
1086 * It's not possible to have two independent iterators over the same OSet,
1087 * so complain if lhs == rhs.
1088 */
1089 tl_assert(lhs != rhs);
1090
1091 s_bitmap_merge_count++;
1092
1093 VG_(OSetGen_ResetIter)(rhs->oset);
1094
1095 for ( ; (bm2r = VG_(OSetGen_Next)(rhs->oset)) != 0; )
1096 {
1097 bm2l = VG_(OSetGen_Lookup)(lhs->oset, &bm2r->addr);
1098 if (bm2l && bm2l->recalc)
1099 {
1100 tl_assert(bm2l != bm2r);
1101 bm2_merge(bm2l, bm2r);
1102 }
1103 }
1104}
1105
1106/** Remove all marked second-level bitmaps that do not contain any access. */
1107void DRD_(bm_remove_cleared_marked)(struct bitmap* bm)
1108{
1109 struct bitmap2* bm2;
1110
1111 VG_(OSetGen_ResetIter)(bm->oset);
1112 for ( ; (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0; )
1113 {
1114 const UWord a1 = bm2->addr;
1115 if (bm2->recalc
1116 && ! DRD_(bm_has_any_access(bm, make_address(a1, 0),
1117 make_address(a1 + 1, 0))))
1118 {
1119 bm2_remove(bm, a1);
1120 VG_(OSetGen_ResetIterAt)(bm->oset, &a1);
1121 }
1122 }
1123}
1124
sewardjaf44c822007-11-25 14:01:38 +00001125/**
1126 * Report whether there are any RW / WR / WW patterns in lhs and rhs.
1127 * @param lhs First bitmap.
1128 * @param rhs Bitmap to be compared with lhs.
1129 * @return !=0 if there are data races, == 0 if there are none.
1130 */
bart99edb292009-02-15 15:59:20 +00001131int DRD_(bm_has_races)(struct bitmap* const lhs, struct bitmap* const rhs)
sewardjaf44c822007-11-25 14:01:38 +00001132{
bartbedfd232009-03-26 19:07:15 +00001133 VG_(OSetGen_ResetIter)(lhs->oset);
1134 VG_(OSetGen_ResetIter)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +00001135
bartbedfd232009-03-26 19:07:15 +00001136 for (;;)
1137 {
bartbedfd232009-03-26 19:07:15 +00001138 const struct bitmap2* bm2l;
1139 const struct bitmap2* bm2r;
1140 const struct bitmap1* bm1l;
1141 const struct bitmap1* bm1r;
1142 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +00001143
bart7b706b32009-05-10 06:55:39 +00001144 bm2l = VG_(OSetGen_Next)(lhs->oset);
1145 bm2r = VG_(OSetGen_Next)(rhs->oset);
bartbedfd232009-03-26 19:07:15 +00001146 while (bm2l && bm2r && bm2l->addr != bm2r->addr)
sewardjaf44c822007-11-25 14:01:38 +00001147 {
bartbedfd232009-03-26 19:07:15 +00001148 if (bm2l->addr < bm2r->addr)
bart7b706b32009-05-10 06:55:39 +00001149 bm2l = VG_(OSetGen_Next)(lhs->oset);
bartbedfd232009-03-26 19:07:15 +00001150 else
bart7b706b32009-05-10 06:55:39 +00001151 bm2r = VG_(OSetGen_Next)(rhs->oset);
sewardjaf44c822007-11-25 14:01:38 +00001152 }
bartbedfd232009-03-26 19:07:15 +00001153 if (bm2l == 0 || bm2r == 0)
1154 break;
1155
1156 bm1l = &bm2l->bm1;
1157 bm1r = &bm2r->bm1;
1158
1159 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1160 {
1161 unsigned b;
1162 for (b = 0; b < BITS_PER_UWORD; b++)
1163 {
1164 UWord const access_mask
1165 = ((bm1l->bm0_r[k] & bm0_mask(b)) ? LHS_R : 0)
1166 | ((bm1l->bm0_w[k] & bm0_mask(b)) ? LHS_W : 0)
1167 | ((bm1r->bm0_r[k] & bm0_mask(b)) ? RHS_R : 0)
1168 | ((bm1r->bm0_w[k] & bm0_mask(b)) ? RHS_W : 0);
bart7b706b32009-05-10 06:55:39 +00001169 Addr const a = make_address(bm2l->addr, k * BITS_PER_UWORD | b);
bartbedfd232009-03-26 19:07:15 +00001170 if (HAS_RACE(access_mask) && ! DRD_(is_suppressed)(a, a + 1))
1171 {
1172 return 1;
1173 }
1174 }
1175 }
1176 }
1177 return 0;
sewardjaf44c822007-11-25 14:01:38 +00001178}
1179
bart99edb292009-02-15 15:59:20 +00001180void DRD_(bm_print)(struct bitmap* const bm)
sewardjaf44c822007-11-25 14:01:38 +00001181{
bartbedfd232009-03-26 19:07:15 +00001182 struct bitmap2* bm2;
sewardjaf44c822007-11-25 14:01:38 +00001183
bart7b706b32009-05-10 06:55:39 +00001184 for (VG_(OSetGen_ResetIter)(bm->oset);
1185 (bm2 = VG_(OSetGen_Next)(bm->oset)) != 0;
1186 )
bartbedfd232009-03-26 19:07:15 +00001187 {
bart7b706b32009-05-10 06:55:39 +00001188 bm2_print(bm2);
1189 }
1190}
bartf647d342008-03-24 19:12:12 +00001191
bart7b706b32009-05-10 06:55:39 +00001192static void bm2_print(const struct bitmap2* const bm2)
1193{
1194 const struct bitmap1* bm1;
1195 Addr a;
1196
1197 tl_assert(bm2);
1198
1199 bm1 = &bm2->bm1;
1200 for (a = make_address(bm2->addr, 0);
1201 a <= make_address(bm2->addr + 1, 0) - 1;
1202 a++)
1203 {
1204 const Bool r = bm0_is_set(bm1->bm0_r, address_lsb(a)) != 0;
1205 const Bool w = bm0_is_set(bm1->bm0_w, address_lsb(a)) != 0;
1206 if (r || w)
sewardjaf44c822007-11-25 14:01:38 +00001207 {
bart7b706b32009-05-10 06:55:39 +00001208 VG_(printf)("0x%08lx %c %c\n",
1209 a,
1210 w ? 'W' : ' ',
1211 r ? 'R' : ' ');
sewardjaf44c822007-11-25 14:01:38 +00001212 }
bartbedfd232009-03-26 19:07:15 +00001213 }
sewardjaf44c822007-11-25 14:01:38 +00001214}
1215
bart99edb292009-02-15 15:59:20 +00001216ULong DRD_(bm_get_bitmap_creation_count)(void)
sewardjaf44c822007-11-25 14:01:38 +00001217{
bartbedfd232009-03-26 19:07:15 +00001218 return s_bitmap_creation_count;
sewardjaf44c822007-11-25 14:01:38 +00001219}
1220
bart99edb292009-02-15 15:59:20 +00001221ULong DRD_(bm_get_bitmap2_creation_count)(void)
sewardjaf44c822007-11-25 14:01:38 +00001222{
bartbedfd232009-03-26 19:07:15 +00001223 return s_bitmap2_creation_count;
sewardjaf44c822007-11-25 14:01:38 +00001224}
1225
bart7b706b32009-05-10 06:55:39 +00001226ULong DRD_(bm_get_bitmap2_merge_count)(void)
bartf647d342008-03-24 19:12:12 +00001227{
bart7b706b32009-05-10 06:55:39 +00001228 return s_bitmap2_merge_count;
bartf647d342008-03-24 19:12:12 +00001229}
1230
bart7b706b32009-05-10 06:55:39 +00001231/** Compute *bm2l |= *bm2r. */
1232static
1233void bm2_merge(struct bitmap2* const bm2l, const struct bitmap2* const bm2r)
sewardjaf44c822007-11-25 14:01:38 +00001234{
bartbedfd232009-03-26 19:07:15 +00001235 unsigned k;
sewardjaf44c822007-11-25 14:01:38 +00001236
bartbedfd232009-03-26 19:07:15 +00001237 tl_assert(bm2l);
1238 tl_assert(bm2r);
1239 tl_assert(bm2l->addr == bm2r->addr);
bart7b706b32009-05-10 06:55:39 +00001240
1241 s_bitmap2_merge_count++;
sewardjaf44c822007-11-25 14:01:38 +00001242
bartbedfd232009-03-26 19:07:15 +00001243 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1244 {
1245 bm2l->bm1.bm0_r[k] |= bm2r->bm1.bm0_r[k];
1246 }
1247 for (k = 0; k < BITMAP1_UWORD_COUNT; k++)
1248 {
1249 bm2l->bm1.bm0_w[k] |= bm2r->bm1.bm0_w[k];
1250 }
sewardjaf44c822007-11-25 14:01:38 +00001251}