store_set.cc revision 1061
1#include "cpu/beta_cpu/store_set.hh"
2#include "base/trace.hh"
3
4StoreSet::StoreSet(int _SSIT_size, int _LFST_size)
5    : SSIT_size(_SSIT_size), LFST_size(_LFST_size)
6{
7    DPRINTF(StoreSet, "StoreSet: Creating store set object.\n");
8
9    SSIT = new SSID[SSIT_size];
10
11    validSSIT.resize(SSIT_size);
12
13    for (int i = 0; i < SSIT_size; ++i)
14        validSSIT[i] = false;
15
16    LFST = new InstSeqNum[LFST_size];
17
18    validLFST.resize(LFST_size);
19
20    SSCounters = new int[LFST_size];
21
22    for (int i = 0; i < LFST_size; ++i)
23    {
24        validLFST[i] = false;
25        SSCounters[i] = 0;
26    }
27
28    index_mask = SSIT_size - 1;
29
30    offset_bits = 2;
31}
32
33void
34StoreSet::violation(Addr load_PC, Addr store_PC)
35{
36    int load_index = calcIndex(load_PC);
37    int store_index = calcIndex(store_PC);
38
39    bool valid_load_SSID = validSSIT[load_index];
40    bool valid_store_SSID = validSSIT[store_index];
41
42    if (!valid_load_SSID && !valid_store_SSID) {
43        // Calculate a new SSID here.
44        SSID new_set = calcSSID(load_PC);
45
46        validSSIT[load_index] = true;
47
48        SSIT[load_index] = new_set;
49
50        validSSIT[store_index] = true;
51
52        SSIT[store_index] = new_set;
53
54        SSCounters[new_set]++;
55    } else if (valid_load_SSID && !valid_store_SSID) {
56        SSID load_SSID = SSIT[load_index];
57
58        validSSIT[store_index] = true;
59
60        SSIT[store_index] = load_SSID;
61
62        SSCounters[load_SSID]++;
63    } else if (!valid_load_SSID && valid_store_SSID) {
64        SSID store_SSID = SSIT[store_index];
65
66        validSSIT[load_index] = true;
67
68        SSIT[load_index] = store_SSID;
69
70        // Because we are having a load point to an already existing set,
71        // the size of the store set is not incremented.
72    } else {
73        SSID load_SSID = SSIT[load_index];
74        SSID store_SSID = SSIT[store_index];
75
76        int load_SS_size = SSCounters[load_SSID];
77        int store_SS_size = SSCounters[store_SSID];
78
79        // If the load has the bigger store set, then assign the store
80        // to the same store set as the load.  Otherwise vice-versa.
81        if (load_SS_size > store_SS_size) {
82            SSIT[store_index] = load_SSID;
83
84            SSCounters[load_SSID]++;
85            SSCounters[store_SSID]--;
86        } else {
87            SSIT[load_index] = store_SSID;
88
89            SSCounters[store_SSID]++;
90            SSCounters[load_SSID]--;
91        }
92    }
93}
94
95void
96StoreSet::insertLoad(Addr load_PC, InstSeqNum load_seq_num)
97{
98    // Does nothing.
99    return;
100}
101
102void
103StoreSet::insertStore(Addr store_PC, InstSeqNum store_seq_num)
104{
105    int index = calcIndex(store_PC);
106
107    int store_SSID;
108
109    if (!validSSIT[index]) {
110        // Do nothing if there's no valid entry.
111        return;
112    } else {
113        store_SSID = SSIT[index];
114
115        assert(store_SSID < LFST_size);
116
117        // Update the last store that was fetched with the current one.
118        LFST[store_SSID] = store_seq_num;
119    }
120}
121
122InstSeqNum
123StoreSet::checkInst(Addr PC)
124{
125    int index = calcIndex(PC);
126
127    int inst_SSID;
128
129    if (!validSSIT[index]) {
130        // Return 0 if there's no valid entry.
131        return 0;
132    } else {
133        inst_SSID = SSIT[index];
134
135        assert(inst_SSID < LFST_size);
136
137        if (!validLFST[inst_SSID]) {
138            return 0;
139        } else {
140            return LFST[inst_SSID];
141        }
142    }
143}
144
145void
146StoreSet::issued(Addr issued_PC, InstSeqNum issued_seq_num, bool is_store)
147{
148    // This only is updated upon a store being issued.
149    if (!is_store) {
150        return;
151    }
152
153    int index = calcIndex(issued_PC);
154
155    int store_SSID;
156
157    // Make sure the SSIT still has a valid entry for the issued store.
158    assert(validSSIT[index]);
159
160    store_SSID = SSIT[index];
161
162    // If the last fetched store in the store set refers to the store that
163    // was just issued, then invalidate the entry.
164    if (validLFST[store_SSID] && LFST[store_SSID] == issued_seq_num) {
165        validLFST[store_SSID] = false;
166    }
167}
168
169void
170StoreSet::squash(InstSeqNum squashed_num)
171{
172    // Not really sure how to do this well.
173
174    for (int i = 0; i < LFST_size; ++i) {
175        if (LFST[i] < squashed_num) {
176            validLFST[i] = false;
177        }
178    }
179}
180
181void
182StoreSet::clear()
183{
184    for (int i = 0; i < SSIT_size; ++i) {
185        validSSIT[i] = false;
186    }
187
188    for (int i = 0; i < LFST_size; ++i) {
189        validLFST[i] = false;
190    }
191}
192
193