diff --git a/MODULEINFO b/MODULEINFO index 52cdba44e..2bc57d320 100644 --- a/MODULEINFO +++ b/MODULEINFO @@ -42,6 +42,7 @@ Make: dmlc $(HOST)/bin/dml/python/dml/dmllex14.py $(HOST)/bin/dml/python/dml/dmlparse.py $(HOST)/bin/dml/python/dml/dmlc.py + $(HOST)/bin/dml/python/dml/errors.py $(HOST)/bin/dml/python/dml/expr.py $(HOST)/bin/dml/python/dml/expr_util.py $(HOST)/bin/dml/python/dml/globals.py @@ -50,9 +51,9 @@ Make: dmlc $(HOST)/bin/dml/python/dml/int_register.py $(HOST)/bin/dml/python/dml/io_memory.py $(HOST)/bin/dml/python/dml/logging.py - $(HOST)/bin/dml/python/dml/messages.py $(HOST)/bin/dml/python/dml/objects.py $(HOST)/bin/dml/python/dml/output.py + $(HOST)/bin/dml/python/dml/porting.py $(HOST)/bin/dml/python/dml/provisional.py $(HOST)/bin/dml/python/dml/reginfo.py $(HOST)/bin/dml/python/dml/serialize.py @@ -65,6 +66,7 @@ Make: dmlc $(HOST)/bin/dml/python/dml/topsort.py $(HOST)/bin/dml/python/dml/traits.py $(HOST)/bin/dml/python/dml/types.py + $(HOST)/bin/dml/python/dml/warnings.py $(HOST)/bin/dml/python/dml/dml12_parsetab.py $(HOST)/bin/dml/python/dml/dml14_parsetab.py $(HOST)/bin/dml/python/LICENSE diff --git a/Makefile b/Makefile index 688a9ece2..30511e272 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,7 @@ PYFILES := dml/__init__.py \ dml/dmllex14.py \ dml/dmlparse.py \ dml/dmlc.py \ + dml/errors.py \ dml/expr.py \ dml/expr_util.py \ dml/globals.py \ @@ -34,9 +35,9 @@ PYFILES := dml/__init__.py \ dml/io_memory.py \ dml/int_register.py \ dml/logging.py \ - dml/messages.py \ dml/objects.py \ dml/output.py \ + dml/porting.py \ dml/provisional.py \ dml/reginfo.py \ dml/serialize.py \ @@ -44,6 +45,7 @@ PYFILES := dml/__init__.py \ dml/slotsmeta.py \ dml/structure.py \ dml/symtab.py \ + dml/warnings.py \ __main__.py PYUNIT_FILES := $(wildcard $(DMLC_DIR)/py/dml/*_test.py) diff --git a/messages_to_md.py b/messages_to_md.py index 5ef7bd3f9..f9bb46ccd 100644 --- a/messages_to_md.py +++ b/messages_to_md.py @@ -21,30 +21,15 @@ def fmt_message(err): def extract_messages(sys_path): sys.path.append(sys_path) - from dml import messages - from dml.messages import DMLError, DMLWarning + from dml import warnings, errors - errors = [] - warnings = [] - - for n in dir(messages): - o = getattr(messages, n) - #sys.stderr.write("%s: %r\n" % (n, o)) - if isinstance(o, type): - if issubclass(o, DMLError) and o is not DMLError: - errors.append(o) - elif issubclass(o, DMLWarning) and o is not DMLWarning: - warnings.append(o) - - errors.sort(key=lambda x: x.fmt) - warnings.sort(key=lambda x: x.fmt) - return (warnings, errors) + return (warnings.all_warnings, errors.all_errors) def print_message_table(f, messages): f.write("
- struct xyz { ... }
-
-
- and should be replaced with the following:
-
-
- typedef struct { ... } xyz;
- """
- fmt = "use typedef syntax for struct type declaration"
-
-class PFIELDRANGE(PortingMessage):
- """In a field declaration, the field range declaration must be
- preceded by `@`. In DML 1.4, the syntax `field f[4]`
- declares a field array of size 4, while in DML 1.2 it denotes a field
- occupying bit 4 in its parent register."""
- fmt = "insert @ before field range declaration"
-
-class PINLINEDECL(PortingMessage):
- """Methods with untyped parameters must be explicitly marked 'inline'
- in DML 1.4, as in `inline method m(inline x) -> (int y)`"""
- fmt = "add inline annotation to method with untyped parameters"
-
-class PRETVAL(PortingMessage):
- """Method output parameters are not named in DML 1.4:
- ```
- method m() -> (int, int) {
- ...
- }
- ```
-
- See also `PRETURNARGS`."""
- fmt = "remove name from method output parameter"
-
-class PRETVAL_END(PortingMessage):
- """Methods with output arguments must end with an explicit return
- statement in DML 1.4; in DML 1.2, the method would return whatever
- value the output argument had upon exit. See also `PRETVAL`.
- """
- fmt = "add return statement to end of method"
-
-class PRETURNARGS(PortingMessage):
- """In methods with return values, return statements now take arguments:
- ```
- method m() -> (int, int) {
- return (1, 4);
- }
- method n() -> (int) {
- return 3;
- }
- ```"""
- fmt = "add arguments to return statement"
-
-class POUTARGRETURN(PortingMessage):
- """An assignment to an output argument directly followed by a
- return statement is more concisely written as a single return
- statement, without an intermediate assignment. For instance,
- ```
- dml 1.2;
- method four() -> (int x) {
- x = 4;
- return;
- }
- ```
- can be expressed as:
- ```
- dml 1.4;
- method four() -> (int) {
- return 4;
- }
- ```
- """
- fmt = "merge outarg assignment with return statement"
-
-class PTYPEDOUTPARAM(PortingMessage):
- """Method output parameters must have explicit types in DML 1.4. The
- automatic conversion script will convert untyped output parameters
- to `uint64`."""
- fmt = "declare explicit type for output parameter"
-
-class PINARGTYPE(PortingMessage):
- """When overriding a method in DML 1.4, the overriding and default
- implementation must declare the same arguments as `inline`.
- If the override has untyped arguments that are typed in the default
- method, then the conversion script will add a type to the override's
- argument.
-
- Note: The inserted type declaration uses C syntax, which in most
- cases matches DML syntax; however, there are exceptions where the
- inserted declaration will be broken and needs to be fixed manually.
- """
- fmt = ""
-
-class PINVOKE(PortingMessage):
- """Method invocation syntax changed. Replace
-
- ```
- call m(x) -> (a, b);
- inline n() -> (c);
- call o();
- ```
- with:
- ```
- (a, b) = m(x);
- c = n();
- o();
- ```"""
- fmt = "Use assignment syntax for method invocation"
-
-class PLOGKIND(PortingMessage):
- """In log statements, the old syntax where log type is denoted by a string
- has been removed. Use the new identifier-based syntax instead. E.g.,
- instead of:
- ```
- log "info": "foo";
- log "spec_violation": "foo";
- ```
- you must now write:
- ```
- log info: "foo";
- log spec_viol: "foo";
- ```
-"""
- fmt = "Don't use string literal syntax for log type"
-
-class PAFTER(PortingMessage):
- """The syntax of `after` statements changed: The delay should
- be followed by `s` to denote time unit; furthermore, the
- `call` keyword should no longer be used, and brackets
- around the delay are optional. Example:
- ```
- after (1.3) call send_frame(); // DML 1.2 syntax
- after 1.3 s: send_frame(); // DML 1.4 syntax
- ```"""
- fmt = "Remove 'call' and add 's' in 'after' statement"
-
-class PAUTO(PortingMessage):
- """The `auto` keyword is deprecated; use the equivalent
- `local` instead."""
- fmt = "replace 'auto' with 'local'"
-
-class PSESSION(PortingMessage):
- """The `data` and `static` keywords have both been replaced
- with `session`:
- ```
- session uint32 x;
- ```"""
- fmt = "replace 'data' and 'static' with 'session'"
-
-class PHARD_RESET_VALUE(PortingMessage):
- """The `hard_reset_value` parameter is no longer
- recognized. The parameter is automatically renamed to
- `init_val`, which has roughly the same effect."""
- fmt = "change hard_reset_value to init_val"
-
-class PSOFT_RESET_VALUE(PortingMessage):
- """The `soft_reset_value` parameter is renamed to
- `soft_reset_val`, and requires the template
- `soft_reset_val` to be instantiated."""
- fmt = "change soft_reset_value to soft_reset_val"
-
-class PMISS_PATTERN(PortingMessage):
- """The `miss_pattern` parameter is no longer recognized by
- banks, unless the `miss_pattern_bank` template, from utility.dml, is
- instantiated. An instantiation is automatically added."""
- fmt = "instantiate miss_pattern_bank to use the miss_pattern parameter"
-
-class PATTRIBUTE(PortingMessage):
- """The `allocate_type` parameter is no longer valid for attributes.
- Integer, boolean and floating-point attributes instead use
- standard templates such as `uint64_attr`, `int64_attr`, `bool_attr` and
- `double_attr`.
-
- The porting rule will remove `allocate_type`, together with an
- explicit type parameter if present. All integer types will be
- changed to 64-bit types. Attributes with `allocate_type="string"`
- have to be manually rewritten.
- """
- fmt = "use uint64_attr template instead of allocate_type parameter"
-
-class PEVENT(PortingMessage):
- """Event objects no longer have the `timebase` parameter;
- instead you must choose a standard template to instantiate. The
- conversion script will pick `custom_time_event`,
- `custom_cycle_event`, `simple_time_event`, or `simple_cycle_event`.
- """
-
-class PEVENT_NO_ARG(PortingMessage):
- """When `PEVENT` converts an event to `simple_time_event` or
- `simple_cycle_event`, the `data` function argument to methods
- `post`, `posted`, `next` and `remove` are removed.
- """
-
-class PEVENT_UINT64_ARG(PortingMessage):
- """When one of the methods `post`, `posted`, `next` and `remove`
- is called with an integer value cast to a pointer in the `data`
- arg, that event is converted to a `uint64_time_event` or
- `uint64_cycle_event`. The converter removes the cast and
- causes the event object to be converted to a
- `uint64_time_event` instead of `uint64_custom_event`.
- """
-
-class PEVENT_REMOVE_INFO(PortingMessage):
- """When an event is converted to a `uint64_time_event` or
- `uint64_cycle_event`, the `set_event_info` and `get_event_info` methods
- are removed.
- """
-
-class POVERRIDE(PortingMessage):
- """If a method has exactly one default and one non-default
- declaration, and the non-default declaration resides in a
- template, then DML 1.4 requires that this template inherits from
- the template containing the default declaration. Conversion is done
- automatically for the most common case."""
- fmt = "template with method override must instantiate overridden template"
-
-class POVERRIDE_IMPORT(PortingMessage):
- """Similar to POVERRIDE, but if a default method does _not_
- reside in a template, then the file that instantiates the non-default
- declaration must import the file containing the default declaration."""
- fmt = "template with method override must import overridden file"
-
-# TODO: convert
-
-class PBEFAFT(PortingMessage):
- """In objects of type attribute, register and connect, before/after
- methods (e.g. `before_write`, `after_read`,
- `after_set`), are no longer called. They are transformed
- into an override of the corresponding base function
- (`write_register`, `read_register`, `set`).
- Note that when a before/after method is implemented by a template,
- then an additional `is register` declaration may be needed in
- 1.4; this is not automatically added.
- """
- fmt = "before / after method no longer called, override base method instead"
-
-class PABSTRACT_TEMPLATE(PortingMessage):
- """When implementing methods `read` or `write` in a
- field or register, or `hard_reset` or
- `soft_reset` in a bank, or `get`, `set`,
- `read_field`, `write_field` in a field, then this will
- have no effect unless a template named like the method is instantiated. The
- automatic converter will add e.g. `is read;` before an
- implementation of `read`."""
- fmt = ("method has no effect unless corresponding abstract template is"
- + " instantiated")
-
-class PTRAMPOLINE(PortingMessage):
- """The methods `miss_read_access` and
- `miss_write_access` in `bank` objects have been
- renamed to `unmapped_read` and `unmapped_write`
- in 1.4. The converter creates methods with the new names, which
- call the existing unmodified methods."""
- fmt = "method has been renamed in 1.4, will insert trampoline method"
-
-class PIMPORT_DML12COMPAT(PortingMessage):
- """The `PTRAMPOLINE` porting rule sometimes requires
- that `dml12-compatibility.dml` is imported."""
- fmt = ''
-
-class PCHANGE_INARGS(PortingMessage):
- """Many overridable methods in the standard library have changed, and
- method overrides must be changed accordingly. A method in 1.2
- usually has a counterpart in 1.4, but its semantics may have
- changed slightly and quite often the set of arguments has changed
- as well. The automatic converter will adjust the names and
- signatures of a number of methods. Invocations, including
- `default()`, are not updated and must be manually converted
- (compile errors). Some method arguments are removed by the
- converter; if these arguments are used, the implementation must be
- modified accordingly. In particular, the `memop` arg of
- various bank and register methods is no longer present. This has
- been replaced with an argument `void *aux`, which is
- normally NULL. If some register in a bank needs a memop, then the
- `io_memory_access` method can be updated to pass down the
- memop in the `aux` argument (just call `default`
- with `memop` in the last arg). An explicit call to a bank
- method, e.g. a redirection of an access to a different bank,
- should normally be rewritten as a call to `read` or
- `write`, usually with NULL in the `aux`
- argument.
-
- Bank methods are converted as follows: `access` →
- `io_memory_access`; `read_access`,
- `read_access_memop` → `read`;
- `write_access`, `write_access_memop` →
- `write`
-
- Register methods are converted like so: `read_access`
- → `read_register`, `write_access` →
- `write_register`
-
- Field methods are converted thusly: `read_access`
- → `read_field`, `write_access` →
- `write_field`
-
- In `register` and `field` objects, the
- `set` and
- `write_register`/`write_field` methods will get
- an explicit type `uint64`.
-
- The read and write methods on `bank`, `register`,
- and `field` objects all take a new `uint64` argument
- denoting enabled bytes or bits, depending on the context, which
- may mask an access.
-
- In `connect` objects, `validate_port` is converted
- to `validate`; named ports are deprecated in Simics 6, but
- the port name is available in the `port` session variable.
-
- In `attribute` objects, the `set` method will get
- an explicit argument type `attr_value_t`, and a
- `throws` annotation.
- """
- fmt = "override of library method with new name or signature"
-
-class PBITNEQ(PortingMessage):
- """DML 1.2 permits using 1-bit fields as boolean values. In DML 1.4,
- field values are 64 bit, and thus require an explicit `!= 0`"""
- fmt = ""
-
-class PVAL(PortingMessage):
- """The value of a `register`, `field` or `attribute`
- object, and the interface struct of a `interface` object, is now
- accessed through the `.val` member."""
- fmt = "use .val member to access register/attribute value"
-
-class PNODOLLAR(PortingMessage):
- """The `$` character is no longer needed when referencing objects."""
- fmt = "remove $"
-
-class PDOLLAR_QUALIFY(PortingMessage):
- """In DML 1.4, there is no separate scope for `$`, so local
- variables can shadow object references. This conversion rule
- attempts to detect this, and add `this.` or
- dev.path. where needed."""
- fmt = "use qualified object reference to escape shadowing"
-
-class PCONSTANT(PortingMessage):
- """`constant` declarations are removed in 1.4 and should be
- replaced with `param` declarations. Both are accessible
- from the top-level scope of a device."""
- fmt = "change 'constant' to 'param'"
-
-class PPARAMETER(PortingMessage):
- """The `parameter` keyword has been renamed to `param`."""
- fmt = "change 'parameter' to 'param'"
-
-class PARRAY_I(PortingMessage):
- """The syntax for object arrays has changed: Instead of
- `register r[12]`, you write `register r[i < 12]`"""
- fmt = "explicit index in object array declaration"
-
-class PARRAY(PortingMessage):
- """The syntax for object arrays has changed: Instead of
- `register r[j in 0..size - 1]`, you write
- `register r[j < size]`"""
- fmt = "'<' replaces 'in 0..' in object array declaration"
-
-class PHASH(PortingMessage):
- """`if` statements on top level must be prefixed with a `#`
- character. The same applies to `if` statement inside a method body
- if the condition is constant and the dead branch contains errors.
-
- Similarly, the conditional operator (`? :`) is updated to #? #:
- when needed, `select` is updated to `#select`, and
- `foreach` is updated to `#foreach`."""
- fmt = "insert '#' before 'if'"
-
-class PHASHELSE(PortingMessage):
- """If an `if` is updated to `#if`, and there is a
- corresponding `else` clause, then it must be updated to
- `#else`. The same applies to the `else` clause in
- `select` statements."""
- fmt = "insert '#' before 'else'"
-
-class PANDOR(PortingMessage):
- """DML 1.2 permits the right operand of an `&&` or
- `||` expression to contain errors, as long as the left
- operand evaluates to a constant that makes the right operand
- dead. DML 1.4 does not permit this, so the expression `A
- && B` must be converted to `A #? B #: false`.
- One common use case is expressions like
- `(defined X && X.y == ...)`.
- """
- fmt = ''
-
-class PIFAND(PortingMessage):
- """If statements on the form `if (defined(X) && X.y) { ... }`
- are converted to a nested `#if` statement"""
- fmt = ''
-
-class PSTRINGIFY(PortingMessage):
- """In DML 1.4, `#` is changed to the
- `stringify` operator"""
- fmt = "Replace '#(X)' with 'stringify(X)' operator"
-
-class PWUNUSED(PortingMessage):
- """This message is used to signal to the porting script that a piece
- of conditional code was not fully covered by the compile. Some
- portings are never applied on dead code. The porting script
- can signal a warning for this."""
- fmt = ""
- typed_methods = set()
- # site -> objects.Method
- inline_methods = {}
- inlined_methods = set()
- positive_conds = set()
- negative_conds = set()
- satisfied_conds = set()
- used_templates = set()
-
-class PNO_WUNUSED(PortingMessage):
- """Used in conjunction with PWUNUSED to signal that a piece of
- conditional code was indeed used. If using multiple runs of DMLC
- as input to the porting script, and a piece of code was used in
- some runs and unused in others, then no warning is shown.
- """
- fmt = ""
-
-class PRENAME_TEMPLATE(PortingMessage):
- """Some templates in `utility.dml` have been renamed; in
- particular, `unimplemented` has been renamed to
- `unimpl`.
- """
- fmt = ""
-
-class PUNDEFOFFS(PortingMessage):
- """`undefined` is no longer a valid offset for registers; `unmapped_offset`
- should be used instead.
- """
- fmt = "Use 'unmapped_offset' instead of 'undefined'"
-
-class PINT1(PortingMessage):
- """Integer types have different semantics in DML 1.2 and DML 1.4;
- the `int1` type in DML 1.2 is converted to `uint1` in DML 1.4
- because that is a better match for some common operations. In
- particular, if the value 1 is assigned to variables of these
- types, then the value of the variable becomes 1, whereas for
- `int1` in DML 1.4 the value is -1."""
- fmt = "Change int1 to uint1"
-
-warnings = {name: cls for (name, cls) in globals().items()
- if isinstance(cls, type) and issubclass(cls, DMLWarning)
- and cls is not DMLWarning}
+all_errors = {
+ o.tag(): o for o in globals().values()
+ if isinstance(o, type)
+ and issubclass(o, DMLError)
+ and o is not DMLError}
diff --git a/py/dml/expr.py b/py/dml/expr.py
index d5a225494..80ea95ad3 100644
--- a/py/dml/expr.py
+++ b/py/dml/expr.py
@@ -4,13 +4,13 @@
import abc
import dml.globals
-from .logging import *
-from .messages import *
-from .output import *
-from .types import *
-from .slotsmeta import *
-
+from . import logging
+from .logging import ICE
+from . import errors as E
from . import output
+from . import types as tp
+from .slotsmeta import SlotsMeta, auto_init
+
__all__ = (
'Code',
@@ -36,7 +36,7 @@ def __repr__(self):
for name in self.init_args[2:]))
def linemark(self):
- site_linemark(self.site)
+ output.site_linemark(self.site)
class Expression(Code):
'''An Expression can represent either:
@@ -56,7 +56,7 @@ class Expression(Code):
the composite expression.'''
slots = ('context',)
- # An instance of DMLType
+ # An instance of tp.DMLType
#type = None
# If true, this is a constant, with the value stored in .value, as
@@ -123,9 +123,9 @@ class Expression(Code):
c_lval = False
def __init__(self, site):
- assert not site or isinstance(site, Site)
+ assert not site or isinstance(site, logging.Site)
self.site = site
- self.context = ErrorContext.current()
+ self.context = logging.ErrorContext.current()
def __str__(self):
"Format the expression in DML form"
@@ -137,7 +137,7 @@ def read(self):
# Produce a C expression but don't worry about the value.
def discard(self, explicit=False):
- if not explicit or safe_realtype_shallow(self.ctype()).void:
+ if not explicit or tp.safe_realtype_shallow(self.ctype()).void:
return self.read()
if self.constant:
@@ -202,7 +202,7 @@ def apply(self, inits, location, scope):
raise self.exc()
def exc(self):
'''Exception to raise when expression appears in an incorrect context'''
- return ENVAL(self.site, self)
+ return E.NVAL(self.site, self)
class NonValueArrayRef(NonValue):
'''Reference to an array node before it's indexed. Indexing is the
@@ -215,7 +215,7 @@ def local_indices(self): pass
def local_dimsizes(self): pass
def exc(self):
- return EARRAY(self.site, self)
+ return E.ARRAY(self.site, self)
class Lit(Expression):
"A literal C expression"
@@ -252,7 +252,7 @@ class NullConstant(Expression):
constant = True
value = None
priority = 1000
- type = TPtr(void, const=True)
+ type = tp.Ptr(tp.void, const=True)
def __str__(self):
return 'NULL'
def read(self):
@@ -265,7 +265,7 @@ def copy(self, site):
def typecheck_inargs(site, args, inp, kind="function", known_arglen=None):
arglen = len(args) if known_arglen is None else known_arglen
if arglen != len(inp):
- raise EARG(site, kind)
+ raise E.ARG(site, kind)
for (i, (arg, p)) in enumerate(zip(args, inp)):
if kind == 'method':
@@ -274,18 +274,18 @@ def typecheck_inargs(site, args, inp, kind="function", known_arglen=None):
else:
(pname, ptype) = p
logref = f"'{pname}'"
- argtype = safe_realtype(arg.ctype())
+ argtype = tp.safe_realtype(arg.ctype())
if not argtype:
raise ICE(site, "unknown expression type")
- rtype = safe_realtype(ptype)
+ rtype = tp.safe_realtype(ptype)
assert rtype
(ok, trunc, constviol) = rtype.canstore(argtype)
if ok:
if constviol:
- raise ECONSTP(site, logref, kind + " call")
+ raise E.CONSTP(site, logref, kind + " call")
else:
- raise EPTYPE(site, arg, rtype, logref, kind)
+ raise E.PTYPE(site, arg, rtype, logref, kind)
# Typecheck a DML method application, where the arguments are given as a list
# where each element is either an AST of an initializer, or an initializer
@@ -296,7 +296,7 @@ def typecheck_inarg_inits(site, inits, inp, location, scope,
allow_undefined_args=False,
on_ptr_to_stack=None):
if (not variadic and len(inits) != len(inp)) or len(inits) < len(inp):
- raise EARG(site, kind)
+ raise E.ARG(site, kind)
from .expr_util import coerce_if_eint
from .codegen import eval_initializer, codegen_expression, \
@@ -319,19 +319,19 @@ def typecheck_inarg_inits(site, inits, inp, location, scope,
else:
try:
arg = init.as_expr(ptype)
- except EASTYPE as e:
+ except E.ASTYPE as e:
if e.site is init.site:
- raise EPTYPE(site, e.source, e.target_type, logref,
+ raise E.PTYPE(site, e.source, e.target_type, logref,
kind) from e
raise
# better error message
- except EDISCONST as e:
+ except E.DISCONST as e:
if e.site is init.site:
- raise ECONSTP(site, logref, kind + " call") from e
+ raise E.CONSTP(site, logref, kind + " call") from e
raise
elif ptype is None:
if init.kind != 'initializer_scalar':
- raise ESYNTAX(init.site, '{',
+ raise E.SYNTAX(init.site, '{',
'the argument for an untyped parameter must be '
+ 'a simple expression')
arg = codegen_expression_maybe_nonvalue(init.args[0], location,
@@ -344,35 +344,35 @@ def typecheck_inarg_inits(site, inits, inp, location, scope,
and init.kind == 'initializer_scalar'):
arg = coerce_if_eint(codegen_expression(init.args[0],
location, scope))
- argtype = safe_realtype(arg.ctype())
+ argtype = tp.safe_realtype(arg.ctype())
if not argtype:
raise ICE(site, "unknown expression type")
- rtype = safe_realtype(ptype)
+ rtype = tp.safe_realtype(ptype)
assert rtype
(ok, trunc, constviol) = rtype.canstore(argtype)
if ok:
if constviol:
- raise ECONSTP(site, logref, kind + " call")
+ raise E.CONSTP(site, logref, kind + " call")
else:
- raise EPTYPE(site, arg, rtype, logref, kind)
+ raise E.PTYPE(site, arg, rtype, logref, kind)
else:
try:
arg = eval_initializer(init.site, ptype, init, location,
scope, False).as_expr(ptype)
- except EASTYPE as e:
+ except E.ASTYPE as e:
if e.site is init.site:
- raise EPTYPE(site, e.source, e.target_type, logref,
+ raise E.PTYPE(site, e.source, e.target_type, logref,
kind) from e
raise
# better error message
- except EDISCONST as e:
+ except E.DISCONST as e:
if e.site is init.site:
- raise ECONSTP(site, logref, kind + " call") from e
+ raise E.CONSTP(site, logref, kind + " call") from e
raise
if (on_ptr_to_stack
- and isinstance(safe_realtype_shallow(ptype), TPtr)
+ and isinstance(tp.safe_realtype_shallow(ptype), tp.Ptr)
and arg.is_pointer_to_stack_allocation):
on_ptr_to_stack(arg)
args.append(arg)
@@ -380,7 +380,7 @@ def typecheck_inarg_inits(site, inits, inp, location, scope,
if variadic and len(inits) > len(inp):
for init in inits[len(inp):]:
if init.kind != 'initializer_scalar':
- raise ESYNTAX(init.site, '{',
+ raise E.SYNTAX(init.site, '{',
'variadic arguments must be simple expressions')
args.append(coerce_if_eint(codegen_expression(init.args[0],
location, scope)))
@@ -407,18 +407,18 @@ def mkApplyInits(site, fun, inits, location, scope):
funtype = fun.ctype()
if not funtype:
- raise EAPPLY(fun)
+ raise E.APPLY(fun)
try:
- funtype = realtype(funtype)
- if isinstance(funtype, TPtr) and isinstance(funtype.base, TFunction):
+ funtype = tp.realtype(funtype)
+ if isinstance(funtype, tp.Ptr) and isinstance(funtype.base, tp.Function):
# Pointers to functions are the same as the functions
- funtype = realtype(funtype.base)
- except DMLUnknownType:
- raise ETYPE(site, funtype)
+ funtype = tp.realtype(funtype.base)
+ except tp.DMLUnknownType:
+ raise E.TYPE(site, funtype)
- if not isinstance(funtype, TFunction):
- raise EAPPLY(fun)
+ if not isinstance(funtype, tp.Function):
+ raise E.APPLY(fun)
args = typecheck_inarg_inits(
site, inits,
@@ -432,18 +432,18 @@ def mkApply(site, fun, args):
funtype = fun.ctype()
if not funtype:
- raise EAPPLY(fun)
+ raise E.APPLY(fun)
try:
- funtype = realtype(funtype)
- if isinstance(funtype, TPtr) and isinstance(funtype.base, TFunction):
+ funtype = tp.realtype(funtype)
+ if isinstance(funtype, tp.Ptr) and isinstance(funtype.base, tp.Function):
# Pointers to functions are the same as the functions
- funtype = realtype(funtype.base)
- except DMLUnknownType:
- raise ETYPE(site, funtype)
+ funtype = tp.realtype(funtype.base)
+ except tp.DMLUnknownType:
+ raise E.TYPE(site, funtype)
- if not isinstance(funtype, TFunction):
- raise EAPPLY(fun)
+ if not isinstance(funtype, tp.Function):
+ raise E.APPLY(fun)
if funtype.varargs and len(args) > len(funtype.input_types):
known_arglen = len(funtype.input_types)
@@ -480,6 +480,6 @@ class StaticIndex(NonValue):
def __init__(self, site, var):
pass
def __str__(self):
- return dollar(self.site) + ("_" if self.var is None else self.var)
+ return logging.dollar(self.site) + ("_" if self.var is None else self.var)
def exc(self):
- return EIDXVAR(self.site, str(self))
+ return E.IDXVAR(self.site, str(self))
diff --git a/py/dml/expr_util.py b/py/dml/expr_util.py
index 8227eb2e3..aa36eec0f 100644
--- a/py/dml/expr_util.py
+++ b/py/dml/expr_util.py
@@ -3,10 +3,10 @@
# Various convenience functions for common operations on expressions
import dml.globals
-from .logging import report, ICE
-from .messages import *
-from .types import *
-from .expr import *
+from .logging import report, DMLError
+from . import errors as E
+from . import types as tp
+from .expr import Lit, NonValue, NullConstant, StaticIndex
__all__ = (
'defined', 'undefined',
@@ -62,9 +62,9 @@ def expr_constvalue(expr, pytype, typestr):
if isinstance(expr, NonValue):
raise expr.exc()
if not expr.constant:
- raise ENCONST(expr.site, expr)
+ raise E.NCONST(expr.site, expr)
if not isinstance(expr.value, pytype):
- raise EBTYPE(expr.site, expr.ctype(), typestr)
+ raise E.BTYPE(expr.site, expr.ctype(), typestr)
return expr.value
@@ -73,7 +73,7 @@ def expr_strval(expr):
try:
return value.decode('utf-8')
except UnicodeDecodeError:
- raise EBTYPE(expr.site, expr.ctype(), 'utf-8 encoded string')
+ raise E.BTYPE(expr.site, expr.ctype(), 'utf-8 encoded string')
def expr_intval(expr):
@@ -111,7 +111,7 @@ def param_bool(node, name):
def coerce_if_eint(expr):
from .ctree import as_int
- e_type = realtype(expr.ctype())
+ e_type = tp.realtype(expr.ctype())
if e_type.is_int and e_type.is_endian:
return as_int(expr)
return expr
diff --git a/py/dml/g_backend.py b/py/dml/g_backend.py
index 15a3a5474..f7c808651 100644
--- a/py/dml/g_backend.py
+++ b/py/dml/g_backend.py
@@ -6,11 +6,10 @@
__all__ = ('generate',)
import pickle as pickle
-from . import ctree, crep, expr_util, types
+from . import crep, types
from . import logging
from .expr import mkLit
-from .logging import dollar
-import dml.globals
+
VERSION = (0, 1)
@@ -50,7 +49,7 @@ def enc(expr):
try:
with crep.DeviceInstanceContext():
expr = node.get_expr(tuple(
- mkLit(node.site, dollar(node.site) + idxvar, types.TInt(32, False))
+ mkLit(node.site, logging.dollar(node.site) + idxvar, types.Int(32, False))
for idxvar in node.parent.idxvars()))
except logging.DMLError:
import os, sys, traceback
diff --git a/py/dml/info_backend.py b/py/dml/info_backend.py
index b19fe2c4c..e0be8e432 100644
--- a/py/dml/info_backend.py
+++ b/py/dml/info_backend.py
@@ -6,13 +6,11 @@
import dml.globals
from itertools import product
from collections import OrderedDict
+from . import expr_util
from .ctree import (StringConstant, IntegerConstant, mkIntegerLiteral,
all_index_exprs, param_str_fixup)
-from .expr_util import (
- defined, undefined, param_int, param_defined,
- static_indices)
-from .messages import *
-from .logging import *
+from .expr_util import defined
+from .logging import report, DMLError
class XMLWriter(object):
def __init__(self, filename):
@@ -50,7 +48,7 @@ def string_param(node, pname, dimsizes):
# Allowing index variables to appear in the expression,
# but requires them all evaluated to the same value.
try:
- val = pnode.get_expr(static_indices(node))
+ val = pnode.get_expr(expr_util.static_indices(node))
except DMLError as e:
report(e)
return None
@@ -116,7 +114,7 @@ def reg_info(fmt, node, name, dimsizes):
attrs = common_attrs(node, name, dimsizes)
xml_offs = ' '.join([str(o) if offset_defined(o)
else '-1' for o in all_offs])
- attrs.update(offset=xml_offs, size=param_int(node, 'size'))
+ attrs.update(offset=xml_offs, size=expr_util.param_int(node, 'size'))
fmt.open_element('register', attrs)
for n in node.get_components('field'):
if not n.ident:
diff --git a/py/dml/int_register.py b/py/dml/int_register.py
index 0f2753279..95d42b911 100644
--- a/py/dml/int_register.py
+++ b/py/dml/int_register.py
@@ -1,36 +1,35 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-from .expr import *
-from .ctree import *
-from .types import *
-from .logging import dbg
-from .symtab import *
+from .expr import Lit, mkApply, mkLit
+from . import ctree as c
+from . import types as tp
+from .symtab import global_scope, Symtab
from .crep import node_storage_type
from . import globals
-reg_table_type = TPtr(TNamed('_dml_reg_t', const=True))
-regmap_table_type = TPtr(TNamed('_dml_reg_number_t', const=True))
+reg_table_type = tp.Ptr(tp.Named('_dml_reg_t', const=True))
+regmap_table_type = tp.Ptr(tp.Named('_dml_reg_number_t', const=True))
make_regname = mkLit(None, '_DML_make_regname',
- TFunction([reg_table_type, regmap_table_type],
- TPtr(TNamed('char', const=True))))
+ tp.Function([reg_table_type, regmap_table_type],
+ tp.Ptr(tp.Named('char', const=True))))
find_regnum = mkLit(None, '_DML_find_regnum',
- TFunction([regmap_table_type,
- TInt(32, False),
- TInt(32, False)],
+ tp.Function([regmap_table_type,
+ tp.Int(32, False),
+ tp.Int(32, False)],
regmap_table_type))
find_regname = mkLit(None, '_DML_find_regname',
- TFunction([regmap_table_type,
- TInt(32, False),
- TPtr(TNamed('char', const=True)),
+ tp.Function([regmap_table_type,
+ tp.Int(32, False),
+ tp.Ptr(tp.Named('char', const=True)),
reg_table_type],
regmap_table_type))
def return_success(site):
- return mkReturn(site, mkBoolConstant(site, False))
+ return c.mkReturn(site, c.mkBoolConstant(site, False))
-dml_reg_t = TExternStruct({}, '_dml_reg_t', const=True)
+dml_reg_t = tp.ExternStruct({}, '_dml_reg_t', const=True)
def codegen_get_name(impl, indices, inargs, outargs, site):
bank = impl.parent
@@ -39,25 +38,25 @@ def codegen_get_name(impl, indices, inargs, outargs, site):
[name] = outargs
if not bank.numbered_registers:
- return mkCompound(
- site, [mkCopyData(site, Lit(None, 'NULL', TPtr(TVoid()), 1), name),
+ return c.mkCompound(
+ site, [c.mkCopyData(site, Lit(None, 'NULL', tp.Ptr(tp.Void()), 1), name),
return_success(site)])
- reg_table = mkLit(None, '_DML_R_' + bank.name, TPtr(dml_reg_t))
+ reg_table = mkLit(None, '_DML_R_' + bank.name, tp.Ptr(dml_reg_t))
regnum_table = mkLit(None, '_DML_RN_' + bank.name,
regmap_table_type)
# name = make_regname(reg_table, find_regnum(regnum_table, num))
regnum_table_len = mkLit(site, 'ALEN(_DML_RN_%s)' % bank.name,
- TInt(32, False))
+ tp.Int(32, False))
reg = mkApply(site, find_regnum, [regnum_table, regnum_table_len, num])
regname = mkApply(site, make_regname, [reg_table, reg])
- return mkCompound(
+ return c.mkCompound(
site,
- [mkCopyData(site, regname, name),
- mkIf(site,
- mkNot(site, as_bool(name)),
- log_statement(site, log_object(site, bank, indices), "error",
+ [c.mkCopyData(site, regname, name),
+ c.mkIf(site,
+ c.mkNot(site, c.as_bool(name)),
+ c.log_statement(site, c.log_object(site, bank, indices), "error",
None, None, "There is no register with number %d",
num)),
return_success(site)])
@@ -69,42 +68,42 @@ def codegen_get_number(impl, indices, inargs, outargs, site):
[num] = outargs
if not bank.numbered_registers:
- return mkCompound(
- site, [mkCopyData(site, mkIntegerConstant(site, -1, True), num),
+ return c.mkCompound(
+ site, [c.mkCopyData(site, c.mkIntegerConstant(site, -1, True), num),
return_success(site)])
- reg_table = mkLit(None, '_DML_R_' + bank.name, TPtr(dml_reg_t))
+ reg_table = mkLit(None, '_DML_R_' + bank.name, tp.Ptr(dml_reg_t))
regnum_table = mkLit(None, '_DML_RN_' + bank.name,
regmap_table_type)
# num = find_regname(regnum_table, name)->num
regnum_table_len = mkLit(site, 'ALEN(_DML_RN_%s)' % bank.name,
- TInt(32, False))
- reg = ExpressionInitializer(
+ tp.Int(32, False))
+ reg = c.ExpressionInitializer(
mkApply(site, find_regname, [regnum_table, regnum_table_len, name,
reg_table]))
scope = Symtab(global_scope)
- regvar = mkLocalVariable(site, scope.add_variable(
+ regvar = c.mkLocalVariable(site, scope.add_variable(
'reg',
type=regmap_table_type,
init=reg,
make_unique=True,
site=site))
- return mkCompound(
+ return c.mkCompound(
site,
- [sym_declaration(regvar.sym),
- mkIf(site,
- as_bool(regvar),
- mkCopyData(site,
- mkSubRef(site, regvar, 'num', '->'),
+ [c.sym_declaration(regvar.sym),
+ c.mkIf(site,
+ c.as_bool(regvar),
+ c.mkCopyData(site,
+ c.mkSubRef(site, regvar, 'num', '->'),
num),
- mkCompound(site,
- [mkCopyData(site,
- mkIntegerConstant(site, -1, True),
+ c.mkCompound(site,
+ [c.mkCopyData(site,
+ c.mkIntegerConstant(site, -1, True),
num),
- log_statement(site, log_object(site, bank, indices),
+ c.log_statement(site, c.log_object(site, bank, indices),
"error", None, None,
"There is no register with name %s",
name)])),
@@ -116,21 +115,21 @@ def codegen_read(impl, indices, inargs, outargs, site):
[val] = outargs
if not bank.numbered_registers:
- return mkCompound(
- site, [mkCopyData(site, mkIntegerLiteral(site, 0), val),
+ return c.mkCompound(
+ site, [c.mkCopyData(site, c.mkIntegerLiteral(site, 0), val),
return_success(site)])
- reg_table = mkLit(None, '_DML_R_' + bank.name, TPtr(dml_reg_t))
+ reg_table = mkLit(None, '_DML_R_' + bank.name, tp.Ptr(dml_reg_t))
regmap_table = mkLit(None, '_DML_RN_' + bank.name,
regmap_table_type)
regmap_table_len = mkLit(site, 'ALEN(_DML_RN_%s)' % bank.name,
- TInt(32, False))
+ tp.Int(32, False))
scope = Symtab(global_scope)
- regvar = mkLocalVariable(site, scope.add_variable(
+ regvar = c.mkLocalVariable(site, scope.add_variable(
'reg',
type=regmap_table_type,
- init=ExpressionInitializer(
+ init=c.ExpressionInitializer(
mkApply(site, find_regnum,
[regmap_table, regmap_table_len, num])),
make_unique=True,
@@ -138,23 +137,23 @@ def codegen_read(impl, indices, inargs, outargs, site):
devtype = node_storage_type(globals.device)
read_reg = mkLit(None, '_DML_read_reg',
- TFunction([devtype,
+ tp.Function([devtype,
regmap_table_type,
reg_table_type],
- TInt(64, False)))
+ tp.Int(64, False)))
- return mkCompound(
+ return c.mkCompound(
site,
- [sym_declaration(regvar.sym),
- mkIf(site,
- as_bool(regvar),
- mkCopyData(site,
+ [c.sym_declaration(regvar.sym),
+ c.mkIf(site,
+ c.as_bool(regvar),
+ c.mkCopyData(site,
mkApply(site, read_reg,
[mkLit(site, '_dev', devtype),
regvar,
reg_table]),
val),
- log_statement(site, log_object(site, bank, indices), "error",
+ c.log_statement(site, c.log_object(site, bank, indices), "error",
None, None, "There is no register with number %d",
num)),
return_success(site)])
@@ -164,44 +163,44 @@ def codegen_write(impl, indices, inargs, outargs, site):
[num, val] = inargs
if not bank.numbered_registers:
- return mkCompound(site, [return_success(site)])
+ return c.mkCompound(site, [return_success(site)])
- reg_table = mkLit(None, '_DML_R_' + bank.name, TPtr(dml_reg_t))
+ reg_table = mkLit(None, '_DML_R_' + bank.name, tp.Ptr(dml_reg_t))
regmap_table = mkLit(None, '_DML_RN_' + bank.name,
regmap_table_type)
regmap_table_len = mkLit(site, 'ALEN(_DML_RN_%s)' % bank.name,
- TInt(32, False))
+ tp.Int(32, False))
scope = Symtab(global_scope)
- regvar = mkLocalVariable(site, scope.add_variable(
+ regvar = c.mkLocalVariable(site, scope.add_variable(
'reg',
site=site,
type=regmap_table_type,
- init=ExpressionInitializer(
+ init=c.ExpressionInitializer(
mkApply(site, find_regnum,
[regmap_table, regmap_table_len, num])),
make_unique=True))
devtype = node_storage_type(globals.device)
write_reg = mkLit(None, '_DML_write_reg',
- TFunction([devtype,
+ tp.Function([devtype,
regmap_table_type,
reg_table_type,
- TInt(64, False)],
- TVoid()))
+ tp.Int(64, False)],
+ tp.Void()))
- return mkCompound(
+ return c.mkCompound(
site,
- [sym_declaration(regvar.sym),
- mkIf(site,
- as_bool(regvar),
- mkExpressionStatement(site,
+ [c.sym_declaration(regvar.sym),
+ c.mkIf(site,
+ c.as_bool(regvar),
+ c.mkExpressionStatement(site,
mkApply(site, write_reg,
[mkLit(site, '_dev', devtype),
regvar,
reg_table,
val])),
- log_statement(site, log_object(site, bank, indices), "error",
+ c.log_statement(site, c.log_object(site, bank, indices), "error",
None, None, "There is no register with number %d",
num)),
return_success(site)])
diff --git a/py/dml/io_memory.py b/py/dml/io_memory.py
index f11028824..6eb5a0ba0 100644
--- a/py/dml/io_memory.py
+++ b/py/dml/io_memory.py
@@ -1,22 +1,20 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-import operator
-from .ctree import *
-from .expr import *
-from .expr_util import *
-from .types import *
+from . import ctree as c
+from .expr import mkLit
+from .expr_util import param_bool, param_defined, param_str
+from . import types as tp
from .logging import report
-from .messages import WEXPERIMENTAL_UNMAPPED
-from .symtab import *
-from .codegen import (require_fully_typed, mark_method_referenced,
- method_instance, codegen_call_byname, declarations,
- ReturnFailure)
+from . import warnings as W
+from .symtab import global_scope, Symtab
+from .codegen import codegen_call_byname, declarations
+from . import codegen
from . import crep
import dml.globals
# Emit a warning if the hook methods are overridden, as they are
-# introduced as an experimental feature, at the moment.
+# introduced as an experimental feature, at the moment.
def check_unmapped_access_handling(bank, isread):
if isread:
meth_node = bank.get_component('_unmapped_read_access', 'method')
@@ -25,7 +23,7 @@ def check_unmapped_access_handling(bank, isread):
overridden = meth_node and meth_node.default_method.node
if overridden:
- report(WEXPERIMENTAL_UNMAPPED(meth_node, meth_node.name))
+ report(W.EXPERIMENTAL_UNMAPPED(meth_node, meth_node.name))
def unmapped_access(site, bank, idx, scope, isread, overlapping, bigendian,
memop, offset, size, writevalue, size2, value2):
@@ -33,21 +31,21 @@ def unmapped_access(site, bank, idx, scope, isread, overlapping, bigendian,
# Only pass the first byte of the access to _unmapped_*_access
if not isread:
if bigendian:
- writevalue = mkShR(
- site, writevalue, mkMult(
+ writevalue = c.mkShR(
+ site, writevalue, c.mkMult(
site,
- mkSubtract(site, size, mkIntegerLiteral(site, 1)),
- mkIntegerLiteral(site, 8)))
+ c.mkSubtract(site, size, c.mkIntegerLiteral(site, 1)),
+ c.mkIntegerLiteral(site, 8)))
else:
- writevalue = mkBitAnd(
- site, writevalue, mkIntegerLiteral(site, 0xff))
- size = mkIntegerLiteral(site, 1)
+ writevalue = c.mkBitAnd(
+ site, writevalue, c.mkIntegerLiteral(site, 0xff))
+ size = c.mkIntegerLiteral(site, 1)
scope = Symtab(scope)
code = []
- success = mkLocalVariable(site, scope.add_variable(
- 'success', type=TBool(), site=site,
- init=ExpressionInitializer(mkBoolConstant(site, 0)),
+ success = c.mkLocalVariable(site, scope.add_variable(
+ 'success', type=tp.Bool(), site=site,
+ init=c.ExpressionInitializer(c.mkBoolConstant(site, 0)),
make_unique=True))
if isread:
@@ -68,13 +66,13 @@ def unmapped_access(site, bank, idx, scope, isread, overlapping, bigendian,
[success]))
code.extend([
- mkCopyData(
+ c.mkCopyData(
site,
- mkIfExpr(site, success, size, mkIntegerLiteral(site, 0)),
+ c.mkIfExpr(site, success, size, c.mkIntegerLiteral(site, 0)),
size2),
- mkReturn(site, mkBoolConstant(site, False))])
+ c.mkReturn(site, c.mkBoolConstant(site, False))])
- return mkCompound(site, declarations(scope) + code)
+ return c.mkCompound(site, declarations(scope) + code)
# The basic idea of the register dispatcher is to statically
# create a static table with one item for each register instance,
@@ -147,9 +145,9 @@ def codegen_access(bank, bank_indices, isread, memop, offset, size, writevalue,
for reg in bank.mapped_registers:
meth_node = reg.node.get_component(method_name, 'method')
- require_fully_typed(site, meth_node)
- func = method_instance(meth_node)
- mark_method_referenced(func)
+ codegen.require_fully_typed(site, meth_node)
+ func = codegen.method_instance(meth_node)
+ codegen.mark_method_referenced(func)
cname = func.get_cname()
by_dims.setdefault(len(reg.layout[0].coord), []).extend(
(instance, cname) for instance in reg.layout)
@@ -221,8 +219,8 @@ def dim_sort_key(data):
regvar, size.read())])
lines.append(
' %s;' % (
- size2.write(ExpressionInitializer(mkLit(site, 'bytes',
- TInt(64, False))))))
+ size2.write(c.ExpressionInitializer(mkLit(site, 'bytes',
+ tp.Int(64, False))))))
if partial:
if bigendian:
lines.extend([
@@ -247,8 +245,8 @@ def dim_sort_key(data):
regvar, indices, memop.read(), bytepos_args),
' if (ret) return true;',
' %s;' % (
- value2.write(ExpressionInitializer(
- mkLit(site, 'val', TInt(64, False))))),
+ value2.write(c.ExpressionInitializer(
+ mkLit(site, 'val', tp.Int(64, False))))),
' return false;'])
else:
# Shifting/masking can normally be skipped in banks with
@@ -274,8 +272,8 @@ def dim_sort_key(data):
' if (offset >= %s[last].offset' % (regvar,)
+ ' && offset < %s[last].offset + %s[last].size) {'
% (regvar, regvar),
- ' %s;' % (size2.write(ExpressionInitializer(
- mkIntegerLiteral(site, 0))),),
+ ' %s;' % (size2.write(c.ExpressionInitializer(
+ c.mkIntegerLiteral(site, 0))),),
' return false;',
' }'])
lines.extend([
@@ -284,14 +282,14 @@ def dim_sort_key(data):
'}'])
scope = Symtab(global_scope)
- code = [mkInline(site, line) for line in lines]
+ code = [c.mkInline(site, line) for line in lines]
check_unmapped_access_handling(bank, isread)
- with ReturnFailure(site):
+ with codegen.ReturnFailure(site):
code.append(unmapped_access(site, bank, bank_indices, scope, isread,
overlapping, bigendian, memop,
offset, size, writevalue, size2, value2))
- return mkCompound(
+ return c.mkCompound(
site, declarations(scope) + code)
def codegen_write_access(bank, idx, inargs, outargs, site):
diff --git a/py/dml/logging.py b/py/dml/logging.py
index 98cc90979..923eb3847 100644
--- a/py/dml/logging.py
+++ b/py/dml/logging.py
@@ -8,7 +8,6 @@
'ICE',
'show_porting',
- 'is_warning_tag',
'ignore_warning',
'warning_is_ignored',
'enable_warning',
@@ -26,6 +25,9 @@
'InEachSite',
'dbg',
+
+ 'truncate',
+ 'binary_dump',
)
import sys
@@ -50,11 +52,6 @@ def set_include_tag(val):
global include_tag
include_tag = val
-def is_warning_tag(tag):
- from . import messages
- cls = getattr(messages, tag, None)
- return isinstance(cls, type) and issubclass(cls, DMLWarning)
-
# A set of ignored warnings
ignored_warnings = {}
def ignore_warning(tag):
@@ -119,6 +116,8 @@ class LogMessage(object):
outfile = sys.stderr
+ tag_prefix = ''
+
def __init__(self, site, *msgargs):
# The site is the place in the source that this log message
# refers to.
@@ -156,8 +155,9 @@ def print_site_message(self, site, msg):
if os.getenv('DMLC_DEBUG'):
raise
- def tag(self):
- return self.__class__.__name__
+ @classmethod
+ def tag(cls):
+ return cls.tag_prefix + cls.__name__
def preprocess(self):
'''Call before log when reporting. Return True to actually log
@@ -214,6 +214,7 @@ def __init__(self, site, msg):
# This is a base class for warning messages
#
class DMLWarning(LogMessage):
+ tag_prefix = 'W'
kind = "warning"
next_warning_yields_error = False
@@ -239,6 +240,7 @@ def postprocess(self):
# This is a base class for error messages
#
class DMLError(Exception, LogMessage):
+ tag_prefix = 'E'
kind = "error"
def __init__(self, site, *msgargs):
@@ -250,6 +252,7 @@ def postprocess(self):
report_error()
class PortingMessage(LogMessage):
+ tag_prefix = 'P'
kind = 'porting'
fmt = ''
@@ -487,3 +490,17 @@ def suppress_errors():
store_errors.append(e)
finally:
store_errors = orig
+
+def truncate(s, maxlen):
+ "Make sure that s is not longer than maxlen"
+ if len(s) > maxlen:
+ return s[:maxlen-3] + '...'
+ return s
+
+def binary_dump(lh, rh):
+ """Produce a string to use in warning and error messages describing
+ operands to a binary operation"""
+ return ("LH: '%s' of type '%s'\n"
+ "RH: '%s' of type '%s'"
+ % (truncate(str(lh), 40), lh.ctype(),
+ truncate(str(rh), 40), rh.ctype()))
diff --git a/py/dml/objects.py b/py/dml/objects.py
index 3ac5fc089..d82bb6563 100644
--- a/py/dml/objects.py
+++ b/py/dml/objects.py
@@ -5,7 +5,7 @@
import abc
import contextlib
-from .logging import dollar
+from . import logging
from .set import Set
import dml.globals
@@ -268,7 +268,7 @@ def logname(self, indices=(), relative='device'):
if self.isindexed():
suff = "".join('[%s]' % i for i in
indices[-self.local_dimensions():])
- suff += "".join(f'[{dollar(self.site)}'
+ suff += "".join(f'[{logging.dollar(self.site)}'
+ f'{"_" if idxvar is None else idxvar}]'
for idxvar in self._idxvars[len(indices):])
indices = indices[:-self.local_dimensions()]
@@ -296,7 +296,7 @@ def identity(self, indices=(), relative='device'):
if self.isindexed():
suff = "".join('[%s]' % i for i in
indices[-self.local_dimensions():])
- suff += "".join(f'[{dollar(self.site)}'
+ suff += "".join(f'[{logging.dollar(self.site)}'
+ f'{"_" if idxvar is None else idxvar} < {arrlen}]'
for (idxvar, arrlen) in
itertools.islice(
diff --git a/py/dml/output.py b/py/dml/output.py
index e58173700..4e93e0cab 100644
--- a/py/dml/output.py
+++ b/py/dml/output.py
@@ -6,7 +6,8 @@
from pathlib import Path
import dml.globals
-from .logging import ICE, SimpleSite
+from . import logging
+from .logging import ICE
__all__ = (
'NoOutput',
@@ -117,7 +118,7 @@ def close(self):
def commit(self):
if self.indent:
- raise ICE(SimpleSite(f"{self.filename}:0"), 'Unbalanced indent')
+ raise ICE(logging.SimpleSite(f"{self.filename}:0"), 'Unbalanced indent')
try:
os.remove(self.filename)
except OSError:
@@ -164,7 +165,7 @@ def quote_filename(filename):
def site_linemark_nocoverity(site, adjust=0):
if dml.globals.linemarks:
- if site is not None and not isinstance(site, SimpleSite):
+ if site is not None and not isinstance(site, logging.SimpleSite):
filename = site.filename()
lineno = site.lineno
if lineno + adjust < 0:
@@ -183,7 +184,7 @@ def coverity_marker(event, classification=None, site=None):
coverity_markers([(event, classification)], site)
def coverity_markers(markers, site=None):
- site_with_loc = site is not None and not isinstance(site, SimpleSite)
+ site_with_loc = site is not None and not isinstance(site, logging.SimpleSite)
if dml.globals.coverity and site_with_loc:
custom_markers = []
filename = site.filename()
diff --git a/py/dml/porting.py b/py/dml/porting.py
new file mode 100644
index 000000000..0429f5386
--- /dev/null
+++ b/py/dml/porting.py
@@ -0,0 +1,487 @@
+# © 2021 Intel Corporation
+# SPDX-License-Identifier: MPL-2.0
+
+from .logging import PortingMessage
+
+class SHA1(PortingMessage):
+ """The `port-dml` script requires that the DML file has not been
+ changed since the tag file was generated. This is verified by a
+ SHA1 checksum."""
+ fmt = 'SHA1 checksum of DML file'
+
+class VERSION(PortingMessage):
+ """DML 1.4 files should start with `dml 1.4;` instead
+ of `dml 1.2;`"""
+ fmt = "update version statement to 1.4"
+
+class NOTHROW(PortingMessage):
+ """In DML 1.4, it is assumed by default that a method may not throw an
+ exception. Any `nothrow` annotations must be removed."""
+ fmt = "remove nothrow annotation"
+
+class THROWS(PortingMessage):
+ """In DML 1.4, methods that can throw an exception must explicitly
+ declare that with a 'throws' annotation. Such annotation is
+ automatically added for methods that override a throwing method
+ that was declared in a DML 1.4 file."""
+ fmt = "add throws annotation"
+
+class INPARAMLIST(PortingMessage):
+ """If a method has no input arguments, the empty input parameter
+ list `()` is now required in method declarations
+ and `call`/`inline` statements."""
+ fmt = "add () after method"
+
+class STRUCTDECL(PortingMessage):
+ """Struct type definitions can no longer be declared using the
+ labeled struct syntax. The equivalent typedef declaration should
+ be used instead. For example, the following is now disallowed:
+
+
+ struct xyz { ... }
+
+
+ and should be replaced with the following:
+
+
+ typedef struct { ... } xyz;
+ """
+ fmt = "use typedef syntax for struct type declaration"
+
+class FIELDRANGE(PortingMessage):
+ """In a field declaration, the field range declaration must be
+ preceded by `@`. In DML 1.4, the syntax `field f[4]`
+ declares a field array of size 4, while in DML 1.2 it denotes a field
+ occupying bit 4 in its parent register."""
+ fmt = "insert @ before field range declaration"
+
+class INLINEDECL(PortingMessage):
+ """Methods with untyped parameters must be explicitly marked 'inline'
+ in DML 1.4, as in `inline method m(inline x) -> (int y)`"""
+ fmt = "add inline annotation to method with untyped parameters"
+
+class RETVAL(PortingMessage):
+ """Method output parameters are not named in DML 1.4:
+ ```
+ method m() -> (int, int) {
+ ...
+ }
+ ```
+
+ See also `PRETURNARGS`."""
+ fmt = "remove name from method output parameter"
+
+class RETVAL_END(PortingMessage):
+ """Methods with output arguments must end with an explicit return
+ statement in DML 1.4; in DML 1.2, the method would return whatever
+ value the output argument had upon exit. See also `PRETVAL`.
+ """
+ fmt = "add return statement to end of method"
+
+class RETURNARGS(PortingMessage):
+ """In methods with return values, return statements now take arguments:
+ ```
+ method m() -> (int, int) {
+ return (1, 4);
+ }
+ method n() -> (int) {
+ return 3;
+ }
+ ```"""
+ fmt = "add arguments to return statement"
+
+class OUTARGRETURN(PortingMessage):
+ """An assignment to an output argument directly followed by a
+ return statement is more concisely written as a single return
+ statement, without an intermediate assignment. For instance,
+ ```
+ dml 1.2;
+ method four() -> (int x) {
+ x = 4;
+ return;
+ }
+ ```
+ can be expressed as:
+ ```
+ dml 1.4;
+ method four() -> (int) {
+ return 4;
+ }
+ ```
+ """
+ fmt = "merge outarg assignment with return statement"
+
+class TYPEDOUTPARAM(PortingMessage):
+ """Method output parameters must have explicit types in DML 1.4. The
+ automatic conversion script will convert untyped output parameters
+ to `uint64`."""
+ fmt = "declare explicit type for output parameter"
+
+class INARGTYPE(PortingMessage):
+ """When overriding a method in DML 1.4, the overriding and default
+ implementation must declare the same arguments as `inline`.
+ If the override has untyped arguments that are typed in the default
+ method, then the conversion script will add a type to the override's
+ argument.
+
+ Note: The inserted type declaration uses C syntax, which in most
+ cases matches DML syntax; however, there are exceptions where the
+ inserted declaration will be broken and needs to be fixed manually.
+ """
+ fmt = ""
+
+class INVOKE(PortingMessage):
+ """Method invocation syntax changed. Replace
+
+ ```
+ call m(x) -> (a, b);
+ inline n() -> (c);
+ call o();
+ ```
+ with:
+ ```
+ (a, b) = m(x);
+ c = n();
+ o();
+ ```"""
+ fmt = "Use assignment syntax for method invocation"
+
+class LOGKIND(PortingMessage):
+ """In log statements, the old syntax where log type is denoted by a string
+ has been removed. Use the new identifier-based syntax instead. E.g.,
+ instead of:
+ ```
+ log "info": "foo";
+ log "spec_violation": "foo";
+ ```
+ you must now write:
+ ```
+ log info: "foo";
+ log spec_viol: "foo";
+ ```
+"""
+ fmt = "Don't use string literal syntax for log type"
+
+class AFTER(PortingMessage):
+ """The syntax of `after` statements changed: The delay should
+ be followed by `s` to denote time unit; furthermore, the
+ `call` keyword should no longer be used, and brackets
+ around the delay are optional. Example:
+ ```
+ after (1.3) call send_frame(); // DML 1.2 syntax
+ after 1.3 s: send_frame(); // DML 1.4 syntax
+ ```"""
+ fmt = "Remove 'call' and add 's' in 'after' statement"
+
+class AUTO(PortingMessage):
+ """The `auto` keyword is deprecated; use the equivalent
+ `local` instead."""
+ fmt = "replace 'auto' with 'local'"
+
+class SESSION(PortingMessage):
+ """The `data` and `static` keywords have both been replaced
+ with `session`:
+ ```
+ session uint32 x;
+ ```"""
+ fmt = "replace 'data' and 'static' with 'session'"
+
+class HARD_RESET_VALUE(PortingMessage):
+ """The `hard_reset_value` parameter is no longer
+ recognized. The parameter is automatically renamed to
+ `init_val`, which has roughly the same effect."""
+ fmt = "change hard_reset_value to init_val"
+
+class SOFT_RESET_VALUE(PortingMessage):
+ """The `soft_reset_value` parameter is renamed to
+ `soft_reset_val`, and requires the template
+ `soft_reset_val` to be instantiated."""
+ fmt = "change soft_reset_value to soft_reset_val"
+
+class MISS_PATTERN(PortingMessage):
+ """The `miss_pattern` parameter is no longer recognized by
+ banks, unless the `miss_pattern_bank` template, from utility.dml, is
+ instantiated. An instantiation is automatically added."""
+ fmt = "instantiate miss_pattern_bank to use the miss_pattern parameter"
+
+class ATTRIBUTE(PortingMessage):
+ """The `allocate_type` parameter is no longer valid for attributes.
+ Integer, boolean and floating-point attributes instead use
+ standard templates such as `uint64_attr`, `int64_attr`, `bool_attr` and
+ `double_attr`.
+
+ The porting rule will remove `allocate_type`, together with an
+ explicit type parameter if present. All integer types will be
+ changed to 64-bit types. Attributes with `allocate_type="string"`
+ have to be manually rewritten.
+ """
+ fmt = "use uint64_attr template instead of allocate_type parameter"
+
+class EVENT(PortingMessage):
+ """Event objects no longer have the `timebase` parameter;
+ instead you must choose a standard template to instantiate. The
+ conversion script will pick `custom_time_event`,
+ `custom_cycle_event`, `simple_time_event`, or `simple_cycle_event`.
+ """
+
+class EVENT_NO_ARG(PortingMessage):
+ """When `PEVENT` converts an event to `simple_time_event` or
+ `simple_cycle_event`, the `data` function argument to methods
+ `post`, `posted`, `next` and `remove` are removed.
+ """
+
+class EVENT_UINT64_ARG(PortingMessage):
+ """When one of the methods `post`, `posted`, `next` and `remove`
+ is called with an integer value cast to a pointer in the `data`
+ arg, that event is converted to a `uint64_time_event` or
+ `uint64_cycle_event`. The converter removes the cast and
+ causes the event object to be converted to a
+ `uint64_time_event` instead of `uint64_custom_event`.
+ """
+
+class EVENT_REMOVE_INFO(PortingMessage):
+ """When an event is converted to a `uint64_time_event` or
+ `uint64_cycle_event`, the `set_event_info` and `get_event_info` methods
+ are removed.
+ """
+
+class OVERRIDE(PortingMessage):
+ """If a method has exactly one default and one non-default
+ declaration, and the non-default declaration resides in a
+ template, then DML 1.4 requires that this template inherits from
+ the template containing the default declaration. Conversion is done
+ automatically for the most common case."""
+ fmt = "template with method override must instantiate overridden template"
+
+class OVERRIDE_IMPORT(PortingMessage):
+ """Similar to POVERRIDE, but if a default method does _not_
+ reside in a template, then the file that instantiates the non-default
+ declaration must import the file containing the default declaration."""
+ fmt = "template with method override must import overridden file"
+
+# TODO: convert
+
+class BEFAFT(PortingMessage):
+ """In objects of type attribute, register and connect, before/after
+ methods (e.g. `before_write`, `after_read`,
+ `after_set`), are no longer called. They are transformed
+ into an override of the corresponding base function
+ (`write_register`, `read_register`, `set`).
+ Note that when a before/after method is implemented by a template,
+ then an additional `is register` declaration may be needed in
+ 1.4; this is not automatically added.
+ """
+ fmt = "before / after method no longer called, override base method instead"
+
+class ABSTRACT_TEMPLATE(PortingMessage):
+ """When implementing methods `read` or `write` in a
+ field or register, or `hard_reset` or
+ `soft_reset` in a bank, or `get`, `set`,
+ `read_field`, `write_field` in a field, then this will
+ have no effect unless a template named like the method is instantiated. The
+ automatic converter will add e.g. `is read;` before an
+ implementation of `read`."""
+ fmt = ("method has no effect unless corresponding abstract template is"
+ + " instantiated")
+
+class TRAMPOLINE(PortingMessage):
+ """The methods `miss_read_access` and
+ `miss_write_access` in `bank` objects have been
+ renamed to `unmapped_read` and `unmapped_write`
+ in 1.4. The converter creates methods with the new names, which
+ call the existing unmodified methods."""
+ fmt = "method has been renamed in 1.4, will insert trampoline method"
+
+class IMPORT_DML12COMPAT(PortingMessage):
+ """The `PTRAMPOLINE` porting rule sometimes requires
+ that `dml12-compatibility.dml` is imported."""
+ fmt = ''
+
+class CHANGE_INARGS(PortingMessage):
+ """Many overridable methods in the standard library have changed, and
+ method overrides must be changed accordingly. A method in 1.2
+ usually has a counterpart in 1.4, but its semantics may have
+ changed slightly and quite often the set of arguments has changed
+ as well. The automatic converter will adjust the names and
+ signatures of a number of methods. Invocations, including
+ `default()`, are not updated and must be manually converted
+ (compile errors). Some method arguments are removed by the
+ converter; if these arguments are used, the implementation must be
+ modified accordingly. In particular, the `memop` arg of
+ various bank and register methods is no longer present. This has
+ been replaced with an argument `void *aux`, which is
+ normally NULL. If some register in a bank needs a memop, then the
+ `io_memory_access` method can be updated to pass down the
+ memop in the `aux` argument (just call `default`
+ with `memop` in the last arg). An explicit call to a bank
+ method, e.g. a redirection of an access to a different bank,
+ should normally be rewritten as a call to `read` or
+ `write`, usually with NULL in the `aux`
+ argument.
+
+ Bank methods are converted as follows: `access` →
+ `io_memory_access`; `read_access`,
+ `read_access_memop` → `read`;
+ `write_access`, `write_access_memop` →
+ `write`
+
+ Register methods are converted like so: `read_access`
+ → `read_register`, `write_access` →
+ `write_register`
+
+ Field methods are converted thusly: `read_access`
+ → `read_field`, `write_access` →
+ `write_field`
+
+ In `register` and `field` objects, the
+ `set` and
+ `write_register`/`write_field` methods will get
+ an explicit type `uint64`.
+
+ The read and write methods on `bank`, `register`,
+ and `field` objects all take a new `uint64` argument
+ denoting enabled bytes or bits, depending on the context, which
+ may mask an access.
+
+ In `connect` objects, `validate_port` is converted
+ to `validate`; named ports are deprecated in Simics 6, but
+ the port name is available in the `port` session variable.
+
+ In `attribute` objects, the `set` method will get
+ an explicit argument type `attr_value_t`, and a
+ `throws` annotation.
+ """
+ fmt = "override of library method with new name or signature"
+
+class BITNEQ(PortingMessage):
+ """DML 1.2 permits using 1-bit fields as boolean values. In DML 1.4,
+ field values are 64 bit, and thus require an explicit `!= 0`"""
+ fmt = ""
+
+class VAL(PortingMessage):
+ """The value of a `register`, `field` or `attribute`
+ object, and the interface struct of a `interface` object, is now
+ accessed through the `.val` member."""
+ fmt = "use .val member to access register/attribute value"
+
+class NODOLLAR(PortingMessage):
+ """The `$` character is no longer needed when referencing objects."""
+ fmt = "remove $"
+
+class DOLLAR_QUALIFY(PortingMessage):
+ """In DML 1.4, there is no separate scope for `$`, so local
+ variables can shadow object references. This conversion rule
+ attempts to detect this, and add `this.` or
+ dev.path. where needed."""
+ fmt = "use qualified object reference to escape shadowing"
+
+class CONSTANT(PortingMessage):
+ """`constant` declarations are removed in 1.4 and should be
+ replaced with `param` declarations. Both are accessible
+ from the top-level scope of a device."""
+ fmt = "change 'constant' to 'param'"
+
+class PARAMETER(PortingMessage):
+ """The `parameter` keyword has been renamed to `param`."""
+ fmt = "change 'parameter' to 'param'"
+
+class ARRAY_I(PortingMessage):
+ """The syntax for object arrays has changed: Instead of
+ `register r[12]`, you write `register r[i < 12]`"""
+ fmt = "explicit index in object array declaration"
+
+class ARRAY(PortingMessage):
+ """The syntax for object arrays has changed: Instead of
+ `register r[j in 0..size - 1]`, you write
+ `register r[j < size]`"""
+ fmt = "'<' replaces 'in 0..' in object array declaration"
+
+class HASH(PortingMessage):
+ """`if` statements on top level must be prefixed with a `#`
+ character. The same applies to `if` statement inside a method body
+ if the condition is constant and the dead branch contains errors.
+
+ Similarly, the conditional operator (`? :`) is updated to #? #:
+ when needed, `select` is updated to `#select`, and
+ `foreach` is updated to `#foreach`."""
+ fmt = "insert '#' before 'if'"
+
+class HASHELSE(PortingMessage):
+ """If an `if` is updated to `#if`, and there is a
+ corresponding `else` clause, then it must be updated to
+ `#else`. The same applies to the `else` clause in
+ `select` statements."""
+ fmt = "insert '#' before 'else'"
+
+class ANDOR(PortingMessage):
+ """DML 1.2 permits the right operand of an `&&` or
+ `||` expression to contain errors, as long as the left
+ operand evaluates to a constant that makes the right operand
+ dead. DML 1.4 does not permit this, so the expression `A
+ && B` must be converted to `A #? B #: false`.
+ One common use case is expressions like
+ `(defined X && X.y == ...)`.
+ """
+ fmt = ''
+
+class IFAND(PortingMessage):
+ """If statements on the form `if (defined(X) && X.y) { ... }`
+ are converted to a nested `#if` statement"""
+ fmt = ''
+
+class STRINGIFY(PortingMessage):
+ """In DML 1.4, `#` is changed to the
+ `stringify` operator"""
+ fmt = "Replace '#(X)' with 'stringify(X)' operator"
+
+class WUNUSED(PortingMessage):
+ """This message is used to signal to the porting script that a piece
+ of conditional code was not fully covered by the compile. Some
+ portings are never applied on dead code. The porting script
+ can signal a warning for this."""
+ fmt = ""
+ typed_methods = set()
+ # site -> objects.Method
+ inline_methods = {}
+ inlined_methods = set()
+ positive_conds = set()
+ negative_conds = set()
+ satisfied_conds = set()
+ used_templates = set()
+
+class NO_WUNUSED(PortingMessage):
+ """Used in conjunction with PWUNUSED to signal that a piece of
+ conditional code was indeed used. If using multiple runs of DMLC
+ as input to the porting script, and a piece of code was used in
+ some runs and unused in others, then no warning is shown.
+ """
+ fmt = ""
+
+class RENAME_TEMPLATE(PortingMessage):
+ """Some templates in `utility.dml` have been renamed; in
+ particular, `unimplemented` has been renamed to
+ `unimpl`.
+ """
+ fmt = ""
+
+class UNDEFOFFS(PortingMessage):
+ """`undefined` is no longer a valid offset for registers; `unmapped_offset`
+ should be used instead.
+ """
+ fmt = "Use 'unmapped_offset' instead of 'undefined'"
+
+class INT1(PortingMessage):
+ """Integer types have different semantics in DML 1.2 and DML 1.4;
+ the `int1` type in DML 1.2 is converted to `uint1` in DML 1.4
+ because that is a better match for some common operations. In
+ particular, if the value 1 is assigned to variables of these
+ types, then the value of the variable becomes 1, whereas for
+ `int1` in DML 1.4 the value is -1."""
+ fmt = "Change int1 to uint1"
+
+
+all_portings = {
+ o.tag(): o for o in globals().values()
+ if isinstance(o, type)
+ and issubclass(o, PortingMessage)
+ and o is not PortingMessage}
diff --git a/py/dml/provisional.py b/py/dml/provisional.py
index c7c3c5e77..b40554be2 100644
--- a/py/dml/provisional.py
+++ b/py/dml/provisional.py
@@ -3,7 +3,8 @@
import abc
from . import logging
-from . import messages
+from .logging import Site
+from . import errors as E
class ProvisionalFeature(abc.ABC):
def tag(self) -> str:
@@ -214,6 +215,6 @@ def parse_provisional(
if name in features:
ret[features[name]] = site
else:
- logging.report(messages.ENOPROV(
+ logging.report(E.NOPROV(
site, name, ', '.join(sorted(features))))
return ret
diff --git a/py/dml/reginfo.py b/py/dml/reginfo.py
index a9b469cf2..23ac61c58 100644
--- a/py/dml/reginfo.py
+++ b/py/dml/reginfo.py
@@ -1,16 +1,17 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-from collections import namedtuple
import operator
import itertools
from functools import reduce
import dml.globals
-from . import logging
-from .ctree import *
-from .logging import *
-from .messages import *
-from .expr_util import *
+from . import expr_util, logging
+from . import ctree as c
+from . import porting as P
+from .logging import report, DMLError
+from . import errors as E, warnings as W
+from .expr_util import (
+ defined, param_expr, param_expr_site, param_int, static_indices)
__all__ = ('explode_registers',)
@@ -54,8 +55,8 @@ def node_instances(self):
# r1 is a two-dimensional register array, but the partition only
# contains r1[3][1] and r1[4][5]. Can happen if register offset
# is undefined for some, but not all, indices.
- [(r1, (mkIntegerLiteral(3), mkIntegerLiteral(1)), ()),
- (r1, (mkIntegerLiteral(4), mkIntegerLiteral(5)), ())]
+ [(r1, (c.mkIntegerLiteral(3), c.mkIntegerLiteral(1)), ()),
+ (r1, (c.mkIntegerLiteral(4), c.mkIntegerLiteral(5)), ())]
# r2 is a two-dimensional register array, and the partition contains
# all 6 instances
[(r2, (), (3, 2))]
@@ -64,7 +65,7 @@ def node_instances(self):
node.dimensions == bank.dimensions + len(indices) + len(dimsizes).
'''
if self.dimsizes is None:
- return ((self.node, tuple(mkIntegerLiteral(self.node.site, i)
+ return ((self.node, tuple(c.mkIntegerLiteral(self.node.site, i)
for i in instance.coord), ())
for instance in self.layout)
else:
@@ -120,11 +121,11 @@ def explode_register(node):
indices = static_indices(node, param_expr_site(node, 'offset'))
offset = param_expr(node, 'offset', indices)
if offset.undefined:
- report(PUNDEFOFFS(offset.site))
- except EIDXVAR:
+ report(P.UNDEFOFFS(offset.site))
+ except E.IDXVAR:
pass
for indices in itertools.product(*(
- (mkIntegerLiteral(node.site, idx) for idx in range(dimsize))
+ (c.mkIntegerLiteral(node.site, idx) for idx in range(dimsize))
for dimsize in dimsizes)):
coord = tuple(i.value for i in indices)
roffset, rsize, regnum = one_register(node, indices, n)
@@ -158,9 +159,9 @@ def one_register(node, indices, bank):
try:
if dml.globals.dml_version == (1, 2):
roffset = param_expr(node, 'offset', bank_indices + indices)
- roffset = expr_intval(roffset) if defined(roffset) else None
+ roffset = expr_util.expr_intval(roffset) if defined(roffset) else None
regnum = param_expr(node, 'regnum', bank_indices + indices)
- regnum = expr_intval(regnum) if defined(regnum) else None
+ regnum = expr_util.expr_intval(regnum) if defined(regnum) else None
else:
roffset = param_int(node, 'offset', indices=bank_indices + indices)
# in 1.4, we use the magic constant unmapped_offset to denote
@@ -174,7 +175,7 @@ def one_register(node, indices, bank):
# roffset is undefined for unmapped registers
if roffset and roffset < 0:
- report(WNEGOFFS(param_expr_site(node, 'offset'), roffset))
+ report(W.NEGOFFS(param_expr_site(node, 'offset'), roffset))
roffset &= 0xffffffffffffffff
return (roffset, rsize, regnum)
@@ -190,7 +191,7 @@ def check_overlap(regs):
[[node1], [node2]] = [
[reg.node for reg in regs if ri in reg.layout]
for ri in [ri1, ri2]]
- report(EREGOL(node1, node2, ri1.coord, ri2.coord))
+ report(E.REGOL(node1, node2, ri1.coord, ri2.coord))
def explode_registers(bank):
"""Expand all registers of a bank, and calculate the offsets of every
diff --git a/py/dml/reginfo_test.py b/py/dml/reginfo_test.py
index 3ea6b8d84..12f45a4de 100644
--- a/py/dml/reginfo_test.py
+++ b/py/dml/reginfo_test.py
@@ -2,10 +2,9 @@
# SPDX-License-Identifier: MPL-2.0
import unittest
-import operator
import itertools
-from dml.reginfo import RegInstance, RegInfo, explode_register
+from dml.reginfo import RegInstance, RegInfo
from dml.objects import Device, Bank, Group, Register
class TestRegInfo(unittest.TestCase):
diff --git a/py/dml/serialize.py b/py/dml/serialize.py
index 4742a83d9..416501671 100644
--- a/py/dml/serialize.py
+++ b/py/dml/serialize.py
@@ -4,11 +4,11 @@
# This module contains the functions used to generate methods to convert between
# dml values and attribute values
-from . import ctree, expr, types, logging, symtab, messages, output, logging
+from . import ctree, expr, logging, symtab, errors as E, output
from . import objects
-from .types import *
-from .logging import *
-from .expr_util import *
+from . import types as tp
+from .logging import ICE
+from .expr_util import expr_intval
from .set import Set
import dml.globals
@@ -20,14 +20,14 @@
'lookup_deserialize',
)
-attr_value_t = TNamed('attr_value_t')
-set_error_t = TNamed('set_error_t')
-uint64_t = TInt(64, False)
-const_void = void.clone()
+attr_value_t = tp.Named('attr_value_t')
+set_error_t = tp.Named('set_error_t')
+uint64_t = tp.Int(64, False)
+const_void = tp.void.clone()
const_void.const = True
-serializer_t = TFunction([TPtr(const_void), TPtr(void)], attr_value_t)
-deserializer_t = TFunction([attr_value_t, TPtr(void), TPtr(void)],
+serializer_t = tp.Function([tp.Ptr(const_void), tp.Ptr(tp.void)], attr_value_t)
+deserializer_t = tp.Function([attr_value_t, tp.Ptr(tp.void), tp.Ptr(tp.void)],
set_error_t)
# code to insert before body
@@ -49,7 +49,7 @@ def add(self, trait):
# used to convert dmltype to attr_value_t
serialize_function_list = []
def lookup_serialize(lookup_t):
- lookup_t = safe_realtype(lookup_t)
+ lookup_t = tp.safe_realtype(lookup_t)
descriptor = type_signature(lookup_t, True)
for (t, f) in serialize_function_list:
# we will consider two types equal if they would get the same
@@ -63,7 +63,7 @@ def lookup_serialize(lookup_t):
# list of tuples (dmltype, mapping fun), used to convert attr_value_t to dmltype
deserialize_function_list = []
def lookup_deserialize(lookup_t):
- lookup_t = safe_realtype(lookup_t)
+ lookup_t = tp.safe_realtype(lookup_t)
descriptor = type_signature(lookup_t, False)
for (t, f) in deserialize_function_list:
# we will consider two types equal if they would get the same
@@ -85,49 +85,41 @@ def declare_variable(site, name, type, init_expr = None):
site, symtab.LocalSymbol(name, name, type, site=site)))
def prepare_array_de_serialization(site, t):
- assert(isinstance(t, TArray))
+ assert(isinstance(t, tp.Array))
dims = []
base = t
- while isinstance(base, TArray):
+ while isinstance(base, tp.Array):
dims.append(base.size)
base = base.base
sizeof_base = expr.mkLit(site, f"sizeof({base.declaration('')})",
- TNamed('size_t'))
+ tp.Named('size_t'))
dimsizes_lit = ('(const uint32 []) { %s }'
% ((', '.join(dim.read() for dim in dims)),))
- dimsizes_expr = expr.mkLit(site, dimsizes_lit, TPtr(TInt(32, False)))
+ dimsizes_expr = expr.mkLit(site, dimsizes_lit, tp.Ptr(tp.Int(32, False)))
return (base, dims, sizeof_base, dimsizes_expr)
def mkSubRefLit(site, expr, sub, typ, op):
- real_etype = safe_realtype_shallow(expr.ctype())
+ real_etype = tp.safe_realtype_shallow(expr.ctype())
- if isinstance(real_etype, TPtr):
- if op == '.':
- raise ENOSTRUCT(site, expr)
- basetype = real_etype.base
- real_basetype = safe_realtype(basetype)
- else:
- if op == '->':
- raise ENOPTR(site, expr)
- real_basetype = safe_realtype(etype)
-
- real_basetype = real_basetype.resolve()
+ assert isinstance(real_etype, tp.Ptr), (site, expr)
+ assert op == '->', (site, expr)
+ real_basetype = tp.safe_realtype(real_etype.base).resolve()
return ctree.StructMember(site, expr, sub,
- conv_const(real_basetype.const, typ), op)
+ tp.conv_const(real_basetype.const, typ), op)
# This works on the assumption that args do not need to be hard-cast
# to fit the actual fun signature
def apply_c_fun(site, fun, args, rettype):
- function_type = TFunction([a.ctype() for a in args], rettype)
+ function_type = tp.Function([a.ctype() for a in args], rettype)
lit = expr.mkLit(site, fun, function_type)
return expr.mkApply(site, lit, args)
def call_c_fun(site, fun, args):
return ctree.mkExpressionStatement(
- site, apply_c_fun(site, fun, args, void))
+ site, apply_c_fun(site, fun, args, tp.void))
# serialize current_expr, interpreted as real_type, and assign
# to target_expr
@@ -145,7 +137,7 @@ def construct_assign_apply(funname, intype):
funname = "SIM_make_attr_uint64"
if real_type.is_endian:
converted_arg = ctree.as_int(current_expr)
- function_type = TFunction([converted_arg.ctype], attr_value_t)
+ function_type = tp.Function([converted_arg.ctype], attr_value_t)
apply_expr = expr.Apply(current_site,
expr.mkLit(current_site,
funname,
@@ -159,11 +151,11 @@ def construct_assign_apply(funname, intype):
apply_expr))])
else:
return construct_assign_apply(funname, real_type)
- elif isinstance(real_type, TBool):
+ elif isinstance(real_type, tp.Bool):
return construct_assign_apply("SIM_make_attr_boolean", real_type)
- elif isinstance(real_type, TFloat):
+ elif isinstance(real_type, tp.Float):
return construct_assign_apply("SIM_make_attr_floating", real_type)
- elif isinstance(real_type, TArray):
+ elif isinstance(real_type, tp.Array):
(base, dimsizes, sizeof_base,
dimsizes_expr) = prepare_array_de_serialization(current_site,
real_type)
@@ -175,7 +167,7 @@ def construct_assign_apply(funname, intype):
else lookup_serialize(base))
elem_serializer = expr.mkLit(current_site, serializer_ptr,
- TPtr(serializer_t))
+ tp.Ptr(serializer_t))
apply_expr = apply_c_fun(current_site, '_serialize_array',
[ctree.mkAddressOf(current_site,
current_expr),
@@ -187,26 +179,26 @@ def construct_assign_apply(funname, intype):
return ctree.AssignStatement(current_site, target_expr,
ctree.ExpressionInitializer(apply_expr))
- elif isinstance(real_type, (TStruct, TVector)):
+ elif isinstance(real_type, (tp.Struct, tp.Vector)):
apply_expr = apply_c_fun(
current_site, lookup_serialize(real_type),
[ctree.mkAddressOf(current_site, current_expr)], attr_value_t)
return ctree.AssignStatement(current_site, target_expr,
ctree.ExpressionInitializer(apply_expr))
- elif isinstance(real_type, TTrait):
+ elif isinstance(real_type, tp.Trait):
id_infos = expr.mkLit(current_site, '_id_infos',
- TPtr(TNamed('_id_info_t', const = True)))
+ tp.Ptr(tp.Named('_id_info_t', const = True)))
identity_expr = ctree.StructMember(current_site, current_expr, "id",
- TNamed("_identity_t"), ".")
+ tp.Named("_identity_t"), ".")
apply_expr = apply_c_fun(current_site, "_serialize_identity",
[id_infos, identity_expr], attr_value_t)
return ctree.AssignStatement(current_site, target_expr,
ctree.ExpressionInitializer(apply_expr))
- elif isinstance(real_type, THook):
+ elif isinstance(real_type, tp.Hook):
id_infos = expr.mkLit(current_site,
'_hook_id_infos' if objects.Device.hooks
else 'NULL',
- TPtr(TNamed('_id_info_t', const = True)))
+ tp.Ptr(tp.Named('_id_info_t', const = True)))
apply_expr = apply_c_fun(current_site, "_serialize_identity",
[id_infos, current_expr], attr_value_t)
return ctree.AssignStatement(current_site, target_expr,
@@ -224,23 +216,23 @@ def deserialize(real_type, current_expr, target_expr, error_out):
current_site = current_expr.site
def construct_assign_apply(attr_typ, intype, mod_apply_expr=lambda x: x):
check_expr = apply_c_fun(current_site, 'SIM_attr_is_' + attr_typ,
- [current_expr], TBool())
+ [current_expr], tp.Bool())
apply_expr = mod_apply_expr(apply_c_fun(current_site,
'SIM_attr_' + attr_typ,
[current_expr], intype))
error_stmts = error_out('Sim_Set_Illegal_Type', 'expected ' + attr_typ)
target = target_expr
- if real_type.const and not realtype(target_expr.ctype()).const:
+ if real_type.const and not tp.realtype(target_expr.ctype()).const:
# This can happen if constness is inherited from a parent
# deserialization of a struct type.
# Rewrite target_expr to an equivalent lvalue with constified type,
- # so that ExpressionInitializer's deep_const logic kicks in.
+ # so that ExpressionInitializer's tp.deep_const logic kicks in.
target = ctree.mkDereference(
current_site,
ctree.mkCast(current_site,
ctree.mkAddressOf(current_site, target_expr),
- TPtr(real_type)))
+ tp.Ptr(real_type)))
return ctree.mkIf(current_site,
check_expr,
@@ -251,8 +243,8 @@ def construct_assign_apply(attr_typ, intype, mod_apply_expr=lambda x: x):
def addressof_target_unconst():
base = ctree.mkAddressOf(current_site, target_expr)
- if deep_const(real_type):
- base = ctree.mkCast(current_site, base, TPtr(void))
+ if tp.deep_const(real_type):
+ base = ctree.mkCast(current_site, base, tp.Ptr(tp.void))
return base
def construct_subcall(apply_expr):
@@ -263,7 +255,7 @@ def construct_subcall(apply_expr):
ctree.ExpressionInitializer(apply_expr))
check_expr = ctree.mkLit(current_site,
f'{sub_success_arg.read()} != Sim_Set_Ok',
- TBool())
+ tp.Bool())
return ctree.mkCompound(current_site,
[sub_success_decl, assign_stmt,
ctree.mkIf(current_site, check_expr,
@@ -279,18 +271,18 @@ def mod_apply_expr(expr):
else:
def mod_apply_expr(expr):
return expr
- return construct_assign_apply("integer", TInt(64, True),
+ return construct_assign_apply("integer", tp.Int(64, True),
mod_apply_expr)
- elif isinstance(real_type, TBool):
+ elif isinstance(real_type, tp.Bool):
return construct_assign_apply("boolean", real_type)
- elif isinstance(real_type, TFloat):
+ elif isinstance(real_type, tp.Float):
return construct_assign_apply("floating", real_type)
- elif isinstance(real_type, TArray):
+ elif isinstance(real_type, tp.Array):
(base, dimsizes, sizeof_base,
dimsizes_expr) = prepare_array_de_serialization(current_site,
real_type)
elem_deserializer = expr.mkLit(current_site, lookup_deserialize(base),
- TPtr(deserializer_t))
+ tp.Ptr(deserializer_t))
# elems_are_bytes informs if the final dimension may either be
# deserialized as a list or a data attribute value.
# This is true for all integer types of width 8 bits
@@ -303,19 +295,19 @@ def mod_apply_expr(expr):
ctree.mkIntegerLiteral(current_site, len(dimsizes)),
elem_deserializer, elems_are_bytes], set_error_t)
return construct_subcall(apply_expr)
- elif isinstance(real_type, (TStruct, TVector)):
+ elif isinstance(real_type, (tp.Struct, tp.Vector)):
apply_expr = apply_c_fun(
current_site, lookup_deserialize(real_type),
[current_expr, addressof_target_unconst()],
set_error_t)
return construct_subcall(apply_expr)
- elif isinstance(real_type, TTrait):
+ elif isinstance(real_type, tp.Trait):
id_info_ht = expr.mkLit(current_site, '&_id_info_ht',
- TPtr(TNamed('ht_str_table_t')))
+ tp.Ptr(tp.Named('ht_str_table_t')))
assert dml.globals.object_trait
if real_type.trait is dml.globals.object_trait:
object_vtable_array = expr.mkLit(current_site, '_object_vtables',
- TPtr(TPtr(void, const=True)))
+ tp.Ptr(tp.Ptr(tp.void, const=True)))
apply_expr = apply_c_fun(
current_site, '_deserialize_object_trait_reference',
[id_info_ht, object_vtable_array,
@@ -325,8 +317,8 @@ def mod_apply_expr(expr):
vtable_name = real_type.trait.name
vtable_ht = expr.mkLit(current_site,
'NULL' if real_type.trait.empty()
- else f'&_{cident(vtable_name)}_vtable_ht',
- TPtr(TNamed('ht_int_table_t')))
+ else f'&_{tp.cident(vtable_name)}_vtable_ht',
+ tp.Ptr(tp.Named('ht_int_table_t')))
apply_expr = apply_c_fun(
current_site, '_deserialize_trait_reference',
[id_info_ht, vtable_ht,
@@ -334,15 +326,15 @@ def mod_apply_expr(expr):
current_expr, addressof_target_unconst()],
set_error_t)
return construct_subcall(apply_expr)
- elif isinstance(real_type, THook):
+ elif isinstance(real_type, tp.Hook):
id_info_ht = expr.mkLit(current_site,
'&_hook_id_info_ht'
if objects.Device.hooks else 'NULL',
- TPtr(TNamed('ht_str_table_t')))
+ tp.Ptr(tp.Named('ht_str_table_t')))
hook_aux_infos = expr.mkLit(current_site,
'_hook_aux_infos'
if objects.Device.hooks else 'NULL',
- TPtr(const_void))
+ tp.Ptr(const_void))
from .codegen import get_type_sequence_info
expected_typ_uniq = ctree.mkIntegerConstant(
current_site,
@@ -362,29 +354,29 @@ def mod_apply_expr(expr):
def map_dmltype_to_attrtype(site, dmltype):
"return attrtype string describing this dmltype"
# raw data instead
- real_type = safe_realtype(dmltype)
+ real_type = tp.safe_realtype(dmltype)
# tints, endian_ints, and their bitfield variants can all be safely
# stored in integer attributes
- if isinstance(real_type, IntegerType):
+ if isinstance(real_type, tp.IntegerType):
return 'i'
- if isinstance(real_type, TBool):
+ if isinstance(real_type, tp.Bool):
return 'b'
- if isinstance(real_type, TFloat):
+ if isinstance(real_type, tp.Float):
return 'f'
- if isinstance(real_type, TStruct):
+ if isinstance(real_type, tp.Struct):
return '[%s]' % "".join([map_dmltype_to_attrtype(site, mt)
for (_, mt) in real_type.members])
- if isinstance(real_type, TArray):
+ if isinstance(real_type, tp.Array):
assert real_type.size.constant
arr_attr_type = map_dmltype_to_attrtype(site, real_type.base)
arr_length = expr_intval(real_type.size)
# Byte arrays may use data values
or_data = '|d' * (real_type.base.is_int and real_type.base.bits == 8)
return '[%s{%s}]' % (arr_attr_type, arr_length) + or_data
- if isinstance(real_type, (TTrait, THook)):
+ if isinstance(real_type, (tp.Trait, tp.Hook)):
return '[s[i*]]'
# TODO should be implemented
- #if isinstance(real_type, TVector):
+ #if isinstance(real_type, tp.Vector):
# return '[%s*]' % (map_dmltype_to_attrtype(site, real_type.base))
raise ICE(site, 'unserializable type: %r' % (dmltype,))
@@ -392,23 +384,23 @@ def mark_for_serialization(site, dmltype):
'''check a dml type for serializability and ensure artifacts needed for
calls of serialize/deserialize to result in valid C are generated
'''
- real_type = safe_realtype(dmltype)
- if isinstance(real_type, TStruct):
+ real_type = tp.safe_realtype(dmltype)
+ if isinstance(real_type, tp.Struct):
for (_, mt) in real_type.members:
mark_for_serialization(site, mt)
- elif isinstance(real_type, TArray):
+ elif isinstance(real_type, tp.Array):
# Can only serialize constant-size arrays
if not real_type.size.constant:
- raise messages.ESERIALIZE(site, dmltype)
+ raise E.SERIALIZE(site, dmltype)
mark_for_serialization(site, real_type.base)
- elif isinstance(real_type, TTrait):
+ elif isinstance(real_type, tp.Trait):
dml.globals.serialized_traits.add(real_type.trait)
- elif isinstance(real_type, THook):
+ elif isinstance(real_type, tp.Hook):
real_type.validate(dmltype.declaration_site or site)
from .codegen import get_type_sequence_info
get_type_sequence_info(real_type.msg_types, create_new=True)
- elif not isinstance(real_type, (IntegerType, TBool, TFloat)):
- raise messages.ESERIALIZE(site, dmltype)
+ elif not isinstance(real_type, (tp.IntegerType, tp.Bool, tp.Float)):
+ raise E.SERIALIZE(site, dmltype)
# generate a part of the function name from a description of the dmltype
# Each type maps uniquely to a string, obeying the following invariants:
@@ -429,32 +421,32 @@ def mark_for_serialization(site, dmltype):
# deserialization case the signatures should be separate.
# Trait references are an example of such a type.
def type_signature(dmltype, is_for_serialization):
- dmltype = realtype(dmltype)
- if isinstance(dmltype, TLong):
+ dmltype = tp.realtype(dmltype)
+ if isinstance(dmltype, tp.Long):
return f'IL{"s" if dmltype.signed else "u"}'
- if isinstance(dmltype, TSize):
+ if isinstance(dmltype, tp.Size):
return f'IS{"s" if dmltype.signed else "u"}'
- if isinstance(dmltype, IntegerType):
+ if isinstance(dmltype, tp.IntegerType):
return 'I%d%s%s' % (dmltype.bits,
dmltype.byte_order[0] if dmltype.is_endian else "h",
"s" if dmltype.signed else "u")
- if isinstance(dmltype, TBool):
+ if isinstance(dmltype, tp.Bool):
return 'B'
- if isinstance(dmltype, TFloat):
+ if isinstance(dmltype, tp.Float):
return {'double': 'Fd', 'float': 'Fs'}[dmltype.name]
- if isinstance(dmltype, TStruct):
+ if isinstance(dmltype, tp.Struct):
return 'S' + dmltype.label
- if isinstance(dmltype, TArray):
+ if isinstance(dmltype, tp.Array):
assert dmltype.size.constant
arr_attr_type = type_signature(dmltype.base, is_for_serialization)
arr_length = expr_intval(dmltype.size)
return 'A%d%s' % (arr_length, arr_attr_type)
- if isinstance(dmltype, TVector):
+ if isinstance(dmltype, tp.Vector):
return 'V%s' % type_signature(dmltype.base, is_for_serialization)
- if isinstance(dmltype, TTrait):
- return 'T' + (cident(dmltype.trait.name)
+ if isinstance(dmltype, tp.Trait):
+ return 'T' + (tp.cident(dmltype.trait.name)
if not is_for_serialization else '')
- if isinstance(dmltype, THook):
+ if isinstance(dmltype, tp.Hook):
from .codegen import get_type_sequence_info
suffix = (str(get_type_sequence_info(dmltype.msg_types).uniq)
if not is_for_serialization else '')
@@ -498,14 +490,14 @@ def generate_serialize(real_type):
f"")
function_name = "DML_serialize_%s" % type_signature(real_type, True)
- in_arg_ty = TPtr(real_type)
- (_, in_arg_uncasted) = declare_variable(site, "_in", TPtr(const_void))
+ in_arg_ty = tp.Ptr(real_type)
+ (_, in_arg_uncasted) = declare_variable(site, "_in", tp.Ptr(const_void))
(in_arg_decl, in_arg) = declare_variable(
site, "in", in_arg_ty, ctree.mkCast(site, in_arg_uncasted, in_arg_ty))
(out_arg_decl, out_arg) = declare_variable(site, "out", attr_value_t)
function_decl = "attr_value_t %s(%s)" % (
function_name,
- TPtr(const_void).declaration("_in"))
+ tp.Ptr(const_void).declaration("_in"))
serialize_prototypes.append(function_decl)
func_code = output.StrOutput()
@@ -514,18 +506,18 @@ def generate_serialize(real_type):
# cast void* inarg to the correct type
in_arg_decl.toc()
out_arg_decl.toc()
- if isinstance(real_type, TStruct):
+ if isinstance(real_type, tp.Struct):
sources = (
(mkSubRefLit(
- site, in_arg, name or TStruct.anon_member_cident(i),
+ site, in_arg, name or tp.Struct.anon_member_cident(i),
typ, "->"),
- safe_realtype(typ))
+ tp.safe_realtype(typ))
for (i, (name, typ)) in enumerate(real_type.members))
serialize_sources_to_list(site, sources, out_arg)
- elif isinstance(real_type, TVector):
+ elif isinstance(real_type, tp.Vector):
raise ICE(site, "TODO: serialize vector")
- elif isinstance(real_type, (IntegerType, TBool, TFloat, TTrait,
- TArray, THook)):
+ elif isinstance(real_type, (tp.IntegerType, tp.Bool, tp.Float, tp.Trait,
+ tp.Array, tp.Hook)):
serialize(real_type,
ctree.mkDereference(site, in_arg),
out_arg).toc()
@@ -569,7 +561,7 @@ def sub_error_out(exc, msg):
statements.append(sub_deserialize)
else:
is_not_nil_expr = expr.mkLit(site, '!SIM_attr_is_nil(_imm_attr)',
- TBool())
+ tp.Bool())
statements.append(ctree.mkIf(
site, is_not_nil_expr,
ctree.mkCompound(
@@ -581,10 +573,10 @@ def sub_error_out(exc, msg):
+ f' during {error_context}' * bool(error_context)
))))
deserialization = ctree.mkCompound(site, statements)
- attr_is_list = apply_c_fun(site, "SIM_attr_is_list", [val_attr], TBool())
+ attr_is_list = apply_c_fun(site, "SIM_attr_is_list", [val_attr], tp.Bool())
attr_list_size = apply_c_fun(site, "SIM_attr_list_size", [val_attr],
- TInt(32, False))
+ tp.Int(32, False))
attr_list_size_check = ctree.mkEquals(
site, attr_list_size,
ctree.mkIntegerConstant(site, len(targets), False))
@@ -607,16 +599,16 @@ def generate_deserialize(real_type):
f"")
function_name = "DML_deserialize_%s" % type_signature(real_type, False)
- out_arg_ty = TPtr(real_type)
+ out_arg_ty = tp.Ptr(real_type)
(_, in_arg) = declare_variable(site, "in", attr_value_t)
- (_, out_arg_uncasted) = declare_variable(site, "_out", TPtr(void))
+ (_, out_arg_uncasted) = declare_variable(site, "_out", tp.Ptr(tp.void))
(out_arg_decl, out_arg) = declare_variable(
site, "out", out_arg_ty,
ctree.mkCast(site, out_arg_uncasted, out_arg_ty))
function_decl = "set_error_t %s(%s, %s)" % (
function_name,
attr_value_t.declaration("in"),
- TPtr(void).declaration("_out"))
+ tp.Ptr(tp.void).declaration("_out"))
serialize_prototypes.append(function_decl)
func_code = output.StrOutput()
@@ -633,19 +625,19 @@ def error_out(exc, msg):
ctree.mkInline(site, f'SIM_attribute_error("{msg}");'))
stmts.append(ctree.mkInline(site, 'goto _exit;'))
return stmts
- if isinstance(real_type, TStruct):
+ if isinstance(real_type, tp.Struct):
(tmp_out_decl, tmp_out_ref) = declare_variable(
- site, "_tmp_out", TPtr(real_type),
+ site, "_tmp_out", tp.Ptr(real_type),
ctree.mkNew(site, real_type))
- cleanup_ref = (tmp_out_ref if not deep_const(real_type)
- else ctree.mkCast(site, tmp_out_ref, TPtr(void)))
+ cleanup_ref = (tmp_out_ref if not tp.deep_const(real_type)
+ else ctree.mkCast(site, tmp_out_ref, tp.Ptr(tp.void)))
cleanup.append(ctree.mkDelete(site, cleanup_ref))
tmp_out_decl.toc()
targets = tuple(
(mkSubRefLit(
site, tmp_out_ref,
- name or TStruct.anon_member_cident(i), typ, "->"),
- conv_const(real_type.const, safe_realtype(typ)))
+ name or tp.Struct.anon_member_cident(i), typ, "->"),
+ tp.conv_const(real_type.const, tp.safe_realtype(typ)))
for (i, (name, typ)) in enumerate(real_type.members))
def error_out_at_index(_i, exc, msg):
return error_out(exc, msg)
@@ -658,10 +650,10 @@ def error_out_at_index(_i, exc, msg):
ctree.mkDereference(
site, tmp_out_ref))).toc()
- elif isinstance(real_type, TVector):
+ elif isinstance(real_type, tp.Vector):
raise ICE(site, "TODO: serialize vector")
- elif isinstance(real_type, (IntegerType, TBool, TFloat, TTrait,
- TArray, THook)):
+ elif isinstance(real_type, (tp.IntegerType, tp.Bool, tp.Float, tp.Trait,
+ tp.Array, tp.Hook)):
deserialize(real_type,
in_arg,
ctree.mkDereference(site, out_arg),
diff --git a/py/dml/slotsmeta_test.py b/py/dml/slotsmeta_test.py
index a1f27d27e..a4b0828a8 100644
--- a/py/dml/slotsmeta_test.py
+++ b/py/dml/slotsmeta_test.py
@@ -3,7 +3,7 @@
import unittest
-from dml.slotsmeta import *
+from dml.slotsmeta import auto_init, SlotsMeta
# Silence 'unused' warnings from fisketur
def use(o): pass
@@ -88,4 +88,3 @@ class Sub1(Base):
def __init__(self, x, y):
self.x += self.y
self.assertEqual(Sub1(4, 1).x, 9)
-
diff --git a/py/dml/structure.py b/py/dml/structure.py
index 604f03873..69a8d1ed5 100644
--- a/py/dml/structure.py
+++ b/py/dml/structure.py
@@ -4,28 +4,29 @@
# Structure stuff
import itertools
-import collections
-import abc
import re
from contextlib import ExitStack
import functools
import operator
-from . import objects, logging, crep, ast
+from . import objects, expr_util, logging, crep, ast
from . import traits
-from . import toplevel
from . import topsort
from . import slotsmeta
from . import ctree
-from . import env
from . import serialize
-from .logging import *
-from .codegen import *
-from .symtab import *
-from .expr import *
-from .ctree import *
-from .expr_util import *
-from .messages import *
-from .types import *
+from .logging import ICE, report, DMLError
+from . import codegen
+from .codegen import eval_type
+from .symtab import global_scope
+from .expr import Expression, mkLit, mkNullConstant, NonValue, StaticIndex
+from . import ctree as c
+from . import porting as P
+from .expr_util import (
+ defined, param_bool, param_defined, param_expr,
+ param_expr_site, param_int, param_str,
+ static_indices)
+from . import errors as E, warnings as W
+from . import types as tp
import dml.globals
from . import template
from .template import Rank, RankDesc, ObjectSpec, InstantiatedTemplateSpec
@@ -54,7 +55,7 @@ def check_constant_expr(expr):
proper value, or (recursively) a list of proper values; raise an
error otherwise.'''
if isinstance(expr, NonValue):
- if isinstance(expr, List):
+ if isinstance(expr, c.List):
for sub in expr.value:
check_constant_expr(sub)
else:
@@ -105,7 +106,7 @@ def mkglobals(stmts):
if len(nonextern_clash) > 1 or (extern_clash and nonextern_clash):
second = extern_clash[0] if extern_clash else nonextern_clash[1]
- report(ENAMECOLL(nonextern_clash[0].site, second.site, name))
+ report(E.NAMECOLL(nonextern_clash[0].site, second.site, name))
stmts.remove(nonextern_clash[0])
# retry with duplicate removed
mkglobals(stmts)
@@ -117,13 +118,13 @@ def mkglobals(stmts):
try:
if stmt[0] == 'constant':
_, site, name, expr = stmt
- expr = codegen_expression_maybe_nonvalue(
+ expr = codegen.codegen_expression_maybe_nonvalue(
expr, None, global_scope)
check_constant_expr(expr)
if expr.constant:
- global_scope.add(ExpressionSymbol(name, expr, site))
+ global_scope.add(c.ExpressionSymbol(name, expr, site))
else:
- raise ENCONST(expr, expr)
+ raise E.NCONST(expr, expr)
except DMLError as e:
report(e)
@@ -132,7 +133,7 @@ def mkglobals(stmts):
new_symbols = []
# all non-extern anonymous struct types, str -> type
anonymous_structs = {}
- # names of non-extern typedefs
+ # names of non-extern tp.typedefs
new_typedefs = set()
# Duplicate extern declarations
extern_clashes = {}
@@ -180,8 +181,8 @@ def mkglobals(stmts):
assert dml.globals.dml_version == (1, 2)
if (breaking_changes.dml12_remove_misc_quirks.enabled
and not site.filename().endswith('simics-api.dml')):
- report(EEXTERN(stmt.site))
- typ = TUnknown()
+ report(E.EXTERN(stmt.site))
+ typ = tp.Unknown()
else:
(struct_defs, typ) = eval_type(
typ, site, None, global_scope, extern=True,
@@ -191,36 +192,36 @@ def mkglobals(stmts):
if name in externs:
extern_clashes.setdefault(name, []).append((site, typ))
else:
- new_symbols.append(LiteralSymbol(name, typ, site))
+ new_symbols.append(c.LiteralSymbol(name, typ, site))
externs[name] = (site, typ)
elif stmt[0] == 'extern_typedef':
(_, site, (_, _, name, typ)) = stmt
- assert not typedefs.get(name, None)
+ assert not tp.typedefs.get(name, None)
(struct_defs, typ) = eval_type(
typ, site, None, global_scope, typename=name, extern=True,
allow_void=True)
# any substructs are converted to anonymous extern structs
assert not struct_defs
- typedefs[name] = typ
+ tp.typedefs[name] = typ
elif stmt[0] == 'dml_typedef':
(_, site, (_, _, name, typ)) = stmt
- assert not typedefs.get(name, None)
+ assert not tp.typedefs.get(name, None)
(struct_defs, typ) = eval_type(typ, site, None, global_scope,
typename=name, allow_void=True)
for (_, t) in struct_defs:
if t is not typ:
anonymous_structs[t.label] = t
- typedefs[name] = typ
+ tp.typedefs[name] = typ
assert name not in new_typedefs
new_typedefs.add(name)
elif stmt[0] == 'loggroup':
_, site, name = stmt
if len(dml.globals.log_groups) >= 63:
- report(ELOGGROUPS(site))
+ report(E.LOGGROUPS(site))
dml.globals.log_groups.append(name)
- new_symbols.append(ExpressionSymbol(
- name, LogGroup(site, name), site))
+ new_symbols.append(c.ExpressionSymbol(
+ name, c.LogGroup(site, name), site))
elif stmt.kind != 'constant': # handled above
raise ICE(stmt.site, 'bad AST kind: %s' % (stmt.kind,))
except DMLError as e:
@@ -236,38 +237,38 @@ def mkglobals(stmts):
for (tname, tpl) in list(dml.globals.templates.items()):
if tpl.trait:
- assert tname not in typedefs
+ assert tname not in tp.typedefs
trait_type = tpl.trait.type()
# any name collisions were caught earlier with ENAMECOLL
- typedefs[tname] = trait_type
+ tp.typedefs[tname] = trait_type
type_declaration_order = sort_type_declarations(new_typedefs,
anonymous_structs)
- global_type_declaration_order[:] = type_declaration_order
- global_anonymous_structs.clear()
- global_anonymous_structs.update(anonymous_structs)
+ tp.global_type_declaration_order[:] = type_declaration_order
+ tp.global_anonymous_structs.clear()
+ tp.global_anonymous_structs.update(anonymous_structs)
if breaking_changes.forbid_broken_unused_types.enabled:
- for t in typedefs.values():
+ for t in tp.typedefs.values():
try:
- check_named_types(t)
- except ETYPE as e:
+ tp.check_named_types(t)
+ except E.TYPE as e:
report(e)
for sym in new_symbols:
try:
- check_named_types(sym.type)
- except ETYPE as e:
+ tp.check_named_types(sym.type)
+ except E.TYPE as e:
report(e)
elif dml.globals.dml_version != (1, 2):
- for t in typedefs.values():
+ for t in tp.typedefs.values():
try:
- safe_realtype(t)
- except ETYPE as e:
+ tp.safe_realtype(t)
+ except E.TYPE as e:
report(e)
for sym in new_symbols:
try:
- safe_realtype(sym.type)
- except ETYPE as e:
+ tp.safe_realtype(sym.type)
+ except E.TYPE as e:
report(e)
for t in dml.globals.traits.values():
@@ -276,23 +277,23 @@ def mkglobals(stmts):
# Resolve duplicate externs
for (name, clashes) in extern_clashes.items():
(canonical_site, canonical_t) = externs[name]
- canonical_rt = safe_realtype(canonical_t)
+ canonical_rt = tp.safe_realtype(canonical_t)
for (site, typ) in clashes:
try:
- if not canonical_rt.eq(safe_realtype(typ)):
- report(EEXTERNINCOMP(site, canonical_site, name, typ,
+ if not canonical_rt.eq(tp.safe_realtype(typ)):
+ report(E.EXTERNINCOMP(site, canonical_site, name, typ,
canonical_t))
- except ETYPE as e:
+ except E.TYPE as e:
report(e)
def type_deps(t, include_structs, expanded_typedefs):
'''Given that t appears inside a DML typedef, return the set of DML
- typedefs that need to appear before this typedef in generated C
+ tp.typedefs that need to appear before this typedef in generated C
code. The location of a named struct ("typedef struct { ... } t;"
in DML) in the dependency graph refers to the struct definition in
C code ("struct t { ... }"); the type definition/struct
declaration ("typedef struct t t;") appears
- before all other typedefs in generated C code.
+ before all other tp.typedefs in generated C code.
include_structs controls whether named structs count as
dependencies. They do count for struct members and array types, since
@@ -300,10 +301,10 @@ def type_deps(t, include_structs, expanded_typedefs):
expanded_typedefs is used to avoid infinite recursion.
'''
- if isinstance(t, TNamed):
- if t.c not in typedefs:
- raise ETYPE(t.declaration_site, t)
- if isinstance(typedefs[t.c], TStruct):
+ if isinstance(t, tp.Named):
+ if t.c not in tp.typedefs:
+ raise E.TYPE(t.declaration_site, t)
+ if isinstance(tp.typedefs[t.c], tp.Struct):
if include_structs:
if t.c in expanded_typedefs:
return [t.c]
@@ -314,13 +315,13 @@ def type_deps(t, include_structs, expanded_typedefs):
# typedef struct { B b; } C;
# Here, B does not depend on A, but C
# depends on A via B.
- return [t.c] + type_deps(typedefs[t.c], True,
+ return [t.c] + type_deps(tp.typedefs[t.c], True,
expanded_typedefs + [t.c])
else:
return []
else:
return [t.c]
- elif isinstance(t, TStruct):
+ elif isinstance(t, tp.Struct):
t.resolve()
deps = []
if include_structs:
@@ -328,36 +329,31 @@ def type_deps(t, include_structs, expanded_typedefs):
for (_, mt) in t.members:
deps.extend(type_deps(mt, True, expanded_typedefs))
return deps
- elif isinstance(t, TArray):
+ elif isinstance(t, tp.Array):
return type_deps(t.base, True, expanded_typedefs)
- elif isinstance(t, (TPtr, TVector)):
+ elif isinstance(t, (tp.Ptr, tp.Vector)):
return type_deps(t.base, False, expanded_typedefs)
- elif isinstance(t, TFunction):
+ elif isinstance(t, tp.Function):
return ([dep for pt in t.input_types
for dep in type_deps(pt, False, expanded_typedefs)]
+ type_deps(t.output_type, False, expanded_typedefs))
- elif isinstance(t, (IntegerType, TVoid, TBool, TFloat, TTrait)):
+ elif isinstance(t, (tp.IntegerType, tp.Void, tp.Bool, tp.Float, tp.Trait)):
return []
- elif isinstance(t, TExternStruct):
+ elif isinstance(t, tp.ExternStruct):
# extern structs are assumed to be self-contained
return []
else:
raise ICE(t.declaration_site, "unknown type %r" % t)
-def remove_type(name):
- del typedefs[name]
- if name in new_global_types:
- new_global_types.remove(name)
-
def sort_type_declarations(new_typedefs, anonymous_structs):
deps = {}
- for name in typedefs:
+ for name in tp.typedefs:
if name in new_typedefs:
try:
- deplist = type_deps(typedefs[name], False, [])
+ deplist = type_deps(tp.typedefs[name], False, [])
except DMLError as e:
report(e)
- del typedefs[name]
+ del tp.typedefs[name]
return sort_type_declarations(new_typedefs - {name},
anonymous_structs)
else:
@@ -374,18 +370,18 @@ def sort_type_declarations(new_typedefs, anonymous_structs):
try:
type_order = topsort.topsort(deps)
except topsort.CycleFound as e:
- report(ETREC([typedefs[n].declaration_site for n in e.cycle
- if n in typedefs],
- typedefs[e.cycle[0]]))
+ report(E.TREC([tp.typedefs[n].declaration_site for n in e.cycle
+ if n in tp.typedefs],
+ tp.typedefs[e.cycle[0]]))
for n in e.cycle:
- del typedefs[n]
+ del tp.typedefs[n]
# retry with this cycle removed
return sort_type_declarations(
new_typedefs.difference(e.cycle), anonymous_structs)
# TODO: we could check that no extern typedef depends on a
# non-extern typedef, SIMICS-9987
return [n for n in type_order
- # exclude extern typedefs
+ # exclude extern tp.typedefs
if n in new_typedefs or n in anonymous_structs]
unused_field_methods = {'after_read',
@@ -451,12 +447,12 @@ def check_unused_and_warn(node):
not used. This usually applies to methods and parameters."""
if node.refcount == 0:
- if not warning_is_ignored('WUNUSED'):
- report(WUNUSED(node))
+ if not logging.warning_is_ignored('WUNUSED'):
+ report(W.UNUSED(node))
elif is_unused_default(node):
- report(WUNUSEDDEFAULT(node))
+ report(W.UNUSEDDEFAULT(node))
elif dml.globals.dml_version != (1, 2) and is_dml12_method(node):
- report(WUNUSED_DML12(node))
+ report(W.UNUSED_DML12(node))
for n in node.get_components():
check_unused_and_warn(n)
@@ -544,7 +540,7 @@ def add_templates(obj_specs, each_stmts):
# stricter checking in 1.2, because that doesn't hurt.
breaking_changes.forbid_broken_conditional_is.enabled
or not breaking_changes.dml12_remove_misc_quirks.enabled)):
- report(ENTMPL(site, tpl.name))
+ report(E.NTMPL(site, tpl.name))
continue
if tpl in used_templates:
continue
@@ -553,7 +549,7 @@ def add_templates(obj_specs, each_stmts):
obj_spec = tpl.spec
else:
obj_spec = InstantiatedTemplateSpec(
- tpl, *wrap_sites(TemplateSite, tpl.spec, site, tpl.name))
+ tpl, *wrap_sites(logging.TemplateSite, tpl.spec, site, tpl.name))
used_templates[tpl] = obj_spec
for (tpls, orig_tpls, spec) in each_stmts.get(tpl, []):
@@ -571,7 +567,7 @@ def add_templates(obj_specs, each_stmts):
else:
# All templates match; expand the each statement.
obj_specs.append(
- ObjectSpec(*wrap_sites(InEachSite, spec, spec.site,
+ ObjectSpec(*wrap_sites(logging.InEachSite, spec, spec.site,
[t.name for t in orig_tpls])))
queue.extend(spec.templates)
@@ -579,7 +575,7 @@ def add_templates(obj_specs, each_stmts):
queue.extend(obj_spec.templates)
if logging.show_porting:
- PWUNUSED.used_templates.update(used_templates)
+ P.WUNUSED.used_templates.update(used_templates)
return (obj_specs, used_templates)
@@ -623,9 +619,9 @@ def merge_parameters(params, obj_specs):
for (_, p) in params:
(name, _, _, value) = p.args
if value is not None:
- raise EAUTOPARAM(p.site, name)
+ raise E.AUTOPARAM(p.site, name)
if len(autos) != 1:
- raise EAUTOPARAM(autos[0].site, autos[0].args[0])
+ raise E.AUTOPARAM(autos[0].site, autos[0].args[0])
return autos[0]
if dml.globals.dml_version == (1, 2):
@@ -643,13 +639,13 @@ def merge_parameters(params, obj_specs):
decls[rank] = param
else:
if rank in defs:
- raise ENAMECOLL(param.site, defs[rank].site, name)
+ raise E.NAMECOLL(param.site, defs[rank].site, name)
defs[rank] = param
if not defs:
[decl, *_] = decls.values()
(name, _, _, _) = decl.args
- raise ENPARAM(decl.site, name)
+ raise E.NPARAM(decl.site, name)
all_inferior = set().union(*(rank.inferior for rank in defs))
superior = [(rank, p) for (rank, p) in defs.items()
@@ -665,7 +661,7 @@ def decl_is_default(decl):
[(rank1, p1), (rank2, p2)] = sorted(
superior, key=decl_is_default)[:2]
(name, _, _, _) = p1.args
- raise EAMBINH(
+ raise E.AMBINH(
p1.site, p2.site, name, rank1.desc, rank2.desc,
decl_is_default((rank1, p1)))
@@ -684,14 +680,14 @@ def decl_is_default(decl):
if not declared_as_override and parent_ranks:
[parent, *_] = (parent for (parent_rank, parent) in params
if parent_rank in parent_ranks)
- report(EOVERRIDEPARAM(type_info.site, parent.site, name,
+ report(E.OVERRIDEPARAM(type_info.site, parent.site, name,
'default' if is_default else '='))
if not declared_as_override and rank in decls:
- report(EOVERRIDEPARAM(type_info.site, decls[rank].site, name,
+ report(E.OVERRIDEPARAM(type_info.site, decls[rank].site, name,
'default' if is_default else '='))
elif (not parent_ranks and declared_as_override
and rank not in decls):
- report(ENOVERRIDEPARAM(
+ report(E.NOVERRIDEPARAM(
p.site, name, 'default' if is_default else '='))
[(rank0, param0)] = superior
@@ -700,7 +696,7 @@ def decl_is_default(decl):
(name, _, is_default, _) = param.args
if not is_default and rank is not rank0:
# Attempt to override non-default parameter
- report(EINVOVER(param0.site, param.site, name))
+ report(E.INVOVER(param0.site, param.site, name))
return param
if dml.globals.dml_version == (1, 2):
@@ -708,10 +704,10 @@ def decl_is_default(decl):
if len(defs) == 2:
(_, _, is_default, _) = param0.args
if is_default:
- report(WEXPERIMENTAL(
+ report(W.EXPERIMENTAL(
param0.site, "parameter with two default declarations"))
elif len(defs) > 2:
- report(WEXPERIMENTAL(
+ report(W.EXPERIMENTAL(
param0.site, "more than one level of parameter overrides"))
return param0
@@ -732,9 +728,9 @@ def typecheck_method_override(m1, m2, location):
# We should also check parameter types here (SIMICS-9337)
if len(inp1) != len(inp2):
- raise EMETH(m1.site, m2.site, "different number of input parameters")
+ raise E.METH(m1.site, m2.site, "different number of input parameters")
if len(outp1) != len(outp2):
- raise EMETH(m1.site, m2.site, "different number of output parameters")
+ raise E.METH(m1.site, m2.site, "different number of output parameters")
for (idx, (a1, a2)) in enumerate(zip(inp1, inp2)):
((n1, t1), (n2, t2)) = (a1.args, a2.args)
if (t1 is None) != (t2 is None):
@@ -752,17 +748,17 @@ def typecheck_method_override(m1, m2, location):
# Not that we really EXPECT the discard identifier here
ident = n1.args[0] if n1.kind == 'variable' else '_'
- report(PINARGTYPE(a1.site, type2.declaration(ident)))
+ report(P.INARGTYPE(a1.site, type2.declaration(ident)))
else:
- raise EMETH(m1.site, m2.site, "different inline args")
+ raise E.METH(m1.site, m2.site, "different inline args")
if (t1 and t2
and a1.site.dml_version() != (1, 2)
and a2.site.dml_version() != (1, 2)):
# TODO move to caller
(_, type1) = eval_type(t1, a1.site, location, global_scope)
(_, type2) = eval_type(t2, a2.site, location, global_scope)
- type1 = safe_realtype_unconst(type1)
- type2 = safe_realtype_unconst(type2)
+ type1 = tp.safe_realtype_unconst(type1)
+ type2 = tp.safe_realtype_unconst(type2)
ok = (type1.eq_fuzzy(type2)
if not breaking_changes.strict_typechecking.enabled
@@ -770,7 +766,7 @@ def typecheck_method_override(m1, m2, location):
if not ok:
ref = f"'{n1.args[0]}'" if n1.kind == 'variable' else (idx + 1)
- raise EMETH(a1.site, a2.site,
+ raise E.METH(a1.site, a2.site,
f"mismatching types in input argument {ref}")
for (i, (a1, a2)) in enumerate(zip(outp1, outp2)):
@@ -778,8 +774,8 @@ def typecheck_method_override(m1, m2, location):
((n1, t1), (n2, t2)) = (a1.args, a2.args)
(_, type1) = eval_type(t1, a1.site, location, global_scope)
(_, type2) = eval_type(t2, a2.site, location, global_scope)
- type1 = safe_realtype_unconst(type1)
- type2 = safe_realtype_unconst(type2)
+ type1 = tp.safe_realtype_unconst(type1)
+ type2 = tp.safe_realtype_unconst(type2)
ok = (type1.eq_fuzzy(type2)
if not breaking_changes.strict_typechecking.enabled
else type1.eq(type2))
@@ -787,17 +783,17 @@ def typecheck_method_override(m1, m2, location):
msg = "mismatching types in return value"
if len(outp1) > 1:
msg += f" {i + 1}"
- raise EMETH(a1.site, a2.site, msg)
+ raise E.METH(a1.site, a2.site, msg)
if (logging.show_porting
and all(a2.args[1] for a2 in inp2)
and any(not a1.args[1] for a1 in inp1)):
# hack to change 'inline method' -> 'method' if needed
- report(PINARGTYPE(m1.site, 'method'))
+ report(P.INARGTYPE(m1.site, 'method'))
def qualifier_check(qualifier_name, qualifier1, qualifier2):
if qualifier1 != qualifier2:
- raise EMETH(m1.site, m2.site,
+ raise E.METH(m1.site, m2.site,
(f"one declaration is qualified as {qualifier_name}, "
+ "but the other is not"))
@@ -815,19 +811,19 @@ def report_poverride(sup, inf, obj_specs):
assert sup_objs
for sup_obj in sup_objs:
if inf.desc.kind == 'template':
- report(POVERRIDE(sup_obj.site, inf.desc.text))
+ report(P.OVERRIDE(sup_obj.site, inf.desc.text))
else:
- report(POVERRIDE_IMPORT(sup_obj.site, inf.desc.text))
+ report(P.OVERRIDE_IMPORT(sup_obj.site, inf.desc.text))
def merge_subobj_defs(name, defs, parent):
specs = [spec for (_, _, _, spec) in defs]
(objtype, arrayinfo, _, _) = defs[0]
for (ot, ai, _, spec) in defs[1:]:
if ot != objtype:
- report(ENAMECOLL(specs[0].site, spec.site, name))
+ report(E.NAMECOLL(specs[0].site, spec.site, name))
return merge_subobj_defs(name, defs[1:], parent)
if len(ai) != len(arrayinfo):
- raise EAINCOMP(specs[0].site, spec.site, name,
+ raise E.AINCOMP(specs[0].site, spec.site, name,
"mixing declarations with different number "
"of array dimensions")
@@ -836,7 +832,7 @@ def merge_subobj_defs(name, defs, parent):
# False -> explicit decl
if all(extension_status is True for (_, _, extension_status, _) in defs):
for spec in specs:
- report(EEXTENSION(spec.site, name))
+ report(E.EXTENSION(spec.site, name))
explicit_decls = [
spec for (_, _, extension_status, spec) in defs if extension_status is False]
@@ -850,11 +846,11 @@ def merge_subobj_defs(name, defs, parent):
lowest = other
for decl in explicit_decls:
if decl is not lowest:
- report(EMULTIOBJDECL(decl.site, lowest.site, objtype, name))
+ report(E.MULTIOBJDECL(decl.site, lowest.site, objtype, name))
merged_arrayinfo = []
if arrayinfo:
- parent_scope = Location(parent, static_indices(parent))
+ parent_scope = c.Location(parent, static_indices(parent))
for (dim_i, dim) in enumerate(
zip(*(arrayinfo for (_, arrayinfo, _, _) in defs))):
(idxvar_asts, len_asts) = zip(*dim)
@@ -871,19 +867,19 @@ def merge_subobj_defs(name, defs, parent):
[(idxvar, first_asts), *rest] = candidates.items()
for (_, conflicting_asts) in rest:
for ast in conflicting_asts:
- report(EAINCOMP(
+ report(E.AINCOMP(
ast.site, first_asts[0].site, name,
"mismatching index variables"))
candidates = {}
for len_ast in len_asts:
if len_ast is not None:
- length = eval_arraylen(len_ast, parent_scope)
+ length = codegen.eval_arraylen(len_ast, parent_scope)
candidates.setdefault(length, []).append(len_ast)
if len(candidates) == 0:
idxref = (f" (with index variable '{idxvar}')"
if idxvar else "")
- report(EAUNKDIMSIZE(specs[0].site, dim_i, idxref))
+ report(E.AUNKDIMSIZE(specs[0].site, dim_i, idxref))
length = 1
lensite = specs[0].site
else:
@@ -891,7 +887,7 @@ def merge_subobj_defs(name, defs, parent):
lensite = asts[0].site
for (_, asts) in rest:
for ast in asts:
- report(EAINCOMP(ast.site, lensite, name,
+ report(E.AINCOMP(ast.site, lensite, name,
"mismatching array sizes"))
merged_arrayinfo.append((idxvar, length, lensite))
@@ -911,37 +907,37 @@ def method_is_std(node, methname):
def mkdata(spec, parent):
site, name, typ, astinit = spec
- parent_scope = Location(parent, static_indices(parent))
+ parent_scope = c.Location(parent, static_indices(parent))
(struct_defs, dtype) = eval_type(
typ, site, parent_scope, global_scope)
dtype = dtype.resolve()
- add_late_global_struct_defs(struct_defs)
+ tp.add_late_global_struct_defs(struct_defs)
obj = objects.Session(name, dtype, astinit, site, parent)
if astinit:
dml.globals.device.add_init_data(obj)
try:
- realtype(crep.node_storage_type(obj))
- except DMLUnknownType as e:
- raise ETYPE(obj, e.type)
+ tp.realtype(crep.node_storage_type(obj))
+ except tp.DMLUnknownType as e:
+ raise E.TYPE(obj, e.type)
return obj
def mksaved(spec, parent):
site, name, typ, astinit = spec
- parent_scope = Location(parent, static_indices(parent))
+ parent_scope = c.Location(parent, static_indices(parent))
(struct_defs, dtype) = eval_type(typ, site, parent_scope, global_scope)
- add_late_global_struct_defs(struct_defs)
+ tp.add_late_global_struct_defs(struct_defs)
dtype.resolve()
- if deep_const(dtype):
- raise ESAVEDCONST(site, dtype)
+ if tp.deep_const(dtype):
+ raise E.SAVEDCONST(site, dtype)
obj = objects.Saved(name, dtype, astinit, site, parent)
if astinit:
dml.globals.device.add_init_data(obj)
typ = crep.node_storage_type(obj)
try:
- realtype(typ)
- except DMLUnknownType as e:
- raise ETYPE(obj, e.type)
+ tp.realtype(typ)
+ except tp.DMLUnknownType as e:
+ raise E.TYPE(obj, e.type)
serialize.mark_for_serialization(site, typ)
@@ -949,21 +945,21 @@ def mksaved(spec, parent):
def mkhook(spec, parent):
(_, site, name, arraylen_asts, type_asts) = spec
- parent_scope = Location(parent, static_indices(parent))
+ parent_scope = c.Location(parent, static_indices(parent))
types = []
for type_ast in type_asts:
(struct_defs, dtype) = eval_type(type_ast, site, parent_scope,
global_scope)
- add_late_global_struct_defs(struct_defs)
+ tp.add_late_global_struct_defs(struct_defs)
typ = dtype.resolve()
try:
- safe_realtype(typ).key()
- except DMLUnkeyableType as e:
- report(EHOOKTYPE(typ.declaration_site or site, typ,
+ tp.safe_realtype(typ).key()
+ except tp.DMLUnkeyableType as e:
+ report(E.HOOKTYPE(typ.declaration_site or site, typ,
e.clarification))
types.append(typ)
- array_lens = tuple(eval_arraylen(len_ast, parent_scope)
+ array_lens = tuple(codegen.eval_arraylen(len_ast, parent_scope)
for len_ast in arraylen_asts)
return objects.Hook(name, site, parent, types, array_lens)
@@ -979,7 +975,7 @@ def register_fields(reg):
# before we can know that the group actually contains a field.
# For this reason, in DML 1.2 we disallow groups in regs
# altogether.
- report(ENALLOW(g.site, reg))
+ report(E.NALLOW(g.site, reg))
unexpanded = reg.get_components('field')
for field in unexpanded:
@@ -987,16 +983,16 @@ def register_fields(reg):
for fieldi in itertools.product(
*(list(range(sz)) for sz in field.dimsizes[reg.dimensions:])):
indices = static_indices(reg) + tuple(
- mkIntegerLiteral(field.site, i) for i in fieldi)
+ c.mkIntegerLiteral(field.site, i) for i in fieldi)
lsb = param_int(field, 'lsb', indices=indices)
msb = param_int(field, 'msb', indices=indices)
if msb < lsb:
- raise EBITRN(field, msb, lsb)
+ raise E.BITRN(field, msb, lsb)
yield (field, fieldi, lsb, msb)
# bitsize is defined in terms of lsb and msb, so we
# don't need to evaluate it across register indices
bitsize = param_expr(field, 'bitsize',
- tuple(mkIntegerLiteral(field.site, i)
+ tuple(c.mkIntegerLiteral(field.site, i)
for i in (0,) * reg.dimensions + fieldi))
if not bitsize.constant:
# guaranteed by dml-builtins.dml
@@ -1006,27 +1002,27 @@ def register_fields(reg):
if any(sz != bitsizes[0] for sz in bitsizes[1:]):
# bitsize is defined in dml-builtins, so the 'msb'
# site is probably more relevant
- report(EFARRSZ(param_expr_site(field, 'msb')))
+ report(E.FARRSZ(param_expr_site(field, 'msb')))
def report_unused_templates():
- for tpl in PWUNUSED.used_templates:
+ for tpl in P.WUNUSED.used_templates:
if not tpl.name.startswith('@'):
- report(PNO_WUNUSED(tpl.site, 'template', tpl.name))
- for tpl in set(dml.globals.templates.values()) - PWUNUSED.used_templates:
+ report(P.NO_WUNUSED(tpl.site, 'template', tpl.name))
+ for tpl in set(dml.globals.templates.values()) - P.WUNUSED.used_templates:
if not tpl.name.startswith('@'):
- report(PWUNUSED(tpl.site, 'template', tpl.name))
+ report(P.WUNUSED(tpl.site, 'template', tpl.name))
def report_unused_conds():
- for cond in PWUNUSED.positive_conds:
- if cond in PWUNUSED.satisfied_conds:
- report(PNO_WUNUSED(cond.site, 'if', None))
+ for cond in P.WUNUSED.positive_conds:
+ if cond in P.WUNUSED.satisfied_conds:
+ report(P.NO_WUNUSED(cond.site, 'if', None))
else:
- report(PWUNUSED(cond.site, 'if', None))
- for cond in PWUNUSED.negative_conds:
- if cond in PWUNUSED.satisfied_conds:
- report(PNO_WUNUSED(cond.site, 'else', None))
+ report(P.WUNUSED(cond.site, 'if', None))
+ for cond in P.WUNUSED.negative_conds:
+ if cond in P.WUNUSED.satisfied_conds:
+ report(P.NO_WUNUSED(cond.site, 'else', None))
else:
- report(PWUNUSED(cond.site, 'else', None))
+ report(P.WUNUSED(cond.site, 'else', None))
def mkdev(devname, obj_specs):
dev = mkobj(devname, 'device', (), obj_specs, None, {})
@@ -1052,9 +1048,9 @@ def mkobj(ident, objtype, arrayinfo, obj_specs, parent, each_stmts):
arraylens, index_vars)
num_elems = functools.reduce(operator.mul, obj.dimsizes, 1)
if num_elems >= 1 << 31:
- raise EASZLARGE(site, num_elems)
+ raise E.ASZLARGE(site, num_elems)
- with ErrorContext(obj):
+ with logging.ErrorContext(obj):
(obj_specs, used_templates) = add_templates(obj_specs, each_stmts)
obj.templates = used_templates
obj_params = create_parameters(obj, obj_specs, index_vars, index_sites)
@@ -1068,7 +1064,7 @@ def create_object(site, ident, objtype, parent,
elif objtype == 'bank':
if (ident is None
and breaking_changes.dml12_remove_misc_quirks.enabled):
- report(ESYNTAX(site, 'bank', 'anonymous banks are not allowed'))
+ report(E.SYNTAX(site, 'bank', 'anonymous banks are not allowed'))
return objects.Bank(ident, site, parent, arraylens, index_vars)
elif objtype == 'group':
return objects.Group(ident, site, parent, arraylens, index_vars)
@@ -1103,12 +1099,12 @@ def make_autoparams(obj, index_vars, index_sites):
autoparams = {}
if dml.globals.dml_version == (1, 2):
- autoparams['name'] = SimpleParamExpr(
- mkStringConstant(site, obj.ident) if obj.ident
- else mkUndefined(site))
+ autoparams['name'] = c.SimpleParamExpr(
+ c.mkStringConstant(site, obj.ident) if obj.ident
+ else c.mkUndefined(site))
else:
- autoparams['_ident'] = SimpleParamExpr(
- mkStringConstant(site, obj.ident))
+ autoparams['_ident'] = c.SimpleParamExpr(
+ c.mkStringConstant(site, obj.ident))
index_params = ()
# Handle array information
@@ -1137,34 +1133,34 @@ def make_autoparams(obj, index_vars, index_sites):
# If in a multi-dimensional array, this will be set to undefined
# So in 1.2 you can verify if you are in a multi-dimensional
# array by checking if this is defined
- autoparams['indexvar'] = SimpleParamExpr(
- mkStringConstant(
+ autoparams['indexvar'] = c.SimpleParamExpr(
+ c.mkStringConstant(
# TODO or maybe 'i'?
index_site, '' if index_var is None else index_var))
autoparams['index'] = index_param
elif index_vars:
- autoparams['indexvar'] = SimpleParamExpr(mkUndefined(site))
+ autoparams['indexvar'] = c.SimpleParamExpr(c.mkUndefined(site))
autoparams['index'] = IndexListParamExpr(site, index_params)
else:
- autoparams['indexvar'] = SimpleParamExpr(mkUndefined(site))
- autoparams['index'] = SimpleParamExpr(mkUndefined(site))
+ autoparams['indexvar'] = c.SimpleParamExpr(c.mkUndefined(site))
+ autoparams['index'] = c.SimpleParamExpr(c.mkUndefined(site))
else:
autoparams['indices'] = IndexListParamExpr(site, index_params)
if obj.objtype == 'device':
with crep.DeviceInstanceContext():
- autoparams['obj'] = SimpleParamExpr(mkDeviceObject(site))
+ autoparams['obj'] = c.SimpleParamExpr(c.mkDeviceObject(site))
if dml.globals.dml_version == (1, 2):
autoparams['banks'] = UninitializedParamExpr(site, 'banks')
else:
autoparams['NULL'] = NullParamExpr(site)
- autoparams['_be_bitorder'] = SimpleParamExpr(
- mkBoolConstant(site, site.bitorder() == 'be'))
- autoparams['simics_api_version'] = SimpleParamExpr(
- mkStringConstant(site, dml.globals.api_version.str))
+ autoparams['_be_bitorder'] = c.SimpleParamExpr(
+ c.mkBoolConstant(site, site.bitorder() == 'be'))
+ autoparams['simics_api_version'] = c.SimpleParamExpr(
+ c.mkStringConstant(site, dml.globals.api_version.str))
for change in breaking_changes.changes.values():
- autoparams[f'_breaking_change_{change.ident()}'] = SimpleParamExpr(
- mkBoolConstant(site, change.enabled))
+ autoparams[f'_breaking_change_{change.ident()}'] = c.SimpleParamExpr(
+ c.mkBoolConstant(site, change.enabled))
dml.globals.device = obj
elif obj.objtype == 'bank':
@@ -1183,13 +1179,13 @@ def make_autoparams(obj, index_vars, index_sites):
# If this is an automatic field, create msb/lsb parameter from
# the size of the register
if obj.ident:
- autoparams['explicit'] = SimpleParamExpr(
- mkBoolConstant(site, True))
+ autoparams['explicit'] = c.SimpleParamExpr(
+ c.mkBoolConstant(site, True))
else:
- autoparams['name'] = SimpleParamExpr(
+ autoparams['name'] = c.SimpleParamExpr(
param_expr(obj.parent, 'name'))
- autoparams['explicit'] = SimpleParamExpr(
- mkBoolConstant(site, False))
+ autoparams['explicit'] = c.SimpleParamExpr(
+ c.mkBoolConstant(site, False))
elif obj.objtype == 'connect':
if dml.globals.dml_version == (1, 2):
@@ -1216,14 +1212,14 @@ def make_autoparams(obj, index_vars, index_sites):
if obj.parent:
autoparams['parent'] = ParentParamExpr(obj)
else:
- autoparams['parent'] = SimpleParamExpr(mkUndefined(obj.site))
+ autoparams['parent'] = c.SimpleParamExpr(c.mkUndefined(obj.site))
if dml.globals.dml_version != (1, 2):
if obj.nongroup_parent:
autoparams['_nongroup_parent'] = NongroupParentParamExpr(obj.site,
obj)
else:
- autoparams['_nongroup_parent'] = SimpleParamExpr(
- mkUndefined(obj.site))
+ autoparams['_nongroup_parent'] = c.SimpleParamExpr(
+ c.mkUndefined(obj.site))
autoparams['templates'] = TemplatesParamExpr(obj.site, obj)
@@ -1234,7 +1230,7 @@ def implicit_params(obj, index_vars, index_sites):
ivar_sites = {}
for (var, site) in zip(index_vars, index_sites):
if var in ivar_sites and var is not None:
- report(ENAMECOLL(ivar_sites[var], site, var))
+ report(E.NAMECOLL(ivar_sites[var], site, var))
ivar_sites[var] = site
params = [ast.param(site, var, ast.auto(site), False, None)
for (var, site) in zip(index_vars, index_sites) if var is not None]
@@ -1277,21 +1273,21 @@ def create_parameters(obj, obj_specs, index_vars, index_sites):
def eval_precond(cond_ast, obj, global_scope):
try:
- with ErrorContext(obj, cond_ast.site):
- cond = codegen_expression(
- cond_ast, Location(obj, static_indices(obj, cond_ast.site)),
+ with logging.ErrorContext(obj, cond_ast.site):
+ cond = codegen.codegen_expression(
+ cond_ast, c.Location(obj, static_indices(obj, cond_ast.site)),
global_scope)
except DMLError as e:
report(e)
return False # whatever
else:
- cond = as_bool(cond)
+ cond = c.as_bool(cond)
if cond.constant:
- # guaranteed by as_bool()
- assert isinstance(cond.ctype(), TBool)
+ # guaranteed by c.as_bool()
+ assert isinstance(cond.ctype(), tp.Bool)
return cond.value
else:
- report(ENCONST(cond, cond))
+ report(E.NCONST(cond, cond))
return False # whatever
class InvalidDefault(objects.MethodDefault):
@@ -1307,9 +1303,9 @@ class DefaultMethodObj(objects.MethodDefault):
def __init__(self, node):
self.node = node
def default_sym(self, indices):
- return ExpressionSymbol(
+ return c.ExpressionSymbol(
'default',
- mkNodeRef(self.node.site, self.node, indices),
+ c.mkNodeRef(self.node.site, self.node, indices),
self.node.site)
class DefaultTraitMethod(objects.MethodDefault):
@@ -1332,10 +1328,10 @@ def default_sym(self, indices):
# This is safe; ancestry paths are tuples
ancestry_path += default_def_trait.ancestry_paths[
self.trait_method.vtable_trait][0]
- return ExpressionSymbol(
+ return c.ExpressionSymbol(
'default',
- TraitMethodDirect(
- site, ObjTraitRef(
+ c.TraitMethodDirect(
+ site, c.ObjTraitRef(
site, self.trait_node, self.trait_method.vtable_trait,
indices,
ancestry_path=ancestry_path),
@@ -1417,23 +1413,23 @@ def report_pbefaft(obj, method_asts):
method_decl = method_decl.replace('value', value_arg)
default_call = default_call.replace('value', value_arg)
- report(PBEFAFT(bef.site, dmlparse.start_site(bef_body.site),
+ report(P.BEFAFT(bef.site, dmlparse.start_site(bef_body.site),
method_decl, default_call, return_stmt,
bef.site, dmlparse.start_site(bef_body.site),
dmlparse.end_site(bef_body.site),
*aft_args))
else:
- report(PBEFAFT(aft.site, dmlparse.start_site(aft_body.site),
+ report(P.BEFAFT(aft.site, dmlparse.start_site(aft_body.site),
method_decl, default_call, return_stmt,
None, None, None,
*aft_args))
if obj.objtype == 'register':
tramp_site = bef.site if bef else aft.site
if before_name == 'before_read':
- report(PTRAMPOLINE(tramp_site, None,
+ report(P.TRAMPOLINE(tramp_site, None,
'is dml12_compat_read_register;'))
elif before_name == 'before_write':
- report(PTRAMPOLINE(tramp_site, None,
+ report(P.TRAMPOLINE(tramp_site, None,
'is dml12_compat_write_register;'))
@@ -1441,7 +1437,7 @@ def wrap_method_body_in_try(site, overridden_site, obj, name, body,
rbrace_site):
if (obj.objtype != 'implement'
and not site.filename().endswith('dml-builtins.dml')):
- report(WTHROWS_DML12(site, overridden_site))
+ report(W.THROWS_DML12(site, overridden_site))
return ast.compound(site, [
ast.try_(site, body, ast.log(
site, 'error', ast.int(site, 1), None, ast.int(site, 0),
@@ -1527,7 +1523,7 @@ def process_method_declarations(obj, name, declarations,
for other in others:
if not other.abstract:
# two conflicting method definitions in the same block
- raise ENAMECOLL(other.site, impl.site, other.name)
+ raise E.NAMECOLL(other.site, impl.site, other.name)
if (not impl.shared # Handled separately
and impl.site.provisional_enabled(
@@ -1536,16 +1532,16 @@ def process_method_declarations(obj, name, declarations,
for m in rank_to_methods[anc]]
if impl.explicit_decl:
if existing:
- report(EOVERRIDEMETH(impl.site, existing[0].site,
+ report(E.OVERRIDEMETH(impl.site, existing[0].site,
impl.name,
'default ' * impl.overridable))
elif not existing:
- report(ENOVERRIDEMETH(impl.site, impl.name,
+ report(E.NOVERRIDEMETH(impl.site, impl.name,
'default ' * impl.overridable))
(default_map, method_order) = traits.sort_method_implementations(impls)
- location = Location(obj, static_indices(obj))
+ location = c.Location(obj, static_indices(obj))
nonshared_impls = []
@@ -1553,7 +1549,7 @@ def process_method_declarations(obj, name, declarations,
if impl.shared:
if default_map[impl]:
# shared method overrides a non-shared method
- report(ETMETH(
+ report(E.TMETH(
default_map[impl][0].site, impl.site, name))
else:
nonshared_impls.append(impl)
@@ -1587,7 +1583,7 @@ def process_method_declarations(obj, name, declarations,
else:
# This only done in this path because we favor reporting
# EABSTEMPLATE (done by the caller) over EABSMETH
- report(EABSMETH(abstract_decls[0].site, name))
+ report(E.ABSMETH(abstract_decls[0].site, name))
if not nonshared_impls:
return None
@@ -1626,7 +1622,7 @@ def process_method_declarations(obj, name, declarations,
throws = False
for overridden in default_map[impl]:
if not overridden.overridable:
- raise EDMETH(impl.site, overridden.site, name)
+ raise E.DMETH(impl.site, overridden.site, name)
# the override of trait ASTs is checked later, by
# traits.typecheck_method_override
if not overridden.shared:
@@ -1660,7 +1656,7 @@ def process_method_declarations(obj, name, declarations,
# 1.2 and 1.4,
pass
else:
- raise EMETH(impl.site, overridden.site,
+ raise E.METH(impl.site, overridden.site,
"different 'throws' annotations")
template = (impl.obj_spec.parent_template
@@ -1684,18 +1680,18 @@ def process_method_declarations(obj, name, declarations,
(_, msite, _, _, _, exported, _, _) = method_ast
if exported:
if not method.fully_typed:
- raise EEXTERN(method.site)
- func = method_instance(method)
- mark_method_referenced(func)
- mark_method_exported(func, crep.cref_method(method), msite)
+ raise E.EXTERN(method.site)
+ func = codegen.method_instance(method)
+ codegen.mark_method_referenced(func)
+ codegen.mark_method_exported(func, crep.cref_method(method), msite)
break
# Export hard_reset and soft_reset from device objects in 1.2
# automatically
if (obj.objtype == 'device' and
name in {'hard_reset', 'soft_reset'}):
- func = method_instance(method)
- mark_method_referenced(func)
- mark_method_exported(func, crep.cref_method(method), obj.site)
+ func = codegen.method_instance(method)
+ codegen.mark_method_referenced(func)
+ codegen.mark_method_exported(func, crep.cref_method(method), obj.site)
return method
@@ -1711,9 +1707,9 @@ def mkobj2(obj, obj_specs, params, each_stmts):
# to site. For name collision detection.
symbols = {param.name: param.site for param in params}
if dml.globals.dml_version == (1, 4):
- objname = param_str_fixup(obj, 'name', obj.ident)
+ objname = c.param_str_fixup(obj, 'name', obj.ident)
if not ident_re.match(objname):
- report(ENAMEID(param_expr_site(obj, 'name'), objname))
+ report(E.NAMEID(param_expr_site(obj, 'name'), objname))
objname = obj.ident
obj.name = objname
else:
@@ -1722,15 +1718,15 @@ def mkobj2(obj, obj_specs, params, each_stmts):
pnode = obj.get_component('_build_confidentiality')
if pnode and pnode.objtype == 'parameter':
val = pnode.get_expr(())
- if isinstance(val, IntegerConstant) and val.value > 0:
+ if isinstance(val, c.IntegerConstant) and val.value > 0:
dml.globals.build_confidentiality = val.value
if obj.objtype == 'register':
if not param_defined(obj, 'size'):
- raise EREGNSZ(obj)
+ raise E.REGNSZ(obj)
if param_int(obj, 'size') > 8:
- raise EREGISZ(obj)
+ raise E.REGISZ(obj)
obj_traits = []
for obj_spec in obj_specs:
@@ -1745,7 +1741,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
if all(eval_precond(cond, obj, global_scope)
for cond in preconds):
if logging.show_porting:
- PWUNUSED.satisfied_conds.update(preconds)
+ P.WUNUSED.satisfied_conds.update(preconds)
shallow_subobjs.append((shallow, obj_spec))
composite_subobjs.append((composite, obj_spec))
for (templates, spec) in in_eachs:
@@ -1766,12 +1762,12 @@ def mkobj2(obj, obj_specs, params, each_stmts):
for s in stmts:
if s.kind == 'error':
_, esite, msg = s
- raise EERRSTMT(esite, msg or "explicit error")
+ raise E.ERRSTMT(esite, msg or "explicit error")
elif s.kind == 'method':
(name, _, _, _, _, _) = s.args
if name not in method_asts:
if name in symbols:
- report(ENAMECOLL(s.site, symbols[name], name))
+ report(E.NAMECOLL(s.site, symbols[name], name))
else:
symbols[name] = s.site
method_asts[name] = [(obj_spec, s)]
@@ -1780,7 +1776,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
elif s.kind == 'session':
(decls, inits) = s.args
if inits is not None and len(decls) != len(inits):
- report(ESYNTAX(s.site, None,
+ report(E.SYNTAX(s.site, None,
'wrong number of initializers:\n'
+ f'{len(decls)} variables declared\n'
+ f'{len(inits)} initializers specified'))
@@ -1790,7 +1786,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
for (decl_ast, init_ast) in zip(decls, inits):
(name, typ_ast) = decl_ast.args
if name in symbols:
- report(ENAMECOLL(s.site, symbols[name], name))
+ report(E.NAMECOLL(s.site, symbols[name], name))
else:
symbols[name] = s.site
sessions[name] = (s.site, name, typ_ast, init_ast)
@@ -1798,7 +1794,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
elif s.kind == 'saved':
(decls, inits) = s.args
if inits is not None and len(decls) != len(inits):
- report(ESYNTAX(s.site, None,
+ report(E.SYNTAX(s.site, None,
'wrong number of initializers:\n'
+ f'{len(decls)} variables declared\n'
+ f'{len(inits)} initializers specified'))
@@ -1808,7 +1804,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
for (decl_ast, init_ast) in zip(decls, inits):
(name, typ_ast) = decl_ast.args
if name in symbols:
- report(ENAMECOLL(s.site, symbols[name], name))
+ report(E.NAMECOLL(s.site, symbols[name], name))
else:
symbols[name] = s.site
saved[name] = (s.site, name, typ_ast, init_ast)
@@ -1834,7 +1830,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
for (ident, defs) in subobj_spec_by_ident.items():
if ident in symbols:
for (_, _, _, subobj_spec) in defs:
- report(ENAMECOLL(subobj_spec.site, symbols[ident], ident))
+ report(E.NAMECOLL(subobj_spec.site, symbols[ident], ident))
else:
subobj_defs[ident] = merge_subobj_defs(ident, defs, obj)
@@ -1871,7 +1867,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
trait_method_impls = traits.merge_method_impl_maps(
obj.site, explicit_traits)
- obj_scope = Location(obj, static_indices(obj))
+ obj_scope = c.Location(obj, static_indices(obj))
# Create all method nodes
for name in sorted(method_asts):
if dml.globals.dml_version == (1, 2):
@@ -1897,7 +1893,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
}.get(obj.objtype, set())):
if dml.globals.traits[name] not in ancestors:
(_, mast) = declarations[0]
- report(WNOIS(mast.site, name))
+ report(W.NOIS(mast.site, name))
trait_impls = trait_method_impls.get(name, [])
trait_abstract_decls = Set()
@@ -1980,7 +1976,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
or (dml.globals.dml_version == (1, 2)
and obj.objtype != 'device'
and objtype == 'bank')):
- report(ENALLOW(subobj_specs[0].site, obj))
+ report(E.NALLOW(subobj_specs[0].site, obj))
continue
try:
subobj = mkobj(ident, objtype, arrayinfo, subobj_specs, obj,
@@ -1990,7 +1986,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
else:
if subobj.name:
if subobj.name in subobj_name_defs:
- report(ENAMECOLL(subobj.name_site,
+ report(E.NAMECOLL(subobj.name_site,
subobj_name_defs[subobj.name],
subobj.name))
continue
@@ -1998,7 +1994,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
# named "dev", as the device object's serialized identity
# logname is "dev", and must be unique
elif subobj.name == 'dev' and obj.objtype == 'device':
- report(ENAMECOLL(subobj.name_site, obj.site, 'dev'))
+ report(E.NAMECOLL(subobj.name_site, obj.site, 'dev'))
continue
subobj_name_defs[subobj.name] = (
subobj.name_site if
@@ -2009,7 +2005,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
for o in subobjs:
obj.add_component(o)
- # Map name to MethodFunc.
+ # Map name to codegen.MethodFunc.
trait_method_overrides = {}
# Map name to objects.Parameter.
trait_param_nodes = {}
@@ -2040,18 +2036,18 @@ def mkobj2(obj, obj_specs, params, each_stmts):
assert member_kind in {'method', 'parameter'}
for (tsite, t) in obj_traits:
if t.implements(decl_trait):
- raise EABSTEMPLATE(
+ raise E.ABSTEMPLATE(
tsite, decl_site, decl_trait.name,
member_kind, member)
raise ICE(decl_trait.site,
- 'no site found for EABSTEMPLATE(%s)' % (member,))
+ 'no site found for E.ABSTEMPLATE(%s)' % (member,))
elif len(impl_traits) > 1:
# report error: override required to resolve ambiguity
assert member_kind == 'method'
sm0 = impl_traits[0].method_impls[member]
sm1 = impl_traits[1].method_impls[member]
- raise EAMBINH(sm0.site,
+ raise E.AMBINH(sm0.site,
sm1.site,
sm0.name,
RankDesc('template', sm0.trait.name),
@@ -2063,7 +2059,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
if override.objtype != decl_trait.member_kind(member):
# e.g. an attempt to override a parameter with a method
- report(ENAMECOLL(override.site, decl_site, member))
+ report(E.NAMECOLL(override.site, decl_site, member))
continue
vtable_trait = trait.vtable_trait(member)
@@ -2073,14 +2069,14 @@ def mkobj2(obj, obj_specs, params, each_stmts):
if not override.fully_typed:
for p in override.inp:
if p.inlined:
- raise EMETH(
+ raise E.METH(
override.site, tsite,
'input argument declared without a type')
if dml.globals.dml_version == (1, 2):
# untyped outputs only exist in 1.2
for (n, t) in override.outp:
if not t:
- raise EMETH(
+ raise E.METH(
override.site, tsite,
'output argument declared without a type')
raise ICE(override.site, 'no untyped args')
@@ -2111,12 +2107,12 @@ def mkobj2(obj, obj_specs, params, each_stmts):
obj.site, [(b, (), b.dimsizes) for b in banks]))
for b in banks:
- for indices in all_index_exprs(b):
+ for indices in c.all_index_exprs(b):
funexpr = param_expr(b, 'function', indices)
if defined(funexpr):
- funnum = expr_intval(funexpr)
+ funnum = expr_util.expr_intval(funexpr)
if funnum in used:
- report(EDBFUNC(param_expr(b, 'function'),
+ report(E.DBFUNC(param_expr(b, 'function'),
param_expr(used[funnum], 'function'),
funnum))
else:
@@ -2135,31 +2131,31 @@ def mkobj2(obj, obj_specs, params, each_stmts):
and global_scope.lookup(p.name) is None):
try:
global_scope.add(
- ExpressionSymbol(p.name, p.get_expr(()), p.site))
+ c.ExpressionSymbol(p.name, p.get_expr(()), p.site))
except DMLError:
# handled later
pass
# Evaluate all parameters once, to early smoke out non-existing
# identifiers. TODO: perhaps this should not be done?
- zero_index = (mkIntegerLiteral(obj.site, 0),)
+ zero_index = (c.mkIntegerLiteral(obj.site, 0),)
for param in obj.get_recursive_components('parameter'):
with ExitStack() as stack:
- stack.enter_context(ErrorContext(param, None))
+ stack.enter_context(logging.ErrorContext(param, None))
stack.enter_context(crep.DeviceInstanceContext())
try:
try:
# Evaluate statically, because it triggers caching
# in ASTParamExpr
param.get_expr(static_indices(param.parent))
- except EIDXVAR as e:
+ except E.IDXVAR as e:
# Dependency on index variable, re-evaluate at one
# index to capture errors early
param.get_expr(zero_index * param.dimensions)
except DMLError as e:
if (dml.globals.dml_version == (1, 2)
and dml.globals.api_version <= breaking_changes.api_5
- and isinstance(e, EREF)):
+ and isinstance(e, E.REF)):
# We forgive some errors in unused parameters, to
# avoid the annoyance caused by hard errors from code
# that used to compile fine.
@@ -2173,7 +2169,7 @@ def mkobj2(obj, obj_specs, params, each_stmts):
#
# In future versions, we should not forgive
# broken dead parameters. This is SIMICS-9886.
- WREF.instances.append(WREF(
+ W.REF.instances.append(W.REF(
param.site, param.logname(), e))
else:
report(e)
@@ -2184,52 +2180,52 @@ def mkobj2(obj, obj_specs, params, each_stmts):
for p in obj.get_components():
sym = global_scope.lookup(p.name)
if sym and (
- # hacky workaround for the ExpressionSymbol
+ # hacky workaround for the c.ExpressionSymbol
# implicitly added above. Needed when importing 1.4
# code from 1.2 with --breaking-change=dml12_remove_misc_quirks
dml.globals.dml_version != (1, 2)
or p.site.dml_version() == (1, 2)
or p.site != sym.site):
- report(ENAMECOLL(p.site, sym.site, p.name))
+ report(E.NAMECOLL(p.site, sym.site, p.name))
# At this point, methods and subobjs are created and we can
# try to evaluate their exporting
for export in exports:
method_ref_ast, name_ast = (export.args)
- method_ref = codegen_expression_maybe_nonvalue(
+ method_ref = codegen.codegen_expression_maybe_nonvalue(
method_ref_ast, obj_scope, global_scope)
- name_expr = codegen_expression(name_ast, obj_scope, global_scope)
+ name_expr = codegen.codegen_expression(name_ast, obj_scope, global_scope)
# By continuing we can discover more error, since exports
# have no effect if invalid
- if not isinstance(method_ref, NodeRef):
- report(ENOBJ(method_ref_ast.site, method_ref))
+ if not isinstance(method_ref, c.NodeRef):
+ report(E.NOBJ(method_ref_ast.site, method_ref))
continue
method, indices = method_ref.get_ref()
if not isinstance(method, objects.Method):
- report(ENMETH(method_ref_ast.site, method))
+ report(E.NMETH(method_ref_ast.site, method))
continue
if indices:
- report(EEXPORT(method.site, method))
+ report(E.EXPORT(method.site, method))
continue
if not method.fully_typed:
- report(EEXPORT(method.site, export.site))
+ report(E.EXPORT(method.site, export.site))
continue
- name = expr_strval(name_expr)
+ name = expr_util.expr_strval(name_expr)
if not re.match(r"[A-Za-z_][\w_]*", name):
- report(ENAMEID(name_ast.site, name))
+ report(E.NAMEID(name_ast.site, name))
continue
if method.throws or len(method.outp) > 1:
- report(EEXPORT(method.site, export.site))
+ report(E.EXPORT(method.site, export.site))
continue
- func = method_instance(method)
- mark_method_referenced(func)
- mark_method_exported(func, name, export.site)
+ func = codegen.method_instance(method)
+ codegen.mark_method_referenced(func)
+ codegen.mark_method_exported(func, name, export.site)
elif obj.objtype == 'bank':
set_confidential_object(obj)
if logging.show_porting:
if param_defined(obj, 'function'):
- report(PABSTRACT_TEMPLATE(symbols['function'],
+ report(P.ABSTRACT_TEMPLATE(symbols['function'],
'function_mapped_bank'))
elif obj.objtype == 'register':
@@ -2243,13 +2239,13 @@ def field_msb(field):
register_fields(obj),
key = field_msb)
if obj.wholefield:
- if not param_bool_fixup(obj, 'allocate', True):
+ if not c.param_bool_fixup(obj, 'allocate', True):
if method_is_std(obj, 'set'):
obj.writable = False
if method_is_std(obj, 'get'):
obj.readable = False
else:
- if not any(param_bool_fixup(f, 'allocate', True)
+ if not any(c.param_bool_fixup(f, 'allocate', True)
for (f, _, _, _) in fields):
if all(method_is_std(f, 'set') for (f, _, _, _) in fields):
obj.writable = False
@@ -2262,18 +2258,18 @@ def field_msb(field):
# Check that the fields don't overlap
(lsf, _, lsb, _) = fields[0]
if lsb < 0:
- raise EBITRR(lsf)
+ raise E.BITRR(lsf)
for ((lsf, li, lsb, _), (msf, mi, _, msb)) in zip(fields[1:],
fields[:-1]):
if lsb <= msb:
reg_indices = (0,) * (lsf.dimensions - len(li))
- report(EBITRO(lsf, tuple(mkIntegerLiteral(None, i)
+ report(E.BITRO(lsf, tuple(c.mkIntegerLiteral(None, i)
for i in reg_indices + li),
- msf, tuple(mkIntegerLiteral(None, i)
+ msf, tuple(c.mkIntegerLiteral(None, i)
for i in reg_indices + mi)))
(msf, _, _, msb) = fields[-1]
if msb >= param_int(obj, 'bitsize'):
- raise EBITRR(msf)
+ raise E.BITRR(msf)
# Set the 'fields' parameter
obj.fields = [field for (field, _, _, _) in fields]
@@ -2281,7 +2277,7 @@ def field_msb(field):
obj.site,
# Always expand all indices: the list order is
# significant, and two field arrays may be interleaved
- [(f, tuple(mkIntegerLiteral(f.site, i) for i in indices), ())
+ [(f, tuple(c.mkIntegerLiteral(f.site, i) for i in indices), ())
for (f, indices, _, _) in fields]))
else: # DML version >= 1.4
if not param_bool(obj, 'writable'):
@@ -2292,9 +2288,9 @@ def field_msb(field):
if not obj.writable or not obj.readable:
confparam = param_str(obj, 'configuration')
if not obj.writable and not obj.readable and confparam != "none":
- raise EANULL(obj.site)
+ raise E.ANULL(obj.site)
if confparam in {'required', 'optional'}:
- raise EACHK(obj.site)
+ raise E.ACHK(obj.site)
elif obj.objtype == 'field':
if dml.globals.dml_version == (1, 2) and obj.ident == None:
@@ -2305,7 +2301,7 @@ def field_msb(field):
if not param_defined(obj,
'attr_type' if dml.globals.dml_version == (1, 2)
else '_attr_type'):
- raise EATYPE(obj)
+ raise E.ATYPE(obj)
if ((dml.globals.dml_version == (1, 2)
and method_is_std(obj, 'set_attribute')
@@ -2325,15 +2321,15 @@ def field_msb(field):
if not obj.writable or not obj.readable:
confparam = param_str(obj, 'configuration')
if not obj.writable and not obj.readable and confparam != "none":
- raise EANULL(obj.site)
+ raise E.ANULL(obj.site)
if confparam in {'required', 'optional'}:
- raise EACHK(obj.site)
+ raise E.ACHK(obj.site)
if logging.show_porting and dml.globals.dml_version == (1, 2):
param = obj.get_component('allocate_type')
atype_expr = param.get_expr(static_indices(obj))
if defined(atype_expr):
- atype = expr_strval(atype_expr)
+ atype = expr_util.expr_strval(atype_expr)
type_param = obj.get_component('type')
# if 'parameter type = "i"' appears together with allocate_type,
# then remove that as well
@@ -2350,15 +2346,15 @@ def field_msb(field):
# be enum saved as string. Trust that the getter/setter
# works in this case, but remove the allocate_type
# (SIMICS-23126).
- report(PATTRIBUTE(obj.site, None, param.site, None))
+ report(P.ATTRIBUTE(obj.site, None, param.site, None))
elif atype.startswith('uint'):
- report(PATTRIBUTE(obj.site, 'uint64_attr', param.site,
+ report(P.ATTRIBUTE(obj.site, 'uint64_attr', param.site,
type_site))
elif atype.startswith('int'):
- report(PATTRIBUTE(obj.site, 'int64_attr', param.site,
+ report(P.ATTRIBUTE(obj.site, 'int64_attr', param.site,
type_site))
elif atype in {'double', 'bool'}:
- report(PATTRIBUTE(obj.site, atype + '_attr', param.site,
+ report(P.ATTRIBUTE(obj.site, atype + '_attr', param.site,
type_site))
elif obj.objtype == 'connect':
@@ -2371,17 +2367,17 @@ def field_msb(field):
elif obj.objtype == 'interface':
typename = param_str(obj, 'c_type' if dml.globals.dml_version == (1, 2)
else '_c_type')
- t = TPtr(TNamed(typename, const=True))
+ t = tp.Ptr(tp.Named(typename, const=True))
t.declaration_site = obj.site
try:
- realtype(t)
- except DMLUnknownType:
- raise EIFTYPE(obj, t)
+ tp.realtype(t)
+ except tp.DMLUnknownType:
+ raise E.IFTYPE(obj, t)
elif obj.objtype == 'event':
if (dml.globals.dml_version == (1, 2)
and param_str(obj, 'timebase') == 'stacked'):
- report(WDEPRECATED(obj.get_component('timebase').site,
+ report(W.DEPRECATED(obj.get_component('timebase').site,
"stacked events are deprecated"))
if logging.show_porting and dml.globals.dml_version == (1, 2):
timebase = param_str(obj, 'timebase')
@@ -2392,39 +2388,39 @@ def field_msb(field):
else '_cycle_event')
if method_is_std(obj, 'get_event_info'):
prefix = 'simple'
- report(PCHANGE_INARGS(obj.get_component('event').site,
+ report(P.CHANGE_INARGS(obj.get_component('event').site,
'method event()'))
else:
prefix = 'custom'
- report(PEVENT(obj.site, f'{prefix}{suffix}', param_site, None))
+ report(P.EVENT(obj.site, f'{prefix}{suffix}', param_site, None))
return obj
def set_confidential_object(obj):
expr = param_expr(obj, '_confidentiality')
- val = expr_intval(expr) if defined(expr) else 0
+ val = expr_util.expr_intval(expr) if defined(expr) else 0
if (val - dml.globals.build_confidentiality) > 0:
obj._confidential = True
if obj.objtype in {'register', 'field'} and obj.name:
- setparam(obj, 'name', SimpleParamExpr(mkHiddenName(
+ setparam(obj, 'name', c.SimpleParamExpr(c.mkHiddenName(
obj.site, obj.name, obj)))
setparam(obj, 'qname', HiddenQNameParamExpr(obj))
def get_register_registers(reg, indexvars):
# Get a flat list of all individual registers in a potential
- # register array. Return it as list of NodeRef objects
+ # register array. Return it as list of c.NodeRef objects
# Obtain all combinations of indices into a potentially
# multi-dimensional array
index_crossproduct = itertools.product(*(
- (mkIntegerLiteral(reg.site, i) for i in range(array_len))
+ (c.mkIntegerLiteral(reg.site, i) for i in range(array_len))
for array_len in reg.arraylens()))
- return [mkNodeRef(reg.site, reg,
+ return [c.mkNodeRef(reg.site, reg,
indexvars +
indices) for indices in index_crossproduct]
def get_group_registers(group, indexvars):
# Get a flat list of all individual registers in a bank/group.
- # Return it as list of NodeRef objects
+ # Return it as list of c.NodeRef objects
subnodes = group.get_components('group', 'register')
regs = []
@@ -2433,7 +2429,7 @@ def get_group_registers(group, indexvars):
# Obtain all combinations of indices into a potentially
# multi-dimensional array
index_crossproduct = itertools.product(*(
- (mkIntegerLiteral(None, i) for i in range(array_len))
+ (c.mkIntegerLiteral(None, i) for i in range(array_len))
for array_len in group.arraylens()))
for indices in index_crossproduct:
subindexvars = indexvars + indices
@@ -2462,7 +2458,7 @@ def param_linear_int(param):
uint64 or int64.
'''
class IndexVar(Expression):
- type = TInt(64, True)
+ type = tp.Int(64, True)
@slotsmeta.auto_init
def __init__(self, site, variables): pass
@@ -2504,7 +2500,7 @@ def expr_linear_int(expr):
except DMLError:
return None
try:
- return tuple(c & ((1 << 64) - 1) for c in expr_linear_int(expr))
+ return tuple(coeff & ((1 << 64) - 1) for coeff in expr_linear_int(expr))
except NotLinear:
return None
@@ -2553,7 +2549,7 @@ def explode_offsets(reg):
indices=bank_indices + reg_indices), coord)
for (reg_indices, coord) in zip(
itertools.product(
- *([mkIntegerLiteral(reg.site, i)
+ *([c.mkIntegerLiteral(reg.site, i)
for i in range(dimsize)]
for dimsize in reg.dimsizes[
bank.dimensions:])),
@@ -2583,7 +2579,7 @@ def explode_offsets(reg):
del all_offsets[-1]
for (a, b) in zip(all_offsets, all_offsets[1:]):
if a[1] > b[0]:
- report(EREGOL(a[2], b[2], a[3], b[3]))
+ report(E.REGOL(a[2], b[2], a[3], b[3]))
def check_register_fields(reg):
assert dml.globals.dml_version != (1, 2)
@@ -2593,7 +2589,7 @@ def explode_ranges(field):
assert param.objtype == 'parameter'
ranges = []
for field_indices in itertools.product(
- *([mkIntegerLiteral(field.site, i) for i in range(dimsize)]
+ *([c.mkIntegerLiteral(field.site, i) for i in range(dimsize)]
for dimsize in field.dimsizes[reg.dimensions:])):
reg_indices = tuple(StaticIndex(field.site, var)
for var in reg.idxvars())
@@ -2601,7 +2597,7 @@ def explode_ranges(field):
try:
lsb_expr = param_expr(field, 'lsb', indices)
msb_expr = param_expr(field, 'msb', indices)
- except EIDXVAR:
+ except E.IDXVAR:
# msb/lsb expression dependent on bank/register indices.
# Disregard this field when checking ranges.
return []
@@ -2609,15 +2605,15 @@ def explode_ranges(field):
if isinstance(expr, NonValue):
raise expr.exc()
if expr.constant and not isinstance(expr.value, int):
- raise EBTYPE(expr.site, expr.ctype(), "integer")
+ raise E.BTYPE(expr.site, expr.ctype(), "integer")
if lsb_expr.constant and msb_expr.constant:
lsb = lsb_expr.value
msb = msb_expr.value
if lsb < 0 or bitsize <= msb:
- raise EBITRR(field)
+ raise E.BITRR(field)
if msb < lsb:
- raise EBITRN(field, msb, lsb)
+ raise E.BITRN(field, msb, lsb)
ranges.append((lsb, msb, indices))
return ranges
@@ -2629,7 +2625,7 @@ def explode_ranges(field):
all_ranges.sort(key=lambda t: t[0])
for (a, b) in zip(all_ranges, all_ranges[1:]):
if a[1] >= b[0]:
- report(EBITRO(a[2], a[3], b[2], b[3]))
+ report(E.BITRO(a[2], a[3], b[2], b[3]))
class ParentParamExpr(objects.ParamExpr):
def __init__(self, obj):
@@ -2640,7 +2636,7 @@ def mkexpr(self, indices):
assert len(indices) == self.obj.dimensions
if self.obj.isindexed():
indices = indices[:-self.obj.local_dimensions()]
- return mkNodeRef(self.obj.site, self.obj.parent, indices)
+ return c.mkNodeRef(self.obj.site, self.obj.parent, indices)
class QNameParamExpr(objects.ParamExpr):
def __init__(self, node, relative):
@@ -2650,7 +2646,7 @@ def __init__(self, node, relative):
@property
def site(self): return self.node.site
def mkexpr(self, indices):
- return QName(self.node.site, self.node, self.relative, indices)
+ return c.QName(self.node.site, self.node, self.relative, indices)
class HiddenQNameParamExpr(objects.ParamExpr):
def __init__(self, node):
@@ -2658,16 +2654,16 @@ def __init__(self, node):
@property
def site(self): return self.node.site
def mkexpr(self, indices):
- return HiddenQName(self.node.site, self.node, indices)
+ return c.HiddenQName(self.node.site, self.node, indices)
class ObjectListParamExpr(objects.ParamExpr):
- '''List of DML objects, using a common parent'''
+ '''c.List of DML objects, using a common parent'''
__slots__ = ('site', 'instances')
def __init__(self, site, instances):
self.site = site
self.instances = instances
def mkexpr(self, indices):
- return mkObjectList(
+ return c.mkObjectList(
self.site,
[(node, indices + parent_relative_indices, dimsizes)
for (node, parent_relative_indices, dimsizes) in self.instances])
@@ -2685,7 +2681,7 @@ def site(self): return self.node.site
def mkexpr(self, indices):
if self.cached is not None:
return self.cached
- self.cached = mkStringConstant(
+ self.cached = c.mkStringConstant(
self.node.site,
self.node.logname_anonymized(relative=self.relative))
return self.cached
@@ -2704,12 +2700,12 @@ def mkexpr(self, indices):
if self.cached:
return self.cached
if self in self.params_on_stack:
- raise ERECPARAM([pe.ast.site for pe in self.params_on_stack[
+ raise E.RECPARAM([pe.ast.site for pe in self.params_on_stack[
self.params_on_stack.index(self):]])
self.params_on_stack.append(self)
try:
- expr = codegen_expression_maybe_nonvalue(
- self.ast, Location(self.parent, indices), global_scope)
+ expr = codegen.codegen_expression_maybe_nonvalue(
+ self.ast, c.Location(self.parent, indices), global_scope)
finally:
popped = self.params_on_stack.pop()
assert popped is self
@@ -2724,11 +2720,11 @@ def __init__(self, site, name):
self.site = site
self.name = name
def mkexpr(self, indices):
- raise EUNINITIALIZED(self.site, self.name)
+ raise E.UNINITIALIZED(self.site, self.name)
class EventClassExpr(ctree.LValue):
slots = ('node', 'indices')
- type = TPtr(TNamed('event_class_t'), const=True)
+ type = tp.Ptr(tp.Named('event_class_t'), const=True)
@auto_init
def __init__(self, site, node, indices): pass
def __str__(self):
@@ -2777,7 +2773,7 @@ def __init__(self, site, params):
self.params = params
self.site = site
def mkexpr(self, indices):
- return mkList(self.site,
+ return c.mkList(self.site,
[param.mkexpr(indices) for param in self.params])
class NullParamExpr(objects.ParamExpr):
@@ -2800,7 +2796,7 @@ def __init__(self, site, node):
self.node = node
def mkexpr(self, indices):
- return mkNodeRef(self.site, self.node.nongroup_parent,
+ return c.mkNodeRef(self.site, self.node.nongroup_parent,
indices[:self.node.nongroup_parent.dimensions])
@@ -2813,7 +2809,7 @@ def __init__(self, site, node):
self.node = node
def mkexpr(self, indices):
- return mkTemplatesRef(self.site, self.node, indices)
+ return c.mkTemplatesRef(self.site, self.node, indices)
def port_class_ident(port):
'''The C identifier used for a port class within the device class
@@ -2864,7 +2860,7 @@ def mkexpr(self, indices):
prefix = parent.name + "_" + prefix
parent = parent.parent
- self.cached = mkStringConstant(self.site,
+ self.cached = c.mkStringConstant(self.site,
get_attr_name(prefix, self.node))
return self.cached
@@ -2888,7 +2884,7 @@ def mkexpr(self, indices):
lit = f'&{port_class_ident(object_parent)}'
else:
lit = 'NULL'
- self.cached = mkLit(self.site, lit, TPtr(TPtr(TNamed('conf_class_t'))))
+ self.cached = mkLit(self.site, lit, tp.Ptr(tp.Ptr(tp.Named('conf_class_t'))))
return self.cached
def need_port_proxy_attrs(port):
@@ -2925,12 +2921,12 @@ def mkexpr(self, indices):
'(_dml_attr_parent_obj_proxy_info_t) { .valid = true,'
+ f'.is_bank = {is_bank}, .is_array = {is_array}, '
+ f'.portname = "{object_parent.name}" }}',
- TNamed('_dml_attr_parent_obj_proxy_info_t'))
+ tp.Named('_dml_attr_parent_obj_proxy_info_t'))
else:
self.cached = mkLit(
self.site,
'(_dml_attr_parent_obj_proxy_info_t) { .valid = false }',
- TNamed('_dml_attr_parent_obj_proxy_info_t'))
+ tp.Named('_dml_attr_parent_obj_proxy_info_t'))
return self.cached
class InterfacesDocParamExpr(objects.ParamExpr):
@@ -2959,9 +2955,9 @@ def mkexpr(self, indices):
text += (f'\n\n{req} interface{s}: '
+ ', '.join(f'{iface}'
for iface in sorted(ifaces)))
- self.cached = mkStringConstant(self.site, text)
+ self.cached = c.mkStringConstant(self.site, text)
else:
- self.cached = mkUndefined(self.site)
+ self.cached = c.mkUndefined(self.site)
return self.cached
def mkparam(obj, autoparams, param):
@@ -2978,7 +2974,7 @@ def mkparam(obj, autoparams, param):
name, site, obj, autoparams[name])
elif auto:
# user-supplied 'auto' declaration
- raise EAUTOPARAM(site, name)
+ raise E.AUTOPARAM(site, name)
# caught earlier, ENPARAM
assert value is not None
@@ -2994,7 +2990,7 @@ def port_builtin_method_overrides(name, site, inp_ast, parent_obj):
and parent_obj.objtype in {'bank', 'device'})):
tpl_name = {'read_access': 'read_field',
'write_access': 'write_field'}.get(name, name)
- report(PABSTRACT_TEMPLATE(site, tpl_name))
+ report(P.ABSTRACT_TEMPLATE(site, tpl_name))
known_signatures = {
'bank': {
@@ -3058,7 +3054,7 @@ def port_builtin_method_overrides(name, site, inp_ast, parent_obj):
else:
n = old_idx
new_inp.append(new_type + n)
- report(PCHANGE_INARGS(site, 'method %s(%s)%s' % (
+ report(P.CHANGE_INARGS(site, 'method %s(%s)%s' % (
new_name, ', '.join(new_inp), ' throws' if throws else '')))
# Mapping objkind -> (1.4 trampoline, 1.2 trampoline)
# Two cases:
@@ -3226,11 +3222,11 @@ def port_builtin_method_overrides(name, site, inp_ast, parent_obj):
if name in trampoline_methods:
(tramp14, tramp12) = trampoline_methods[name]
if 'is dml12_compat' in tramp12:
- report(PIMPORT_DML12COMPAT(site))
+ report(P.IMPORT_DML12COMPAT(site))
else:
tramp12 = ('#if (dml_1_2) {\n %s\n}'
% (tramp12.replace('\n', '\n ')))
- report(PTRAMPOLINE(site, tramp14, tramp12))
+ report(P.TRAMPOLINE(site, tramp14, tramp12))
def mkmethod(site, rbrace_site, location, parent_obj, name, inp_ast,
@@ -3245,7 +3241,7 @@ def mkmethod(site, rbrace_site, location, parent_obj, name, inp_ast,
argnames = set()
for (_, tsite, n, t) in named_args:
if n in argnames:
- raise EARGD(tsite, n)
+ raise E.ARGD(tsite, n)
argnames.add(n)
if logging.show_porting and body.site.dml_version() == (1, 2):
@@ -3256,26 +3252,26 @@ def mkmethod(site, rbrace_site, location, parent_obj, name, inp_ast,
# non-integer outputs seem to be rather uncommon.
for (_, psite, pname, ptype) in outp_ast:
if not ptype:
- report(PTYPEDOUTPARAM(psite, 'uint64'))
+ report(P.TYPEDOUTPARAM(psite, 'uint64'))
if not isinstance(default, InvalidDefault):
port_builtin_method_overrides(name, site, inp_ast, parent_obj)
if (default.node and default.node.throws
and default.node.site.dml_version() == (1, 4)):
- report(PTHROWS(body.site))
+ report(P.THROWS(body.site))
- inp = eval_method_inp(inp_ast, location, global_scope)
- outp = eval_method_outp(outp_ast, location, global_scope)
+ inp = codegen.eval_method_inp(inp_ast, location, global_scope)
+ outp = codegen.eval_method_outp(outp_ast, location, global_scope)
for t in [p.typ for p in inp] + [t for (_, t) in outp]:
if t:
- check_named_types(t)
- t = realtype(t)
+ tp.check_named_types(t)
+ t = tp.realtype(t)
if t.is_int and t.is_endian:
- raise EEARG(site)
+ raise E.EARG(site)
for (n, t) in outp:
# See SIMICS-19028
- if t and deep_const(t):
+ if t and tp.deep_const(t):
raise ICE(site,
'Methods with (partially) const output/return '
+ 'values are not yet supported.')
@@ -3289,12 +3285,12 @@ def mkmethod(site, rbrace_site, location, parent_obj, name, inp_ast,
body, default, rbrace_site)
if startup:
(memoized_startups if memoized else startups).append(method)
- func = method_instance(method)
- mark_method_referenced(func)
+ func = codegen.method_instance(method)
+ codegen.mark_method_referenced(func)
if logging.show_porting:
if method.fully_typed:
- PWUNUSED.typed_methods.add(method)
+ P.WUNUSED.typed_methods.add(method)
else:
- PWUNUSED.inline_methods[method.site] = method
+ P.WUNUSED.inline_methods[method.site] = method
return method
diff --git a/py/dml/structure_test.py b/py/dml/structure_test.py
index 78a9a48d1..96f735875 100644
--- a/py/dml/structure_test.py
+++ b/py/dml/structure_test.py
@@ -78,12 +78,12 @@ def test(self):
self.assertEqual(
param_linear_int(self.p(
lambda indices:
- ctree.mkCast(site, indices[0], types.TInt(64, signed)),
+ ctree.mkCast(site, indices[0], types.Int(64, signed)),
(2,))),
(1, 0))
self.assertEqual(
param_linear_int(self.p(
lambda indices:
- ctree.mkCast(site, indices[0], types.TInt(63, signed)),
+ ctree.mkCast(site, indices[0], types.Int(63, signed)),
(2,))),
None)
diff --git a/py/dml/symtab.py b/py/dml/symtab.py
index b136ad432..9860877bb 100644
--- a/py/dml/symtab.py
+++ b/py/dml/symtab.py
@@ -12,8 +12,7 @@
'global_scope',
)
-from .logging import report, ICE, SimpleSite, dbg
-import dml.globals
+from .logging import ICE
class Symbol(object):
"a symbol in a symbol table"
diff --git a/py/dml/template.py b/py/dml/template.py
index 122f220d7..0c49a9c75 100644
--- a/py/dml/template.py
+++ b/py/dml/template.py
@@ -7,8 +7,8 @@
import functools
from . import ast, logging
from . import breaking_changes
-from .logging import *
-from .messages import *
+from .logging import ICE, report
+from . import errors as E, porting as P
from .set import Set
import dml.globals
import dml.traits
@@ -230,9 +230,9 @@ def flatten_ifs(in_each_specs, templates, stmts, preconds):
f, preconds + [neg]))
if logging.show_porting:
if t:
- PWUNUSED.positive_conds.add(cond)
+ P.WUNUSED.positive_conds.add(cond)
if f:
- PWUNUSED.negative_conds.add(neg)
+ P.WUNUSED.negative_conds.add(neg)
elif stmt.kind == 'object':
composite.append(stmt)
elif stmt.kind == 'in_each':
@@ -280,7 +280,7 @@ def obj_from_asts(site, stmts):
'_write_unimplemented': 'write_unimpl',}
for (issite, name) in template_refs:
if name in template_renames:
- report(PRENAME_TEMPLATE(issite, name,
+ report(P.RENAME_TEMPLATE(issite, name,
template_renames[name]))
is_stmts.extend([(issite, templates[name])
for (issite, name) in template_refs])
@@ -380,7 +380,7 @@ def process_templates(template_decls):
# delay error until template instantiation
dml.globals.missing_templates.add(missing)
else:
- report(ENTMPL(site, missing))
+ report(E.NTMPL(site, missing))
template_decls[missing] = (site, [], None)
return process_templates(template_decls)
try:
@@ -393,9 +393,9 @@ def process_templates(template_decls):
(ref_asts, _, _) = rank_structure(asts)
is_sites.append(ref_asts[p].site)
if any(name.startswith('@') for name in e.cycle):
- report(ECYCLICIMP(is_sites))
+ report(E.CYCLICIMP(is_sites))
else:
- report(ECYCLICTEMPLATE(is_sites))
+ report(E.CYCLICTEMPLATE(is_sites))
for name in e.cycle:
# prune the templates that created a cycle
(site, _, _) = template_decls[name]
diff --git a/py/dml/toplevel.py b/py/dml/toplevel.py
index 8e2e347ab..c12603607 100644
--- a/py/dml/toplevel.py
+++ b/py/dml/toplevel.py
@@ -14,13 +14,12 @@
from ply import lex, yacc
-from . import objects, logging, codegen, ctree, ast
+from . import logging, codegen, ctree, ast
from . import breaking_changes
from . import symtab
-from .messages import *
-from .logging import *
+from . import errors as E, warnings as W, porting as P
+from .logging import ICE, DMLError, report
import dml.globals
-import dml.dmllex
import dml.dmlparse
__all__ = ('produce_dmlast', 'get_parser', 'parse_main_file')
@@ -72,7 +71,7 @@ def determine_version(filestr, filename):
column = ver_start - filestr.rfind('\n', 0, ver_start)
m = check_version.match(filestr, pos=ver_start)
if not m:
- raise ESYNTAX(SimpleSite(f"{filename}:{lineno}:{column}"),
+ raise E.SYNTAX(logging.SimpleSite(f"{filename}:{lineno}:{column}"),
None, "malformed DML version tag")
version = (int(m.group('major')), int(m.group('minor')))
# Remove the language version tag, but preserve the correct
@@ -84,30 +83,30 @@ def determine_version(filestr, filename):
filestr = ' ' * ver_end + filestr[ver_end:]
else:
if not breaking_changes.require_version_statement.enabled:
- report(WNOVER(SimpleSite(f"{filename}:1")))
+ report(W.NOVER(logging.SimpleSite(f"{filename}:1")))
version = (1, 2)
lineno = 1
column = 1
else:
- raise ESYNTAX(
- SimpleSite(f"{filename}:1"), None,
+ raise E.SYNTAX(
+ logging.SimpleSite(f"{filename}:1"), None,
"missing DML version statement")
if (not breaking_changes.require_version_statement.enabled
and version == (1, 3)):
- report(WDEPRECATED(
- SimpleSite(f"{filename}:{lineno}:{column}"),
+ report(W.DEPRECATED(
+ logging.SimpleSite(f"{filename}:{lineno}:{column}"),
"'dml 1.3' is a deprecated alias of dml 1.4"))
version = (1, 4)
if version not in supported_versions:
- raise ESYNTAX(SimpleSite(f"{filename}:{lineno}:{column}"), None,
+ raise E.SYNTAX(logging.SimpleSite(f"{filename}:{lineno}:{column}"), None,
"DML version %s not supported; allowed: %s"
% (fmt_version(version),
", ".join(map(fmt_version, supported_versions))))
if logging.show_porting and version == (1, 2):
- report(PVERSION(SimpleSite(f"{filename}:{lineno}:{column}")))
+ report(P.VERSION(logging.SimpleSite(f"{filename}:{lineno}:{column}")))
return (version, filestr)
@@ -123,7 +122,7 @@ def parse(s, file_info, filename, version):
ast = parser.parse(s, lexer = lexer, tracking = True,
tokenfunc = dml.dmlparse.mk_get_token(lexer))
except dml.dmlparse.UnexpectedEOF:
- raise ESYNTAX(DumpableSite(file_info, file_info.size()),
+ raise E.SYNTAX(logging.DumpableSite(file_info, file_info.size()),
None, "unexpected end-of-file")
return ast
@@ -151,7 +150,7 @@ def scan_statements(filename, site, stmts):
elif s.kind == 'toplevel_if':
[cond, tbranch, fbranch, bad_stmts] = s.args
scope = symtab.Symtab()
- bsite = SimpleSite('',
+ bsite = logging.SimpleSite('',
dml_version=dml.globals.dml_version)
# HACK Add constants to scope typically defined by dml-builtins,
# which is not accessible here
@@ -168,10 +167,10 @@ def scan_statements(filename, site, stmts):
expr = ctree.as_bool(codegen.codegen_expression(
cond, None, scope))
if not expr.constant:
- raise ENCONST(expr.site, expr)
- except EIDENT:
+ raise E.NCONST(expr.site, expr)
+ except E.IDENT:
for stmt in bad_stmts:
- report(EBADCONDSTMT(stmt.site, stmt.kind))
+ report(E.BADCONDSTMT(stmt.site, stmt.kind))
except DMLError as e:
report(e)
else:
@@ -203,7 +202,7 @@ def check_bidi(filename, filestr):
for m in bidi_re.finditer(filestr):
lineno = filestr[:m.start()].count('\n') + 1
col = m.start() - filestr.rfind('\n', 0, m.start())
- report(ESYNTAX(SimpleSite(f"{filename}:{lineno}:{col}"),
+ report(E.SYNTAX(logging.SimpleSite(f"{filename}:{lineno}:{col}"),
repr(m.group())[1:-1],
"Unicode BiDi character not allowed"))
@@ -222,7 +221,7 @@ def parse_pragma(filename, start_lineno, end_lineno, pragma, data):
if pragma == 'COVERITY':
data = data and pragma_coverity_data_re.match(data)
if data is None:
- report(ESYNTAX(SimpleSite(f"{filename}:{start_lineno}"),
+ report(E.SYNTAX(logging.SimpleSite(f"{filename}:{start_lineno}"),
None,
"COVERITY pragma must specify event to suppress, "
+ "and optionally classification"))
@@ -230,7 +229,7 @@ def parse_pragma(filename, start_lineno, end_lineno, pragma, data):
return ('COVERITY',
(filename, start_lineno, end_lineno + 1, data.groups()))
else:
- report(EPRAGMA(SimpleSite(f"{filename}:{start_lineno}"), pragma))
+ report(E.PRAGMA(logging.SimpleSite(f"{filename}:{start_lineno}"), pragma))
return None
def process_pragma(t):
@@ -251,15 +250,15 @@ def parse_file(dml_filename):
with open(dml_filename, 'r') as f:
filestr = f.read()
except IOError as msg:
- raise EIMPORT(SimpleSite(f"{dml_filename}:0"), f"{dml_filename}: {msg}")
+ raise E.IMPORT(logging.SimpleSite(f"{dml_filename}:0"), f"{dml_filename}: {msg}")
except UnicodeDecodeError:
with open(dml_filename, 'rb') as f:
for (lineno, line) in enumerate(f):
try:
line.decode('utf-8')
except UnicodeDecodeError as e:
- raise ESYNTAX(
- SimpleSite(
+ raise E.SYNTAX(
+ logging.SimpleSite(
f"{dml_filename}:{lineno + 1}:{e.start + 1}"),
repr(line[e.start:e.end]),
'utf-8 decoding error: ' + e.reason)
@@ -275,7 +274,7 @@ def parse_file(dml_filename):
if version == (1, 2) and logging.show_porting:
with open(dml_filename, 'rb') as f:
sha1 = hashlib.sha1(f.read()).hexdigest() # nosec
- report(PSHA1(SimpleSite(f'{dml_filename}:1:0'), sha1))
+ report(P.SHA1(logging.SimpleSite(f'{dml_filename}:1:0'), sha1))
ast = parse(contents, file_info, dml_filename, version)
return ast
@@ -284,7 +283,7 @@ def load_dmlast(ast_filename):
try:
return pickle.loads(bz2.BZ2File(ast_filename).read()) # nosec
except Exception as e:
- raise ICE(SimpleSite(ast_filename),
+ raise ICE(logging.SimpleSite(ast_filename),
"Failed to load AST from %r: %s"
% (ast_filename, e))
@@ -318,7 +317,7 @@ def parse_dmlast_or_dml(dml_filename):
# This detects a common error: after getting a compile
# error in dml-builtins.dml, one accidentally edits the
# copy in [host]/bin/dml/, instead of the one in the repo.
- report(WOLDAST(dml_filename))
+ report(W.OLDAST(dml_filename))
else:
file_info, pragmas, parsedata = load_dmlast(ast_filename)
if file_info.name is None:
@@ -341,7 +340,7 @@ def import_file(importsite, path):
version = site.dml_version()
if (version != dml.globals.dml_version
and (version, dml.globals.dml_version) != ((1, 4), (1, 2))):
- raise EVERS(SimpleSite(f"{path}:0"),
+ raise E.VERS(logging.SimpleSite(f"{path}:0"),
importsite,
fmt_version(version),
fmt_version(importsite.dml_version()))
@@ -350,7 +349,7 @@ def import_file(importsite, path):
assert version in ((1, 2), (1, 4))
if name is not None:
- raise EDEVIMP(importsite)
+ raise E.DEVIMP(importsite)
return (site, stmts)
def exists(filename):
@@ -362,7 +361,7 @@ def exists(filename):
def parse_main_file(inputfilename, explicit_import_path):
if not exists(inputfilename):
- raise ENOFILE(SimpleSite(f"{inputfilename}:0"))
+ raise E.NOFILE(logging.SimpleSite(f"{inputfilename}:0"))
(kind, site, name, stmts) = parse_dmlast_or_dml(
str(Path(inputfilename).resolve()))
# guaranteed by grammar
@@ -387,7 +386,7 @@ def parse_main_file(inputfilename, explicit_import_path):
global_defs.append(ast.template_dml12(site, '@' + inputfilename, spec_asts))
if name is None:
- raise EDEVICE(site)
+ raise E.DEVICE(site)
# Also look in a subdir named like the DML version
import_path = [
@@ -399,7 +398,7 @@ def parse_main_file(inputfilename, explicit_import_path):
# we may want to bump last version to 8 if we want to postpone the
# deprecation of DML 1.2
if version == (1, 2) and dml.globals.api_version > breaking_changes.api_7:
- raise ESIMAPI(site, fmt_version(version), dml.globals.api_version.str)
+ raise E.SIMAPI(site, fmt_version(version), dml.globals.api_version.str)
# Map normalized, absolute path of an imported file, to list of
# seen spellings. One spelling is a string in an import statement which
@@ -423,7 +422,7 @@ def parse_main_file(inputfilename, explicit_import_path):
path = find_file_in_dirs(importfile, import_path)
try:
if path is None:
- raise EIMPORT(importsite, importfile)
+ raise E.IMPORT(importsite, importfile)
deps.setdefault(path, set()).add(importfile)
diff --git a/py/dml/traits.py b/py/dml/traits.py
index 6be9de04f..fead3b2d7 100644
--- a/py/dml/traits.py
+++ b/py/dml/traits.py
@@ -8,17 +8,18 @@
import contextlib
import abc
import os
-from . import objects, logging, crep, codegen, toplevel, topsort
+from . import crep, codegen, symtab, topsort
+from .symtab import global_scope
from . import breaking_changes, provisional
-from .logging import *
-from .codegen import *
-from .symtab import *
-from .ctree import *
-from .expr import *
-from .expr_util import *
-from .messages import *
+from . import logging
+from .template import Rank
+from .logging import ICE, DMLError, report
+from .codegen import c_extra_inargs, c_rettype, eval_type
+from . import ctree as c
+from .expr import mkLit, NonValue
+from . import errors as E, warnings as W
from .slotsmeta import auto_init
-from .types import *
+from . import types as tp
from .set import Set
import dml.globals
@@ -27,7 +28,6 @@
'merge_ancestor_vtables',
'typecheck_method_override',
'ObjTraits',
- 'TraitObjMethod',
'mktrait',
'NoDefaultSymbol',
'AmbiguousDefaultSymbol',
@@ -42,16 +42,16 @@ def process_trait(site, name, subasts, ancestors, template_symbols):
def check_namecoll(name, site):
if name in methods:
(othersite, _, _, _, _, _, _, _, _, _, _) = methods[name]
- raise ENAMECOLL(site, othersite, name)
+ raise E.NAMECOLL(site, othersite, name)
if name in params:
(othersite, _) = params[name]
- raise ENAMECOLL(site, othersite, name)
+ raise E.NAMECOLL(site, othersite, name)
if name in sessions:
(othersite, _) = sessions[name]
- raise ENAMECOLL(site, othersite, name)
+ raise E.NAMECOLL(site, othersite, name)
if name in hooks:
(othersite, _, _) = hooks[name]
- raise ENAMECOLL(site, othersite, name)
+ raise E.NAMECOLL(site, othersite, name)
for ast in subasts:
try:
@@ -62,13 +62,13 @@ def check_namecoll(name, site):
startup = 'startup' in qualifiers
memoized = 'memoized' in qualifiers
if (startup and not independent) or (memoized and not startup):
- raise ICE(impl.site,
+ raise ICE(ast.site,
'Invalid qualifier combination: '
+ ' '.join(['independent']*independent
+ ['startup']*startup
+ ['memoized']*memoized))
- inp = eval_method_inp(inp_asts, None, global_scope)
- outp = eval_method_outp(outp_asts, None, global_scope)
+ inp = codegen.eval_method_inp(inp_asts, None, global_scope)
+ outp = codegen.eval_method_outp(outp_asts, None, global_scope)
check_namecoll(mname, ast.site)
methods[mname] = (ast.site, inp, outp, throws, independent,
startup, memoized, overridable,
@@ -79,7 +79,7 @@ def check_namecoll(name, site):
(sname, type_ast) = decl_ast.args
(struct_defs, stype) = eval_type(
type_ast, ast.site, None, global_scope)
- add_late_global_struct_defs(struct_defs)
+ tp.add_late_global_struct_defs(struct_defs)
check_namecoll(sname, ast.site)
sessions[sname] = (ast.site, stype)
elif ast.kind == 'param':
@@ -90,7 +90,7 @@ def check_namecoll(name, site):
global_scope)
# this would be trivial to support, but completely meaningless
for (err_site, _) in struct_defs:
- report(EANONSTRUCT(err_site, "parameter type"))
+ report(E.ANONSTRUCT(err_site, "parameter type"))
check_namecoll(pname, ast.site)
params[pname] = (ast.site, ptype)
elif ast.kind == 'hook':
@@ -100,10 +100,10 @@ def check_namecoll(name, site):
for type_ast in type_asts:
(struct_defs, dtype) = eval_type(type_ast, ast.site, None,
global_scope)
- add_late_global_struct_defs(struct_defs)
- # TODO maybe realtype?
+ tp.add_late_global_struct_defs(struct_defs)
+ # TODO maybe tp.realtype?
msg_types.append(dtype)
- array_lens = tuple(eval_arraylen(len_ast, global_scope)
+ array_lens = tuple(codegen.eval_arraylen(len_ast, global_scope)
for len_ast in arraylen_asts)
check_namecoll(hname, ast.site)
hooks[hname] = (ast.site, array_lens, msg_types)
@@ -114,7 +114,7 @@ def check_namecoll(name, site):
return mktrait(site, name, ancestors, methods, params, sessions, hooks,
template_symbols)
-class NoDefaultSymbol(Symbol):
+class NoDefaultSymbol(symtab.Symbol):
"""A broken reference to 'default' inside a method that has no default
method. This is represented as an explicit symbol in order to
report ENDEFAULT instead of the slightly less informative
@@ -122,9 +122,9 @@ class NoDefaultSymbol(Symbol):
def __init__(self, site):
super(NoDefaultSymbol, self).__init__('default', site=site)
def expr(self, site):
- raise ENDEFAULT(site)
+ raise E.NDEFAULT(site)
-class AmbiguousDefaultSymbol(Symbol):
+class AmbiguousDefaultSymbol(symtab.Symbol):
"""A broken reference to 'default' inside a method that has two
possible parent methods. This is represented as an explicit
symbol in order to report EAMBDEFAULT instead of the slightly
@@ -134,7 +134,7 @@ def __init__(self, default_method_sites):
'default', site=default_method_sites[0])
self.default_method_sites = default_method_sites
def expr(self, site):
- raise EAMBDEFAULT(site, self.default_method_sites)
+ raise E.AMBDEFAULT(site, self.default_method_sites)
class TraitVTableItem(metaclass=abc.ABCMeta):
'''A value for a struct field in a vtable instance'''
@@ -180,10 +180,10 @@ def memo_outs_struct(self):
assert self.memoized
if self._memo_outs_struct is None:
memo_dict = {'p_' + name: typ for (name, typ) in self.outp}
- memo_dict['ran'] = TInt(8, True)
+ memo_dict['ran'] = tp.Int(8, True)
if self.throws:
- memo_dict['threw'] = TBool()
- self._memo_outs_struct = TStruct(
+ memo_dict['threw'] = tp.Bool()
+ self._memo_outs_struct = tp.Struct(
memo_dict, label=f'_memo_{self.trait.name}__{self.name}')
return self._memo_outs_struct
@@ -224,9 +224,9 @@ def declaration(self):
def codegen_body(self):
with (crep.DeviceInstanceContext()
if not self.independent else contextlib.nullcontext()):
- scope = MethodParamScope(self.trait.scope(global_scope))
+ scope = symtab.MethodParamScope(self.trait.scope(global_scope))
implicit_inargs = self.vtable_trait.implicit_args()
- site = SimpleSite(self.site.loc())
+ site = logging.SimpleSite(self.site.loc())
if len(self.default_traits) > 1:
default = AmbiguousDefaultSymbol(
[trait.method_impls[self.name].site
@@ -235,11 +235,11 @@ def codegen_body(self):
[default_trait] = self.default_traits
default_method = default_trait.method_impls[self.name]
[(name, typ)] = implicit_inargs
- default = ExpressionSymbol(
+ default = c.ExpressionSymbol(
'default',
- TraitMethodDirect(
+ c.TraitMethodDirect(
default_method.site,
- mkLit(site, cident(name), typ),
+ mkLit(site, tp.cident(name), typ),
default_method),
site)
else:
@@ -247,7 +247,7 @@ def codegen_body(self):
for (n, t) in self.outp:
# See SIMICS-19028
- if deep_const(t):
+ if tp.deep_const(t):
raise ICE(self.site,
'Methods with (partially) const output/return '
+ 'values are not yet supported.')
@@ -257,21 +257,21 @@ def codegen_body(self):
memoization = codegen.SharedIndependentMemoized(self)
else:
memoization = None
- body = codegen_method(
+ body = codegen.codegen_method(
self.astbody.site, self.inp, self.outp, self.throws,
self.independent, memoization, self.astbody, default,
- Location(dml.globals.device, ()), scope, self.rbrace_site)
+ c.Location(dml.globals.device, ()), scope, self.rbrace_site)
downcast_path = self.downcast_path()
if downcast_path:
- trait_decl = mkInline(
+ trait_decl = c.mkInline(
site,
'%s UNUSED = DOWNCAST(%s, %s, %s);' % (
- self.trait.type().declaration('_' + cident(self.trait.name)),
- '_' + cident(self.vtable_trait.name),
- cident(self.trait.name),
- '.'.join(cident(t.name) for t in downcast_path)))
- body = mkCompound(site, [trait_decl, body])
+ self.trait.type().declaration('_' + tp.cident(self.trait.name)),
+ '_' + tp.cident(self.vtable_trait.name),
+ tp.cident(self.trait.name),
+ '.'.join(tp.cident(t.name) for t in downcast_path)))
+ body = c.mkCompound(site, [trait_decl, body])
return body
def merge_ancestor_vtables(ancestors, site):
@@ -285,7 +285,7 @@ def merge_ancestor_vtables(ancestors, site):
# This may mean that an abstract method or parameter is
# defined in two traits. We could allow this, as long
# as types match, and it's overridden in an unambiguous way.
- report(EAMBINH(site, None, name,
+ report(E.AMBINH(site, None, name,
ancestor.name, ancestor_vtables[name].name))
else:
ancestor_vtables[name] = ancestor
@@ -308,7 +308,7 @@ def mktrait(site, tname, ancestors, methods, params, sessions, hooks,
if coll:
(orig_site, _) = coll
(param_site, _) = params[name]
- report(ENAMECOLL(param_site, orig_site, name))
+ report(E.NAMECOLL(param_site, orig_site, name))
bad_params.append(name)
for name in bad_params:
del params[name]
@@ -320,7 +320,7 @@ def mktrait(site, tname, ancestors, methods, params, sessions, hooks,
if coll:
(orig_site, _) = coll
(session_site, _) = sessions[name]
- report(ENAMECOLL(session_site, orig_site, name))
+ report(E.NAMECOLL(session_site, orig_site, name))
bad_sessions.append(name)
for name in bad_sessions:
del sessions[name]
@@ -333,7 +333,7 @@ def mktrait(site, tname, ancestors, methods, params, sessions, hooks,
for p in inp:
if p.ident:
if p.ident in argnames:
- report(EARGD(msite, p.ident))
+ report(E.ARGD(msite, p.ident))
bad_methods.add(name)
argnames.add(p.ident)
@@ -345,7 +345,7 @@ def mktrait(site, tname, ancestors, methods, params, sessions, hooks,
(orig_site, orig_trait) = coll
if orig_trait.member_kind(name) != 'method':
# cannot override non-method with method
- report(ENAMECOLL(msite, orig_site, name))
+ report(E.NAMECOLL(msite, orig_site, name))
bad_methods.add(name)
elif body is None and name in ancestor_vtables:
@@ -354,28 +354,28 @@ def mktrait(site, tname, ancestors, methods, params, sessions, hooks,
# declarations would make no sense, because the
# only sensible interpretation would be to ignore
# the declaration.
- report(EAMETH(msite, orig_site, name))
+ report(E.AMETH(msite, orig_site, name))
bad_methods.add(name)
elif (name in orig_trait.method_impls
and not orig_trait.method_impls[name].overridable):
- report(EDMETH(msite, orig_trait.method_impls[name].site,
+ report(E.DMETH(msite, orig_trait.method_impls[name].site,
name))
bad_methods.add(name)
elif explicit_decl:
- report(EOVERRIDEMETH(msite, orig_site, name,
+ report(E.OVERRIDEMETH(msite, orig_site, name,
'default ' * overridable))
bad_methods.add(name)
elif name not in ancestor_vtables:
raise ICE(msite,
'ancestor is overridable but not in vtable')
- # Type-checking of overrides is done later, after typedefs
+ # Type-checking of overrides is done later, after tp.typedefs
# have been populated with all template types.
# See Trait.typecheck_methods()
if (body is not None and not some_coll and not explicit_decl
and msite.provisional_enabled(provisional.explicit_method_decls)):
- report(ENOVERRIDEMETH(msite, name, 'default ' * overridable))
+ report(E.NOVERRIDEMETH(msite, name, 'default ' * overridable))
bad_methods.add(name)
for name in bad_methods:
@@ -388,7 +388,7 @@ def mktrait(site, tname, ancestors, methods, params, sessions, hooks,
if coll:
(orig_site, _) = coll
(session_site, _, _) = hooks[name]
- report(ENAMECOLL(session_site, orig_site, name))
+ report(E.NAMECOLL(session_site, orig_site, name))
bad_hooks.append(name)
for name in bad_hooks:
del hooks[name]
@@ -411,33 +411,33 @@ def typecheck_method_override(left, right):
(site0, inp0, outp0, throws0, independent0, startup0, memoized0) = left
(site1, inp1, outp1, throws1, independent1, startup1, memoized1) = right
if len(inp0) != len(inp1):
- raise EMETH(site0, site1, "different number of input arguments")
+ raise E.METH(site0, site1, "different number of input arguments")
if len(outp0) != len(outp1):
- raise EMETH(site0, site1, "different number of output arguments")
+ raise E.METH(site0, site1, "different number of output arguments")
if throws0 != throws1:
- raise EMETH(site0, site1, "different 'throws' annotations")
+ raise E.METH(site0, site1, "different 'throws' annotations")
for (p0, p1) in zip(inp0, inp1):
- t0 = safe_realtype_unconst(p0.typ)
- t1 = safe_realtype_unconst(p1.typ)
+ t0 = tp.safe_realtype_unconst(p0.typ)
+ t1 = tp.safe_realtype_unconst(p1.typ)
ok = (t0.eq_fuzzy(t1)
if not breaking_changes.strict_typechecking.enabled
else t0.eq(t1))
if not ok:
- raise EMETH(site0, site1,
+ raise E.METH(site0, site1,
f"mismatching types in input argument {p0.logref}")
for (i, ((_, t0), (_, t1))) in enumerate(zip(outp0, outp1)):
- t0 = safe_realtype_unconst(t0)
- t1 = safe_realtype_unconst(t1)
+ t0 = tp.safe_realtype_unconst(t0)
+ t1 = tp.safe_realtype_unconst(t1)
ok = (t0.eq_fuzzy(t1)
if not breaking_changes.strict_typechecking.enabled
else t0.eq(t1))
if not ok:
- raise EMETH(site0, site1,
+ raise E.METH(site0, site1,
"mismatching types in output argument %d" % (i + 1,))
def qualifier_check(qualifier_name, qualifier0, qualifier1):
if qualifier0 != qualifier1:
- raise EMETH(site0, site1,
+ raise E.METH(site0, site1,
(f"one declaration is qualified as {qualifier_name}, "
+ "but the other is not"))
@@ -500,7 +500,7 @@ def merge_method_impl_maps(site, parents):
and (len(existing_impls) != 1
or existing_impls[0].method_impls[
mname].overridable))):
- report(EAMBINH(
+ report(E.AMBINH(
site, None, mname,
unmerged_impl.name,
existing_impls[0].name))
@@ -587,7 +587,7 @@ def is_default(r):
return rank_to_method[r].overridable
[r1, r2] = sorted(minimal_ancestry[None], key=is_default)[:2]
- raise EAMBINH(rank_to_method[r1].site,
+ raise E.AMBINH(rank_to_method[r1].site,
rank_to_method[r2].site,
rank_to_method[r1].name,
r1.desc, r2.desc,
@@ -604,10 +604,10 @@ def is_default(r):
if (dml.globals.dml_version == (1, 2)
and os.path.basename(m.site.filename()) != 'dml12-compatibility.dml'):
if len(implementations) > 2:
- report(WEXPERIMENTAL(
+ report(W.EXPERIMENTAL(
m.site, "more than one level of method overrides"))
if len(implementations) == 2 and m.overridable:
- report(WEXPERIMENTAL(
+ report(W.EXPERIMENTAL(
m.site, "method with two default declarations"))
return (method_map, method_order)
@@ -692,7 +692,7 @@ def lookup_shared_method_impl(self, site, name, indices):
assert isinstance(indices, tuple)
for trait in self.direct_parents:
if name in trait.method_impl_traits:
- ref = ObjTraitRef(site, self.node, trait, indices)
+ ref = c.ObjTraitRef(site, self.node, trait, indices)
method = trait.lookup(name, ref, site)
assert method
return method
@@ -716,7 +716,7 @@ def exc(self):
# template type, but not if declared inside #if
'subobj': 'subobject %s',
}[self.kind] % (self.name,)
- return ENSHARED(self.site, fmt, self.template, self.decl_site)
+ return E.NSHARED(self.site, fmt, self.template, self.decl_site)
class Trait(SubTrait):
'''A trait, as defined by a top-level 'trait' statement'''
@@ -761,7 +761,7 @@ def __init__(self, site, name, ancestors, methods, params, sessions, hooks,
if overridable and name not in ancestor_vtables}
self.vtable_params = params
self.vtable_sessions = sessions
- self.vtable_hooks = {name: (hooks[name], THook(hooks[name][2]))
+ self.vtable_hooks = {name: (hooks[name], tp.Hook(hooks[name][2]))
for name in hooks}
self.vtable_memoized_outs = {
'_memo_outs_' + name: method.memo_outs_struct
@@ -782,7 +782,7 @@ def __lt__(self, other):
return self.name < other.name
def type(self):
- return TTrait(self)
+ return tp.Trait(self)
def typecheck_members(self):
self.typecheck_methods()
@@ -791,7 +791,7 @@ def typecheck_members(self):
bad_members = []
for (name, (_, typ)) in table.items():
try:
- check_named_types(typ)
+ tp.check_named_types(typ)
except DMLError as e:
report(e)
bad_members.append(name)
@@ -810,7 +810,7 @@ def typecheck_methods(self):
for (_, inp, outp, _, _, _, _) in self.vtable_methods.values():
for t in [p.typ for p in inp] + [t for (_, t) in outp]:
try:
- check_named_types(t)
+ tp.check_named_types(t)
except DMLError as e:
report(e)
@@ -820,7 +820,7 @@ def typecheck_methods(self):
if sm.name not in self.vtable_methods:
for t in [p.typ for p in sm.inp] + [t for (_, t) in sm.outp]:
try:
- check_named_types(t)
+ tp.check_named_types(t)
except DMLError as e:
bad = True
report(e)
@@ -842,17 +842,17 @@ def typecheck_methods(self):
def scope(self, global_scope):
'''Return a scope for looking up sibling objects in this trait'''
- s = Symtab(global_scope)
- selfref = mkLit(self.site, '_' + cident(self.name), self.type())
+ s = symtab.Symtab(global_scope)
+ selfref = mkLit(self.site, '_' + tp.cident(self.name), self.type())
for name in self.members():
# This is very hacky, but works well
try:
- expr = mkSubRef(self.site, selfref, name, '.')
- except EINDEPENDENTVIOL:
- expr = InvalidSymbol(self.site, name, EINDEPENDENTVIOL)
- s.add(ExpressionSymbol(name, expr, self.site))
+ expr = c.mkSubRef(self.site, selfref, name, '.')
+ except E.INDEPENDENTVIOL:
+ expr = c.InvalidSymbol(self.site, name, E.INDEPENDENTVIOL)
+ s.add(c.ExpressionSymbol(name, expr, self.site))
# grammar prohibits name collision on 'this'
- s.add(ExpressionSymbol('this', selfref, self.site))
+ s.add(c.ExpressionSymbol('this', selfref, self.site))
return s
def empty(self):
@@ -914,7 +914,7 @@ def lookup(self, name, expr, site):
'''Look up a member of this trait; return a referencing expression or
None. expr is an expression referencing this trait.'''
if name == 'templates':
- return mkTraitTemplatesRef(site, self, expr)
+ return c.mkTraitTemplatesRef(site, self, expr)
if name in self.method_impl_traits:
impl_traits = self.method_impl_traits[name]
if not all(impl_trait.method_impls[name].overridable
@@ -929,42 +929,42 @@ def lookup(self, name, expr, site):
[impl_trait] = impl_traits
impl = impl_trait.method_impls[name]
if self is not impl_trait:
- expr = TraitUpcast(site, expr, impl_trait)
+ expr = c.TraitUpcast(site, expr, impl_trait)
if impl_trait is not impl.vtable_trait:
- expr = TraitUpcast(site, expr, impl.vtable_trait)
- return TraitMethodDirect(site, expr, impl)
+ expr = c.TraitUpcast(site, expr, impl.vtable_trait)
+ return c.TraitMethodDirect(site, expr, impl)
if name in self.vtable_methods:
(_, inp, outp, throws, independent, _, _) = \
self.vtable_methods[name]
- return TraitMethodIndirect(site, expr, name, inp, outp, throws,
+ return c.TraitMethodIndirect(site, expr, name, inp, outp, throws,
independent)
if name in self.vtable_params:
(_, ptype) = self.vtable_params[name]
- return TraitParameter(site, expr, name, ptype)
+ return c.TraitParameter(site, expr, name, ptype)
if name in self.vtable_sessions:
(_, ptype) = self.vtable_sessions[name]
- return mkDereference(site, TraitSessionRef(site, expr, name, ptype))
+ return c.mkDereference(site, c.TraitSessionRef(site, expr, name, ptype))
if name in self.vtable_hooks:
((_, dimsizes, _), hooktyp) = self.vtable_hooks[name]
if dimsizes:
- return TraitHookArrayRef(site, dimsizes, hooktyp, expr, name,
+ return c.TraitHookArrayRef(site, dimsizes, hooktyp, expr, name,
())
else:
- return TraitHookRef(site, (), hooktyp, expr, name, ())
+ return c.TraitHookRef(site, (), hooktyp, expr, name, ())
vtable_trait = self.ancestor_vtables.get(name, None)
if vtable_trait:
return vtable_trait.lookup(
- name, TraitUpcast(site, expr, vtable_trait), site)
+ name, c.TraitUpcast(site, expr, vtable_trait), site)
if name in self.reserved_symbols:
(kind, decl_site) = self.reserved_symbols[name]
return ReservedSymbol(site, name, kind, self.name, decl_site)
return None
def implicit_args(self):
- return [("_" + cident(self.name), self.type())]
+ return [("_" + tp.cident(self.name), self.type())]
def vtable_method_type(self, inp, outp, throws, independent):
- return TPtr(TFunction(
+ return tp.Ptr(tp.Function(
[t for (_, t) in
crep.maybe_dev_arg(independent) + self.implicit_args()]
+ [p.typ for p in inp]
diff --git a/py/dml/traits_test.py b/py/dml/traits_test.py
index 34f24d6d1..eb601365e 100644
--- a/py/dml/traits_test.py
+++ b/py/dml/traits_test.py
@@ -11,7 +11,6 @@
import dml.ctree
from dml import crep
from dml import types
-from dml import traits
from dml import serialize
class Test_traits(unittest.TestCase):
@@ -52,4 +51,4 @@ def test_one_default_method(self):
self.assertTrue(ref)
# does not crash
with crep.DeviceInstanceContext(), self.dev.use_for_codegen():
- ref.call_expr([], types.TVoid()).read()
+ ref.call_expr([], types.Void()).read()
diff --git a/py/dml/types.py b/py/dml/types.py
index c1e2c13e2..c4fdc8384 100644
--- a/py/dml/types.py
+++ b/py/dml/types.py
@@ -24,40 +24,38 @@
'add_late_global_struct_defs',
'TypeSequence',
'DMLType',
- 'TVoid',
- 'TUnknown',
- 'TDevice',
- 'TNamed',
+ 'Void',
+ 'Unknown',
+ 'Device',
+ 'Named',
'IntegerType',
- 'TBool',
- 'TInt',
- 'TEndianInt',
- 'TLong',
- 'TSize',
- 'TFloat',
- 'TArray',
- 'TPtr',
- 'TVector',
- 'TTrait',
- 'TTraitList',
+ 'Bool',
+ 'Int',
+ 'EndianInt',
+ 'Long',
+ 'Size',
+ 'Float',
+ 'Array',
+ 'Ptr',
+ 'Vector',
+ 'Trait',
+ 'TraitList',
'StructType',
- 'TExternStruct',
- 'TStruct',
- 'TLayout',
- 'TFunction',
- 'THook',
+ 'ExternStruct',
+ 'Struct',
+ 'Layout',
+ 'Function',
+ 'Hook',
'cident',
'void',
)
-import sys
import re
-from itertools import *
from .env import is_windows
from .output import out
-from .messages import *
-from .logging import *
+from . import errors as E
+from .logging import ICE, report, DMLError
from . import breaking_changes
from . import output
import dml .globals
@@ -91,28 +89,28 @@ def __str__(self):
def check_named_types(t):
'''Checks that a type does not reference a non-existing type'''
- if isinstance(t, TNamed):
+ if isinstance(t, Named):
if t.c not in typedefs:
- raise ETYPE(t.declaration_site, t)
+ raise E.TYPE(t.declaration_site, t)
elif isinstance(t, StructType):
t.resolve()
for (mn, mt) in t.members:
check_named_types(mt)
- elif isinstance(t, (TPtr, TVector, TArray)):
+ elif isinstance(t, (Ptr, Vector, Array)):
check_named_types(t.base)
- elif isinstance(t, TFunction):
+ elif isinstance(t, Function):
for pt in t.input_types:
check_named_types(pt)
check_named_types(t.output_type)
- elif isinstance(t, TTraitList):
+ elif isinstance(t, TraitList):
if t.traitname not in dml.globals.traits:
- raise ETYPE(t.declaration_site, t)
- elif isinstance(t, THook):
+ raise E.TYPE(t.declaration_site, t)
+ elif isinstance(t, Hook):
for msg_t in t.msg_types:
check_named_types(msg_t)
- elif isinstance(t, (TVoid, IntegerType, TBool, TFloat, TTrait)):
+ elif isinstance(t, (Void, IntegerType, Bool, Float, Trait)):
pass
- elif dml.globals.dml_version == (1, 2) and isinstance(t, TUnknown):
+ elif dml.globals.dml_version == (1, 2) and isinstance(t, Unknown):
pass
else:
raise ICE(t.declaration_site, "unknown type %r" % t)
@@ -122,7 +120,7 @@ def realtype_shallow(t):
"Lookup a named type"
#assert isinstance(t, DMLType)
seen = set()
- while isinstance(t, TNamed):
+ while isinstance(t, Named):
if t in seen:
raise ICE(t.declaration_site,
"recursive type definition of %r" % t)
@@ -132,8 +130,8 @@ def realtype_shallow(t):
if not t2:
raise DMLUnknownType(t)
if t.const and not t2.const:
- if isinstance(t2, TFunction):
- raise ECONSTFUN(t.declaration_site)
+ if isinstance(t2, Function):
+ raise E.CONSTFUN(t.declaration_site)
t = t2.clone()
t.const = True
else:
@@ -143,11 +141,11 @@ def realtype_shallow(t):
def realtype(t):
t = realtype_shallow(t)
- if isinstance(t, TPtr):
+ if isinstance(t, Ptr):
t2 = realtype(t.base)
if t2 != t:
- return TPtr(t2, t.const)
- if isinstance(t, TTraitList):
+ return Ptr(t2, t.const)
+ if isinstance(t, TraitList):
# in 'sequence(t)' and 'each t in (...)', t refers to the
# template name rather than the type; this is a misplaced check
# that there is a template named t.
@@ -157,23 +155,23 @@ def realtype(t):
if (t.traitname not in dml.globals.templates
or not dml.globals.templates[t.traitname].trait):
raise DMLUnknownType(t)
- elif isinstance(t, TArray):
+ elif isinstance(t, Array):
t2 = realtype(t.base)
if t2 != t:
- return TArray(t2, t.size, t.const)
- elif isinstance(t, TVector):
+ return Array(t2, t.size, t.const)
+ elif isinstance(t, Vector):
t2 = realtype(t.base)
if t2 != t:
- return TVector(t2, t.const, t.uniq)
- elif isinstance(t, TFunction):
+ return Vector(t2, t.const, t.uniq)
+ elif isinstance(t, Function):
input_types = tuple(realtype(sub) for sub in t.input_types)
output_type = realtype(t.output_type)
if input_types != t.input_types or output_type != t.output_type:
- return TFunction(input_types, output_type, t.varargs, t.const)
- elif isinstance(t, THook):
+ return Function(input_types, output_type, t.varargs, t.const)
+ elif isinstance(t, Hook):
msg_types = tuple(realtype(sub) for sub in t.msg_types)
if msg_types != t.msg_types:
- return THook(msg_types, t.validated, t.const)
+ return Hook(msg_types, t.validated, t.const)
return t
@@ -181,19 +179,19 @@ def safe_realtype(t):
try:
return realtype(t)
except DMLUnknownType as e:
- raise ETYPE(e.type.declaration_site or None, e.type)
+ raise E.TYPE(e.type.declaration_site or None, e.type)
def safe_realtype_shallow(t):
try:
return realtype_shallow(t)
except DMLUnknownType as e:
- raise ETYPE(e.type.declaration_site or None, e.type)
+ raise E.TYPE(e.type.declaration_site or None, e.type)
def conv_const(const, t):
# Functions cannot be const. Usually function types cannot happen
# where conv_const is called, but if they can, then that deserves
# that the caller handles it explicitly.
- assert not isinstance(t, TFunction)
+ assert not isinstance(t, Function)
if const and not t.const:
t = t.clone()
t.const = True
@@ -201,7 +199,7 @@ def conv_const(const, t):
def safe_realtype_unconst(t0):
def sub(t):
- if isinstance(t, TArray):
+ if isinstance(t, Array):
base = sub(t.base)
if t.const or base is not t.base:
t = t.clone()
@@ -215,7 +213,7 @@ def sub(t):
def shallow_const(t):
t = safe_realtype_shallow(t)
- while not t.const and isinstance(t, TArray):
+ while not t.const and isinstance(t, Array):
t = safe_realtype_shallow(t.base)
return t.const
@@ -226,7 +224,7 @@ def deep_const(origt):
st = safe_realtype_shallow(subtypes.pop())
if st.const:
return True
- if isinstance(st, TArray):
+ if isinstance(st, Array):
subtypes.append(st.base)
elif isinstance(st, StructType):
subtypes.extend(t for (_, t) in st.members)
@@ -262,7 +260,7 @@ class DMLType(metaclass=abc.ABCMeta):
void = False
# shorthand for isinstance(x, IntegerType)
is_int = False
- # shorthand for isinstance(x, TFloat)
+ # shorthand for isinstance(x, Float)
is_float = False
# shorthand for (is_int or is_float)
is_arith = False
@@ -322,8 +320,8 @@ def eq_fuzzy(self, other):
(1) and (2) of 'eq', and does away with criteria (3) entirely.
For example, using eq_fuzzy to compare any bitfields with its base
integer type will return True, but also,
- TPtr(void).eq_fuzzy(TPtr(TBool())) is allowed to return True, as is
- TPtr(TBool()).eq_fuzzy(TArray(TBool())).
+ Ptr(void).eq_fuzzy(Ptr(Bool())) is allowed to return True, as is
+ Ptr(Bool()).eq_fuzzy(Array(Bool())).
Most notably, cmp_fuzzy does not take const-qualification into account.
@@ -390,19 +388,19 @@ def resolve(self):
return self"""
return self
-class TVoid(DMLType):
+class Void(DMLType):
__slots__ = ()
void = True
def __repr__(self):
- return 'TVoid()'
+ return 'Void()'
def describe(self):
return 'void'
def declaration(self, var):
return 'void ' + self.const_str + ' ' + var
def clone(self):
- return TVoid(self.const)
+ return Void(self.const)
-class TUnknown(DMLType):
+class Unknown(DMLType):
'''A type unknown to DML. Typically used for a generic C macro
imported to DML with an untyped 'extern' declaration, where some
argument or return value cannot be simply expressed as a C type.
@@ -417,7 +415,7 @@ def describe(self):
def clone(self):
raise ICE(self.declaration_site, "cannot clone unknown type")
-class TDevice(DMLType):
+class Device(DMLType):
"""The type of the device object
This is the type of $dev. No other values have this type.
@@ -427,7 +425,7 @@ def __init__(self, name, const=False):
DMLType.__init__(self, const)
self.name = name
def __repr__(self):
- return 'TDevice(%s)' % repr(self.name)
+ return 'Device(%s)' % repr(self.name)
def c_name(self):
return f'{self.name} *'
def describe(self):
@@ -438,11 +436,11 @@ def canstore(self, other):
constviol = False
if not self.const and other.const:
constviol = True
- if isinstance(other, TDevice):
+ if isinstance(other, Device):
return (True, False, constviol)
return (False, False, constviol)
def clone(self):
- return TDevice(self.name, self.const)
+ return Device(self.name, self.const)
def declaration(self, var):
return f'{self.c_name()}{self.const_str}{var}'
@@ -472,7 +470,7 @@ def cident(name):
# Extern typedefs would have to be excluded, though.
return cident_renames.get(name, name)
-class TNamed(DMLType):
+class Named(DMLType):
__slots__ = ('c',)
def __init__(self, name, const = False):
DMLType.__init__(self, const)
@@ -494,15 +492,15 @@ def hashed(self):
assert False, 'need realtype before hashed'
def clone(self):
- return TNamed(self.c, self.const)
+ return Named(self.c, self.const)
def declaration(self, var):
return cident(self.c) + ' ' + self.const_str + var
-class TBool(DMLType):
+class Bool(DMLType):
__slots__ = ()
def __repr__(self):
- return 'TBool(%r)' % self.const
+ return 'Bool(%r)' % self.const
def describe(self):
return 'bool'
def declaration(self, var):
@@ -510,14 +508,14 @@ def declaration(self, var):
def canstore(self, other):
constviol = False
- if type(other) is TBool:
+ if type(other) is Bool:
return (True, False, constviol)
if (other.is_int
and other.bits == 1 and not other.signed):
return (True, False, constviol)
return (False, False, constviol)
def clone(self):
- return TBool(self.const)
+ return Bool(self.const)
class IntegerType(DMLType):
'''Type that can contain an integer value
@@ -531,7 +529,7 @@ def __init__(self, bits, signed, members=None, const=False):
self.bits = bits
assert isinstance(signed, bool)
if members is not None:
- assert all(isinstance(m, TInt) for (m, _, _) in members.values())
+ assert all(isinstance(m, Int) for (m, _, _) in members.values())
assert not signed
self.signed = signed
self.members = members
@@ -641,18 +639,18 @@ def canstore(self, other):
else:
return (False, False, False)
-class TInt(IntegerType):
+class Int(IntegerType):
'''An integer. In a declaration, the corresponding C type is the
smallest type with the same sign, in which the type fits.
When looking at the types of rvalues, it is slightly unclear how
- TInt maps to C integers. It seems that the bitsize of the TInt of
+ Int maps to C integers. It seems that the bitsize of the Int of
an expression maintains an approximate upper bound of the possible
values of the expression, and that the corresponding C type is (often)
the first of [int32, uint32, int64, uint64] in which the DML type fits.
DMLC does not seem to maintain consistency between signedness of
- TInt and the corresponding C type. This seldom makes a difference,
+ Int and the corresponding C type. This seldom makes a difference,
because it means that C's operational semantics is what's used in
practice.
'''
@@ -667,7 +665,7 @@ def describe(self):
def describe_backing_type(self):
return f'{"u"*(not self.signed)}int{self.bits}'
def __repr__(self):
- return 'TInt(%r,%r,%r,%r)' % (self.bits, self.signed,
+ return 'Int(%r,%r,%r,%r)' % (self.bits, self.signed,
self.members, self.const)
def apitype(self):
@@ -697,7 +695,7 @@ def canstore(self, other):
if other.is_int:
trunc = (other.bits > self.bits)
if (not breaking_changes.dml12_remove_misc_quirks.enabled
- and isinstance(other, TBool)):
+ and isinstance(other, Bool)):
return (False, False, constviol)
return (True, trunc, constviol)
if other.is_float and not self.is_bitfields:
@@ -705,7 +703,7 @@ def canstore(self, other):
return (False, False, constviol)
def clone(self):
- return TInt(self.bits, self.signed, self.members, self.label,
+ return Int(self.bits, self.signed, self.members, self.label,
self.const)
def declaration(self, var):
@@ -716,7 +714,7 @@ def declaration(self, var):
else:
return 'uint8 ' + self.const_str + var + '[' + str(self.bytes) + ']'
-class TLong(IntegerType):
+class Long(IntegerType):
'''The 'long' type from C'''
__slots__ = ()
def __init__(self, signed, const=False):
@@ -730,15 +728,15 @@ def describe_backing_type(self):
return self.c_name()
def __repr__(self):
- return 'TLong(%r, %r)' % (self.signed, self.const)
+ return 'Long(%r, %r)' % (self.signed, self.const)
def clone(self):
- return TLong(self.signed, self.const)
+ return Long(self.signed, self.const)
def declaration(self, var):
return f'{self.const_str}{self.c_name()} {var}'
-class TSize(IntegerType):
+class Size(IntegerType):
'''The 'size_t' type from C'''
__slots__ = ()
def __init__(self, signed, const=False):
@@ -751,15 +749,15 @@ def describe_backing_type(self):
return self.c_name()
def __repr__(self):
- return 'TSize(%r, %r)' % (self.signed, self.const)
+ return 'Size(%r, %r)' % (self.signed, self.const)
def clone(self):
- return TSize(self.signed, self.const)
+ return Size(self.signed, self.const)
def declaration(self, var):
return f'{self.const_str}{self.c_name()} {var}'
-class TInt64_t(IntegerType):
+class Int64_t(IntegerType):
'''The '[u]int64_t' type from ISO C. For compatibility with C
APIs, e.g., calling an externally defined C function that takes a
`uint64_t *` arg. We find `uint64` a generally more useful type
@@ -777,15 +775,15 @@ def describe_backing_type(self):
return self.c_name()
def __repr__(self):
- return 'TInt64_t(%r, %r)' % (self.signed, self.const)
+ return 'Int64_t(%r, %r)' % (self.signed, self.const)
def clone(self):
- return TInt64_t(self.signed, self.const)
+ return Int64_t(self.signed, self.const)
def declaration(self, var):
return f'{self.const_str}{self.c_name()} {var}'
-class TEndianInt(IntegerType):
+class EndianInt(IntegerType):
'''An integer where the byte storage order is defined.
Corresponds to the (u)?intX_[be|le] family of types defined in
dmllib.h
@@ -813,13 +811,13 @@ def describe_backing_type(self):
return self.c_name()
def __repr__(self):
- return 'TEndianInt(%r,%r,%r,%r,%r)' % (
+ return 'EndianInt(%r,%r,%r,%r,%r)' % (
self.bits, self.signed, self.byte_order, self.members, self.const)
@property
def access_type(self):
"""Integer type used for read/write access"""
- return TInt(64, self.signed or self.bits != 64)
+ return Int(64, self.signed or self.bits != 64)
def dmllib_fun(self, fun):
"""translate a function name to the c dmllib function"""
@@ -848,22 +846,22 @@ def get_store_fun(self):
"""function reference to dmllib function used to store values to an
endianint"""
return (self.dmllib_store,
- TFunction([self.access_type], self))
+ Function([self.access_type], self))
def get_load_fun(self):
"""function reference to dmllib function used to load values from an
endianint"""
return (self.dmllib_load,
- TFunction([self], self.access_type))
+ Function([self], self.access_type))
def clone(self):
- return TEndianInt(self.bits, self.signed,
+ return EndianInt(self.bits, self.signed,
self.byte_order, self.members, self.const)
def declaration(self, var):
return f'{self.const_str}{self.c_name()} {var}'
-class TFloat(DMLType):
+class Float(DMLType):
__slots__ = ('name',)
is_float = True
is_arith = True
@@ -879,22 +877,22 @@ def eq(self, other):
and other.is_float and self.name == other.name)
def hashed(self):
- return hash((TFloat, self.const, self.name))
+ return hash((Float, self.const, self.name))
def canstore(self, other):
constviol = False
if other.is_float:
return (True, False, constviol)
- if isinstance(other, TInt):
+ if isinstance(other, Int):
return (True, True, constviol)
return (False, False, constviol)
def declaration(self, var):
return self.name + ' ' + self.const_str + var
def clone(self):
- return TFloat(self.name, self.const)
+ return Float(self.name, self.const)
-class TArray(DMLType):
+class Array(DMLType):
__slots__ = ('base', 'size')
def __init__(self, base, size, const = False):
DMLType.__init__(self, const)
@@ -903,7 +901,7 @@ def __init__(self, base, size, const = False):
self.base = base
self.size = size
def __repr__(self):
- return "TArray(%r,%r,%r)" % (self.base, self.size, self.const)
+ return "Array(%r,%r,%r)" % (self.base, self.size, self.const)
def key(self):
if not self.size.constant:
raise DMLUnkeyableType(self, "array of non-constant size")
@@ -934,7 +932,7 @@ def sizeof(self):
return self.size.value * elt_size
def eq(self, other):
- if not isinstance(other, TArray):
+ if not isinstance(other, Array):
return False
if not (self.size is other.size
or (self.size.constant and other.size.constant
@@ -944,25 +942,25 @@ def eq(self, other):
conv_const(other.const, other.base))
def eq_fuzzy(self, other):
- if isinstance(other, (TArray, TPtr)):
+ if isinstance(other, (Array, Ptr)):
return other.base.void or self.base.eq_fuzzy(other.base)
return False
def hashed(self):
size = self.size.value if self.size.constant else self.size
- return hash((TArray,
+ return hash((Array,
size,
conv_const(self.const, self.base).hashed()))
def canstore(self, other):
return (False, False, False)
def clone(self):
- return TArray(self.base, self.size, self.const)
+ return Array(self.base, self.size, self.const)
def resolve(self):
self.base.resolve()
return self
-class TPtr(DMLType):
+class Ptr(DMLType):
__slots__ = ('base',)
def __init__(self, base, const = False):
DMLType.__init__(self, const)
@@ -970,7 +968,7 @@ def __init__(self, base, const = False):
raise DMLTypeError("base is not a type: %r" % (base,))
self.base = base
def __repr__(self):
- return "TPtr(%r,%r)" % (self.base, self.const)
+ return "Ptr(%r,%r)" % (self.base, self.const)
def key(self):
return f'{self.const_str}pointer({self.base.key()})'
def describe(self):
@@ -980,20 +978,20 @@ def eq(self, other):
return DMLType.eq(self, other) and self.base.eq(other.base)
def eq_fuzzy(self, other):
- if isinstance(other, (TPtr, TArray)):
+ if isinstance(other, (Ptr, Array)):
if self.base.void or other.base.void:
return True
return self.base.eq_fuzzy(other.base)
return False
def hashed(self):
- return hash((TPtr, self.const, self.base.hashed()))
+ return hash((Ptr, self.const, self.base.hashed()))
def canstore(self, other):
ok = False
trunc = False
constviol = False
- if isinstance(other, (TPtr, TArray)):
+ if isinstance(other, (Ptr, Array)):
constviol = (not shallow_const(self.base)
and shallow_const(other.base))
if self.base.void or other.base.void:
@@ -1010,21 +1008,21 @@ def canstore(self, other):
and unconst_other_base.is_int)
else unconst_self_base.eq)(unconst_other_base)
- elif isinstance(other, TFunction):
+ elif isinstance(other, Function):
ok = (not breaking_changes.strict_typechecking.enabled
or safe_realtype_unconst(self.base).eq(other))
# TODO gate this behind dml.globals.dml_version == (1, 2) or
# remove_misc_quirks?
- if self.base.void and isinstance(other, TDevice):
+ if self.base.void and isinstance(other, Device):
ok = True
- #dbg('TPtr.canstore %r %r => %r' % (self, other, ok))
+ #dbg('Ptr.canstore %r %r => %r' % (self, other, ok))
return (ok, trunc, constviol)
def clone(self):
- return TPtr(self.base, self.const)
+ return Ptr(self.base, self.const)
def declaration(self, var):
- if isinstance(self.base, (TFunction, TArray)):
+ if isinstance(self.base, (Function, Array)):
var = f'(*{self.const_str}{var})'
else:
var = f'*{self.const_str}{var}'
@@ -1033,20 +1031,20 @@ def resolve(self):
self.base.resolve()
return self
-class TVector(DMLType):
+class Vector(DMLType):
count = 0
__slots__ = ('base', 'uniq',)
def __init__(self, base, const=False, uniq=None):
DMLType.__init__(self, const)
if uniq is None:
- uniq = TVector.count
- TVector.count += 1
+ uniq = Vector.count
+ Vector.count += 1
self.uniq = uniq
if not base:
raise DMLTypeError("Null base")
self.base = base
def __repr__(self):
- return "TVector(%r,%r)" % (self.base, self.const)
+ return "Vector(%r,%r)" % (self.base, self.const)
def key(self):
raise DMLUnkeyableType(self)
def describe(self):
@@ -1054,21 +1052,21 @@ def describe(self):
def eq(self, other):
return DMLType.eq(self, other) and self.uniq == other.uniq
def eq_fuzzy(self, other):
- if isinstance(other, TVector):
+ if isinstance(other, Vector):
# Can only compare for voidness or equality
if self.base.void or other.base.void:
return True
return self.base.eq_fuzzy(other.base)
return False
def hashed(self):
- return hash((TVector, self.const, self.uniq))
+ return hash((Vector, self.const, self.uniq))
def clone(self):
- return TVector(self.base, self.const, self.uniq)
+ return Vector(self.base, self.const, self.uniq)
def declaration(self, var):
s = self.base.declaration('')
return 'VECT(%s) %s%s' % (s, self.const_str, var)
-class TTrait(DMLType):
+class Trait(DMLType):
'''A run-time reference to a trait. Represented in C as a pointer
to a trait vtable struct, together with an object identity'''
__slots__ = ('trait',)
@@ -1078,10 +1076,10 @@ def __init__(self, trait, const=False):
self.trait = trait
def __repr__(self):
- return "TTrait(%s)" % (self.trait.name,)
+ return "Trait(%s)" % (self.trait.name,)
def clone(self):
- return TTrait(self.trait, self.const)
+ return Trait(self.trait, self.const)
def eq(self, other):
return DMLType.eq(self, other) and self.trait is other.trait
@@ -1090,7 +1088,7 @@ def key(self):
return f'{self.const_str}trait({self.trait.name})'
def hashed(self):
- return hash((TTrait, self.const, self.trait))
+ return hash((Trait, self.const, self.trait))
def c_name(self):
return cident(self.trait.name)
@@ -1101,7 +1099,7 @@ def describe(self):
def declaration(self, var):
return f'{self.const_str}{self.c_name()} {var}'
-class TTraitList(DMLType):
+class TraitList(DMLType):
__slots__ = ('traitname')
def __init__(self, traitname, const=False):
@@ -1109,10 +1107,10 @@ def __init__(self, traitname, const=False):
self.traitname = traitname
def __repr__(self):
- return "TTraitList(%s)" % (self.traitname,)
+ return "TraitList(%s)" % (self.traitname,)
def clone(self):
- return TTraitList(self.traitname, self.const)
+ return TraitList(self.traitname, self.const)
def eq(self, other):
return DMLType.eq(self, other) and self.traitname == other.traitname
@@ -1121,7 +1119,7 @@ def key(self):
return f'{self.const_str}sequence({self.traitname})'
def hashed(self):
- return hash((TTraitList, self.const, self.traitname))
+ return hash((TraitList, self.const, self.traitname))
def c_type(self):
return f'{self.const_str}_each_in_t'
@@ -1156,7 +1154,7 @@ def get_member_qualified(self, member):
t = self.named_members.get(member)
return t if t is None else conv_const(self.const, t)
-class TExternStruct(StructType):
+class ExternStruct(StructType):
'''A struct-like type defined by code outside DMLC's control.
'members' is the potential right operands of binary '.',
and 'label' is the typedef:ed type name.'''
@@ -1164,7 +1162,7 @@ class TExternStruct(StructType):
count = 0
def __init__(self, named_members, id, typename=None, const=False):
- super(TExternStruct, self).__init__(named_members, const)
+ super(ExternStruct, self).__init__(named_members, const)
# unique object (wrt ==) representing this type in type comparisons
# integer for anonymous structs, string for named types
self.id = id
@@ -1172,13 +1170,13 @@ def __init__(self, named_members, id, typename=None, const=False):
self.typename = typename
def __repr__(self):
- return 'TExternStruct(%r,%r,%r,%r)' % (
+ return 'ExternStruct(%r,%r,%r,%r)' % (
self.named_members, self.id, self.typename, self.const)
@staticmethod
def unique_id():
- TExternStruct.count += 1
- return TExternStruct.count
+ ExternStruct.count += 1
+ return ExternStruct.count
def key(self):
if not self.typename:
@@ -1191,24 +1189,24 @@ def describe(self):
def declaration(self, var):
if not self.typename:
- raise EANONEXT(self.declaration_site)
+ raise ICE(self.declaration_site, 'no typename')
return "%s %s%s" % (self.typename, self.const_str, var)
def eq(self, other):
return DMLType.eq(self, other) and self.id == other.id
def hashed(self):
- return hash((TExternStruct, self.const, self.id))
+ return hash((ExternStruct, self.const, self.id))
def clone(self):
- return TExternStruct(self.named_members,
+ return ExternStruct(self.named_members,
self.id, self.typename, self.const)
def add_late_global_struct_defs(decls):
- TStruct.late_global_struct_defs.extend((site, t.resolve())
+ Struct.late_global_struct_defs.extend((site, t.resolve())
for (site, t) in decls)
-class TStruct(StructType):
+class Struct(StructType):
__slots__ = ('label', 'anonymous')
# Anonymous struct types defined in global scope, but outside typedef
# declarations, e.g. 'session struct { int x; } y;'.
@@ -1219,13 +1217,13 @@ def __init__(self, members, label=None, const=False):
assert members is None or members
self.anonymous = label is None
if self.anonymous:
- label = '_anon_struct_%d' % (TStruct.num_anon_structs,)
- TStruct.num_anon_structs += 1
+ label = '_anon_struct_%d' % (Struct.num_anon_structs,)
+ Struct.num_anon_structs += 1
self.label = label
super().__init__(members, const)
def __repr__(self):
- return 'TStruct(%r,%r,%r)' % (self.named_members, self.label,
+ return 'Struct(%r,%r,%r)' % (self.named_members, self.label,
self.const)
def key(self):
@@ -1255,7 +1253,7 @@ def print_struct_definition(self):
output.site_linemark(t.declaration_site)
t.print_declaration(n
if n is not None else
- TStruct.anon_member_cident(i))
+ Struct.anon_member_cident(i))
output.site_linemark(self.declaration_site)
out("};\n", preindent = -1)
@@ -1263,25 +1261,25 @@ def eq(self, other):
return DMLType.eq(self, other) and self.label == other.label
def hashed(self):
- return hash((TStruct, self.const, self.label))
+ return hash((Struct, self.const, self.label))
def clone(self):
- return TStruct(self.named_members, self.label, self.const)
+ return Struct(self.named_members, self.label, self.const)
-class TLayout(TStruct):
+class Layout(Struct):
__slots__= ('endian', 'member_decls', 'size', 'discarded')
def __init__(self, endian, member_decls, label=None, const=False):
# Intentionally wait with setting member types until
# resolve is finished
- super(TLayout, self).__init__(None, label, const)
+ super(Layout, self).__init__(None, label, const)
self.member_decls = member_decls
self.endian = endian
self.size = None
self.discarded = None
def __repr__(self):
- return 'TLayout(%r, %r, %r, %r)' % (self.endian, self.member_decls,
+ return 'Layout(%r, %r, %r, %r)' % (self.endian, self.member_decls,
self.label, self.const)
def key(self):
if self.anonymous:
@@ -1315,34 +1313,34 @@ def check_layout_member_type(site, t, memberref):
rt = t
# We cannot use non-shallow instead of this loop because we need
# to keep track of when we move through arrays
- while isinstance(rt, TNamed):
+ while isinstance(rt, Named):
rt = safe_realtype_shallow(rt)
rt.resolve()
- if isinstance(rt, TLayout):
+ if isinstance(rt, Layout):
# In the case of a layout, we need to keep the member type as
# the original declared type to prevent dis-aliasing a typedef.
return t, rt
if rt.is_int:
if (rt.bits % 8) != 0:
- raise ELAYOUT(site,
+ raise E.LAYOUT(site,
f"size of {memberref} is not a whole byte")
- if (isinstance(rt, TInt)
+ if (isinstance(rt, Int)
or (dml.globals.compat_dml12_int(site)
- and isinstance(rt, TSize))):
- toret = TEndianInt(rt.bits, rt.signed,
+ and isinstance(rt, Size))):
+ toret = EndianInt(rt.bits, rt.signed,
self.endian, rt.members, rt.const)
return (toret, toret)
- if isinstance(rt, TEndianInt):
+ if isinstance(rt, EndianInt):
return (rt, rt)
- if isinstance(rt, TArray):
+ if isinstance(rt, Array):
# In the case of an array, we return one array that respects
# the original declaration when necessary, and one array
# that is the fully resolved type
new_base, real_base = check_layout_member_type(
site, rt.base, memberref)
- return (TArray(new_base, rt.size, rt.const),
- TArray(real_base, rt.size, rt.const),)
- raise ELAYOUT(site, "illegal layout member type: %s" % t)
+ return (Array(new_base, rt.size, rt.const),
+ Array(real_base, rt.size, rt.const),)
+ raise E.LAYOUT(site, "illegal layout member type: %s" % t)
self.size = 0
self.named_members = {}
@@ -1365,7 +1363,7 @@ def check_layout_member_type(site, t, memberref):
size = rt.sizeof()
if size is None:
# variable-sized array
- raise ELAYOUT(site, "unknown layout size")
+ raise E.LAYOUT(site, "unknown layout size")
else:
self.size += size
except DMLError as e:
@@ -1380,7 +1378,7 @@ def sizeof(self):
return self.size
def clone(self):
- cloned = TLayout(self.endian, self.member_decls, self.label,
+ cloned = Layout(self.endian, self.member_decls, self.label,
self.const)
if self.named_members is not None:
cloned.named_members = self.named_members
@@ -1390,7 +1388,7 @@ def clone(self):
-class TFunction(DMLType):
+class Function(DMLType):
__slots__ = ('input_types', 'output_type', 'varargs')
def __init__(self, input_types, output_type,
varargs = False, const = False):
@@ -1400,7 +1398,7 @@ def __init__(self, input_types, output_type,
self.output_type = output_type
self.varargs = varargs
def __repr__(self):
- return "TFunction(%r,%r)" % (self.input_types, self.output_type)
+ return "Function(%r,%r)" % (self.input_types, self.output_type)
@property
def const(self): return False
@@ -1426,7 +1424,7 @@ def describe(self):
% (inparams, self.output_type.describe()))
def eq(self, other):
- return (isinstance(other, TFunction)
+ return (isinstance(other, Function)
and len(self.input_types) == len(other.input_types)
and all(
safe_realtype_unconst(arg1).eq(safe_realtype_unconst(arg2))
@@ -1437,7 +1435,7 @@ def eq(self, other):
and self.varargs == other.varargs)
def eq_fuzzy(self, other):
- return (isinstance(other, TFunction)
+ return (isinstance(other, Function)
and len(self.input_types) == len(other.input_types)
and all(arg1.eq_fuzzy(arg2)
for (arg1, arg2)
@@ -1446,7 +1444,7 @@ def eq_fuzzy(self, other):
and self.varargs == other.varargs)
def hashed(self):
- return hash((TFunction,
+ return hash((Function,
tuple(safe_realtype_unconst(typ).hashed()
for typ in self.input_types),
safe_realtype_unconst(self.output_type).hashed(),
@@ -1456,7 +1454,7 @@ def canstore(self, other):
return (False, False, False)
def clone(self):
- return TFunction(self.input_types, self.output_type, self.varargs,
+ return Function(self.input_types, self.output_type, self.varargs,
self.const)
def declaration(self, var):
@@ -1466,7 +1464,7 @@ def declaration(self, var):
arglist += ", ..."
return self.output_type.declaration(f'{var}({arglist})')
-class THook(DMLType):
+class Hook(DMLType):
__slots__ = ('msg_types', 'validated')
def __init__(self, msg_types, validated=False, const=False):
@@ -1475,10 +1473,10 @@ def __init__(self, msg_types, validated=False, const=False):
self.validated = validated
def __repr__(self):
- return 'THook(%s)' % (', '.join(repr(typ) for typ in self.msg_types),)
+ return 'Hook(%s)' % (', '.join(repr(typ) for typ in self.msg_types),)
def clone(self):
- return THook(self.msg_types, self.validated, self.const)
+ return Hook(self.msg_types, self.validated, self.const)
def eq(self, other):
return (DMLType.eq(self, other)
@@ -1488,7 +1486,7 @@ def eq(self, other):
other.msg_types)))
def hashed(self):
- return hash((THook,
+ return hash((Hook,
self.const,
tuple(comp.hashed() for comp in self.msg_types)))
@@ -1510,7 +1508,7 @@ def validate(self, fallback_site):
try:
safe_realtype(typ).key()
except DMLUnkeyableType as e:
- raise EHOOKTYPE(self.declaration_site or fallback_site,
+ raise E.HOOKTYPE(self.declaration_site or fallback_site,
typ, e.clarification) from e
@@ -1523,47 +1521,47 @@ def parse_type(typename):
bits = int(m.group(2))
byte_order = m.group(3)
if byte_order:
- return TEndianInt(
+ return EndianInt(
bits, signed,
"big-endian" if byte_order == "_be_t" else "little-endian")
else:
- return TInt(bits, signed)
+ return Int(bits, signed)
elif typename in {'double', 'float'}:
- return TFloat(typename)
+ return Float(typename)
elif typename == 'bool':
- return TBool()
+ return Bool()
elif typename == 'void':
- return TVoid()
+ return Void()
elif typename == 'integer_t' and dml.globals.api_version < breaking_changes.api_7:
- return TInt(64, True)
+ return Int(64, True)
elif typename == 'uinteger_t' and dml.globals.api_version < breaking_changes.api_7:
- return TInt(64, False)
+ return Int(64, False)
else:
- return TNamed(typename)
+ return Named(typename)
def type_union(type1, type2):
"Return the greater of two types"
- if (type1.is_float or isinstance(type1, TUnknown)
+ if (type1.is_float or isinstance(type1, Unknown)
or (type1.is_int and type2.is_int
and type1.bits > type2.bits)):
return type1
return type2
-void = TVoid()
+void = Void()
# These are the named types used. This includes both "imported"
# typedefs for types declared in C header files, and types defined in
# the DML file.
typedefs = {}
for (name, typ) in [
('void', void),
- ('int', TInt(32, True)),
- ('char', TInt(8, True)),
- ('long', TLong(True)),
- ('ulong', TLong(False)),
- ('ssize_t', TSize(True)),
- ('size_t', TSize(False)),
- ('int64_t', TInt64_t(True)),
- ('uint64_t', TInt64_t(False))]:
+ ('int', Int(32, True)),
+ ('char', Int(8, True)),
+ ('long', Long(True)),
+ ('ulong', Long(False)),
+ ('ssize_t', Size(True)),
+ ('size_t', Size(False)),
+ ('int64_t', Int64_t(True)),
+ ('uint64_t', Int64_t(False))]:
typedefs[name] = typ
for sym in __all__:
diff --git a/py/dml/types_test.py b/py/dml/types_test.py
index 27970800a..24fff4afc 100644
--- a/py/dml/types_test.py
+++ b/py/dml/types_test.py
@@ -1,7 +1,7 @@
# © 2024 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-from dml.types import *
+import dml.types as tp
import dml.globals
from dml import ctree
from dml import expr
@@ -14,48 +14,48 @@
class TestClone(unittest.TestCase):
def test(self):
# types which support clone
- typ0 = TVoid()
- for typ in (TVoid(),
- TNamed("int"),
- TBool(),
- TInt(8, False, {}),
- TEndianInt(8, False, 'big-endian', {}),
- TFloat("a"),
- TArray(typ0, ctree.mkIntegerLiteral(0, 2)),
- TPtr(typ0),
- TVector(typ0),
- TTrait(object()),
- TStruct({"name": TInt(32, False)}),
- TLayout("big-endian", []),
- TDevice("a")):
+ typ0 = tp.Void()
+ for typ in (tp.Void(),
+ tp.Named("int"),
+ tp.Bool(),
+ tp.Int(8, False, {}),
+ tp.EndianInt(8, False, 'big-endian', {}),
+ tp.Float("a"),
+ tp.Array(typ0, ctree.mkIntegerLiteral(0, 2)),
+ tp.Ptr(typ0),
+ tp.Vector(typ0),
+ tp.Trait(object()),
+ tp.Struct({"name": tp.Int(32, False)}),
+ tp.Layout("big-endian", []),
+ tp.Device("a")):
typ_clone = typ.clone()
self.assertTrue(
- realtype(typ_clone).eq(realtype(typ)))
+ tp.realtype(typ_clone).eq(tp.realtype(typ)))
self.assertTrue(
- realtype(typ).eq(realtype(typ_clone)))
+ tp.realtype(typ).eq(tp.realtype(typ_clone)))
typ_clone.const = True
self.assertFalse(typ.const)
typ = typ_clone.clone()
self.assertTrue(typ.const)
- # special case for TraitList, because realtype requires global
+ # special case for tp.TraitList, because tp.realtype requires global
# state (typedefs)
- typ = TTraitList("a")
+ typ = tp.TraitList("a")
typ_clone = typ.clone()
self.assertTrue(typ.eq(typ_clone))
self.assertTrue(typ_clone.eq(typ))
dml.globals.dml_version = (1, 2)
# types which do not support clone
with self.assertRaises(logging.ICE):
- TUnknown().clone()
+ tp.Unknown().clone()
-class Typ1(DMLType):
+class Typ1(tp.DMLType):
def describe(self):
return 'Typ1'
def clone(self):
return Typ1(self.const)
-class Typ2(DMLType):
+class Typ2(tp.DMLType):
def describe(self):
return 'Typ2'
def clone(self):
@@ -68,7 +68,7 @@ def assert_eq(self, t1, t2):
self.assertEqual(t1.hashed(), t2.hashed())
try:
self.assertEqual(t1.key(), t2.key())
- except DMLUnkeyableType:
+ except tp.DMLUnkeyableType:
pass
def assert_neq(self, t1, t2, hash_collision=False):
@@ -78,7 +78,7 @@ def assert_neq(self, t1, t2, hash_collision=False):
self.assertNotEqual(t1.hashed(), t2.hashed())
try:
self.assertNotEqual(t1.key(), t2.key())
- except DMLUnkeyableType:
+ except tp.DMLUnkeyableType:
pass
def test_DMLType(self):
@@ -87,22 +87,22 @@ def test_DMLType(self):
self.assert_neq(Typ1(), Typ2())
def test_IntegerType(self):
- self.assert_eq(TInt(8, False), TInt(8, False))
- self.assert_neq(TInt(16, False), TInt(8, False))
+ self.assert_eq(tp.Int(8, False), tp.Int(8, False))
+ self.assert_neq(tp.Int(16, False), tp.Int(8, False))
# Not equivalent even though the C representations of uint16 and uint13
# are compatible
- self.assert_neq(TInt(16, False), TInt(13, False))
+ self.assert_neq(tp.Int(16, False), tp.Int(13, False))
# Signedness
- self.assert_neq(TInt(8, True), TInt(8, False))
+ self.assert_neq(tp.Int(8, True), tp.Int(8, False))
# bitfields
- self.assert_neq(TInt(8, False), TInt(8, False, members={}))
+ self.assert_neq(tp.Int(8, False), tp.Int(8, False, members={}))
def bitfields():
- return TInt(32, False, { 'a': (TInt(8, False), 13, 6),
- 'b': (TInt(13, False), 27, 15) })
+ return tp.Int(32, False, { 'a': (tp.Int(8, False), 13, 6),
+ 'b': (tp.Int(13, False), 27, 15) })
- self.assert_eq(TInt(8, False, members={}), TInt(8, False, members={}))
+ self.assert_eq(tp.Int(8, False, members={}), tp.Int(8, False, members={}))
self.assert_eq(bitfields(), bitfields())
@contextmanager
@@ -134,19 +134,19 @@ def neq_bitfields_testcase():
del t.members['b']
def test_TEndianInt(self):
- self.assert_eq(TEndianInt(8, False, 'big-endian'),
- TEndianInt(8, False, 'big-endian'))
- self.assert_neq(TEndianInt(8, False, 'big-endian'),
- TEndianInt(8, False, 'little-endian'))
+ self.assert_eq(tp.EndianInt(8, False, 'big-endian'),
+ tp.EndianInt(8, False, 'big-endian'))
+ self.assert_neq(tp.EndianInt(8, False, 'big-endian'),
+ tp.EndianInt(8, False, 'little-endian'))
def test_TFloat(self):
- self.assert_eq(TFloat('double'), TFloat('double'))
- self.assert_neq(TFloat('double'), TFloat('float'))
+ self.assert_eq(tp.Float('double'), tp.Float('double'))
+ self.assert_neq(tp.Float('double'), tp.Float('float'))
def mkTArray(self, size, signed=False):
size = (ctree.mkIntegerConstant(None, size, signed) if size is not None
- else expr.mkLit(None, 'lit', TInt(32, False)))
- return TArray(TInt(32, False), size)
+ else expr.mkLit(None, 'lit', tp.Int(32, False)))
+ return tp.Array(tp.Int(32, False), size)
def test_TArray(self):
# Arrays of constant size need the sizes be equal to be equal.
@@ -193,92 +193,92 @@ def neq_array_testcase(): return array_testcase(self.assert_neq)
b.const = True
# Pointers are not equivalent to arrays
- self.assert_neq(self.mkTArray(4), TPtr(TInt(32, False)))
+ self.assert_neq(self.mkTArray(4), tp.Ptr(tp.Int(32, False)))
def test_TPtr(self):
- self.assert_eq(TPtr(Typ1()), TPtr(Typ1()))
- self.assert_neq(TPtr(Typ1()), TPtr(Typ2()))
- self.assert_neq(TPtr(Typ1(), const=True), TPtr(Typ1()))
- self.assert_neq(TPtr(Typ1(const=True)), TPtr(Typ1()))
- self.assert_neq(TPtr(Typ1(), const=True),
- TPtr(Typ1(const=True)))
+ self.assert_eq(tp.Ptr(Typ1()), tp.Ptr(Typ1()))
+ self.assert_neq(tp.Ptr(Typ1()), tp.Ptr(Typ2()))
+ self.assert_neq(tp.Ptr(Typ1(), const=True), tp.Ptr(Typ1()))
+ self.assert_neq(tp.Ptr(Typ1(const=True)), tp.Ptr(Typ1()))
+ self.assert_neq(tp.Ptr(Typ1(), const=True),
+ tp.Ptr(Typ1(const=True)))
# void pointers are not special
- self.assert_neq(TPtr(Typ1()), TPtr(TVoid()))
+ self.assert_neq(tp.Ptr(Typ1()), tp.Ptr(tp.Void()))
def test_TVector(self):
- v1 = TVector(Typ1())
+ v1 = tp.Vector(Typ1())
self.assert_eq(v1, v1.clone())
v2 = v1.clone()
v2.const = True
self.assert_neq(v1, v2)
- self.assert_neq(v1, TVector(Typ1()))
+ self.assert_neq(v1, tp.Vector(Typ1()))
def test_TTrait(self):
tr1 = traits.Trait(None, 't1', set(), {}, {}, {}, {}, {}, {}, {})
tr2 = traits.Trait(None, 't2', set(), {}, {}, {}, {}, {}, {}, {})
- self.assert_eq(TTrait(tr1), TTrait(tr1))
- self.assert_neq(TTrait(tr1), TTrait(tr2))
+ self.assert_eq(tp.Trait(tr1), tp.Trait(tr1))
+ self.assert_neq(tp.Trait(tr1), tp.Trait(tr2))
def test_TTraitList(self):
- self.assert_eq(TTraitList('t1'), TTraitList('t1'))
- self.assert_neq(TTraitList('t1'), TTraitList('t2'))
+ self.assert_eq(tp.TraitList('t1'), tp.TraitList('t1'))
+ self.assert_neq(tp.TraitList('t1'), tp.TraitList('t2'))
def test_TStruct(self):
members = {'a': Typ1()}
- t1 = TStruct(members, label="a_struct")
- t2 = TStruct(members)
+ t1 = tp.Struct(members, label="a_struct")
+ t2 = tp.Struct(members)
- self.assert_eq(t1, TStruct(members, label="a_struct"))
+ self.assert_eq(t1, tp.Struct(members, label="a_struct"))
self.assert_neq(t1, t2)
self.assert_eq(t2, t2.clone())
- self.assert_neq(t2, TStruct(members))
+ self.assert_neq(t2, tp.Struct(members))
def test_TExternStruct(self):
- self.assert_eq(TExternStruct({}, 0), TExternStruct({}, 0))
- self.assert_eq(TExternStruct({}, "str"), TExternStruct({}, "str"))
- self.assert_neq(TExternStruct({}, 0), TExternStruct({}, "str"))
+ self.assert_eq(tp.ExternStruct({}, 0), tp.ExternStruct({}, 0))
+ self.assert_eq(tp.ExternStruct({}, "str"), tp.ExternStruct({}, "str"))
+ self.assert_neq(tp.ExternStruct({}, 0), tp.ExternStruct({}, "str"))
def test_TFunction(self):
- self.assert_eq(TFunction((), TVoid()), TFunction((), TVoid()))
- self.assert_neq(TFunction((Typ1(),), TVoid()), TFunction((), TVoid()))
-
- self.assert_eq(TFunction((Typ1(), TPtr(TVoid())), TPtr(Typ2())),
- TFunction((Typ1(), TPtr(TVoid())), TPtr(Typ2())))
- self.assert_neq(TFunction((Typ1(), TPtr(TVoid())), TPtr(Typ1())),
- TFunction((Typ1(), TPtr(TVoid())), TPtr(Typ2())))
- self.assert_neq(TFunction((Typ2(), TPtr(TVoid())), TPtr(Typ2())),
- TFunction((Typ1(), TPtr(TVoid())), TPtr(Typ2())))
- self.assert_neq(TFunction((TPtr(TVoid()), Typ1()), TPtr(Typ2())),
- TFunction((Typ1(), TPtr(TVoid())), TPtr(Typ2())))
+ self.assert_eq(tp.Function((), tp.Void()), tp.Function((), tp.Void()))
+ self.assert_neq(tp.Function((Typ1(),), tp.Void()), tp.Function((), tp.Void()))
+
+ self.assert_eq(tp.Function((Typ1(), tp.Ptr(tp.Void())), tp.Ptr(Typ2())),
+ tp.Function((Typ1(), tp.Ptr(tp.Void())), tp.Ptr(Typ2())))
+ self.assert_neq(tp.Function((Typ1(), tp.Ptr(tp.Void())), tp.Ptr(Typ1())),
+ tp.Function((Typ1(), tp.Ptr(tp.Void())), tp.Ptr(Typ2())))
+ self.assert_neq(tp.Function((Typ2(), tp.Ptr(tp.Void())), tp.Ptr(Typ2())),
+ tp.Function((Typ1(), tp.Ptr(tp.Void())), tp.Ptr(Typ2())))
+ self.assert_neq(tp.Function((tp.Ptr(tp.Void()), Typ1()), tp.Ptr(Typ2())),
+ tp.Function((Typ1(), tp.Ptr(tp.Void())), tp.Ptr(Typ2())))
# Direct constness doesn't matter
- self.assert_eq(TFunction((Typ1(True), TPtr(TVoid(), True)),
- TPtr(Typ2(), True)),
- TFunction((Typ1(), TPtr(TVoid())), TPtr(Typ2())))
+ self.assert_eq(tp.Function((Typ1(True), tp.Ptr(tp.Void(), True)),
+ tp.Ptr(Typ2(), True)),
+ tp.Function((Typ1(), tp.Ptr(tp.Void())), tp.Ptr(Typ2())))
# Constness behind indirection does
- self.assert_neq(TFunction((Typ1(), TPtr(TVoid(True))), TPtr(Typ2())),
- TFunction((Typ1(), TPtr(TVoid())), TPtr(Typ2())))
- self.assert_neq(TFunction((Typ1(), TPtr(TVoid())), TPtr(Typ2(True))),
- TFunction((Typ1(), TPtr(TVoid())), TPtr(Typ2())))
+ self.assert_neq(tp.Function((Typ1(), tp.Ptr(tp.Void(True))), tp.Ptr(Typ2())),
+ tp.Function((Typ1(), tp.Ptr(tp.Void())), tp.Ptr(Typ2())))
+ self.assert_neq(tp.Function((Typ1(), tp.Ptr(tp.Void())), tp.Ptr(Typ2(True))),
+ tp.Function((Typ1(), tp.Ptr(tp.Void())), tp.Ptr(Typ2())))
# Variadicity matters
- self.assert_eq(TFunction((), TVoid(), varargs=True),
- TFunction((), TVoid(), varargs=True))
- self.assert_neq(TFunction((), TVoid()),
- TFunction((), TVoid(), varargs=True))
+ self.assert_eq(tp.Function((), tp.Void(), varargs=True),
+ tp.Function((), tp.Void(), varargs=True))
+ self.assert_neq(tp.Function((), tp.Void()),
+ tp.Function((), tp.Void(), varargs=True))
def test_THook(self):
- self.assert_eq(THook(()), THook(()))
- self.assert_neq(THook(()), THook((Typ1(),)))
+ self.assert_eq(tp.Hook(()), tp.Hook(()))
+ self.assert_neq(tp.Hook(()), tp.Hook((Typ1(),)))
- self.assert_eq(THook((Typ1(), Typ2())), THook((Typ1(), Typ2())))
+ self.assert_eq(tp.Hook((Typ1(), Typ2())), tp.Hook((Typ1(), Typ2())))
# Order matters
- self.assert_neq(THook((Typ1(), Typ2())), THook((Typ2(), Typ1())))
+ self.assert_neq(tp.Hook((Typ1(), Typ2())), tp.Hook((Typ2(), Typ1())))
# Direct constness matters (for now; might change with tuple types)
- self.assert_neq(THook((Typ1(True), Typ2())), THook((Typ1(), Typ2())))
+ self.assert_neq(tp.Hook((Typ1(True), Typ2())), tp.Hook((Typ1(), Typ2())))
diff --git a/py/dml/warnings.py b/py/dml/warnings.py
new file mode 100644
index 000000000..57dce83b9
--- /dev/null
+++ b/py/dml/warnings.py
@@ -0,0 +1,433 @@
+# © 2021 Intel Corporation
+# SPDX-License-Identifier: MPL-2.0
+
+from .logging import DMLWarning, binary_dump, dollar, SimpleSite
+
+class NOVER(DMLWarning):
+ """
+ A DML file must start with a version statement, such as `dml 1.4;`
+ """
+ fmt = "file has no version tag, assuming version 1.2"
+
+class SHALL(DMLWarning):
+ """
+ The result of the shift operation will always be zero.
+ (This warning is disabled by default.)
+ """
+ fmt = "shifting away all data\n%s"
+ def __init__(self, node, lh, rh):
+ DMLWarning.__init__(self, node, binary_dump(lh, rh))
+
+class NDOC(DMLWarning):
+ """
+ No documentation string was specified for the attribute.
+ (This warning is disabled by default.)
+ """
+ fmt = "no documentation for '%s'"
+ def __init__(self, node, member):
+ DMLWarning.__init__(self, node, member)
+
+class NSHORTDESC(DMLWarning):
+ """
+ No short description string was specified using the 'desc' parameter.
+ (This warning is disabled by default.)
+ """
+ fmt = "no 'desc' parameter specified for device"
+ def __init__(self, node):
+ DMLWarning.__init__(self, node)
+
+class NDOCRA(DMLWarning):
+ """
+ No documentation string was specified for a _required_ attribute.
+ """
+ fmt = "no documentation for required attribute '%s'"
+ def __init__(self, node, member):
+ DMLWarning.__init__(self, node, member)
+
+class NEGOFFS(DMLWarning):
+ """
+ A negative integer expression is given as a register offset.
+ Register offsets are unsigned 64-bit numbers, which means that
+ a negative offset expression translates to a very large offset.
+ """
+ fmt = "negative register offset: %d"
+
+class UNUSED(DMLWarning):
+ """
+ The object is not referenced anywhere.
+ (This warning is disabled by default.; it typically causes many false
+ warnings.)
+ """
+ fmt = "unused: %s"
+ def __init__(self, obj):
+ DMLWarning.__init__(self, obj, obj.identity())
+
+class UNUSEDDEFAULT(DMLWarning):
+ """
+ The object is not referenced anywhere but it matches a name of an
+ object automatically referenced in another scope. This is the same
+ as WUNUSED but only for known common errors and it will never be
+ emitted if WUNUSED is enabled.
+ """
+ fmt = "unused: %s methods are not called automatically for %s objects in %s"
+ def __init__(self, obj):
+ DMLWarning.__init__(self, obj, obj.name, obj.parent.objtype,
+ obj.identity())
+
+class UNUSED_DML12(DMLWarning):
+ """A DML 1.4 file contains a method implementation that would override
+ a library method in DML 1.2, but which is not part of the DML 1.4
+ library, because some methods have been renamed. For instance,
+ implementing `read_access` in a register makes no sense
+ in DML 1.4, because the method has been renamed to
+ `read_register`.
+
+ If a DML 1.4 file contains common code that also is imported from
+ DML 1.2 devices, then it may need to implement methods like
+ `read_access` to get the right callbacks when compiled
+ for DML 1.2. Such implementations can be placed inside `#if
+ (dml_1_2) { }` blocks to avoid this warning.
+ """
+ fmt = ("unused implementation of DML 1.2 method %s;"
+ + " enclose in #if (dml_1_2) ?")
+ def __init__(self, obj):
+ DMLWarning.__init__(self, obj, obj.name)
+
+class DUPEVENT(DMLWarning):
+ """
+ Two or more events will be checkpointed using the same name, which
+ means that the checkpoint cannot be safely read back.
+ """
+ fmt = "duplicate event checkpoint names: %s"
+ def __init__(self, site, objlist):
+ DMLWarning.__init__(self, site,
+ ", ".join(dollar(self.site) + o.logname()
+ for o in objlist))
+
+class SIZEOFTYPE(DMLWarning):
+ """
+ The 'sizeof' operator is used on a type name, but expects an
+ expression. Use the 'sizeoftype' operator for types.
+ """
+ fmt = "sizeof on a type is not legal, use sizeoftype instead"
+
+class DEPRECATED(DMLWarning):
+ """
+ This part of the language is deprecated, usually because the
+ underlying support in Simics is deprecated.
+ """
+ fmt = "deprecation: %s"
+
+class EXPERIMENTAL(DMLWarning):
+ """
+ This part of the language is experimental, and not yet officially
+ supported. Code relying on the feature may break without notice in
+ future releases.
+ """
+ fmt = "Use of unsupported feature: %s"
+ def preprocess(self):
+ return super(EXPERIMENTAL, self).preprocess()
+
+class EXPERIMENTAL_UNMAPPED(EXPERIMENTAL):
+ __doc__ = EXPERIMENTAL.__doc__
+
+class CONFIDENTIAL(DMLWarning):
+ """
+ The object's name/qname is used as part of an expression in a
+ context other than the log statement, which could potentially lead
+ to the leak of confidential information.
+ """
+ fmt = "potential leak of confidential information"
+ def __init__(self, site):
+ DMLWarning.__init__(self, site)
+
+# Not used (see ctree.py class CopyData), not documented.
+# class WASSIGN(DMLWarning):
+# def __init__(self, site):
+# DMLWarning.__init__(self, site, "cannot perform assignment")
+
+class OLDAST(DMLWarning):
+ """
+ A precompiled DML file has an old time-stamp. This may happen if a
+ user accidentally edits a DML file from the standard library. A
+ safe way to suppress the warning is to remove the outdated
+ `.dmlast` file.
+ """
+ fmt = "Outdated AST file: %s"
+ def __init__(self, dmlfile):
+ DMLWarning.__init__(self, SimpleSite(dmlfile + ":0"),
+ dmlfile + "ast")
+
+class WRNSTMT(DMLWarning):
+ """
+ The source code contained a statement "`warning;`", which
+ causes a warning to be printed.
+ """
+ fmt = "%s"
+
+ # This message should be removed, SIMICS-9886
+
+class REF(DMLWarning):
+ """An unused parameter refers to an object that has not been declared.
+
+ This warning message will be replaced with a hard error in future
+ major versions of Simics.
+ """
+ instances = []
+ fmt = "unused parameter %s contains %s"
+
+ def __init__(self, site, param, eref):
+ # message formatting hack is based on this assumption
+ assert eref.msg.startswith('reference to unknown object ')
+ DMLWarning.__init__(self, site, param, eref.msg)
+
+class TEMPLATEIS(DMLWarning):
+ """In a template with methods marked `shared`, it is recommended that
+ other templates are instantiated on the same line"""
+ fmt = ("prefer 'is' statement outside template braces,"
+ + " 'template ... is (x, y) {'")
+
+class NOIS(DMLWarning):
+ """Many standard method overrides will only be recognized if a
+ template named like the method is also instantiated. For instance,
+ the method `set` in a field has no effect unless the
+ `set` template is instantiated.
+ """
+ def __init__(self, site, name):
+ DMLWarning.__init__(self, site, name, name)
+ fmt = ("implementation of %s() without 'is %s' is ignored"
+ + " by the standard library")
+
+class THROWS_DML12(DMLWarning):
+ """In DML 1.2, a method is by default permitted to throw an exception,
+ while in DML 1.4, an annotation `throws` is required for that.
+ So, if a method without annotations is ported to DML 1.4, it will
+ no longer permit exceptions. If such method is overridden by
+ a DML 1.2 file, then a non-throwing method is overridden by a potentially
+ throwing method, which is normally a type error. However, this particular
+ case is reduced to this warning. If an exception is uncaught in the
+ override, then this will automatically be caught in runtime and
+ an error message will be printed.
+ """
+ fmt = ("overriding non-throwing DML 1.4 method"
+ + " with throwing DML 1.2 method")
+ def __init__(self, site, other_site=None):
+ DMLWarning.__init__(self, site)
+ self.other_site = other_site
+ def log(self):
+ DMLWarning.log(self)
+ self.print_site_message(
+ self.other_site,
+ "original non-throwing declaration")
+
+class NEGCONSTCOMP(DMLWarning):
+ """DML uses a special method when comparing an unsigned and signed integer,
+ meaning that comparing a negative constant to an unsigned integer always
+ has the same result, which is usually not the intended behaviour."""
+ def __init__(self, site, expr, ty):
+ DMLWarning.__init__(self, site)
+ self.expr = expr
+ self.ty = ty
+ fmt = ("Comparing negative constant to unsigned integer has a constant "
+ + "result")
+ def log(self):
+ DMLWarning.log(self)
+ self.print_site_message(
+ self.expr.site, "Consider 'cast(%s, %s)'" % (self.expr, self.ty))
+
+class ASTRUNC(DMLWarning):
+ """The source of an assignment is a constant value that can't fit in the
+ type of the target, and is thus truncated. This warning can be silenced by
+ explicitly casting the expression to the target type.
+ """
+ fmt = ("The assignment source is a constant value which does not fit "
+ + "the assign target of type '%s', and will thus be truncated")
+
+class REDUNDANTLEVEL(DMLWarning):
+ """`X then Y` log level syntax has no effect when the
+ first and subsequent levels are the same.
+ """
+ def __init__(self, site):
+ DMLWarning.__init__(self, site)
+ fmt = ("'X then Y' log level has no effect when the levels are the same")
+
+class TTYPEC(DMLWarning):
+ """
+ The delay value provided to an `after` call is subject to
+ implicit type conversion which may be unexpected for certain types.
+ To silence this warning, explicitly cast the delay value to the expected
+ type.
+ """
+ fmt = ("the time value of type '%s' is implicitly converted "
+ + "to the type '%s' expected by the specified time unit '%s'.")
+
+class PCAST(DMLWarning):
+ """
+ A pointer is cast to a base type which has incompatible representation
+ compared to the original. Accessing the pointed-to object via the new
+ pointer type will almost certainly constitute undefined behavior.
+
+ This warning is extremely limited in scope: don't rely on it to catch every
+ bad pointer cast.
+
+ To silence this warning, first cast the pointer to `void *`, then cast it
+ to the desired type.
+ """
+ fmt = ("very suspect pointer-to-pointer cast: the new base type has "
+ + "incompatible representation. This could lead to your code "
+ + "getting mangled by the C compiler, with unpredictable results.\n"
+ + "old base type: %s\n"
+ + "new base type: %s%s")
+ def __init__(self, site, old, new, maybe_intended):
+ suggestion = ('\nperhaps you meant the new base type to be '
+ + maybe_intended.describe()
+ if maybe_intended else '')
+ DMLWarning.__init__(self, site, old, new, suggestion)
+
+class LOGMIXUP(DMLWarning):
+ """
+
+ A specified log level of a `log` looks as though you meant to specify the
+ log groups instead, and/or vice versa. For example:
+ ```
+ // Log group used as log level, when the intention is instead to
+ // specify log groups and implicitly use log level 1
+ log spec_viol, some_log_group: ...;
+
+ // Log groups and log level mistakenly specified in reverse order
+ log info, (some_log_group | another_log_group), 2: ...;
+
+ // Log level used as log groups, when the intention is instead to
+ // specify the subsequent log level
+ log info, 2, 3: ...;
+ ```
+ If you want to specify log groups, make sure to (explicitly) specify the
+ log level beforehand. If you want to specify the subsequent log level, use
+ `then` syntax.
+ ```
+ log spec_viol, 1, some_log_group: ...;
+ log info, 2, (some_log_group | another_log_group): ...;
+ log info, 2 then 3: ...;
+ ```
+
+ This warning is only enabled by default with Simics API version 7 or above
+ (due to the breaking change `enable_WLOGMIXUP`.)
+ """
+ fmt = ("log statement with likely misspecified log level(s) and log "
+ + "groups: %s")
+ def __init__(self, site, kind, level, later_level, groups):
+ suggestions = []
+ from .codegen import probable_loggroups_specification, \
+ probable_loglevel_specification
+ # There are three main scenarios for which we want to offer suggestions
+ # -- those covered in the docstring. All other scenarios either involve
+ # subsequent log levels -- at which point it's too difficult to guess
+ # what the user actually wanted to do -- or have no obvious fix that is
+ # not blatantly incorrect.
+ if probable_loggroups_specification(level):
+ if (not later_level
+ and not (groups.constant and not (1 <= groups.value <= 4))):
+ # Scenario 2: 'log info, 2, some_log_groups: ...;'
+ details = ("the specified log level and log groups look as "
+ + "though they are meant to be reversed.")
+ suggestions.append(f"log {kind}, {groups}, {level}: ...;")
+ else:
+ details = ("log group(s) and/or constant 0 are used as log "
+ + "level.")
+ if not later_level and groups.constant and groups.value == 0:
+ # Scenario 1: 'log info, some_log_groups: ...;'
+ suggestions.append(f"log {kind}, 1, {level}: ...;")
+ elif later_level and probable_loggroups_specification(later_level):
+ details = ("log group(s) and/or constant 0 are used as subsequent "
+ + "log level.")
+ else:
+ assert probable_loglevel_specification(groups)
+ details = "non-zero integer constant used as log groups."
+ if not later_level:
+ if site is None or site.dml_version != (1, 2):
+ # Scenario 3: 'log info, 2, 3: ...;'
+ suggestions.append(
+ f"log {kind}, {level} then {groups}: ...;")
+ if (not probable_loglevel_specification(level)
+ and not (groups.constant and groups.value == 5)):
+ # Scenario 2: 'log info, nonconstant, 3: ...;'
+ suggestions.append(f"log {kind}, {groups}, {level}: ...;")
+
+ if suggestions:
+ details += (" Perhaps you meant%s:\n%s"
+ % (" one of the below"*(len(suggestions) > 1),
+ '\n'.join(suggestions)))
+
+ DMLWarning.__init__(self, site, details)
+
+class IMMAFTER(DMLWarning):
+ """
+ An immediate `after` statement was specified where some argument to the
+ callback is a pointer to some stack-allocated data — i.e. a pointer
+ to data stored within a local variable. That data is guaranteed to be
+ invalid by the point the callback is called, which presents an enormous
+ security risk!
+ """
+ version = "1.4"
+ fmt = ("***INCREDIBLY UNSAFE*** use of immediate 'after' statement: the "
+ + "callback argument '%s' is a pointer to stack-allocated data!")
+
+class HOOKSEND(DMLWarning):
+ """
+ The `send` operation of a hook was called, and some provided message
+ component is a pointer to some stack-allocated data — i.e. a pointer
+ to data stored within a local variable. That data is guaranteed to be
+ invalid by the point the message is sent, which presents an enormous
+ security risk!
+
+ If you must use pointers to stack-allocated data, then `send_now` should
+ be used instead of `send`. If you want the message to be delayed to avoid
+ ordering bugs, create a method which wraps the `send_now` call together
+ with the declarations of the local variable(s) which you need pointers to,
+ and then use immediate after (`after: m(...)`) to delay the call to that
+ method.
+ """
+ version = "1.4"
+ fmt = ("***INCREDIBLY UNSAFE*** use of the 'send' operation of a hook: "
+ + "the message component '%s' is a pointer to stack-allocated "
+ + "data!\n"
+ + "Did you mean to use 'send_now' instead? See the Hook "
+ + "Declarations section in the DML 1.4 reference manual for "
+ + "information about the differences between 'send' and 'send_now'")
+
+class STRAYIS(DMLWarning):
+ """
+ A standalone `is` statement was found that looks like it was instead
+ intended to affect a preceding object declaration rather than the enclosing
+ object/template in which the `is` statement and (sub)object declaration are
+ made.
+
+ This typically happens due to a stray semicolon before the `is`, e.g.:
+ ```
+ field f @ [31:0]; is read_only;
+ ```
+ or
+ ```
+ field f @ [31:0];
+ is read_only;
+ ```
+
+ If done unintentionally, address this warning by making the `is` part of
+ the declared object. If there is indeed a stray semicolon this can
+ typically be accomplished simply by removing it.
+
+ If the standalone `is` statement is intentional, silence this warning
+ by making sure the `is` statement is on a new line separate from the object
+ declaration, and is not indented any deeper than the object declaration is.
+ """
+ fmt = ("suspect standalone 'is': formatting suggests it was meant to "
+ + "affect the %s declared just before it rather than the "
+ + "enclosing object/template. "
+ + "Perhaps you have a stray ';' before the 'is'?")
+
+
+all_warnings = dict(sorted(
+ (o.tag(), o) for o in globals().values()
+ if isinstance(o, type)
+ and issubclass(o, DMLWarning)
+ and o is not DMLWarning))
diff --git a/py/port_dml.py b/py/port_dml.py
index 2312efa15..6c4c4e847 100644
--- a/py/port_dml.py
+++ b/py/port_dml.py
@@ -27,7 +27,8 @@ def find_lexer(self_path):
path = self_path.parent
if (path / 'dml').is_dir():
sys.path.append(str(path))
- import dml.dmllex14 as _
+ # https://github.com/astral-sh/ruff/issues/25399
+ import dml.dmllex14 as _ # noqa: F401
return
raise Exception(
f'cannot find dmlc in {path}.'
@@ -283,7 +284,7 @@ def test_decode_loc(self):
def test_read_tokens(self):
find_lexer(Path(__file__))
- from dml.messages import ESYNTAX
+ import dml.errors as E
with TempFile(b"75 /**/ xyz;") as tf:
f = SourceFile(tf.name)
@@ -296,7 +297,7 @@ def test_read_tokens(self):
try:
for _ in f.read_tokens(2):
pass
- except ESYNTAX as e:
+ except E.SYNTAX as e:
self.assertIn('%s:5:4:' % (tf.name,), str(e))
else:
self.fail('expected ESYNTAX')
diff --git a/run_unit_tests.py b/run_unit_tests.py
index a70355818..6935de52b 100644
--- a/run_unit_tests.py
+++ b/run_unit_tests.py
@@ -8,12 +8,12 @@
(hostdir, testscript) = sys.argv[1:]
path = os.path.join(hostdir, "bin", "dml", "python")
if not os.path.isdir(path):
- optpar.error('not a directory: %r' % path)
+ sys.exit('error: not a directory: %r' % path)
sys.path.append(path)
if not os.path.isfile(testscript):
- optpar.error('not a file: %r' % testscript)
+ sys.exit('error: not a file: %r' % testscript)
sys.path.append(os.path.dirname(testscript))
base, ext = os.path.splitext(os.path.basename(testscript))
if ext != '.py':
- optpar.error('file name does end with .py: %r' % testscript)
+ sys.exit('error: file name does end with .py: %r' % testscript)
unittest.main(module = base, argv = [""])
diff --git a/test/1.2/events/T_after.py b/test/1.2/events/T_after.py
index 424a48846..72cc51d67 100644
--- a/test/1.2/events/T_after.py
+++ b/test/1.2/events/T_after.py
@@ -1,6 +1,9 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+import simics
+import testenv
+obj = testenv.instantiate()
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
obj.alttest = 1
diff --git a/test/1.2/events/T_after_array.py b/test/1.2/events/T_after_array.py
index 184bb281b..522cfa9d6 100644
--- a/test/1.2/events/T_after_array.py
+++ b/test/1.2/events/T_after_array.py
@@ -1,9 +1,12 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+import testenv
+obj = testenv.instantiate()
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
obj.alttest = 1
-SIM_continue(100000)
+simics.SIM_continue(100000)
stest.expect_true(obj.runtest)
diff --git a/test/1.2/events/T_after_chk_dup.cont.py b/test/1.2/events/T_after_chk_dup.cont.py
index 2492198e8..a91af0afa 100644
--- a/test/1.2/events/T_after_chk_dup.cont.py
+++ b/test/1.2/events/T_after_chk_dup.cont.py
@@ -1,11 +1,13 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import conf
-run_command("peq")
+simics.SIM_run_command("peq")
print("Running 2 s")
-SIM_continue(2000000)
+simics.SIM_continue(2000000)
stest.expect_true(conf.obj.a_flag)
stest.expect_true(conf.obj.b_flag)
diff --git a/test/1.2/events/T_after_chk_dup.py b/test/1.2/events/T_after_chk_dup.py
index f3fce40d3..1ec8354d6 100644
--- a/test/1.2/events/T_after_chk_dup.py
+++ b/test/1.2/events/T_after_chk_dup.py
@@ -1,20 +1,26 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-from os.path import join
+import simics
+from os.path import join, dirname
+from pathlib import Path
import subprocess
from simicsutils.host import batch_suffix
+import testenv
+import conf
+obj = testenv.instantiate()
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
obj.alttest = 1
-SIM_write_configuration_to_file(testname + ".chkp", Sim_Save_Nobundle)
+stem = Path(__file__).stem
+simics.SIM_write_configuration_to_file(stem + ".chkp", simics.Sim_Save_Nobundle)
subprocess.check_call(
[f'{conf.sim.project}/bin/simics{batch_suffix()}'] +
["--batch-mode", "--quiet", "--no-copyright", "--dump-core", "--werror",
'--project', conf.sim.project,
- "--module-path", scratchdir,
- "-e", f'read-configuration {testname + ".chkp"}',
- join(basedir, "T_"+testname+".cont.py")])
+ "--module-path", testenv.scratchdir(),
+ "-e", f'read-configuration {stem}.chkp',
+ join(dirname(__file__), stem + ".cont.py")])
diff --git a/test/1.2/events/T_after_param.py b/test/1.2/events/T_after_param.py
index cd0f9c160..da38fb53f 100644
--- a/test/1.2/events/T_after_param.py
+++ b/test/1.2/events/T_after_param.py
@@ -1,10 +1,13 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+import testenv
+obj = testenv.instantiate()
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
obj.alttest = 30
-SIM_continue(100000)
+simics.SIM_continue(100000)
stest.expect_equal(obj.num, 30)
stest.expect_equal(obj.p_num, [0, 30])
diff --git a/test/1.2/events/T_describe_event.py b/test/1.2/events/T_describe_event.py
index 487efa31c..287ec2af4 100644
--- a/test/1.2/events/T_describe_event.py
+++ b/test/1.2/events/T_describe_event.py
@@ -1,9 +1,12 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
obj.post_all = None
diff --git a/test/1.2/events/T_dup.cont.py b/test/1.2/events/T_dup.cont.py
index ee8492ae1..78cda0199 100644
--- a/test/1.2/events/T_dup.cont.py
+++ b/test/1.2/events/T_dup.cont.py
@@ -1,9 +1,11 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import conf
-SIM_continue(1000000)
+simics.SIM_continue(1000000)
stest.expect_equal(conf.obj.a_flag, True)
stest.expect_equal(conf.obj.b_flag, True)
diff --git a/test/1.2/events/T_dup.py b/test/1.2/events/T_dup.py
index 2db51e9aa..03cfbdea0 100644
--- a/test/1.2/events/T_dup.py
+++ b/test/1.2/events/T_dup.py
@@ -1,20 +1,24 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-from os.path import join
+import simics
+from os.path import join, dirname
import subprocess
from simicsutils.host import batch_suffix
+import testenv
+import conf
+obj = testenv.instantiate()
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
obj.postall = 1
-SIM_write_configuration_to_file("dup.chkp", Sim_Save_Nobundle)
+simics.SIM_write_configuration_to_file("dup.chkp", simics.Sim_Save_Nobundle)
subprocess.check_call(
[f'{conf.sim.project}/bin/simics{batch_suffix()}'] +
["--batch-mode", "--quiet", "--no-copyright", "--dump-core", "--werror",
'--project', conf.sim.project,
- "--module-path", scratchdir,
+ "--module-path", testenv.scratchdir(),
"-e", "read-configuration dup.chkp",
- join(basedir, "T_dup.cont.py")])
+ join(dirname(__file__), "T_dup.cont.py")])
diff --git a/test/1.2/events/T_event_info.py b/test/1.2/events/T_event_info.py
index 0530f153c..5ce0d7acb 100644
--- a/test/1.2/events/T_event_info.py
+++ b/test/1.2/events/T_event_info.py
@@ -1,14 +1,17 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
# Just posting user data with an event works.
obj.post_all = 100
-SIM_continue(1)
+simics.SIM_continue(1)
stest.expect_equal(obj.a, 100)
stest.expect_equal(obj.b, [[0, 0], [0, 100]])
@@ -16,7 +19,7 @@
# converted back and forth to an attribute.
obj.post_all = 100
cpu.time_queue = list(cpu.time_queue)
-SIM_continue(1)
+simics.SIM_continue(1)
# 20 + 3 was added to the parameter because of translation via
# get_event_info() + set_event_info()
stest.expect_equal(obj.a, 123)
diff --git a/test/1.2/events/T_next.py b/test/1.2/events/T_next.py
index 3f88c98ab..1f597aada 100644
--- a/test/1.2/events/T_next.py
+++ b/test/1.2/events/T_next.py
@@ -1,7 +1,10 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+import testenv
+obj = testenv.instantiate()
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
stest.expect_true(obj.runtest)
diff --git a/test/1.2/events/T_next_time.py b/test/1.2/events/T_next_time.py
index 3f88c98ab..1f597aada 100644
--- a/test/1.2/events/T_next_time.py
+++ b/test/1.2/events/T_next_time.py
@@ -1,7 +1,10 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+import testenv
+obj = testenv.instantiate()
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
stest.expect_true(obj.runtest)
diff --git a/test/1.2/events/T_no_queue.py b/test/1.2/events/T_no_queue.py
index a5a708cf2..a317ecabd 100644
--- a/test/1.2/events/T_no_queue.py
+++ b/test/1.2/events/T_no_queue.py
@@ -2,6 +2,8 @@
# SPDX-License-Identifier: MPL-2.0
import stest
+import testenv
+obj = testenv.instantiate()
with stest.expect_log_mgr(obj, "error"):
obj.after_test = 1
diff --git a/test/1.2/events/T_posted.py b/test/1.2/events/T_posted.py
index 3f88c98ab..1f597aada 100644
--- a/test/1.2/events/T_posted.py
+++ b/test/1.2/events/T_posted.py
@@ -1,7 +1,10 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+import testenv
+obj = testenv.instantiate()
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
stest.expect_true(obj.runtest)
diff --git a/test/1.2/events/T_remove.py b/test/1.2/events/T_remove.py
index 35b3a48d8..ab11477d0 100644
--- a/test/1.2/events/T_remove.py
+++ b/test/1.2/events/T_remove.py
@@ -1,16 +1,19 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
# event happens if you don't remove it. Should be caught by other test.
obj.last_ev = -1
obj.last_destroy = 0
obj.post = [5, 42]
-SIM_continue(5)
+simics.SIM_continue(5)
assert obj.last_ev == 42
assert obj.last_destroy == 0
@@ -18,19 +21,19 @@
obj.last_ev = 0
obj.last_destroy = 0
obj.post = [5, 42]
-SIM_continue(4)
+simics.SIM_continue(4)
obj.remove = 42
stest.expect_equal(obj.last_destroy, 42)
-SIM_continue(1)
+simics.SIM_continue(1)
stest.expect_equal(obj.last_ev, 0)
# event happens if you remove it with mismatching event data.
obj.last_ev = 0
obj.last_destroy = 0
obj.post = [5, 42]
-SIM_continue(4)
+simics.SIM_continue(4)
obj.remove = 43
-SIM_continue(1)
+simics.SIM_continue(1)
stest.expect_equal(obj.last_destroy, 0)
stest.expect_equal(obj.last_ev, 42)
@@ -48,7 +51,7 @@ def set_pattr_array(attrname, valarray):
set_pattr_array('last_ev', [[-1, -1], [-1, -1]])
set_pattr_array('last_destroy', [[0, 0], [0, 0]])
set_pattr_array('post', [[[5, 42], [5, 42]], [[5, 42], [5, 42]]])
-SIM_continue(5)
+simics.SIM_continue(5)
stest.expect_equal(get_pattr_array('last_ev'), [[42, 42], [42, 42]])
stest.expect_equal(get_pattr_array('last_destroy'), [[0, 0], [0, 0]])
@@ -56,19 +59,19 @@ def set_pattr_array(attrname, valarray):
set_pattr_array('last_ev', [[0, 0], [0, 0]])
set_pattr_array('last_destroy', [[0, 0], [0, 0]])
set_pattr_array('post', [[[5, 42], [5, 42]], [[5, 42], [5, 42]]])
-SIM_continue(4)
+simics.SIM_continue(4)
set_pattr_array('remove', [[42, 42], [42, 42]])
stest.expect_equal(get_pattr_array('last_destroy'), [[42, 42], [42, 42]])
-SIM_continue(1)
+simics.SIM_continue(1)
set_pattr_array('last_ev', [[0, 0], [0, 0]])
# event happens if you remove it with mismatching event data.
set_pattr_array('last_ev', [[0, 0], [0, 0]])
set_pattr_array('last_destroy', [[0, 0], [0, 0]])
set_pattr_array('post', [[[5, 42], [5, 42]], [[5, 42], [5, 42]]])
-SIM_continue(4)
+simics.SIM_continue(4)
set_pattr_array('remove', [[43, 43], [43, 43]])
-SIM_continue(1)
+simics.SIM_continue(1)
stest.expect_equal(get_pattr_array('last_ev'), [[42, 42], [42, 42]])
stest.expect_equal(get_pattr_array('last_destroy'), [[0, 0], [0, 0]])
diff --git a/test/1.2/events/T_stacked.py b/test/1.2/events/T_stacked.py
index c8ba718e2..b794d31bc 100644
--- a/test/1.2/events/T_stacked.py
+++ b/test/1.2/events/T_stacked.py
@@ -1,7 +1,10 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+import simics
+import testenv
+obj = testenv.instantiate()
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
obj.post = None
-SIM_continue(1)
+simics.SIM_continue(1)
diff --git a/test/1.2/internal/T_int_register.py b/test/1.2/internal/T_int_register.py
index 658c2848c..fee4a33ab 100644
--- a/test/1.2/internal/T_int_register.py
+++ b/test/1.2/internal/T_int_register.py
@@ -1,6 +1,8 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import testenv
+obj = testenv.instantiate()
RN = 17
RS = '_r0x0' # anonymized name
diff --git a/test/1.2/misc/T_destroy.py b/test/1.2/misc/T_destroy.py
index 596c9c847..99fd76e8e 100644
--- a/test/1.2/misc/T_destroy.py
+++ b/test/1.2/misc/T_destroy.py
@@ -4,11 +4,14 @@
# We need to create a second object, since run-test.py expects obj to
# remain after executing this script.
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+import simics
+import testenv
+obj = testenv.instantiate()
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
-o = SIM_create_object("test", "o", [["queue", cpu]])
+o = simics.SIM_create_object("test", "o", [["queue", cpu]])
print("Deleting")
-SIM_delete_object(o)
+simics.SIM_delete_object(o)
print("Done")
-SIM_continue(10000000)
+simics.SIM_continue(10000000)
print("Events not triggered")
diff --git a/test/1.2/misc/T_notify_state.py b/test/1.2/misc/T_notify_state.py
index 03c37a485..dcc10277f 100644
--- a/test/1.2/misc/T_notify_state.py
+++ b/test/1.2/misc/T_notify_state.py
@@ -1,13 +1,16 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
# Every time we access the counter, it will increase by 1
stest.expect_equal(obj.count, 0)
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
stest.expect_equal(obj.count, 1)
@@ -24,7 +27,7 @@
stest.expect_equal(obj.count, 7)
-SIM_continue(100000)
+simics.SIM_continue(100000)
stest.expect_equal(obj.count, 9)
diff --git a/test/1.2/misc/T_register_view_no_xml.py b/test/1.2/misc/T_register_view_no_xml.py
index e73d3e9e7..28efd5064 100644
--- a/test/1.2/misc/T_register_view_no_xml.py
+++ b/test/1.2/misc/T_register_view_no_xml.py
@@ -4,6 +4,8 @@
import stest
from simics import SIM_get_port_interface
+import testenv
+obj = testenv.instantiate()
b = SIM_get_port_interface(obj, 'register_view', 'b')
stest.expect_equal(b.description(), "")
diff --git a/test/1.2/misc/T_unimpl_templates.py b/test/1.2/misc/T_unimpl_templates.py
index 721d1c3da..1a1123066 100644
--- a/test/1.2/misc/T_unimpl_templates.py
+++ b/test/1.2/misc/T_unimpl_templates.py
@@ -1,8 +1,11 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import dev_util as du
import stest
+import testenv
+obj = testenv.instantiate()
expect = '''
Write to unimplemented register regs.r1 (0x10) (value written = 0x00001267).
@@ -124,7 +127,7 @@ def collect(arg, obj, logtype, msg):
global log_messages
log_messages.append(msg)
-SIM_hap_add_callback("Core_Log_Message", collect, 0)
+simics.SIM_hap_add_callback("Core_Log_Message", collect, 0)
def write(reg, val):
reg.write(val)
@@ -143,7 +146,7 @@ def test(obj, access):
reg = du.Register_LE(obj.bank.with_fields, offset)
access(reg)
-o = SIM_create_object("test", "o", [])
+o = simics.SIM_create_object("test", "o", [])
n = 4711
for l in range(1, 5):
o.bank.regs.log_level = l
diff --git a/test/1.2/misc/T_utility_14_api.py b/test/1.2/misc/T_utility_14_api.py
index a393a84ac..e01ee3e10 100644
--- a/test/1.2/misc/T_utility_14_api.py
+++ b/test/1.2/misc/T_utility_14_api.py
@@ -4,7 +4,8 @@
import stest
import dev_util
import sim_commands
-import contextlib
+import testenv
+obj = testenv.instantiate()
[read_write,
ignore_write,
diff --git a/test/1.2/misc/register_view.py b/test/1.2/misc/register_view.py
index 02266f640..c794f56dc 100644
--- a/test/1.2/misc/register_view.py
+++ b/test/1.2/misc/register_view.py
@@ -2,7 +2,9 @@
# SPDX-License-Identifier: MPL-2.0
import test_register_view
-from stest import expect_equal, expect_true, expect_log_mgr
+from stest import expect_equal, expect_log_mgr
+import testenv
+obj = testenv.instantiate()
test_register_view.test(obj)
diff --git a/test/1.2/misc/register_view_bitorder_be.py b/test/1.2/misc/register_view_bitorder_be.py
index d88d227f4..1b67e188c 100644
--- a/test/1.2/misc/register_view_bitorder_be.py
+++ b/test/1.2/misc/register_view_bitorder_be.py
@@ -1,7 +1,10 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
from stest import expect_true
+import testenv
+obj = testenv.instantiate()
-b = SIM_get_port_interface(obj, 'register_view', 'b')
+b = simics.SIM_get_port_interface(obj, 'register_view', 'b')
expect_true(b.big_endian_bitorder())
diff --git a/test/1.2/misc/register_view_bitorder_le.py b/test/1.2/misc/register_view_bitorder_le.py
index 99e4ff604..c3f3400f8 100644
--- a/test/1.2/misc/register_view_bitorder_le.py
+++ b/test/1.2/misc/register_view_bitorder_le.py
@@ -1,7 +1,10 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
from stest import expect_false
+import testenv
+obj = testenv.instantiate()
-b = SIM_get_port_interface(obj, 'register_view', 'b')
+b = simics.SIM_get_port_interface(obj, 'register_view', 'b')
expect_false(b.big_endian_bitorder())
diff --git a/test/1.2/misc/register_view_descriptions.py b/test/1.2/misc/register_view_descriptions.py
index 1691a7761..f04cf3dc3 100644
--- a/test/1.2/misc/register_view_descriptions.py
+++ b/test/1.2/misc/register_view_descriptions.py
@@ -2,5 +2,7 @@
# SPDX-License-Identifier: MPL-2.0
import test_register_view_descriptions
+import testenv
+obj = testenv.instantiate()
test_register_view_descriptions.test(obj)
diff --git a/test/1.2/misc/register_view_fields.py b/test/1.2/misc/register_view_fields.py
index 8ab40afff..c7d4e7eef 100644
--- a/test/1.2/misc/register_view_fields.py
+++ b/test/1.2/misc/register_view_fields.py
@@ -1,11 +1,13 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-from simics import *
+import simics
from stest import expect_equal
+import testenv
+obj = testenv.instantiate()
def test(obj):
- b = SIM_get_port_interface(obj, 'register_view', 'b')
+ b = simics.SIM_get_port_interface(obj, 'register_view', 'b')
expect_equal(b.register_info(0)[4], [['all', '', 0, 31]])
expect_equal(b.register_info(1)[4], [['g', '7', 7, 7],
diff --git a/test/1.2/misc/register_view_inquiry.py b/test/1.2/misc/register_view_inquiry.py
index e9edd7bcf..f684037d1 100644
--- a/test/1.2/misc/register_view_inquiry.py
+++ b/test/1.2/misc/register_view_inquiry.py
@@ -2,5 +2,7 @@
# SPDX-License-Identifier: MPL-2.0
import test_register_view_inquiry
+import testenv
+obj = testenv.instantiate()
test_register_view_inquiry.test(obj)
diff --git a/test/1.2/operators/T_interface_avail.py b/test/1.2/operators/T_interface_avail.py
index c92a42b0e..535061f4f 100644
--- a/test/1.2/operators/T_interface_avail.py
+++ b/test/1.2/operators/T_interface_avail.py
@@ -1,7 +1,10 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-cpu = SIM_create_object("clock", "cpu", [["freq_mhz", 1]])
+import simics
+import testenv
+obj = testenv.instantiate()
+cpu = simics.SIM_create_object("clock", "cpu", [["freq_mhz", 1]])
failures = 0
@@ -33,5 +36,5 @@
failures += 1
if failures:
- SIM_quit(1)
+ simics.SIM_quit(1)
diff --git a/test/1.2/registers/T_bankarray.py b/test/1.2/registers/T_bankarray.py
index cb18231b4..7ec4a3294 100644
--- a/test/1.2/registers/T_bankarray.py
+++ b/test/1.2/registers/T_bankarray.py
@@ -1,11 +1,15 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import dev_util
from stest import expect_equal
+import conf
+import testenv
+obj = testenv.instantiate()
-mem = SIM_create_object("memory-space", "mem",
- [["map",
+mem = simics.SIM_create_object("memory-space", "mem",
+ [["map",
[[0x0, [obj, "regs[0]"], 0, 0, 0x100],
[0x100, [obj, "regs[1]"], 0, 0, 0x100],
[0x200, obj, 3, 0, 0x100],
@@ -25,7 +29,6 @@ def wr(offset, value):
expect_equal(rd(0x200), 0xbadc0ffe)
expect_equal(rd(0x300), 0xdeadbeef)
-obj = conf.obj
obj.regs_ra = [[[0x10, 0x14], [0x18, 0x1c]], [[0x110, 0x114], [0x118, 0x11c]]]
obj.regs_g_gr = [[0x40, 0x54], [0x140, 0x154]]
obj.regs_g_gra = [[[[0x44, 0x48], [0x4c, 0x50]],
diff --git a/test/1.2/registers/T_be_slice.py b/test/1.2/registers/T_be_slice.py
index 794850c5d..167067449 100644
--- a/test/1.2/registers/T_be_slice.py
+++ b/test/1.2/registers/T_be_slice.py
@@ -1,10 +1,13 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
from functools import reduce
import operator
import stest, dev_util
-run_command("log-level 4")
+import testenv
+obj = testenv.instantiate()
+simics.SIM_run_command("log-level 4")
def check(bank, offset, size):
data = reduce(operator.ior, (
diff --git a/test/1.2/registers/T_get_exc.py b/test/1.2/registers/T_get_exc.py
index c1f779d84..9cd51093c 100644
--- a/test/1.2/registers/T_get_exc.py
+++ b/test/1.2/registers/T_get_exc.py
@@ -1,9 +1,12 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
+import testenv
+obj = testenv.instantiate()
try:
print(obj.b_r)
print("attribute get didn't fail as it should have")
- SIM_quit(1)
+ simics.SIM_quit(1)
except Exception as e:
print(e)
diff --git a/test/1.2/registers/T_inquiry.py b/test/1.2/registers/T_inquiry.py
index 84a283874..f83bbe88a 100644
--- a/test/1.2/registers/T_inquiry.py
+++ b/test/1.2/registers/T_inquiry.py
@@ -1,13 +1,14 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-import random
-
-from stest import *
+import simics
+import stest
import dev_util as du
from functools import reduce
+import testenv
+obj = testenv.instantiate()
-SIM_run_command("log-level 4")
+simics.SIM_run_command("log-level 4")
def reset_dev(d, r_val):
d.b_r = r_val
@@ -37,46 +38,46 @@ def expected_int(bytes, offs):
reset_dev(obj, 0)
r.write(val)
- expect_equal(obj.write_val, val << offs * 8)
- expect_equal(obj.before_write_called, True)
- expect_equal(obj.after_write_called, True)
- expect_equal(obj.before_read_called, False)
- expect_equal(obj.after_read_called, False)
- expect_equal(obj.before_set_called, False)
- expect_equal(obj.after_set_called, False)
+ stest.expect_equal(obj.write_val, val << offs * 8)
+ stest.expect_equal(obj.before_write_called, True)
+ stest.expect_equal(obj.after_write_called, True)
+ stest.expect_equal(obj.before_read_called, False)
+ stest.expect_equal(obj.after_read_called, False)
+ stest.expect_equal(obj.before_set_called, False)
+ stest.expect_equal(obj.after_set_called, False)
reset_dev(obj, 0)
r_inq.write(val)
- expect_equal(obj.b_r, val << offs * 8)
- expect_equal(obj.write_val, 0)
- expect_equal(obj.before_write_called, False)
- expect_equal(obj.after_write_called, False)
- expect_equal(obj.before_read_called, False)
- expect_equal(obj.after_read_called, False)
- expect_equal(obj.before_set_called, True)
- expect_equal(obj.after_set_called, True)
+ stest.expect_equal(obj.b_r, val << offs * 8)
+ stest.expect_equal(obj.write_val, 0)
+ stest.expect_equal(obj.before_write_called, False)
+ stest.expect_equal(obj.after_write_called, False)
+ stest.expect_equal(obj.before_read_called, False)
+ stest.expect_equal(obj.after_read_called, False)
+ stest.expect_equal(obj.before_set_called, True)
+ stest.expect_equal(obj.after_set_called, True)
READ_VALUE = (0xdeadbeefbaadc0de >> offs * 8) & ((1 << size * 8) - 1)
reset_dev(obj, val)
ret = r.read()
- expect_equal(ret, READ_VALUE)
- expect_equal(obj.b_r, val)
- expect_equal(obj.write_val, 0)
- expect_equal(obj.before_write_called, False)
- expect_equal(obj.after_write_called, False)
- expect_equal(obj.before_read_called, True)
- expect_equal(obj.after_read_called, True)
- expect_equal(obj.before_set_called, False)
- expect_equal(obj.after_set_called, False)
+ stest.expect_equal(ret, READ_VALUE)
+ stest.expect_equal(obj.b_r, val)
+ stest.expect_equal(obj.write_val, 0)
+ stest.expect_equal(obj.before_write_called, False)
+ stest.expect_equal(obj.after_write_called, False)
+ stest.expect_equal(obj.before_read_called, True)
+ stest.expect_equal(obj.after_read_called, True)
+ stest.expect_equal(obj.before_set_called, False)
+ stest.expect_equal(obj.after_set_called, False)
reset_dev(obj, val << offs * 8)
ret = r_inq.read()
- expect_equal(ret, val)
- expect_equal(obj.b_r, val << offs * 8)
- expect_equal(obj.write_val, 0)
- expect_equal(obj.before_write_called, False)
- expect_equal(obj.after_write_called, False)
- expect_equal(obj.before_read_called, False)
- expect_equal(obj.after_read_called, False)
- expect_equal(obj.before_set_called, False)
- expect_equal(obj.after_set_called, False)
+ stest.expect_equal(ret, val)
+ stest.expect_equal(obj.b_r, val << offs * 8)
+ stest.expect_equal(obj.write_val, 0)
+ stest.expect_equal(obj.before_write_called, False)
+ stest.expect_equal(obj.after_write_called, False)
+ stest.expect_equal(obj.before_read_called, False)
+ stest.expect_equal(obj.after_read_called, False)
+ stest.expect_equal(obj.before_set_called, False)
+ stest.expect_equal(obj.after_set_called, False)
diff --git a/test/1.2/registers/T_instrumentation.py b/test/1.2/registers/T_instrumentation.py
index 66a8f2b65..f24d8c73a 100644
--- a/test/1.2/registers/T_instrumentation.py
+++ b/test/1.2/registers/T_instrumentation.py
@@ -1,6 +1,7 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import instrumentation_access_inquire
import instrumentation_access_set_missed
import instrumentation_access_set_offset
@@ -22,16 +23,18 @@
import instrumentation_remove_callback
import instrumentation_remove_connection_callbacks
import instrumentation_subscribe_multiple
+import testenv
+obj = testenv.instantiate()
-subscribe_b1 = SIM_get_port_interface(
+subscribe_b1 = simics.SIM_get_port_interface(
obj, 'bank_instrumentation_subscribe', 'b1')
-subscribe_b2 = SIM_get_port_interface(
+subscribe_b2 = simics.SIM_get_port_interface(
obj, 'bank_instrumentation_subscribe', 'b2')
-order_b1 = SIM_get_port_interface(obj, 'instrumentation_order', 'b1')
+order_b1 = simics.SIM_get_port_interface(obj, 'instrumentation_order', 'b1')
subscribe_ba = [
- SIM_get_port_interface(obj, 'bank_instrumentation_subscribe', 'ba[0]'),
- SIM_get_port_interface(obj, 'bank_instrumentation_subscribe', 'ba[1]')]
+ simics.SIM_get_port_interface(obj, 'bank_instrumentation_subscribe', 'ba[0]'),
+ simics.SIM_get_port_interface(obj, 'bank_instrumentation_subscribe', 'ba[1]')]
# The tests don't clean up created connections, so run the connection
# order test first
diff --git a/test/1.2/registers/T_large_stride.py b/test/1.2/registers/T_large_stride.py
index d548d3c7d..b522c4fcc 100644
--- a/test/1.2/registers/T_large_stride.py
+++ b/test/1.2/registers/T_large_stride.py
@@ -2,6 +2,8 @@
# SPDX-License-Identifier: MPL-2.0
import stest, dev_util
+import testenv
+obj = testenv.instantiate()
regs = [dev_util.Register_LE(obj.bank.b, i*0x10000000, size=1) for i in range(16)]
diff --git a/test/1.2/registers/T_largearray.py b/test/1.2/registers/T_largearray.py
index 7b06db1ce..ca0cb2dcd 100644
--- a/test/1.2/registers/T_largearray.py
+++ b/test/1.2/registers/T_largearray.py
@@ -2,6 +2,8 @@
# SPDX-License-Identifier: MPL-2.0
import dev_util
+import testenv
+obj = testenv.instantiate()
a = dev_util.Register_LE(obj.bank.b, 50000)
b = dev_util.Register_LE(obj.bank.b, 90000)
diff --git a/test/1.2/registers/T_lowarray.py b/test/1.2/registers/T_lowarray.py
index aab83305a..e2cd6c4f1 100644
--- a/test/1.2/registers/T_lowarray.py
+++ b/test/1.2/registers/T_lowarray.py
@@ -1,20 +1,23 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-from stest import *
-untrap_log("spec-viol")
+import simics
+import stest
+import testenv
+obj = testenv.instantiate()
+stest.untrap_log("spec-viol")
-mem = SIM_create_object("memory-space", "mem",
+mem = simics.SIM_create_object("memory-space", "mem",
[["map", [[0, obj, 0, 0, 0x10000000, None, 0, 8192]]]])
try:
mem.iface.memory_space.read(None, 0, 4, 0)
- raise TestFailure("no exception")
-except SimExc_Memory:
+ raise stest.TestFailure("no exception")
+except simics.SimExc_Memory:
pass
data = mem.iface.memory_space.read(None, 16, 4, 0)
-expect_equal(data, (0x22,0x22,0x22,0x22))
+stest.expect_equal(data, (0x22,0x22,0x22,0x22))
data = mem.iface.memory_space.read(None, 40, 4, 0)
-expect_equal(data, (0x22,0x22,0x22,0x22))
+stest.expect_equal(data, (0x22,0x22,0x22,0x22))
diff --git a/test/1.2/registers/T_miss.py b/test/1.2/registers/T_miss.py
index 29e6d0d4b..f5db14d0a 100644
--- a/test/1.2/registers/T_miss.py
+++ b/test/1.2/registers/T_miss.py
@@ -18,6 +18,8 @@
import stest
import dev_util
+import testenv
+obj = testenv.instantiate()
def read(bank, offs, len):
return dev_util.Register_LE(bank, offs, size=len).read()
diff --git a/test/1.2/registers/T_miss_pattern.py b/test/1.2/registers/T_miss_pattern.py
index 4e7dea2b4..3e8ed9dea 100644
--- a/test/1.2/registers/T_miss_pattern.py
+++ b/test/1.2/registers/T_miss_pattern.py
@@ -4,6 +4,8 @@
import contextlib
import stest, dev_util
from stest import expect_equal
+import testenv
+obj = testenv.instantiate()
mkR = dev_util.Register_LE
@@ -133,8 +135,6 @@ def test_partial():
r5.write(0xabcd)
expect_equal(ru.read(), 0xcdab)
-#conf.obj.log_level = 4
-
test_overlap()
test_partial()
diff --git a/test/1.2/registers/T_numbered.py b/test/1.2/registers/T_numbered.py
index 905b0b3a1..46dc3205c 100644
--- a/test/1.2/registers/T_numbered.py
+++ b/test/1.2/registers/T_numbered.py
@@ -1,10 +1,13 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
def check_reg(bankname, name, regnum, val):
- iface = SIM_get_port_interface(obj, "int_register", bankname)
+ iface = simics.SIM_get_port_interface(obj, "int_register", bankname)
if name:
qname = bankname + "." + name
diff --git a/test/1.2/registers/T_par_over_endian.py b/test/1.2/registers/T_par_over_endian.py
index 2bd27a408..31819d75f 100644
--- a/test/1.2/registers/T_par_over_endian.py
+++ b/test/1.2/registers/T_par_over_endian.py
@@ -2,8 +2,10 @@
# SPDX-License-Identifier: MPL-2.0
import contextlib
-from simics import *
+import simics
import stest, dev_util
+import testenv
+obj = testenv.instantiate()
def byte_at(offs, big_endian_regsize):
if big_endian_regsize:
@@ -36,8 +38,8 @@ def write(bank, offset, length, partial = False, overlapping = False,
data = expected_data(offset, length, not little_endian)
print("DATA %x" % (data,))
illegal = (illegal
- or (partial and 'nonpar' in SIM_object_name(bank))
- or (overlapping and 'nonover' in SIM_object_name(bank)))
+ or (partial and 'nonpar' in simics.SIM_object_name(bank))
+ or (overlapping and 'nonover' in simics.SIM_object_name(bank)))
if illegal:
with expect_miss(bank):
reg.write(data)
@@ -50,8 +52,8 @@ def read(bank, offset, length,
print("Reading %d bytes from offset %#x" % (length, offset))
reg = dev_util.Register_LE(bank, offset, size=length)
illegal = (illegal
- or (partial and 'nonpar' in SIM_object_name(bank))
- or (overlapping and 'nonover' in SIM_object_name(bank)))
+ or (partial and 'nonpar' in simics.SIM_object_name(bank))
+ or (overlapping and 'nonover' in simics.SIM_object_name(bank)))
if illegal:
with expect_miss(bank):
reg.read()
@@ -154,5 +156,5 @@ def w(offs, size, force_little_endian=False, **args):
for p in ['nonpar', 'par']:
for o in ['nonover', 'over']:
for e in ['le', 'be']:
- test_some(SIM_object_descendant(obj.bank, '_'.join([p, o, e])),
+ test_some(simics.SIM_object_descendant(obj.bank, '_'.join([p, o, e])),
e == 'le')
diff --git a/test/1.2/registers/T_read_constant.py b/test/1.2/registers/T_read_constant.py
index 82aa16930..a68b79277 100644
--- a/test/1.2/registers/T_read_constant.py
+++ b/test/1.2/registers/T_read_constant.py
@@ -1,18 +1,21 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
stest.expect_equal(obj.b_r0, 0x12345678)
stest.expect_equal(obj.b_r1, 0x12345678)
try:
obj.b_r0 = 17
stest.fail("register is writable")
-except SimExc_AttrNotWritable:
+except simics.SimExc_AttrNotWritable:
pass
try:
obj.b_r1 = 17
stest.fail("register is writable")
-except SimExc_AttrNotWritable:
+except simics.SimExc_AttrNotWritable:
pass
diff --git a/test/1.2/registers/T_read_only.py b/test/1.2/registers/T_read_only.py
index b7df0f9c7..cd4302076 100644
--- a/test/1.2/registers/T_read_only.py
+++ b/test/1.2/registers/T_read_only.py
@@ -4,8 +4,10 @@
# Test that the read_only template works on registers with and without
# fields (bug 16355)
-from stest import *
+import stest
import dev_util as du
+import testenv
+obj = testenv.instantiate()
# Create register objects for accessing the DUT. R0 is a simple
# read-only register and R1 has a field. Both registers implement the
@@ -15,47 +17,47 @@
# Registers should have 0 as reset value and ignore writes (since they
# are read_only). They should also emit 'spec-viol' on write access.
-expect_equal(r0.read(), 0)
-expect_log(r0.write, [17], obj.bank.b, 'spec-viol')
-expect_equal(r0.read(), 0)
+stest.expect_equal(r0.read(), 0)
+stest.expect_log(r0.write, [17], obj.bank.b, 'spec-viol')
+stest.expect_equal(r0.read(), 0)
-expect_equal(r1.read(), 0)
-expect_log(r1.write, [17], obj.bank.b, 'spec-viol')
-expect_equal(r1.read(), 0)
+stest.expect_equal(r1.read(), 0)
+stest.expect_log(r1.write, [17], obj.bank.b, 'spec-viol')
+stest.expect_equal(r1.read(), 0)
# read-only fields should be writable with the same value
r2 = du.Register_LE(obj.bank.b, 8)
-expect_equal(r2.read(), 0)
+stest.expect_equal(r2.read(), 0)
r2.write(0)
-expect_log(r2.write, [17], obj.bank.b, 'spec-viol')
-expect_equal(r2.read(), 0)
+stest.expect_log(r2.write, [17], obj.bank.b, 'spec-viol')
+stest.expect_equal(r2.read(), 0)
# Testing no-alloc variants of read_only template
r3 = du.Register_LE(obj.bank.b, 12)
-expect_equal(r3.read(), 0)
-expect_log(r3.write, [17], obj.bank.b, 'spec-viol')
-expect_equal(r3.read(), 0)
+stest.expect_equal(r3.read(), 0)
+stest.expect_log(r3.write, [17], obj.bank.b, 'spec-viol')
+stest.expect_equal(r3.read(), 0)
r4 = du.Register_LE(obj.bank.b, 16)
-expect_equal(r4.read(), 0)
-expect_log(r4.write, [17], obj.bank.b, 'spec-viol')
-expect_equal(r4.read(), 0)
+stest.expect_equal(r4.read(), 0)
+stest.expect_log(r4.write, [17], obj.bank.b, 'spec-viol')
+stest.expect_equal(r4.read(), 0)
r5 = du.Register_LE(obj.bank.b, 20)
-expect_equal(r5.read(), 0)
+stest.expect_equal(r5.read(), 0)
r5.write(0)
-expect_log(r5.write, [17], obj.bank.b, 'spec-viol')
-expect_equal(r5.read(), 0)
+stest.expect_log(r5.write, [17], obj.bank.b, 'spec-viol')
+stest.expect_equal(r5.read(), 0)
r6 = du.Register_LE(obj.bank.b, 24)
-expect_equal(r6.read(), 7)
+stest.expect_equal(r6.read(), 7)
r6.write(7)
-expect_log(r6.write, [11], obj.bank.b, 'spec-viol')
-expect_equal(r6.read(), 7)
+stest.expect_log(r6.write, [11], obj.bank.b, 'spec-viol')
+stest.expect_equal(r6.read(), 7)
r7 = du.Register_LE(obj.bank.b, 28)
-expect_equal(r7.read(), 7)
+stest.expect_equal(r7.read(), 7)
r7.write(7)
-expect_log(r7.write, [11], obj.bank.b, 'spec-viol')
-expect_equal(r7.read(), 7)
+stest.expect_log(r7.write, [11], obj.bank.b, 'spec-viol')
+stest.expect_equal(r7.read(), 7)
diff --git a/test/1.2/registers/T_reserved.py b/test/1.2/registers/T_reserved.py
index 32b9dda39..d13be6c6c 100644
--- a/test/1.2/registers/T_reserved.py
+++ b/test/1.2/registers/T_reserved.py
@@ -1,30 +1,33 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-SIM_run_command("log-level 4")
-mem = SIM_create_object("memory-space", "mem",
+import simics
+import testenv
+obj = testenv.instantiate()
+simics.SIM_run_command("log-level 4")
+mem = simics.SIM_create_object("memory-space", "mem",
[["map", [[0, [obj, "regs"], 0, 0, 0x10000000]]]])
def loghap(arg, obj, logtype, msg):
global specviol
- if logtype == Sim_Log_Spec_Violation:
+ if logtype == simics.Sim_Log_Spec_Violation:
specviol = True
-SIM_hap_add_callback("Core_Log_Message", loghap, None)
+simics.SIM_hap_add_callback("Core_Log_Message", loghap, None)
def dowrite(offset, data, expect_failure):
global specviol
specviol = False
exc = mem.iface.memory_space.write(None, 0, data, 0)
- if exc != Sim_PE_No_Exception:
+ if exc != simics.Sim_PE_No_Exception:
print("exception when writing")
- SIM_quit(1)
+ simics.SIM_quit(1)
if expect_failure and not specviol:
print("no violation detected")
- SIM_quit(1)
+ simics.SIM_quit(1)
if not expect_failure and specviol:
print("stray violation detected")
- SIM_quit(1)
+ simics.SIM_quit(1)
# Should always be OK to write zero
dowrite(0, (0,0,0,0), False)
diff --git a/test/1.2/registers/T_unmapped_hole.py b/test/1.2/registers/T_unmapped_hole.py
index abe74e427..09c2000a1 100644
--- a/test/1.2/registers/T_unmapped_hole.py
+++ b/test/1.2/registers/T_unmapped_hole.py
@@ -2,6 +2,8 @@
# SPDX-License-Identifier: MPL-2.0
import stest, dev_util
+import testenv
+obj = testenv.instantiate()
regs = [dev_util.Register_LE(obj.bank.b, i, size=1) for i in range(3)]
diff --git a/test/1.2/statements/T_log.py b/test/1.2/statements/T_log.py
index 4386183b8..74ea82a9a 100644
--- a/test/1.2/statements/T_log.py
+++ b/test/1.2/statements/T_log.py
@@ -1,5 +1,8 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import testenv
+import conf
+obj = testenv.instantiate()
conf.sim.stop_on_error = False
obj.log_stuff = None
diff --git a/test/1.2/statements/T_log_new.py b/test/1.2/statements/T_log_new.py
index 6b57df918..35378d5e0 100644
--- a/test/1.2/statements/T_log_new.py
+++ b/test/1.2/statements/T_log_new.py
@@ -1,9 +1,13 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
+import testenv
+import conf
+obj = testenv.instantiate()
conf.sim.stop_on_error = False
if not obj.runtest:
print('test attribute returned false')
- SIM_quit(1)
+ simics.SIM_quit(1)
diff --git a/test/1.2/structure/T_attribute_array_1.py b/test/1.2/structure/T_attribute_array_1.py
index b532af7ce..71307e870 100644
--- a/test/1.2/structure/T_attribute_array_1.py
+++ b/test/1.2/structure/T_attribute_array_1.py
@@ -3,8 +3,10 @@
import stest
import simics
+import testenv
+obj = testenv.instantiate()
-[footype] = [attr[4] for attr in VT_get_all_attributes("test")
+[footype] = [attr[4] for attr in simics.VT_get_all_attributes("test")
if attr[0] == 'foo']
stest.expect_equal(footype, "[[i{4}]{4}]")
@@ -12,7 +14,7 @@
[8, 9, 10, 11], [12, 13, 14, 15]])
with stest.expect_exception_mgr(simics.SimExc_General):
- SIM_get_attribute(obj, 'bad')
+ simics.SIM_get_attribute(obj, 'bad')
with stest.expect_exception_mgr(simics.SimExc_General):
obj.bad = [None] * 5
diff --git a/test/1.2/structure/T_attribute_conf.dml b/test/1.2/structure/T_attribute_conf.dml
index 6279e12d0..f33513d8e 100644
--- a/test/1.2/structure/T_attribute_conf.dml
+++ b/test/1.2/structure/T_attribute_conf.dml
@@ -6,7 +6,6 @@ dml 1.2;
device test;
// must set required attributes
-/// INSTANTIATE-MANUALLY
attribute persist {
parameter persistent = true;
diff --git a/test/1.2/structure/T_attribute_conf.py b/test/1.2/structure/T_attribute_conf.py
index 6d010cf5c..9b9a6a5c2 100644
--- a/test/1.2/structure/T_attribute_conf.py
+++ b/test/1.2/structure/T_attribute_conf.py
@@ -2,9 +2,10 @@
# SPDX-License-Identifier: MPL-2.0
import stest
+import simics
import simicsutils
-obj = SIM_create_object('test', 'obj', [['b1_a', 5], ['b2_a', [0,1,2,3]]])
+obj = simics.SIM_create_object('test', 'obj', [['b1_a', 5], ['b2_a', [0,1,2,3]]])
stest.expect_equal(obj.bank.b1.a, 5)
stest.expect_equal([obj.bank.b2[i].a for i in range(4)], list(range(4)))
@@ -14,11 +15,11 @@
obj.persist = 17
if simicsutils.internal.get_simics_major() == "6":
- CORE_write_configuration_persistent("persistent.conf", None, Sim_Save_Nobundle)
+ simics.CORE_write_configuration_persistent("persistent.conf", None, simics.Sim_Save_Nobundle)
else:
- SIM_write_persistent_state("persistent.conf", None, Sim_Save_Nobundle)
+ simics.SIM_write_persistent_state("persistent.conf", None, simics.Sim_Save_Nobundle)
-config = VT_get_configuration("persistent.conf")
+config = simics.VT_get_configuration("persistent.conf")
print(config)
pobj = config.get('obj')
diff --git a/test/1.2/structure/T_attribute_string.py b/test/1.2/structure/T_attribute_string.py
index 804ee8b66..e4a06c47f 100644
--- a/test/1.2/structure/T_attribute_string.py
+++ b/test/1.2/structure/T_attribute_string.py
@@ -1,7 +1,10 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
+import testenv
+obj = testenv.instantiate()
obj.s = "teststring"
if obj.s != "teststring":
print("Failed to set and get string attribute")
- SIM_quit(1)
+ simics.SIM_quit(1)
diff --git a/test/1.2/structure/T_attribute_throw.py b/test/1.2/structure/T_attribute_throw.py
index 391001ded..e08337f18 100644
--- a/test/1.2/structure/T_attribute_throw.py
+++ b/test/1.2/structure/T_attribute_throw.py
@@ -1,16 +1,19 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
-with stest.expect_exception_mgr(SimExc_IllegalValue):
+with stest.expect_exception_mgr(simics.SimExc_IllegalValue):
obj.a = None
-with stest.expect_exception_mgr(SimExc_General):
- SIM_get_attribute(obj, "a")
+with stest.expect_exception_mgr(simics.SimExc_General):
+ simics.SIM_get_attribute(obj, "a")
-with stest.expect_exception_mgr(SimExc_IllegalValue):
+with stest.expect_exception_mgr(simics.SimExc_IllegalValue):
obj.b = None
-with stest.expect_exception_mgr(SimExc_General):
- SIM_get_attribute(obj, "b")
+with stest.expect_exception_mgr(simics.SimExc_General):
+ simics.SIM_get_attribute(obj, "b")
diff --git a/test/1.2/structure/T_connect_array.py b/test/1.2/structure/T_connect_array.py
index c83d3ec74..d55372d48 100644
--- a/test/1.2/structure/T_connect_array.py
+++ b/test/1.2/structure/T_connect_array.py
@@ -3,6 +3,8 @@
import stest
import dev_util
+import testenv
+obj = testenv.instantiate()
stest.expect_equal(obj.c, [[None, None, None], [None, None, None]])
diff --git a/test/1.2/structure/T_connect_validate.py b/test/1.2/structure/T_connect_validate.py
index bdfd23c84..1f5d966bb 100644
--- a/test/1.2/structure/T_connect_validate.py
+++ b/test/1.2/structure/T_connect_validate.py
@@ -1,11 +1,15 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
+import testenv
+import conf
+obj = testenv.instantiate()
conf.sim.stop_on_error = False
obj.foo = conf.sim
try:
obj.foo = obj
print("*** Failed to detect wrong object")
- SIM_quit(1)
-except SimExc_IllegalValue:
+ simics.SIM_quit(1)
+except simics.SimExc_IllegalValue:
pass
diff --git a/test/1.2/structure/T_connects_in_port_array.py b/test/1.2/structure/T_connects_in_port_array.py
index 43d083a5e..7be9a0e6f 100644
--- a/test/1.2/structure/T_connects_in_port_array.py
+++ b/test/1.2/structure/T_connects_in_port_array.py
@@ -3,6 +3,8 @@
import stest
import dev_util
+import testenv
+obj = testenv.instantiate()
for pa1 in obj.port.p:
for pa2 in pa1:
diff --git a/test/1.2/structure/T_desc.py b/test/1.2/structure/T_desc.py
index 51fc95562..57dd4d155 100644
--- a/test/1.2/structure/T_desc.py
+++ b/test/1.2/structure/T_desc.py
@@ -1,20 +1,23 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
stest.expect_equal(obj.class_desc, 'short desc 1')
-stest.expect_equal(VT_get_class_description(SIM_object_class(obj)),
+stest.expect_equal(simics.VT_get_class_description(simics.SIM_object_class(obj)),
'short desc 1')
-port = SIM_object_descendant(obj, 'bank.descb')
+port = simics.SIM_object_descendant(obj, 'bank.descb')
stest.expect_equal(port.class_desc, 'short desc 2')
-stest.expect_equal(VT_get_class_description(SIM_object_class(port)),
+stest.expect_equal(simics.VT_get_class_description(simics.SIM_object_class(port)),
'short desc 2')
-port = SIM_object_descendant(obj, 'port.descp')
+port = simics.SIM_object_descendant(obj, 'port.descp')
stest.expect_equal(port.class_desc, 'short desc 3')
-stest.expect_equal(VT_get_class_description(SIM_object_class(port)),
+stest.expect_equal(simics.VT_get_class_description(simics.SIM_object_class(port)),
'short desc 3')
for portname in ['port.nodescp', 'bank.nodescb']:
- port = SIM_object_descendant(obj, portname)
+ port = simics.SIM_object_descendant(obj, portname)
stest.expect_equal(port.class_desc, None)
- stest.expect_equal(VT_get_class_description(SIM_object_class(port)), None)
+ stest.expect_equal(simics.VT_get_class_description(simics.SIM_object_class(port)), None)
diff --git a/test/1.2/structure/T_doc.py b/test/1.2/structure/T_doc.py
index c220916db..f15f14919 100644
--- a/test/1.2/structure/T_doc.py
+++ b/test/1.2/structure/T_doc.py
@@ -1,16 +1,19 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
stest.expect_equal(obj.class_desc, None)
-stest.expect_equal(VT_get_class_description(SIM_object_class(obj)),
+stest.expect_equal(simics.VT_get_class_description(simics.SIM_object_class(obj)),
'long description')
-port = SIM_object_descendant(obj, 'port.doc_only')
+port = simics.SIM_object_descendant(obj, 'port.doc_only')
stest.expect_equal(port.class_desc, None)
-stest.expect_equal(VT_get_class_description(SIM_object_class(port)),
+stest.expect_equal(simics.VT_get_class_description(simics.SIM_object_class(port)),
'long description 2')
-port = SIM_object_descendant(obj, 'bank.doc_desc')
+port = simics.SIM_object_descendant(obj, 'bank.doc_desc')
stest.expect_equal(port.class_desc, 'short desc')
-stest.expect_equal(VT_get_class_description(SIM_object_class(port)),
+stest.expect_equal(simics.VT_get_class_description(simics.SIM_object_class(port)),
'long description 3')
diff --git a/test/1.2/structure/T_group_attr.py b/test/1.2/structure/T_group_attr.py
index ebedc2b37..b99bb98d2 100644
--- a/test/1.2/structure/T_group_attr.py
+++ b/test/1.2/structure/T_group_attr.py
@@ -1,6 +1,9 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
+import testenv
+obj = testenv.instantiate()
print(obj.b_ga_a)
if obj.b_ga_a == [[[i*100 + j*10 + k for k in range(3)]
@@ -9,4 +12,4 @@
print("OK")
else:
print("Incorrect value")
- SIM_quit(1)
+ simics.SIM_quit(1)
diff --git a/test/1.2/structure/T_mappable.py b/test/1.2/structure/T_mappable.py
index e6d231939..4482df999 100644
--- a/test/1.2/structure/T_mappable.py
+++ b/test/1.2/structure/T_mappable.py
@@ -1,15 +1,18 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
-print(SIM_get_port_interface(obj, "io_memory", "b1"))
+import testenv
+obj = testenv.instantiate()
+print(simics.SIM_get_port_interface(obj, "io_memory", "b1"))
try:
- print(SIM_get_port_interface(obj, "io_memory", "b2"))
+ print(simics.SIM_get_port_interface(obj, "io_memory", "b2"))
print("b2 is mappable")
- SIM_quit(1)
-except SimExc_Lookup:
+ simics.SIM_quit(1)
+except simics.SimExc_Lookup:
pass
-print(SIM_get_port_interface(obj, "io_memory", "b3"))
+print(simics.SIM_get_port_interface(obj, "io_memory", "b3"))
stest.expect_true(obj.runtest)
diff --git a/test/1.2/structure/T_port.py b/test/1.2/structure/T_port.py
index 1a0d57514..703995943 100644
--- a/test/1.2/structure/T_port.py
+++ b/test/1.2/structure/T_port.py
@@ -1,17 +1,20 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
-iface = SIM_get_port_interface(obj, "simple_interrupt", "p")
+iface = simics.SIM_get_port_interface(obj, "simple_interrupt", "p")
iface.interrupt(17)
stest.expect_equal(obj.p_last_irq, 17)
-port = SIM_object_descendant(obj, 'port.p')
-portclass = SIM_object_class(port)
+port = simics.SIM_object_descendant(obj, 'port.p')
+portclass = simics.SIM_object_class(port)
stest.expect_equal(portclass.name, 'test.p')
with stest.expect_log_mgr(log_type='error'):
- with stest.expect_exception_mgr(SimExc_General):
- SIM_create_object(portclass, obj.name + '.port.q', [])
-iface = SIM_get_interface(port, 'simple_interrupt')
+ with stest.expect_exception_mgr(simics.SimExc_General):
+ simics.SIM_create_object(portclass, obj.name + '.port.q', [])
+iface = simics.SIM_get_interface(port, 'simple_interrupt')
iface.interrupt(43)
stest.expect_equal(port.last_irq, 43)
diff --git a/test/1.2/structure/T_port_array.py b/test/1.2/structure/T_port_array.py
index b43d26bee..012ccb917 100644
--- a/test/1.2/structure/T_port_array.py
+++ b/test/1.2/structure/T_port_array.py
@@ -1,11 +1,14 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
-arr_iface = SIM_get_port_interface(obj, "signal", "prt[0]")
+arr_iface = simics.SIM_get_port_interface(obj, "signal", "prt[0]")
arr_iface.signal_raise()
-arr_iface = SIM_get_port_interface(obj, "signal", "prt[1]")
+arr_iface = simics.SIM_get_port_interface(obj, "signal", "prt[1]")
arr_iface.signal_raise()
stest.expect_equal(obj.prt_raised, [True, True, False, False])
@@ -24,8 +27,8 @@
for j, val in enumerate(sublist):
stest.expect_equal(obj.port.prtarr[i][j].raised, val)
-port = SIM_object_descendant(obj, 'port.prtarr[3][0]')
-portclass = SIM_object_class(port)
+port = simics.SIM_object_descendant(obj, 'port.prtarr[3][0]')
+portclass = simics.SIM_object_class(port)
stest.expect_equal(portclass.name, 'test.prtarr')
stest.expect_equal(port.raised, False)
diff --git a/test/1.2/structure/T_string_attribute.dml b/test/1.2/structure/T_string_attribute.dml
index 180a5db80..879695667 100644
--- a/test/1.2/structure/T_string_attribute.dml
+++ b/test/1.2/structure/T_string_attribute.dml
@@ -6,7 +6,6 @@ dml 1.2;
device test;
// must set required attributes
-/// INSTANTIATE-MANUALLY
attribute req "required" {
parameter allocate_type = "string";
diff --git a/test/1.2/structure/T_string_attribute.py b/test/1.2/structure/T_string_attribute.py
index 0bd22e3c3..d63cc3ba6 100644
--- a/test/1.2/structure/T_string_attribute.py
+++ b/test/1.2/structure/T_string_attribute.py
@@ -2,7 +2,7 @@
# SPDX-License-Identifier: MPL-2.0
import simics
-from stest import *
+import stest
obj = simics.SIM_create_object('test', 'obj', [['req', 'banan']])
@@ -10,23 +10,23 @@
_ = obj.opt
_ = obj.pse
-expect_equal(obj.req, "banan")
-expect_equal(obj.opt, None)
-expect_equal(obj.pse, None)
+stest.expect_equal(obj.req, "banan")
+stest.expect_equal(obj.opt, None)
+stest.expect_equal(obj.pse, None)
obj.req = "bazooka"
obj.opt = "apelsin"
obj.pse = "krutong"
-expect_equal(obj.req, "bazooka")
-expect_equal(obj.opt, "apelsin")
-expect_equal(obj.pse, "krutong")
+stest.expect_equal(obj.req, "bazooka")
+stest.expect_equal(obj.opt, "apelsin")
+stest.expect_equal(obj.pse, "krutong")
-expect_exception(setattr, [obj, 'req', None], SimExc_Type)
+stest.expect_exception(setattr, [obj, 'req', None], simics.SimExc_Type)
obj.opt = None
#obj.pse = None
#
-#expect_equal(obj.req, "bazooka")
-#expect_equal(obj.opt, "apelsin")
-#expect_equal(obj.pse, "krutong")
+#stest.expect_equal(obj.req, "bazooka")
+#stest.expect_equal(obj.opt, "apelsin")
+#stest.expect_equal(obj.pse, "krutong")
diff --git a/test/1.4/events/T_after.py b/test/1.4/events/T_after.py
index 9b62f6dc4..c1f375d32 100644
--- a/test/1.4/events/T_after.py
+++ b/test/1.4/events/T_after.py
@@ -1,9 +1,12 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
@@ -13,25 +16,25 @@
obj.trigger = [[1, 1], [1, 1]]
obj.trigger_hook = [1, 1]
obj.operate = None
-SIM_continue(99999)
+simics.SIM_continue(99999)
stest.expect_equal(obj.trigger, [[0, 0], [0, 0]])
stest.expect_equal(obj.trigger_hook, [0, 0])
stest.expect_equal(obj.single_operator, 0)
stest.expect_equal(obj.multi_operator, [[0, 0], [0, 0]])
stest.expect_equal(obj.hook_operator, [[0, 0], [0, 0]])
-SIM_continue(2)
+simics.SIM_continue(2)
stest.expect_equal(obj.trigger, [[0, 0], [0, 4]])
stest.expect_equal(obj.trigger_hook, [0, 2])
stest.expect_equal(obj.single_operator, 5)
stest.expect_equal(obj.multi_operator, [[0, 5], [3, 0]])
stest.expect_equal(obj.hook_operator, [[0, 5], [3, 0]])
-SIM_continue(99998)
+simics.SIM_continue(99998)
stest.expect_equal(obj.single_operator, 5)
-SIM_continue(2)
+simics.SIM_continue(2)
stest.expect_equal(obj.single_operator, 3)
obj.trigger_constig = None
-SIM_continue(99999)
+simics.SIM_continue(99999)
stest.expect_equal(obj.constig_res, [0, 0])
-SIM_continue(2)
+simics.SIM_continue(2)
stest.expect_equal(obj.constig_res, [4, 7 << 32 | 11])
diff --git a/test/1.4/events/T_after_cancel.py b/test/1.4/events/T_after_cancel.py
index 1b618f5ac..363fb65fc 100644
--- a/test/1.4/events/T_after_cancel.py
+++ b/test/1.4/events/T_after_cancel.py
@@ -1,9 +1,12 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
def init():
@@ -12,10 +15,10 @@ def init():
init()
obj.test_1 = None
-SIM_continue(99999)
+simics.SIM_continue(99999)
stest.expect_equal(obj.single_operator, 1)
stest.expect_equal(obj.multi_operator, [[1, 1], [1, 1]])
-SIM_continue(2)
+simics.SIM_continue(2)
stest.expect_equal(obj.single_operator, 216)
stest.expect_equal(obj.multi_operator, [[1, 216], [1, 1]])
@@ -23,10 +26,10 @@ def init():
try:
init()
obj.test_2 = i
- SIM_continue(99999)
+ simics.SIM_continue(99999)
stest.expect_equal(obj.single_operator, 1)
stest.expect_equal(obj.multi_operator, [[1, 1], [1, 1]])
- SIM_continue(2)
+ simics.SIM_continue(2)
stest.expect_equal(obj.single_operator, 2)
stest.expect_equal(obj.multi_operator, [[1, 5], [1, 1]])
except Exception as e:
diff --git a/test/1.4/events/T_after_chk.cont.py b/test/1.4/events/T_after_chk.cont.py
index f0967217d..45e109235 100644
--- a/test/1.4/events/T_after_chk.cont.py
+++ b/test/1.4/events/T_after_chk.cont.py
@@ -1,13 +1,14 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import conf
-run_command("peq")
+simics.run_command("peq")
conf.obj.cancel_afters = None
print("Running 2 s")
-SIM_continue(2000000)
-
+simics.SIM_continue(2000000)
stest.expect_equal(conf.obj.flag, [True]*2)
stest.expect_equal(conf.obj.g_flag, [False]*2)
stest.expect_equal(conf.obj.port.p[0][0].flag, [False]*2)
diff --git a/test/1.4/events/T_after_chk.py b/test/1.4/events/T_after_chk.py
index 06170e598..1c408e1a9 100644
--- a/test/1.4/events/T_after_chk.py
+++ b/test/1.4/events/T_after_chk.py
@@ -1,20 +1,24 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-from os.path import join
+import simics
+from os.path import join, dirname
import subprocess
from simicsutils.host import batch_suffix
+import testenv
+import conf
+obj = testenv.instantiate()
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
obj.exec_afters = None
-SIM_write_configuration_to_file("after_chk.chkp", Sim_Save_Nobundle)
+simics.SIM_write_configuration_to_file("after_chk.chkp", simics.Sim_Save_Nobundle)
subprocess.check_call(
[f'{conf.sim.project}/bin/simics{batch_suffix()}'] +
["--batch-mode", "--quiet", "--no-copyright", "--dump-core", "--werror",
'--project', conf.sim.project,
- "--module-path", scratchdir,
+ "--module-path", testenv.scratchdir(),
"-e", "read-configuration after_chk.chkp",
- join(basedir, "T_after_chk.cont.py")])
+ join(dirname(__file__), "T_after_chk.cont.py")])
diff --git a/test/1.4/expressions/T_illegal_arithmetic.py b/test/1.4/expressions/T_illegal_arithmetic.py
index 0d642df4e..4a287f31b 100644
--- a/test/1.4/expressions/T_illegal_arithmetic.py
+++ b/test/1.4/expressions/T_illegal_arithmetic.py
@@ -2,6 +2,9 @@
# SPDX-License-Identifier: MPL-2.0
import simics
+import testenv
+import conf
+obj = testenv.instantiate()
conf.sim.stop_on_error = False
try:
obj.not_zero = 0
diff --git a/test/1.4/expressions/T_trait_identity.py b/test/1.4/expressions/T_trait_identity.py
index e08d6076f..95eb49fca 100644
--- a/test/1.4/expressions/T_trait_identity.py
+++ b/test/1.4/expressions/T_trait_identity.py
@@ -3,6 +3,9 @@
import simics
import stest
+import testenv
+import conf
+obj = testenv.instantiate()
conf.sim.stop_on_error = False
try:
diff --git a/test/1.4/hooks/T_asynchronous_send.py b/test/1.4/hooks/T_asynchronous_send.py
index 812557f07..72250a73d 100644
--- a/test/1.4/hooks/T_asynchronous_send.py
+++ b/test/1.4/hooks/T_asynchronous_send.py
@@ -1,25 +1,28 @@
# © 2024 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+import simics
+import testenv
+obj = testenv.instantiate()
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
-setup_ev = SIM_register_event("setup_ev", None, Sim_EC_Notsaved,
+setup_ev = simics.SIM_register_event("setup_ev", None, simics.Sim_EC_Notsaved,
lambda _o, _d: obj.setup, None, None, None, None)
-test_ev = SIM_register_event("test_ev", None, Sim_EC_Notsaved,
+test_ev = simics.SIM_register_event("test_ev", None, simics.Sim_EC_Notsaved,
lambda _o, _d: obj.test, None, None, None, None)
# global context
_ = obj.setup
-SIM_process_pending_work()
+simics.SIM_process_pending_work()
_ = obj.test
# execution context
-SIM_event_post_cycle(cpu, setup_ev, obj, 0, None)
-SIM_continue(1)
+simics.SIM_event_post_cycle(cpu, setup_ev, obj, 0, None)
+simics.SIM_continue(1)
_ = obj.test
# global context into execution context
-SIM_event_post_cycle(cpu, test_ev, obj, 0, None)
+simics.SIM_event_post_cycle(cpu, test_ev, obj, 0, None)
_ = obj.setup
-SIM_continue(1)
+simics.SIM_continue(1)
diff --git a/test/1.4/hooks/T_bad_hookattr_set.py b/test/1.4/hooks/T_bad_hookattr_set.py
index d8dbf5f71..a017d282a 100644
--- a/test/1.4/hooks/T_bad_hookattr_set.py
+++ b/test/1.4/hooks/T_bad_hookattr_set.py
@@ -3,6 +3,8 @@
import simics;
import stest;
+import testenv
+obj = testenv.instantiate()
after_to_m_elem = ['after', ["('g[%u].m', (None, None))", [2], [2, True],
[['dev', []]]]]
diff --git a/test/1.4/hooks/T_checkpointing.cont.py b/test/1.4/hooks/T_checkpointing.cont.py
index 3e4b44aec..324ea06fc 100644
--- a/test/1.4/hooks/T_checkpointing.cont.py
+++ b/test/1.4/hooks/T_checkpointing.cont.py
@@ -1,6 +1,8 @@
# © 2024 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-SIM_read_configuration("checkpointing.chkp")
+import simics
+import conf
+simics.SIM_read_configuration("checkpointing.chkp")
conf.obj.test_state = None
diff --git a/test/1.4/hooks/T_checkpointing.py b/test/1.4/hooks/T_checkpointing.py
index ce0754173..3416b3644 100644
--- a/test/1.4/hooks/T_checkpointing.py
+++ b/test/1.4/hooks/T_checkpointing.py
@@ -1,17 +1,21 @@
# © 2024 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-from os.path import join
+import simics
+from os.path import join, dirname
import subprocess
from simicsutils.host import batch_suffix
+import testenv
+import conf
+obj = testenv.instantiate()
obj.setup_state = None
-SIM_write_configuration_to_file("checkpointing.chkp", Sim_Save_Nobundle)
+simics.SIM_write_configuration_to_file("checkpointing.chkp", simics.Sim_Save_Nobundle)
subprocess.check_call(
[f'{conf.sim.project}/bin/simics{batch_suffix()}'] +
["--batch-mode", "--quiet", "--no-copyright", "--dump-core", "--werror",
'--project', conf.sim.project,
- "-L", scratchdir,
- join(basedir, "T_checkpointing.cont.py")])
+ "-L", testenv.scratchdir(),
+ join(dirname(__file__), "T_checkpointing.cont.py")])
diff --git a/test/1.4/legacy/T_restrict_log_levels_disabled.py b/test/1.4/legacy/T_restrict_log_levels_disabled.py
index 679d3b7d0..6f5123f7c 100644
--- a/test/1.4/legacy/T_restrict_log_levels_disabled.py
+++ b/test/1.4/legacy/T_restrict_log_levels_disabled.py
@@ -1,7 +1,10 @@
# © 2024 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import sim_commands
import stest
+import testenv
+obj = testenv.instantiate()
class LogCapture(object):
def __init__(self):
diff --git a/test/1.4/lib/T_bad_subobj_connect.dml b/test/1.4/lib/T_bad_subobj_connect.dml
index 52b2986e6..882932616 100644
--- a/test/1.4/lib/T_bad_subobj_connect.dml
+++ b/test/1.4/lib/T_bad_subobj_connect.dml
@@ -6,8 +6,6 @@ dml 1.4;
device test;
-/// INSTANTIATE-MANUALLY
-
connect x is init_as_subobj {
param classname = "garbage";
}
diff --git a/test/1.4/lib/T_bad_subobj_connect.py b/test/1.4/lib/T_bad_subobj_connect.py
index b379c5f4a..7b0787c35 100644
--- a/test/1.4/lib/T_bad_subobj_connect.py
+++ b/test/1.4/lib/T_bad_subobj_connect.py
@@ -3,9 +3,10 @@
import simics
import stest
+import conf
conf.sim.stop_on_error = False
try:
- simics.SIM_load_module(f'dml-test-bad_subobj_connect')
+ simics.SIM_load_module('dml-test-bad_subobj_connect')
except simics.CriticalErrors as e:
stest.expect_true('garbage' in str(e))
else:
diff --git a/test/1.4/lib/T_bank.py b/test/1.4/lib/T_bank.py
index 99facdada..eb1e55fb5 100644
--- a/test/1.4/lib/T_bank.py
+++ b/test/1.4/lib/T_bank.py
@@ -1,7 +1,11 @@
# © 2026 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import sim_commands
import stest
+import testenv
+import conf
+obj = testenv.instantiate()
class LogCapture(object):
def __init__(self, kind='error'):
diff --git a/test/1.4/lib/T_connect.dml b/test/1.4/lib/T_connect.dml
index 35ee57337..f381f0fc5 100644
--- a/test/1.4/lib/T_connect.dml
+++ b/test/1.4/lib/T_connect.dml
@@ -10,7 +10,6 @@ import "simics/devs/signal.dml";
import "simics/devs/ethernet.dml";
// must define class 'signal_stub' before instantiating
-/// INSTANTIATE-MANUALLY
connect validate {
method validate(conf_object_t *obj) -> (bool) {
diff --git a/test/1.4/lib/T_connect.py b/test/1.4/lib/T_connect.py
index 606f4fc30..dfe29ac13 100644
--- a/test/1.4/lib/T_connect.py
+++ b/test/1.4/lib/T_connect.py
@@ -3,8 +3,8 @@
import pyobj
import stest
-import dev_util
import simics
+import conf
calls = []
class signal_stub(pyobj.ConfObject): pass
@@ -18,7 +18,7 @@ class signal_stub(pyobj.ConfObject): pass
stest.expect_equal(bad.sub_renamed, [None, None])
conf.sim.stop_on_error = True
-SIM_register_interface('signal_stub', 'signal', signal_interface_t(
+simics.SIM_register_interface('signal_stub', 'signal', simics.signal_interface_t(
signal_raise=lambda obj: calls.append((obj, 'signal_raise'))))
obj = simics.SIM_create_object('test', 'obj', [])
@@ -29,18 +29,18 @@ class signal_stub(pyobj.ConfObject): pass
stest.expect_equal(obj.attr.sub_renamed, [obj.sub[0].renamed,
obj.sub[1].renamed])
-stest.expect_true(SIM_object_descendant(obj, "a2[1].bank.b2[2].c2[4].d[6]"))
-stest.expect_true(SIM_object_descendant(obj, "a2[1].e.f"))
-stest.expect_true(SIM_object_descendant(obj, "a2[1].port.p.q"))
+stest.expect_true(simics.SIM_object_descendant(obj, "a2[1].bank.b2[2].c2[4].d[6]"))
+stest.expect_true(simics.SIM_object_descendant(obj, "a2[1].e.f"))
+stest.expect_true(simics.SIM_object_descendant(obj, "a2[1].port.p.q"))
# by default, init_as_subobj connects have configuration=none
-stest.expect_false(SIM_class_has_attribute('test', 'noconf'))
+stest.expect_false(simics.SIM_class_has_attribute('test', 'noconf'))
-with stest.expect_exception_mgr(SimExc_General):
+with stest.expect_exception_mgr(simics.SimExc_General):
obj.validate = [conf.sim, "foo"]
-with stest.expect_exception_mgr(SimExc_General):
+with stest.expect_exception_mgr(simics.SimExc_General):
obj.validate = conf.sim
-with stest.expect_exception_mgr(SimExc_General):
+with stest.expect_exception_mgr(simics.SimExc_General):
obj.validate = [obj, "bar"]
obj.validate = [obj, "foo"]
obj.validate = obj
@@ -65,12 +65,12 @@ def signal_lower(self): pass
both.register()
three.register()
[only_common, only_cable, both, three] = [
- SIM_create_object(name, name, []) for name in [
+ simics.SIM_create_object(name, name, []) for name in [
'only_common', 'only_cable', 'both', 'three']]
-with stest.expect_exception_mgr(SimExc_General):
+with stest.expect_exception_mgr(simics.SimExc_General):
obj.ifaces = only_common
-with stest.expect_exception_mgr(SimExc_General):
+with stest.expect_exception_mgr(simics.SimExc_General):
obj.ifaces = only_cable
obj.ifaces = both
diff --git a/test/1.4/lib/T_destroy.py b/test/1.4/lib/T_destroy.py
index 76ebb89d6..79dfd8b88 100644
--- a/test/1.4/lib/T_destroy.py
+++ b/test/1.4/lib/T_destroy.py
@@ -1,6 +1,9 @@
# © 2024 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
destroy_list = None
def on_destroyed(*invocations):
@@ -8,10 +11,10 @@ def on_destroyed(*invocations):
stest.expect_equal(destroy_list, None)
destroy_list = list(invocations)
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
obj.post_ev = None
-SIM_delete_object(obj)
+simics.SIM_delete_object(obj)
stest.expect_equal(destroy_list, ["ev", "g2", "g1", "dev"])
diff --git a/test/1.4/lib/T_event.py b/test/1.4/lib/T_event.py
index f07b9f2cf..84c2aadd3 100644
--- a/test/1.4/lib/T_event.py
+++ b/test/1.4/lib/T_event.py
@@ -1,9 +1,13 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
+import sim_commands
import stest
+import testenv
+obj = testenv.instantiate()
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
def get_posted_attrs(obj):
@@ -93,10 +97,10 @@ def read_happened_attrs(obj):
for cycle in sorted(cycles):
left = cycle - now
assert left > 1
- SIM_continue(left - 1)
+ simics.SIM_continue(left - 1)
stest.expect_equal(set(read_happened_attrs(obj).values()), {0},
'cycle %d' % (cycle - 1,))
- SIM_continue(1)
+ simics.SIM_continue(1)
now = cycle
happened_attrs = read_happened_attrs(obj)
# side-effect of a single event() call
@@ -148,6 +152,6 @@ def read_happened_attrs(obj):
def callback(o, kind, msg):
msgs.append(msg)
with sim_commands.logger.filter(callback):
- SIM_delete_object(obj)
+ simics.SIM_delete_object(obj)
stest.expect_equal(len(msgs), 2)
stest.expect_equal(set(msgs), {'DESTROY CYCLE -1', 'DESTROY TIME 1750'})
diff --git a/test/1.4/lib/T_event_large_uint64.py b/test/1.4/lib/T_event_large_uint64.py
index 68e3e13d9..607b2ee6b 100644
--- a/test/1.4/lib/T_event_large_uint64.py
+++ b/test/1.4/lib/T_event_large_uint64.py
@@ -1,12 +1,15 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
-clock = SIM_create_object('clock', 'clock', [['freq_mhz', 1]])
+clock = simics.SIM_create_object('clock', 'clock', [['freq_mhz', 1]])
obj.queue = clock
obj.post = None
-SIM_continue(1)
+simics.SIM_continue(1)
stest.expect_equal(obj.happened, 0xAFFFFFFFFFFFFFFF)
diff --git a/test/1.4/lib/T_field.py b/test/1.4/lib/T_field.py
index 53022de20..a75e67def 100644
--- a/test/1.4/lib/T_field.py
+++ b/test/1.4/lib/T_field.py
@@ -3,6 +3,8 @@
import dev_util
import stest
+import testenv
+obj = testenv.instantiate()
for name in ['r1', 'r2', 'r3', 'r4']:
setattr(obj, 'b_' + name, 4)
# set adds 1, get adds 2
diff --git a/test/1.4/lib/T_io_memory.py b/test/1.4/lib/T_io_memory.py
index 8a19336a9..155717a8a 100644
--- a/test/1.4/lib/T_io_memory.py
+++ b/test/1.4/lib/T_io_memory.py
@@ -1,8 +1,11 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
import dev_util
+import testenv
+obj = testenv.instantiate()
# bank_io_memory works
stest.expect_equal(dev_util.Register_LE(obj.port.bare, 0, size=1).read(), 0xaa)
@@ -33,7 +36,7 @@
stest.expect_equal(dev_util.Register_LE((obj.ab.cc, 0xb, 0), size=1).read(),
0xcc)
# accessing 0x10 hits address 0x100 in the bank
-ms = SIM_create_object('memory-space', 'ms', map=[[0x10, obj, 0xf, 0x100, 1]])
+ms = simics.SIM_create_object('memory-space', 'ms', map=[[0x10, obj, 0xf, 0x100, 1]])
ms.iface.memory_space.read(None, 0x10, 1, False)
# .. and incorrect function numbers are handled somewhat gracefully
with stest.expect_log_mgr(obj, 'error'), stest.expect_exception_mgr(
diff --git a/test/1.4/lib/T_largearray.py b/test/1.4/lib/T_largearray.py
index 65258a331..e34e2a9c8 100644
--- a/test/1.4/lib/T_largearray.py
+++ b/test/1.4/lib/T_largearray.py
@@ -2,6 +2,8 @@
# SPDX-License-Identifier: MPL-2.0
import dev_util
+import testenv
+obj = testenv.instantiate()
a = dev_util.Register_LE(obj.bank.b, 50000)
b = dev_util.Register_LE(obj.bank.b, 90000)
diff --git a/test/1.4/lib/T_map_target_connect.py b/test/1.4/lib/T_map_target_connect.py
index dbaac00f2..eb9d391b1 100644
--- a/test/1.4/lib/T_map_target_connect.py
+++ b/test/1.4/lib/T_map_target_connect.py
@@ -5,6 +5,8 @@
import simics
from dev_util import Register_LE
import re
+import testenv
+obj = testenv.instantiate()
stest.expect_equal(obj.y_value, 42)
diff --git a/test/1.4/lib/T_miss_pattern.py b/test/1.4/lib/T_miss_pattern.py
index ea202192f..143646ab3 100644
--- a/test/1.4/lib/T_miss_pattern.py
+++ b/test/1.4/lib/T_miss_pattern.py
@@ -4,6 +4,9 @@
import contextlib
import stest, dev_util
from stest import expect_equal
+import testenv
+import conf
+obj = testenv.instantiate()
mkR = dev_util.Register_LE
diff --git a/test/1.4/lib/T_objects_finalized.dml b/test/1.4/lib/T_objects_finalized.dml
index a044a937e..e2e74269f 100644
--- a/test/1.4/lib/T_objects_finalized.dml
+++ b/test/1.4/lib/T_objects_finalized.dml
@@ -6,8 +6,6 @@ dml 1.4;
device test;
-/// INSTANTIATE-MANUALLY
-
saved bool objects_finalized_done;
connect partner;
diff --git a/test/1.4/lib/T_objects_finalized.py b/test/1.4/lib/T_objects_finalized.py
index 33ef76af0..eb6e62c1d 100644
--- a/test/1.4/lib/T_objects_finalized.py
+++ b/test/1.4/lib/T_objects_finalized.py
@@ -1,14 +1,15 @@
# © 2026 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import conf
-
-obj1 = pre_conf_object('obj1', 'test')
-obj2 = pre_conf_object('obj2', 'test')
+obj1 = simics.pre_conf_object('obj1', 'test')
+obj2 = simics.pre_conf_object('obj2', 'test')
obj1.partner = obj2
obj2.partner = obj1
-SIM_add_configuration([obj1, obj2], None)
+simics.SIM_add_configuration([obj1, obj2], None)
stest.expect_true(conf.obj1.objects_finalized_done)
stest.expect_true(conf.obj1.g_objects_finalized_done)
diff --git a/test/1.4/lib/T_partial_access_log.py b/test/1.4/lib/T_partial_access_log.py
index 5aaac7507..66796dc04 100644
--- a/test/1.4/lib/T_partial_access_log.py
+++ b/test/1.4/lib/T_partial_access_log.py
@@ -1,8 +1,11 @@
# © 2025 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import dev_util
import stest
+import testenv
+obj = testenv.instantiate()
for (order, bank) in [('little', obj.bank.le), ('big', obj.bank.be)]:
bank.log_level = 4
diff --git a/test/1.4/lib/T_regdisp.py b/test/1.4/lib/T_regdisp.py
index b2b3bcf13..375bc622e 100644
--- a/test/1.4/lib/T_regdisp.py
+++ b/test/1.4/lib/T_regdisp.py
@@ -2,9 +2,10 @@
# SPDX-License-Identifier: MPL-2.0
import contextlib
-from simics import *
+import simics
import stest
-import dev_util
+import testenv
+obj = testenv.instantiate()
def test_some(mem, obj, port, allow_partial, allow_overlapping,
bigendian=False):
@@ -32,11 +33,11 @@ def write(offset, length, partial, overlapping, illegal):
or (overlapping and not allow_overlapping))
with contextlib.ExitStack() as ctx:
if illegal:
- ctx.enter_context(stest.expect_exception_mgr(SimExc_Memory))
+ ctx.enter_context(stest.expect_exception_mgr(simics.SimExc_Memory))
ctx.enter_context(stest.expect_log_mgr(None, 'spec-viol'))
exc = mem.iface.memory_space.write(None, offset, data, 0)
- if exc != Sim_PE_No_Exception:
- raise SimExc_Memory
+ if exc != simics.Sim_PE_No_Exception:
+ raise simics.SimExc_Memory
print("Wrote %r to %#x" % (data, offset))
def read(offset, length, partial, overlapping, illegal):
@@ -47,7 +48,7 @@ def read(offset, length, partial, overlapping, illegal):
or (overlapping and not allow_overlapping))
with contextlib.ExitStack() as ctx:
if illegal:
- ctx.enter_context(stest.expect_exception_mgr(SimExc_Memory))
+ ctx.enter_context(stest.expect_exception_mgr(simics.SimExc_Memory))
ctx.enter_context(stest.expect_log_mgr(None, 'spec-viol'))
data = mem.iface.memory_space.read(None, offset, length, 0)
print("Read %r from %#x" % (data, offset))
@@ -122,7 +123,7 @@ def access(offset, length, partial = False, overlapping = False,
access(0x500, 8, overlapping = True)
access(0x501, 8, overlapping = True)
-mem = SIM_create_object("memory-space", "mem", [])
+mem = simics.SIM_create_object("memory-space", "mem", [])
test_some(mem, obj, 'par_over',
allow_partial = True,
diff --git a/test/1.4/lib/T_reset.py b/test/1.4/lib/T_reset.py
index e27459c34..0482d0a8c 100644
--- a/test/1.4/lib/T_reset.py
+++ b/test/1.4/lib/T_reset.py
@@ -2,6 +2,8 @@
# SPDX-License-Identifier: MPL-2.0
import stest
+import testenv
+obj = testenv.instantiate()
stest.expect_equal(obj.b_r, [0, 1])
stest.expect_equal(obj.b_p, 0)
stest.expect_equal(obj.b_q, 0x123b)
diff --git a/test/1.4/lib/T_signal_templates.dml b/test/1.4/lib/T_signal_templates.dml
index 65be3f9c1..1b985b08a 100644
--- a/test/1.4/lib/T_signal_templates.dml
+++ b/test/1.4/lib/T_signal_templates.dml
@@ -2,7 +2,6 @@
© 2022 Intel Corporation
SPDX-License-Identifier: MPL-2.0
*/
-/// INSTANTIATE-MANUALLY
dml 1.4;
device test;
diff --git a/test/1.4/lib/T_signal_templates.py b/test/1.4/lib/T_signal_templates.py
index 11f52ba4c..f687d7299 100644
--- a/test/1.4/lib/T_signal_templates.py
+++ b/test/1.4/lib/T_signal_templates.py
@@ -4,6 +4,7 @@
import os
import simics
import stest
+import testenv
class signal_stub:
@@ -36,7 +37,7 @@ def signal_lower(self):
stest.expect_equal(stub.level, 1)
# loading a checkpoint doesn't call raise
-cpfile = os.path.join(scratchdir, "checkpoint")
+cpfile = os.path.join(testenv.scratchdir(), "checkpoint")
simics.SIM_write_configuration_to_file(cpfile, 0)
simics.SIM_delete_objects([clock, clock.cell, stub, obj])
simics.SIM_read_configuration(cpfile)
diff --git a/test/1.4/lib/T_transaction.py b/test/1.4/lib/T_transaction.py
index ef5a0c2ec..3794ca5e8 100644
--- a/test/1.4/lib/T_transaction.py
+++ b/test/1.4/lib/T_transaction.py
@@ -1,43 +1,45 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-from simics import Sim_PE_No_Exception
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
for b, endian in ((obj.bank.b, 'little'), (obj.bank.be, 'big')):
- trans = transaction_t(read=True, size=4)
+ trans = simics.transaction_t(read=True, size=4)
stest.expect_equal((b.iface.transaction.issue(trans, 3), b.read_offset,
trans.value_be if endian == 'big' else trans.value_le,
b.read_mask, b.read_aux),
- (Sim_PE_No_Exception, 3, 4711, 0xffffffff, 1234),
+ (simics.Sim_PE_No_Exception, 3, 4711, 0xffffffff, 1234),
trans.data)
stest.expect_equal(b.iface.transaction.issue(trans, 13),
- Sim_PE_IO_Not_Taken)
+ simics.Sim_PE_IO_Not_Taken)
- trans = transaction_t(read=True, inquiry=True, size=4)
+ trans = simics.transaction_t(read=True, inquiry=True, size=4)
stest.expect_equal((b.iface.transaction.issue(trans, 3), b.get_offset,
trans.value_be if endian == 'big' else trans.value_le,
b.get_size),
- (Sim_PE_No_Exception, 3, 4711, 4,))
+ (simics.Sim_PE_No_Exception, 3, 4711, 4,))
stest.expect_equal(b.iface.transaction.issue(trans, 13),
- Sim_PE_IO_Not_Taken)
+ simics.Sim_PE_IO_Not_Taken)
- trans = transaction_t(write=True, data=int.to_bytes(4712, 3, endian))
+ trans = simics.transaction_t(write=True, data=int.to_bytes(4712, 3, endian))
stest.expect_equal((b.iface.transaction.issue(trans, 5),
b.write_offset, b.write_value, b.write_mask,
b.write_aux),
- (Sim_PE_No_Exception, 5, 4712, 0xffffff, 1234))
+ (simics.Sim_PE_No_Exception, 5, 4712, 0xffffff, 1234))
stest.expect_equal(b.iface.transaction.issue(trans, 13),
- Sim_PE_IO_Not_Taken)
+ simics.Sim_PE_IO_Not_Taken)
- trans = transaction_t(
+ trans = simics.transaction_t(
write=True, inquiry=True, data=int.to_bytes(4712, 3, endian))
stest.expect_equal((b.iface.transaction.issue(trans, 5),
b.set_offset, b.set_value, b.set_size),
- (Sim_PE_No_Exception, 5, 4712, 3))
+ (simics.Sim_PE_No_Exception, 5, 4712, 3))
stest.expect_equal(b.iface.transaction.issue(trans, 13),
- Sim_PE_No_Exception)
+ simics.Sim_PE_No_Exception)
exp_offsets = [17, 24, 32, 0]
exp_chunks = [(0, 7), (7, 15), (15, 20)]
@@ -46,31 +48,31 @@
for (v, sz) in zip(exp_multi_value, (7, 8, 5)))
exp_value = exp_multi_value[2]
- trans = transaction_t(write=True, inquiry=True, data=data)
+ trans = simics.transaction_t(write=True, inquiry=True, data=data)
stest.expect_equal((b.iface.transaction.issue(trans, 17),
b.set_offset, b.set_value, b.set_size),
- (Sim_PE_No_Exception, 32, exp_value, 5))
+ (simics.Sim_PE_No_Exception, 32, exp_value, 5))
stest.expect_equal(b.set_multi_value, exp_multi_value)
stest.expect_equal(b.set_multi_offset, exp_offsets)
- trans = transaction_t(write=True, data=data)
+ trans = simics.transaction_t(write=True, data=data)
stest.expect_equal((b.iface.transaction.issue(trans, 17),
b.write_offset, b.write_value),
- (Sim_PE_No_Exception, 32, exp_value))
+ (simics.Sim_PE_No_Exception, 32, exp_value))
stest.expect_equal(b.write_multi_value, exp_multi_value)
stest.expect_equal(b.write_multi_offset, exp_offsets)
- trans = transaction_t(read=True, inquiry=True, size=20)
+ trans = simics.transaction_t(read=True, inquiry=True, size=20)
stest.expect_equal((b.iface.transaction.issue(trans, 17),
b.get_offset, b.get_size),
- (Sim_PE_No_Exception, 32, 5))
+ (simics.Sim_PE_No_Exception, 32, 5))
stest.expect_equal(b.get_multi_offset, exp_offsets)
for x, y in exp_chunks:
stest.expect_equal(int.from_bytes(trans.data[x:y], endian), 4711)
- trans = transaction_t(read=True, size=20)
+ trans = simics.transaction_t(read=True, size=20)
stest.expect_equal((b.iface.transaction.issue(trans, 17), b.read_offset),
- (Sim_PE_No_Exception, 32))
+ (simics.Sim_PE_No_Exception, 32))
stest.expect_equal(b.read_multi_offset, exp_offsets)
for x, y in exp_chunks:
stest.expect_equal(int.from_bytes(trans.data[x:y], endian), 4711)
diff --git a/test/1.4/lib/T_utility.py b/test/1.4/lib/T_utility.py
index ef6cb6cc6..8783f3d13 100644
--- a/test/1.4/lib/T_utility.py
+++ b/test/1.4/lib/T_utility.py
@@ -4,7 +4,9 @@
import stest
import dev_util
import sim_commands
-import contextlib
+import testenv
+import conf
+obj = testenv.instantiate()
[read_write,
ignore_write,
diff --git a/test/1.4/methods/T_startup.dml b/test/1.4/methods/T_startup.dml
index f106d24ac..10f050665 100644
--- a/test/1.4/methods/T_startup.dml
+++ b/test/1.4/methods/T_startup.dml
@@ -6,8 +6,6 @@ dml 1.4;
device test;
-/// INSTANTIATE-MANUALLY
-
independent method call_on_startup(const char *name) {
local attr_value_t args = SIM_make_attr_list(
1, SIM_make_attr_string(name));
diff --git a/test/1.4/methods/T_startup.py b/test/1.4/methods/T_startup.py
index 46c287c75..484325b23 100644
--- a/test/1.4/methods/T_startup.py
+++ b/test/1.4/methods/T_startup.py
@@ -1,6 +1,7 @@
# © 2022 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
startup_calls = {'a': 0, 'b': 0}
@@ -10,7 +11,7 @@ def on_startup(name):
startup_calls[name] += 1
stest.expect_equal(startup_calls, {'a': 0, 'b': 0})
-SIM_load_module('dml-test-startup')
+simics.SIM_load_module('dml-test-startup')
stest.expect_equal(startup_calls, {'a': 1, 'b': 4})
-obj = SIM_create_object('test', 'obj', [])
+obj = simics.SIM_create_object('test', 'obj', [])
stest.expect_equal(startup_calls, {'a': 1, 'b': 4})
diff --git a/test/1.4/methods/T_startup_memoized.dml b/test/1.4/methods/T_startup_memoized.dml
index 47cbedd3b..541bf4414 100644
--- a/test/1.4/methods/T_startup_memoized.dml
+++ b/test/1.4/methods/T_startup_memoized.dml
@@ -5,8 +5,6 @@
dml 1.4;
device test;
-/// INSTANTIATE-MANUALLY
-
independent method call_on_startup(const char *node, const char *meth) {
local attr_value_t args = SIM_make_attr_list(
2, SIM_make_attr_string(node), SIM_make_attr_string(meth));
diff --git a/test/1.4/methods/T_startup_memoized.py b/test/1.4/methods/T_startup_memoized.py
index 02e139d0c..1256ed75d 100644
--- a/test/1.4/methods/T_startup_memoized.py
+++ b/test/1.4/methods/T_startup_memoized.py
@@ -1,6 +1,7 @@
# © 2022 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import itertools
import stest
@@ -17,7 +18,7 @@ def on_startup(node, meth):
global startup_calls
startup_calls[(node, meth)] += 1
-SIM_load_module('dml-test-startup_memoized')
+simics.SIM_load_module('dml-test-startup_memoized')
stest.expect_equal(startup_calls, expected_after_startup)
-obj = SIM_create_object('test', 'obj', [])
+obj = simics.SIM_create_object('test', 'obj', [])
stest.expect_equal(startup_calls, expected_after_startup)
diff --git a/test/1.4/misc/T_notify_state.py b/test/1.4/misc/T_notify_state.py
index c9a2e219b..9dbe23bd4 100644
--- a/test/1.4/misc/T_notify_state.py
+++ b/test/1.4/misc/T_notify_state.py
@@ -1,11 +1,14 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
stest.expect_equal(obj.count, 0)
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
# TODO: is this the desired behaviour? attributes not controlled by DML do not
# count for the context
obj.queue = cpu
@@ -24,7 +27,7 @@
stest.expect_equal(obj.count, 3)
-SIM_continue(100000)
+simics.SIM_continue(100000)
stest.expect_equal(obj.count, 4)
@@ -32,11 +35,11 @@
stest.expect_equal(obj.count, 5)
-SIM_notify(obj, SIM_notifier_type("exported-entry"))
+simics.SIM_notify(obj, simics.SIM_notifier_type("exported-entry"))
stest.expect_equal(obj.count, 6)
-SIM_notify(obj, SIM_notifier_type("statically-exported-entry"))
+simics.SIM_notify(obj, simics.SIM_notifier_type("statically-exported-entry"))
stest.expect_equal(obj.count, 7)
@@ -44,6 +47,6 @@
stest.expect_equal(obj.count, 8)
-SIM_process_pending_work()
+simics.SIM_process_pending_work()
stest.expect_equal(obj.count, 9)
diff --git a/test/1.4/misc/T_register_view.py b/test/1.4/misc/T_register_view.py
index b501dd008..05f89ae0d 100644
--- a/test/1.4/misc/T_register_view.py
+++ b/test/1.4/misc/T_register_view.py
@@ -2,5 +2,7 @@
# SPDX-License-Identifier: MPL-2.0
import test_register_view
+import testenv
+obj = testenv.instantiate()
test_register_view.test(obj)
diff --git a/test/1.4/misc/T_register_view_bitorder_be.py b/test/1.4/misc/T_register_view_bitorder_be.py
index d88d227f4..1b67e188c 100644
--- a/test/1.4/misc/T_register_view_bitorder_be.py
+++ b/test/1.4/misc/T_register_view_bitorder_be.py
@@ -1,7 +1,10 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
from stest import expect_true
+import testenv
+obj = testenv.instantiate()
-b = SIM_get_port_interface(obj, 'register_view', 'b')
+b = simics.SIM_get_port_interface(obj, 'register_view', 'b')
expect_true(b.big_endian_bitorder())
diff --git a/test/1.4/misc/T_register_view_bitorder_le.py b/test/1.4/misc/T_register_view_bitorder_le.py
index 99e4ff604..c3f3400f8 100644
--- a/test/1.4/misc/T_register_view_bitorder_le.py
+++ b/test/1.4/misc/T_register_view_bitorder_le.py
@@ -1,7 +1,10 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
from stest import expect_false
+import testenv
+obj = testenv.instantiate()
-b = SIM_get_port_interface(obj, 'register_view', 'b')
+b = simics.SIM_get_port_interface(obj, 'register_view', 'b')
expect_false(b.big_endian_bitorder())
diff --git a/test/1.4/misc/T_register_view_descriptions.py b/test/1.4/misc/T_register_view_descriptions.py
index 1691a7761..f04cf3dc3 100644
--- a/test/1.4/misc/T_register_view_descriptions.py
+++ b/test/1.4/misc/T_register_view_descriptions.py
@@ -2,5 +2,7 @@
# SPDX-License-Identifier: MPL-2.0
import test_register_view_descriptions
+import testenv
+obj = testenv.instantiate()
test_register_view_descriptions.test(obj)
diff --git a/test/1.4/misc/T_register_view_fields.py b/test/1.4/misc/T_register_view_fields.py
index 1e8e4f7ca..36557bcc8 100644
--- a/test/1.4/misc/T_register_view_fields.py
+++ b/test/1.4/misc/T_register_view_fields.py
@@ -1,11 +1,13 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-from simics import *
+import simics
from stest import expect_equal
+import testenv
+obj = testenv.instantiate()
def test(obj):
- b = SIM_get_port_interface(obj, 'register_view', 'b')
+ b = simics.SIM_get_port_interface(obj, 'register_view', 'b')
expect_equal(b.register_info(0)[4], [['all', '', 0, 31]])
expect_equal(b.register_info(1)[4], [['ab', '12', 0, 2],
diff --git a/test/1.4/misc/T_register_view_inquiry.py b/test/1.4/misc/T_register_view_inquiry.py
index e9edd7bcf..f684037d1 100644
--- a/test/1.4/misc/T_register_view_inquiry.py
+++ b/test/1.4/misc/T_register_view_inquiry.py
@@ -2,5 +2,7 @@
# SPDX-License-Identifier: MPL-2.0
import test_register_view_inquiry
+import testenv
+obj = testenv.instantiate()
test_register_view_inquiry.test(obj)
diff --git a/test/1.4/misc/T_register_view_read_only.py b/test/1.4/misc/T_register_view_read_only.py
index 5fe76cdfe..1953a61ef 100644
--- a/test/1.4/misc/T_register_view_read_only.py
+++ b/test/1.4/misc/T_register_view_read_only.py
@@ -3,6 +3,8 @@
from simics import SIM_get_port_interface
from stest import expect_equal
+import testenv
+obj = testenv.instantiate()
b = SIM_get_port_interface(obj, 'register_view_read_only', 'b')
expect_equal(b.is_read_only(0), False)
diff --git a/test/1.4/registers/T_inquiry.py b/test/1.4/registers/T_inquiry.py
index de58a6bd5..addb764b0 100644
--- a/test/1.4/registers/T_inquiry.py
+++ b/test/1.4/registers/T_inquiry.py
@@ -1,10 +1,13 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
from dev_util import Register_LE
from stest import expect_equal, expect_true, expect_false
+import testenv
+obj = testenv.instantiate()
-SIM_run_command("log-level 4")
+simics.SIM_run_command("log-level 4")
aaaa = 0xaaaaaaaaaaaaaaaa
bbbb = 0xbbbbbbbbbbbbbbbb
diff --git a/test/1.4/registers/T_instrumentation_io_memory.py b/test/1.4/registers/T_instrumentation_io_memory.py
index a08b50b09..8a2a3d14b 100644
--- a/test/1.4/registers/T_instrumentation_io_memory.py
+++ b/test/1.4/registers/T_instrumentation_io_memory.py
@@ -1,7 +1,8 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-import instrumentation_test
from instrumentation_test import test
+import testenv
+obj = testenv.instantiate()
test(obj)
diff --git a/test/1.4/registers/T_instrumentation_transaction.py b/test/1.4/registers/T_instrumentation_transaction.py
index 7cdef8ed8..8a2a3d14b 100644
--- a/test/1.4/registers/T_instrumentation_transaction.py
+++ b/test/1.4/registers/T_instrumentation_transaction.py
@@ -2,5 +2,7 @@
# SPDX-License-Identifier: MPL-2.0
from instrumentation_test import test
+import testenv
+obj = testenv.instantiate()
test(obj)
diff --git a/test/1.4/registers/instrumentation_test.py b/test/1.4/registers/instrumentation_test.py
index 31371ad56..67e61eed9 100644
--- a/test/1.4/registers/instrumentation_test.py
+++ b/test/1.4/registers/instrumentation_test.py
@@ -24,6 +24,8 @@
import instrumentation_remove_connection_callbacks
import stest
+import testenv
+obj = testenv.instantiate()
def test(obj):
subscribe_b1 = obj.bank.b1.iface.bank_instrumentation_subscribe
diff --git a/test/1.4/saved/T_simple.py b/test/1.4/saved/T_simple.py
index 23012e9c0..2998b6866 100644
--- a/test/1.4/saved/T_simple.py
+++ b/test/1.4/saved/T_simple.py
@@ -1,7 +1,11 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+import conf
+obj = testenv.instantiate()
# check the initial values where applicable
stest.expect_equal(obj.DML_saved_saved_initialized_int, 5)
@@ -12,16 +16,16 @@
obj.verify_all_saved = 1
# take checkpoint
-SIM_write_configuration_to_file("init.ckpt", 0)
+simics.SIM_write_configuration_to_file("init.ckpt", 0)
# change values
obj.modify_all_saved = 3
# sanity
obj.verify_all_saved = 3
-SIM_delete_objects(SIM_get_all_objects())
+simics.SIM_delete_objects(simics.SIM_get_all_objects())
# load checkpoint, verify values reset
-SIM_read_configuration("init.ckpt")
+simics.SIM_read_configuration("init.ckpt")
# plain 'obj' reference is dead here
conf.obj.verify_all_saved = 1
diff --git a/test/1.4/serialize/T_identity_compat.py b/test/1.4/serialize/T_identity_compat.py
index 1e91d00b3..32bcb5aed 100644
--- a/test/1.4/serialize/T_identity_compat.py
+++ b/test/1.4/serialize/T_identity_compat.py
@@ -3,6 +3,8 @@
import stest
import simics
+import testenv
+obj = testenv.instantiate()
with stest.expect_exception_mgr(simics.SimExc_IllegalValue):
obj.s = ["test", []]
diff --git a/test/1.4/serialize/T_saved_declaration.py b/test/1.4/serialize/T_saved_declaration.py
index 96c8b3321..ce7fffe80 100644
--- a/test/1.4/serialize/T_saved_declaration.py
+++ b/test/1.4/serialize/T_saved_declaration.py
@@ -2,6 +2,8 @@
# SPDX-License-Identifier: MPL-2.0
import stest
+import testenv
+obj = testenv.instantiate()
# Test initial values
obj.test_initial = None
diff --git a/test/1.4/serialize/T_saved_failure.py b/test/1.4/serialize/T_saved_failure.py
index 836ab8b8e..c3cade854 100644
--- a/test/1.4/serialize/T_saved_failure.py
+++ b/test/1.4/serialize/T_saved_failure.py
@@ -3,6 +3,8 @@
import stest
import simics
+import testenv
+obj = testenv.instantiate()
with stest.expect_exception_mgr(simics.SimExc_IllegalValue):
obj.g_saved_objects = [[['g[%u]', [1]], ['dev', []]],
diff --git a/test/1.4/serialize/T_saved_statement.py b/test/1.4/serialize/T_saved_statement.py
index e68a4aea8..add17c24f 100644
--- a/test/1.4/serialize/T_saved_statement.py
+++ b/test/1.4/serialize/T_saved_statement.py
@@ -1,10 +1,13 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
# Needed so that we can check 'after'
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
# check initial value through attribute
diff --git a/test/1.4/statements/T_immediate_after_basic.py b/test/1.4/statements/T_immediate_after_basic.py
index 812557f07..72250a73d 100644
--- a/test/1.4/statements/T_immediate_after_basic.py
+++ b/test/1.4/statements/T_immediate_after_basic.py
@@ -1,25 +1,28 @@
# © 2024 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+import simics
+import testenv
+obj = testenv.instantiate()
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
-setup_ev = SIM_register_event("setup_ev", None, Sim_EC_Notsaved,
+setup_ev = simics.SIM_register_event("setup_ev", None, simics.Sim_EC_Notsaved,
lambda _o, _d: obj.setup, None, None, None, None)
-test_ev = SIM_register_event("test_ev", None, Sim_EC_Notsaved,
+test_ev = simics.SIM_register_event("test_ev", None, simics.Sim_EC_Notsaved,
lambda _o, _d: obj.test, None, None, None, None)
# global context
_ = obj.setup
-SIM_process_pending_work()
+simics.SIM_process_pending_work()
_ = obj.test
# execution context
-SIM_event_post_cycle(cpu, setup_ev, obj, 0, None)
-SIM_continue(1)
+simics.SIM_event_post_cycle(cpu, setup_ev, obj, 0, None)
+simics.SIM_continue(1)
_ = obj.test
# global context into execution context
-SIM_event_post_cycle(cpu, test_ev, obj, 0, None)
+simics.SIM_event_post_cycle(cpu, test_ev, obj, 0, None)
_ = obj.setup
-SIM_continue(1)
+simics.SIM_continue(1)
diff --git a/test/1.4/statements/T_immediate_after_cancel.py b/test/1.4/statements/T_immediate_after_cancel.py
index 812557f07..72250a73d 100644
--- a/test/1.4/statements/T_immediate_after_cancel.py
+++ b/test/1.4/statements/T_immediate_after_cancel.py
@@ -1,25 +1,28 @@
# © 2024 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+import simics
+import testenv
+obj = testenv.instantiate()
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
obj.queue = cpu
-setup_ev = SIM_register_event("setup_ev", None, Sim_EC_Notsaved,
+setup_ev = simics.SIM_register_event("setup_ev", None, simics.Sim_EC_Notsaved,
lambda _o, _d: obj.setup, None, None, None, None)
-test_ev = SIM_register_event("test_ev", None, Sim_EC_Notsaved,
+test_ev = simics.SIM_register_event("test_ev", None, simics.Sim_EC_Notsaved,
lambda _o, _d: obj.test, None, None, None, None)
# global context
_ = obj.setup
-SIM_process_pending_work()
+simics.SIM_process_pending_work()
_ = obj.test
# execution context
-SIM_event_post_cycle(cpu, setup_ev, obj, 0, None)
-SIM_continue(1)
+simics.SIM_event_post_cycle(cpu, setup_ev, obj, 0, None)
+simics.SIM_continue(1)
_ = obj.test
# global context into execution context
-SIM_event_post_cycle(cpu, test_ev, obj, 0, None)
+simics.SIM_event_post_cycle(cpu, test_ev, obj, 0, None)
_ = obj.setup
-SIM_continue(1)
+simics.SIM_continue(1)
diff --git a/test/1.4/statements/T_immediate_after_entrances.dml b/test/1.4/statements/T_immediate_after_entrances.dml
index e5bc3cf86..113c11efd 100644
--- a/test/1.4/statements/T_immediate_after_entrances.dml
+++ b/test/1.4/statements/T_immediate_after_entrances.dml
@@ -9,8 +9,6 @@ device test;
import "simics/devs/signal.dml";
import "simics/simulator/callbacks.dml";
-/// INSTANTIATE-MANUALLY
-
// attributes set/get -- hardcoded
attribute count is uint64_attr {
diff --git a/test/1.4/statements/T_immediate_after_entrances.py b/test/1.4/statements/T_immediate_after_entrances.py
index de244c6d9..651428f0f 100644
--- a/test/1.4/statements/T_immediate_after_entrances.py
+++ b/test/1.4/statements/T_immediate_after_entrances.py
@@ -2,96 +2,94 @@
# SPDX-License-Identifier: MPL-2.0
import stest
-import dev_util
import simics
-from simics import *
class signal_stub:
- cls = confclass('signal-stub')
+ cls = simics.confclass('signal-stub')
@cls.iface.signal.signal_raise
def signal_raise(self):
return obj.iface.signal.signal_raise()
-cpu = SIM_create_object("clock", "clock", [["freq_mhz", 1]])
+cpu = simics.SIM_create_object("clock", "clock", [["freq_mhz", 1]])
destroyed_map = {}
def destroyed(name):
destroyed_map[name] = destroyed_map.get(name, 0) + 1
-obj = SIM_create_object('test', 'obj', queue=cpu, post_inc_attr=None)
+obj = simics.SIM_create_object('test', 'obj', queue=cpu, post_inc_attr=None)
# objects_finalized will execute immediate afters posted in init(), post_init(),
# objects_finalized(), and attribute configuration
stest.expect_equal(obj.count, 4)
obj.count = 0
-SIM_process_pending_work()
+simics.SIM_process_pending_work()
stest.expect_equal(obj.count, 0)
obj.count = 0
obj.simple_attr = None
stest.expect_equal(obj.count, 0)
-SIM_process_pending_work()
+simics.SIM_process_pending_work()
stest.expect_equal(obj.count, 1)
obj.count = 0
obj.iface.signal.signal_raise()
stest.expect_equal(obj.count, 0)
-SIM_process_pending_work()
+simics.SIM_process_pending_work()
stest.expect_equal(obj.count, 1)
obj.count = 0
obj.recursive_entry_attr = None
stest.expect_equal(obj.count, 0)
-SIM_process_pending_work()
+simics.SIM_process_pending_work()
stest.expect_equal(obj.count, 1)
obj.count = 0
-SIM_notify(obj, SIM_notifier_type("static-export"))
+simics.SIM_notify(obj, simics.SIM_notifier_type("static-export"))
stest.expect_equal(obj.count, 0)
-SIM_process_pending_work()
+simics.SIM_process_pending_work()
stest.expect_equal(obj.count, 1)
obj.count = 0
-SIM_notify(obj, SIM_notifier_type("extern-export"))
+simics.SIM_notify(obj, simics.SIM_notifier_type("extern-export"))
stest.expect_equal(obj.count, 0)
-SIM_process_pending_work()
+simics.SIM_process_pending_work()
stest.expect_equal(obj.count, 1)
obj.count = 0
-SIM_continue(99999)
+simics.SIM_continue(99999)
stest.expect_equal(obj.count, 0)
-SIM_continue(1)
+simics.SIM_continue(1)
stest.expect_equal(obj.count, 1)
-SIM_continue(99999)
+simics.SIM_continue(99999)
stest.expect_equal(obj.count, 1)
-SIM_continue(1)
+simics.SIM_continue(1)
stest.expect_equal(obj.count, 2)
obj.post_never_called = None
# The immediate after posted by the post_never_called write will be warned
# about and cancelled
with stest.expect_log_mgr(obj, 'warning', regex='immediate after'):
- SIM_delete_object(obj)
+ simics.SIM_delete_object(obj)
stest.expect_equal(destroyed_map.get('dev', 0), 1)
stest.expect_equal(destroyed_map.get('event', 0), 1)
# Make sure that the delayed deallocation of immediate after state doesn't
# error or segfault
-SIM_process_pending_work()
+simics.SIM_process_pending_work()
# Check that the immediate afters posted during init, post_init, and attribute
-# configuration are cancelled without warning when SIM_add_configuration fails
+# configuration are cancelled without warning when simics.SIM_add_configuration fails
# late and has to rollback object creation
-conf.sim.warnings_as_errors = True
-with stest.expect_exception_mgr(SimExc_General):
- SIM_add_configuration(
- [pre_conf_object('obj1', 'test', queue=cpu, post_never_called=None),
- pre_conf_object('obj2', 'test', queue=cpu, error_on_post_init=True)],
+simics.conf.sim.warnings_as_errors = True
+with stest.expect_exception_mgr(simics.SimExc_General):
+ simics.SIM_add_configuration(
+ [simics.pre_conf_object('obj1', 'test', queue=cpu, post_never_called=None),
+ simics.pre_conf_object('obj2', 'test', queue=cpu, error_on_post_init=True)],
None)
stest.expect_equal(destroyed_map.get('dev', 0), 3)
stest.expect_equal(destroyed_map.get('event', 0), 5)
-SIM_process_pending_work()
+simics.SIM_process_pending_work()
diff --git a/test/1.4/statements/T_log.py b/test/1.4/statements/T_log.py
index c1983b13f..e090800fa 100644
--- a/test/1.4/statements/T_log.py
+++ b/test/1.4/statements/T_log.py
@@ -2,6 +2,8 @@
# SPDX-License-Identifier: MPL-2.0
import stest
+import testenv
+obj = testenv.instantiate()
try:
with stest.expect_log_mgr(obj, 'info'):
diff --git a/test/1.4/statements/T_subsequent_log.py b/test/1.4/statements/T_subsequent_log.py
index 55188d12e..c028608f8 100644
--- a/test/1.4/statements/T_subsequent_log.py
+++ b/test/1.4/statements/T_subsequent_log.py
@@ -1,8 +1,10 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-import simics
+import sim_commands
import stest
+import testenv
+obj = testenv.instantiate()
obj.log_level = 1
diff --git a/test/1.4/structure/T_connect_array.py b/test/1.4/structure/T_connect_array.py
index c83d3ec74..d55372d48 100644
--- a/test/1.4/structure/T_connect_array.py
+++ b/test/1.4/structure/T_connect_array.py
@@ -3,6 +3,8 @@
import stest
import dev_util
+import testenv
+obj = testenv.instantiate()
stest.expect_equal(obj.c, [[None, None, None], [None, None, None]])
diff --git a/test/1.4/structure/T_connect_doc.py b/test/1.4/structure/T_connect_doc.py
index b0473d46d..2c903f1a0 100644
--- a/test/1.4/structure/T_connect_doc.py
+++ b/test/1.4/structure/T_connect_doc.py
@@ -1,6 +1,8 @@
# © 2026 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
import stest
+import testenv
+obj = testenv.instantiate()
attr_doc = {name: doc for (name, _, doc, _) in obj.attributes}
diff --git a/test/1.4/structure/T_loggroup.py b/test/1.4/structure/T_loggroup.py
index bc55cd54b..e5ed9941d 100644
--- a/test/1.4/structure/T_loggroup.py
+++ b/test/1.4/structure/T_loggroup.py
@@ -2,6 +2,8 @@
# SPDX-License-Identifier: MPL-2.0
import stest
+import testenv
+obj = testenv.instantiate()
stest.expect_equal(set(obj.log_groups), {
'Default_Log_Group', 'Register_Read', 'Register_Write', 'abc_4711'})
diff --git a/test/1.4/structure/T_subobjs.py b/test/1.4/structure/T_subobjs.py
index 6e24c9e37..44cbf9f4e 100644
--- a/test/1.4/structure/T_subobjs.py
+++ b/test/1.4/structure/T_subobjs.py
@@ -2,6 +2,8 @@
# SPDX-License-Identifier: MPL-2.0
import stest
+import testenv
+obj = testenv.instantiate()
with stest.expect_log_mgr(obj.port.p[1], 'info'):
obj.port.p[1].pa = 3
diff --git a/test/1.4/structure/T_trait_largearray.dml b/test/1.4/structure/T_trait_largearray.dml
index aa9f0c94a..1d179d671 100644
--- a/test/1.4/structure/T_trait_largearray.dml
+++ b/test/1.4/structure/T_trait_largearray.dml
@@ -4,7 +4,6 @@
*/
dml 1.4;
-/// INSTANTIATE-MANUALLY
device test;
// vtable size: 8 bytes
diff --git a/test/1.4/structure/T_trait_largearray.py b/test/1.4/structure/T_trait_largearray.py
index 0873ca230..8ed8ed8f9 100644
--- a/test/1.4/structure/T_trait_largearray.py
+++ b/test/1.4/structure/T_trait_largearray.py
@@ -1,17 +1,18 @@
# © 2022 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
from simicsutils.host import is_windows
if is_windows():
# resource module only available on linux
- SIM_create_object('test', 'obj', [])
+ simics.SIM_create_object('test', 'obj', [])
exit(0)
import resource
import stest
before = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
-SIM_create_object('test', 'obj', [])
+simics.SIM_create_object('test', 'obj', [])
after = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
print(after - before)
stest.expect_true(after - before < 1024)
diff --git a/test/bugs/T_15852.py b/test/bugs/T_15852.py
index 41133c2fc..685cd0304 100644
--- a/test/bugs/T_15852.py
+++ b/test/bugs/T_15852.py
@@ -1,9 +1,12 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
import stest
+import testenv
+obj = testenv.instantiate()
# Test that all banks get the int_register interface, no matter if
# they are mappable or not
for bank in ('b1', 'b2', 'b3'):
- print(SIM_get_port_interface(obj, 'int_register', bank))
+ print(simics.SIM_get_port_interface(obj, 'int_register', bank))
stest.expect_true(obj.runtest)
diff --git a/test/bugs/T_17423.py b/test/bugs/T_17423.py
index 755a78c50..6d4c13a45 100644
--- a/test/bugs/T_17423.py
+++ b/test/bugs/T_17423.py
@@ -1,10 +1,13 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
+import testenv
+obj = testenv.instantiate()
obj.log_level = 4
print(obj)
-cpu = SIM_create_object("clock", "cpu", [["freq_mhz", 1]])
-mem = SIM_create_object("memory-space", "mem",
+cpu = simics.SIM_create_object("clock", "cpu", [["freq_mhz", 1]])
+mem = simics.SIM_create_object("memory-space", "mem",
[["map", [[0, [obj, 'bank0'], 0, 0, 0x10]]]])
reg_vals = (0xfa1afe1, 0xbabe, 0xabba)
@@ -15,7 +18,7 @@
try:
mem.iface.memory_space.write(cpu, 0, (0 , 1), 0)
raise Exception("expected nothing-is-mapped error")
-except SimExc_Memory:
+except simics.SimExc_Memory:
if (obj.bank0_REG1 != reg_vals[0] or obj.bank0_REG2 != reg_vals[1]
or obj.bank0_REG3 != reg_vals[2]):
raise Exception("expect registers 1-3 to be unchanged")
diff --git a/test/bugs/T_17729.py b/test/bugs/T_17729.py
index d5cc42383..6b12e64fa 100644
--- a/test/bugs/T_17729.py
+++ b/test/bugs/T_17729.py
@@ -3,6 +3,8 @@
import stest
import dev_util
+import testenv
+obj = testenv.instantiate()
regs = [[dev_util.Register((obj, 'b', i*2 + j*5), size = 1)
for j in range(2)]
diff --git a/test/bugs/T_4873.py b/test/bugs/T_4873.py
index 87db72992..5e709bd77 100644
--- a/test/bugs/T_4873.py
+++ b/test/bugs/T_4873.py
@@ -1,7 +1,10 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-mem = SIM_create_object("memory-space", "mem",
+import simics
+import testenv
+obj = testenv.instantiate()
+mem = simics.SIM_create_object("memory-space", "mem",
[["map", [[0, obj, 0, 0, 0x10000, None, 0, 8192]]]])
obj.log_level = 4
@@ -23,21 +26,21 @@
# Not all parts of the FIR register are implemented
if r1 + r2 + r3 != (1,2,3,4,5,6,7,8,9,10,11,12):
print("Wrong registers values")
- SIM_quit(1)
+ simics.SIM_quit(1)
# Now read an overlapping range
try:
r1r2 = mem.iface.memory_space.read(None, 2, 4, 0)
print("Didn't get expected exception when reading r1r2")
print("r1r2 = %s" % (r1r2,))
- SIM_quit(1)
-except SimExc_Memory:
+ simics.SIM_quit(1)
+except simics.SimExc_Memory:
print("Got expected exception when reading r1r2")
try:
r2r3 = mem.iface.memory_space.read(None, 6, 4, 0)
print("Didn't get expected exception when reading r2r3")
print("r1r2 = %s" % (r2r3,))
- SIM_quit(1)
-except SimExc_Memory:
+ simics.SIM_quit(1)
+except simics.SimExc_Memory:
print("Got expected exception when reading r2r3")
diff --git a/test/bugs/T_5878.py b/test/bugs/T_5878.py
index d8349bdc8..28b7167bb 100644
--- a/test/bugs/T_5878.py
+++ b/test/bugs/T_5878.py
@@ -1,12 +1,15 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
+import simics
+import testenv
+obj = testenv.instantiate()
obj.log_level = 4
-cpu = SIM_create_object("clock", "cpu", [["freq_mhz", 1]])
-mem = SIM_create_object("memory-space", "mem",
+cpu = simics.SIM_create_object("clock", "cpu", [["freq_mhz", 1]])
+mem = simics.SIM_create_object("memory-space", "mem",
[["map", [[0, obj, 0, 0, 0x10]]]])
try:
mem.iface.memory_space.write(cpu, 0, (1,2,3,4), 0)
raise Exception("expected nothing-is-mapped error")
-except SimExc_Memory:
+except simics.SimExc_Memory:
pass
diff --git a/test/common/instrumentation_access_value_at_miss.py b/test/common/instrumentation_access_value_at_miss.py
index a41177368..2532affa2 100644
--- a/test/common/instrumentation_access_value_at_miss.py
+++ b/test/common/instrumentation_access_value_at_miss.py
@@ -2,7 +2,6 @@
# SPDX-License-Identifier: MPL-2.0
import dev_util
-import simics
import stest
def expect_error(connection, access, handle, obj):
diff --git a/test/common/instrumentation_callback_args.py b/test/common/instrumentation_callback_args.py
index 5b14505ed..d25961d2d 100644
--- a/test/common/instrumentation_callback_args.py
+++ b/test/common/instrumentation_callback_args.py
@@ -2,7 +2,6 @@
# SPDX-License-Identifier: MPL-2.0
import dev_util
-import simics
import stest
import instrumentation_common as common
diff --git a/test/common/instrumentation_callback_inquiry.py b/test/common/instrumentation_callback_inquiry.py
index b6bd46e44..ce7b5ef35 100644
--- a/test/common/instrumentation_callback_inquiry.py
+++ b/test/common/instrumentation_callback_inquiry.py
@@ -2,7 +2,6 @@
# SPDX-License-Identifier: MPL-2.0
import dev_util
-import simics
import stest
def test_inquiry(register_callback, remove_callback,
diff --git a/test/common/instrumentation_connection_order.py b/test/common/instrumentation_connection_order.py
index ce8975520..a590670f9 100644
--- a/test/common/instrumentation_connection_order.py
+++ b/test/common/instrumentation_connection_order.py
@@ -1,7 +1,6 @@
# © 2021 Intel Corporation
# SPDX-License-Identifier: MPL-2.0
-import dev_util
import stest
import instrumentation_common as common
diff --git a/test/common/instrumentation_endianness.py b/test/common/instrumentation_endianness.py
index 1e93e67b9..cd9b9d64f 100644
--- a/test/common/instrumentation_endianness.py
+++ b/test/common/instrumentation_endianness.py
@@ -2,7 +2,6 @@
# SPDX-License-Identifier: MPL-2.0
import dev_util
-import simics
import stest
def expect_value(value):
diff --git a/test/common/instrumentation_endianness_overlapping.py b/test/common/instrumentation_endianness_overlapping.py
index 2125e9259..a8adcd98b 100644
--- a/test/common/instrumentation_endianness_overlapping.py
+++ b/test/common/instrumentation_endianness_overlapping.py
@@ -2,7 +2,6 @@
# SPDX-License-Identifier: MPL-2.0
import dev_util
-import simics
import stest
def expect_value(value):
diff --git a/test/common/instrumentation_remove_connection_callbacks.py b/test/common/instrumentation_remove_connection_callbacks.py
index fd37fe160..b5957d77a 100644
--- a/test/common/instrumentation_remove_connection_callbacks.py
+++ b/test/common/instrumentation_remove_connection_callbacks.py
@@ -2,7 +2,6 @@
# SPDX-License-Identifier: MPL-2.0
import dev_util
-import simics
import stest
import instrumentation_common as common
diff --git a/test/common/testenv.py b/test/common/testenv.py
new file mode 100644
index 000000000..9acbb7b18
--- /dev/null
+++ b/test/common/testenv.py
@@ -0,0 +1,15 @@
+# © 2021 Intel Corporation
+# SPDX-License-Identifier: MPL-2.0
+
+# Test environment parameters injected by the test runner.
+# Test scripts should import this module and call the functions below.
+_scratchdir: str = ''
+
+
+def scratchdir() -> str:
+ return _scratchdir
+
+
+def instantiate():
+ import simics
+ return simics.SIM_create_object('test', 'obj', [])
diff --git a/test/tests.py b/test/tests.py
index 922ac4ab1..4dc0372af 100644
--- a/test/tests.py
+++ b/test/tests.py
@@ -484,7 +484,6 @@ class TestFlags:
cc_flags: list[str] = dataclasses.field(default_factory=list)
dmlc_flags: list[str] = dataclasses.field(default_factory=list)
api_version: str = default_api_version
- instantiate_manually: bool = False
compile_only: bool = False
no_cc: bool = False
@@ -540,8 +539,6 @@ def test_flags(self, filename=None, append_to=None):
flags.cc_flags.append(data)
elif key == 'GREP':
flags.exp_stdout.append(data)
- elif key == 'INSTANTIATE-MANUALLY':
- flags.instantiate_manually = True
elif key == 'COMPILE-ONLY':
flags.compile_only = True
elif key == 'NO-CC':
@@ -666,7 +663,7 @@ def run_linker(self):
self.pr("LD: %r" % args)
return status
- def run_simics(self, pyfile=None, auto_instantiate=True):
+ def run_simics(self, pyfile=None):
name = self.shortname
self.simics_stdout = join(self.scratchdir, name+'.simics_stdout')
self.simics_stderr = join(self.scratchdir, name+'.simics_stderr')
@@ -675,16 +672,13 @@ def run_simics(self, pyfile=None, auto_instantiate=True):
sc = open(self.scriptname, "w")
#sc.write("print conf.sim.module_searchpath\n")
#sc.write("run_command('list-modules')\n")
- sc.write("testname = %r\n" % self.shortname)
sc.write("scratchdir = %r\n" % self.scratchdir)
- sc.write("basedir = %r\n" % join(os.path.dirname(self.filename)))
+ sc.write("import sys\n")
+ sc.write("sys.path.insert(0, %r)\n" % join(os.getcwd(), 'common'))
+ sc.write("import testenv\n")
+ sc.write("testenv._scratchdir = scratchdir\n")
sc.write("SIM_add_module_dir(scratchdir)\n")
sc.write("SIM_module_list_refresh()\n")
- if auto_instantiate:
- sc.write(f"SIM_load_module('dml-test-{self.shortname}')\n")
- sc.write("obj = SIM_create_object('test', 'obj', [])\n")
- else:
- assert pyfile
if pyfile:
sc.write("print('running', %r)\n" % pyfile)
@@ -694,6 +688,7 @@ def run_simics(self, pyfile=None, auto_instantiate=True):
sc.write("sys.path.append(%r)\n" % os.path.dirname(pyfile))
sc.write("SIM_source_python(%r)\n" % pyfile)
elif self.fullname.startswith(('1.2/', 'bugs/')):
+ sc.write('obj = testenv.instantiate()\n')
sc.write("if not obj.runtest:\n")
sc.write(" print('test attribute returned false')\n")
sc.write(" SIM_quit(1)\n")
@@ -780,8 +775,7 @@ def test(self):
return
# Run simics
- status = self.runlog("Simics", lambda: self.run_simics(
- pyfile, not self.flags.instantiate_manually))
+ status = self.runlog("Simics", lambda: self.run_simics(pyfile))
if status != 0:
self.print_logs('simics', self.simics_stdout, self.simics_stderr)
raise TestFail("simics status=%d" % status)
@@ -804,9 +798,9 @@ def test(self):
class XmlTestCase(CTestCase):
__slots__ = ()
- def run_simics(self, pyfile=None, auto_instantiate=True):
+ def run_simics(self, pyfile=None):
os.rename('%s.xml' % self.cfilename, join(self.scratchdir, 'test.xml'))
- return CTestCase.run_simics(self, pyfile, auto_instantiate)
+ return CTestCase.run_simics(self, pyfile)
class DMLCProfileTestCase(CTestCase):
__slots__ = ()
diff --git a/validate_md_links.py b/validate_md_links.py
index b37488c83..41fadbf68 100644
--- a/validate_md_links.py
+++ b/validate_md_links.py
@@ -6,7 +6,6 @@
import re
import json
import functools
-import traceback
def lookup(f, dirs):
for d in dirs: