mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-09-02 06:51:53 -06:00
Implement parameter fields.
Push warning pragmas into the generated code. -----BEGIN PGP SIGNATURE----- iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAl1avOEdHHJpY2hhcmQu aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV//cgf+KYMCuvJ8ekICYpJG HDBELEszkV27A9kag0nseeyHUaJvJqCAUl2sfN4qnAxBACLV6tftIfM01pI1UVqh x0vCfqZSxd2BrBbfgciPhA/7vAC4tUsWlLseahxRlYoj3vFFsU4wjef2mqSQtNVw /kfJLo38jaiBkziDSrf4mqYE5WTApuEP2ljnS8WNeaCHivveC8qZ6SbI7fiuT1/s lpCCWcbuYK2QnRc1MoUTHYQPtQEL51CtsQtA5sDGIrXNVp645Z3i5LYi2p0Zv9bG pXWZaixymzO8nx0j1cNURejuyvMHDhBEWcKuDd1dGo5juW4HsbI2+160GmRT//mR SUW3fg== =/CkI -----END PGP SIGNATURE----- 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: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
6894576347
5 changed files with 79 additions and 30 deletions
|
@ -23,7 +23,7 @@ Fields
|
||||||
|
|
||||||
Syntax::
|
Syntax::
|
||||||
|
|
||||||
field_def := '%' identifier ( unnamed_field )+ ( !function=identifier )?
|
field_def := '%' identifier ( unnamed_field )* ( !function=identifier )?
|
||||||
unnamed_field := number ':' ( 's' ) number
|
unnamed_field := number ':' ( 's' ) number
|
||||||
|
|
||||||
For *unnamed_field*, the first number is the least-significant bit position
|
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
|
If ``!function`` is specified, the concatenated result is passed through the
|
||||||
named function, taking and returning an integral value.
|
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
|
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.
|
is restricted to ``int``. Which means that we cannot expand 64-bit items.
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ arguments = {}
|
||||||
formats = {}
|
formats = {}
|
||||||
patterns = []
|
patterns = []
|
||||||
allpatterns = []
|
allpatterns = []
|
||||||
|
anyextern = False
|
||||||
|
|
||||||
translate_prefix = 'trans'
|
translate_prefix = 'trans'
|
||||||
translate_scope = 'static '
|
translate_scope = 'static '
|
||||||
|
@ -245,7 +246,7 @@ class ConstField:
|
||||||
|
|
||||||
|
|
||||||
class FunctionField:
|
class FunctionField:
|
||||||
"""Class representing a field passed through an expander"""
|
"""Class representing a field passed through a function"""
|
||||||
def __init__(self, func, base):
|
def __init__(self, func, base):
|
||||||
self.mask = base.mask
|
self.mask = base.mask
|
||||||
self.sign = base.sign
|
self.sign = base.sign
|
||||||
|
@ -266,6 +267,27 @@ class FunctionField:
|
||||||
# end 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 Arguments:
|
||||||
"""Class representing the extracted fields of a format"""
|
"""Class representing the extracted fields of a format"""
|
||||||
def __init__(self, nm, flds, extern):
|
def __init__(self, nm, flds, extern):
|
||||||
|
@ -433,17 +455,23 @@ def parse_field(lineno, name, toks):
|
||||||
|
|
||||||
if width > insnwidth:
|
if width > insnwidth:
|
||||||
error(lineno, 'field too large')
|
error(lineno, 'field too large')
|
||||||
if len(subs) == 1:
|
if len(subs) == 0:
|
||||||
f = subs[0]
|
if func:
|
||||||
|
f = ParameterField(func)
|
||||||
|
else:
|
||||||
|
error(lineno, 'field with no value')
|
||||||
else:
|
else:
|
||||||
mask = 0
|
if len(subs) == 1:
|
||||||
for s in subs:
|
f = subs[0]
|
||||||
if mask & s.mask:
|
else:
|
||||||
error(lineno, 'field components overlap')
|
mask = 0
|
||||||
mask |= s.mask
|
for s in subs:
|
||||||
f = MultiField(subs, mask)
|
if mask & s.mask:
|
||||||
if func:
|
error(lineno, 'field components overlap')
|
||||||
f = FunctionField(func, f)
|
mask |= s.mask
|
||||||
|
f = MultiField(subs, mask)
|
||||||
|
if func:
|
||||||
|
f = FunctionField(func, f)
|
||||||
|
|
||||||
if name in fields:
|
if name in fields:
|
||||||
error(lineno, 'duplicate field', name)
|
error(lineno, 'duplicate field', name)
|
||||||
|
@ -455,12 +483,14 @@ def parse_arguments(lineno, name, toks):
|
||||||
"""Parse one argument set from TOKS at LINENO"""
|
"""Parse one argument set from TOKS at LINENO"""
|
||||||
global arguments
|
global arguments
|
||||||
global re_ident
|
global re_ident
|
||||||
|
global anyextern
|
||||||
|
|
||||||
flds = []
|
flds = []
|
||||||
extern = False
|
extern = False
|
||||||
for t in toks:
|
for t in toks:
|
||||||
if re_fullmatch('!extern', t):
|
if re_fullmatch('!extern', t):
|
||||||
extern = True
|
extern = True
|
||||||
|
anyextern = True
|
||||||
continue
|
continue
|
||||||
if not re_fullmatch(re_ident, t):
|
if not re_fullmatch(re_ident, t):
|
||||||
error(lineno, 'invalid argument set token "{0}"'.format(t))
|
error(lineno, 'invalid argument set token "{0}"'.format(t))
|
||||||
|
@ -1161,6 +1191,7 @@ def main():
|
||||||
global insnmask
|
global insnmask
|
||||||
global decode_function
|
global decode_function
|
||||||
global variablewidth
|
global variablewidth
|
||||||
|
global anyextern
|
||||||
|
|
||||||
decode_scope = 'static '
|
decode_scope = 'static '
|
||||||
|
|
||||||
|
@ -1221,6 +1252,19 @@ def main():
|
||||||
# A single translate function can be invoked for different patterns.
|
# A single translate function can be invoked for different patterns.
|
||||||
# Make sure that the argument sets are the same, and declare the
|
# Make sure that the argument sets are the same, and declare the
|
||||||
# function only once.
|
# 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 = {}
|
out_pats = {}
|
||||||
for i in allpatterns:
|
for i in allpatterns:
|
||||||
if i.name in out_pats:
|
if i.name in out_pats:
|
||||||
|
@ -1232,6 +1276,11 @@ def main():
|
||||||
out_pats[i.name] = i
|
out_pats[i.name] = i
|
||||||
output('\n')
|
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()):
|
for n in sorted(formats.keys()):
|
||||||
f = formats[n]
|
f = formats[n]
|
||||||
f.output_extract()
|
f.output_extract()
|
||||||
|
|
|
@ -708,26 +708,9 @@ static bool gen_shift(DisasContext *ctx, arg_r *a,
|
||||||
#include "insn_trans/trans_rvd.inc.c"
|
#include "insn_trans/trans_rvd.inc.c"
|
||||||
#include "insn_trans/trans_privileged.inc.c"
|
#include "insn_trans/trans_privileged.inc.c"
|
||||||
|
|
||||||
/*
|
/* Include the auto-generated decoder for 16 bit insn */
|
||||||
* 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 "decode_insn16.inc.c"
|
#include "decode_insn16.inc.c"
|
||||||
|
|
||||||
#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE
|
|
||||||
# pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void decode_opc(DisasContext *ctx)
|
static void decode_opc(DisasContext *ctx)
|
||||||
{
|
{
|
||||||
/* check for compressed insn */
|
/* check for compressed insn */
|
||||||
|
|
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…
Add table
Add a link
Reference in a new issue