qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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 RFC PATCH v2 01/14] risugen_common: add insnv, randint_constr, rand_fill
Date: Mon,  1 Jul 2019 00:35:23 -0400	[thread overview]
Message-ID: <20190701043536.26019-2-jan.bobek@gmail.com> (raw)
In-Reply-To: <20190701043536.26019-1-jan.bobek@gmail.com>

Add three common utility functions:

- insnv allows emitting variable-length instructions in little-endian
  or big-endian byte order; it subsumes functionality of former
  insn16() and insn32() functions.

- randint_constr allows generating random integers according to
  several constraints passed as arguments.

- rand_fill uses randint_constr to fill a given hash with
  (optionally constrained) random values.

Signed-off-by: Jan Bobek <jan.bobek@gmail.com>
---
 risugen_common.pm | 107 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 101 insertions(+), 6 deletions(-)

diff --git a/risugen_common.pm b/risugen_common.pm
index 71ee996..c5d861e 100644
--- a/risugen_common.pm
+++ b/risugen_common.pm
@@ -23,7 +23,8 @@ BEGIN {
     require Exporter;
 
     our @ISA = qw(Exporter);
-    our @EXPORT = qw(open_bin close_bin set_endian insn32 insn16 $bytecount
+    our @EXPORT = qw(open_bin close_bin set_endian insn32 insn16
+                   $bytecount insnv randint_constr rand_fill
                    progress_start progress_update progress_end
                    eval_with_fields is_pow_of_2 sextract ctz
                    dump_insn_details);
@@ -37,7 +38,7 @@ my $bigendian = 0;
 # (default is little endian, 0).
 sub set_endian
 {
-    $bigendian = @_;
+    ($bigendian) = @_;
 }
 
 sub open_bin
@@ -52,18 +53,112 @@ sub close_bin
     close(BIN) or die "can't close output file: $!";
 }
 
+sub insnv(%)
+{
+    my (%args) = @_;
+
+    # Default to big-endian order, so that the instruction bytes are
+    # emitted in the same order as they are written in the
+    # configuration file.
+    $args{bigendian} = 1 unless defined $args{bigendian};
+
+    my $bitcur = 0;
+    my $bitend = 8 * $args{len};
+    while ($bitcur < $bitend) {
+        my $format;
+        my $bitlen;
+
+        if ($bitcur + 64 <= $bitend) {
+            $format = "Q";
+            $bitlen = 64;
+        } elsif ($bitcur + 32 <= $bitend) {
+            $format = "L";
+            $bitlen = 32;
+        } elsif ($bitcur + 16 <= $bitend) {
+            $format = "S";
+            $bitlen = 16;
+        } else {
+            $format = "C";
+            $bitlen = 8;
+        }
+
+        $format .= ($args{bigendian} ? ">" : "<") if $bitlen > 8;
+
+        my $bitmask = (1 << $bitlen) - 1;
+        my $value = $args{value} >> ($args{bigendian}
+                                     ? $bitend - $bitcur - $bitlen
+                                     : $bitcur);
+
+        print BIN pack($format, $value & $bitmask);
+        $bytecount += $bitlen / 8;
+
+        $bitcur += $bitlen;
+    }
+}
+
 sub insn32($)
 {
     my ($insn) = @_;
-    print BIN pack($bigendian ? "N" : "V", $insn);
-    $bytecount += 4;
+    insnv(value => $insn, len => 4, bigendian => $bigendian);
 }
 
 sub insn16($)
 {
     my ($insn) = @_;
-    print BIN pack($bigendian ? "n" : "v", $insn);
-    $bytecount += 2;
+    insnv(value => $insn, len => 2, bigendian => $bigendian);
+}
+
+sub randint_constr(%)
+{
+    my (%args) = @_;
+    my $bitlen = $args{bitlen};
+    my $halfrange = 1 << ($bitlen - 1);
+
+    while (1) {
+        my $value = int(rand(2 * $halfrange));
+        $value -= $halfrange if defined $args{signed} && $args{signed};
+        $value &= ~$args{fixedbitmask} if defined $args{fixedbitmask};
+        $value |= $args{fixedbits} if defined $args{fixedbits};
+
+        if (defined $args{constraint}) {
+            # The idea is: if the most significant bit of
+            # $args{constraint} is zero, $args{constraint} is the
+            # value we want to return; if the most significant bit is
+            # one, ~$args{constraint} (its bit inversion) is the value
+            # we want to *avoid*, so we try again.
+
+            if (!($args{constraint} >> 63)) {
+                $value = $args{constraint};
+            } elsif ($value == ~$args{constraint}) {
+                next;
+            }
+        }
+
+        return $value;
+    }
+}
+
+sub rand_fill($$)
+{
+    my ($target, $constraints) = @_;
+
+    for (keys %{$target}) {
+        my %args = (bitlen => $target->{$_}{bitlen});
+
+        $args{fixedbits} = $target->{$_}{fixedbits}
+            if defined $target->{$_}{fixedbits};
+        $args{fixedbitmask} = $target->{$_}{fixedbitmask}
+            if defined $target->{$_}{fixedbitmask};
+        $args{signed} = $target->{$_}{signed}
+            if defined $target->{$_}{signed};
+
+        $args{constraint} = $constraints->{$_}
+            if defined $constraints->{$_};
+
+        $target->{$_} = randint_constr(%args);
+    }
+
+    return $target;
 }
 
 # Progress bar implementation
-- 
2.20.1



  reply	other threads:[~2019-07-01  4:41 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-01  4:35 [Qemu-devel] [RISU RFC PATCH v2 00/14] Support for generating x86 MMX/SSE/AVX test images Jan Bobek
2019-07-01  4:35 ` Jan Bobek [this message]
2019-07-03 15:22   ` [Qemu-devel] [RISU RFC PATCH v2 01/14] risugen_common: add insnv, randint_constr, rand_fill Richard Henderson
2019-07-10 17:48     ` Jan Bobek
2019-07-01  4:35 ` [Qemu-devel] [RISU RFC PATCH v2 02/14] risugen_x86_asm: add module Jan Bobek
2019-07-03 15:37   ` Richard Henderson
2019-07-10 18:02     ` Jan Bobek
2019-07-01  4:35 ` [Qemu-devel] [RISU RFC PATCH v2 03/14] risugen_x86_emit: " Jan Bobek
2019-07-03 15:47   ` Richard Henderson
2019-07-10 18:08     ` Jan Bobek
2019-07-01  4:35 ` [Qemu-devel] [RISU RFC PATCH v2 04/14] risugen_x86: " Jan Bobek
2019-07-03 16:11   ` Richard Henderson
2019-07-10 18:21     ` Jan Bobek
2019-07-11  9:26       ` Richard Henderson
2019-07-11 13:10         ` Jan Bobek
2019-07-01  4:35 ` [Qemu-devel] [RISU RFC PATCH v2 05/14] risugen: allow all byte-aligned instructions Jan Bobek
2019-07-01  4:35 ` [Qemu-devel] [RISU RFC PATCH v2 06/14] x86.risu: add MMX instructions Jan Bobek
2019-07-03 21:35   ` Richard Henderson
2019-07-10 18:29     ` Jan Bobek
2019-07-11  9:32       ` Richard Henderson
2019-07-11 13:29         ` Jan Bobek
2019-07-11 13:57           ` Richard Henderson
2019-07-11 21:29             ` Jan Bobek
2019-07-03 21:49   ` Richard Henderson
2019-07-10 18:32     ` Jan Bobek
2019-07-11  9:34       ` Richard Henderson
2019-07-11  9:44         ` Alex Bennée
2019-07-03 22:01   ` Peter Maydell
2019-07-10 18:35     ` Jan Bobek
2019-07-11  6:45       ` Alex Bennée
2019-07-11 13:33         ` Jan Bobek
2019-07-01  4:35 ` [Qemu-devel] [RISU RFC PATCH v2 07/14] x86.risu: add SSE instructions Jan Bobek
2019-07-01  4:35 ` [Qemu-devel] [RISU RFC PATCH v2 08/14] x86.risu: add SSE2 instructions Jan Bobek
2019-07-01  4:35 ` [Qemu-devel] [RISU RFC PATCH v2 09/14] x86.risu: add SSE3 instructions Jan Bobek
2019-07-01  4:35 ` [Qemu-devel] [RISU RFC PATCH v2 10/14] x86.risu: add SSSE3 instructions Jan Bobek
2019-07-01  4:35 ` [Qemu-devel] [RISU RFC PATCH v2 11/14] x86.risu: add SSE4.1 and SSE4.2 instructions Jan Bobek
2019-07-01  4:35 ` [Qemu-devel] [RISU RFC PATCH v2 13/14] x86.risu: add AVX instructions Jan Bobek
2019-07-01  4:35 ` [Qemu-devel] [RISU RFC PATCH v2 14/14] x86.risu: add AVX2 instructions Jan Bobek

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=20190701043536.26019-2-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).