decodetree: Allow !function with no input bits
Call this form a "parameter", returning a value extracted from the DisasContext. Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
3fbd3405d2
commit
94597b6146
@ -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.
|
||||
|
||||
|
@ -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,17 +454,23 @@ def parse_field(lineno, name, toks):
|
||||
|
||||
if width > insnwidth:
|
||||
error(lineno, 'field too large')
|
||||
if len(subs) == 1:
|
||||
f = subs[0]
|
||||
if len(subs) == 0:
|
||||
if func:
|
||||
f = ParameterField(func)
|
||||
else:
|
||||
error(lineno, 'field with no value')
|
||||
else:
|
||||
mask = 0
|
||||
for s in subs:
|
||||
if mask & s.mask:
|
||||
error(lineno, 'field components overlap')
|
||||
mask |= s.mask
|
||||
f = MultiField(subs, mask)
|
||||
if func:
|
||||
f = FunctionField(func, f)
|
||||
if len(subs) == 1:
|
||||
f = subs[0]
|
||||
else:
|
||||
mask = 0
|
||||
for s in subs:
|
||||
if mask & s.mask:
|
||||
error(lineno, 'field components overlap')
|
||||
mask |= s.mask
|
||||
f = MultiField(subs, mask)
|
||||
if func:
|
||||
f = FunctionField(func, f)
|
||||
|
||||
if name in fields:
|
||||
error(lineno, 'duplicate field', name)
|
||||
|
5
tests/decode/err_field6.decode
Normal file
5
tests/decode/err_field6.decode
Normal file
@ -0,0 +1,5 @@
|
||||
# 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
tests/decode/succ_function.decode
Normal file
6
tests/decode/succ_function.decode
Normal file
@ -0,0 +1,6 @@
|
||||
# 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
|
Loading…
Reference in New Issue
Block a user