# Copyright (c) 2012-2014, 2017-2019, 2021 Arm Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Copyright (c) 2004-2006 The Regents of The University of Michigan
# Copyright (c) 2010-2011 Advanced Micro Devices, Inc.
# 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.

#####################################################################
#
# Parameter description classes
#
# The _params dictionary in each class maps parameter names to either
# a Param or a VectorParam object.  These objects contain the
# parameter description string, the parameter type, and the default
# value (if any).  The convert() method on these objects is used to
# force whatever value is assigned to the parameter to the appropriate
# type.
#
# Note that the default values are loaded into the class's attribute
# space when the parameter dictionary is initialized (in
# MetaSimObject._new_param()); after that point they aren't used.
#
#####################################################################

import copy
import datetime
import re
import sys
import time
import math

from . import proxy
from . import ticks
from .util import *


def isSimObject(*args, **kwargs):
    from . import SimObject

    return SimObject.isSimObject(*args, **kwargs)


def isSimObjectSequence(*args, **kwargs):
    from . import SimObject

    return SimObject.isSimObjectSequence(*args, **kwargs)


def isSimObjectClass(*args, **kwargs):
    from . import SimObject

    return SimObject.isSimObjectClass(*args, **kwargs)


allParams = {}


class MetaParamValue(type):
    def __new__(mcls, name, bases, dct):
        cls = super().__new__(mcls, name, bases, dct)
        if name in allParams:
            warn(
                "%s already exists in allParams. This may be caused by the "
                "Python 2.7 compatibility layer." % (name,)
            )
        allParams[name] = cls
        return cls


# Dummy base class to identify types that are legitimate for SimObject
# parameters.
class ParamValue(object, metaclass=MetaParamValue):
    cmd_line_settable = False

    # Generate the code needed as a prerequisite for declaring a C++
    # object of this type.  Typically generates one or more #include
    # statements.  Used when declaring parameters of this type.
    @classmethod
    def cxx_predecls(cls, code):
        pass

    @classmethod
    def pybind_predecls(cls, code):
        cls.cxx_predecls(code)

    # default for printing to .ini file is regular string conversion.
    # will be overridden in some cases
    def ini_str(self):
        return str(self)

    # default for printing to .json file is regular string conversion.
    # will be overridden in some cases, mostly to use native Python
    # types where there are similar JSON types
    def config_value(self):
        return str(self)

    # Prerequisites for .ini parsing with cxx_ini_parse
    @classmethod
    def cxx_ini_predecls(cls, code):
        pass

    # parse a .ini file entry for this param from string expression
    # src into lvalue dest (of the param's C++ type)
    @classmethod
    def cxx_ini_parse(cls, code, src, dest, ret):
        code("// Unhandled param type: %s" % cls.__name__)
        code("%s false;" % ret)

    # allows us to blithely call unproxy() on things without checking
    # if they're really proxies or not
    def unproxy(self, base):
        return self

    # Produce a human readable version of the stored value
    def pretty_print(self, value):
        return str(value)


# Regular parameter description.
class ParamDesc(object):
    def __init__(self, ptype_str, ptype, *args, **kwargs):
        self.ptype_str = ptype_str
        # remember ptype only if it is provided
        if ptype != None:
            self.ptype = ptype

        if args:
            if len(args) == 1:
                self.desc = args[0]
            elif len(args) == 2:
                self.default = args[0]
                self.desc = args[1]
            else:
                raise TypeError("too many arguments")

        if "desc" in kwargs:
            assert not hasattr(self, "desc")
            self.desc = kwargs["desc"]
            del kwargs["desc"]

        if "default" in kwargs:
            assert not hasattr(self, "default")
            self.default = kwargs["default"]
            del kwargs["default"]

        if kwargs:
            raise TypeError("extra unknown kwargs %s" % kwargs)

        if not hasattr(self, "desc"):
            raise TypeError("desc attribute missing")

    def __getattr__(self, attr):
        if attr == "ptype":
            from . import SimObject

            ptype = SimObject.allClasses[self.ptype_str]
            assert isSimObjectClass(ptype)
            self.ptype = ptype
            return ptype

        raise AttributeError(
            "'%s' object has no attribute '%s'" % (type(self).__name__, attr)
        )

    def example_str(self):
        if hasattr(self.ptype, "ex_str"):
            return self.ptype.ex_str
        else:
            return self.ptype_str

    # Is the param available to be exposed on the command line
    def isCmdLineSettable(self):
        if hasattr(self.ptype, "cmd_line_settable"):
            return self.ptype.cmd_line_settable
        else:
            return False

    def convert(self, value):
        if isinstance(value, proxy.BaseProxy):
            value.set_param_desc(self)
            return value
        if "ptype" not in self.__dict__ and isNullPointer(value):
            # deferred evaluation of SimObject; continue to defer if
            # we're just assigning a null pointer
            return value
        if isinstance(value, self.ptype):
            return value
        if isNullPointer(value) and isSimObjectClass(self.ptype):
            return value
        return self.ptype(value)

    def pretty_print(self, value):
        if isinstance(value, proxy.BaseProxy):
            return str(value)
        if isNullPointer(value):
            return NULL
        return self.ptype(value).pretty_print(value)

    def cxx_predecls(self, code):
        code("#include <cstddef>")
        self.ptype.cxx_predecls(code)

    def pybind_predecls(self, code):
        self.ptype.pybind_predecls(code)

    def cxx_decl(self, code):
        code("${{self.ptype.cxx_type}} ${{self.name}};")


# Vector-valued parameter description.  Just like ParamDesc, except
# that the value is a vector (list) of the specified type instead of a
# single value.


class VectorParamValue(list, metaclass=MetaParamValue):
    def __setattr__(self, attr, value):
        raise AttributeError(
            "Not allowed to set %s on '%s'" % (attr, type(self).__name__)
        )

    def config_value(self):
        return [v.config_value() for v in self]

    def ini_str(self):
        return " ".join([v.ini_str() for v in self])

    def getValue(self):
        return [v.getValue() for v in self]

    def unproxy(self, base):
        if len(self) == 1 and isinstance(self[0], proxy.BaseProxy):
            # The value is a proxy (e.g. Parent.any, Parent.all or
            # Parent.x) therefore try resolve it
            return self[0].unproxy(base)
        else:
            return [v.unproxy(base) for v in self]


class SimObjectVector(VectorParamValue):
    # support clone operation
    def __call__(self, **kwargs):
        return SimObjectVector([v(**kwargs) for v in self])

    def clear_parent(self, old_parent):
        for v in self:
            v.clear_parent(old_parent)

    def set_parent(self, parent, name):
        if len(self) == 1:
            self[0].set_parent(parent, name)
        else:
            width = int(math.ceil(math.log(len(self)) / math.log(10)))
            for i, v in enumerate(self):
                v.set_parent(parent, "%s%0*d" % (name, width, i))

    def has_parent(self):
        return any([e.has_parent() for e in self if not isNullPointer(e)])

    # return 'cpu0 cpu1' etc. for print_ini()
    def get_name(self):
        return " ".join([v._name for v in self])

    # By iterating through the constituent members of the vector here
    # we can nicely handle iterating over all a SimObject's children
    # without having to provide lots of special functions on
    # SimObjectVector directly.
    def descendants(self):
        for v in self:
            for obj in v.descendants():
                yield obj

    def get_config_as_dict(self):
        a = []
        for v in self:
            a.append(v.get_config_as_dict())
        return a

    # If we are replacing an item in the vector, make sure to set the
    # parent reference of the new SimObject to be the same as the parent
    # of the SimObject being replaced. Useful to have if we created
    # a SimObjectVector of temporary objects that will be modified later in
    # configuration scripts.
    def __setitem__(self, key, value):
        val = self[key]
        if value.has_parent():
            warn(
                "SimObject %s already has a parent" % value.get_name()
                + " that is being overwritten by a SimObjectVector"
            )
        value.set_parent(val.get_parent(), val._name)
        super().__setitem__(key, value)

    # Enumerate the params of each member of the SimObject vector. Creates
    # strings that will allow indexing into the vector by the python code and
    # allow it to be specified on the command line.
    def enumerateParams(self, flags_dict={}, cmd_line_str="", access_str=""):
        if hasattr(self, "_paramEnumed"):
            print("Cycle detected enumerating params at %s?!" % (cmd_line_str))
        else:
            x = 0
            for vals in self:
                # Each entry in the SimObjectVector should be an
                # instance of a SimObject
                flags_dict = vals.enumerateParams(
                    flags_dict,
                    cmd_line_str + "%d." % x,
                    access_str + "[%d]." % x,
                )
                x = x + 1

        return flags_dict


