Commit 68945763 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/rth/tags/pull-dt-20190819' into staging



Implement parameter fields.
Push warning pragmas into the generated code.

# gpg: Signature made Mon 19 Aug 2019 16:14:41 BST
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* remotes/rth/tags/pull-dt-20190819:
  target/riscv: Remove redundant declaration pragmas
  decodetree: Suppress redundant declaration warnings
  decodetree: Allow !function with no input bits

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 50d69ee0 59a3a1c0
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.

+60 −11
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ arguments = {}
formats = {}
patterns = []
allpatterns = []
anyextern = False

translate_prefix = 'trans'
translate_scope = 'static '
@@ -245,7 +246,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 +267,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 +455,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:
@@ -455,12 +483,14 @@ def parse_arguments(lineno, name, toks):
    """Parse one argument set from TOKS at LINENO"""
    global arguments
    global re_ident
    global anyextern

    flds = []
    extern = False
    for t in toks:
        if re_fullmatch('!extern', t):
            extern = True
            anyextern = True
            continue
        if not re_fullmatch(re_ident, t):
            error(lineno, 'invalid argument set token "{0}"'.format(t))
@@ -1161,6 +1191,7 @@ def main():
    global insnmask
    global decode_function
    global variablewidth
    global anyextern

    decode_scope = 'static '

@@ -1221,6 +1252,19 @@ def main():
    # A single translate function can be invoked for different patterns.
    # Make sure that the argument sets are the same, and declare the
    # function only once.
    #
    # If we're sharing formats, we're likely also sharing trans_* functions,
    # but we can't tell which ones.  Prevent issues from the compiler by
    # suppressing redundant declaration warnings.
    if anyextern:
        output("#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE\n",
               "# pragma GCC diagnostic push\n",
               "# pragma GCC diagnostic ignored \"-Wredundant-decls\"\n",
               "# ifdef __clang__\n"
               "#  pragma GCC diagnostic ignored \"-Wtypedef-redefinition\"\n",
               "# endif\n",
               "#endif\n\n")

    out_pats = {}
    for i in allpatterns:
        if i.name in out_pats:
@@ -1232,6 +1276,11 @@ def main():
            out_pats[i.name] = i
    output('\n')

    if anyextern:
        output("#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE\n",
               "# pragma GCC diagnostic pop\n",
               "#endif\n\n")

    for n in sorted(formats.keys()):
        f = formats[n]
        f.output_extract()
+1 −18
Original line number Diff line number Diff line
@@ -708,26 +708,9 @@ static bool gen_shift(DisasContext *ctx, arg_r *a,
#include "insn_trans/trans_rvd.inc.c"
#include "insn_trans/trans_privileged.inc.c"

/*
 * Auto-generated decoder.
 * Note that the 16-bit decoder reuses some of the trans_* functions
 * initially declared by the 32-bit decoder, which results in duplicate
 * declaration warnings.  Suppress them.
 */
#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wredundant-decls"
# ifdef __clang__
#  pragma GCC diagnostic ignored "-Wtypedef-redefinition"
# endif
#endif

/* Include the auto-generated decoder for 16 bit insn */
#include "decode_insn16.inc.c"

#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
# pragma GCC diagnostic pop
#endif

static void decode_opc(DisasContext *ctx)
{
    /* check for compressed insn */
+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