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

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

RWT Commit : Cosmetic

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