Commit 94597b61 authored by Richard Henderson's avatar Richard Henderson
Browse files

decodetree: Allow !function with no input bits



Call this form a "parameter", returning a value extracted
from the DisasContext.

Reviewed-by: default avatarPhilippe Mathieu-Daude <philmd@redhat.com>
Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
parent 3fbd3405
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ Fields

Syntax::

  field_def     := '%' identifier ( unnamed_field )+ ( !function=identifier )?
  field_def     := '%' identifier ( unnamed_field )* ( !function=identifier )?
  unnamed_field := number ':' ( 's' ) number

For *unnamed_field*, the first number is the least-significant bit position
@@ -34,6 +34,12 @@ present, they are concatenated. In this way one can define disjoint fields.
If ``!function`` is specified, the concatenated result is passed through the
named function, taking and returning an integral value.

One may use ``!function`` with zero ``unnamed_fields``.  This case is called
a *parameter*, and the named function is only passed the ``DisasContext``
and returns an integral value extracted from there.

A field with no ``unnamed_fields`` and no ``!function`` is in error.

FIXME: the fields of the structure into which this result will be stored
is restricted to ``int``.  Which means that we cannot expand 64-bit items.

+38 −11
Original line number Diff line number Diff line
@@ -245,7 +245,7 @@ class ConstField:


class FunctionField:
    """Class representing a field passed through an expander"""
    """Class representing a field passed through a function"""
    def __init__(self, func, base):
        self.mask = base.mask
        self.sign = base.sign
@@ -266,6 +266,27 @@ class FunctionField:
# end FunctionField


class ParameterField:
    """Class representing a pseudo-field read from a function"""
    def __init__(self, func):
        self.mask = 0
        self.sign = 0
        self.func = func

    def __str__(self):
        return self.func

    def str_extract(self):
        return self.func + '(ctx)'

    def __eq__(self, other):
        return self.func == other.func

    def __ne__(self, other):
        return not self.__eq__(other)
# end ParameterField


class Arguments:
    """Class representing the extracted fields of a format"""
    def __init__(self, nm, flds, extern):
@@ -433,6 +454,12 @@ def parse_field(lineno, name, toks):

    if width > insnwidth:
        error(lineno, 'field too large')
    if len(subs) == 0:
        if func:
            f = ParameterField(func)
        else:
            error(lineno, 'field with no value')
    else:
        if len(subs) == 1:
            f = subs[0]
        else:
+5 −0
Original line number Diff line number Diff line
# This work is licensed under the terms of the GNU LGPL, version 2 or later.
# See the COPYING.LIB file in the top-level directory.

# Diagnose no bits in field
%field
+6 −0
Original line number Diff line number Diff line
# This work is licensed under the terms of the GNU LGPL, version 2 or later.
# See the COPYING.LIB file in the top-level directory.

# "Field" as parameter pulled from DisasContext.
%foo  !function=foo
foo   00000000000000000000000000000000 %foo