class VectorParamDesc(ParamDesc):
    # Convert assigned value to appropriate type.  If the RHS is not a
    # list or tuple, it generates a single-element list.
    def convert(self, value):
        if isinstance(value, (list, tuple)):
            # list: coerce each element into new list
            tmp_list = [ParamDesc.convert(self, v) for v in value]
        elif isinstance(value, str):
            # If input is a csv string
            tmp_list = [
                ParamDesc.convert(self, v)
                for v in value.strip("[").strip("]").split(",")
            ]
        else:
            # singleton: coerce to a single-element list
            tmp_list = [ParamDesc.convert(self, value)]

        if isSimObjectSequence(tmp_list):
            return SimObjectVector(tmp_list)
        else:
            return VectorParamValue(tmp_list)

    # Produce a human readable example string that describes
    # how to set this vector parameter in the absence of a default
    # value.
    def example_str(self):
        s = super().example_str()
        help_str = "[" + s + "," + s + ", ...]"
        return help_str

    # Produce a human readable representation of the value of this vector param.
    def pretty_print(self, value):
        if isinstance(value, (list, tuple)):
            tmp_list = [ParamDesc.pretty_print(self, v) for v in value]
        elif isinstance(value, str):
            tmp_list = [
                ParamDesc.pretty_print(self, v) for v in value.split(",")
            ]
        else:
            tmp_list = [ParamDesc.pretty_print(self, value)]

        return tmp_list

    # This is a helper function for the new config system
    def __call__(self, value):
        if isinstance(value, (list, tuple)):
            # list: coerce each element into new list
            tmp_list = [ParamDesc.convert(self, v) for v in value]
        elif isinstance(value, str):
            # If input is a csv string
            tmp_list = [
                ParamDesc.convert(self, v)
                for v in value.strip("[").strip("]").split(",")
            ]
        else:
            # singleton: coerce to a single-element list
            tmp_list = [ParamDesc.convert(self, value)]

        return VectorParamValue(tmp_list)

    def cxx_predecls(self, code):
        code("#include <vector>")
        self.ptype.cxx_predecls(code)

    def pybind_predecls(self, code):
        code("#include <vector>")
        self.ptype.pybind_predecls(code)

    def cxx_decl(self, code):
        code("std::vector< ${{self.ptype.cxx_type}} > ${{self.name}};")


class ParamFactory(object):
    def __init__(self, param_desc_class, ptype_str=None):
        self.param_desc_class = param_desc_class
        self.ptype_str = ptype_str

    def __getattr__(self, attr):
        if self.ptype_str:
            attr = self.ptype_str + "." + attr
        return ParamFactory(self.param_desc_class, attr)

    # E.g., Param.Int(5, "number of widgets")
    def __call__(self, *args, **kwargs):
        ptype = None
        try:
            ptype = allParams[self.ptype_str]
        except KeyError:
            # if name isn't defined yet, assume it's a SimObject, and
            # try to resolve it later
            pass
        return self.param_desc_class(self.ptype_str, ptype, *args, **kwargs)


Param = ParamFactory(ParamDesc)
VectorParam = ParamFactory(VectorParamDesc)

#####################################################################
#
# Parameter Types
#
# Though native Python types could be used to specify parameter types
# (the 'ptype' field of the Param and VectorParam classes), it's more
# flexible to define our own set of types.  This gives us more control
# over how Python expressions are converted to values (via the
# __init__() constructor) and how these values are printed out (via
# the __str__() conversion method).
#
#####################################################################

# String-valued parameter.  Just mixin the ParamValue class with the
# built-in str class.
class String(ParamValue, str):
    cxx_type = "std::string"
    cmd_line_settable = True

    @classmethod
    def cxx_predecls(self, code):
        code("#include <string>")

    def __call__(self, value):
        self = value
        return value

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code("%s = %s;" % (dest, src))
        code("%s true;" % ret)

    def getValue(self):
        return self


# superclass for "numeric" parameter values, to emulate math
# operations in a type-safe way.  e.g., a Latency times an int returns
# a new Latency object.
class NumericParamValue(ParamValue):
    @staticmethod
    def unwrap(v):
        return v.value if isinstance(v, NumericParamValue) else v

    def __str__(self):
        return str(self.value)

    def __float__(self):
        return float(self.value)

    def __int__(self):
        return int(self.value)

    # hook for bounds checking
    def _check(self):
        return

    def __mul__(self, other):
        newobj = self.__class__(self)
        newobj.value *= NumericParamValue.unwrap(other)
        newobj._check()
        return newobj

    __rmul__ = __mul__

    def __truediv__(self, other):
        newobj = self.__class__(self)
        newobj.value /= NumericParamValue.unwrap(other)
        newobj._check()
        return newobj

    def __floordiv__(self, other):
        newobj = self.__class__(self)
        newobj.value //= NumericParamValue.unwrap(other)
        newobj._check()
        return newobj

    def __add__(self, other):
        newobj = self.__class__(self)
        newobj.value += NumericParamValue.unwrap(other)
        newobj._check()
        return newobj

    def __sub__(self, other):
        newobj = self.__class__(self)
        newobj.value -= NumericParamValue.unwrap(other)
        newobj._check()
        return newobj

    def __iadd__(self, other):
        self.value += NumericParamValue.unwrap(other)
        self._check()
        return self

    def __isub__(self, other):
        self.value -= NumericParamValue.unwrap(other)
        self._check()
        return self

    def __imul__(self, other):
        self.value *= NumericParamValue.unwrap(other)
        self._check()
        return self

    def __itruediv__(self, other):
        self.value /= NumericParamValue.unwrap(other)
        self._check()
        return self

    def __ifloordiv__(self, other):
        self.value //= NumericParamValue.unwrap(other)
        self._check()
        return self

    def __lt__(self, other):
        return self.value < NumericParamValue.unwrap(other)

    def config_value(self):
        return self.value

    @classmethod
    def cxx_ini_predecls(cls, code):
        # Assume that base/str.hh will be included anyway
        # code('#include "base/str.hh"')
        pass

    # The default for parsing PODs from an .ini entry is to extract from an
    # istringstream and let overloading choose the right type according to
    # the dest type.
    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code("%s to_number(%s, %s);" % (ret, src, dest))


# Metaclass for bounds-checked integer parameters.  See CheckedInt.
class CheckedIntType(MetaParamValue):
    def __init__(cls, name, bases, dict):
        super().__init__(name, bases, dict)

        # CheckedInt is an abstract base class, so we actually don't
        # want to do any processing on it... the rest of this code is
        # just for classes that derive from CheckedInt.
        if name == "CheckedInt":
            return

        if not (hasattr(cls, "min") and hasattr(cls, "max")):
            if not (hasattr(cls, "size") and hasattr(cls, "unsigned")):
                panic(
                    "CheckedInt subclass %s must define either\n"
                    "    'min' and 'max' or 'size' and 'unsigned'\n",
                    name,
                )
            if cls.unsigned:
                cls.min = 0
                cls.max = 2**cls.size - 1
            else:
                cls.min = -(2 ** (cls.size - 1))
                cls.max = (2 ** (cls.size - 1)) - 1


