summaryrefslogtreecommitdiff
path: root/vg_cachesim_I1.c
blob: 96e9edd23e234235587a882dabd5325fe7439918 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*  I1 cache simulator, generated by vg_cachegen.
 *     total size    = 65536 bytes
 *     line size     = 64 bytes
 *     associativity = 2-way associative
 *
 *  This file should be #include-d into vg_cachesim.c
 */

static char I1_desc_line[] = 
    "desc: I1 cache:         65536 B, 64 B, 2-way associative\n";

static UInt I1_tags[512][2];

static void cachesim_I1_initcache(void)
{
   UInt set, way;
   for (set = 0; set < 512; set++)
      for (way = 0; way < 2; way++)
         I1_tags[set][way] = 0;
}

static __inline__ 
void cachesim_I1_doref(Addr a, UChar size, ULong* m1, ULong *m2)
{
   register UInt set1 = ( a             >> 6) & (512-1);
   register UInt set2 = ((a + size - 1) >> 6) & (512-1);
   register UInt tag  = a >> (6 + 9);

   if (set1 == set2) {

      if (tag == I1_tags[set1][0]) {
         return;
      }
      else if (tag == I1_tags[set1][1]) {
         I1_tags[set1][1] = I1_tags[set1][0];
         I1_tags[set1][0] = tag;
         return;
      }
      else {
         /* A miss */
         I1_tags[set1][1] = I1_tags[set1][0];
         I1_tags[set1][0] = tag;

         (*m1)++;
         cachesim_L2_doref(a, size, m2);
      }

   } else if ((set1 + 1) % 512 == set2) {

      Bool is_I1_miss = False;

      /* Block one */
      if (tag == I1_tags[set1][0]) {
      }
      else if (tag == I1_tags[set1][1]) {
         I1_tags[set1][1] = I1_tags[set1][0];
         I1_tags[set1][0] = tag;
      }
      else {
         /* A miss */
         I1_tags[set1][1] = I1_tags[set1][0];
         I1_tags[set1][0] = tag;

         is_I1_miss = True;
      }

      /* Block two */
      if (tag == I1_tags[set2][0]) {
      }
      else if (tag == I1_tags[set2][1]) {
         I1_tags[set2][1] = I1_tags[set2][0];
         I1_tags[set2][0] = tag;
      }
      else {
         /* A miss */
         I1_tags[set2][1] = I1_tags[set2][0];
         I1_tags[set2][0] = tag;

         is_I1_miss = True;
      }

      /* Miss treatment */
      if (is_I1_miss) {
         (*m1)++;
         cachesim_L2_doref(a, size, m2);
      }

   } else {
      VG_(printf)("\nERROR: Data item 0x%x of size %u bytes is in two non-adjacent\n", a, size);
      VG_(printf)("sets %d and %d.\n", set1, set2);
      VG_(panic)("I1 cache set mismatch");
   }
}