store_set.cc revision 1062
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    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
35void
36StoreSet::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
126void
127StoreSet::insertLoad(Addr load_PC, InstSeqNum load_seq_num)
128{
129    // Does nothing.
130    return;
131}
132
133void
134StoreSet::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
160InstSeqNum
161StoreSet::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
195void
196StoreSet::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
226void
227StoreSet::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
243void
244StoreSet::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
255