All ISO C operators are available in DML, except for certain limitations on the comma-operator, the sizeof operator, and type casts; see Section 4.10. Operators have the same precedences and semantics as in C
DML adds the following expressions:
The constant undefined is an abstract compile-time only value, mostly used as a default for parameters that are intended to be overridden. See also the defined expr test, below.
To make a reference to a component of the DML object structure from within a method, the reference (an object-context identifier) must be prefixed by a $ character; see also Section 4.2. Following the identifier, components may be selected using . and -> as in C. (However, most components in the DML object structure are proper substructures selected with the . operator.) For example,
$this.size $dev.bank1 $bank1.r0.hard_reset
Allocates a chunk of memory large enough for a value of the specified type. The result is a pointer to the allocated memory. (The pointer is never null; if allocation should fail, the Simics application will be terminated.)
When the memory is no longer needed, it should be deallocated using a delete statement.
Type casts in DML must be written with the above explicit cast operator, for syntactical reasons.
Semantically, cast(expr, type) is equivalent to the C expression (type) expr.
The sizeof operator in DML 1.0 can only be used on expressions, not on types, for syntactical reasons. To take the size of a datatype, the sizeoftype operator must be used, as in
int size = sizeoftype io_memory_interface_t;
Semantically, sizeoftype type is equivalent to the C expression sizeof (type).
This compile-time test evaluates to false if expr has the value undefined, and to true otherwise.
[e1, ..., eN]
A list is a compile-time only value, and is an ordered sequence of zero or more compile-time constant values. Lists are in particular used in combination with foreach and select statements, and are often provided by built-in methods or parameters, such as the fields parameter of register objects.
expr[e1:e2] expr[e1:e2, bitorder] expr[e1] expr[e1, bitorder]
If expr is of integer type, then the above bit-slicing syntax can be used in DML to simplify extracting or updating particular bit fields of the integer. Bit slice syntax can be used both as an expression producing a value, or as the target of an assignment (an L-value), e.g., on the left-hand side of an = operator.
Both e1 and e2 must be integers. The syntax expr[e1] is a short-hand for expr[e1:e1] (but only evaluating e1 once).
The bitorder part is optional, and selects the bit numbering scheme (the "endianism") used to interpret the values of e1 and e2. If present, it must be an identifier such as be32, as in a bitorder device-level declaration, and in that case it overrides any global bit order declaration in the program.
The first bit index e1 always indicates the most significant bit of the field, regardless of the bit numbering scheme; cf. Section 4.8.3. If the default little-endian bit numbering is used, the least significant bit of the integer has index zero, and the most significant bit of the integer has index n - 1, where n is the width of the integer type.
If big-endian bit numbering is used, e.g., due to a "bitorder be32;" declaration in the file, or using a specific local bit numbering as in expr[e1:e2, be32], then the bit corresponding to the little-endian bit number n - 1 has index zero, and the least significant bit has the index n - 1, where n is the specified base width - in this case 32. Note that this is not affected by the width of the integer type, in order to avoid subtle errors; e.g., a 16-bit big-endian value could be represented by a 32-bit integer type, but bit slice operations should use be16 in order to interpret the bit indexes correctly.
Translates the value of expr (which must be a compile-time constant) into a string constant. This is similar to the use of # in the C preprocessor, but is performed on the level of compile time values, not tokens. The result is often used with the + string operator.
expr1 + expr2
If both expr1 and expr2 are compile-time string constants, the expression expr1 + expr2 concatenates the two strings at compile time. This is often used in combination with the # operator.