88 lines
2.4 KiB
Python
88 lines
2.4 KiB
Python
# Copyright 2019-2020 Lawrence Livermore National Security, LLC and other
|
|
# Archspec Project Developers. See the top-level COPYRIGHT file for details.
|
|
#
|
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
|
"""Aliases for microarchitecture features."""
|
|
from .schema import TARGETS_JSON, LazyDictionary
|
|
|
|
_FEATURE_ALIAS_PREDICATE = {}
|
|
|
|
|
|
class FeatureAliasTest:
|
|
"""A test that must be passed for a feature alias to succeed.
|
|
|
|
Args:
|
|
rules (dict): dictionary of rules to be met. Each key must be a
|
|
valid alias predicate
|
|
"""
|
|
|
|
# pylint: disable=too-few-public-methods
|
|
def __init__(self, rules):
|
|
self.rules = rules
|
|
self.predicates = []
|
|
for name, args in rules.items():
|
|
self.predicates.append(_FEATURE_ALIAS_PREDICATE[name](args))
|
|
|
|
def __call__(self, microarchitecture):
|
|
return all(feature_test(microarchitecture) for feature_test in self.predicates)
|
|
|
|
|
|
def _feature_aliases():
|
|
"""Returns the dictionary of all defined feature aliases."""
|
|
json_data = TARGETS_JSON["feature_aliases"]
|
|
aliases = {}
|
|
for alias, rules in json_data.items():
|
|
aliases[alias] = FeatureAliasTest(rules)
|
|
return aliases
|
|
|
|
|
|
FEATURE_ALIASES = LazyDictionary(_feature_aliases)
|
|
|
|
|
|
def alias_predicate(func):
|
|
"""Decorator to register a predicate that can be used to evaluate
|
|
feature aliases.
|
|
"""
|
|
name = func.__name__
|
|
|
|
# Check we didn't register anything else with the same name
|
|
if name in _FEATURE_ALIAS_PREDICATE:
|
|
msg = f'the alias predicate "{name}" already exists'
|
|
raise KeyError(msg)
|
|
|
|
_FEATURE_ALIAS_PREDICATE[name] = func
|
|
|
|
return func
|
|
|
|
|
|
@alias_predicate
|
|
def reason(_):
|
|
"""This predicate returns always True and it's there to allow writing
|
|
a documentation string in the JSON file to explain why an alias is needed.
|
|
"""
|
|
return lambda x: True
|
|
|
|
|
|
@alias_predicate
|
|
def any_of(list_of_features):
|
|
"""Returns a predicate that is True if any of the feature in the
|
|
list is in the microarchitecture being tested, False otherwise.
|
|
"""
|
|
|
|
def _impl(microarchitecture):
|
|
return any(x in microarchitecture for x in list_of_features)
|
|
|
|
return _impl
|
|
|
|
|
|
@alias_predicate
|
|
def families(list_of_families):
|
|
"""Returns a predicate that is True if the architecture family of
|
|
the microarchitecture being tested is in the list, False otherwise.
|
|
"""
|
|
|
|
def _impl(microarchitecture):
|
|
return str(microarchitecture.family) in list_of_families
|
|
|
|
return _impl
|