2 * Copyright (c) 2018 Metempsy Technology Consulting
5 * Copyright (c) 2006 INRIA (Institut National de Recherche en
6 * Informatique et en Automatique / French National Research Institute
7 * for Computer Science and Applied Mathematics)
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are
13 * met: redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer;
15 * redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution;
18 * neither the name of the copyright holders nor the names of its
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * Author: André Seznec, Pau Cabre, Javier Bueno
39 * 8KB TAGE-SC-L branch predictor (devised by Andre Seznec)
42 #include "cpu/pred/tage_sc_l_8KB.hh"
44 #include "base/random.hh"
45 #include "debug/TageSCL.hh"
47 TAGE_SC_L_8KB_StatisticalCorrector::TAGE_SC_L_8KB_StatisticalCorrector(
48 const TAGE_SC_L_8KB_StatisticalCorrectorParams
&p
)
49 : StatisticalCorrector(p
),
54 initGEHLTable(gnb
, gm
, ggehl
, logGnb
, wg
, 7);
57 TAGE_SC_L_8KB_StatisticalCorrector::SCThreadHistory
*
58 TAGE_SC_L_8KB_StatisticalCorrector::makeThreadHistory()
60 SC_8KB_ThreadHistory
*sh
= new SC_8KB_ThreadHistory();
61 sh
->setNumOrdinalHistories(1);
62 sh
->initLocalHistory(1, numEntriesFirstLocalHistories
, 2);
67 TAGE_SC_L_8KB_StatisticalCorrector::getIndBiasBank(Addr branch_pc
,
68 BranchInfo
* bi
, int hitBank
, int altBank
) const
70 return (bi
->predBeforeSC
+ (((hitBank
+1)/4)<<4) + (bi
->highConf
<<1) +
71 (bi
->lowConf
<<2) +((altBank
!=0)<<3)) & ((1<<logBias
) -1);
75 TAGE_SC_L_8KB_StatisticalCorrector::gPredictions(
76 ThreadID tid
, Addr branch_pc
, BranchInfo
* bi
, int & lsum
, int64_t phist
)
78 SC_8KB_ThreadHistory
*sh
= static_cast<SC_8KB_ThreadHistory
*>(scHistory
);
80 branch_pc
, sh
->globalHist
, gm
, ggehl
, gnb
, logGnb
, wg
);
83 branch_pc
, sh
->bwHist
, bwm
, bwgehl
, bwnb
, logBwnb
, wbw
);
85 // only 1 local history here
87 branch_pc
, sh
->getLocalHistory(1, branch_pc
), lm
,
88 lgehl
, lnb
, logLnb
, wl
);
91 branch_pc
, sh
->imliCount
, im
, igehl
, inb
, logInb
, wi
);
93 int thres
= (updateThreshold
>>3)+pUpdateThreshold
[getIndUpd(branch_pc
)];
98 int TAGE_SC_L_8KB_StatisticalCorrector::gIndexLogsSubstr(int nbr
, int i
)
104 TAGE_SC_L_8KB_StatisticalCorrector::scHistoryUpdate(Addr branch_pc
,
105 const StaticInstPtr
&inst
, bool taken
, BranchInfo
*tage_bi
,
108 int brtype
= inst
->isDirectCtrl() ? 0 : 2;
109 if (! inst
->isUncondCtrl()) {
112 // Non speculative SC histories update
114 SC_8KB_ThreadHistory
*sh
=
115 static_cast<SC_8KB_ThreadHistory
*>(scHistory
);
116 sh
->globalHist
= (sh
->globalHist
<< 1) + taken
;
119 StatisticalCorrector::scHistoryUpdate(branch_pc
, inst
, taken
, tage_bi
,
124 TAGE_SC_L_8KB_StatisticalCorrector::gUpdates(ThreadID tid
, Addr pc
, bool taken
,
125 BranchInfo
* bi
, int64_t phist
)
127 SC_8KB_ThreadHistory
*sh
= static_cast<SC_8KB_ThreadHistory
*>(scHistory
);
128 gUpdate(pc
, taken
, sh
->globalHist
, gm
, ggehl
, gnb
, logGnb
, wg
, bi
);
129 gUpdate(pc
, taken
, sh
->bwHist
, bwm
, bwgehl
, bwnb
, logBwnb
, wbw
, bi
);
130 gUpdate(pc
, taken
, sh
->getLocalHistory(1, pc
), lm
, lgehl
, lnb
, logLnb
, wl
,
132 gUpdate(pc
, taken
, sh
->imliCount
, im
, igehl
, inb
, logInb
, wi
, bi
);
135 TAGE_SC_L_8KB::TAGE_SC_L_8KB(const TAGE_SC_L_8KBParams
¶ms
)
141 TAGE_SC_L_TAGE_8KB::initFoldedHistories(ThreadHistory
& history
)
143 // Some hardcoded values are used here
144 // (they do not seem to depend on any parameter)
145 for (int i
= 1; i
<= nHistoryTables
; i
++) {
146 history
.computeIndices
[i
].init(
147 histLengths
[i
], 17 + (2 * ((i
- 1) / 2) % 4));
148 history
.computeTags
[0][i
].init(
149 history
.computeIndices
[i
].origLength
, 13);
150 history
.computeTags
[1][i
].init(
151 history
.computeIndices
[i
].origLength
, 11);
152 DPRINTF(TageSCL
, "HistLength:%d, TTSize:%d, TTTWidth:%d\n",
153 histLengths
[i
], logTagTableSizes
[i
], tagTableTagWidths
[i
]);
158 TAGE_SC_L_TAGE_8KB::gindex_ext(int index
, int bank
) const
160 return (index
^ (index
>> logTagTableSizes
[bank
])
161 ^ (index
>> 2 * logTagTableSizes
[bank
]));
165 TAGE_SC_L_TAGE_8KB::gtag(ThreadID tid
, Addr pc
, int bank
) const
167 int tag
= (threadHistory
[tid
].computeIndices
[bank
- 1].comp
<< 2) ^ pc
^
168 (pc
>> instShiftAmt
) ^
169 threadHistory
[tid
].computeIndices
[bank
].comp
;
170 int hlen
= (histLengths
[bank
] > pathHistBits
) ? pathHistBits
:
173 tag
= (tag
>> 1) ^ ((tag
& 1) << 10) ^
174 F(threadHistory
[tid
].pathHist
, hlen
, bank
);
175 tag
^= threadHistory
[tid
].computeTags
[0][bank
].comp
^
176 (threadHistory
[tid
].computeTags
[1][bank
].comp
<< 1);
178 return ((tag
^ (tag
>> tagTableTagWidths
[bank
]))
179 & ((ULL(1) << tagTableTagWidths
[bank
]) - 1));
183 TAGE_SC_L_TAGE_8KB::handleAllocAndUReset(
184 bool alloc
, bool taken
, TAGEBase::BranchInfo
* bi
, int nrand
)
192 int numAllocated
= 0;
193 bool maxAllocReached
= false;
195 for (int I
= calcDep(bi
); I
< nHistoryTables
; I
+= 2) {
196 // Handle the 2-way associativity for allocation
197 for (int j
= 0; j
< 2; ++j
) {
198 int i
= ((j
== 0) ? I
: (I
^ 1)) + 1;
199 if (i
> nHistoryTables
) {
203 if (gtable
[i
][bi
->tableIndices
[i
]].u
== 0) {
204 gtable
[i
][bi
->tableIndices
[i
]].u
=
205 ((random_mt
.random
<int>() & 31) == 0);
206 // protect randomly from fast replacement
207 gtable
[i
][bi
->tableIndices
[i
]].tag
= bi
->tableTags
[i
];
208 gtable
[i
][bi
->tableIndices
[i
]].ctr
= taken
? 0 : -1;
211 if (numAllocated
== maxNumAlloc
) {
212 maxAllocReached
= true;
217 int8_t ctr
= gtable
[i
][bi
->tableIndices
[i
]].ctr
;
218 if ((gtable
[i
][bi
->tableIndices
[i
]].u
== 1) &
219 (abs (2 * ctr
+ 1) == 1)) {
220 if ((random_mt
.random
<int>() & 7) == 0) {
221 gtable
[i
][bi
->tableIndices
[i
]].u
= 0;
232 if (maxAllocReached
) {
237 tCounter
+= (truePen
+ penalty
- 5 * numAllocated
);
243 TAGE_SC_L_TAGE_8KB::resetUctr(uint8_t & u
)
245 // On real HW it should be u >>= 1 instead of if > 0 then u--
252 TAGE_SC_L_TAGE_8KB::handleTAGEUpdate(Addr branch_pc
, bool taken
,
253 TAGEBase::BranchInfo
* bi
)
255 if (bi
->hitBank
> 0) {
256 if (abs (2 * gtable
[bi
->hitBank
][bi
->hitBankIndex
].ctr
+ 1) == 1) {
257 if (bi
->longestMatchPred
!= taken
) { // acts as a protection
258 if (bi
->altBank
> 0) {
259 int8_t ctr
= gtable
[bi
->altBank
][bi
->altBankIndex
].ctr
;
260 if (abs (2 * ctr
+ 1) == 1) {
261 gtable
[bi
->altBank
][bi
->altBankIndex
].u
= 0;
264 //just mute from protected to unprotected
265 ctrUpdate(gtable
[bi
->altBank
][bi
->altBankIndex
].ctr
, taken
,
266 tagTableCounterBits
);
267 ctr
= gtable
[bi
->altBank
][bi
->altBankIndex
].ctr
;
268 if (abs (2 * ctr
+ 1) == 1) {
269 gtable
[bi
->altBank
][bi
->altBankIndex
].u
= 0;
272 if (bi
->altBank
== 0) {
273 baseUpdate(branch_pc
, taken
, bi
);
278 //just mute from protected to unprotected
279 if (abs (2 * gtable
[bi
->hitBank
][bi
->hitBankIndex
].ctr
+ 1) == 1) {
280 gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
= 0;
283 ctrUpdate(gtable
[bi
->hitBank
][bi
->hitBankIndex
].ctr
, taken
,
284 tagTableCounterBits
);
286 //sign changes: no way it can have been useful
287 if (abs (2 * gtable
[bi
->hitBank
][bi
->hitBankIndex
].ctr
+ 1) == 1) {
288 gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
= 0;
291 if (bi
->altTaken
== taken
) {
292 if (bi
->altBank
> 0) {
293 int8_t ctr
= gtable
[bi
->altBank
][bi
->altBankIndex
].ctr
;
294 if (abs (2*ctr
+ 1) == 7) {
295 if (gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
== 1) {
296 if (bi
->longestMatchPred
== taken
) {
297 gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
= 0;
304 baseUpdate(branch_pc
, taken
, bi
);
307 if ((bi
->longestMatchPred
!= bi
->altTaken
) &&
308 (bi
->longestMatchPred
== taken
) &&
309 (gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
< (1 << tagTableUBits
) -1)) {
310 gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
++;