isaspec: Add support for "absolute" branches
afuc has branches which use an absolute offset in instructions from the microcode base. Add another type to support them. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23949>
This commit is contained in:
@@ -244,6 +244,38 @@ In the case of ``<override>`` elements, the override applies if the expression
|
||||
evaluates to non-zero. In the case of ``<derived>`` fields, the expression
|
||||
evaluates to the value of the derived field.
|
||||
|
||||
Branching
|
||||
---------
|
||||
|
||||
isaspec supports a few special field types for printing branch destinations. If
|
||||
``isaspec_decode_options::branch_labels`` is true, a pre-pass over the program
|
||||
to be disassembled determines which instructions are branch destinations and
|
||||
then they are printed when disassembling, in addition to printing the name of
|
||||
the destination when printing the field itself.
|
||||
|
||||
There are two different types, which affect how the destination is computed. If
|
||||
the field type is ``branch``, then the field is interpreted as a signed offset
|
||||
from the current instruction. If the type is ``absbranch``, then it is
|
||||
interpreted as an offset from the first instruction to be disassembled. In
|
||||
either case, the offset is multiplied by the instruction size.
|
||||
|
||||
For example, here is what a signed-offset unconditional jump instruction might
|
||||
look like:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<bitset name="jump" extends="#instruction">
|
||||
<display>
|
||||
jump #{OFFSET}
|
||||
</display>
|
||||
<pattern low="26" high="31">110010</pattern> <!-- opcode goes here -->
|
||||
<field name="OFFSET" low="0" high="25" type="branch"/>
|
||||
</bitset>
|
||||
|
||||
This would produce a disassembly like ``jump #l42`` if the destination is 42
|
||||
instructions after the start of the disassembly. The destination would be
|
||||
preceded by a line with just ``l42:``.
|
||||
|
||||
Encoding
|
||||
--------
|
||||
|
||||
|
@@ -492,7 +492,7 @@ class ISA(object):
|
||||
|
||||
# Validate that all bitset fields have valid types, and in
|
||||
# the case of bitset type, the sizes match:
|
||||
builtin_types = ['branch', 'int', 'uint', 'hex', 'offset', 'uoffset', 'float', 'bool', 'enum']
|
||||
builtin_types = ['branch', 'absbranch', 'int', 'uint', 'hex', 'offset', 'uoffset', 'float', 'bool', 'enum']
|
||||
for bitset_name, bitset in self.bitsets.items():
|
||||
if bitset.extends is not None:
|
||||
assert bitset.extends in self.bitsets, "{} extends invalid type: {}".format(
|
||||
|
@@ -79,7 +79,8 @@ struct isa_field {
|
||||
unsigned high;
|
||||
enum {
|
||||
/* Basic types: */
|
||||
TYPE_BRANCH, /* branch target, like INT but optional labeling*/
|
||||
TYPE_BRANCH, /* relative branch target, like INT but optional labeling*/
|
||||
TYPE_ABSBRANCH, /* absolute branch target */
|
||||
TYPE_INT,
|
||||
TYPE_UINT,
|
||||
TYPE_HEX,
|
||||
|
@@ -610,8 +610,14 @@ display_field(struct decode_scope *scope, const char *field_name)
|
||||
switch (field->type) {
|
||||
/* Basic types: */
|
||||
case TYPE_BRANCH:
|
||||
case TYPE_ABSBRANCH:
|
||||
if (scope->state->options->branch_labels) {
|
||||
int offset = util_sign_extend(val, width) + scope->state->n;
|
||||
int offset;
|
||||
if (field->type == TYPE_BRANCH) {
|
||||
offset = util_sign_extend(val, width) + scope->state->n;
|
||||
} else {
|
||||
offset = val;
|
||||
}
|
||||
if (offset < scope->state->num_instr) {
|
||||
print(scope->state, "l%d", offset);
|
||||
BITSET_SET(scope->state->branch_targets, offset);
|
||||
|
Reference in New Issue
Block a user