1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Cache simulation. ---*/ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- sim.c ---*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Callgrind, a Valgrind tool for call graph 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown profiling programs. 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2003-2013, Josef Weidendorfer (Josef.Weidendorfer@gmx.de) 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This tool is derived from and contains code from Cachegrind 13436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2002-2013 Nicholas Nethercote (njn@valgrind.org) 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "global.h" 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Notes: 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - simulates a write-allocate cache 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - (block --> set) hash function uses simple bit selection 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - handling of references straddling two cache blocks: 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - counts as only one cache access (not two) 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - both blocks hit --> one hit 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - one block hits, the other misses --> one miss 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - both blocks miss --> one miss (not two) 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Cache configuration */ 47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "cg_arch.c" 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* additional structures for cache use info, separated 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * according usage frequency: 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - line_loaded : pointer to cost center of instruction 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * which loaded the line into cache. 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Needed to increment counters when line is evicted. 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - line_use : updated on every access 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct { 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt count; 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt mask; /* e.g. for 64Byte line size 1bit/2Byte */ 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} line_use; 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct { 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr memline, iaddr; 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown line_use* dep_use; /* point to higher-level cacheblock for this memline */ 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong* use_base; 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} line_loaded; 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Cache state */ 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct { 69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* name; 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int size; /* bytes */ 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int assoc; 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int line_size; /* bytes */ 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool sectored; /* prefetch nearside cacheline on read */ 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int sets; 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int sets_min_1; 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int line_size_bits; 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int tag_shift; 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord tag_mask; 79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar desc_line[128]; 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord* tags; 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* for cache use */ 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int line_size_mask; 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int* line_start_mask; 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int* line_end_mask; 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown line_loaded* loaded; 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown line_use* use; 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} cache_t2; 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * States of flat caches in our model. 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * We use a 2-level hierarchy, 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic cache_t2 I1, D1, LL; 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Lower bits of cache tags are used as flags for a cache line */ 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CACHELINE_FLAGMASK (MIN_LINE_SIZE-1) 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CACHELINE_DIRTY 1 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Cache simulator Options */ 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool clo_simulate_writeback = False; 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool clo_simulate_hwpref = False; 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool clo_simulate_sectors = False; 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool clo_collect_cacheuse = False; 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Following global vars are setup before by setup_bbcc(): 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - Addr CLG_(bb_base) (instruction start address of original BB) 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * - ULong* CLG_(cost_base) (start of cost array for BB) 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownAddr CLG_(bb_base); 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownULong* CLG_(cost_base); 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic InstrInfo* current_ii; 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Cache use offsets */ 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The offsets are only correct because all per-instruction event sets get 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the "Use" set added first ! 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int off_I1_AcCost = 0; 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int off_I1_SpLoss = 1; 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int off_D1_AcCost = 0; 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int off_D1_SpLoss = 1; 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int off_LL_AcCost = 2; 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int off_LL_SpLoss = 3; 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Cache access types */ 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef enum { Read = 0, Write = CACHELINE_DIRTY } RefType; 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Result of a reference into a flat cache */ 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef enum { Hit = 0, Miss, MissDirty } CacheResult; 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Result of a reference into a hierarchical cache model */ 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef enum { 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L1_Hit, 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LL_Hit, 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MemAccess, 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WriteBackMemAccess } CacheModelResult; 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef CacheModelResult (*simcall_type)(Addr, UChar); 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic struct { 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simcall_type I1_Read; 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simcall_type D1_Read; 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simcall_type D1_Write; 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} simulator; 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Cache Simulator Initialization ---*/ 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void cachesim_clearcache(cache_t2* c) 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < c->sets * c->assoc; i++) 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->tags[i] = 0; 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (c->use) { 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < c->sets * c->assoc; i++) { 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->loaded[i].memline = 0; 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->loaded[i].use_base = 0; 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->loaded[i].dep_use = 0; 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->loaded[i].iaddr = 0; 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->use[i].mask = 0; 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->use[i].count = 0; 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->tags[i] = i % c->assoc; /* init lower bits as pointer */ 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void cacheuse_initcache(cache_t2* c); 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* By this point, the size/assoc/line_size has been checked. */ 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void cachesim_initcache(cache_t config, cache_t2* c) 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->size = config.size; 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->assoc = config.assoc; 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->line_size = config.line_size; 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->sectored = False; // FIXME 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->sets = (c->size / c->line_size) / c->assoc; 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->sets_min_1 = c->sets - 1; 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->line_size_bits = VG_(log2)(c->line_size); 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->tag_shift = c->line_size_bits + VG_(log2)(c->sets); 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->tag_mask = ~((1<<c->tag_shift)-1); 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Can bits in tag entries be used for flags? 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Should be always true as MIN_LINE_SIZE >= 16 */ 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_ASSERT( (c->tag_mask & CACHELINE_FLAGMASK) == 0); 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (c->assoc == 1) { 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(c->desc_line, "%d B, %d B, direct-mapped%s", 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->size, c->line_size, 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->sectored ? ", sectored":""); 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(c->desc_line, "%d B, %d B, %d-way associative%s", 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->size, c->line_size, c->assoc, 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->sectored ? ", sectored":""); 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->tags = (UWord*) CLG_MALLOC("cl.sim.cs_ic.1", 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(UWord) * c->sets * c->assoc); 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (clo_collect_cacheuse) 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cacheuse_initcache(c); 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->use = 0; 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cachesim_clearcache(c); 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void print_cache(cache_t2* c) 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt set, way, i; 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note initialisation and update of 'i'. */ 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0, set = 0; set < c->sets; set++) { 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (way = 0; way < c->assoc; way++, i++) { 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("%8x ", c->tags[i]); 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("\n"); 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- Simple Cache Simulation ---*/ 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 234436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * Model: single inclusive, 2-level cache hierarchy (L1/LL) 235436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * with write-allocate 236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * 237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * For simple cache hit/miss counts, we do not have to 238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * maintain the dirty state of lines (no need to distinguish 239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * read/write references), and the resulting counts are the 240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * same for write-through and write-back caches. 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Simulator functions: 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * CacheModelResult cachesim_I1_ref(Addr a, UChar size) 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * CacheModelResult cachesim_D1_ref(Addr a, UChar size) 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov__attribute__((always_inline)) 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __inline__ 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheResult cachesim_setref(cache_t2* c, UInt set_no, UWord tag) 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i, j; 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord *set; 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set = &(c->tags[set_no * c->assoc]); 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This loop is unrolled for just the first case, which is the most */ 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* common. We can't unroll any further because it would screw up */ 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* if we have a direct-mapped (1-way) cache. */ 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tag == set[0]) 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return Hit; 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If the tag is one other than the MRU, move it into the MRU spot */ 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* and shuffle the rest down. */ 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 1; i < c->assoc; i++) { 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tag == set[i]) { 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = i; j > 0; j--) { 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[j] = set[j - 1]; 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[0] = tag; 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return Hit; 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A miss; install this tag as MRU, shuffle rest down. */ 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = c->assoc - 1; j > 0; j--) { 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[j] = set[j - 1]; 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[0] = tag; 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return Miss; 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 282436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov__attribute__((always_inline)) 283436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic __inline__ 284436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovCacheResult cachesim_ref(cache_t2* c, Addr a, UChar size) 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 286436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord block1 = a >> c->line_size_bits; 287436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord block2 = (a+size-1) >> c->line_size_bits; 288436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt set1 = block1 & c->sets_min_1; 289436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* the tag does not need to include bits specifying the set, 290436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * but it can, and this saves instructions */ 291436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord tag1 = block1; 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Access entirely within line. */ 294436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (block1 == block2) 295436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return cachesim_setref(c, set1, tag1); 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Access straddles two lines. */ 298436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else if (block1 + 1 == block2) { 299436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt set2 = block2 & c->sets_min_1; 300436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord tag2 = block2; 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* the call updates cache structures as side effect */ 303436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov CacheResult res1 = cachesim_setref(c, set1, tag1); 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CacheResult res2 = cachesim_setref(c, set2, tag2); 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ((res1 == Miss) || (res2 == Miss)) ? Miss : Hit; 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 308436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(printf)("addr: %lx size: %u blocks: %ld %ld", 309436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a, size, block1, block2); 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tool_panic)("item straddles more than two cache sets"); 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return Hit; 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheModelResult cachesim_I1_ref(Addr a, UChar size) 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &I1, a, size) == Hit ) return L1_Hit; 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &LL, a, size) == Hit ) return LL_Hit; 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return MemAccess; 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheModelResult cachesim_D1_ref(Addr a, UChar size) 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &D1, a, size) == Hit ) return L1_Hit; 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &LL, a, size) == Hit ) return LL_Hit; 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return MemAccess; 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Write Back Cache Simulation ---*/ 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * More complex model: L1 Write-through, LL Write-back 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * This needs to distinguish among read and write references. 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Simulator functions: 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * CacheModelResult cachesim_I1_Read(Addr a, UChar size) 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * CacheModelResult cachesim_D1_Read(Addr a, UChar size) 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * CacheModelResult cachesim_D1_Write(Addr a, UChar size) 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * With write-back, result can be a miss evicting a dirty line 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * The dirty state of a cache line is stored in Bit0 of the tag for 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * this cache line (CACHELINE_DIRTY = 1). By OR'ing the reference 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * type (Read/Write), the line gets dirty on a write. 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov__attribute__((always_inline)) 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __inline__ 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheResult cachesim_setref_wb(cache_t2* c, RefType ref, UInt set_no, UWord tag) 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i, j; 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord *set, tmp_tag; 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set = &(c->tags[set_no * c->assoc]); 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This loop is unrolled for just the first case, which is the most */ 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* common. We can't unroll any further because it would screw up */ 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* if we have a direct-mapped (1-way) cache. */ 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tag == (set[0] & ~CACHELINE_DIRTY)) { 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[0] |= ref; 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return Hit; 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If the tag is one other than the MRU, move it into the MRU spot */ 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* and shuffle the rest down. */ 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 1; i < c->assoc; i++) { 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tag == (set[i] & ~CACHELINE_DIRTY)) { 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp_tag = set[i] | ref; // update dirty flag 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = i; j > 0; j--) { 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[j] = set[j - 1]; 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[0] = tmp_tag; 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return Hit; 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A miss; install this tag as MRU, shuffle rest down. */ 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp_tag = set[c->assoc - 1]; 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = c->assoc - 1; j > 0; j--) { 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[j] = set[j - 1]; 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[0] = tag | ref; 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (tmp_tag & CACHELINE_DIRTY) ? MissDirty : Miss; 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 391436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov__attribute__((always_inline)) 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __inline__ 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheResult cachesim_ref_wb(cache_t2* c, RefType ref, Addr a, UChar size) 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt set1 = ( a >> c->line_size_bits) & (c->sets_min_1); 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt set2 = ((a+size-1) >> c->line_size_bits) & (c->sets_min_1); 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord tag = a & c->tag_mask; 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Access entirely within line. */ 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (set1 == set2) 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cachesim_setref_wb(c, ref, set1, tag); 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Access straddles two lines. */ 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Nb: this is a fast way of doing ((set1+1) % c->sets) */ 405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else if (((set1 + 1) & (c->sets_min_1)) == set2) { 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord tag2 = (a+size-1) & c->tag_mask; 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* the call updates cache structures as side effect */ 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CacheResult res1 = cachesim_setref_wb(c, ref, set1, tag); 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CacheResult res2 = cachesim_setref_wb(c, ref, set2, tag2); 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((res1 == MissDirty) || (res2 == MissDirty)) return MissDirty; 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ((res1 == Miss) || (res2 == Miss)) ? Miss : Hit; 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("addr: %lx size: %u sets: %d %d", a, size, set1, set2); 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tool_panic)("item straddles more than two cache sets"); 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return Hit; 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheModelResult cachesim_I1_Read(Addr a, UChar size) 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &I1, a, size) == Hit ) return L1_Hit; 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch( cachesim_ref_wb( &LL, Read, a, size) ) { 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Hit: return LL_Hit; 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Miss: return MemAccess; 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: break; 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return WriteBackMemAccess; 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheModelResult cachesim_D1_Read(Addr a, UChar size) 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &D1, a, size) == Hit ) return L1_Hit; 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch( cachesim_ref_wb( &LL, Read, a, size) ) { 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Hit: return LL_Hit; 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Miss: return MemAccess; 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: break; 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return WriteBackMemAccess; 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheModelResult cachesim_D1_Write(Addr a, UChar size) 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &D1, a, size) == Hit ) { 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Even for a L1 hit, the write-trough L1 passes 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the write to the LL to make the LL line dirty. 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * But this causes no latency, so return the hit. 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cachesim_ref_wb( &LL, Write, a, size); 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return L1_Hit; 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch( cachesim_ref_wb( &LL, Write, a, size) ) { 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Hit: return LL_Hit; 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Miss: return MemAccess; 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: break; 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return WriteBackMemAccess; 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Hardware Prefetch Simulation ---*/ 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic ULong prefetch_up = 0; 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic ULong prefetch_down = 0; 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PF_STREAMS 8 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PF_PAGEBITS 12 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt pf_lastblock[PF_STREAMS]; 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int pf_seqblocks[PF_STREAMS]; 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid prefetch_clear(void) 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i; 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for(i=0;i<PF_STREAMS;i++) 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf_lastblock[i] = pf_seqblocks[i] = 0; 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * HW Prefetch emulation 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Start prefetching when detecting sequential access to 3 memory blocks. 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * One stream can be detected per 4k page. 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __inline__ 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid prefetch_LL_doref(Addr a) 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt stream = (a >> PF_PAGEBITS) % PF_STREAMS; 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt block = ( a >> LL.line_size_bits); 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (block != pf_lastblock[stream]) { 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (pf_seqblocks[stream] == 0) { 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (pf_lastblock[stream] +1 == block) pf_seqblocks[stream]++; 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (pf_lastblock[stream] -1 == block) pf_seqblocks[stream]--; 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (pf_seqblocks[stream] >0) { 505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (pf_lastblock[stream] +1 == block) { 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf_seqblocks[stream]++; 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (pf_seqblocks[stream] >= 2) { 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prefetch_up++; 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cachesim_ref(&LL, a + 5 * LL.line_size,1); 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else pf_seqblocks[stream] = 0; 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (pf_seqblocks[stream] <0) { 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (pf_lastblock[stream] -1 == block) { 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf_seqblocks[stream]--; 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (pf_seqblocks[stream] <= -2) { 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prefetch_down++; 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cachesim_ref(&LL, a - 5 * LL.line_size,1); 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else pf_seqblocks[stream] = 0; 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pf_lastblock[stream] = block; 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* simple model with hardware prefetch */ 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheModelResult prefetch_I1_ref(Addr a, UChar size) 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &I1, a, size) == Hit ) return L1_Hit; 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prefetch_LL_doref(a); 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &LL, a, size) == Hit ) return LL_Hit; 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return MemAccess; 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheModelResult prefetch_D1_ref(Addr a, UChar size) 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &D1, a, size) == Hit ) return L1_Hit; 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prefetch_LL_doref(a); 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &LL, a, size) == Hit ) return LL_Hit; 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return MemAccess; 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* complex model with hardware prefetch */ 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheModelResult prefetch_I1_Read(Addr a, UChar size) 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &I1, a, size) == Hit ) return L1_Hit; 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prefetch_LL_doref(a); 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch( cachesim_ref_wb( &LL, Read, a, size) ) { 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Hit: return LL_Hit; 558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Miss: return MemAccess; 559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: break; 560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return WriteBackMemAccess; 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheModelResult prefetch_D1_Read(Addr a, UChar size) 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &D1, a, size) == Hit ) return L1_Hit; 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prefetch_LL_doref(a); 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch( cachesim_ref_wb( &LL, Read, a, size) ) { 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Hit: return LL_Hit; 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Miss: return MemAccess; 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: break; 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return WriteBackMemAccess; 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheModelResult prefetch_D1_Write(Addr a, UChar size) 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prefetch_LL_doref(a); 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( cachesim_ref( &D1, a, size) == Hit ) { 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Even for a L1 hit, the write-trough L1 passes 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the write to the LL to make the LL line dirty. 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * But this causes no latency, so return the hit. 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cachesim_ref_wb( &LL, Write, a, size); 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return L1_Hit; 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch( cachesim_ref_wb( &LL, Write, a, size) ) { 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Hit: return LL_Hit; 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Miss: return MemAccess; 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: break; 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return WriteBackMemAccess; 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Cache Simulation with use metric collection ---*/ 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* can not be combined with write-back or prefetch */ 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid cacheuse_initcache(cache_t2* c) 606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i; 608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int start_mask, start_val; 609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int end_mask, end_val; 610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->use = CLG_MALLOC("cl.sim.cu_ic.1", 612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(line_use) * c->sets * c->assoc); 613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->loaded = CLG_MALLOC("cl.sim.cu_ic.2", 614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(line_loaded) * c->sets * c->assoc); 615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->line_start_mask = CLG_MALLOC("cl.sim.cu_ic.3", 616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(int) * c->line_size); 617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->line_end_mask = CLG_MALLOC("cl.sim.cu_ic.4", 618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(int) * c->line_size); 619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->line_size_mask = c->line_size-1; 621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Meaning of line_start_mask/line_end_mask 623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Example: for a given cache line, you get an access starting at 624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * byte offset 5, length 4, byte 5 - 8 was touched. For a cache 625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * line size of 32, you have 1 bit per byte in the mask: 626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * bit31 bit8 bit5 bit 0 628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * | | | | 629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 11..111111100000 line_start_mask[5] 630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 00..000111111111 line_end_mask[(5+4)-1] 631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * use_mask |= line_start_mask[5] && line_end_mask[8] 633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown start_val = end_val = ~0; 636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (c->line_size < 32) { 637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int bits_per_byte = 32/c->line_size; 638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown start_mask = (1<<bits_per_byte)-1; 639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown end_mask = start_mask << (32-bits_per_byte); 640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for(i=0;i<c->line_size;i++) { 641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->line_start_mask[i] = start_val; 642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown start_val = start_val & ~start_mask; 643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown start_mask = start_mask << bits_per_byte; 644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->line_end_mask[c->line_size-i-1] = end_val; 646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown end_val = end_val & ~end_mask; 647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown end_mask = end_mask >> bits_per_byte; 648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int bytes_per_bit = c->line_size/32; 652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown start_mask = 1; 653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown end_mask = 1 << 31; 654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for(i=0;i<c->line_size;i++) { 655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->line_start_mask[i] = start_val; 656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->line_end_mask[c->line_size-i-1] = end_val; 657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( ((i+1)%bytes_per_bit) == 0) { 658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown start_val &= ~start_mask; 659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown end_val &= ~end_mask; 660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown start_mask <<= 1; 661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown end_mask >>= 1; 662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6, "Config %s:\n", c->desc_line); 667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for(i=0;i<c->line_size;i++) { 668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6, " [%2d]: start mask %8x, end mask %8x\n", 669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i, c->line_start_mask[i], c->line_end_mask[i]); 670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We use lower tag bits as offset pointers to cache use info. 673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * I.e. some cache parameters don't work. 674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( (1<<c->tag_shift) < c->assoc) { 676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_DebugMsg, 677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "error: Use associativity < %d for cache use statistics!\n", 678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (1<<c->tag_shift) ); 679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tool_panic)("Unsupported cache configuration"); 680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* for I1/D1 caches */ 685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CACHEUSE(L) \ 686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic CacheModelResult cacheuse##_##L##_doRead(Addr a, UChar size) \ 688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt set1 = ( a >> L.line_size_bits) & (L.sets_min_1); \ 690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt set2 = ((a+size-1) >> L.line_size_bits) & (L.sets_min_1); \ 691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord tag = a & L.tag_mask; \ 692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord tag2; \ 693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i, j, idx; \ 694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord *set, tmp_tag; \ 695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt use_mask; \ 696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6,"%s.Acc(Addr %#lx, size %d): Sets [%d/%d]\n", \ 698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.name, a, size, set1, set2); \ 699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* First case: word entirely within line. */ \ 701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (set1 == set2) { \ 702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set = &(L.tags[set1 * L.assoc]); \ 704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use_mask = L.line_start_mask[a & L.line_size_mask] & \ 705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.line_end_mask[(a+size-1) & L.line_size_mask]; \ 706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This loop is unrolled for just the first case, which is the most */\ 708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* common. We can't unroll any further because it would screw up */\ 709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* if we have a direct-mapped (1-way) cache. */\ 710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tag == (set[0] & L.tag_mask)) { \ 711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx = (set1 * L.assoc) + (set[0] & ~L.tag_mask); \ 712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.use[idx].count ++; \ 713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.use[idx].mask |= use_mask; \ 714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6," Hit0 [idx %d] (line %#lx from %#lx): %x => %08x, count %d\n",\ 715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx, L.loaded[idx].memline, L.loaded[idx].iaddr, \ 716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use_mask, L.use[idx].mask, L.use[idx].count); \ 717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return L1_Hit; \ 718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If the tag is one other than the MRU, move it into the MRU spot */\ 720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* and shuffle the rest down. */\ 721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 1; i < L.assoc; i++) { \ 722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tag == (set[i] & L.tag_mask)) { \ 723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp_tag = set[i]; \ 724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = i; j > 0; j--) { \ 725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[j] = set[j - 1]; \ 726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[0] = tmp_tag; \ 728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx = (set1 * L.assoc) + (tmp_tag & ~L.tag_mask); \ 729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.use[idx].count ++; \ 730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.use[idx].mask |= use_mask; \ 731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6," Hit%d [idx %d] (line %#lx from %#lx): %x => %08x, count %d\n",\ 732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i, idx, L.loaded[idx].memline, L.loaded[idx].iaddr, \ 733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use_mask, L.use[idx].mask, L.use[idx].count); \ 734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return L1_Hit; \ 735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A miss; install this tag as MRU, shuffle rest down. */ \ 739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp_tag = set[L.assoc - 1] & ~L.tag_mask; \ 740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = L.assoc - 1; j > 0; j--) { \ 741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[j] = set[j - 1]; \ 742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[0] = tag | tmp_tag; \ 744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx = (set1 * L.assoc) + tmp_tag; \ 745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return update_##L##_use(&L, idx, \ 746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use_mask, a &~ L.line_size_mask); \ 747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Second case: word straddles two lines. */ \ 749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Nb: this is a fast way of doing ((set1+1) % L.sets) */ \ 750b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } else if (((set1 + 1) & (L.sets_min_1)) == set2) { \ 751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int miss1=0, miss2=0; /* 0: L1 hit, 1:L1 miss, 2:LL miss */ \ 752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set = &(L.tags[set1 * L.assoc]); \ 753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use_mask = L.line_start_mask[a & L.line_size_mask]; \ 754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tag == (set[0] & L.tag_mask)) { \ 755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx = (set1 * L.assoc) + (set[0] & ~L.tag_mask); \ 756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.use[idx].count ++; \ 757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.use[idx].mask |= use_mask; \ 758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6," Hit0 [idx %d] (line %#lx from %#lx): %x => %08x, count %d\n",\ 759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx, L.loaded[idx].memline, L.loaded[idx].iaddr, \ 760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use_mask, L.use[idx].mask, L.use[idx].count); \ 761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto block2; \ 762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 1; i < L.assoc; i++) { \ 764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tag == (set[i] & L.tag_mask)) { \ 765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp_tag = set[i]; \ 766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = i; j > 0; j--) { \ 767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[j] = set[j - 1]; \ 768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[0] = tmp_tag; \ 770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx = (set1 * L.assoc) + (tmp_tag & ~L.tag_mask); \ 771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.use[idx].count ++; \ 772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.use[idx].mask |= use_mask; \ 773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6," Hit%d [idx %d] (line %#lx from %#lx): %x => %08x, count %d\n",\ 774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i, idx, L.loaded[idx].memline, L.loaded[idx].iaddr, \ 775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use_mask, L.use[idx].mask, L.use[idx].count); \ 776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto block2; \ 777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp_tag = set[L.assoc - 1] & ~L.tag_mask; \ 780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = L.assoc - 1; j > 0; j--) { \ 781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[j] = set[j - 1]; \ 782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[0] = tag | tmp_tag; \ 784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx = (set1 * L.assoc) + tmp_tag; \ 785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown miss1 = update_##L##_use(&L, idx, \ 786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use_mask, a &~ L.line_size_mask); \ 787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownblock2: \ 788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set = &(L.tags[set2 * L.assoc]); \ 789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use_mask = L.line_end_mask[(a+size-1) & L.line_size_mask]; \ 790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tag2 = (a+size-1) & L.tag_mask; \ 791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tag2 == (set[0] & L.tag_mask)) { \ 792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx = (set2 * L.assoc) + (set[0] & ~L.tag_mask); \ 793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.use[idx].count ++; \ 794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.use[idx].mask |= use_mask; \ 795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6," Hit0 [idx %d] (line %#lx from %#lx): %x => %08x, count %d\n",\ 796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx, L.loaded[idx].memline, L.loaded[idx].iaddr, \ 797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use_mask, L.use[idx].mask, L.use[idx].count); \ 798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return miss1; \ 799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 1; i < L.assoc; i++) { \ 801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tag2 == (set[i] & L.tag_mask)) { \ 802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp_tag = set[i]; \ 803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = i; j > 0; j--) { \ 804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[j] = set[j - 1]; \ 805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[0] = tmp_tag; \ 807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx = (set2 * L.assoc) + (tmp_tag & ~L.tag_mask); \ 808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.use[idx].count ++; \ 809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown L.use[idx].mask |= use_mask; \ 810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6," Hit%d [idx %d] (line %#lx from %#lx): %x => %08x, count %d\n",\ 811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i, idx, L.loaded[idx].memline, L.loaded[idx].iaddr, \ 812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use_mask, L.use[idx].mask, L.use[idx].count); \ 813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return miss1; \ 814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp_tag = set[L.assoc - 1] & ~L.tag_mask; \ 817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = L.assoc - 1; j > 0; j--) { \ 818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[j] = set[j - 1]; \ 819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[0] = tag2 | tmp_tag; \ 821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx = (set2 * L.assoc) + tmp_tag; \ 822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown miss2 = update_##L##_use(&L, idx, \ 823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use_mask, (a+size-1) &~ L.line_size_mask); \ 824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (miss1==MemAccess || miss2==MemAccess) ? MemAccess:LL_Hit; \ 825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { \ 827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("addr: %#lx size: %u sets: %d %d", a, size, set1, set2); \ 828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tool_panic)("item straddles more than two cache sets"); \ 829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; \ 831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* logarithmic bitcounting algorithm, see 835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * http://graphics.stanford.edu/~seander/bithacks.html 836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __inline__ unsigned int countBits(unsigned int bits) 838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int c; // store the total here 840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const int S[] = {1, 2, 4, 8, 16}; // Magic Binary Numbers 841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF}; 842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c = bits; 844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c = ((c >> S[0]) & B[0]) + (c & B[0]); 845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c = ((c >> S[1]) & B[1]) + (c & B[1]); 846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c = ((c >> S[2]) & B[2]) + (c & B[2]); 847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c = ((c >> S[3]) & B[3]) + (c & B[3]); 848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c = ((c >> S[4]) & B[4]) + (c & B[4]); 849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return c; 850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void update_LL_use(int idx, Addr memline) 853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown line_loaded* loaded = &(LL.loaded[idx]); 855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown line_use* use = &(LL.use[idx]); 856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i = ((32 - countBits(use->mask)) * LL.line_size)>>5; 857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(2, " LL.miss [%d]: at %#lx accessing memline %#lx\n", 859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx, CLG_(bb_base) + current_ii->instr_offset, memline); 860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (use->count>0) { 861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(2, " old: used %d, loss bits %d (%08x) [line %#lx from %#lx]\n", 862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use->count, i, use->mask, loaded->memline, loaded->iaddr); 863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(2, " collect: %d, use_base %p\n", 864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_state).collect, loaded->use_base); 865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).collect && loaded->use_base) { 867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (loaded->use_base)[off_LL_AcCost] += 1000 / use->count; 868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (loaded->use_base)[off_LL_SpLoss] += i; 869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use->count = 0; 873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use->mask = 0; 874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown loaded->memline = memline; 876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown loaded->iaddr = CLG_(bb_base) + current_ii->instr_offset; 877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown loaded->use_base = (CLG_(current_state).nonskipped) ? 878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_state).nonskipped->skipped : 879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cost_base) + current_ii->cost_offset; 880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCacheModelResult cacheuse_LL_access(Addr memline, line_loaded* l1_loaded) 884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt setNo = (memline >> LL.line_size_bits) & (LL.sets_min_1); 886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord* set = &(LL.tags[setNo * LL.assoc]); 887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord tag = memline & LL.tag_mask; 888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i, j, idx; 890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord tmp_tag; 891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6,"LL.Acc(Memline %#lx): Set %d\n", memline, setNo); 893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tag == (set[0] & LL.tag_mask)) { 895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx = (setNo * LL.assoc) + (set[0] & ~LL.tag_mask); 896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown l1_loaded->dep_use = &(LL.use[idx]); 897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6," Hit0 [idx %d] (line %#lx from %#lx): => %08x, count %d\n", 899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx, LL.loaded[idx].memline, LL.loaded[idx].iaddr, 900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LL.use[idx].mask, LL.use[idx].count); 901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return LL_Hit; 902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 1; i < LL.assoc; i++) { 904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tag == (set[i] & LL.tag_mask)) { 905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp_tag = set[i]; 906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = i; j > 0; j--) { 907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[j] = set[j - 1]; 908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[0] = tmp_tag; 910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx = (setNo * LL.assoc) + (tmp_tag & ~LL.tag_mask); 911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown l1_loaded->dep_use = &(LL.use[idx]); 912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6," Hit%d [idx %d] (line %#lx from %#lx): => %08x, count %d\n", 914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i, idx, LL.loaded[idx].memline, LL.loaded[idx].iaddr, 915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LL.use[idx].mask, LL.use[idx].count); 916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return LL_Hit; 917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A miss; install this tag as MRU, shuffle rest down. */ 921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tmp_tag = set[LL.assoc - 1] & ~LL.tag_mask; 922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = LL.assoc - 1; j > 0; j--) { 923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[j] = set[j - 1]; 924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set[0] = tag | tmp_tag; 926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown idx = (setNo * LL.assoc) + tmp_tag; 927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown l1_loaded->dep_use = &(LL.use[idx]); 928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown update_LL_use(idx, memline); 930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return MemAccess; 932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define UPDATE_USE(L) \ 938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic CacheModelResult update##_##L##_use(cache_t2* cache, int idx, \ 940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt mask, Addr memline) \ 941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ \ 942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown line_loaded* loaded = &(cache->loaded[idx]); \ 943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown line_use* use = &(cache->use[idx]); \ 944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int c = ((32 - countBits(use->mask)) * cache->line_size)>>5; \ 945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(2, " %s.miss [%d]: at %#lx accessing memline %#lx (mask %08x)\n", \ 947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cache->name, idx, CLG_(bb_base) + current_ii->instr_offset, memline, mask); \ 948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (use->count>0) { \ 949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(2, " old: used %d, loss bits %d (%08x) [line %#lx from %#lx]\n",\ 950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use->count, c, use->mask, loaded->memline, loaded->iaddr); \ 951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(2, " collect: %d, use_base %p\n", \ 952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_state).collect, loaded->use_base); \ 953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).collect && loaded->use_base) { \ 955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (loaded->use_base)[off_##L##_AcCost] += 1000 / use->count; \ 956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (loaded->use_base)[off_##L##_SpLoss] += c; \ 957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* FIXME (?): L1/LL line sizes must be equal ! */ \ 959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown loaded->dep_use->mask |= use->mask; \ 960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown loaded->dep_use->count += use->count; \ 961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } \ 963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use->count = 1; \ 965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown use->mask = mask; \ 966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown loaded->memline = memline; \ 967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown loaded->iaddr = CLG_(bb_base) + current_ii->instr_offset; \ 968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown loaded->use_base = (CLG_(current_state).nonskipped) ? \ 969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_state).nonskipped->skipped : \ 970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cost_base) + current_ii->cost_offset; \ 971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown \ 972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (memline == 0) return LL_Hit; \ 973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cacheuse_LL_access(memline, loaded); \ 974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownUPDATE_USE(I1); 977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownUPDATE_USE(D1); 978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCACHEUSE(I1); 980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownCACHEUSE(D1); 981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid cacheuse_finish(void) 985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i; 987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown InstrInfo ii = { 0,0,0,0 }; 988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!CLG_(current_state).collect) return; 990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(bb_base) = 0; 992b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov current_ii = ⅈ /* needs to be set for update_XX_use */ 993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cost_base) = 0; 994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* update usage counters */ 996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (I1.use) 997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < I1.sets * I1.assoc; i++) 998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (I1.loaded[i].use_base) 999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown update_I1_use( &I1, i, 0,0); 1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (D1.use) 1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < D1.sets * D1.assoc; i++) 1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (D1.loaded[i].use_base) 1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown update_D1_use( &D1, i, 0,0); 1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (LL.use) 1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < LL.sets * LL.assoc; i++) 1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (LL.loaded[i].use_base) 1009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown update_LL_use(i, 0); 1010b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1011b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov current_ii = 0; 1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Helper functions called by instrumented code ---*/ 1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __inline__ 1022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid inc_costs(CacheModelResult r, ULong* c1, ULong* c2) 1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch(r) { 1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case WriteBackMemAccess: 1026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (clo_simulate_writeback) { 1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c1[3]++; 1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c2[3]++; 1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // fall through 1031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case MemAccess: 1033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c1[2]++; 1034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c2[2]++; 1035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // fall through 1036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case LL_Hit: 1038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c1[1]++; 1039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c2[1]++; 1040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // fall through 1041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 1043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c1[0]++; 1044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c2[0]++; 1045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 1049436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconst HChar* cacheRes(CacheModelResult r) 1050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch(r) { 1052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case L1_Hit: return "L1 Hit "; 1053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case LL_Hit: return "LL Hit "; 1054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case MemAccess: return "LL Miss"; 1055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case WriteBackMemAccess: return "LL Miss (dirty)"; 1056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 1057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(0); 1058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return "??"; 1060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_REGPARM(1) 1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void log_1I0D(InstrInfo* ii) 1064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CacheModelResult IrRes; 1066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_ii = ii; 1068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IrRes = (*simulator.I1_Read)(CLG_(bb_base) + ii->instr_offset, ii->instr_size); 1069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6, "log_1I0D: Ir %#lx/%u => %s\n", 1071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(bb_base) + ii->instr_offset, ii->instr_size, cacheRes(IrRes)); 1072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).collect) { 1074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong* cost_Ir; 1075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).nonskipped) 1077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Ir = CLG_(current_state).nonskipped->skipped + fullOffset(EG_IR); 1078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 1079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Ir = CLG_(cost_base) + ii->cost_offset + ii->eventset->offset[EG_IR]; 1080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(IrRes, cost_Ir, 1082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_state).cost + fullOffset(EG_IR) ); 1083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_REGPARM(2) 1087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void log_2I0D(InstrInfo* ii1, InstrInfo* ii2) 1088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CacheModelResult Ir1Res, Ir2Res; 1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong *global_cost_Ir; 1091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_ii = ii1; 1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ir1Res = (*simulator.I1_Read)(CLG_(bb_base) + ii1->instr_offset, ii1->instr_size); 1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_ii = ii2; 1095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ir2Res = (*simulator.I1_Read)(CLG_(bb_base) + ii2->instr_offset, ii2->instr_size); 1096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6, "log_2I0D: Ir1 %#lx/%u => %s, Ir2 %#lx/%u => %s\n", 1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(bb_base) + ii1->instr_offset, ii1->instr_size, cacheRes(Ir1Res), 1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(bb_base) + ii2->instr_offset, ii2->instr_size, cacheRes(Ir2Res) ); 1100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!CLG_(current_state).collect) return; 1102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown global_cost_Ir = CLG_(current_state).cost + fullOffset(EG_IR); 1104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).nonskipped) { 1105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong* skipped_cost_Ir = 1106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_state).nonskipped->skipped + fullOffset(EG_IR); 1107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(Ir1Res, global_cost_Ir, skipped_cost_Ir); 1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(Ir2Res, global_cost_Ir, skipped_cost_Ir); 1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(Ir1Res, global_cost_Ir, 1114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cost_base) + ii1->cost_offset + ii1->eventset->offset[EG_IR]); 1115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(Ir2Res, global_cost_Ir, 1116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cost_base) + ii2->cost_offset + ii2->eventset->offset[EG_IR]); 1117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_REGPARM(3) 1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void log_3I0D(InstrInfo* ii1, InstrInfo* ii2, InstrInfo* ii3) 1121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CacheModelResult Ir1Res, Ir2Res, Ir3Res; 1123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong *global_cost_Ir; 1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_ii = ii1; 1126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ir1Res = (*simulator.I1_Read)(CLG_(bb_base) + ii1->instr_offset, ii1->instr_size); 1127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_ii = ii2; 1128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ir2Res = (*simulator.I1_Read)(CLG_(bb_base) + ii2->instr_offset, ii2->instr_size); 1129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_ii = ii3; 1130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Ir3Res = (*simulator.I1_Read)(CLG_(bb_base) + ii3->instr_offset, ii3->instr_size); 1131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6, "log_3I0D: Ir1 %#lx/%u => %s, Ir2 %#lx/%u => %s, Ir3 %#lx/%u => %s\n", 1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(bb_base) + ii1->instr_offset, ii1->instr_size, cacheRes(Ir1Res), 1134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(bb_base) + ii2->instr_offset, ii2->instr_size, cacheRes(Ir2Res), 1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(bb_base) + ii3->instr_offset, ii3->instr_size, cacheRes(Ir3Res) ); 1136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!CLG_(current_state).collect) return; 1138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown global_cost_Ir = CLG_(current_state).cost + fullOffset(EG_IR); 1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).nonskipped) { 1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong* skipped_cost_Ir = 1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_state).nonskipped->skipped + fullOffset(EG_IR); 1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(Ir1Res, global_cost_Ir, skipped_cost_Ir); 1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(Ir2Res, global_cost_Ir, skipped_cost_Ir); 1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(Ir3Res, global_cost_Ir, skipped_cost_Ir); 1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(Ir1Res, global_cost_Ir, 1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cost_base) + ii1->cost_offset + ii1->eventset->offset[EG_IR]); 1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(Ir2Res, global_cost_Ir, 1152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cost_base) + ii2->cost_offset + ii2->eventset->offset[EG_IR]); 1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(Ir3Res, global_cost_Ir, 1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cost_base) + ii3->cost_offset + ii3->eventset->offset[EG_IR]); 1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Instruction doing a read access */ 1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_REGPARM(3) 1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void log_1I1Dr(InstrInfo* ii, Addr data_addr, Word data_size) 1161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CacheModelResult IrRes, DrRes; 1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_ii = ii; 1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IrRes = (*simulator.I1_Read)(CLG_(bb_base) + ii->instr_offset, ii->instr_size); 1166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DrRes = (*simulator.D1_Read)(data_addr, data_size); 1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6, "log_1I1Dr: Ir %#lx/%u => %s, Dr %#lx/%lu => %s\n", 1169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(bb_base) + ii->instr_offset, ii->instr_size, cacheRes(IrRes), 1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown data_addr, data_size, cacheRes(DrRes)); 1171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).collect) { 1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong *cost_Ir, *cost_Dr; 1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).nonskipped) { 1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Ir = CLG_(current_state).nonskipped->skipped + fullOffset(EG_IR); 1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Dr = CLG_(current_state).nonskipped->skipped + fullOffset(EG_DR); 1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Ir = CLG_(cost_base) + ii->cost_offset + ii->eventset->offset[EG_IR]; 1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Dr = CLG_(cost_base) + ii->cost_offset + ii->eventset->offset[EG_DR]; 1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(IrRes, cost_Ir, 1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_state).cost + fullOffset(EG_IR) ); 1186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(DrRes, cost_Dr, 1187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_state).cost + fullOffset(EG_DR) ); 1188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Note that addEvent_D_guarded assumes that log_0I1Dr and log_0I1Dw 1193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov have exactly the same prototype. If you change them, you must 1194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov change addEvent_D_guarded too. */ 1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_REGPARM(3) 1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void log_0I1Dr(InstrInfo* ii, Addr data_addr, Word data_size) 1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CacheModelResult DrRes; 1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_ii = ii; 1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DrRes = (*simulator.D1_Read)(data_addr, data_size); 1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6, "log_0I1Dr: Dr %#lx/%lu => %s\n", 1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown data_addr, data_size, cacheRes(DrRes)); 1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).collect) { 1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong *cost_Dr; 1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).nonskipped) 1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Dr = CLG_(current_state).nonskipped->skipped + fullOffset(EG_DR); 1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 1212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Dr = CLG_(cost_base) + ii->cost_offset + ii->eventset->offset[EG_DR]; 1213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(DrRes, cost_Dr, 1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_state).cost + fullOffset(EG_DR) ); 1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Instruction doing a write access */ 1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_REGPARM(3) 1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void log_1I1Dw(InstrInfo* ii, Addr data_addr, Word data_size) 1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CacheModelResult IrRes, DwRes; 1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_ii = ii; 1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown IrRes = (*simulator.I1_Read)(CLG_(bb_base) + ii->instr_offset, ii->instr_size); 1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DwRes = (*simulator.D1_Write)(data_addr, data_size); 1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6, "log_1I1Dw: Ir %#lx/%u => %s, Dw %#lx/%lu => %s\n", 1232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(bb_base) + ii->instr_offset, ii->instr_size, cacheRes(IrRes), 1233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown data_addr, data_size, cacheRes(DwRes)); 1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).collect) { 1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong *cost_Ir, *cost_Dw; 1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).nonskipped) { 1239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Ir = CLG_(current_state).nonskipped->skipped + fullOffset(EG_IR); 1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Dw = CLG_(current_state).nonskipped->skipped + fullOffset(EG_DW); 1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Ir = CLG_(cost_base) + ii->cost_offset + ii->eventset->offset[EG_IR]; 1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Dw = CLG_(cost_base) + ii->cost_offset + ii->eventset->offset[EG_DW]; 1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(IrRes, cost_Ir, 1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_state).cost + fullOffset(EG_IR) ); 1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(DwRes, cost_Dw, 1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_state).cost + fullOffset(EG_DW) ); 1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1254436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* See comment on log_0I1Dr. */ 1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_REGPARM(3) 1256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void log_0I1Dw(InstrInfo* ii, Addr data_addr, Word data_size) 1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CacheModelResult DwRes; 1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_ii = ii; 1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DwRes = (*simulator.D1_Write)(data_addr, data_size); 1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(6, "log_0I1Dw: Dw %#lx/%lu => %s\n", 1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown data_addr, data_size, cacheRes(DwRes)); 1265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).collect) { 1267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong *cost_Dw; 1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(current_state).nonskipped) 1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Dw = CLG_(current_state).nonskipped->skipped + fullOffset(EG_DW); 1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 1272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost_Dw = CLG_(cost_base) + ii->cost_offset + ii->eventset->offset[EG_DW]; 1273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown inc_costs(DwRes, cost_Dw, 1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_state).cost + fullOffset(EG_DW) ); 1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Cache configuration ---*/ 1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic cache_t clo_I1_cache = UNDEFINED_CACHE; 1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic cache_t clo_D1_cache = UNDEFINED_CACHE; 1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic cache_t clo_LL_cache = UNDEFINED_CACHE; 1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Initialize and clear simulator state */ 1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void cachesim_post_clo_init(void) 1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Cache configurations. */ 1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cache_t I1c, D1c, LLc; 1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Initialize access handlers */ 1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!CLG_(clo).simulate_cache) { 1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_1I0D = 0; 1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_1I0D_name = "(no function)"; 1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_2I0D = 0; 1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_2I0D_name = "(no function)"; 1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_3I0D = 0; 1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_3I0D_name = "(no function)"; 1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_1I1Dr = 0; 1305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_1I1Dr_name = "(no function)"; 1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_1I1Dw = 0; 1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_1I1Dw_name = "(no function)"; 1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_0I1Dr = 0; 1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_0I1Dr_name = "(no function)"; 1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_0I1Dw = 0; 1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_0I1Dw_name = "(no function)"; 1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Configuration of caches only needed with real cache simulation */ 1317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(post_clo_init_configure_caches)(&I1c, &D1c, &LLc, 1318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov &clo_I1_cache, 1319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov &clo_D1_cache, 1320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov &clo_LL_cache); 1321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown I1.name = "I1"; 1323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown D1.name = "D1"; 1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LL.name = "LL"; 1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1326663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // min_line_size is used to make sure that we never feed 1327663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // accesses to the simulator straddling more than two 1328663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // cache lines at any cache level 1329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng CLG_(min_line_size) = (I1c.line_size < D1c.line_size) 1330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ? I1c.line_size : D1c.line_size; 1331663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng CLG_(min_line_size) = (LLc.line_size < CLG_(min_line_size)) 1332663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ? LLc.line_size : CLG_(min_line_size); 1333663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1334663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int largest_load_or_store_size 1335663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = VG_(machine_get_size_of_largest_guest_register)(); 1336663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (CLG_(min_line_size) < largest_load_or_store_size) { 1337663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* We can't continue, because the cache simulation might 1338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng straddle more than 2 lines, and it will assert. So let's 1339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng just stop before we start. */ 1340663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(umsg)("Callgrind: cannot continue: the minimum line size (%d)\n", 1341663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (Int)CLG_(min_line_size)); 1342663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(umsg)(" must be equal to or larger than the maximum register size (%d)\n", 1343663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng largest_load_or_store_size ); 1344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(umsg)(" but it is not. Exiting now.\n"); 1345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(exit)(1); 1346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cachesim_initcache(I1c, &I1); 1349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cachesim_initcache(D1c, &D1); 1350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cachesim_initcache(LLc, &LL); 1351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* the other cache simulators use the standard helpers 1353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * with dispatching via simulator struct */ 1354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_1I0D = log_1I0D; 1356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_1I0D_name = "log_1I0D"; 1357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_2I0D = log_2I0D; 1358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_2I0D_name = "log_2I0D"; 1359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_3I0D = log_3I0D; 1360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_3I0D_name = "log_3I0D"; 1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_1I1Dr = log_1I1Dr; 1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_1I1Dw = log_1I1Dw; 1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_1I1Dr_name = "log_1I1Dr"; 1365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_1I1Dw_name = "log_1I1Dw"; 1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_0I1Dr = log_0I1Dr; 1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_0I1Dw = log_0I1Dw; 1369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_0I1Dr_name = "log_0I1Dr"; 1370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(cachesim).log_0I1Dw_name = "log_0I1Dw"; 1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (clo_collect_cacheuse) { 1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Output warning for not supported option combinations */ 1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (clo_simulate_hwpref) { 1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_DebugMsg, 1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "warning: prefetch simulation can not be " 1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "used with cache usage\n"); 1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown clo_simulate_hwpref = False; 1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (clo_simulate_writeback) { 1383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_DebugMsg, 1384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "warning: write-back simulation can not be " 1385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "used with cache usage\n"); 1386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown clo_simulate_writeback = False; 1387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.I1_Read = cacheuse_I1_doRead; 1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.D1_Read = cacheuse_D1_doRead; 1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.D1_Write = cacheuse_D1_doRead; 1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (clo_simulate_hwpref) { 1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prefetch_clear(); 1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (clo_simulate_writeback) { 1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.I1_Read = prefetch_I1_Read; 1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.D1_Read = prefetch_D1_Read; 1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.D1_Write = prefetch_D1_Write; 1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.I1_Read = prefetch_I1_ref; 1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.D1_Read = prefetch_D1_ref; 1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.D1_Write = prefetch_D1_ref; 1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (clo_simulate_writeback) { 1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.I1_Read = cachesim_I1_Read; 1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.D1_Read = cachesim_D1_Read; 1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.D1_Write = cachesim_D1_Write; 1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.I1_Read = cachesim_I1_ref; 1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.D1_Read = cachesim_D1_ref; 1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown simulator.D1_Write = cachesim_D1_ref; 1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Clear simulator state. Has to be initialized before */ 1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid cachesim_clear(void) 1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cachesim_clearcache(&I1); 1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cachesim_clearcache(&D1); 1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cachesim_clearcache(&LL); 1432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prefetch_clear(); 1434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1437436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void cachesim_getdesc(HChar* buf) 1438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int p; 1440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = VG_(sprintf)(buf, "\ndesc: I1 cache: %s\n", I1.desc_line); 1441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p += VG_(sprintf)(buf+p, "desc: D1 cache: %s\n", D1.desc_line); 1442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf+p, "desc: LL cache: %s\n", LL.desc_line); 1443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 1446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid cachesim_print_opts(void) 1447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)( 1449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown"\n cache simulator options (does cache simulation if used):\n" 1450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --simulate-wb=no|yes Count write-back events [no]\n" 1451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --simulate-hwpref=no|yes Simulate hardware prefetch [no]\n" 1452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if CLG_EXPERIMENTAL 1453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --simulate-sectors=no|yes Simulate sectored behaviour [no]\n" 1454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 1455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" --cacheuse=no|yes Collect cache block use [no]\n"); 1456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(print_cache_clo_opts)(); 1457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Check for command line option for cache configuration. 1460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Return False if unknown and not handled. 1461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 1462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Called from CLG_(process_cmd_line_option)() in clo.c 1463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic Bool cachesim_parse_opt(const HChar* arg) 1465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if VG_BOOL_CLO(arg, "--simulate-wb", clo_simulate_writeback) {} 1467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--simulate-hwpref", clo_simulate_hwpref) {} 1468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--simulate-sectors", clo_simulate_sectors) {} 1469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--cacheuse", clo_collect_cacheuse) { 1471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (clo_collect_cacheuse) { 1472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Use counters only make sense with fine dumping */ 1473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(clo).dump_instr = True; 1474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else if (VG_(str_clo_cache_opt)(arg, 1478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov &clo_I1_cache, 1479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov &clo_D1_cache, 1480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov &clo_LL_cache)) {} 1481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 1483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return False; 1484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 1486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Adds commas to ULong, right justifying in a field field_width wide, returns 1489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * the string in buf. */ 1490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 1491436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy IvanovInt commify(ULong n, int field_width, HChar* buf) 1492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int len, n_commas, i, j, new_len, space; 1494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "%llu", n); 1496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len = VG_(strlen)(buf); 1497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_commas = (len - 1) / 3; 1498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown new_len = len + n_commas; 1499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown space = field_width - new_len; 1500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Allow for printing a number in a field_width smaller than it's size */ 1502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (space < 0) space = 0; 1503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Make j = -1 because we copy the '\0' before doing the numbers in groups 1505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * of three. */ 1506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = -1, i = len ; i >= 0; i--) { 1507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf[i + n_commas + space] = buf[i]; 1508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((i>0) && (3 == ++j)) { 1510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown j = 0; 1511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_commas--; 1512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf[i + n_commas + space] = ','; 1513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Right justify in field. */ 1516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < space; i++) buf[i] = ' '; 1517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return new_len; 1518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 1521436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid percentify(Int n, Int ex, Int field_width, HChar buf[]) 1522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i, len, space; 1524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "%d.%d%%", n / ex, n % ex); 1526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len = VG_(strlen)(buf); 1527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown space = field_width - len; 1528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (space < 0) space = 0; /* Allow for v. small field_width */ 1529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i = len; 1530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Right justify in field */ 1532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for ( ; i >= 0; i--) buf[i + space] = buf[i]; 1533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < space; i++) buf[i] = ' '; 1534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 1537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid cachesim_printstat(Int l1, Int l2, Int l3) 1538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown FullCost total = CLG_(total_cost), D_total = 0; 1540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong LL_total_m, LL_total_mr, LL_total_mw, 1541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LL_total, LL_total_r, LL_total_w; 1542436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar buf1[RESULTS_BUF_LEN], 1543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf2[RESULTS_BUF_LEN], 1544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf3[RESULTS_BUF_LEN]; 1545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int p; 1546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((VG_(clo_verbosity) >1) && clo_simulate_hwpref) { 1548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_DebugMsg, "Prefetch Up: %llu\n", 1549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prefetch_up); 1550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_DebugMsg, "Prefetch Down: %llu\n", 1551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown prefetch_down); 1552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_DebugMsg, "\n"); 1553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(total[fullOffset(EG_IR) +1], l1, buf1); 1556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "I1 misses: %s\n", buf1); 1557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(total[fullOffset(EG_IR) +2], l1, buf1); 1559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "LLi misses: %s\n", buf1); 1560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = 100; 1562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 == total[fullOffset(EG_IR)]) 1564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_IR)] = 1; 1565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown percentify(total[fullOffset(EG_IR)+1] * 100 * p / 1567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_IR)], p, l1+1, buf1); 1568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "I1 miss rate: %s\n", buf1); 1569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown percentify(total[fullOffset(EG_IR)+2] * 100 * p / 1571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_IR)], p, l1+1, buf1); 1572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "LLi miss rate: %s\n", buf1); 1573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "\n"); 1574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* D cache results. 1576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Use the D_refs.rd and D_refs.wr values to determine the 1577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * width of columns 2 & 3. */ 1578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown D_total = CLG_(get_eventset_cost)( CLG_(sets).full ); 1580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(init_cost)( CLG_(sets).full, D_total); 1581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // we only use the first 3 values of D_total, adding up Dr and Dw costs 1582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(copy_cost)( CLG_(get_event_set)(EG_DR), D_total, total + fullOffset(EG_DR) ); 1583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(add_cost) ( CLG_(get_event_set)(EG_DW), D_total, total + fullOffset(EG_DW) ); 1584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify( D_total[0], l1, buf1); 1586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(total[fullOffset(EG_DR)], l2, buf2); 1587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(total[fullOffset(EG_DW)], l3, buf3); 1588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "D refs: %s (%s rd + %s wr)\n", 1589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf1, buf2, buf3); 1590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify( D_total[1], l1, buf1); 1592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(total[fullOffset(EG_DR)+1], l2, buf2); 1593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(total[fullOffset(EG_DW)+1], l3, buf3); 1594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "D1 misses: %s (%s rd + %s wr)\n", 1595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf1, buf2, buf3); 1596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify( D_total[2], l1, buf1); 1598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(total[fullOffset(EG_DR)+2], l2, buf2); 1599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(total[fullOffset(EG_DW)+2], l3, buf3); 1600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "LLd misses: %s (%s rd + %s wr)\n", 1601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf1, buf2, buf3); 1602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = 10; 1604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 == D_total[0]) D_total[0] = 1; 1606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 == total[fullOffset(EG_DR)]) total[fullOffset(EG_DR)] = 1; 1607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 == total[fullOffset(EG_DW)]) total[fullOffset(EG_DW)] = 1; 1608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown percentify( D_total[1] * 100 * p / D_total[0], p, l1+1, buf1); 1610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown percentify(total[fullOffset(EG_DR)+1] * 100 * p / 1611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_DR)], p, l2+1, buf2); 1612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown percentify(total[fullOffset(EG_DW)+1] * 100 * p / 1613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_DW)], p, l3+1, buf3); 1614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "D1 miss rate: %s (%s + %s )\n", 1615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf1, buf2,buf3); 1616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown percentify( D_total[2] * 100 * p / D_total[0], p, l1+1, buf1); 1618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown percentify(total[fullOffset(EG_DR)+2] * 100 * p / 1619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_DR)], p, l2+1, buf2); 1620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown percentify(total[fullOffset(EG_DW)+2] * 100 * p / 1621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_DW)], p, l3+1, buf3); 1622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "LLd miss rate: %s (%s + %s )\n", 1623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf1, buf2,buf3); 1624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "\n"); 1625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* LL overall results */ 1629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LL_total = 1631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_DR) +1] + 1632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_DW) +1] + 1633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_IR) +1]; 1634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LL_total_r = 1635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_DR) +1] + 1636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_IR) +1]; 1637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LL_total_w = total[fullOffset(EG_DW) +1]; 1638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(LL_total, l1, buf1); 1639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(LL_total_r, l2, buf2); 1640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(LL_total_w, l3, buf3); 1641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "LL refs: %s (%s rd + %s wr)\n", 1642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf1, buf2, buf3); 1643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LL_total_m = 1645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_DR) +2] + 1646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_DW) +2] + 1647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_IR) +2]; 1648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LL_total_mr = 1649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_DR) +2] + 1650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_IR) +2]; 1651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LL_total_mw = total[fullOffset(EG_DW) +2]; 1652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(LL_total_m, l1, buf1); 1653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(LL_total_mr, l2, buf2); 1654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown commify(LL_total_mw, l3, buf3); 1655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "LL misses: %s (%s rd + %s wr)\n", 1656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf1, buf2, buf3); 1657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown percentify(LL_total_m * 100 * p / 1659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (total[fullOffset(EG_IR)] + D_total[0]), p, l1+1, buf1); 1660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown percentify(LL_total_mr * 100 * p / 1661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (total[fullOffset(EG_IR)] + total[fullOffset(EG_DR)]), 1662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p, l2+1, buf2); 1663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown percentify(LL_total_mw * 100 * p / 1664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown total[fullOffset(EG_DW)], p, l3+1, buf3); 1665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, "LL miss rate: %s (%s + %s )\n", 1666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown buf1, buf2,buf3); 1667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Setup for Event set. ---*/ 1672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct event_sets CLG_(sets); 1675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_eventsets)() 1677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Event groups from which the event sets are composed 1679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the "Use" group only is used with "cacheuse" simulation 1680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (clo_collect_cacheuse) 1681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(register_event_group4)(EG_USE, 1682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "AcCost1", "SpLoss1", "AcCost2", "SpLoss2"); 1683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!CLG_(clo).simulate_cache) 1685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(register_event_group)(EG_IR, "Ir"); 1686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (!clo_simulate_writeback) { 1687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(register_event_group3)(EG_IR, "Ir", "I1mr", "ILmr"); 1688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(register_event_group3)(EG_DR, "Dr", "D1mr", "DLmr"); 1689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(register_event_group3)(EG_DW, "Dw", "D1mw", "DLmw"); 1690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { // clo_simulate_writeback 1692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(register_event_group4)(EG_IR, "Ir", "I1mr", "ILmr", "ILdmr"); 1693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(register_event_group4)(EG_DR, "Dr", "D1mr", "DLmr", "DLdmr"); 1694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(register_event_group4)(EG_DW, "Dw", "D1mw", "DLmw", "DLdmw"); 1695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(clo).simulate_branch) { 1698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(register_event_group2)(EG_BC, "Bc", "Bcm"); 1699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(register_event_group2)(EG_BI, "Bi", "Bim"); 1700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(clo).collect_bus) 1703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(register_event_group)(EG_BUS, "Ge"); 1704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(clo).collect_alloc) 1706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(register_event_group2)(EG_ALLOC, "allocCount", "allocSize"); 1707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (CLG_(clo).collect_systime) 1709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(register_event_group2)(EG_SYS, "sysCount", "sysTime"); 1710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // event set used as base for instruction self cost 1712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(sets).base = CLG_(get_event_set2)(EG_USE, EG_IR); 1713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // event set comprising all event groups, used for inclusive cost 1715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(sets).full = CLG_(add_event_group2)(CLG_(sets).base, EG_DR, EG_DW); 1716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(sets).full = CLG_(add_event_group2)(CLG_(sets).full, EG_BC, EG_BI); 1717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(sets).full = CLG_(add_event_group) (CLG_(sets).full, EG_BUS); 1718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(sets).full = CLG_(add_event_group2)(CLG_(sets).full, EG_ALLOC, EG_SYS); 1719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUGIF(1) { 1721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(1, "EventSets:\n"); 1722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(print_eventset)(-2, CLG_(sets).base); 1723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(print_eventset)(-2, CLG_(sets).full); 1724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Not-existing events are silently ignored */ 1727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(dumpmap) = CLG_(get_eventmapping)(CLG_(sets).full); 1728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "Ir"); 1729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "Dr"); 1730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "Dw"); 1731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "I1mr"); 1732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "D1mr"); 1733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "D1mw"); 1734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "ILmr"); 1735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "DLmr"); 1736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "DLmw"); 1737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "ILdmr"); 1738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "DLdmr"); 1739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "DLdmw"); 1740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "Bc"); 1741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "Bcm"); 1742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "Bi"); 1743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "Bim"); 1744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "AcCost1"); 1745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "SpLoss1"); 1746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "AcCost2"); 1747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "SpLoss2"); 1748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "Ge"); 1749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "allocCount"); 1750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "allocSize"); 1751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "sysCount"); 1752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(append_event)(CLG_(dumpmap), "sysTime"); 1753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* this is called at dump time for every instruction executed */ 1757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void cachesim_add_icost(SimCost cost, BBCC* bbcc, 1758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown InstrInfo* ii, ULong exe_count) 1759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!CLG_(clo).simulate_cache) 1761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cost[ fullOffset(EG_IR) ] += exe_count; 1762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ii->eventset) 1764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(add_and_zero_cost2)( CLG_(sets).full, cost, 1765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ii->eventset, bbcc->cost + ii->cost_offset); 1766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 1769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid cachesim_finish(void) 1770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (clo_collect_cacheuse) 1772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cacheuse_finish(); 1773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- The simulator defined in this file ---*/ 1777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct cachesim_if CLG_(cachesim) = { 1780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .print_opts = cachesim_print_opts, 1781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .parse_opt = cachesim_parse_opt, 1782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .post_clo_init = cachesim_post_clo_init, 1783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .clear = cachesim_clear, 1784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .getdesc = cachesim_getdesc, 1785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .printstat = cachesim_printstat, 1786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .add_icost = cachesim_add_icost, 1787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .finish = cachesim_finish, 1788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* these will be set by cachesim_post_clo_init */ 1790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_1I0D = 0, 1791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_2I0D = 0, 1792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_3I0D = 0, 1793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_1I1Dr = 0, 1795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_1I1Dw = 0, 1796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_0I1Dr = 0, 1798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_0I1Dw = 0, 1799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_1I0D_name = "(no function)", 1801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_2I0D_name = "(no function)", 1802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_3I0D_name = "(no function)", 1803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_1I1Dr_name = "(no function)", 1805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_1I1Dw_name = "(no function)", 1806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_0I1Dr_name = "(no function)", 1808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .log_0I1Dw_name = "(no function)", 1809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}; 1810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 1813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end ct_sim.c ---*/ 1814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 1815