127fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 227fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote/*--------------------------------------------------------------------*/ 327fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote/*--- Cache simulation cg_sim.c ---*/ 427fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote/*--------------------------------------------------------------------*/ 527fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 627fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote/* 727fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote This file is part of Cachegrind, a Valgrind tool for cache 827fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote profiling programs. 927fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 10b3a1e4bffbdbbf38304f216af405009868f43628sewardj Copyright (C) 2002-2015 Nicholas Nethercote 112bc10126a94b421a490b2759dc50ab67ec4ee116njn njn@valgrind.org 1227fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 1327fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote This program is free software; you can redistribute it and/or 1427fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote modify it under the terms of the GNU General Public License as 1527fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote published by the Free Software Foundation; either version 2 of the 1627fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote License, or (at your option) any later version. 1727fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 1827fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote This program is distributed in the hope that it will be useful, but 1927fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote WITHOUT ANY WARRANTY; without even the implied warranty of 2027fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 2127fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote General Public License for more details. 2227fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 2327fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote You should have received a copy of the GNU General Public License 2427fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote along with this program; if not, write to the Free Software 2527fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 2627fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 02111-1307, USA. 2727fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 2827fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote The GNU General Public License is contained in the file COPYING. 2927fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote*/ 3027fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 3127fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote/* Notes: 3227fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote - simulates a write-allocate cache 3327fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote - (block --> set) hash function uses simple bit selection 3427fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote - handling of references straddling two cache blocks: 3527fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote - counts as only one cache access (not two) 3627fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote - both blocks hit --> one hit 3727fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote - one block hits, the other misses --> one miss 3827fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote - both blocks miss --> one miss (not two) 3927fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote*/ 4027fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 4127fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercotetypedef struct { 420103de5f5d39add9080fe72884af2a5520c1f661njn Int size; /* bytes */ 430103de5f5d39add9080fe72884af2a5520c1f661njn Int assoc; 440103de5f5d39add9080fe72884af2a5520c1f661njn Int line_size; /* bytes */ 450103de5f5d39add9080fe72884af2a5520c1f661njn Int sets; 460103de5f5d39add9080fe72884af2a5520c1f661njn Int sets_min_1; 470103de5f5d39add9080fe72884af2a5520c1f661njn Int line_size_bits; 480103de5f5d39add9080fe72884af2a5520c1f661njn Int tag_shift; 49fed3c04fdddde080fd2834212f6f514be96db47cflorian HChar desc_line[128]; /* large enough */ 50b619ca777d7d21945e0b593a4b9489b16b405d8fnjn UWord* tags; 5127fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote} cache_t2; 5227fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 5327fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote/* By this point, the size/assoc/line_size has been checked. */ 5427fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercotestatic void cachesim_initcache(cache_t config, cache_t2* c) 5527fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote{ 560103de5f5d39add9080fe72884af2a5520c1f661njn Int i; 5727fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 5827fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote c->size = config.size; 5927fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote c->assoc = config.assoc; 6027fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote c->line_size = config.line_size; 6127fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 6227fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote c->sets = (c->size / c->line_size) / c->assoc; 6327fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote c->sets_min_1 = c->sets - 1; 6427fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote c->line_size_bits = VG_(log2)(c->line_size); 6527fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote c->tag_shift = c->line_size_bits + VG_(log2)(c->sets); 6627fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 6727fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote if (c->assoc == 1) { 6827fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote VG_(sprintf)(c->desc_line, "%d B, %d B, direct-mapped", 6927fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote c->size, c->line_size); 7027fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote } else { 7127fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote VG_(sprintf)(c->desc_line, "%d B, %d B, %d-way associative", 7227fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote c->size, c->line_size, c->assoc); 7327fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote } 7427fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj c->tags = VG_(malloc)("cg.sim.ci.1", 769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sizeof(UWord) * c->sets * c->assoc); 7727fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 7827fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote for (i = 0; i < c->sets * c->assoc; i++) 7927fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote c->tags[i] = 0; 8027fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote} 8127fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 82c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo/* This attribute forces GCC to inline the function, getting rid of a 83c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo * lot of indirection around the cache_t2 pointer, if it is known to be 84c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo * constant in the caller (the caller is inlined itself). 85c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo * Without inlining of simulator functions, cachegrind can get 40% slower. 86c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo */ 87c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo__attribute__((always_inline)) 88b0909b40589ec17f370a9c716e47db87b1bb90a4weidendostatic __inline__ 89b0909b40589ec17f370a9c716e47db87b1bb90a4weidendoBool cachesim_setref_is_miss(cache_t2* c, UInt set_no, UWord tag) 90c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo{ 91c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo int i, j; 92c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo UWord *set; 93c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 94c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo set = &(c->tags[set_no * c->assoc]); 95c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 96c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo /* This loop is unrolled for just the first case, which is the most */ 97c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo /* common. We can't unroll any further because it would screw up */ 98c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo /* if we have a direct-mapped (1-way) cache. */ 99c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo if (tag == set[0]) 100c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo return False; 101c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 102c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo /* If the tag is one other than the MRU, move it into the MRU spot */ 103c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo /* and shuffle the rest down. */ 104c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo for (i = 1; i < c->assoc; i++) { 105c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo if (tag == set[i]) { 106c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo for (j = i; j > 0; j--) { 107c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo set[j] = set[j - 1]; 108c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo } 109c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo set[0] = tag; 110c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 111c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo return False; 112c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo } 113c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo } 114c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 115c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo /* A miss; install this tag as MRU, shuffle rest down. */ 116c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo for (j = c->assoc - 1; j > 0; j--) { 117c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo set[j] = set[j - 1]; 118c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo } 119c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo set[0] = tag; 120c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 121c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo return True; 12227fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote} 12327fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 124c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo__attribute__((always_inline)) 125b0909b40589ec17f370a9c716e47db87b1bb90a4weidendostatic __inline__ 126b0909b40589ec17f370a9c716e47db87b1bb90a4weidendoBool cachesim_ref_is_miss(cache_t2* c, Addr a, UChar size) 127c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo{ 1283694c9fa51437cf2025d3b66a46637aae73d0c28weidendo /* A memory block has the size of a cache line */ 1293694c9fa51437cf2025d3b66a46637aae73d0c28weidendo UWord block1 = a >> c->line_size_bits; 1303694c9fa51437cf2025d3b66a46637aae73d0c28weidendo UWord block2 = (a+size-1) >> c->line_size_bits; 1313694c9fa51437cf2025d3b66a46637aae73d0c28weidendo UInt set1 = block1 & c->sets_min_1; 1323694c9fa51437cf2025d3b66a46637aae73d0c28weidendo 1333694c9fa51437cf2025d3b66a46637aae73d0c28weidendo /* Tags used in real caches are minimal to save space. 1343694c9fa51437cf2025d3b66a46637aae73d0c28weidendo * As the last bits of the block number of addresses mapping 1353694c9fa51437cf2025d3b66a46637aae73d0c28weidendo * into one cache set are the same, real caches use as tag 1363694c9fa51437cf2025d3b66a46637aae73d0c28weidendo * tag = block >> log2(#sets) 1373694c9fa51437cf2025d3b66a46637aae73d0c28weidendo * But using the memory block as more specific tag is fine, 1383694c9fa51437cf2025d3b66a46637aae73d0c28weidendo * and saves instructions. 1393694c9fa51437cf2025d3b66a46637aae73d0c28weidendo */ 1403694c9fa51437cf2025d3b66a46637aae73d0c28weidendo UWord tag1 = block1; 141c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 142c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo /* Access entirely within line. */ 1433694c9fa51437cf2025d3b66a46637aae73d0c28weidendo if (block1 == block2) 1443694c9fa51437cf2025d3b66a46637aae73d0c28weidendo return cachesim_setref_is_miss(c, set1, tag1); 145c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 146c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo /* Access straddles two lines. */ 1473694c9fa51437cf2025d3b66a46637aae73d0c28weidendo else if (block1 + 1 == block2) { 1483694c9fa51437cf2025d3b66a46637aae73d0c28weidendo UInt set2 = block2 & c->sets_min_1; 1493694c9fa51437cf2025d3b66a46637aae73d0c28weidendo UWord tag2 = block2; 150c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 151c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo /* always do both, as state is updated as side effect */ 1523694c9fa51437cf2025d3b66a46637aae73d0c28weidendo if (cachesim_setref_is_miss(c, set1, tag1)) { 153c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo cachesim_setref_is_miss(c, set2, tag2); 154c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo return True; 155c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo } 156c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo return cachesim_setref_is_miss(c, set2, tag2); 157c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo } 158686870c103c1add7b4d455c62585419c524b4b00florian VG_(printf)("addr: %lx size: %u blocks: %lu %lu", 1593694c9fa51437cf2025d3b66a46637aae73d0c28weidendo a, size, block1, block2); 160c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo VG_(tool_panic)("item straddles more than two cache sets"); 161c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo /* not reached */ 162c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo return True; 163c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo} 164c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 165c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 166c1e9426c345714aac9e05751ca621d1f69c2b95fweidendostatic cache_t2 LL; 167c1e9426c345714aac9e05751ca621d1f69c2b95fweidendostatic cache_t2 I1; 168c1e9426c345714aac9e05751ca621d1f69c2b95fweidendostatic cache_t2 D1; 169c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 170c1e9426c345714aac9e05751ca621d1f69c2b95fweidendostatic void cachesim_initcaches(cache_t I1c, cache_t D1c, cache_t LLc) 171c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo{ 172c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo cachesim_initcache(I1c, &I1); 173c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo cachesim_initcache(D1c, &D1); 174c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo cachesim_initcache(LLc, &LL); 175c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo} 176c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 177c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo__attribute__((always_inline)) 178b0909b40589ec17f370a9c716e47db87b1bb90a4weidendostatic __inline__ 1796fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendovoid cachesim_I1_doref_Gen(Addr a, UChar size, ULong* m1, ULong *mL) 180c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo{ 181c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo if (cachesim_ref_is_miss(&I1, a, size)) { 182c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo (*m1)++; 183c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo if (cachesim_ref_is_miss(&LL, a, size)) 184c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo (*mL)++; 185c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo } 186c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo} 187c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo 1886fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo// common special case IrNoX 1896fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo__attribute__((always_inline)) 1906fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendostatic __inline__ 1916fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendovoid cachesim_I1_doref_NoX(Addr a, UChar size, ULong* m1, ULong *mL) 1926fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo{ 1936fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo UWord block = a >> I1.line_size_bits; 1946fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo UInt I1_set = block & I1.sets_min_1; 1956fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo 1966fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo // use block as tag 1976fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo if (cachesim_setref_is_miss(&I1, I1_set, block)) { 1986fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo UInt LL_set = block & LL.sets_min_1; 1996fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo (*m1)++; 2006fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo // can use block as tag as L1I and LL cache line sizes are equal 2016fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo if (cachesim_setref_is_miss(&LL, LL_set, block)) 2026fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo (*mL)++; 2036fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo } 2046fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo} 2056fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo 206c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo__attribute__((always_inline)) 207b0909b40589ec17f370a9c716e47db87b1bb90a4weidendostatic __inline__ 208b0909b40589ec17f370a9c716e47db87b1bb90a4weidendovoid cachesim_D1_doref(Addr a, UChar size, ULong* m1, ULong *mL) 209c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo{ 210c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo if (cachesim_ref_is_miss(&D1, a, size)) { 211c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo (*m1)++; 212c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo if (cachesim_ref_is_miss(&LL, a, size)) 213c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo (*mL)++; 214c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo } 215c1e9426c345714aac9e05751ca621d1f69c2b95fweidendo} 21627fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 2176fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo/* Check for special case IrNoX. Called at instrumentation time. 2186fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo * 2196fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo * Does this Ir only touch one cache line, and are L1I/LL cache 2206fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo * line sizes the same? This allows to get rid of a runtime check. 2216fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo * 2226fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo * Returning false is always fine, as this calls the generic case 2236fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo */ 2246fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendostatic Bool cachesim_is_IrNoX(Addr a, UChar size) 2256fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo{ 2266fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo UWord block1, block2; 2276fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo 2286fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo if (I1.line_size_bits != LL.line_size_bits) return False; 2296fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo block1 = a >> I1.line_size_bits; 2306fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo block2 = (a+size-1) >> I1.line_size_bits; 2316fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo if (block1 != block2) return False; 2326fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo 2336fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo return True; 2346fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo} 2356fc0de0c31dc5ff9423d004d3af5f2219259cff4weidendo 23627fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote/*--------------------------------------------------------------------*/ 23727fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote/*--- end cg_sim.c ---*/ 23827fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote/*--------------------------------------------------------------------*/ 23927fc1dacf94f1b9622d3a9bf48677fc09f61f7aanethercote 240