diff --git a/src/arch/generic/BaseTLB.py b/src/arch/generic/BaseTLB.py index 8af4585c6e..cbc296b0d6 100644 --- a/src/arch/generic/BaseTLB.py +++ b/src/arch/generic/BaseTLB.py @@ -45,6 +45,13 @@ class TypeTLB(ScopedEnum): instruction: TLB contains instruction entries only data: TLB contains data entries only unified: TLB contains both instruction and data entries + + The enum values have been selected in order to perform bitwise + operations on them. For example a unified TLB contains both + instruction and data entries so code trying to assess if the + TLB is storing (e.g.) data entries can do that with: + + bool has_data = tlb->type() & TypeTLB::data; """ map = { 'instruction' : 0x1, diff --git a/src/arch/generic/tlb.hh b/src/arch/generic/tlb.hh index 8f192ebfe5..16b7eec48f 100644 --- a/src/arch/generic/tlb.hh +++ b/src/arch/generic/tlb.hh @@ -41,6 +41,8 @@ #ifndef __ARCH_GENERIC_TLB_HH__ #define __ARCH_GENERIC_TLB_HH__ +#include + #include "arch/generic/mmu.hh" #include "base/logging.hh" #include "enums/TypeTLB.hh" @@ -125,6 +127,21 @@ class BaseTLB : public SimObject BaseTLB* nextLevel() const { return _nextLevel; } }; +/** Implementing the "&" bitwise operator for TypeTLB allows us to handle + * TypeTLB::unified efficiently. For example if I want to check if a TLB + * is storing instruction entries I can do this with: + * + * tlb->type() & TypeTLB::instruction + * + * which will cover both TypeTLB::instruction and TypeTLB::unified TLBs + */ +inline auto +operator&(TypeTLB lhs, TypeTLB rhs) +{ + using T = std::underlying_type_t; + return static_cast(lhs) & static_cast(rhs); +} + } // namespace gem5 #endif // __ARCH_GENERIC_TLB_HH__