# Abstract superclass for bounds-checked integer parameters.  This
# class is subclassed to generate parameter classes with specific
# bounds.  Initialization of the min and max bounds is done in the
# metaclass CheckedIntType.__init__.
class CheckedInt(NumericParamValue, metaclass=CheckedIntType):
    cmd_line_settable = True

    def _check(self):
        if not self.min <= self.value <= self.max:
            raise TypeError(
                "Integer param out of bounds %d < %d < %d"
                % (self.min, self.value, self.max)
            )

    def __init__(self, value):
        if isinstance(value, str):
            self.value = convert.toInteger(value)
        elif isinstance(value, (int, float, NumericParamValue)):
            self.value = int(value)
        else:
            raise TypeError(
                "Can't convert object of type %s to CheckedInt"
                % type(value).__name__
            )
        self._check()

    def __call__(self, value):
        self.__init__(value)
        return value

    def __index__(self):
        return int(self.value)

    @classmethod
    def cxx_predecls(cls, code):
        # most derived types require this, so we just do it here once
        code('#include "base/types.hh"')

    def getValue(self):
        return int(self.value)


class Int(CheckedInt):
    cxx_type = "int"
    size = 32
    unsigned = False


class Unsigned(CheckedInt):
    cxx_type = "unsigned"
    size = 32
    unsigned = True


class Int8(CheckedInt):
    cxx_type = "int8_t"
    size = 8
    unsigned = False


class UInt8(CheckedInt):
    cxx_type = "uint8_t"
    size = 8
    unsigned = True


class Int16(CheckedInt):
    cxx_type = "int16_t"
    size = 16
    unsigned = False


class UInt16(CheckedInt):
    cxx_type = "uint16_t"
    size = 16
    unsigned = True


class Int32(CheckedInt):
    cxx_type = "int32_t"
    size = 32
    unsigned = False


class UInt32(CheckedInt):
    cxx_type = "uint32_t"
    size = 32
    unsigned = True


class Int64(CheckedInt):
    cxx_type = "int64_t"
    size = 64
    unsigned = False


class UInt64(CheckedInt):
    cxx_type = "uint64_t"
    size = 64
    unsigned = True


class Counter(CheckedInt):
    cxx_type = "Counter"
    size = 64
    unsigned = True


class Tick(CheckedInt):
    cxx_type = "Tick"
    size = 64
    unsigned = True


class TcpPort(CheckedInt):
    cxx_type = "uint16_t"
    size = 16
    unsigned = True


class UdpPort(CheckedInt):
    cxx_type = "uint16_t"
    size = 16
    unsigned = True


class Percent(CheckedInt):
    cxx_type = "int"
    min = 0
    max = 100


class Cycles(CheckedInt):
    cxx_type = "Cycles"
    size = 64
    unsigned = True

    def getValue(self):
        from _m5.core import Cycles

        return Cycles(self.value)

    @classmethod
    def cxx_ini_predecls(cls, code):
        # Assume that base/str.hh will be included anyway
        # code('#include "base/str.hh"')
        pass

    @classmethod
    def cxx_ini_parse(cls, code, src, dest, ret):
        code("uint64_t _temp;")
        code("bool _ret = to_number(%s, _temp);" % src)
        code("if (_ret)")
        code("    %s = Cycles(_temp);" % dest)
        code("%s _ret;" % ret)


class Float(ParamValue, float):
    cxx_type = "double"
    cmd_line_settable = True

    def __init__(self, value):
        if isinstance(value, (int, float, NumericParamValue, Float, str)):
            self.value = float(value)
        else:
            raise TypeError(
                "Can't convert object of type %s to Float"
                % type(value).__name__
            )

    def __call__(self, value):
        self.__init__(value)
        return value

    def getValue(self):
        return float(self.value)

    def config_value(self):
        return self

    @classmethod
    def cxx_ini_predecls(cls, code):
        code("#include <sstream>")

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code("%s (std::istringstream(%s) >> %s).eof();" % (ret, src, dest))


class MemorySize(CheckedInt):
    cxx_type = "uint64_t"
    ex_str = "512MiB"
    size = 64
    unsigned = True

    def __init__(self, value):
        if isinstance(value, MemorySize):
            self.value = value.value
        else:
            self.value = convert.toMemorySize(value)
        self._check()


class MemorySize32(CheckedInt):
    cxx_type = "uint32_t"
    ex_str = "512MiB"
    size = 32
    unsigned = True

    def __init__(self, value):
        if isinstance(value, MemorySize):
            self.value = value.value
        else:
            self.value = convert.toMemorySize(value)
        self._check()


class Addr(CheckedInt):
    cxx_type = "Addr"
    size = 64
    unsigned = True

    def __init__(self, value):
        if isinstance(value, Addr):
            self.value = value.value
        else:
            try:
                # Often addresses are referred to with sizes. Ex: A device
                # base address is at "512MiB".  Use toMemorySize() to convert
                # these into addresses. If the address is not specified with a
                # "size", an exception will occur and numeric translation will
                # proceed below.
                self.value = convert.toMemorySize(value)
            except (TypeError, ValueError):
                # Convert number to string and use long() to do automatic
                # base conversion (requires base=0 for auto-conversion)
                self.value = int(str(value), base=0)

        self._check()

    def __add__(self, other):
        if isinstance(other, Addr):
            return self.value + other.value
        else:
            return self.value + other

    def pretty_print(self, value):
        try:
            val = convert.toMemorySize(value)
        except TypeError:
            val = int(value)
        return "0x%x" % int(val)


