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 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_StatisticalCorrector
*
136 TAGE_SC_L_8KB_StatisticalCorrectorParams::create()
138 return new TAGE_SC_L_8KB_StatisticalCorrector(this);
141 TAGE_SC_L_8KB::TAGE_SC_L_8KB(const TAGE_SC_L_8KBParams
*params
)
147 TAGE_SC_L_TAGE_8KB::initFoldedHistories(ThreadHistory
& history
)
149 // Some hardcoded values are used here
150 // (they do not seem to depend on any parameter)
151 for (int i
= 1; i
<= nHistoryTables
; i
++) {
152 history
.computeIndices
[i
].init(
153 histLengths
[i
], 17 + (2 * ((i
- 1) / 2) % 4));
154 history
.computeTags
[0][i
].init(
155 history
.computeIndices
[i
].origLength
, 13);
156 history
.computeTags
[1][i
].init(
157 history
.computeIndices
[i
].origLength
, 11);
158 DPRINTF(TageSCL
, "HistLength:%d, TTSize:%d, TTTWidth:%d\n",
159 histLengths
[i
], logTagTableSizes
[i
], tagTableTagWidths
[i
]);
164 TAGE_SC_L_TAGE_8KB::gindex_ext(int index
, int bank
) const
166 return (index
^ (index
>> logTagTableSizes
[bank
])
167 ^ (index
>> 2 * logTagTableSizes
[bank
]));
171 TAGE_SC_L_TAGE_8KB::gtag(ThreadID tid
, Addr pc
, int bank
) const
173 int tag
= (threadHistory
[tid
].computeIndices
[bank
- 1].comp
<< 2) ^ pc
^
174 (pc
>> instShiftAmt
) ^
175 threadHistory
[tid
].computeIndices
[bank
].comp
;
176 int hlen
= (histLengths
[bank
] > pathHistBits
) ? pathHistBits
:
179 tag
= (tag
>> 1) ^ ((tag
& 1) << 10) ^
180 F(threadHistory
[tid
].pathHist
, hlen
, bank
);
181 tag
^= threadHistory
[tid
].computeTags
[0][bank
].comp
^
182 (threadHistory
[tid
].computeTags
[1][bank
].comp
<< 1);
184 return ((tag
^ (tag
>> tagTableTagWidths
[bank
]))
185 & ((ULL(1) << tagTableTagWidths
[bank
]) - 1));
189 TAGE_SC_L_TAGE_8KB::handleAllocAndUReset(
190 bool alloc
, bool taken
, TAGEBase::BranchInfo
* bi
, int nrand
)
198 int numAllocated
= 0;
199 bool maxAllocReached
= false;
201 for (int I
= calcDep(bi
); I
< nHistoryTables
; I
+= 2) {
202 // Handle the 2-way associativity for allocation
203 for (int j
= 0; j
< 2; ++j
) {
204 int i
= ((j
== 0) ? I
: (I
^ 1)) + 1;
205 if (i
> nHistoryTables
) {
209 if (gtable
[i
][bi
->tableIndices
[i
]].u
== 0) {
210 gtable
[i
][bi
->tableIndices
[i
]].u
=
211 ((random_mt
.random
<int>() & 31) == 0);
212 // protect randomly from fast replacement
213 gtable
[i
][bi
->tableIndices
[i
]].tag
= bi
->tableTags
[i
];
214 gtable
[i
][bi
->tableIndices
[i
]].ctr
= taken
? 0 : -1;
217 if (numAllocated
== maxNumAlloc
) {
218 maxAllocReached
= true;
223 int8_t ctr
= gtable
[i
][bi
->tableIndices
[i
]].ctr
;
224 if ((gtable
[i
][bi
->tableIndices
[i
]].u
== 1) &
225 (abs (2 * ctr
+ 1) == 1)) {
226 if ((random_mt
.random
<int>() & 7) == 0) {
227 gtable
[i
][bi
->tableIndices
[i
]].u
= 0;
238 if (maxAllocReached
) {
243 tCounter
+= (truePen
+ penalty
- 5 * numAllocated
);
249 TAGE_SC_L_TAGE_8KB::resetUctr(uint8_t & u
)
251 // On real HW it should be u >>= 1 instead of if > 0 then u--
258 TAGE_SC_L_TAGE_8KB::handleTAGEUpdate(Addr branch_pc
, bool taken
,
259 TAGEBase::BranchInfo
* bi
)
261 if (bi
->hitBank
> 0) {
262 if (abs (2 * gtable
[bi
->hitBank
][bi
->hitBankIndex
].ctr
+ 1) == 1) {
263 if (bi
->longestMatchPred
!= taken
) { // acts as a protection
264 if (bi
->altBank
> 0) {
265 int8_t ctr
= gtable
[bi
->altBank
][bi
->altBankIndex
].ctr
;
266 if (abs (2 * ctr
+ 1) == 1) {
267 gtable
[bi
->altBank
][bi
->altBankIndex
].u
= 0;
270 //just mute from protected to unprotected
271 ctrUpdate(gtable
[bi
->altBank
][bi
->altBankIndex
].ctr
, taken
,
272 tagTableCounterBits
);
273 ctr
= gtable
[bi
->altBank
][bi
->altBankIndex
].ctr
;
274 if (abs (2 * ctr
+ 1) == 1) {
275 gtable
[bi
->altBank
][bi
->altBankIndex
].u
= 0;
278 if (bi
->altBank
== 0) {
279 baseUpdate(branch_pc
, taken
, bi
);
284 //just mute from protected to unprotected
285 if (abs (2 * gtable
[bi
->hitBank
][bi
->hitBankIndex
].ctr
+ 1) == 1) {
286 gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
= 0;
289 ctrUpdate(gtable
[bi
->hitBank
][bi
->hitBankIndex
].ctr
, taken
,
290 tagTableCounterBits
);
292 //sign changes: no way it can have been useful
293 if (abs (2 * gtable
[bi
->hitBank
][bi
->hitBankIndex
].ctr
+ 1) == 1) {
294 gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
= 0;
297 if (bi
->altTaken
== taken
) {
298 if (bi
->altBank
> 0) {
299 int8_t ctr
= gtable
[bi
->altBank
][bi
->altBankIndex
].ctr
;
300 if (abs (2*ctr
+ 1) == 7) {
301 if (gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
== 1) {
302 if (bi
->longestMatchPred
== taken
) {
303 gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
= 0;
310 baseUpdate(branch_pc
, taken
, bi
);
313 if ((bi
->longestMatchPred
!= bi
->altTaken
) &&
314 (bi
->longestMatchPred
== taken
) &&
315 (gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
< (1 << tagTableUBits
) -1)) {
316 gtable
[bi
->hitBank
][bi
->hitBankIndex
].u
++;
321 TAGE_SC_L_TAGE_8KBParams::create()
323 return new TAGE_SC_L_TAGE_8KB(this);
327 TAGE_SC_L_8KBParams::create()
329 return new TAGE_SC_L_8KB(this);