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: bpred.h,v 1.1.1.1 2003/09/18 00:57:54 panalyzer Exp $ 00053 * 00054 * $Log: bpred.h,v $ 00055 * Revision 1.1.1.1 2003/09/18 00:57:54 panalyzer 00056 * 00057 * 00058 * Revision 1.1.1.1 2003/09/18 00:18:43 panalyzer 00059 * 00060 * 00061 * Revision 1.1.1.1 2003/09/16 18:48:14 gdm 00062 * 00063 * 00064 * Revision 1.1.1.1 2000/11/29 14:53:54 cu-cs 00065 * Grand unification of arm sources. 00066 * 00067 * 00068 * Revision 1.1.1.1 2000/05/26 15:18:57 taustin 00069 * SimpleScalar Tool Set 00070 * 00071 * 00072 * Revision 1.5 1998/08/31 17:12:11 taustin 00073 * eliminated unportable "uint" reference 00074 * 00075 * Revision 1.4 1998/08/27 08:00:15 taustin 00076 * implemented host interface description in host.h 00077 * explicit BTB sizing option added to branch predictors, use 00078 * "-btb" option to configure BTB 00079 * return address stack (RAS) performance stats improved 00080 * 00081 * Revision 1.1.1.1 1997/05/22 18:04:05 aklauser 00082 * 00083 * Revision 1.8 1997/05/01 20:23:06 skadron 00084 * BTB bug fixes; jumps no longer update direction state; non-taken 00085 * branches non longer update BTB 00086 * 00087 * Revision 1.7 1997/05/01 00:05:51 skadron 00088 * Separated BTB from direction-predictor 00089 * 00090 * Revision 1.6 1997/04/29 23:50:44 skadron 00091 * Added r31 info to distinguish between return-JRs and other JRs for bpred 00092 * 00093 * Revision 1.5 1997/04/29 22:53:10 skadron 00094 * Hopefully bpred is now right: bpred now allocates entries only for 00095 * branches; on a BTB miss it still returns a direction; and it uses a 00096 * return-address stack. Returns are not yet distinguished among JR's 00097 * 00098 * Revision 1.4 1997/04/28 17:37:09 skadron 00099 * Bpred now allocates entries for any instruction instead of only 00100 * branches; also added return-address stack 00101 * 00102 * Revision 1.3 1997/04/24 16:57:27 skadron 00103 * Bpred used to return no prediction if the indexing branch didn't match 00104 * in the BTB. Now it can predict a direction even on a BTB address 00105 * conflict 00106 * 00107 * Revision 1.2 1997/03/25 16:17:21 skadron 00108 * Added function called after priming 00109 * 00110 * Revision 1.1 1997/02/16 22:23:54 skadron 00111 * Initial revision 00112 * 00113 * 00114 */ 00115 00116 #ifndef BPRED_H 00117 #define BPRED_H 00118 00119 #define dassert(a) assert(a) 00120 00121 #include <stdio.h> 00122 00123 #include "host.h" 00124 #include "misc.h" 00125 #include "machine.h" 00126 #include "stats.h" 00127 00128 /* 00129 * This module implements a number of branch predictor mechanisms. The 00130 * following predictors are supported: 00131 * 00132 * BPred2Level: two level adaptive branch predictor 00133 * 00134 * It can simulate many prediction mechanisms that have up to 00135 * two levels of tables. Parameters are: 00136 * N # entries in first level (# of shift register(s)) 00137 * W width of shift register(s) 00138 * M # entries in 2nd level (# of counters, or other FSM) 00139 * One BTB entry per level-2 counter. 00140 * 00141 * Configurations: N, W, M 00142 * 00143 * counter based: 1, 0, M 00144 * 00145 * GAg : 1, W, 2^W 00146 * GAp : 1, W, M (M > 2^W) 00147 * PAg : N, W, 2^W 00148 * PAp : N, W, M (M == 2^(N+W)) 00149 * 00150 * BPred2bit: a simple direct mapped bimodal predictor 00151 * 00152 * This predictor has a table of two bit saturating counters. 00153 * Where counter states 0 & 1 are predict not taken and 00154 * counter states 2 & 3 are predict taken, the per-branch counters 00155 * are incremented on taken branches and decremented on 00156 * no taken branches. One BTB entry per counter. 00157 * 00158 * BPredTaken: static predict branch taken 00159 * 00160 * BPredNotTaken: static predict branch not taken 00161 * 00162 */ 00163 00164 /* branch predictor types */ 00165 enum bpred_class { 00166 BPredComb, /* combined predictor (McFarling) */ 00167 BPred2Level, /* 2-level correlating pred w/2-bit counters */ 00168 BPred2bit, /* 2-bit saturating cntr pred (dir mapped) */ 00169 BPredTaken, /* static predict taken */ 00170 BPredNotTaken, /* static predict not taken */ 00171 BPred_NUM 00172 }; 00173 00174 /* an entry in a BTB */ 00175 struct bpred_btb_ent_t { 00176 md_addr_t addr; /* address of branch being tracked */ 00177 enum md_opcode op; /* opcode of branch corresp. to addr */ 00178 md_addr_t target; /* last destination of branch when taken */ 00179 struct bpred_btb_ent_t *prev, *next; /* lru chaining pointers */ 00180 }; 00181 00182 /* direction predictor def */ 00183 struct bpred_dir_t { 00184 enum bpred_class class; /* type of predictor */ 00185 union { 00186 struct { 00187 unsigned int size; /* number of entries in direct-mapped table */ 00188 unsigned char *table; /* prediction state table */ 00189 } bimod; 00190 struct { 00191 int l1size; /* level-1 size, number of history regs */ 00192 int l2size; /* level-2 size, number of pred states */ 00193 int shift_width; /* amount of history in level-1 shift regs */ 00194 int xor; /* history xor address flag */ 00195 int *shiftregs; /* level-1 history table */ 00196 unsigned char *l2table; /* level-2 prediction state table */ 00197 } two; 00198 } config; 00199 }; 00200 00201 /* branch predictor def */ 00202 struct bpred_t { 00203 enum bpred_class class; /* type of predictor */ 00204 struct { 00205 struct bpred_dir_t *bimod; /* first direction predictor */ 00206 struct bpred_dir_t *twolev; /* second direction predictor */ 00207 struct bpred_dir_t *meta; /* meta predictor */ 00208 } dirpred; 00209 00210 struct { 00211 int sets; /* num BTB sets */ 00212 int assoc; /* BTB associativity */ 00213 struct bpred_btb_ent_t *btb_data; /* BTB addr-prediction table */ 00214 } btb; 00215 00216 struct { 00217 int size; /* return-address stack size */ 00218 int tos; /* top-of-stack */ 00219 struct bpred_btb_ent_t *stack; /* return-address stack */ 00220 } retstack; 00221 00222 /* stats */ 00223 counter_t addr_hits; /* num correct addr-predictions */ 00224 counter_t dir_hits; /* num correct dir-predictions (incl addr) */ 00225 counter_t used_ras; /* num RAS predictions used */ 00226 counter_t used_bimod; /* num bimodal predictions used (BPredComb) */ 00227 counter_t used_2lev; /* num 2-level predictions used (BPredComb) */ 00228 counter_t jr_hits; /* num correct addr-predictions for JR's */ 00229 counter_t jr_seen; /* num JR's seen */ 00230 counter_t jr_non_ras_hits; /* num correct addr-preds for non-RAS JR's */ 00231 counter_t jr_non_ras_seen; /* num non-RAS JR's seen */ 00232 counter_t misses; /* num incorrect predictions */ 00233 00234 counter_t lookups; /* num lookups */ 00235 counter_t retstack_pops; /* number of times a value was popped */ 00236 counter_t retstack_pushes; /* number of times a value was pushed */ 00237 counter_t ras_hits; /* num correct return-address predictions */ 00238 }; 00239 00240 /* branch predictor update information */ 00241 struct bpred_update_t { 00242 char *pdir1; /* direction-1 predictor counter */ 00243 char *pdir2; /* direction-2 predictor counter */ 00244 char *pmeta; /* meta predictor counter */ 00245 struct { /* predicted directions */ 00246 unsigned int ras : 1; /* RAS used */ 00247 unsigned int bimod : 1; /* bimodal predictor */ 00248 unsigned int twolev : 1; /* 2-level predictor */ 00249 unsigned int meta : 1; /* meta predictor (0..bimod / 1..2lev) */ 00250 } dir; 00251 }; 00252 00253 /* create a branch predictor */ 00254 struct bpred_t * /* branch predictory instance */ 00255 bpred_create(enum bpred_class class, /* type of predictor to create */ 00256 unsigned int bimod_size, /* bimod table size */ 00257 unsigned int l1size, /* level-1 table size */ 00258 unsigned int l2size, /* level-2 table size */ 00259 unsigned int meta_size, /* meta predictor table size */ 00260 unsigned int shift_width, /* history register width */ 00261 unsigned int xor, /* history xor address flag */ 00262 unsigned int btb_sets, /* number of sets in BTB */ 00263 unsigned int btb_assoc, /* BTB associativity */ 00264 unsigned int retstack_size);/* num entries in ret-addr stack */ 00265 00266 /* create a branch direction predictor */ 00267 struct bpred_dir_t * /* branch direction predictor instance */ 00268 bpred_dir_create ( 00269 enum bpred_class class, /* type of predictor to create */ 00270 unsigned int l1size, /* level-1 table size */ 00271 unsigned int l2size, /* level-2 table size (if relevant) */ 00272 unsigned int shift_width, /* history register width */ 00273 unsigned int xor); /* history xor address flag */ 00274 00275 /* print branch predictor configuration */ 00276 void 00277 bpred_config(struct bpred_t *pred, /* branch predictor instance */ 00278 FILE *stream); /* output stream */ 00279 00280 /* print predictor stats */ 00281 void 00282 bpred_stats(struct bpred_t *pred, /* branch predictor instance */ 00283 FILE *stream); /* output stream */ 00284 00285 /* register branch predictor stats */ 00286 void 00287 bpred_reg_stats(struct bpred_t *pred, /* branch predictor instance */ 00288 struct stat_sdb_t *sdb);/* stats database */ 00289 00290 /* reset stats after priming, if appropriate */ 00291 void bpred_after_priming(struct bpred_t *bpred); 00292 00293 /* probe a predictor for a next fetch address, the predictor is probed 00294 with branch address BADDR, the branch target is BTARGET (used for 00295 static predictors), and OP is the instruction opcode (used to simulate 00296 predecode bits; a pointer to the predictor state entry (or null for jumps) 00297 is returned in *DIR_UPDATE_PTR (used for updating predictor state), 00298 and the non-speculative top-of-stack is returned in stack_recover_idx 00299 (used for recovering ret-addr stack after mis-predict). */ 00300 md_addr_t /* predicted branch target addr */ 00301 bpred_lookup(struct bpred_t *pred, /* branch predictor instance */ 00302 md_addr_t baddr, /* branch address */ 00303 md_addr_t btarget, /* branch target if taken */ 00304 enum md_opcode op, /* opcode of instruction */ 00305 int is_call, /* non-zero if inst is fn call */ 00306 int is_return, /* non-zero if inst is fn return */ 00307 struct bpred_update_t *dir_update_ptr, /* pred state pointer */ 00308 int *stack_recover_idx); /* Non-speculative top-of-stack; 00309 * used on mispredict recovery */ 00310 00311 /* Speculative execution can corrupt the ret-addr stack. So for each 00312 * lookup we return the top-of-stack (TOS) at that point; a mispredicted 00313 * branch, as part of its recovery, restores the TOS using this value -- 00314 * hopefully this uncorrupts the stack. */ 00315 void 00316 bpred_recover(struct bpred_t *pred, /* branch predictor instance */ 00317 md_addr_t baddr, /* branch address */ 00318 int stack_recover_idx); /* Non-speculative top-of-stack; 00319 * used on mispredict recovery */ 00320 00321 /* update the branch predictor, only useful for stateful predictors; updates 00322 entry for instruction type OP at address BADDR. BTB only gets updated 00323 for branches which are taken. Inst was determined to jump to 00324 address BTARGET and was taken if TAKEN is non-zero. Predictor 00325 statistics are updated with result of prediction, indicated by CORRECT and 00326 PRED_TAKEN, predictor state to be updated is indicated by *DIR_UPDATE_PTR 00327 (may be NULL for jumps, which shouldn't modify state bits). Note if 00328 bpred_update is done speculatively, branch-prediction may get polluted. */ 00329 void 00330 bpred_update(struct bpred_t *pred, /* branch predictor instance */ 00331 md_addr_t baddr, /* branch address */ 00332 md_addr_t btarget, /* resolved branch target */ 00333 int taken, /* non-zero if branch was taken */ 00334 int pred_taken, /* non-zero if branch was pred taken */ 00335 int correct, /* was earlier prediction correct? */ 00336 enum md_opcode op, /* opcode of instruction */ 00337 struct bpred_update_t *dir_update_ptr); /* pred state pointer */ 00338 00339 00340 #ifdef foo0 00341 /* OBSOLETE */ 00342 /* dump branch predictor state (for debug) */ 00343 void 00344 bpred_dump(struct bpred_t *pred, /* branch predictor instance */ 00345 FILE *stream); /* output stream */ 00346 #endif 00347 00348 #endif /* BPRED_H */