class AddrRange(ParamValue):
    cxx_type = "AddrRange"

    def __init__(self, *args, **kwargs):
        # Disable interleaving and hashing by default
        self.intlvBits = 0
        self.intlvMatch = 0
        self.masks = []

        def handle_kwargs(self, kwargs):
            # An address range needs to have an upper limit, specified
            # either explicitly with an end, or as an offset using the
            # size keyword.
            if "end" in kwargs:
                self.end = Addr(kwargs.pop("end"))
            elif "size" in kwargs:
                self.end = self.start + Addr(kwargs.pop("size"))
            else:
                raise TypeError("Either end or size must be specified")

            # Now on to the optional bit
            if "intlvMatch" in kwargs:
                self.intlvMatch = int(kwargs.pop("intlvMatch"))

            if "masks" in kwargs:
                self.masks = [int(x) for x in list(kwargs.pop("masks"))]
                self.intlvBits = len(self.masks)
            else:
                if "intlvBits" in kwargs:
                    self.intlvBits = int(kwargs.pop("intlvBits"))
                    self.masks = [0] * self.intlvBits
                    if "intlvHighBit" not in kwargs:
                        raise TypeError("No interleave bits specified")
                    intlv_high_bit = int(kwargs.pop("intlvHighBit"))
                    xor_high_bit = 0
                    if "xorHighBit" in kwargs:
                        xor_high_bit = int(kwargs.pop("xorHighBit"))
                    for i in range(0, self.intlvBits):
                        bit1 = intlv_high_bit - i
                        mask = 1 << bit1
                        if xor_high_bit != 0:
                            bit2 = xor_high_bit - i
                            mask |= 1 << bit2
                        self.masks[self.intlvBits - i - 1] = mask

        if len(args) == 0:
            self.start = Addr(kwargs.pop("start"))
            handle_kwargs(self, kwargs)

        elif len(args) == 1:
            if kwargs:
                self.start = Addr(args[0])
                handle_kwargs(self, kwargs)
            elif isinstance(args[0], (list, tuple)):
                self.start = Addr(args[0][0])
                self.end = Addr(args[0][1])
            else:
                self.start = Addr(0)
                self.end = Addr(args[0])

        elif len(args) == 2:
            self.start = Addr(args[0])
            self.end = Addr(args[1])
        else:
            raise TypeError("Too many arguments specified")

        if kwargs:
            raise TypeError("Too many keywords: %s" % list(kwargs.keys()))

    def __str__(self):
        if len(self.masks) == 0:
            return "%s:%s" % (self.start, self.end)
        else:
            return "%s:%s:%s:%s" % (
                self.start,
                self.end,
                self.intlvMatch,
                ":".join(str(m) for m in self.masks),
            )

    def size(self):
        # Divide the size by the size of the interleaving slice
        return (int(self.end) - int(self.start)) >> self.intlvBits

    @classmethod
    def cxx_predecls(cls, code):
        Addr.cxx_predecls(code)
        code('#include "base/addr_range.hh"')

    @classmethod
    def pybind_predecls(cls, code):
        Addr.pybind_predecls(code)
        code('#include "base/addr_range.hh"')

    @classmethod
    def cxx_ini_predecls(cls, code):
        code("#include <sstream>")
        code("#include <vector>")
        code('#include "base/types.hh"')

    @classmethod
    def cxx_ini_parse(cls, code, src, dest, ret):
        code("bool _ret = true;")
        code("uint64_t _start, _end, _intlvMatch = 0;")
        code("std::vector<Addr> _masks;")
        code("char _sep;")
        code("std::istringstream _stream(${src});")
        code("_stream >> _start;")
        code("_stream.get(_sep);")
        code("_ret = _sep == ':';")
        code("_stream >> _end;")
        code("if (!_stream.fail() && !_stream.eof()) {")
        code("    _stream.get(_sep);")
        code("    _ret = ret && _sep == ':';")
        code("    _stream >> _intlvMatch;")
        code("    while (!_stream.fail() && !_stream.eof()) {")
        code("        _stream.get(_sep);")
        code("        _ret = ret && _sep == ':';")
        code("        Addr mask;")
        code("        _stream >> mask;")
        code("        _masks.push_back(mask);")
        code("    }")
        code("}")
        code("_ret = _ret && !_stream.fail() && _stream.eof();")
        code("if (_ret)")
        code("   ${dest} = AddrRange(_start, _end, _masks, _intlvMatch);")
        code("${ret} _ret;")

    def getValue(self):
        # Go from the Python class to the wrapped C++ class
        from _m5.range import AddrRange

        return AddrRange(
            int(self.start), int(self.end), self.masks, int(self.intlvMatch)
        )

    def exclude(self, ranges):
        pybind_exclude = list([r.getValue() for r in ranges])
        pybind_include = self.getValue().exclude(pybind_exclude)

        return list([AddrRange(r.start(), r.end()) for r in pybind_include])


# Boolean parameter type.  Python doesn't let you subclass bool, since
# it doesn't want to let you create multiple instances of True and
# False.  Thus this is a little more complicated than String.
class Bool(ParamValue):
    cxx_type = "bool"
    cmd_line_settable = True

    def __init__(self, value):
        try:
            self.value = convert.toBool(value)
        except TypeError:
            self.value = bool(value)

    def __call__(self, value):
        self.__init__(value)
        return value

    def getValue(self):
        return bool(self.value)

    def __str__(self):
        return str(self.value)

    # implement truth value testing for Bool parameters so that these params
    # evaluate correctly during the python configuration phase
    def __bool__(self):
        return bool(self.value)

    # Python 2.7 uses __nonzero__ instead of __bool__
    __nonzero__ = __bool__

    def ini_str(self):
        if self.value:
            return "true"
        return "false"

    def config_value(self):
        return self.value

    @classmethod
    def cxx_ini_predecls(cls, code):
        # Assume that base/str.hh will be included anyway
        # code('#include "base/str.hh"')
        pass

    @classmethod
    def cxx_ini_parse(cls, code, src, dest, ret):
        code("%s to_bool(%s, %s);" % (ret, src, dest))


def IncEthernetAddr(addr, val=1):
    bytes = [int(x, 16) for x in addr.split(":")]
    bytes[5] += val
    for i in (5, 4, 3, 2, 1):
        val, rem = divmod(bytes[i], 256)
        bytes[i] = rem
        if val == 0:
            break
        bytes[i - 1] += val
    assert bytes[0] <= 255
    return ":".join(map(lambda x: "%02x" % x, bytes))


_NextEthernetAddr = "00:90:00:00:00:01"


def NextEthernetAddr():
    global _NextEthernetAddr

    value = _NextEthernetAddr
    _NextEthernetAddr = IncEthernetAddr(_NextEthernetAddr, 1)
    return value


class EthernetAddr(ParamValue):
    cxx_type = "networking::EthAddr"
    ex_str = "00:90:00:00:00:01"
    cmd_line_settable = True

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "base/inet.hh"')

    def __init__(self, value):
        if value == NextEthernetAddr:
            self.value = value
            return

        if not isinstance(value, str):
            raise TypeError("expected an ethernet address and didn't get one")

        bytes = value.split(":")
        if len(bytes) != 6:
            raise TypeError("invalid ethernet address %s" % value)

        for byte in bytes:
            if not 0 <= int(byte, base=16) <= 0xFF:
                raise TypeError("invalid ethernet address %s" % value)

        self.value = value

    def __call__(self, value):
        self.__init__(value)
        return value

    def unproxy(self, base):
        if self.value == NextEthernetAddr:
            return EthernetAddr(self.value())
        return self

    def getValue(self):
        from _m5.net import EthAddr

        return EthAddr(self.value)

    def __str__(self):
        return self.value

    def ini_str(self):
        return self.value

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code("%s = networking::EthAddr(%s);" % (dest, src))
        code("%s true;" % ret)


# When initializing an IpAddress, pass in an existing IpAddress, a string of
# the form "a.b.c.d", or an integer representing an IP.
class IpAddress(ParamValue):
    cxx_type = "networking::IpAddress"
    ex_str = "127.0.0.1"
    cmd_line_settable = True

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "base/inet.hh"')

    def __init__(self, value):
        if isinstance(value, IpAddress):
            self.ip = value.ip
        else:
            try:
                self.ip = convert.toIpAddress(value)
            except TypeError:
                self.ip = int(value)
        self.verifyIp()

    def __call__(self, value):
        self.__init__(value)
        return value

    def __str__(self):
        tup = [(self.ip >> i) & 0xFF for i in (24, 16, 8, 0)]
        return "%d.%d.%d.%d" % tuple(tup)

    def __eq__(self, other):
        if isinstance(other, IpAddress):
            return self.ip == other.ip
        elif isinstance(other, str):
            try:
                return self.ip == convert.toIpAddress(other)
            except:
                return False
        else:
            return self.ip == other

    def __ne__(self, other):
        return not (self == other)

    def verifyIp(self):
        if self.ip < 0 or self.ip >= (1 << 32):
            raise TypeError("invalid ip address %#08x" % self.ip)

    def getValue(self):
        from _m5.net import IpAddress

        return IpAddress(self.ip)


