source: branches/RWT/modules/vci_mem_cache/caba/source/include/mem_cache_directory.h @ 822

Last change on this file since 822 was 814, checked in by devigne, 10 years ago

RWT commit : Cosmetic (Remove trailing whitespace)

File size: 23.6 KB
RevLine 
[307]1#ifndef SOCLIB_CABA_MEM_CACHE_DIRECTORY_H
[814]2#define SOCLIB_CABA_MEM_CACHE_DIRECTORY_H
[307]3
4#include <inttypes.h>
5#include <systemc>
6#include <cassert>
7#include "arithmetics.h"
8
9//#define RANDOM_EVICTION
10
11namespace soclib { namespace caba {
12
13  using namespace sc_core;
14
15  ////////////////////////////////////////////////////////////////////////
[814]16  //                    A LRU entry
[307]17  ////////////////////////////////////////////////////////////////////////
18  class LruEntry {
19
20    public:
21
[814]22      bool recent;
[307]23
24      void init()
25      {
26        recent=false;
27      }
28
29  }; // end class LruEntry
30
31  ////////////////////////////////////////////////////////////////////////
32  //                    An Owner
33  ////////////////////////////////////////////////////////////////////////
34  class Owner{
[814]35
[307]36    public:
37    // Fields
38      bool      inst;       // Is the owner an ICache ?
39      size_t    srcid;      // The SRCID of the owner
40
41    ////////////////////////
42    // Constructors
43    ////////////////////////
[495]44      Owner(bool   i_inst,
45            size_t i_srcid)
46      {
[307]47        inst    = i_inst;
48        srcid   = i_srcid;
49      }
50
[495]51      Owner(const Owner &a)
52      {
[307]53        inst    = a.inst;
54        srcid   = a.srcid;
55      }
56
[495]57      Owner()
58      {
[307]59        inst    = false;
60        srcid   = 0;
61      }
62      // end constructors
63
64  }; // end class Owner
65
66
67  ////////////////////////////////////////////////////////////////////////
[814]68  //                    A directory entry
[307]69  ////////////////////////////////////////////////////////////////////////
70  class DirectoryEntry {
71
72    typedef uint32_t tag_t;
73
74    public:
75
76    bool    valid;                  // entry valid
[477]77    bool    cache_coherent;         // WB or WT policy
[307]78    bool    is_cnt;                 // directory entry is in counter mode
79    bool    dirty;                  // entry dirty
80    bool    lock;                   // entry locked
81    tag_t   tag;                    // tag of the entry
82    size_t  count;                  // number of copies
[814]83    Owner   owner;                  // an owner of the line
[307]84    size_t  ptr;                    // pointer to the next owner
85
86    DirectoryEntry()
87    {
88      valid         = false;
[477]89      cache_coherent= false;
[307]90      is_cnt        = false;
91      dirty         = false;
92      lock          = false;
93      tag           = 0;
94      count         = 0;
95      owner.inst    = 0;
96      owner.srcid   = 0;
97      ptr           = 0;
98    }
99
100    DirectoryEntry(const DirectoryEntry &source)
101    {
102      valid         = source.valid;
[477]103      cache_coherent= source.cache_coherent;
[307]104      is_cnt        = source.is_cnt;
105      dirty         = source.dirty;
106      lock          = source.lock;
107      tag           = source.tag;
108      count         = source.count;
109      owner         = source.owner;
110      ptr           = source.ptr;
[814]111    }
[307]112
113    /////////////////////////////////////////////////////////////////////
[814]114    // The init() function initializes the entry
[307]115    /////////////////////////////////////////////////////////////////////
116    void init()
117    {
118      valid     = false;
[477]119      cache_coherent = false;
[307]120      is_cnt    = false;
121      dirty     = false;
122      lock      = false;
123      count     = 0;
124    }
125
126    /////////////////////////////////////////////////////////////////////
[814]127    // The copy() function copies an existing source entry to a target
[307]128    /////////////////////////////////////////////////////////////////////
129    void copy(const DirectoryEntry &source)
130    {
[814]131      valid     = source.valid;
[477]132      cache_coherent = source.cache_coherent;
[307]133      is_cnt    = source.is_cnt;
[814]134      dirty     = source.dirty;
135      lock      = source.lock;
136      tag       = source.tag;
[307]137      count     = source.count;
138      owner     = source.owner;
139      ptr       = source.ptr;
140    }
141
142    ////////////////////////////////////////////////////////////////////
[814]143    // The print() function prints the entry
[307]144    ////////////////////////////////////////////////////////////////////
145    void print()
146    {
[814]147      std::cout << "Valid = " << valid
[477]148                << " ; COHERENCE = " << cache_coherent
[814]149                << " ; IS COUNT = " << is_cnt
150                << " ; Dirty = " << dirty
151                << " ; Lock = " << lock
152                << " ; Tag = " << std::hex << tag << std::dec
153                << " ; Count = " << count
154                << " ; Owner = " << owner.srcid
155                << " " << owner.inst
[307]156                << " ; Pointer = " << ptr << std::endl;
157    }
158
159  }; // end class DirectoryEntry
160
161  ////////////////////////////////////////////////////////////////////////
[814]162  //                       The directory
[307]163  ////////////////////////////////////////////////////////////////////////
164  class CacheDirectory {
165
166    typedef sc_dt::sc_uint<40> addr_t;
167    typedef uint32_t data_t;
168    typedef uint32_t tag_t;
169
170    private:
171
172    // Directory constants
[814]173    size_t   m_ways;
174    size_t   m_sets;
175    size_t   m_words;
176    size_t   m_width;
177    uint32_t lfsr;
[307]178
179    // the directory & lru tables
[814]180    DirectoryEntry **m_dir_tab;
181    LruEntry       **m_lru_tab;
[307]182
183    public:
184
185    ////////////////////////
186    // Constructor
187    ////////////////////////
[814]188    CacheDirectory( size_t ways, size_t sets, size_t words, size_t address_width)
[307]189    {
[814]190      m_ways  = ways;
[307]191      m_sets  = sets;
192      m_words = words;
193      m_width = address_width;
194      lfsr = -1;
195
196      m_dir_tab = new DirectoryEntry*[sets];
197      for ( size_t i=0; i<sets; i++ ) {
198        m_dir_tab[i] = new DirectoryEntry[ways];
199        for ( size_t j=0 ; j<ways ; j++) m_dir_tab[i][j].init();
200      }
201      m_lru_tab = new LruEntry*[sets];
202      for ( size_t i=0; i<sets; i++ ) {
203        m_lru_tab[i] = new LruEntry[ways];
204        for ( size_t j=0 ; j<ways ; j++) m_lru_tab[i][j].init();
205      }
206    } // end constructor
207
208    /////////////////
209    // Destructor
210    /////////////////
211    ~CacheDirectory()
212    {
213      for(size_t i=0 ; i<m_sets ; i++){
214        delete [] m_dir_tab[i];
215        delete [] m_lru_tab[i];
216      }
217      delete [] m_dir_tab;
218      delete [] m_lru_tab;
219    } // end destructor
220
221    /////////////////////////////////////////////////////////////////////
222    // The read() function reads a directory entry. In case of hit, the
223    // LRU is updated.
224    // Arguments :
[814]225    // - address : the address of the entry
[307]226    // - way : (return argument) the way of the entry in case of hit
[814]227    // The function returns a copy of a (valid or invalid) entry
[307]228    /////////////////////////////////////////////////////////////////////
[449]229    DirectoryEntry read(const addr_t &address, size_t &way)
[307]230    {
231
232#define L2 soclib::common::uint32_log2
233      const size_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1);
234      const tag_t  tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2));
235#undef L2
236
237      bool hit       = false;
238      for ( size_t i=0 ; i<m_ways ; i++ ) {
239        bool equal = ( m_dir_tab[set][i].tag == tag );
240        bool valid = m_dir_tab[set][i].valid;
241        hit = equal && valid;
[814]242        if ( hit ) {
[307]243          way = i;
244          break;
[814]245        }
[307]246      }
247      if ( hit ) {
248        m_lru_tab[set][way].recent = true;
249        return DirectoryEntry(m_dir_tab[set][way]);
250      } else {
251        return DirectoryEntry();
252      }
253    } // end read()
254
255    /////////////////////////////////////////////////////////////////////
[434]256    // The inval function invalidate an entry defined by the set and
[814]257    // way arguments.
[434]258    /////////////////////////////////////////////////////////////////////
[449]259    void inval( const size_t &way, const size_t &set )
[434]260    {
261        m_dir_tab[set][way].init();
262    }
263
264    /////////////////////////////////////////////////////////////////////
[307]265    // The read_neutral() function reads a directory entry, without
266    // changing the LRU
267    // Arguments :
[814]268    // - address : the address of the entry
269    // The function returns a copy of a (valid or invalid) entry
[307]270    /////////////////////////////////////////////////////////////////////
[814]271    DirectoryEntry read_neutral( const addr_t &address,
[449]272                                 size_t*      ret_way,
273                                 size_t*      ret_set )
[307]274    {
275
276#define L2 soclib::common::uint32_log2
[449]277        size_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1);
278        tag_t  tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2));
[307]279#undef L2
280
[814]281        for ( size_t way = 0 ; way < m_ways ; way++ )
[449]282        {
283            bool equal = ( m_dir_tab[set][way].tag == tag );
284            bool valid = m_dir_tab[set][way].valid;
285            if ( equal and valid )
286            {
287                *ret_set = set;
[814]288                *ret_way = way;
[449]289                return DirectoryEntry(m_dir_tab[set][way]);
290            }
[814]291        }
[449]292        return DirectoryEntry();
[307]293    } // end read_neutral()
294
295    /////////////////////////////////////////////////////////////////////
[814]296    // The write function writes a new entry,
[307]297    // and updates the LRU bits if necessary.
298    // Arguments :
299    // - set : the set of the entry
300    // - way : the way of the entry
301    // - entry : the entry value
302    /////////////////////////////////////////////////////////////////////
[814]303    void write( const size_t         &set,
304                const size_t         &way,
[495]305                const DirectoryEntry &entry)
[307]306    {
[814]307      assert( (set<m_sets)
[307]308          && "Cache Directory write : The set index is invalid");
[814]309      assert( (way<m_ways)
[307]310          && "Cache Directory write : The way index is invalid");
311
312      // update Directory
313      m_dir_tab[set][way].copy(entry);
314
315      // update LRU bits
316      bool all_recent = true;
[814]317      for ( size_t i=0 ; i<m_ways ; i++ )
[434]318      {
319          if ( i != way ) all_recent = m_lru_tab[set][i].recent && all_recent;
[307]320      }
[814]321      if ( all_recent )
[434]322      {
323          for( size_t i=0 ; i<m_ways ; i++ ) m_lru_tab[set][i].recent = false;
[814]324      }
325      else
[434]326      {
327          m_lru_tab[set][way].recent = true;
[307]328      }
329    } // end write()
330
331    /////////////////////////////////////////////////////////////////////
332    // The print() function prints a selected directory entry
333    // Arguments :
334    // - set : the set of the entry to print
335    // - way : the way of the entry to print
336    /////////////////////////////////////////////////////////////////////
337    void print(const size_t &set, const size_t &way)
338    {
339      std::cout << std::dec << " set : " << set << " ; way : " << way << " ; " ;
340      m_dir_tab[set][way].print();
341    } // end print()
342
343    /////////////////////////////////////////////////////////////////////
344    // The select() function selects a directory entry to evince.
345    // Arguments :
346    // - set   : (input argument) the set to modify
347    // - way   : (return argument) the way to evince
348    /////////////////////////////////////////////////////////////////////
349    DirectoryEntry select(const size_t &set, size_t &way)
350    {
[814]351        assert( (set < m_sets)
[307]352          && "Cache Directory : (select) The set index is invalid");
353
[495]354        // looking for an empty slot
355        for(size_t i=0; i<m_ways; i++)
356        {
357            if( not m_dir_tab[set][i].valid )
358            {
359                way=i;
360                return DirectoryEntry(m_dir_tab[set][way]);
361            }
[307]362        }
363
364#ifdef RANDOM_EVICTION
[495]365        lfsr = (lfsr >> 1) ^ ((-(lfsr & 1)) & 0xd0000001);
366        way = lfsr % m_ways;
367        return DirectoryEntry(m_dir_tab[set][way]);
[307]368#endif
369
[495]370        // looking for a not locked and not recently used entry
371        for(size_t i=0; i<m_ways; i++)
372        {
373            if((not m_lru_tab[set][i].recent) && (not m_dir_tab[set][i].lock) )
374            {
375                way=i;
376                return DirectoryEntry(m_dir_tab[set][way]);
377            }
[307]378        }
[495]379
380        // looking for a locked not recently used entry
381        for(size_t i=0; i<m_ways; i++)
382        {
383            if( (not m_lru_tab[set][i].recent) && (m_dir_tab[set][i].lock))
384            {
385                way=i;
386                return DirectoryEntry(m_dir_tab[set][way]);
387            }
[307]388        }
[495]389
390        // looking for a recently used entry not locked
391        for(size_t i=0; i<m_ways; i++)
392        {
393            if( (m_lru_tab[set][i].recent) && (not m_dir_tab[set][i].lock))
394            {
395                way=i;
396                return DirectoryEntry(m_dir_tab[set][way]);
397            }
[307]398        }
[495]399
400        // select way 0 (even if entry is locked and recently used)
401        way = 0;
402        return DirectoryEntry(m_dir_tab[set][0]);
[307]403    } // end select()
404
405    /////////////////////////////////////////////////////////////////////
[814]406    //               Global initialisation function
[307]407    /////////////////////////////////////////////////////////////////////
408    void init()
409    {
[814]410      for ( size_t set=0 ; set<m_sets ; set++ )
[449]411      {
[814]412        for ( size_t way=0 ; way<m_ways ; way++ )
[449]413        {
[307]414          m_dir_tab[set][way].init();
415          m_lru_tab[set][way].init();
416        }
417      }
418    } // end init()
419
420  }; // end class CacheDirectory
421
422  ///////////////////////////////////////////////////////////////////////
423  //                    A Heap Entry
424  ///////////////////////////////////////////////////////////////////////
425  class HeapEntry{
426
427    public:
428    // Fields of the entry
429      Owner     owner;
430      size_t    next;
431
432    ////////////////////////
433    // Constructor
434    ////////////////////////
435      HeapEntry()
[495]436      :owner(false,0)
[307]437      {
438        next = 0;
439      } // end constructor
440
441    ////////////////////////
442    // Constructor
443    ////////////////////////
[495]444      HeapEntry(const HeapEntry &entry)
445      {
[307]446        owner.inst  = entry.owner.inst;
447        owner.srcid = entry.owner.srcid;
[814]448        next        = entry.next;
[307]449      } // end constructor
450
451    /////////////////////////////////////////////////////////////////////
[814]452    // The copy() function copies an existing source entry to a target
[307]453    /////////////////////////////////////////////////////////////////////
[495]454      void copy(const HeapEntry &entry)
455      {
[814]456        owner.inst  = entry.owner.inst;
457        owner.srcid = entry.owner.srcid;
458        next        = entry.next;
[307]459      } // end copy()
460
461    ////////////////////////////////////////////////////////////////////
[814]462    // The print() function prints the entry
[307]463    ////////////////////////////////////////////////////////////////////
464      void print(){
[814]465        std::cout
[307]466        << " -- owner.inst     : " << std::dec << owner.inst << std::endl
467        << " -- owner.srcid    : " << std::dec << owner.srcid << std::endl
468        << " -- next           : " << std::dec << next << std::endl;
469
470      } // end print()
471
472  }; // end class HeapEntry
473
474  ////////////////////////////////////////////////////////////////////////
[814]475  //                        The Heap
[307]476  ////////////////////////////////////////////////////////////////////////
477  class HeapDirectory{
[814]478
[307]479    private:
480    // Registers and the heap
481      size_t    ptr_free;
482      bool      full;
483      HeapEntry *m_heap_tab;
484
485    // Constants for debugging purpose
486      size_t    tab_size;
487
488    public:
489    ////////////////////////
490    // Constructor
491    ////////////////////////
492      HeapDirectory(uint32_t size){
493        assert(size>0 && "Memory Cache, HeapDirectory constructor : invalid size");
494        ptr_free    = 0;
495        full        = false;
496        m_heap_tab  = new HeapEntry[size];
497        tab_size    = size;
498      } // end constructor
499
500    /////////////////
501    // Destructor
502    /////////////////
503      ~HeapDirectory(){
504        delete [] m_heap_tab;
505      } // end destructor
506
507    /////////////////////////////////////////////////////////////////////
[814]508    //              Global initialisation function
[307]509    /////////////////////////////////////////////////////////////////////
510      void init(){
511        ptr_free=0;
512        full=false;
513        for(size_t i=0; i< tab_size-1;i++){
514          m_heap_tab[i].next = i+1;
515        }
516        m_heap_tab[tab_size-1].next = tab_size-1;
517        return;
518      }
519
520    /////////////////////////////////////////////////////////////////////
521    // The print() function prints a selected directory entry
522    // Arguments :
523    // - ptr : the pointer to the entry to print
524    /////////////////////////////////////////////////////////////////////
525      void print(const size_t &ptr){
526        std::cout << "Heap, printing the entry : " << std::dec << ptr << std::endl;
527        m_heap_tab[ptr].print();
528      } // end print()
529
530    /////////////////////////////////////////////////////////////////////
531    // The print_list() function prints a list from selected directory entry
532    // Arguments :
533    // - ptr : the pointer to the first entry to print
534    /////////////////////////////////////////////////////////////////////
535      void print_list(const size_t &ptr){
536        bool end = false;
537        size_t ptr_temp = ptr;
538        std::cout << "Heap, printing the list from : " << std::dec << ptr << std::endl;
539        while(!end){
540            m_heap_tab[ptr_temp].print();
541            if(ptr_temp == m_heap_tab[ptr_temp].next) end = true;
542            ptr_temp = m_heap_tab[ptr_temp].next;
[814]543        }
[307]544      } // end print_list()
545
546    /////////////////////////////////////////////////////////////////////
547    // The is_full() function return true if the heap is full.
548    /////////////////////////////////////////////////////////////////////
549      bool is_full(){
550        return full;
551      } // end is_full()
552
553    /////////////////////////////////////////////////////////////////////
[814]554    // The next_free_ptr() function returns the pointer
[307]555    // to the next free entry.
556    /////////////////////////////////////////////////////////////////////
557      size_t next_free_ptr(){
558        return ptr_free;
559      } // end next_free_ptr()
560
561    /////////////////////////////////////////////////////////////////////
[814]562    // The next_free_entry() function returns
[307]563    // a copy of the next free entry.
564    /////////////////////////////////////////////////////////////////////
565      HeapEntry next_free_entry(){
566        return HeapEntry(m_heap_tab[ptr_free]);
567      } // end next_free_entry()
[814]568
[307]569    /////////////////////////////////////////////////////////////////////
570    // The write_free_entry() function modify the next free entry.
571    // Arguments :
572    // - entry : the entry to write
573    /////////////////////////////////////////////////////////////////////
574      void write_free_entry(const HeapEntry &entry){
575        m_heap_tab[ptr_free].copy(entry);
576      } // end write_free_entry()
577
578    /////////////////////////////////////////////////////////////////////
579    // The write_free_ptr() function writes the pointer
580    // to the next free entry
581    /////////////////////////////////////////////////////////////////////
582      void write_free_ptr(const size_t &ptr){
583        assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer");
584        ptr_free = ptr;
585      } // end write_free_ptr()
586
587    /////////////////////////////////////////////////////////////////////
588    // The set_full() function sets the full bit (to true).
589    /////////////////////////////////////////////////////////////////////
590      void set_full(){
591        full = true;
592      } // end set_full()
593
594    /////////////////////////////////////////////////////////////////////
595    // The unset_full() function unsets the full bit (to false).
596    /////////////////////////////////////////////////////////////////////
597      void unset_full(){
598        full = false;
599      } // end unset_full()
600
601    /////////////////////////////////////////////////////////////////////
602    // The read() function returns a copy of
603    // the entry pointed by the argument
604    // Arguments :
605    //  - ptr : the pointer to the entry to read
606    /////////////////////////////////////////////////////////////////////
607      HeapEntry read(const size_t &ptr){
608        assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer");
609        return HeapEntry(m_heap_tab[ptr]);
610      } // end read()
611
612    /////////////////////////////////////////////////////////////////////
613    // The write() function writes an entry in the heap
614    // Arguments :
615    //  - ptr : the pointer to the entry to replace
616    //  - entry : the entry to write
617    /////////////////////////////////////////////////////////////////////
618      void write(const size_t &ptr, const HeapEntry &entry){
619        assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer");
620        m_heap_tab[ptr].copy(entry);
621      } // end write()
622
623  }; // end class HeapDirectory
624
625  ////////////////////////////////////////////////////////////////////////
[814]626  //                        Cache Data
[307]627  ////////////////////////////////////////////////////////////////////////
[814]628  class CacheData
[495]629  {
[307]630    private:
631      const uint32_t m_sets;
632      const uint32_t m_ways;
633      const uint32_t m_words;
634
635      uint32_t *** m_cache_data;
636
637    public:
638
[495]639      ///////////////////////////////////////////////////////
[307]640      CacheData(uint32_t ways, uint32_t sets, uint32_t words)
[814]641        : m_sets(sets), m_ways(ways), m_words(words)
[495]642      {
[307]643          m_cache_data = new uint32_t ** [ways];
[814]644          for ( size_t i=0 ; i < ways ; i++ )
[495]645          {
646              m_cache_data[i] = new uint32_t * [sets];
[307]647          }
[814]648          for ( size_t i=0; i<ways; i++ )
[495]649          {
[814]650              for ( size_t j=0; j<sets; j++ )
[495]651              {
652                  m_cache_data[i][j] = new uint32_t [words];
653              }
[307]654          }
[495]655      }
656      ////////////
[814]657      ~CacheData()
[495]658      {
659          for(size_t i=0; i<m_ways ; i++)
660          {
661              for(size_t j=0; j<m_sets ; j++)
662              {
[307]663                  delete [] m_cache_data[i][j];
664              }
665          }
[495]666          for(size_t i=0; i<m_ways ; i++)
667          {
[307]668              delete [] m_cache_data[i];
669          }
670          delete [] m_cache_data;
671      }
[495]672      //////////////////////////////////////////
673      uint32_t read ( const uint32_t &way,
674                      const uint32_t &set,
[814]675                      const uint32_t &word) const
[495]676      {
677          assert((set  < m_sets ) && "Cache data error: Trying to read a wrong set" );
678          assert((way  < m_ways ) && "Cache data error: Trying to read a wrong way" );
679          assert((word < m_words) && "Cache data error: Trying to read a wrong word");
[307]680
[495]681          return m_cache_data[way][set][word];
[307]682      }
[495]683      //////////////////////////////////////////
684      void read_line( const uint32_t &way,
685                      const uint32_t &set,
686                      sc_core::sc_signal<uint32_t> * cache_line)
[307]687      {
[495]688          assert((set < m_sets ) && "Cache data error: Trying to read a wrong set" );
689          assert((way < m_ways ) && "Cache data error: Trying to read a wrong way" );
[449]690
[495]691          for (uint32_t word=0; word<m_words; word++)
692              cache_line[word].write(m_cache_data[way][set][word]);
[307]693      }
[495]694      /////////////////////////////////////////
695      void write ( const uint32_t &way,
696                   const uint32_t &set,
697                   const uint32_t &word,
698                   const uint32_t &data,
[814]699                   const uint32_t &be = 0xF)
[495]700      {
[307]701
[495]702          assert((set  < m_sets ) && "Cache data error: Trying to write a wrong set" );
703          assert((way  < m_ways ) && "Cache data error: Trying to write a wrong way" );
704          assert((word < m_words) && "Cache data error: Trying to write a wrong word");
705          assert((be  <= 0xF    ) && "Cache data error: Trying to write a wrong be");
[307]706
[495]707          if (be == 0x0) return;
[307]708
[814]709          if (be == 0xF)
[495]710          {
[814]711              m_cache_data[way][set][word] = data;
[495]712              return;
713          }
[307]714
[495]715          uint32_t mask = 0;
716          if  (be & 0x1) mask = mask | 0x000000FF;
717          if  (be & 0x2) mask = mask | 0x0000FF00;
718          if  (be & 0x4) mask = mask | 0x00FF0000;
719          if  (be & 0x8) mask = mask | 0xFF000000;
[307]720
[814]721          m_cache_data[way][set][word] =
[495]722              (data & mask) | (m_cache_data[way][set][word] & ~mask);
[307]723      }
724  }; // end class CacheData
725
726}} // end namespaces
727
728#endif
729
730// Local Variables:
731// tab-width: 4
732// c-basic-offset: 4
733// c-file-offsets:((innamespace . 0)(inline-open . 0))
734// indent-tabs-mode: nil
735// End:
736
737// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
738
Note: See TracBrowser for help on using the repository browser.