qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Thomas Huth <thuth@redhat.com>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-devel@nongnu.org, qemu-s390x@nongnu.org,
	Sebastian Mitterle <smitterl@redhat.com>,
	Ilya Leoshkevich <iii@linux.ibm.com>,
	Laurent Vivier <laurent@vivier.eu>,
	Thomas Huth <thuth@redhat.com>
Subject: [risu PATCH 1/2] risugen: allow instructions with length > 32 bit
Date: Fri, 27 Oct 2023 12:04:40 +0200	[thread overview]
Message-ID: <20231027100441.375223-2-thuth@redhat.com> (raw)
In-Reply-To: <20231027100441.375223-1-thuth@redhat.com>

RISU currently only supports instructions with a length of
16 bit or 32 bit, however classical CISC systems like s390x
also have instructions that are longer than 32 bit. Thus let's
change the generator to support longer instructions, too.

This adds support for 48-bit instructions on s390x, while
the other architectures are just minimally changed to preserve
the current state.

Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 risugen                | 48 +++++++++++++++++++++++++++++-------------
 risugen_arm.pm         |  6 +++---
 risugen_common.pm      |  2 +-
 risugen_loongarch64.pm |  4 ++--
 risugen_m68k.pm        |  6 +++---
 risugen_ppc64.pm       |  4 ++--
 risugen_s390x.pm       | 17 +++++++++++----
 7 files changed, 57 insertions(+), 30 deletions(-)

diff --git a/risugen b/risugen
index fa94a39..833b459 100755
--- a/risugen
+++ b/risugen
@@ -105,6 +105,16 @@ sub read_tokenised_line(*)
     return @tokens;
 }
 
+sub check_bitmask($$)
+{
+    my ($fixedbits, $fixedbitmask) = @_;
+
+    if ((($fixedbits & $fixedbitmask) != $fixedbits)
+        || (($fixedbits & ~$fixedbitmask) != 0)) {
+        die "internal error: fixed bits not lined up with mask";
+    }
+}
+
 sub parse_config_file($)
 {
     # Read in the config file defining the instructions we can generate
@@ -160,10 +170,11 @@ sub parse_config_file($)
             exit(1);
         }
 
-        my $fixedbits = 0;
-        my $fixedbitmask = 0;
+        my @fixedbits = (0, 0, 0, 0);
+        my @fixedbitmask = (0, 0, 0, 0);
         my $bitpos = 32;
-        my $insnwidth = 32;
+        my $wordpos = 0;
+        my $insnwidth = 0;
         my $seenblock = 0;
 
         while (@bits) {
@@ -217,36 +228,43 @@ sub parse_config_file($)
 
             my $bitmask = oct("0b". '1' x $bitlen);
             $bitpos -= $bitlen;
+            $insnwidth += $bitlen;
             if ($bitpos < 0) {
                 print STDERR "$file:$.: ($insn $enc) too many bits specified\n";
                 exit(1);
             }
 
             if (defined $bitval) {
-                $fixedbits |= ($bitval << $bitpos);
-                $fixedbitmask |= ($bitmask << $bitpos);
+                $fixedbits[$wordpos] |= ($bitval << $bitpos);
+                $fixedbitmask[$wordpos] |= ($bitmask << $bitpos);
             } else {
-                push @fields, [ $var, $bitpos, $bitmask ];
+                push @fields, [ $var, $bitpos, $bitmask, $wordpos ];
+            }
+
+            if ($bitpos == 0) {
+                check_bitmask($fixedbits[$wordpos], $fixedbitmask[$wordpos]);
+
+                $wordpos += 1;
+                if (@bits) {
+                    $bitpos = 32;
+                }
             }
         }
         if ($bitpos == 16) {
             # assume this is a half-width thumb instruction
             # Note that we don't fiddle with the bitmasks or positions,
             # which means the generated insn will be in the high halfword!
-            $insnwidth = 16;
-        } elsif ($bitpos != 0) {
-            print STDERR "$file:$.: ($insn $enc) not enough bits specified\n";
+            check_bitmask($fixedbits[$wordpos], $fixedbitmask[$wordpos]);
+        } elsif ($bitpos != 0 && $bitpos != 32) {
+            print STDERR "$file:$.: ($insn $enc) not enough bits specified ($bitpos)\n";
             exit(1);
         }