# When initializing an IpNetmask, pass in an existing IpNetmask, a string of
# the form "a.b.c.d/n" or "a.b.c.d/e.f.g.h", or an ip and netmask as
# positional or keyword arguments.
class IpNetmask(IpAddress):
    cxx_type = "networking::IpNetmask"
    ex_str = "127.0.0.0/24"
    cmd_line_settable = True

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "base/inet.hh"')

    def __init__(self, *args, **kwargs):
        def handle_kwarg(self, kwargs, key, elseVal=None):
            if key in kwargs:
                setattr(self, key, kwargs.pop(key))
            elif elseVal:
                setattr(self, key, elseVal)
            else:
                raise TypeError("No value set for %s" % key)

        if len(args) == 0:
            handle_kwarg(self, kwargs, "ip")
            handle_kwarg(self, kwargs, "netmask")

        elif len(args) == 1:
            if kwargs:
                if not "ip" in kwargs and not "netmask" in kwargs:
                    raise TypeError("Invalid arguments")
                handle_kwarg(self, kwargs, "ip", args[0])
                handle_kwarg(self, kwargs, "netmask", args[0])
            elif isinstance(args[0], IpNetmask):
                self.ip = args[0].ip
                self.netmask = args[0].netmask
            else:
                (self.ip, self.netmask) = convert.toIpNetmask(args[0])

        elif len(args) == 2:
            self.ip = args[0]
            self.netmask = args[1]
        else:
            raise TypeError("Too many arguments specified")

        if kwargs:
            raise TypeError("Too many keywords: %s" % list(kwargs.keys()))

        self.verify()

    def __call__(self, value):
        self.__init__(value)
        return value

    def __str__(self):
        return "%s/%d" % (super().__str__(), self.netmask)

    def __eq__(self, other):
        if isinstance(other, IpNetmask):
            return self.ip == other.ip and self.netmask == other.netmask
        elif isinstance(other, str):
            try:
                return (self.ip, self.netmask) == convert.toIpNetmask(other)
            except:
                return False
        else:
            return False

    def verify(self):
        self.verifyIp()
        if self.netmask < 0 or self.netmask > 32:
            raise TypeError("invalid netmask %d" % netmask)

    def getValue(self):
        from _m5.net import IpNetmask

        return IpNetmask(self.ip, self.netmask)


# When initializing an IpWithPort, pass in an existing IpWithPort, a string of
# the form "a.b.c.d:p", or an ip and port as positional or keyword arguments.
class IpWithPort(IpAddress):
    cxx_type = "networking::IpWithPort"
    ex_str = "127.0.0.1:80"
    cmd_line_settable = True

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "base/inet.hh"')

    def __init__(self, *args, **kwargs):
        def handle_kwarg(self, kwargs, key, elseVal=None):
            if key in kwargs:
                setattr(self, key, kwargs.pop(key))
            elif elseVal:
                setattr(self, key, elseVal)
            else:
                raise TypeError("No value set for %s" % key)

        if len(args) == 0:
            handle_kwarg(self, kwargs, "ip")
            handle_kwarg(self, kwargs, "port")

        elif len(args) == 1:
            if kwargs:
                if not "ip" in kwargs and not "port" in kwargs:
                    raise TypeError("Invalid arguments")
                handle_kwarg(self, kwargs, "ip", args[0])
                handle_kwarg(self, kwargs, "port", args[0])
            elif isinstance(args[0], IpWithPort):
                self.ip = args[0].ip
                self.port = args[0].port
            else:
                (self.ip, self.port) = convert.toIpWithPort(args[0])

        elif len(args) == 2:
            self.ip = args[0]
            self.port = args[1]
        else:
            raise TypeError("Too many arguments specified")

        if kwargs:
            raise TypeError("Too many keywords: %s" % list(kwargs.keys()))

        self.verify()

    def __call__(self, value):
        self.__init__(value)
        return value

    def __str__(self):
        return "%s:%d" % (super().__str__(), self.port)

    def __eq__(self, other):
        if isinstance(other, IpWithPort):
            return self.ip == other.ip and self.port == other.port
        elif isinstance(other, str):
            try:
                return (self.ip, self.port) == convert.toIpWithPort(other)
            except:
                return False
        else:
            return False

    def verify(self):
        self.verifyIp()
        if self.port < 0 or self.port > 0xFFFF:
            raise TypeError("invalid port %d" % self.port)

    def getValue(self):
        from _m5.net import IpWithPort

        return IpWithPort(self.ip, self.port)


time_formats = [
    "%a %b %d %H:%M:%S %Z %Y",
    "%a %b %d %H:%M:%S %Y",
    "%Y/%m/%d %H:%M:%S",
    "%Y/%m/%d %H:%M",
    "%Y/%m/%d",
    "%m/%d/%Y %H:%M:%S",
    "%m/%d/%Y %H:%M",
    "%m/%d/%Y",
    "%m/%d/%y %H:%M:%S",
    "%m/%d/%y %H:%M",
    "%m/%d/%y",
]


def parse_time(value):
    from time import gmtime, strptime, struct_time, time
    from datetime import datetime, date

    if isinstance(value, struct_time):
        return value

    if isinstance(value, int):
        return gmtime(value)

    if isinstance(value, (datetime, date)):
        return value.timetuple()

    if isinstance(value, str):
        if value in ("Now", "Today"):
            return time.gmtime(time.time())

        for format in time_formats:
            try:
                return strptime(value, format)
            except ValueError:
                pass

    raise ValueError("Could not parse '%s' as a time" % value)


class Time(ParamValue):
    cxx_type = "tm"

    @classmethod
    def cxx_predecls(cls, code):
        code("#include <time.h>")

    def __init__(self, value):
        self.value = parse_time(value)

    def __call__(self, value):
        self.__init__(value)
        return value

    def getValue(self):
        from _m5.core import tm
        import calendar

        return tm.gmtime(calendar.timegm(self.value))

    def __str__(self):
        return time.asctime(self.value)

    def ini_str(self):
        return str(self)

    def get_config_as_dict(self):
        assert false
        return str(self)

    @classmethod
    def cxx_ini_predecls(cls, code):
        code("#include <time.h>")

    @classmethod
    def cxx_ini_parse(cls, code, src, dest, ret):
        code("char *_parse_ret = strptime((${src}).c_str(),")
        code('    "%a %b %d %H:%M:%S %Y", &(${dest}));')
        code("${ret} _parse_ret && *_parse_ret == '\\0';")


# Enumerated types are a little more complex.  The user specifies the
# type as Enum(foo) where foo is either a list or dictionary of
# alternatives (typically strings, but not necessarily so).  (In the
# long run, the integer value of the parameter will be the list index
# or the corresponding dictionary value.  For now, since we only check
# that the alternative is valid and then spit it into a .ini file,
# there's not much point in using the dictionary.)

# What Enum() must do is generate a new type encapsulating the
# provided list/dictionary so that specific values of the parameter
# can be instances of that type.  We define two hidden internal
# classes (_ListEnum and _DictEnum) to serve as base classes, then
# derive the new type from the appropriate base class on the fly.

allEnums = {}
# Metaclass for Enum types
class MetaEnum(MetaParamValue):
    def __new__(mcls, name, bases, dict):

        cls = super().__new__(mcls, name, bases, dict)
        allEnums[name] = cls
        return cls

    def __init__(cls, name, bases, init_dict):
        if "map" in init_dict:
            if not isinstance(cls.map, dict):
                raise TypeError(
                    "Enum-derived class attribute 'map' "
                    "must be of type dict"
                )
            # build list of value strings from map
            cls.vals = list(cls.map.keys())
            cls.vals.sort()
        elif "vals" in init_dict:
            if not isinstance(cls.vals, list):
                raise TypeError(
                    "Enum-derived class attribute 'vals' "
                    "must be of type list"
                )
            # build string->value map from vals sequence
            cls.map = {}
            for idx, val in enumerate(cls.vals):
                cls.map[val] = idx
        else:
            raise TypeError(
                "Enum-derived class must define " "attribute 'map' or 'vals'"
            )

        if cls.is_class:
            cls.cxx_type = "%s" % name
        else:
            cls.cxx_type = "enums::%s" % name

        super().__init__(name, bases, init_dict)


