diff --git a/src/cpu/probes/pc_count_pair.hh b/src/cpu/probes/pc_count_pair.hh new file mode 100644 index 0000000000..fd6bc639fe --- /dev/null +++ b/src/cpu/probes/pc_count_pair.hh @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2023 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PC_COUNT_PAIR_HH__ +#define __PC_COUNT_PAIR_HH__ + +#include "base/types.hh" + +namespace gem5 +{ + +class PcCountPair +{ + + private: + + /** The Program Counter address */ + Addr pc; + /** The count of the Program Counter address */ + int count; + + public: + + /** Explicit constructor assigning the pc and count values */ + explicit constexpr PcCountPair(Addr _pc, int _count) : + pc(_pc), count(_count) {} + + /** Default constructor for parameter classes */ + PcCountPair() : pc(0), count(0) {} + + /** Returns the Program Counter address */ + constexpr Addr getPC() const { return pc; } + /** Returns the count of the Program */ + constexpr int getCount() const { return count; } + + /** Greater than comparison */ + constexpr bool + operator>(const PcCountPair& cc) const + { + return count > cc.getCount(); + } + + /** Equal comparison */ + constexpr bool + operator==(const PcCountPair& cc) const + { + return (pc == cc.getPC() && count == cc.getCount()); + } + + /** String format */ + std::string + to_string() const + { + std::string s = "(" + std::to_string(pc) + + "," + std::to_string(count) + ")"; + return s; + } + + /** Enable hashing for this parameter */ + struct HashFunction + { + size_t operator()(const PcCountPair& item) const + { + size_t xHash = std::hash()(item.pc); + size_t yHash = std::hash()(item.count); + return xHash * 2 + yHash; + } + }; + +}; + +} // namespace gem5 + +#endif // __PC_COUNT_PAIR_HH__ diff --git a/src/python/m5/params.py b/src/python/m5/params.py index e76380bc40..92e913b2f0 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -854,6 +854,46 @@ class Addr(CheckedInt): return "0x%x" % int(val) +class PcCountPair(ParamValue): + # This parameter stores a Program Counter address and the a count value for + # the Program Counter address + cxx_type = "PcCountPair" + cmd_line_settable = True + + def __init__(self, _pc, _count): + self.pc = _pc + self.count = _count + + def get_pc(self): + return self.pc + + def get_count(self): + return self.count + + def getValue(self): + # convert Python PcCountPair into C++ PcCountPair + from _m5.pc import PcCountPair + + return PcCountPair(self.pc, self.count) + + def __str__(self): + return "(%i,%i)" % (self.pc, self.count) + + def __eq__(self, other): + return self.pc == other.get_pc() and self.count == other.get_count() + + def __hash__(self): + return hash((int(self.pc), int(self.count))) + + @classmethod + def cxx_predecls(cls, code): + code('#include "cpu/probes/pc_count_pair.hh"') + + @classmethod + def pybind_predecls(cls, code): + code('#include "cpu/probes/pc_count_pair.hh"') + + class AddrRange(ParamValue): cxx_type = "AddrRange" @@ -2426,4 +2466,5 @@ __all__ = [ "VectorMasterPort", "VectorSlavePort", "DeprecatedParam", + "PcCountPair", ] diff --git a/src/python/pybind11/core.cc b/src/python/pybind11/core.cc index 89466750d0..bd83a74331 100644 --- a/src/python/pybind11/core.cc +++ b/src/python/pybind11/core.cc @@ -58,6 +58,7 @@ #include "sim/drain.hh" #include "sim/serialize.hh" #include "sim/sim_object.hh" +#include "cpu/probes/pc_count_pair.hh" namespace py = pybind11; @@ -163,6 +164,31 @@ init_range(py::module_ &m_native) m.def("RangeSize", &RangeSize); } +static void +init_pc(py::module_ &m_native) +{ + py::module_ m = m_native.def_submodule("pc"); + py::class_(m, "PcCountPair") + .def(py::init<>()) + .def(py::init()) + .def("__eq__", [](const PcCountPair& self, py::object other) { + py::int_ pyPC = other.attr("get_pc")(); + py::int_ pyCount = other.attr("get_count")(); + uint64_t cPC = pyPC.cast(); + int cCount = pyCount.cast(); + return (self.getPC() == cPC && self.getCount() == cCount); + }) + .def("__hash__", [](const PcCountPair& self){ + py::int_ pyPC = py::cast(self.getPC()); + py::int_ pyCount = py::cast(self.getCount()); + return py::hash(py::make_tuple(pyPC, pyCount)); + }) + .def("__str__", &PcCountPair::to_string) + .def("get_pc", &PcCountPair::getPC) + .def("get_count", &PcCountPair::getCount) + ; +} + static void init_net(py::module_ &m_native) { @@ -307,6 +333,7 @@ pybind_init_core(py::module_ &m_native) init_range(m_native); init_net(m_native); init_loader(m_native); + init_pc(m_native); } } // namespace gem5