1 #include "cpu/beta_cpu/store_set.hh"
2 #include "base/trace.hh"
4 StoreSet::StoreSet(int _SSIT_size
, int _LFST_size
)
5 : SSIT_size(_SSIT_size
), LFST_size(_LFST_size
)
7 DPRINTF(StoreSet
, "StoreSet: Creating store set object.\n");
8 DPRINTF(StoreSet
, "StoreSet: SSIT size: %i, LFST size: %i.\n",
11 SSIT
= new SSID
[SSIT_size
];
13 validSSIT
.resize(SSIT_size
);
15 for (int i
= 0; i
< SSIT_size
; ++i
)
18 LFST
= new InstSeqNum
[LFST_size
];
20 validLFST
.resize(LFST_size
);
22 SSCounters
= new int[LFST_size
];
24 for (int i
= 0; i
< LFST_size
; ++i
)
30 index_mask
= SSIT_size
- 1;
36 StoreSet::violation(Addr store_PC
, Addr load_PC
)
38 int load_index
= calcIndex(load_PC
);
39 int store_index
= calcIndex(store_PC
);
41 assert(load_index
< SSIT_size
&& store_index
< SSIT_size
);
43 bool valid_load_SSID
= validSSIT
[load_index
];
44 bool valid_store_SSID
= validSSIT
[store_index
];
46 if (!valid_load_SSID
&& !valid_store_SSID
) {
47 // Calculate a new SSID here.
48 SSID new_set
= calcSSID(load_PC
);
50 validSSIT
[load_index
] = true;
52 SSIT
[load_index
] = new_set
;
54 validSSIT
[store_index
] = true;
56 SSIT
[store_index
] = new_set
;
58 assert(new_set
< LFST_size
);
60 SSCounters
[new_set
]++;
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
];
69 validSSIT
[store_index
] = true;
71 SSIT
[store_index
] = load_SSID
;
73 assert(load_SSID
< LFST_size
);
75 SSCounters
[load_SSID
]++;
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
];
83 validSSIT
[load_index
] = true;
85 SSIT
[load_index
] = store_SSID
;
87 // Because we are having a load point to an already existing set,
88 // the size of the store set is not incremented.
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
);
94 SSID load_SSID
= SSIT
[load_index
];
95 SSID store_SSID
= SSIT
[store_index
];
97 assert(load_SSID
< LFST_size
&& store_SSID
< LFST_size
);
99 int load_SS_size
= SSCounters
[load_SSID
];
100 int store_SS_size
= SSCounters
[store_SSID
];
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
;
107 SSCounters
[load_SSID
]++;
108 SSCounters
[store_SSID
]--;
110 DPRINTF(StoreSet
, "StoreSet: Load had bigger store set: %i; "
111 "for load %#x, store %#x\n",
112 load_SSID
, load_PC
, store_PC
);
114 SSIT
[load_index
] = store_SSID
;
116 SSCounters
[store_SSID
]++;
117 SSCounters
[load_SSID
]--;
119 DPRINTF(StoreSet
, "StoreSet: Store had bigger store set: %i; "
120 "for load %#x, store %#x\n",
121 store_SSID
, load_PC
, store_PC
);
127 StoreSet::insertLoad(Addr load_PC
, InstSeqNum load_seq_num
)
134 StoreSet::insertStore(Addr store_PC
, InstSeqNum store_seq_num
)
136 int index
= calcIndex(store_PC
);
140 assert(index
< SSIT_size
);
142 if (!validSSIT
[index
]) {
143 // Do nothing if there's no valid entry.
146 store_SSID
= SSIT
[index
];
148 assert(store_SSID
< LFST_size
);
150 // Update the last store that was fetched with the current one.
151 LFST
[store_SSID
] = store_seq_num
;
153 validLFST
[store_SSID
] = 1;
155 DPRINTF(StoreSet
, "Store %#x updated the LFST, SSID: %i\n",
156 store_PC
, store_SSID
);
161 StoreSet::checkInst(Addr PC
)
163 int index
= calcIndex(PC
);
167 assert(index
< SSIT_size
);
169 if (!validSSIT
[index
]) {
170 DPRINTF(StoreSet
, "Inst %#x with index %i had no SSID\n",
173 // Return 0 if there's no valid entry.
176 inst_SSID
= SSIT
[index
];
178 assert(inst_SSID
< LFST_size
);
180 if (!validLFST
[inst_SSID
]) {
182 DPRINTF(StoreSet
, "Inst %#x with index %i and SSID %i had no "
183 "dependency\n", PC
, index
, inst_SSID
);
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
]);
190 return LFST
[inst_SSID
];
196 StoreSet::issued(Addr issued_PC
, InstSeqNum issued_seq_num
, bool is_store
)
198 // This only is updated upon a store being issued.
203 int index
= calcIndex(issued_PC
);
207 assert(index
< SSIT_size
);
209 // Make sure the SSIT still has a valid entry for the issued store.
210 if (!validSSIT
[index
]) {
214 store_SSID
= SSIT
[index
];
216 assert(store_SSID
< LFST_size
);
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;
227 StoreSet::squash(InstSeqNum squashed_num
)
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.
233 DPRINTF(StoreSet
, "StoreSet: Squashing until inum %i\n",
236 for (int i
= 0; i
< LFST_size
; ++i
) {
237 if (validLFST
[i
] && LFST
[i
] < squashed_num
) {
238 validLFST
[i
] = false;
246 for (int i
= 0; i
< SSIT_size
; ++i
) {
247 validSSIT
[i
] = false;
250 for (int i
= 0; i
< LFST_size
; ++i
) {
251 validLFST
[i
] = false;