# Base class for enum types.
class Enum(ParamValue, metaclass=MetaEnum):
    vals = []
    cmd_line_settable = True

    # The name of the wrapping namespace or struct
    wrapper_name = "enums"

    # If true, the enum is wrapped in a struct rather than a namespace
    wrapper_is_struct = False

    is_class = False

    # If not None, use this as the enum name rather than this class name
    enum_name = None

    def __init__(self, value):
        if value not in self.map:
            raise TypeError(
                "Enum param got bad value '%s' (not in %s)"
                % (value, self.vals)
            )
        self.value = value

    def __call__(self, value):
        self.__init__(value)
        return value

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "enums/$0.hh"', cls.__name__)

    @classmethod
    def cxx_ini_parse(cls, code, src, dest, ret):
        code("if (false) {")
        for elem_name in cls.map.keys():
            code('} else if (%s == "%s") {' % (src, elem_name))
            code.indent()
            name = cls.__name__ if cls.enum_name is None else cls.enum_name
            code(
                "%s = %s::%s;"
                % (dest, name if cls.is_class else "enums", elem_name)
            )
            code("%s true;" % ret)
            code.dedent()
        code("} else {")
        code("    %s false;" % ret)
        code("}")

    def getValue(self):
        import m5.internal.params

        e = getattr(m5.internal.params, "enum_%s" % self.__class__.__name__)
        return e(self.map[self.value])

    def __str__(self):
        return self.value


# This param will generate a scoped c++ enum and its python bindings.
class ScopedEnum(Enum):
    vals = []
    cmd_line_settable = True

    # The name of the wrapping namespace or struct
    wrapper_name = None

    # If true, the enum is wrapped in a struct rather than a namespace
    wrapper_is_struct = False

    # If true, the generated enum is a scoped enum
    is_class = True

    # If not None, use this as the enum name rather than this class name
    enum_name = None


class ByteOrder(ScopedEnum):
    """Enum representing component's byte order (endianness)"""

    vals = ["big", "little"]


# how big does a rounding error need to be before we warn about it?
frequency_tolerance = 0.001  # 0.1%


class TickParamValue(NumericParamValue):
    cxx_type = "Tick"
    ex_str = "1MHz"
    cmd_line_settable = True

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "base/types.hh"')

    def __call__(self, value):
        self.__init__(value)
        return value

    def getValue(self):
        return int(self.value)

    @classmethod
    def cxx_ini_predecls(cls, code):
        code("#include <sstream>")

    # Ticks are expressed in seconds in JSON files and in plain
    # Ticks in .ini files.  Switch based on a config flag
    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code("${ret} to_number(${src}, ${dest});")


class Latency(TickParamValue):
    ex_str = "100ns"

    def __init__(self, value):
        if isinstance(value, (Latency, Clock)):
            self.ticks = value.ticks
            self.value = value.value
        elif isinstance(value, Frequency):
            self.ticks = value.ticks
            self.value = 1.0 / value.value
        elif value.endswith("t"):
            self.ticks = True
            self.value = int(value[:-1])
        else:
            self.ticks = False
            self.value = convert.toLatency(value)

    def __call__(self, value):
        self.__init__(value)
        return value

    def __getattr__(self, attr):
        if attr in ("latency", "period"):
            return self
        if attr == "frequency":
            return Frequency(self)
        raise AttributeError("Latency object has no attribute '%s'" % attr)

    def getValue(self):
        if self.ticks or self.value == 0:
            value = self.value
        else:
            value = ticks.fromSeconds(self.value)
        return int(value)

    def config_value(self):
        return self.getValue()

    # convert latency to ticks
    def ini_str(self):
        return "%d" % self.getValue()


class Frequency(TickParamValue):
    ex_str = "1GHz"

    def __init__(self, value):
        if isinstance(value, (Latency, Clock)):
            if value.value == 0:
                self.value = 0
            else:
                self.value = 1.0 / value.value
            self.ticks = value.ticks
        elif isinstance(value, Frequency):
            self.value = value.value
            self.ticks = value.ticks
        else:
            self.ticks = False
            self.value = convert.toFrequency(value)

    def __call__(self, value):
        self.__init__(value)
        return value

    def __getattr__(self, attr):
        if attr == "frequency":
            return self
        if attr in ("latency", "period"):
            return Latency(self)
        raise AttributeError("Frequency object has no attribute '%s'" % attr)

    # convert latency to ticks
    def getValue(self):
        if self.ticks or self.value == 0:
            value = self.value
        else:
            value = ticks.fromSeconds(1.0 / self.value)
        return int(value)

    def config_value(self):
        return self.getValue()

    def ini_str(self):
        return "%d" % self.getValue()


# A generic Frequency and/or Latency value. Value is stored as a
# latency, just like Latency and Frequency.
class Clock(TickParamValue):
    def __init__(self, value):
        if isinstance(value, (Latency, Clock)):
            self.ticks = value.ticks
            self.value = value.value
        elif isinstance(value, Frequency):
            self.ticks = value.ticks
            self.value = 1.0 / value.value
        elif value.endswith("t"):
            self.ticks = True
            self.value = int(value[:-1])
        else:
            self.ticks = False
            self.value = convert.anyToLatency(value)

    def __call__(self, value):
        self.__init__(value)
        return value

    def __str__(self):
        return "%s" % Latency(self)

    def __getattr__(self, attr):
        if attr == "frequency":
            return Frequency(self)
        if attr in ("latency", "period"):
            return Latency(self)
        raise AttributeError("Frequency object has no attribute '%s'" % attr)

    def getValue(self):
        return self.period.getValue()

    def config_value(self):
        return self.period.config_value()

    def ini_str(self):
        return self.period.ini_str()


class Voltage(Float):
    ex_str = "1V"

    def __new__(cls, value):
        value = convert.toVoltage(value)
        return super().__new__(cls, value)

    def __init__(self, value):
        value = convert.toVoltage(value)
        super().__init__(value)


class Current(Float):
    ex_str = "1mA"

    def __new__(cls, value):
        value = convert.toCurrent(value)
        return super().__new__(cls, value)

    def __init__(self, value):
        value = convert.toCurrent(value)
        super().__init__(value)


class Energy(Float):
    ex_str = "1pJ"

    def __new__(cls, value):
        value = convert.toEnergy(value)
        return super().__new__(cls, value)

    def __init__(self, value):
        value = convert.toEnergy(value)
        super().__init__(value)


class Temperature(ParamValue):
    cxx_type = "Temperature"
    cmd_line_settable = True
    ex_str = "1C"

    def __init__(self, value):
        self.value = convert.toTemperature(value)

    def __call__(self, value):
        self.__init__(value)
        return value

    def __str__(self):
        return str(self.value)

    def getValue(self):
        from _m5.core import Temperature

        return Temperature.from_kelvin(self.value)

    def config_value(self):
        return self.value

    @classmethod
    def cxx_predecls(cls, code):
        code('#include "base/temperature.hh"')

    @classmethod
    def cxx_ini_predecls(cls, code):
        # Assume that base/str.hh will be included anyway
        # code('#include "base/str.hh"')
        pass

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code("double _temp;")
        code("bool _ret = to_number(%s, _temp);" % src)
        code("if (_ret)")
        code("    %s = Temperature(_temp);" % dest)
        code("%s _ret;" % ret)


class NetworkBandwidth(float, ParamValue):
    cxx_type = "float"
    ex_str = "1Gbps"
    cmd_line_settable = True

    def __new__(cls, value):
        # convert to bits per second
        val = convert.toNetworkBandwidth(value)
        return super().__new__(cls, val)

    def __str__(self):
        return str(self.val)

    def __call__(self, value):
        val = convert.toNetworkBandwidth(value)
        self.__init__(val)
        return value

    def getValue(self):
        # convert to seconds per byte
        value = 8.0 / float(self)
        # convert to ticks per byte
        value = ticks.fromSeconds(value)
        return float(value)

    def ini_str(self):
        return "%f" % self.getValue()

    def config_value(self):
        return "%f" % self.getValue()

    @classmethod
    def cxx_ini_predecls(cls, code):
        code("#include <sstream>")

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code("%s (std::istringstream(%s) >> %s).eof();" % (ret, src, dest))


