Source code for microprobe.target.isa.instruction_field

# Copyright 2011-2021 IBM Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""":mod:`microprobe.target.isa.instruction_field` module

"""

# Futures
from __future__ import absolute_import, annotations

# Built-in modules
import abc
import os
from typing import TYPE_CHECKING, Dict, List, Tuple, cast

# Third party modules

# Own modules
from microprobe.exceptions import MicroprobeArchitectureDefinitionError
from microprobe.utils.logger import get_logger
from microprobe.utils.typeguard_decorator import typeguard_testsuite
from microprobe.utils.yaml import read_yaml

# Type hinting
if TYPE_CHECKING:
    from microprobe.target.isa.operand import Operand

# Constants
SCHEMA = os.path.join(os.path.dirname(os.path.abspath(__file__)), "schemas",
                      "instruction_field.yaml")

LOG = get_logger(__name__)
__all__ = ["import_definition", "InstructionField", "GenericInstructionField"]


# Functions
[docs] @typeguard_testsuite def import_definition(cls, filenames: List[str], operands: Dict[str, "Operand"]): """ :param filenames: :param operands: """ LOG.debug("Start") ifields = {} ifields_duplicated: Dict[Tuple[int, bool, str, str], str] = {} for filename in filenames: ifield_data = read_yaml(filename, SCHEMA) if ifield_data is None: continue for elem in ifield_data: name = elem["Name"] descr = elem.get("Description", "No description") size = cast(int, elem["Size"]) show = cast(bool, elem.get("Show", False)) fio = cast(str, elem.get("IO", "?")) operand_def = cast(str, elem.get("Operand", "Zero")) key = (size, show, fio, operand_def) if key in ifields_duplicated: LOG.warning( "Similar definition of instruction field: '%s' and" " '%s'. Check if definition needed.", name, ifields_duplicated[key]) else: ifields_duplicated[key] = name try: operand = operands[operand_def] except KeyError: raise MicroprobeArchitectureDefinitionError( "Unknown operand " "defined in instruction" " field '%s' in '%s'." % (name, filename)) ifield = cls(name, descr, size, show, fio, operand) if name in ifields: raise MicroprobeArchitectureDefinitionError( "Duplicated " "definition " "of instruction field" " '%s' found in '%s'" % (name, filename)) LOG.debug(ifield) ifields[name] = ifield LOG.debug("End") return ifields
# Classes
[docs] @typeguard_testsuite class InstructionField(abc.ABC): """Abstract class to represent an instruction field"""
[docs] @abc.abstractmethod def __init__(self): pass
@property @abc.abstractmethod def name(self) -> str: raise NotImplementedError @property @abc.abstractmethod def description(self) -> str: raise NotImplementedError @property @abc.abstractmethod def size(self) -> int: raise NotImplementedError @property @abc.abstractmethod def default_show(self) -> bool: raise NotImplementedError @property @abc.abstractmethod def default_io(self) -> str: raise NotImplementedError @property @abc.abstractmethod def default_operand(self) -> Operand: raise NotImplementedError @abc.abstractmethod def __str__(self) -> str: raise NotImplementedError
[docs] @typeguard_testsuite class GenericInstructionField(InstructionField): """Instruction field generic class. :param fname: Field name. :type fname: :class:`~.str` :param fsize: Field size in bits. :type fsize: :class:`~.int` :param fshow: Assembly show flag. :type fshow: :class:`~.bool` :param fio: Input/Output flag. :type fio: :class:`~.str` :param foperand: Field operand. :type foperand: :class:`~.Operand` instance """ _valid_fio_values = ['I', 'O', 'IO', '?']
[docs] def __init__(self, fname: str, descr: str, fsize: int, fshow: bool, fio: str, foperand: Operand): """ :param fname: :param descr: :param fsize: :param fshow: :param fio: :param foperand: """ super(GenericInstructionField, self).__init__() self._fname = fname self._fdescr = descr self._fsize = fsize self._fshow = fshow self._fio = fio self._foperand = foperand if fio not in self._valid_fio_values: raise MicroprobeArchitectureDefinitionError( f"Invalid default IO definition for field {fname}")
@property def name(self): return self._fname @property def description(self): return self._fdescr @property def size(self): return self._fsize @property def default_show(self): return self._fshow @property def default_operand(self): return self._foperand @property def default_io(self): return self._fio def __str__(self): return "%10s : %s" % (self.name, self.description) def __repr__(self): return "%s('%s')" % (self.__class__.__name__, self.name)