From: Jan Bobek <jan.bobek@gmail.com>
To: qemu-devel@nongnu.org
Cc: "Jan Bobek" <jan.bobek@gmail.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Richard Henderson" <richard.henderson@linaro.org>
Subject: [Qemu-devel] [RISU PATCH v3 02/18] risugen_common: split eval_with_fields into extract_fields and eval_block
Date: Thu, 11 Jul 2019 18:32:44 -0400 [thread overview]
Message-ID: <20190711223300.6061-3-jan.bobek@gmail.com> (raw)
In-Reply-To: <20190711223300.6061-1-jan.bobek@gmail.com>
extract_fields can extract named variable fields from an opcode; it
returns a hash which can be then passed as environment parameter to
eval_block. More importantly, this allows the caller to augment the
block environment with more variables, if they wish to do so.
Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
risugen_arm.pm | 6 +++--
risugen_common.pm | 64 ++++++++++++++++++++++++++++-------------------
risugen_m68k.pm | 3 ++-
risugen_ppc64.pm | 6 +++--
4 files changed, 48 insertions(+), 31 deletions(-)
diff --git a/risugen_arm.pm b/risugen_arm.pm
index 8d423b1..23a468c 100644
--- a/risugen_arm.pm
+++ b/risugen_arm.pm
@@ -992,7 +992,8 @@ sub gen_one_insn($$)
if (defined $constraint) {
# user-specified constraint: evaluate in an environment
# with variables set corresponding to the variable fields.
- my $v = eval_with_fields($insnname, $insn, $rec, "constraints", $constraint);
+ my %env = extract_fields($insn, $rec);
+ my $v = eval_block($insnname, "constraints", $constraint, \%env);
if (!$v) {
$constraintfailures++;
if ($constraintfailures > 10000) {
@@ -1020,7 +1021,8 @@ sub gen_one_insn($$)
} else {
align(4);
}
- $basereg = eval_with_fields($insnname, $insn, $rec, "memory", $memblock);
+ my %env = extract_fields($insn, $rec);
+ $basereg = eval_block($insnname, "memory", $memblock, \%env);
if ($is_aarch64) {
data_barrier();
diff --git a/risugen_common.pm b/risugen_common.pm
index d63250a..3f927ef 100644
--- a/risugen_common.pm
+++ b/risugen_common.pm
@@ -25,8 +25,8 @@ BEGIN {
our @ISA = qw(Exporter);
our @EXPORT = qw(open_bin close_bin set_endian insn32 insn16
$bytecount insnv randint progress_start
- progress_update progress_end
- eval_with_fields is_pow_of_2 sextract ctz
+ progress_update progress_end extract_fields
+ eval_block is_pow_of_2 sextract ctz
dump_insn_details);
}
@@ -138,36 +138,48 @@ sub progress_end()
$| = 0;
}
-sub eval_with_fields($$$$$) {
- # Evaluate the given block in an environment with Perl variables
- # set corresponding to the variable fields for the insn.
- # Return the result of the eval; we die with a useful error
- # message in case of syntax error.
- #
- # At the moment we just evaluate the string in the environment
- # of the calling package.
- # What we *ought* to do here is to give the config snippets
- # their own package, and explicitly import into it only the
- # functions that we want to be accessible to the config.
- # That would provide better separation and an explicitly set up
- # environment that doesn't allow config file code to accidentally
- # change state it shouldn't have access to, and avoid the need to
- # use 'caller' to get the package name of our calling function.
- my ($insnname, $insn, $rec, $blockname, $block) = @_;
+sub extract_fields($$)
+{
+ my ($insn, $rec) = @_;
+
+ my %fields = ();
+ for my $tuple (@{ $rec->{fields} }) {
+ my ($var, $pos, $mask) = @$tuple;
+ $fields{$var} = ($insn >> $pos) & $mask;
+ }
+ return %fields;
+}
+
+# Evaluate the given block in an environment with Perl variables set
+# corresponding to env. Return the result of the eval; we die with a
+# useful error message in case of syntax error.
+#
+# At the moment we just evaluate the string in the environment of the
+# calling package. What we *ought* to do here is to give the config
+# snippets their own package, and explicitly import into it only the
+# functions that we want to be accessible to the config. That would
+# provide better separation and an explicitly set up environment that
+# doesn't allow config file code to accidentally change state it
+# shouldn't have access to, and avoid the need to use 'caller' to get
+# the package name of our calling function.
+sub eval_block($$$$)
+{
+ my ($insnname, $blockname, $block, $env) = @_;
+
my $calling_package = caller;
my $evalstr = "{ package $calling_package; ";
- for my $tuple (@{ $rec->{fields} }) {
- my ($var, $pos, $mask) = @$tuple;
- my $val = ($insn >> $pos) & $mask;
- $evalstr .= "my (\$$var) = $val; ";
+ for (keys %{$env}) {
+ $evalstr .= "my " unless $_ eq '_';
+ $evalstr .= "(\$$_) = \$env->{$_}; ";
}
$evalstr .= $block;
$evalstr .= "}";
+
my $v = eval $evalstr;
- if ($@) {
- print "Syntax error detected evaluating $insnname $blockname string:\n$block\n$@";
- exit(1);
- }
+ die "Syntax error detected evaluating $insnname $blockname string:\n"
+ . "$block\n"
+ . "$@"
+ if ($@);
return $v;
}
diff --git a/risugen_m68k.pm b/risugen_m68k.pm
index 7d62b13..8c812b5 100644
--- a/risugen_m68k.pm
+++ b/risugen_m68k.pm
@@ -129,7 +129,8 @@ sub gen_one_insn($$)
if (defined $constraint) {
# user-specified constraint: evaluate in an environment
# with variables set corresponding to the variable fields.
- my $v = eval_with_fields($insnname, $insn, $rec, "constraints", $constraint);
+ my %env = extract_fields($insn, $rec);
+ my $v = eval_block($insnname, "constraints", $constraint, \%env);
if (!$v) {
$constraintfailures++;
if ($constraintfailures > 10000) {
diff --git a/risugen_ppc64.pm b/risugen_ppc64.pm
index b241172..40f717e 100644
--- a/risugen_ppc64.pm
+++ b/risugen_ppc64.pm
@@ -311,7 +311,8 @@ sub gen_one_insn($$)
if (defined $constraint) {
# user-specified constraint: evaluate in an environment
# with variables set corresponding to the variable fields.
- my $v = eval_with_fields($insnname, $insn, $rec, "constraints", $constraint);
+ my %env = extract_fields($insn, $rec);
+ my $v = eval_block($insnname, "constraints", $constraint, \%env);
if (!$v) {
$constraintfailures++;
if ($constraintfailures > 10000) {
@@ -335,7 +336,8 @@ sub gen_one_insn($$)
# Default alignment requirement for ARM is 4 bytes,
# we use 16 for Aarch64, although often unnecessary and overkill.
align(16);
- $basereg = eval_with_fields($insnname, $insn, $rec, "memory", $memblock);
+ my %env = extract_fields($insn, $rec);
+ $basereg = eval_block($insnname, "memory", $memblock, \%env);
}
insn32($insn);
--
2.20.1
next prev parent reply other threads:[~2019-07-11 22:36 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-11 22:32 [Qemu-devel] [RISU PATCH v3 00/18] Support for generating x86 SIMD test images Jan Bobek
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 01/18] risugen_common: add helper functions insnv, randint Jan Bobek
2019-07-12 5:48 ` Richard Henderson
2019-07-14 21:55 ` Jan Bobek
2019-07-12 12:41 ` Alex Bennée
2019-07-11 22:32 ` Jan Bobek [this message]
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 03/18] risugen_x86_asm: add module Jan Bobek
2019-07-12 14:11 ` Richard Henderson
2019-07-14 22:04 ` Jan Bobek
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 04/18] risugen_x86_constraints: " Jan Bobek
2019-07-12 14:24 ` Richard Henderson
2019-07-14 22:39 ` Jan Bobek
2019-07-21 1:54 ` Richard Henderson
2019-07-22 13:41 ` Jan Bobek
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 05/18] risugen_x86_memory: " Jan Bobek
2019-07-21 1:58 ` Richard Henderson
2019-07-22 13:53 ` Jan Bobek
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 06/18] risugen_x86: " Jan Bobek
2019-07-21 2:02 ` Richard Henderson
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 07/18] risugen: allow all byte-aligned instructions Jan Bobek
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 08/18] risugen: add command-line flag --x86_64 Jan Bobek
2019-07-17 17:00 ` Richard Henderson
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 09/18] risugen: add --xfeatures option for x86 Jan Bobek
2019-07-17 17:01 ` Richard Henderson
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 10/18] x86.risu: add MMX instructions Jan Bobek
2019-07-20 4:30 ` Richard Henderson
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 11/18] x86.risu: add SSE instructions Jan Bobek
2019-07-20 17:50 ` Richard Henderson
2019-07-22 13:57 ` Jan Bobek
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 12/18] x86.risu: add SSE2 instructions Jan Bobek
2019-07-20 21:19 ` Richard Henderson
2019-07-22 14:12 ` Jan Bobek
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 13/18] x86.risu: add SSE3 instructions Jan Bobek
2019-07-20 21:27 ` Richard Henderson
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 14/18] x86.risu: add SSSE3 instructions Jan Bobek
2019-07-20 21:52 ` Richard Henderson
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 15/18] x86.risu: add SSE4.1 and SSE4.2 instructions Jan Bobek
2019-07-20 22:28 ` Richard Henderson
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 16/18] x86.risu: add AES and PCLMULQDQ instructions Jan Bobek
2019-07-20 22:35 ` Richard Henderson
2019-07-11 22:32 ` [Qemu-devel] [RISU PATCH v3 17/18] x86.risu: add AVX instructions Jan Bobek
2019-07-21 0:04 ` Richard Henderson
2019-07-22 14:23 ` Jan Bobek
2019-07-11 22:33 ` [Qemu-devel] [RISU PATCH v3 18/18] x86.risu: add AVX2 instructions Jan Bobek
2019-07-21 0:46 ` Richard Henderson
2019-07-22 14:41 ` Jan Bobek
2019-07-12 13:34 ` [Qemu-devel] [RISU PATCH v3 00/18] Support for generating x86 SIMD test images Alex Bennée
2019-07-14 23:08 ` Jan Bobek
2019-07-15 10:14 ` Alex Bennée
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190711223300.6061-3-jan.bobek@gmail.com \
--to=jan.bobek@gmail.com \
--cc=alex.bennee@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).