class MemoryBandwidth(float, ParamValue):
    cxx_type = "float"
    ex_str = "1GiB/s"
    cmd_line_settable = True

    def __new__(cls, value):
        # convert to bytes per second
        val = convert.toMemoryBandwidth(value)
        return super().__new__(cls, val)

    def __call__(self, value):
        val = convert.toMemoryBandwidth(value)
        self.__init__(val)
        return value

    def getValue(self):
        # convert to seconds per byte
        value = float(self)
        if value:
            value = 1.0 / float(self)
        # convert to ticks per byte
        value = ticks.fromSeconds(value)
        return float(value)

    def ini_str(self):
        return "%f" % self.getValue()

    def config_value(self):
        return "%f" % self.getValue()

    @classmethod
    def cxx_ini_predecls(cls, code):
        code("#include <sstream>")

    @classmethod
    def cxx_ini_parse(self, code, src, dest, ret):
        code("%s (std::istringstream(%s) >> %s).eof();" % (ret, src, dest))


#
# "Constants"... handy aliases for various values.
#

# Special class for NULL pointers.  Note the special check in
# make_param_value() above that lets these be assigned where a
# SimObject is required.
# only one copy of a particular node
class NullSimObject(object, metaclass=Singleton):
    _name = "Null"

    def __call__(cls):
        return cls

    def _instantiate(self, parent=None, path=""):
        pass

    def ini_str(self):
        return "Null"

    def unproxy(self, base):
        return self

    def set_path(self, parent, name):
        pass

    def set_parent(self, parent, name):
        pass

    def clear_parent(self, old_parent):
        pass

    def descendants(self):
        return
        yield None

    def get_config_as_dict(self):
        return {}

    def __str__(self):
        return self._name

    def config_value(self):
        return None

    def getValue(self):
        return None


# The only instance you'll ever need...
NULL = NullSimObject()


def isNullPointer(value):
    return isinstance(value, NullSimObject)


# Some memory range specifications use this as a default upper bound.
MaxAddr = Addr.max
MaxTick = Tick.max
AllMemory = AddrRange(0, MaxAddr)


#####################################################################
#
# Port objects
#
# Ports are used to interconnect objects in the memory system.
#
#####################################################################

# Port reference: encapsulates a reference to a particular port on a
# particular SimObject.
class PortRef(object):
    def __init__(self, simobj, name, role, is_source):
        assert isSimObject(simobj) or isSimObjectClass(simobj)
        self.simobj = simobj
        self.name = name
        self.role = role
        self.is_source = is_source
        self.peer = None  # not associated with another port yet
        self.ccConnected = False  # C++ port connection done?
        self.index = -1  # always -1 for non-vector ports

    def __str__(self):
        return "%s.%s" % (self.simobj, self.name)

    def __len__(self):
        # Return the number of connected ports, i.e. 0 is we have no
        # peer and 1 if we do.
        return int(self.peer != None)

    # for config.ini, print peer's name (not ours)
    def ini_str(self):
        return str(self.peer)

    # for config.json
    def get_config_as_dict(self):
        return {
            "role": self.role,
            "peer": str(self.peer),
            "is_source": str(self.is_source),
        }

    def __getattr__(self, attr):
        if attr == "peerObj":
            # shorthand for proxies
            return self.peer.simobj
        raise AttributeError(
            "'%s' object has no attribute '%s'"
            % (self.__class__.__name__, attr)
        )

    # Full connection is symmetric (both ways).  Called via
    # SimObject.__setattr__ as a result of a port assignment, e.g.,
    # "obj1.portA = obj2.portB", or via VectorPortElementRef.__setitem__,
    # e.g., "obj1.portA[3] = obj2.portB".
    def connect(self, other):
        if isinstance(other, VectorPortRef):
            # reference to plain VectorPort is implicit append
            other = other._get_next()
        if self.peer and not proxy.isproxy(self.peer):
            fatal(
                "Port %s is already connected to %s, cannot connect %s\n",
                self,
                self.peer,
                other,
            )
        self.peer = other

        if proxy.isproxy(other):
            other.set_param_desc(PortParamDesc())
            return
        elif not isinstance(other, PortRef):
            raise TypeError(
                "assigning non-port reference '%s' to port '%s'"
                % (other, self)
            )

        if not Port.is_compat(self, other):
            fatal(
                "Ports %s and %s with roles '%s' and '%s' "
                "are not compatible",
                self,
                other,
                self.role,
                other.role,
            )

        if other.peer is not self:
            other.connect(self)

    # Allow a compatible port pair to be spliced between a port and its
    # connected peer. Useful operation for connecting instrumentation
    # structures into a system when it is necessary to connect the
    # instrumentation after the full system has been constructed.
    def splice(self, new_1, new_2):
        if not self.peer or proxy.isproxy(self.peer):
            fatal("Port %s not connected, cannot splice in new peers\n", self)

        if not isinstance(new_1, PortRef) or not isinstance(new_2, PortRef):
            raise TypeError(
                "Splicing non-port references '%s','%s' to port '%s'"
                % (new_1, new_2, self)
            )

        old_peer = self.peer

        if Port.is_compat(old_peer, new_1) and Port.is_compat(self, new_2):
            old_peer.peer = new_1
            new_1.peer = old_peer
            self.peer = new_2
            new_2.peer = self
        elif Port.is_compat(old_peer, new_2) and Port.is_compat(self, new_1):
            old_peer.peer = new_2
            new_2.peer = old_peer
            self.peer = new_1
            new_1.peer = self
        else:
            fatal(
                "Ports %s(%s) and %s(%s) can't be compatibly spliced with "
                "%s(%s) and %s(%s)",
                self,
                self.role,
                old_peer,
                old_peer.role,
                new_1,
                new_1.role,
                new_2,
                new_2.role,
            )

    def clone(self, simobj, memo):
        if self in memo:
            return memo[self]
        newRef = copy.copy(self)
        memo[self] = newRef
        newRef.simobj = simobj
        assert isSimObject(newRef.simobj)
        if self.peer and not proxy.isproxy(self.peer):
            peerObj = self.peer.simobj(_memo=memo)
            newRef.peer = self.peer.clone(peerObj, memo)
            assert not isinstance(newRef.peer, VectorPortRef)
        return newRef

    def unproxy(self, simobj):
        assert simobj is self.simobj
        if proxy.isproxy(self.peer):
            try:
                realPeer = self.peer.unproxy(self.simobj)
            except:
                print(
                    "Error in unproxying port '%s' of %s"
                    % (self.name, self.simobj.path())
                )
                raise
            self.connect(realPeer)

    # Call C++ to create corresponding port connection between C++ objects
    def ccConnect(self):
        if self.ccConnected:  # already done this
            return

        peer = self.peer
        if not self.peer:  # nothing to connect to
            return

        port = self.simobj.getPort(self.name, self.index)
        peer_port = peer.simobj.getPort(peer.name, peer.index)
        port.bind(peer_port)

        self.ccConnected = True


# A reference to an individual element of a VectorPort... much like a
# PortRef, but has an index.
class VectorPortElementRef(PortRef):
    def __init__(self, simobj, name, role, is_source, index):
        PortRef.__init__(self, simobj, name, role, is_source)
        self.index = index

    def __str__(self):
        return "%s.%s[%d]" % (self.simobj, self.name, self.index)


