3 #include "cpu/beta_cpu/btb.hh"
4 #include "base/trace.hh"
6 DefaultBTB::DefaultBTB(unsigned _numEntries
,
8 unsigned _instShiftAmt
)
9 : numEntries(_numEntries
),
11 instShiftAmt(_instShiftAmt
)
13 // @todo Check to make sure num_entries is valid (a power of 2)
15 DPRINTF(Fetch
, "BTB: Creating BTB object.\n");
17 btb
= new BTBEntry
[numEntries
];
19 for (int i
= 0; i
< numEntries
; ++i
)
24 idxMask
= numEntries
- 1;
26 tagMask
= (1 << tagBits
) - 1;
28 tagShiftAmt
= instShiftAmt
+ (int)log2(numEntries
);
33 DefaultBTB::getIndex(const Addr
&inst_PC
)
35 // Need to shift PC over by the word offset.
36 return (inst_PC
>> instShiftAmt
) & idxMask
;
41 DefaultBTB::getTag(const Addr
&inst_PC
)
43 return (inst_PC
>> tagShiftAmt
) & tagMask
;
47 DefaultBTB::valid(const Addr
&inst_PC
)
49 unsigned btb_idx
= getIndex(inst_PC
);
51 Addr inst_tag
= getTag(inst_PC
);
53 assert(btb_idx
< numEntries
);
55 if (btb
[btb_idx
].valid
&& inst_tag
== btb
[btb_idx
].tag
) {
62 // @todo Create some sort of return struct that has both whether or not the
63 // address is valid, and also the address. For now will just use addr = 0 to
64 // represent invalid entry.
66 DefaultBTB::lookup(const Addr
&inst_PC
)
68 unsigned btb_idx
= getIndex(inst_PC
);
70 Addr inst_tag
= getTag(inst_PC
);
72 assert(btb_idx
< numEntries
);
74 if (btb
[btb_idx
].valid
&& inst_tag
== btb
[btb_idx
].tag
) {
75 return btb
[btb_idx
].target
;
82 DefaultBTB::update(const Addr
&inst_PC
, const Addr
&target
)
84 unsigned btb_idx
= getIndex(inst_PC
);
86 assert(btb_idx
< numEntries
);
88 btb
[btb_idx
].valid
= true;
89 btb
[btb_idx
].target
= target
;
90 btb
[btb_idx
].tag
= getTag(inst_PC
);