-        if ((($fixedbits & $fixedbitmask) != $fixedbits)
-            || (($fixedbits & ~$fixedbitmask) != 0)) {
-            die "internal error: fixed bits not lined up with mask";
-        }
         #  Stick the fixedbit info on the front of the array now we know it
         $insnrec->{name} = $insnname;
         $insnrec->{width} = $insnwidth;
-        $insnrec->{fixedbits} = $fixedbits;
-        $insnrec->{fixedbitmask} = $fixedbitmask;
+        $insnrec->{fixedbits} = [ @fixedbits ];
+        $insnrec->{fixedbitmask} = [ @fixedbitmask ];
+        $insnrec->{words} = $wordpos;
         $insnrec->{fields} = [ @fields ];
         if (@insn_groups) {
             $insnrec->{groups} = [ @insn_groups ];
diff --git a/risugen_arm.pm b/risugen_arm.pm
index 8d423b1..9dd6139 100644
--- a/risugen_arm.pm
+++ b/risugen_arm.pm
@@ -964,15 +964,15 @@ sub gen_one_insn($$)
         my $insn = int(rand(0xffffffff));
         my $insnname = $rec->{name};
         my $insnwidth = $rec->{width};
-        my $fixedbits = $rec->{fixedbits};
-        my $fixedbitmask = $rec->{fixedbitmask};
+        my $fixedbits = (@{ $rec->{fixedbits} })[0];
+        my $fixedbitmask = (@{  $rec->{fixedbitmask} })[0];
         my $constraint = $rec->{blocks}{"constraints"};
         my $memblock = $rec->{blocks}{"memory"};
 
         $insn &= ~$fixedbitmask;
         $insn |= $fixedbits;
         for my $tuple (@{ $rec->{fields} }) {
-            my ($var, $pos, $mask) = @$tuple;
+            my ($var, $pos, $mask, $wordpos) = @$tuple;
             my $val = ($insn >> $pos) & $mask;
             # XXX (claudio) ARM-specific - maybe move to arm.risu?
             # Check constraints here:
diff --git a/risugen_common.pm b/risugen_common.pm
index 71ee996..c816895 100644
--- a/risugen_common.pm
+++ b/risugen_common.pm
@@ -116,7 +116,7 @@ sub eval_with_fields($$$$$) {
     my $calling_package = caller;
     my $evalstr = "{ package $calling_package; ";
     for my $tuple (@{ $rec->{fields} }) {
-        my ($var, $pos, $mask) = @$tuple;
+        my ($var, $pos, $mask, $wordpos) = @$tuple;
         my $val = ($insn >> $pos) & $mask;
         $evalstr .= "my (\$$var) = $val; ";
     }
diff --git a/risugen_loongarch64.pm b/risugen_loongarch64.pm
index 5394fdc..8c74b6e 100644
--- a/risugen_loongarch64.pm
+++ b/risugen_loongarch64.pm
@@ -390,8 +390,8 @@ sub gen_one_insn($$)
         my $insn = int(rand(0xffffffff));
         my $insnname = $rec->{name};
         my $insnwidth = $rec->{width};
-        my $fixedbits = $rec->{fixedbits};
-        my $fixedbitmask = $rec->{fixedbitmask};
+        my $fixedbits = (@{ $rec->{fixedbits} })[0];
+        my $fixedbitmask = (@{  $rec->{fixedbitmask} })[0];
         my $constraint = $rec->{blocks}{"constraints"};
         my $memblock = $rec->{blocks}{"memory"};
         my $safefloat = $rec->{blocks}{"safefloat"};
diff --git a/risugen_m68k.pm b/risugen_m68k.pm
index 7d62b13..49f3100 100644
--- a/risugen_m68k.pm
+++ b/risugen_m68k.pm
@@ -111,8 +111,8 @@ sub gen_one_insn($$)
         my $insn = int(rand(0xffffffff));
         my $insnname = $rec->{name};
         my $insnwidth = $rec->{width};
-        my $fixedbits = $rec->{fixedbits};
-        my $fixedbitmask = $rec->{fixedbitmask};
+        my $fixedbits = (@{ $rec->{fixedbits} })[0];
+        my $fixedbitmask = (@{  $rec->{fixedbitmask} })[0];
         my $constraint = $rec->{blocks}{"constraints"};
         my $memblock = $rec->{blocks}{"memory"};
 
@@ -120,7 +120,7 @@ sub gen_one_insn($$)
         $insn |= $fixedbits;
 
         for my $tuple (@{ $rec->{fields} }) {
-            my ($var, $pos, $mask) = @$tuple;
+            my ($var, $pos, $mask, $wordpos) = @$tuple;
             my $val = ($insn >> $pos) & $mask;
             # Check constraints here:
             # not allowed to use or modify sp (A7) or fp (A6)
diff --git a/risugen_ppc64.pm b/risugen_ppc64.pm
index b241172..d1d3fc9 100644
--- a/risugen_ppc64.pm
+++ b/risugen_ppc64.pm
@@ -300,8 +300,8 @@ sub gen_one_insn($$)
         my $insn = int(rand(0xffffffff));
         my $insnname = $rec->{name};
         my $insnwidth = $rec->{width};
-        my $fixedbits = $rec->{fixedbits};
-        my $fixedbitmask = $rec->{fixedbitmask};
+        my $fixedbits = (@{ $rec->{fixedbits} })[0];
+        my $fixedbitmask = (@{  $rec->{fixedbitmask} })[0];
         my $constraint = $rec->{blocks}{"constraints"};
         my $memblock = $rec->{blocks}{"memory"};
 
diff --git a/risugen_s390x.pm b/risugen_s390x.pm
index 260e2dd..04ea6fb 100644
--- a/risugen_s390x.pm
+++ b/risugen_s390x.pm
@@ -84,15 +84,21 @@ sub gen_one_insn($$)
     INSN: while(1) {
         my ($forcecond, $rec) = @_;
         my $insn = int(rand(0xffffffff));
+        my $insn48 = int(rand(0xffff0000));
         my $insnname = $rec->{name};
         my $insnwidth = $rec->{width};
-        my $fixedbits = $rec->{fixedbits};
-        my $fixedbitmask = $rec->{fixedbitmask};
+        my @fixedbits = (@{ $rec->{fixedbits} });
+        my @fixedbitmask = (@{  $rec->{fixedbitmask} });
         my $constraint = $rec->{blocks}{"constraints"};
         my $memblock = $rec->{blocks}{"memory"};
 
-        $insn &= ~$fixedbitmask;
-        $insn |= $fixedbits;
+        $insn &= ~$fixedbitmask[0];
+        $insn |= $fixedbits[0];
+
+        if ($insnwidth == 48) {
+            $insn48 &= ~$fixedbitmask[1];
+            $insn48 |= $fixedbits[1];
+        }
 
         if (defined $constraint) {
             # user-specified constraint: evaluate in an environment
@@ -121,6 +127,9 @@ sub gen_one_insn($$)
             insn16(($insn >> 16) & 0xffff);
         } else {
             insn32($insn);
+            if ($insnwidth == 48) {
+                insn16(($insn48 >> 16) & 0xffff);
+            }
         }
 
         return;
-- 
2.41.0



  reply	other threads:[~2023-10-27 10:06 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-27 10:04 [risu PATCH 0/2] Add support for instructions with length > 32 bit Thomas Huth
2023-10-27 10:04 ` Thomas Huth [this message]
2023-10-31 15:34   ` [risu PATCH 1/2] risugen: allow " Peter Maydell
2023-10-27 10:04 ` [risu PATCH 2/2] s390x.risu: Add some instructions with a length of 48 bits Thomas Huth

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=20231027100441.375223-2-thuth@redhat.com \
    --to=thuth@redhat.com \
    --cc=iii@linux.ibm.com \
    --cc=laurent@vivier.eu \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-s390x@nongnu.org \
    --cc=smitterl@redhat.com \
    /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).