# A reference to a complete vector-valued port (not just a single element).
# Can be indexed to retrieve individual VectorPortElementRef instances.
class VectorPortRef(object):
    def __init__(self, simobj, name, role, is_source):
        assert isSimObject(simobj) or isSimObjectClass(simobj)
        self.simobj = simobj
        self.name = name
        self.role = role
        self.is_source = is_source
        self.elements = []

    def __str__(self):
        return "%s.%s[:]" % (self.simobj, self.name)

    def __len__(self):
        # Return the number of connected peers, corresponding the the
        # length of the elements.
        return len(self.elements)

    # for config.ini, print peer's name (not ours)
    def ini_str(self):
        return " ".join([el.ini_str() for el in self.elements])

    # for config.json
    def get_config_as_dict(self):
        return {
            "role": self.role,
            "peer": [el.ini_str() for el in self.elements],
            "is_source": str(self.is_source),
        }

    def __getitem__(self, key):
        if not isinstance(key, int):
            raise TypeError("VectorPort index must be integer")
        if key >= len(self.elements):
            # need to extend list
            ext = [
                VectorPortElementRef(
                    self.simobj, self.name, self.role, self.is_source, i
                )
                for i in range(len(self.elements), key + 1)
            ]
            self.elements.extend(ext)
        return self.elements[key]

    def _get_next(self):
        return self[len(self.elements)]

    def __setitem__(self, key, value):
        if not isinstance(key, int):
            raise TypeError("VectorPort index must be integer")
        self[key].connect(value)

    def connect(self, other):
        if isinstance(other, (list, tuple)):
            # Assign list of port refs to vector port.
            # For now, append them... not sure if that's the right semantics
            # or if it should replace the current vector.
            for ref in other:
                self._get_next().connect(ref)
        else:
            # scalar assignment to plain VectorPort is implicit append
            self._get_next().connect(other)

    def clone(self, simobj, memo):
        if self in memo:
            return memo[self]
        newRef = copy.copy(self)
        memo[self] = newRef
        newRef.simobj = simobj
        assert isSimObject(newRef.simobj)
        newRef.elements = [el.clone(simobj, memo) for el in self.elements]
        return newRef

    def unproxy(self, simobj):
        [el.unproxy(simobj) for el in self.elements]

    def ccConnect(self):
        [el.ccConnect() for el in self.elements]


# Port description object.  Like a ParamDesc object, this represents a
# logical port in the SimObject class, not a particular port on a
# SimObject instance.  The latter are represented by PortRef objects.
class Port(object):
    # Port("role", "description")

    _compat_dict = {}

    @classmethod
    def compat(cls, role, peer):
        cls._compat_dict.setdefault(role, set()).add(peer)
        cls._compat_dict.setdefault(peer, set()).add(role)

    @classmethod
    def is_compat(cls, one, two):
        for port in one, two:
            if not port.role in Port._compat_dict:
                fatal("Unrecognized role '%s' for port %s\n", port.role, port)
        return one.role in Port._compat_dict[two.role]

    def __init__(self, role, desc, is_source=False):
        self.desc = desc
        self.role = role
        self.is_source = is_source

    # Generate a PortRef for this port on the given SimObject with the
    # given name
    def makeRef(self, simobj):
        return PortRef(simobj, self.name, self.role, self.is_source)

    # Connect an instance of this port (on the given SimObject with
    # the given name) with the port described by the supplied PortRef
    def connect(self, simobj, ref):
        self.makeRef(simobj).connect(ref)

    # No need for any pre-declarations at the moment as we merely rely
    # on an unsigned int.
    def cxx_predecls(self, code):
        pass

    def pybind_predecls(self, code):
        cls.cxx_predecls(self, code)

    # Declare an unsigned int with the same name as the port, that
    # will eventually hold the number of connected ports (and thus the
    # number of elements for a VectorPort).
    def cxx_decl(self, code):
        code("unsigned int port_${{self.name}}_connection_count;")


Port.compat("GEM5 REQUESTOR", "GEM5 RESPONDER")


class RequestPort(Port):
    # RequestPort("description")
    def __init__(self, desc):
        super().__init__("GEM5 REQUESTOR", desc, is_source=True)


class ResponsePort(Port):
    # ResponsePort("description")
    def __init__(self, desc):
        super().__init__("GEM5 RESPONDER", desc)


# VectorPort description object.  Like Port, but represents a vector
# of connections (e.g., as on a XBar).
class VectorPort(Port):
    def makeRef(self, simobj):
        return VectorPortRef(simobj, self.name, self.role, self.is_source)


class VectorRequestPort(VectorPort):
    # VectorRequestPort("description")
    def __init__(self, desc):
        super().__init__("GEM5 REQUESTOR", desc, is_source=True)


class VectorResponsePort(VectorPort):
    # VectorResponsePort("description")
    def __init__(self, desc):
        super().__init__("GEM5 RESPONDER", desc)


# Old names, maintained for compatibility.
MasterPort = RequestPort
SlavePort = ResponsePort
VectorMasterPort = VectorRequestPort
VectorSlavePort = VectorResponsePort

# 'Fake' ParamDesc for Port references to assign to the _pdesc slot of
# proxy objects (via set_param_desc()) so that proxy error messages
# make sense.
class PortParamDesc(object, metaclass=Singleton):
    ptype_str = "Port"
    ptype = Port


class DeprecatedParam(object):
    """A special type for deprecated parameter variable names.

    There are times when we need to change the name of parameter, but this
    breaks the external-facing python API used in configuration files. Using
    this "type" for a parameter will warn users that they are using the old
    name, but allow for backwards compatibility.

    Usage example:
    In the following example, the `time` parameter is changed to `delay`.

    ```
    class SomeDevice(SimObject):
        delay = Param.Latency('1ns', 'The time to wait before something')
        time = DeprecatedParam(delay, '`time` is now called `delay`')
    ```
    """

    def __init__(self, new_param, message=""):
        """new_param: the new parameter variable that users should be using
        instead of this parameter variable.
        message: an optional message to print when warning the user
        """
        self.message = message
        self.newParam = new_param
        # Note: We won't know the string variable names until later in the
        # SimObject initialization process. Note: we expect that the setters
        # will be called when the SimObject type (class) is initialized so
        # these variables should be filled in before the instance of the
        # SimObject with this parameter is constructed
        self._oldName = ""
        self._newName = ""

    @property
    def oldName(self):
        assert self._oldName != ""  # should already be set
        return self._oldName

    @oldName.setter
    def oldName(self, name):
        assert self._oldName == ""  # Cannot "re-set" this value
        self._oldName = name

    @property
    def newName(self):
        assert self._newName != ""  # should already be set
        return self._newName

    @newName.setter
    def newName(self, name):
        assert self._newName == ""  # Cannot "re-set" this value
        self._newName = name

    def printWarning(self, instance_name, simobj_name):
        """Issue a warning that this variable name should not be used.

        instance_name: str, the name of the instance used in python
        simobj_name: str, the name of the SimObject type
        """
        if not self.message:
            self.message = "See {} for more information".format(simobj_name)
        warn(
            "{}.{} is deprecated. {}".format(
                instance_name, self._oldName, self.message
            )
        )


baseEnums = allEnums.copy()
baseParams = allParams.copy()


def clear():
    global allEnums, allParams

    allEnums = baseEnums.copy()
    allParams = baseParams.copy()


__all__ = [
    "Param",
    "VectorParam",
    "Enum",
    "ScopedEnum",
    "Bool",
    "String",
    "Float",
    "Int",
    "Unsigned",
    "Int8",
    "UInt8",
    "Int16",
    "UInt16",
    "Int32",
    "UInt32",
    "Int64",
    "UInt64",
    "Counter",
    "Addr",
    "Tick",
    "Percent",
    "TcpPort",
    "UdpPort",
    "EthernetAddr",
    "IpAddress",
    "IpNetmask",
    "IpWithPort",
    "MemorySize",
    "MemorySize32",
    "Latency",
    "Frequency",
    "Clock",
    "Voltage",
    "Current",
    "Energy",
    "Temperature",
    "NetworkBandwidth",
    "MemoryBandwidth",
    "AddrRange",
    "MaxAddr",
    "MaxTick",
    "AllMemory",
    "Time",
    "NextEthernetAddr",
    "NULL",
    "Port",
    "RequestPort",
    "ResponsePort",
    "MasterPort",
    "SlavePort",
    "VectorPort",
    "VectorRequestPort",
    "VectorResponsePort",
    "VectorMasterPort",
    "VectorSlavePort",
    "DeprecatedParam",
]
