/******************************************************************************
** 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;
}