/****************************************************************************** ** FILE: branch.c ** Branch predictor. */ #include <assert.h> #include <sys/types.h> #include "internal.h" #include "param.h" /* These are the functions that are called from Facile */ extern void xbranch_init(); extern uchar_t xbranch_predict(ulong_t); extern void xbranch_direction(ulong_t,uchar_t); /* Branch Predictor Statistics */ u_longlong_t count_branch_predict = 0; u_longlong_t count_branch_direction = 0; /*****************************************************************************/ #define BYTES_PER_INST 4 #define BRANCH_PREDICTOR_ENTRIES \ (BRANCH_PREDICTOR_SIZE*8/BRANCH_PREDICTOR_BITS) #define SIGN_MASK (1 << (BRANCH_PREDICTOR_BITS-1)) #define MIN_VALUE (-1 << (BRANCH_PREDICTOR_BITS-1)) #define MAX_VALUE (~MIN_VALUE) static signed char predictor[BRANCH_PREDICTOR_ENTRIES]; void xbranch_init() { ulong_t ii; for(ii=0; ii<BRANCH_PREDICTOR_ENTRIES; ++ii) predictor[ii] = 0; } uchar_t xbranch_predict(ulong_t pc) { ulong_t index; #ifdef STATS ++count_branch_predict; #endif index = (pc/BYTES_PER_INST) % BRANCH_PREDICTOR_ENTRIES; return !(predictor[index] & SIGN_MASK); } void xbranch_direction(ulong_t pc, uchar_t taken) { ulong_t index; #ifdef STATS ++count_branch_direction; #endif index = (pc/BYTES_PER_INST) % BRANCH_PREDICTOR_ENTRIES; predictor[index] += taken ? 1 : -1; if(predictor[index] > MAX_VALUE) predictor[index] = MAX_VALUE; else if(predictor[index] < MIN_VALUE) predictor[index] = MIN_VALUE; }