Merge changes.
[gem5.git] / cpu / beta_cpu / store_set.cc
1 #include "cpu/beta_cpu/store_set.hh"
2 #include "base/trace.hh"
3
4 StoreSet::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 DPRINTF(StoreSet, "StoreSet: SSIT size: %i, LFST size: %i.\n",
9 SSIT_size, LFST_size);
10
11 SSIT = new SSID[SSIT_size];
12
13 validSSIT.resize(SSIT_size);
14
15 for (int i = 0; i < SSIT_size; ++i)
16 validSSIT[i] = false;
17
18 LFST = new InstSeqNum[LFST_size];
19
20 validLFST.resize(LFST_size);
21
22 SSCounters = new int[LFST_size];
23
24 for (int i = 0; i < LFST_size; ++i)
25 {
26 validLFST[i] = false;
27 SSCounters[i] = 0;
28 }
29
30 index_mask = SSIT_size - 1;
31
32 offset_bits = 2;
33 }
34
35 void
36 StoreSet::violation(Addr store_PC, Addr load_PC)
37 {
38 int load_index = calcIndex(load_PC);
39 int store_index = calcIndex(store_PC);
40
41 assert(load_index < SSIT_size && store_index < SSIT_size);
42
43 bool valid_load_SSID = validSSIT[load_index];
44 bool valid_store_SSID = validSSIT[store_index];
45
46 if (!valid_load_SSID && !valid_store_SSID) {
47 // Calculate a new SSID here.
48 SSID new_set = calcSSID(load_PC);
49
50 validSSIT[load_index] = true;
51
52 SSIT[load_index] = new_set;
53
54 validSSIT[store_index] = true;
55
56 SSIT[store_index] = new_set;
57
58 assert(new_set < LFST_size);
59
60 SSCounters[new_set]++;
61
62
63 DPRINTF(StoreSet, "StoreSet: Neither load nor store had a valid "
64 "storeset, creating a new one: %i for load %#x, store %#x\n",
65 new_set, load_PC, store_PC);
66 } else if (valid_load_SSID && !valid_store_SSID) {
67 SSID load_SSID = SSIT[load_index];
68
69 validSSIT[store_index] = true;
70
71 SSIT[store_index] = load_SSID;
72
73 assert(load_SSID < LFST_size);
74
75 SSCounters[load_SSID]++;
76
77 DPRINTF(StoreSet, "StoreSet: Load had a valid store set. Adding "
78 "store to that set: %i for load %#x, store %#x\n",
79 load_SSID, load_PC, store_PC);
80 } else if (!valid_load_SSID && valid_store_SSID) {
81 SSID store_SSID = SSIT[store_index];
82
83 validSSIT[load_index] = true;
84
85 SSIT[load_index] = store_SSID;
86
87 // Because we are having a load point to an already existing set,
88 // the size of the store set is not incremented.
89
90 DPRINTF(StoreSet, "StoreSet: Store had a valid store set: %i for "
91 "load %#x, store %#x\n",
92 store_SSID, load_PC, store_PC);
93 } else {
94 SSID load_SSID = SSIT[load_index];
95 SSID store_SSID = SSIT[store_index];
96
97 assert(load_SSID < LFST_size && store_SSID < LFST_size);
98
99 int load_SS_size = SSCounters[load_SSID];
100 int store_SS_size = SSCounters[store_SSID];
101
102 // If the load has the bigger store set, then assign the store
103 // to the same store set as the load. Otherwise vice-versa.
104 if (load_SS_size > store_SS_size) {
105 SSIT[store_index] = load_SSID;
106
107 SSCounters[load_SSID]++;
108 SSCounters[store_SSID]--;
109
110 DPRINTF(StoreSet, "StoreSet: Load had bigger store set: %i; "
111 "for load %#x, store %#x\n",
112 load_SSID, load_PC, store_PC);
113 } else {
114 SSIT[load_index] = store_SSID;
115
116 SSCounters[store_SSID]++;
117 SSCounters[load_SSID]--;
118
119 DPRINTF(StoreSet, "StoreSet: Store had bigger store set: %i; "
120 "for load %#x, store %#x\n",
121 store_SSID, load_PC, store_PC);
122 }
123 }
124 }
125
126 void
127 StoreSet::insertLoad(Addr load_PC, InstSeqNum load_seq_num)
128 {
129 // Does nothing.
130 return;
131 }
132
133 void
134 StoreSet::insertStore(Addr store_PC, InstSeqNum store_seq_num)
135 {
136 int index = calcIndex(store_PC);
137
138 int store_SSID;
139
140 assert(index < SSIT_size);
141
142 if (!validSSIT[index]) {
143 // Do nothing if there's no valid entry.
144 return;
145 } else {
146 store_SSID = SSIT[index];
147
148 assert(store_SSID < LFST_size);
149
150 // Update the last store that was fetched with the current one.
151 LFST[store_SSID] = store_seq_num;
152
153 validLFST[store_SSID] = 1;
154
155 DPRINTF(StoreSet, "Store %#x updated the LFST, SSID: %i\n",
156 store_PC, store_SSID);
157 }
158 }
159
160 InstSeqNum
161 StoreSet::checkInst(Addr PC)
162 {
163 int index = calcIndex(PC);
164
165 int inst_SSID;
166
167 assert(index < SSIT_size);
168
169 if (!validSSIT[index]) {
170 DPRINTF(StoreSet, "Inst %#x with index %i had no SSID\n",
171 PC, index);
172
173 // Return 0 if there's no valid entry.
174 return 0;
175 } else {
176 inst_SSID = SSIT[index];
177
178 assert(inst_SSID < LFST_size);
179
180 if (!validLFST[inst_SSID]) {
181
182 DPRINTF(StoreSet, "Inst %#x with index %i and SSID %i had no "
183 "dependency\n", PC, index, inst_SSID);
184
185 return 0;
186 } else {
187 DPRINTF(StoreSet, "Inst %#x with index %i and SSID %i had LFST "
188 "inum of %i\n", PC, index, inst_SSID, LFST[inst_SSID]);
189
190 return LFST[inst_SSID];
191 }
192 }
193 }
194
195 void
196 StoreSet::issued(Addr issued_PC, InstSeqNum issued_seq_num, bool is_store)
197 {
198 // This only is updated upon a store being issued.
199 if (!is_store) {
200 return;
201 }
202
203 int index = calcIndex(issued_PC);
204
205 int store_SSID;
206
207 assert(index < SSIT_size);
208
209 // Make sure the SSIT still has a valid entry for the issued store.
210 if (!validSSIT[index]) {
211 return;
212 }
213
214 store_SSID = SSIT[index];
215
216 assert(store_SSID < LFST_size);
217
218 // If the last fetched store in the store set refers to the store that
219 // was just issued, then invalidate the entry.
220 if (validLFST[store_SSID] && LFST[store_SSID] == issued_seq_num) {
221 DPRINTF(StoreSet, "StoreSet: store invalidated itself in LFST.\n");
222 validLFST[store_SSID] = false;
223 }
224 }
225
226 void
227 StoreSet::squash(InstSeqNum squashed_num)
228 {
229 // Not really sure how to do this well.
230 // Generally this is small enough that it should be okay; short circuit
231 // evaluation should take care of invalid entries.
232
233 DPRINTF(StoreSet, "StoreSet: Squashing until inum %i\n",
234 squashed_num);
235
236 for (int i = 0; i < LFST_size; ++i) {
237 if (validLFST[i] && LFST[i] < squashed_num) {
238 validLFST[i] = false;
239 }
240 }
241 }
242
243 void
244 StoreSet::clear()
245 {
246 for (int i = 0; i < SSIT_size; ++i) {
247 validSSIT[i] = false;
248 }
249
250 for (int i = 0; i < LFST_size; ++i) {
251 validLFST[i] = false;
252 }
253 }
254