00001 /* 00002 * bpred.h - branch predictor interfaces 00003 * 00004 * This file is a part of the SimpleScalar tool suite written by 00005 * Todd M. Austin as a part of the Multiscalar Research Project. 00006 * 00007 * The tool suite is currently maintained by Doug Burger and Todd M. Austin. 00008 * 00009 * Copyright (C) 1994, 1995, 1996, 1997, 1998 by Todd M. Austin 00010 * 00011 * This source file is distributed "as is" in the hope that it will be 00012 * useful. The tool set comes with no warranty, and no author or 00013 * distributor accepts any responsibility for the consequences of its 00014 * use. 00015 * 00016 * Everyone is granted permission to copy, modify and redistribute 00017 * this tool set under the following conditions: 00018 * 00019 * This source code is distributed for non-commercial use only. 00020 * Please contact the maintainer for restrictions applying to 00021 * commercial use. 00022 * 00023 * Permission is granted to anyone to make or distribute copies 00024 * of this source code, either as received or modified, in any 00025 * medium, provided that all copyright notices, permission and 00026 * nonwarranty notices are preserved, and that the distributor 00027 * grants the recipient permission for further redistribution as 00028 * permitted by this document. 00029 * 00030 * Permission is granted to distribute this file in compiled 00031 * or executable form under the same conditions that apply for 00032 * source code, provided that either: 00033 * 00034 * A. it is accompanied by the corresponding machine-readable 00035 * source code, 00036 * B. it is accompanied by a written offer, with no time limit, 00037 * to give anyone a machine-readable copy of the corresponding 00038 * source code in return for reimbursement of the cost of 00039 * distribution. This written offer must permit verbatim 00040 * duplication by anyone, or 00041 * C. it is distributed by someone who received only the 00042 * executable form, and is accompanied by a copy of the 00043 * written offer of source code that they received concurrently. 00044 * 00045 * In other words, you are welcome to use, share and improve this 00046 * source file. You are forbidden to forbid anyone else to use, share 00047 * and improve what you give them. 00048 * 00049 * INTERNET: dburger@cs.wisc.edu 00050 * US Mail: 1210 W. Dayton Street, Madison, WI 53706 00051 * 00052 * $Id: ssb_bpred.h,v 1.1.1.1 2006-01-31 16:35:49 afrodri Exp $ 00053 * 00054 * $Log: not supported by cvs2svn $ 00055 * Revision 1.4 2005/08/16 21:12:55 arodrig6 00056 * changes for docs 00057 * 00058 * Revision 1.3 2004/11/16 04:17:46 arodrig6 00059 * added more documentation 00060 * 00061 * Revision 1.2 2004/08/23 14:49:04 arodrig6 00062 * docs 00063 * 00064 * Revision 1.1 2004/08/05 23:51:44 arodrig6 00065 * grabed files from SS and broke up some of them 00066 * 00067 * Revision 1.1.1.1 2000/03/07 05:15:16 karu 00068 * this is the repository created for my own maintanence. 00069 * created when spec95 (lisp and compress worked). 00070 * compress still had the scanf("%i") problem 00071 * DIFF from the repository I am using alongwith ramdass on /projects 00072 * need to merge the two sometime :-) 00073 * 00074 * Revision 1.1.1.1 2000/02/25 21:02:49 karu 00075 * creating cvs repository for ss3-ppc 00076 * 00077 * Revision 1.5 1998/08/31 17:12:11 taustin 00078 * eliminated unportable "uint" reference 00079 * 00080 * Revision 1.4 1998/08/27 08:00:15 taustin 00081 * implemented host interface description in host.h 00082 * explicit BTB sizing option added to branch predictors, use 00083 * "-btb" option to configure BTB 00084 * return address stack (RAS) performance stats improved 00085 * 00086 * Revision 1.1.1.1 1997/05/22 18:04:05 aklauser 00087 * 00088 * Revision 1.8 1997/05/01 20:23:06 skadron 00089 * BTB bug fixes; jumps no longer update direction state; non-taken 00090 * branches non longer update BTB 00091 * 00092 * Revision 1.7 1997/05/01 00:05:51 skadron 00093 * Separated BTB from direction-predictor 00094 * 00095 * Revision 1.6 1997/04/29 23:50:44 skadron 00096 * Added r31 info to distinguish between return-JRs and other JRs for bpred 00097 * 00098 * Revision 1.5 1997/04/29 22:53:10 skadron 00099 * Hopefully bpred is now right: bpred now allocates entries only for 00100 * branches; on a BTB miss it still returns a direction; and it uses a 00101 * return-address stack. Returns are not yet distinguished among JR's 00102 * 00103 * Revision 1.4 1997/04/28 17:37:09 skadron 00104 * Bpred now allocates entries for any instruction instead of only 00105 * branches; also added return-address stack 00106 * 00107 * Revision 1.3 1997/04/24 16:57:27 skadron 00108 * Bpred used to return no prediction if the indexing branch didn't match 00109 * in the BTB. Now it can predict a direction even on a BTB address 00110 * conflict 00111 * 00112 * Revision 1.2 1997/03/25 16:17:21 skadron 00113 * Added function called after priming 00114 * 00115 * Revision 1.1 1997/02/16 22:23:54 skadron 00116 * Initial revision 00117 * 00118 * 00119 */ 00120 00121 #ifndef BPRED_H 00122 #define BPRED_H 00123 00124 #define dassert(a) assert(a) 00125 00126 #include <stdio.h> 00127 00128 #include "ssb_host.h" 00129 #include "ssb_misc.h" 00130 //#include "machine.h" 00131 #include "ssb_stats.h" 00132 00133 /* 00134 * This module implements a number of branch predictor mechanisms. The 00135 * following predictors are supported: 00136 * 00137 * BPred2Level: two level adaptive branch predictor 00138 * 00139 * It can simulate many prediction mechanisms that have up to 00140 * two levels of tables. Parameters are: 00141 * N # entries in first level (# of shift register(s)) 00142 * W width of shift register(s) 00143 * M # entries in 2nd level (# of counters, or other FSM) 00144 * One BTB entry per level-2 counter. 00145 * 00146 * Configurations: N, W, M 00147 * 00148 * counter based: 1, 0, M 00149 * 00150 * GAg : 1, W, 2^W 00151 * GAp : 1, W, M (M > 2^W) 00152 * PAg : N, W, 2^W 00153 * PAp : N, W, M (M == 2^(N+W)) 00154 * 00155 * BPred2bit: a simple direct mapped bimodal predictor 00156 * 00157 * This predictor has a table of two bit saturating counters. 00158 * Where counter states 0 & 1 are predict not taken and 00159 * counter states 2 & 3 are predict taken, the per-branch counters 00160 * are incremented on taken branches and decremented on 00161 * no taken branches. One BTB entry per counter. 00162 * 00163 * BPredTaken: static predict branch taken 00164 * 00165 * BPredNotTaken: static predict branch not taken 00166 * 00167 */ 00168 00169 /* branch predictor types */ 00170 enum bpred_class { 00171 BPredComb, /* combined predictor (McFarling) */ 00172 BPred2Level, /* 2-level correlating pred w/2-bit counters */ 00173 BPred2bit, /* 2-bit saturating cntr pred (dir mapped) */ 00174 BPredTaken, /* static predict taken */ 00175 BPredNotTaken, /* static predict not taken */ 00176 BPred_NUM 00177 }; 00178 00179 //: an entry in a BTB 00180 //!SEC:ssBack 00181 struct bpred_btb_ent_t { 00182 md_addr_t addr; /* address of branch being tracked */ 00183 enum md_opcode op; /* opcode of branch corresp. to addr */ 00184 md_addr_t target; /* last destination of branch when taken */ 00185 struct bpred_btb_ent_t *prev, *next; /* lru chaining pointers */ 00186 }; 00187 00188 //: direction predictor def 00189 //!SEC:ssBack 00190 struct bpred_dir_t { 00191 enum bpred_class Pclass; /* type of predictor */ 00192 union { 00193 struct { 00194 unsigned int size; /* number of entries in direct-mapped table */ 00195 unsigned char *table; /* prediction state table */ 00196 } bimod; 00197 struct { 00198 int l1size; /* level-1 size, number of history regs */ 00199 int l2size; /* level-2 size, number of pred states */ 00200 int shift_width; /* amount of history in level-1 shift regs */ 00201 int xor_h; /* history xor address flag */ 00202 int *shiftregs; /* level-1 history table */ 00203 unsigned char *l2table; /* level-2 prediction state table */ 00204 } two; 00205 } config; 00206 }; 00207 00208 //: branch predictor def 00209 //!SEC:ssBack 00210 struct bpred_t { 00211 enum bpred_class Pclass; /* type of predictor */ 00212 00213 //!SEC:ssBack 00214 struct { 00215 struct bpred_dir_t *bimod; /* first direction predictor */ 00216 struct bpred_dir_t *twolev; /* second direction predictor */ 00217 struct bpred_dir_t *meta; /* meta predictor */ 00218 } dirpred; 00219 00220 //: btb 00221 //!SEC:ssBack 00222 //!IGNORE: 00223 struct { 00224 //: num BTB sets 00225 int sets; 00226 //: BTB associativity 00227 int assoc; 00228 //: BTB addr-prediction table 00229 struct bpred_btb_ent_t *btb_data; 00230 } btb; 00231 00232 //!SEC:ssBack 00233 struct { 00234 int size; /* return-address stack size */ 00235 int tos; /* top-of-stack */ 00236 struct bpred_btb_ent_t *stack; /* return-address stack */ 00237 } retstack; 00238 00239 /* stats */ 00240 counter_t addr_hits; /* num correct addr-predictions */ 00241 counter_t dir_hits; /* num correct dir-predictions (incl addr) */ 00242 counter_t used_ras; /* num RAS predictions used */ 00243 counter_t used_bimod; /* num bimodal predictions used (BPredComb) */ 00244 counter_t used_2lev; /* num 2-level predictions used (BPredComb) */ 00245 counter_t jr_hits; /* num correct addr-predictions for JR's */ 00246 counter_t jr_seen; /* num JR's seen */ 00247 counter_t jr_non_ras_hits; /* num correct addr-preds for non-RAS JR's */ 00248 counter_t jr_non_ras_seen; /* num non-RAS JR's seen */ 00249 counter_t misses; /* num incorrect predictions */ 00250 00251 counter_t lookups; /* num lookups */ 00252 counter_t retstack_pops; /* number of times a value was popped */ 00253 counter_t retstack_pushes; /* number of times a value was pushed */ 00254 counter_t ras_hits; /* num correct return-address predictions */ 00255 }; 00256 00257 /* branch predictor update information */ 00258 //!IGNORE: 00259 struct bpred_update_t { 00260 char *pdir1; /* direction-1 predictor counter */ 00261 char *pdir2; /* direction-2 predictor counter */ 00262 char *pmeta; /* meta predictor counter */ 00263 struct { /* predicted directions */ 00264 unsigned int ras : 1; /* RAS used */ 00265 unsigned int bimod : 1; /* bimodal predictor */ 00266 unsigned int twolev : 1; /* 2-level predictor */ 00267 unsigned int meta : 1; /* meta predictor (0..bimod / 1..2lev) */ 00268 } dir; 00269 }; 00270 00271 /* create a branch predictor */ 00272 struct bpred_t * /* branch predictory instance */ 00273 bpred_create(enum bpred_class Pclass, /* type of predictor to create */ 00274 unsigned int bimod_size, /* bimod table size */ 00275 unsigned int l1size, /* level-1 table size */ 00276 unsigned int l2size, /* level-2 table size */ 00277 unsigned int meta_size, /* meta predictor table size */ 00278 unsigned int shift_width, /* history register width */ 00279 unsigned int xor_h, /* history xor address flag */ 00280 unsigned int btb_sets, /* number of sets in BTB */ 00281 unsigned int btb_assoc, /* BTB associativity */ 00282 unsigned int retstack_size);/* num entries in ret-addr stack */ 00283 00284 /* create a branch direction predictor */ 00285 struct bpred_dir_t * /* branch direction predictor instance */ 00286 bpred_dir_create ( 00287 enum bpred_class Pclass, /* type of predictor to create */ 00288 unsigned int l1size, /* level-1 table size */ 00289 unsigned int l2size, /* level-2 table size (if relevant) */ 00290 unsigned int shift_width, /* history register width */ 00291 unsigned int xor_h); /* history xor address flag */ 00292 00293 /* print branch predictor configuration */ 00294 void 00295 bpred_config(struct bpred_t *pred, /* branch predictor instance */ 00296 FILE *stream); /* output stream */ 00297 00298 /* print predictor stats */ 00299 void 00300 bpred_stats(struct bpred_t *pred, /* branch predictor instance */ 00301 FILE *stream); /* output stream */ 00302 00303 /* register branch predictor stats */ 00304 void 00305 bpred_reg_stats(struct bpred_t *pred, /* branch predictor instance */ 00306 struct stat_sdb_t *sdb);/* stats database */ 00307 00308 /* reset stats after priming, if appropriate */ 00309 void bpred_after_priming(struct bpred_t *bpred); 00310 00311 /* probe a predictor for a next fetch address, the predictor is probed 00312 with branch address BADDR, the branch target is BTARGET (used for 00313 static predictors), and OP is the instruction opcode (used to simulate 00314 predecode bits; a pointer to the predictor state entry (or null for jumps) 00315 is returned in *DIR_UPDATE_PTR (used for updating predictor state), 00316 and the non-speculative top-of-stack is returned in stack_recover_idx 00317 (used for recovering ret-addr stack after mis-predict). */ 00318 md_addr_t /* predicted branch target addr */ 00319 bpred_lookup(struct bpred_t *pred, /* branch predictor instance */ 00320 md_addr_t baddr, /* branch address */ 00321 md_addr_t btarget, /* branch target if taken */ 00322 enum md_opcode op, /* opcode of instruction */ 00323 int is_call, /* non-zero if inst is fn call */ 00324 int is_return, /* non-zero if inst is fn return */ 00325 struct bpred_update_t *dir_update_ptr, /* pred state pointer */ 00326 int *stack_recover_idx); /* Non-speculative top-of-stack; 00327 * used on mispredict recovery */ 00328 00329 /* Speculative execution can corrupt the ret-addr stack. So for each 00330 * lookup we return the top-of-stack (TOS) at that point; a mispredicted 00331 * branch, as part of its recovery, restores the TOS using this value -- 00332 * hopefully this uncorrupts the stack. */ 00333 void 00334 bpred_recover(struct bpred_t *pred, /* branch predictor instance */ 00335 md_addr_t baddr, /* branch address */ 00336 int stack_recover_idx); /* Non-speculative top-of-stack; 00337 * used on mispredict recovery */ 00338 00339 /* update the branch predictor, only useful for stateful predictors; updates 00340 entry for instruction type OP at address BADDR. BTB only gets updated 00341 for branches which are taken. Inst was determined to jump to 00342 address BTARGET and was taken if TAKEN is non-zero. Predictor 00343 statistics are updated with result of prediction, indicated by CORRECT and 00344 PRED_TAKEN, predictor state to be updated is indicated by *DIR_UPDATE_PTR 00345 (may be NULL for jumps, which shouldn't modify state bits). Note if 00346 bpred_update is done speculatively, branch-prediction may get polluted. */ 00347 void 00348 bpred_update(struct bpred_t *pred, /* branch predictor instance */ 00349 md_addr_t baddr, /* branch address */ 00350 md_addr_t btarget, /* resolved branch target */ 00351 int taken, /* non-zero if branch was taken */ 00352 int pred_taken, /* non-zero if branch was pred taken */ 00353 int correct, /* was earlier prediction correct? */ 00354 enum md_opcode op, /* opcode of instruction */ 00355 struct bpred_update_t *dir_update_ptr); /* pred state pointer */ 00356 00357 00358 #ifdef foo0 00359 /* OBSOLETE */ 00360 /* dump branch predictor state (for debug) */ 00361 void 00362 bpred_dump(struct bpred_t *pred, /* branch predictor instance */ 00363 FILE *stream); /* output stream */ 00364 #endif 00365 00366 #endif /* BPRED_H */