All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/5] risu: add m68k target support
@ 2017-02-07 18:33 Laurent Vivier
  2017-02-07 18:33 ` [Qemu-devel] [PATCH 1/5] m68k: implement risugen module Laurent Vivier
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Laurent Vivier @ 2017-02-07 18:33 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Laurent Vivier

This series add the files needed to test the m68k target.

For the moment, it doesn't support FPU instructions.

Laurent Vivier (5):
  m68k: implement risugen module
  m68k: implement server and client side
  m68k: add risufile with m68k instructions.
  m68k: add instruction needing an extended word
  m68k: manage memory block

 configure           |   6 +-
 m68k.risu           | 369 +++++++++++++++++++++++++++++++++++++++++++++++++
 risu.h              |   1 +
 risu_m68k.c         | 158 +++++++++++++++++++++
 risu_reginfo_m68k.c | 151 ++++++++++++++++++++
 risu_reginfo_m68k.h |  32 +++++
 risugen             |   2 +-
 risugen_m68k.pm     | 390 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 test_m68k.s         |  28 ++++
 9 files changed, 1134 insertions(+), 3 deletions(-)
 create mode 100644 m68k.risu
 create mode 100644 risu_m68k.c
 create mode 100644 risu_reginfo_m68k.c
 create mode 100644 risu_reginfo_m68k.h
 create mode 100644 risugen_m68k.pm
 create mode 100644 test_m68k.s

-- 
2.9.3

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PATCH 1/5] m68k: implement risugen module
  2017-02-07 18:33 [Qemu-devel] [PATCH 0/5] risu: add m68k target support Laurent Vivier
@ 2017-02-07 18:33 ` Laurent Vivier
  2017-02-07 18:33 ` [Qemu-devel] [PATCH 2/5] m68k: implement server and client side Laurent Vivier
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Laurent Vivier @ 2017-02-07 18:33 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Laurent Vivier

---
 risugen_m68k.pm | 295 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 295 insertions(+)
 create mode 100644 risugen_m68k.pm

diff --git a/risugen_m68k.pm b/risugen_m68k.pm
new file mode 100644
index 0000000..a9a4341
--- /dev/null
+++ b/risugen_m68k.pm
@@ -0,0 +1,295 @@
+#!/usr/bin/perl -w
+###############################################################################
+# Copyright (c) 2016 Laurent Vivier
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+
+# risugen -- generate a test binary file for use with risu
+# See 'risugen --help' for usage information.
+package risugen_m68k;
+
+use strict;
+use warnings;
+
+require Exporter;
+
+our @ISA    = qw(Exporter);
+our @EXPORT = qw(write_test_code);
+
+my $periodic_reg_random = 1;
+
+my $bytecount;
+#
+# Maximum alignment restriction permitted for a memory op.
+my $MAXALIGN = 64;
+
+sub open_bin
+{
+    my ($fname) = @_;
+    open(BIN, ">", $fname) or die "can't open %fname: $!";
+    $bytecount = 0;
+}
+
+sub close_bin
+{
+    close(BIN) or die "can't close output file: $!";
+}
+
+sub insn32($)
+{
+    my ($insn) = @_;
+    print BIN pack("N", $insn);
+    $bytecount += 4;
+}
+
+sub insn16($)
+{
+    my ($insn) = @_;
+    print BIN pack("n", $insn);
+    $bytecount += 2;
+}
+
+sub write_risuop($)
+{
+    my ($op) = @_;
+    insn32(0x4afc7000 | $op);
+}
+
+sub write_mov_ccr($)
+{
+    my ($imm) = @_;
+    insn16(0x44fc);
+    insn16($imm);
+}
+
+sub write_movb_di($$)
+{
+    my ($r, $imm) = @_;
+
+    # move.b #imm,%dr
+    insn16(0x103c | ($r << 9));
+    insn16($imm)
+}
+
+sub write_mov_di($$)
+{
+    my ($r, $imm) = @_;
+
+    # move.l #imm,%dr
+    insn16(0x203c | ($r << 9));
+    insn32($imm)
+}
+
+sub write_mov_ai($$)
+{
+    my ($r, $imm) = @_;
+
+    # movea.l #imm,%ar
+    insn16(0x207c | ($r << 9));
+    insn32($imm)
+}
+
+sub write_mov_ri($$)
+{
+    my ($r, $imm) = @_;
+
+    if ($r < 8) {
+        write_mov_di($r, $imm);
+    } else {
+        write_mov_ai($r - 8, $imm);
+    }
+}
+
+sub write_random_regdata()
+{
+    # general purpose registers (except A6 (FP) and A7 (SP))
+    for (my $i = 0; $i < 14; $i++) {
+        write_mov_ri($i, rand(0xffffffff));
+    }
+    # initialize condition register
+    write_mov_ccr(rand(0x10000));
+}
+
+my $OP_COMPARE = 0;        # compare registers
+my $OP_TESTEND = 1;        # end of test, stop
+my $OP_SETMEMBLOCK = 2;    # r0 is address of memory block (8192 bytes)
+my $OP_GETMEMBLOCK = 3;    # add the address of memory block to r0
+my $OP_COMPAREMEM = 4;     # compare memory block
+
+sub write_random_register_data()
+{
+    write_random_regdata();
+    write_risuop($OP_COMPARE);
+}
+
+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.
+    my ($insnname, $insn, $rec, $blockname, $block) = @_;
+    my $evalstr = "{ ";
+    for my $tuple (@{ $rec->{fields} }) {
+        my ($var, $pos, $mask) = @$tuple;
+        my $val = ($insn >> $pos) & $mask;
+        $evalstr .= "my (\$$var) = $val; ";
+    }
+    $evalstr .= $block;
+    $evalstr .= "}";
+    my $v = eval $evalstr;
+    if ($@) {
+        print "Syntax error detected evaluating $insnname $blockname string:\n$block\n$@";
+        exit(1);
+    }
+    return $v;
+}
+
+sub gen_one_insn($$)
+{
+    # Given an instruction-details array, generate an instruction
+    my $constraintfailures = 0;
+
+    INSN: while(1) {
+        my ($forcecond, $rec) = @_;
+        my $insn = int(rand(0xffffffff));
+        my $insnname = $rec->{name};
+        my $insnwidth = $rec->{width};
+        my $fixedbits = $rec->{fixedbits};
+        my $fixedbitmask = $rec->{fixedbitmask};
+        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 $val = ($insn >> $pos) & $mask;
+            # Check constraints here:
+            # not allowed to use or modify sp (A7) or fp (A6)
+            next INSN if ($var =~ /^A/ && (($val == 6) || ($val == 7)));
+        }
+        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);
+            if (!$v) {
+                $constraintfailures++;
+                if ($constraintfailures > 10000) {
+                    print "10000 consecutive constraint failures for $insnname constraints string:\n$constraint\n";
+                    exit (1);
+                }
+                next INSN;
+            }
+        }
+
+        # OK, we got a good one
+        $constraintfailures = 0;
+
+        insn16($insn >> 16);
+        if ($insnwidth == 32) {
+            insn16($insn & 0xffff);
+        }
+
+        return;
+    }
+}
+
+my $lastprog;
+my $proglen;
+my $progmax;
+
+sub progress_start($$)
+{
+    ($proglen, $progmax) = @_;
+    $proglen -= 2; # allow for [] chars
+    $| = 1;        # disable buffering so we can see the meter...
+    print "[" . " " x $proglen . "]\r";
+    $lastprog = 0;
+}
+
+sub progress_update($)
+{
+    # update the progress bar with current progress
+    my ($done) = @_;
+    my $barlen = int($proglen * $done / $progmax);
+    if ($barlen != $lastprog) {
+        $lastprog = $barlen;
+        print "[" . "-" x $barlen . " " x ($proglen - $barlen) . "]\r";
+    }
+}
+
+sub progress_end()
+{
+    print "[" . "-" x $proglen . "]\n";
+    $| = 0;
+}
+
+sub write_test_code($)
+{
+    my ($params) = @_;
+
+    my $condprob = $params->{ 'condprob' };
+    my $numinsns = $params->{ 'numinsns' };
+    my $outfile = $params->{ 'outfile' };
+
+    my @pattern_re = @{ $params->{ 'pattern_re' } };
+    my @not_pattern_re = @{ $params->{ 'not_pattern_re' } };
+    my %insn_details = %{ $params->{ 'details' } };
+
+    open_bin($outfile);
+
+    # convert from probability that insn will be conditional to
+    # probability of forcing insn to unconditional
+    $condprob = 1 - $condprob;
+
+    # TODO better random number generator?
+    srand(0);
+
+    # Get a list of the insn keys which are permitted by the re patterns
+    my @keys = sort keys %insn_details;
+    if (@pattern_re) {
+        my $re = '\b((' . join(')|(',@pattern_re) . '))\b';
+        @keys = grep /$re/, @keys;
+    }
+    # exclude any specifics
+    if (@not_pattern_re) {
+        my $re = '\b((' . join(')|(',@not_pattern_re) . '))\b';
+        @keys = grep !/$re/, @keys;
+    }
+    if (!@keys) {
+        print STDERR "No instruction patterns available! (bad config file or --pattern argument?)\n";
+        exit(1);
+    }
+    print "Generating code using patterns: @keys...\n";
+    progress_start(78, $numinsns);
+
+    if (grep { defined($insn_details{$_}->{blocks}->{"memory"}) } @keys) {
+        write_memblock_setup();
+    }
+
+    # memblock setup doesn't clean its registers, so this must come afterwards.
+    write_random_register_data();
+
+    for my $i (1..$numinsns) {
+        my $insn_enc = $keys[int rand (@keys)];
+        my $forcecond = (rand() < $condprob) ? 1 : 0;
+        gen_one_insn($forcecond, $insn_details{$insn_enc});
+        write_risuop($OP_COMPARE);
+        # Rewrite the registers periodically. This avoids the tendency
+        # for the VFP registers to decay to NaNs and zeroes.
+        if ($periodic_reg_random && ($i % 100) == 0) {
+            write_random_register_data();
+        }
+        progress_update($i);
+    }
+    write_risuop($OP_TESTEND);
+    progress_end();
+    close_bin();
+}
+
+1;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PATCH 2/5] m68k: implement server and client side
  2017-02-07 18:33 [Qemu-devel] [PATCH 0/5] risu: add m68k target support Laurent Vivier
  2017-02-07 18:33 ` [Qemu-devel] [PATCH 1/5] m68k: implement risugen module Laurent Vivier
@ 2017-02-07 18:33 ` Laurent Vivier
  2017-02-18 22:37   ` Peter Maydell
  2017-02-07 18:33 ` [Qemu-devel] [PATCH 3/5] m68k: add risufile with m68k instructions Laurent Vivier
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Laurent Vivier @ 2017-02-07 18:33 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Laurent Vivier

This also adds the basic test file and the configuration update.

This implementation can only test instructions with values in register and
no memory access.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 configure           |   6 ++-
 risu_m68k.c         | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 risu_reginfo_m68k.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++
 risu_reginfo_m68k.h |  32 +++++++++++
 test_m68k.s         |  28 ++++++++++
 5 files changed, 368 insertions(+), 2 deletions(-)
 create mode 100644 risu_m68k.c
 create mode 100644 risu_reginfo_m68k.c
 create mode 100644 risu_reginfo_m68k.h
 create mode 100644 test_m68k.s

diff --git a/configure b/configure
index f81bdb5..f5921ee 100755
--- a/configure
+++ b/configure
@@ -18,7 +18,9 @@ EOF
 }
 
 guess_arch() {
-    if check_define __arm__ ; then
+    if check_define __m68k__ ; then
+        ARCH="m68k"
+    elif check_define __arm__ ; then
         ARCH="arm"
     elif check_define __aarch64__ ; then
         ARCH="aarch64"
@@ -63,7 +65,7 @@ Some influential environment variables:
                prefixed with the given string.
 
   ARCH         force target architecture instead of trying to detect it.
-               Valid values=[arm|aarch64|ppc64|ppc64le]
+               Valid values=[arm|aarch64|ppc64|ppc64le|m68k]
 
   CC           C compiler command
   CFLAGS       C compiler flags
diff --git a/risu_m68k.c b/risu_m68k.c
new file mode 100644
index 0000000..15e30b1
--- /dev/null
+++ b/risu_m68k.c
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Laurent Vivier
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+
+#include <stdio.h>
+#include <ucontext.h>
+#include <string.h>
+
+#include "risu.h"
+#include "risu_reginfo_m68k.h"
+
+struct reginfo master_ri, apprentice_ri;
+static int mem_used = 0;
+static int packet_mismatch = 0;
+
+uint8_t apprentice_memblock[MEMBLOCKLEN];
+
+void advance_pc(void *vuc)
+{
+    ucontext_t *uc = (ucontext_t*)vuc;
+    uc->uc_mcontext.gregs[R_PC] += 4;
+}
+
+void set_a0(void *vuc, uint32_t a0)
+{
+    ucontext_t *uc = vuc;
+    uc->uc_mcontext.gregs[R_A0] = a0;
+}
+
+static int get_risuop(uint32_t insn)
+{
+    uint32_t op = insn & 0xf;
+    uint32_t key = insn & ~0xf;
+    uint32_t risukey = 0x4afc7000;
+    return (key != risukey) ? -1 : op;
+}
+
+int send_register_info(int sock, void *uc)
+{
+    struct reginfo ri;
+    int op;
+
+    reginfo_init(&ri, uc);
+    op = get_risuop(ri.faulting_insn);
+
+    switch (op) {
+    case OP_COMPARE:
+    case OP_TESTEND:
+    default:
+        return send_data_pkt(sock, &ri, sizeof(ri));
+    case OP_SETMEMBLOCK:
+        memblock = (void*)ri.gregs[R_A0];
+        break;
+    case OP_GETMEMBLOCK:
+        set_a0(uc, ri.gregs[R_A0] + (uintptr_t)memblock);
+        break;
+    case OP_COMPAREMEM:
+        return send_data_pkt(sock, memblock, MEMBLOCKLEN);
+        break;
+    }
+    return 0;
+}
+
+/* Read register info from the socket and compare it with that from the
+ * ucontext. Return 0 for match, 1 for end-of-test, 2 for mismatch.
+ * NB: called from a signal handler.
+ */
+int recv_and_compare_register_info(int sock, void *uc)
+{
+    int resp = 0;
+    int op;
+
+    reginfo_init(&master_ri, uc);
+    op = get_risuop(master_ri.faulting_insn);
+
+    switch (op) {
+    case OP_COMPARE:
+    case OP_TESTEND:
+    default:
+        if (recv_data_pkt(sock, &apprentice_ri, sizeof(apprentice_ri))) {
+            packet_mismatch = 1;
+            resp = 2;
+        } else if (!reginfo_is_eq(&master_ri, &apprentice_ri, uc)) {
+            resp = 2;
+        }
+        else if (op == OP_TESTEND) {
+            resp = 1;
+        }
+        send_response_byte(sock, resp);
+        break;
+    case OP_SETMEMBLOCK:
+        memblock = (void*)master_ri.gregs[R_A0];
+        break;
+    case OP_GETMEMBLOCK:
+        set_a0(uc, master_ri.gregs[R_A0] + (uintptr_t)memblock);
+        break;
+    case OP_COMPAREMEM:
+        mem_used = 1;
+        if (recv_data_pkt(sock, apprentice_memblock, MEMBLOCKLEN)) {
+            packet_mismatch = 1;
+            resp = 2;
+        } else if (memcmp(memblock, apprentice_memblock, MEMBLOCKLEN) != 0) {
+            resp = 2;
+        }
+        send_response_byte(sock, resp);
+        break;
+    }
+    return resp;
+}
+
+/* Print a useful report on the status of the last comparison
+ * done in recv_and_compare_register_info(). This is called on
+ * exit, so need not restrict itself to signal-safe functions.
+ * Should return 0 if it was a good match (ie end of test)
+ * and 1 for a mismatch.
+ */
+int report_match_status(void)
+{
+    int resp = 0;
+    fprintf(stderr, "match status...\n");
+
+    if (packet_mismatch) {
+        fprintf(stderr, "packet mismatch (probably disagreement "
+                "about UNDEF on load/store)\n");
+        fprintf(stderr, "master reginfo:\n");
+        reginfo_dump(&master_ri, 0);
+    }
+    if (!reginfo_is_eq(&master_ri, &apprentice_ri, NULL)) {
+        fprintf(stderr, "mismatch on regs!\n");
+        resp = 1;
+    }
+    if (mem_used && memcmp(memblock, &apprentice_memblock, MEMBLOCKLEN) != 0) {
+        fprintf(stderr, "mismatch on memory!\n");
+        resp = 1;
+    }
+    if (!resp) {
+        fprintf(stderr, "match!\n");
+        return 0;
+    }
+
+    fprintf(stderr, "master reginfo:\n");
+    reginfo_dump(&master_ri, 1);
+
+    fprintf(stderr, "apprentice reginfo:\n");
+    reginfo_dump(&apprentice_ri, 0);
+
+    reginfo_dump_mismatch(&master_ri, &apprentice_ri, stderr);
+    return resp;
+}
diff --git a/risu_reginfo_m68k.c b/risu_reginfo_m68k.c
new file mode 100644
index 0000000..c9d21cc
--- /dev/null
+++ b/risu_reginfo_m68k.c
@@ -0,0 +1,151 @@
+/*****************************************************************************
+ * Copyright (c) 2016 Laurent Vivier
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *****************************************************************************/
+
+#include <stdio.h>
+#include <ucontext.h>
+#include <string.h>
+#include <math.h>
+
+#include "risu.h"
+#include "risu_reginfo_m68k.h"
+
+/* reginfo_init: initialize with a ucontext */
+void reginfo_init(struct reginfo *ri, ucontext_t *uc)
+{
+    int i;
+    memset(ri, 0, sizeof(*ri));
+
+    ri->faulting_insn = *((uint32_t *)uc->uc_mcontext.gregs[R_PC]);
+    ri->pc = uc->uc_mcontext.gregs[R_PC] - image_start_address;
+
+    for (i = 0; i < NGREG; i++) {
+        ri->gregs[i] = uc->uc_mcontext.gregs[i];
+    }
+
+    ri->fpregs.f_pcr = uc->uc_mcontext.fpregs.f_pcr;
+    ri->fpregs.f_psr = uc->uc_mcontext.fpregs.f_psr;
+    ri->fpregs.f_fpiaddr = uc->uc_mcontext.fpregs.f_fpiaddr;
+    for (i = 0; i < 8; i++) {
+        memcpy(&ri->fpregs.f_fpregs[i * 3],
+               &uc->uc_mcontext.fpregs.f_fpregs[i * 3],
+               3 * sizeof(int));
+    }
+}
+
+/* reginfo_is_eq: compare the reginfo structs, returns nonzero if equal */
+int reginfo_is_eq(struct reginfo *m, struct reginfo *a, ucontext_t *uc)
+{
+    int i;
+
+    if (m->gregs[R_PS] != a->gregs[R_PS]) {
+        return 0;
+    }
+
+    for (i = 0; i < 16; i++) {
+        if (i == R_SP || i == R_A6) {
+            continue;
+        }
+        if (m->gregs[i] != a->gregs[i]) {
+            return 0;
+        }
+    }
+
+    if (m->fpregs.f_pcr != a->fpregs.f_pcr) {
+        return 0;
+    }
+
+    if (m->fpregs.f_psr != a->fpregs.f_psr) {
+        return 0;
+    }
+
+    for (i = 0; i < 8; i++) {
+        if (m->fpregs.f_fpregs[i * 3] != a->fpregs.f_fpregs[i * 3] ||
+            m->fpregs.f_fpregs[i * 3 + 1] != a->fpregs.f_fpregs[i * 3 + 1] ||
+            m->fpregs.f_fpregs[i * 3 + 2] != a->fpregs.f_fpregs[i * 3 + 2]) {
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+/* reginfo_dump: print state to a stream, returns nonzero on success */
+void reginfo_dump(struct reginfo *ri, int is_master)
+{
+    int i;
+    if (is_master) {
+        fprintf(stderr, "  pc            \e[1;101;37m0x%08x\e[0m\n",
+                ri->pc);
+    }
+    fprintf(stderr, "\tPC: %08x\n", ri->gregs[R_PC]);
+    fprintf(stderr, "\tPS: %04x\n", ri->gregs[R_PS]);
+
+    for (i = 0; i < 8; i++) {
+        fprintf(stderr, "\tD%d: %8x\tA%d: %8x\n", i, ri->gregs[i],
+                i, ri->gregs[i + 8]);
+    }
+
+
+    for (i = 0; i < 8; i++) {
+        fprintf(stderr, "\tFP%d: %08x %08x %08x\n", i,
+                ri->fpregs.f_fpregs[i * 3], ri->fpregs.f_fpregs[i * 3 + 1],
+                ri->fpregs.f_fpregs[i * 3 + 2]);
+    }
+
+    fprintf(stderr, "\n");
+}
+
+int reginfo_dump_mismatch(struct reginfo *m, struct reginfo *a, FILE *f)
+{
+    int i;
+
+    if (m->gregs[R_PS] != a->gregs[R_PS]) {
+            fprintf(f, "Mismatch: Register PS\n");
+            fprintf(f, "master: [%x] - apprentice: [%x]\n",
+                    m->gregs[R_PS], a->gregs[R_PS]);
+    }
+
+    for (i = 0; i < 16; i++) {
+        if (i == R_SP || i == R_A6) {
+            continue;
+        }
+        if (m->gregs[i] != a->gregs[i]) {
+            fprintf(f, "Mismatch: Register %c%d\n", i < 8 ? 'D' : 'A', i % 8);
+            fprintf(f, "master: [%x] - apprentice: [%x]\n",
+                    m->gregs[i], a->gregs[i]);
+        }
+    }
+
+    if (m->fpregs.f_pcr != a->fpregs.f_pcr) {
+        fprintf(f, "Mismatch: Register FPCR\n");
+        fprintf(f, "m: [%04x] != a: [%04x]\n",
+                m->fpregs.f_pcr, a->fpregs.f_pcr);
+    }
+
+    if (m->fpregs.f_psr != a->fpregs.f_psr) {
+        fprintf(f, "Mismatch: Register FPSR\n");
+        fprintf(f, "m: [%08x] != a: [%08x]\n",
+                m->fpregs.f_psr, a->fpregs.f_psr);
+    }
+
+    for (i = 0; i < 8; i++) {
+        if (m->fpregs.f_fpregs[i * 3] != a->fpregs.f_fpregs[i * 3] ||
+            m->fpregs.f_fpregs[i * 3 + 1] != a->fpregs.f_fpregs[i * 3 + 1] ||
+            m->fpregs.f_fpregs[i * 3 + 2] != a->fpregs.f_fpregs[i * 3 + 2]) {
+            fprintf(f, "Mismatch: Register FP%d\n", i);
+            fprintf(f, "m: [%08x %08x %08x] != a: [%08x %08x %08x]\n",
+                    m->fpregs.f_fpregs[i * 3], m->fpregs.f_fpregs[i * 3 + 1],
+                    m->fpregs.f_fpregs[i * 3 + 2], a->fpregs.f_fpregs[i * 3],
+                    a->fpregs.f_fpregs[i * 3 + 1],
+                    a->fpregs.f_fpregs[i * 3 + 2]);
+        }
+    }
+
+
+    return !ferror(f);
+}
diff --git a/risu_reginfo_m68k.h b/risu_reginfo_m68k.h
new file mode 100644
index 0000000..9dd8f32
--- /dev/null
+++ b/risu_reginfo_m68k.h
@@ -0,0 +1,32 @@
+/*****************************************************************************
+ * Copyright (c) 2016 Laurent Vivier
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *****************************************************************************/
+
+#ifndef RISU_REGINFO_M68K_H
+#define RISU_REGINFO_M68K_H
+
+struct reginfo
+{
+    uint32_t faulting_insn;
+    uint32_t pc;
+    gregset_t gregs;
+    fpregset_t fpregs;
+};
+
+/* initialize structure from a ucontext */
+void reginfo_init(struct reginfo *ri, ucontext_t *uc);
+
+/* return 1 if structs are equal, 0 otherwise. */
+int reginfo_is_eq(struct reginfo *r1, struct reginfo *r2, ucontext_t *uc);
+
+/* print reginfo state to a stream */
+void reginfo_dump(struct reginfo *ri, int is_master);
+
+/* reginfo_dump_mismatch: print mismatch details to a stream, ret nonzero=ok */
+int reginfo_dump_mismatch(struct reginfo *m, struct reginfo *a, FILE *f);
+
+#endif /* RISU_REGINFO_M68K_H */
diff --git a/test_m68k.s b/test_m68k.s
new file mode 100644
index 0000000..6ca8a92
--- /dev/null
+++ b/test_m68k.s
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Laurent Vivier
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************
+
+/* Initialise the gp regs */
+moveq.l #0, %d0
+move.l %d0, %d1
+move.l %d0, %d2
+move.l %d0, %d3
+move.l %d0, %d4
+move.l %d0, %d5
+move.l %d0, %d6
+move.l %d0, %d7
+move.l %d0, %a0
+move.l %d0, %a1
+move.l %d0, %a2
+move.l %d0, %a3
+move.l %d0, %a4
+move.l %d0, %a5
+
+/* do compare */
+.int 0x4afc7000
+/* exit test */
+.int 0x4afc7001
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PATCH 3/5] m68k: add risufile with m68k instructions.
  2017-02-07 18:33 [Qemu-devel] [PATCH 0/5] risu: add m68k target support Laurent Vivier
  2017-02-07 18:33 ` [Qemu-devel] [PATCH 1/5] m68k: implement risugen module Laurent Vivier
  2017-02-07 18:33 ` [Qemu-devel] [PATCH 2/5] m68k: implement server and client side Laurent Vivier
@ 2017-02-07 18:33 ` Laurent Vivier
  2017-02-07 18:33 ` [Qemu-devel] [PATCH 4/5] m68k: add instruction needing an extended word Laurent Vivier
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Laurent Vivier @ 2017-02-07 18:33 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Laurent Vivier

Add a set of instructions working only on registers.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 m68k.risu | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 241 insertions(+)
 create mode 100644 m68k.risu

diff --git a/m68k.risu b/m68k.risu
new file mode 100644
index 0000000..3317005
--- /dev/null
+++ b/m68k.risu
@@ -0,0 +1,241 @@
+###############################################################################
+# Copyright (c) 2016 Laurent Vivier
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+###############################################################################
+
+.mode m68k
+
+# abcd $dx,$dy
+ABCD  M68000 1100 Dx:3 10000 0 Dy:3 \
+                 !constraints { \
+                        write_movb_di($Dx, rand(10) | (rand(10) << 4)); \
+                        write_movb_di($Dy, rand(10) | (rand(10) << 4)); \
+                        1;\
+                      }
+# add $dx,$dy
+ADD   M68000 1101 Dx:3 0 opmode:2 000 Dy:3 \
+                 !constraints { $opmode != 0b11; }
+# adda $dx, $ay
+ADDA  M68000 1101 Ax:3 size:1 11 000 Dy:3
+# addi #Imm, $dx
+ADDIB M68000 00000110 00 000 Dx:3 00000000 data:8
+ADDIW M68000 00000110 01 000 Dx:3 data:16
+# addq #Imm3, $dx
+ADDQ  M68000 0101 imm:3 0 size:2 000 Dx:3 \
+                 !constraints { $size != 0b11; }
+# addx $dx,$dy
+ADDX  M68000 1101 Dx:3 1 size:2 00 0 Dy:3 \
+                 !constraints { $size != 0b11; }
+# and $dx, $dy
+AND   M68000 1100 Dx:3 0 opmode:2 000 Dy:3 \
+                 !constraints { $opmode != 0b11; }
+# andi #Imm,$dx
+ANDIB M68000 00000010 00 000 Dx:3 00000000 data:8
+ANDIW M68000 00000010 01 000 Dx:3 data:16
+# andi #imm,ccr
+ANDICCR M68000 0000001000111100 data:16 \
+                 !constraints { write_mov_ccr(rand(0x100)); 1; }
+# asl/asr $dx,$dy , asl/asr #im3,$r
+ASx   M68000 1110 count:3 d:1 size:2 i:1 00 r:3 \
+                 !constraints { $size != 0b11; }
+# bchg $dx,$dy
+BCHG  M68000 0000 Dx:3 101 000 Dy:3
+BCHGI M68000 0000 100  001 000 Dx:3 0000000 data:9
+# blcr $dx,$dy
+BCLR  M68000 0000 Dx:3 110 000 Dy:3
+BCLRI M68000 0000 100  010 000 Dx:3 0000000 data:9
+# bfchg $dx,offset:width
+BFCHG M68020 1110101011 000 Dx:3 0000 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }
+# bfclr $dx,offset:width
+BFCLR M68020 1110110011 000 Dx:3 0000 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }
+# bfexts $dx,offset:width,$dy
+BFEXTS M68020 1110101111 000 Dx:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }
+# bfextu $dx,offset:width,$dy
+BFEXTU M68020 1110100111 000 Dx:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }
+# bfffo $dx,offset:width,$dy
+# there is a bug in 68040 with offset > 31
+BFFFO M68020 1110110111 000 Dx:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5    \
+                !constraints {                                        \
+                               if ($Dw == 1) { $width &= 0x7; ;}      \
+                               if ($Do == 1) {                        \
+                                   $offset &= 0x7;                    \
+                                   write_mov_di($offset, rand(0x20)); \
+                               }                                      \
+                               1;                                     \
+                             }
+# bfins $dx,offset:width,$dy
+BFINS M68020 1110111111 000 Dx:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }
+# bfset $dx,offset:width
+BFSET M68020 1110111011 000 Dx:3 0000 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }
+# bftst $dx,offset:width
+BFTST M68020 1110100011 000 Dx:3 0000 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }
+# bset $dx,$dy
+BSET  M68000 0000 Dx:3 111 000 Dy:3
+BSETI M68000 0000 100  011 000 Dx:3 0000000 data:9
+# btst $dx,$dy
+BTST  M68000 0000 Dx:3 100 000 Dy:3
+BTSTI M68000 0000 100  000 000 Dx:3 0000000 data:9
+# clr $dx
+CLR   M68000 01000010 size:2 000 Dx:3 \
+                 !constraints { $size != 0b11; }
+# cmp $dx,$dy
+CMP   M68000 1011 Dx:3 0 size:2 000 Dy:3 \
+                 !constraints { $size != 0b11; }
+# cmpa $dx,$ay
+CMPA  M68000 1011 Ax:3 size:1 11 000 Dy:3
+# cmpi #Imm, $dx
+CMPIB M68000 00001100 00 000 Dx:3 00000000 data:8
+CMPIW M68000 00001100 01 000 Dx:3 data:16
+# divs $dx,$dy
+DIVS  M68000 1000 Dy:3 111 000 Dx:3 \
+                 !constraints { \
+                        write_mov_di($Dx, rand(0xffffffff) + 1); \
+                        1;                                       \
+                      }
+# divsl $dx,$dr:$dq
+DIVSL M68020 0100110001 000 Dx:3  0 Dq:3 1 size:1 0000000 Dr:3 \
+                 !constraints { \
+                        write_mov_di($Dx, rand(0xffffffff) + 1); \
+                        1;                                       \
+                      }
+# divu $dx,$dy
+DIVU  M68000 1000 Dy:3 011 000 Dx:3 \
+                 !constraints { \
+                        write_mov_di($Dx, rand(0xffffffff) + 1); \
+                        1;                                       \
+                      }
+# divul $dx,$dr:$dq
+DIVUL M68020 0100110001 000 Dx:3  0 Dq:3 0 size:1 0000000 Dr:3 \
+                 !constraints { \
+                        write_mov_di($Dx, rand(0xffffffff) + 1); \
+                        1;                                       \
+                      }
+# eor $dx,$dy
+EOR   M68000 1011 Dx:3 1 size:2 000 Dy:3 \
+                 !constraints { $size != 0b11; }
+# eori #Imm, $dx
+EORIB M68000 00001010 00 000 Dx:3 00000000 data:8
+EORIW M68000 00001010 01 000 Dx:3 data:16
+# eori #imm,ccr
+EORICCR M68000 0000101000111100 data:16 \
+                 !constraints { write_mov_ccr(rand(0x100)); 1; }
+# exg $dx,$dy
+EXG_d M68000 1100 Dx:3 1 01000 Dy:3
+# exg $ax,$ay
+EXG_a M68000 1100 Ax:3 1 01000 Ay:3
+# exg $dx,$ay
+EXG   M68000 1100 Dx:3 1 01000 Ay:3
+# ext $dx
+EXT   M68000 0100100 opmode:3 000 Dx:3 \
+                 !constraints { $opmode == 0b010 || $opmode == 0b011 }
+EXTB  M68020 0100100 111 000 Dx:3
+# lsl/lsr $dx,$dy , lsl/lsr #im3,$r
+LSx   M68000 1110 count:3 d:1 size:2 i:1 01 r:3 \
+                 !constraints { $size != 0b11; }
+# move $dx,$dy
+MOVE  M68000 00 size:2 Dy:3 000 000 Dx:3 \
+                 !constraints { $size != 0b00; }
+# movea $dx,$ay
+MOVEA M68000 00 size:2 Ay:3 001 000 Dx:3 \
+                 !constraints { $size != 0b00 && $size != 0b01; }
+# move ccr,$dx
+MOVEFROMCCR  M68010 0100001011 000 Dx:3
+# move $dx,ccr
+MOVETOCCR M68000 0100010011 000 Dx:3
+# moveq #Imm8, $dx
+MOVEQ M68000 0111 Dx:3 0 data:8
+# muls $dx,$dy
+MULS  M68000 1100 Dy:3 111 000 Dx:3
+# mulsl $dx, $dh:$dl
+MULSL M68020 0100110000 000 Dx:3 0 Dl:3 1 size:1 0000000 Dh:3
+# mulu $dx,$dy
+MULU  M68000 1100 Dy:3 011 000 Dx:3
+# mulul $dx, $dh:$dl
+MULUL M68020 0100110000 000 Dx:3 0 Dl:3 0 size:1 0000000 Dh:3
+# nbcd $dx
+NBCD  M68000 0100100000 000 Dx:3 \
+                 !constraints { \
+                        write_movb_di($Dx, rand(10) | (rand(10) << 4)); \
+                        1;                                              \
+                      }
+# neg $dx
+NEG   M68000 01000100 size:2 000 Dx:3 \
+                 !constraints { $size != 0b11; }
+# negx $dx
+NEGX  M68000 01000000 size:2 000 Dx:3 \
+                 !constraints { $size != 0b11; }
+# nop
+NOP   M68000 0100111001110001
+# not $dx
+NOT   M68000 01000110 size:2 000 Dx:3 \
+                 !constraints { $size != 0b11; }
+# or $dx,$dy
+OR    M68000 1000 Dy:3 0 size:2 000 Dx:3 \
+                 !constraints { $size != 0b11; }
+# ori #Imm, $dx
+ORIB M68000 00000000 00 000 Dx:3 00000000 data:8
+ORIW M68000 00000000 01 000 Dx:3 data:16
+# ori #imm,ccr
+ORICCR M68000 0000000000111100 data:16 \
+                 !constraints { write_mov_ccr(rand(0x100)); 1; }
+# rol/ror $dx,$dy , rol/ror #im3,$r
+ROx   M68000 1110 count:3 d:1 size:2 i:1 11 r:3 \
+                 !constraints { $size != 0b11; }
+# roxl/roxr $dx,$dy , roxl/roxr #im3,$r
+ROXx  M68000 1110 count:3 d:1 size:2 i:1 10 r:3 \
+                 !constraints { $size != 0b11; }
+# sbcd $dx,$dy
+SBCD  M68000 1000 Dx:3 10000 0 Dy:3 \
+                 !constraints { \
+                        write_movb_di($Dx, rand(10) | (rand(10) << 4)); \
+                        write_movb_di($Dy, rand(10) | (rand(10) << 4)); \
+                        1;                                              \
+                      }
+# Scc $dx
+SCC M68000 0101 cond:4 11 000 dx:3 \
+                 !constraints { write_mov_ccr(rand(0x100)); 1; }
+# sub $dx,$dy
+SUB   M68000 1001 Dx:3 0 opmode:2 000 Dy:3 \
+                 !constraints { $opmode != 0b11; }
+# suba $dx, $ay
+SUBA  M68000 1001 Ax:3 size:1 11 000 Dy:3
+# subi #Imm, $dx
+SUBIB M68000 00000100 00 000 Dx:3 00000000 data:8
+SUBIW M68000 00000100 01 000 Dx:3 data:16
+# subq #Imm3n $dx
+SUBQ  M68000 0101 imm:3 1 size:2 000 Dx:3 \
+                 !constraints { $size != 0b11; }
+# subx $dx,$dy
+SUBX  M68000 1001 Dx:3 1 size:2 00 0 Dy:3 \
+                 !constraints { $size != 0b11; }
+# swap $dx
+SWAP  M68000 0100100001000 Dx:3
+# tas $dx
+TAS   M68000 0100101011 000 Dx:3
+# tst $dx
+TST   M68000 01001010 size:2 000 Dx:3 \
+                 !constraints { $size != 0b11; }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PATCH 4/5] m68k: add instruction needing an extended word
  2017-02-07 18:33 [Qemu-devel] [PATCH 0/5] risu: add m68k target support Laurent Vivier
                   ` (2 preceding siblings ...)
  2017-02-07 18:33 ` [Qemu-devel] [PATCH 3/5] m68k: add risufile with m68k instructions Laurent Vivier
@ 2017-02-07 18:33 ` Laurent Vivier
  2017-02-07 18:33 ` [Qemu-devel] [PATCH 5/5] m68k: manage memory block Laurent Vivier
  2017-02-10 15:25 ` [Qemu-devel] [PATCH 0/5] risu: add m68k target support Peter Maydell
  5 siblings, 0 replies; 12+ messages in thread
From: Laurent Vivier @ 2017-02-07 18:33 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Laurent Vivier

Some instructions are encoded on more than 32 bits.

To be able to add this word, we introduce a new keyword: "post".
This keyword adds a block to be executed after the instruction
generation.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 m68k.risu       | 42 ++++++++++++++++++++++++++++++++++++------
 risugen         |  2 +-
 risugen_m68k.pm |  4 ++++
 3 files changed, 41 insertions(+), 7 deletions(-)

diff --git a/m68k.risu b/m68k.risu
index 3317005..4297283 100644
--- a/m68k.risu
+++ b/m68k.risu
@@ -23,6 +23,8 @@ ADDA  M68000 1101 Ax:3 size:1 11 000 Dy:3
 # addi #Imm, $dx
 ADDIB M68000 00000110 00 000 Dx:3 00000000 data:8
 ADDIW M68000 00000110 01 000 Dx:3 data:16
+ADDIL M68000 00000110 10 000 Dx:3 \
+                 !post { insn32(rand(0xffffffff)); }
 # addq #Imm3, $dx
 ADDQ  M68000 0101 imm:3 0 size:2 000 Dx:3 \
                  !constraints { $size != 0b11; }
@@ -35,6 +37,8 @@ AND   M68000 1100 Dx:3 0 opmode:2 000 Dy:3 \
 # andi #Imm,$dx
 ANDIB M68000 00000010 00 000 Dx:3 00000000 data:8
 ANDIW M68000 00000010 01 000 Dx:3 data:16
+ANDIL M68000 00000010 10 000 Dx:3 \
+                 !post { insn32(rand(0xffffffff)); }
 # andi #imm,ccr
 ANDICCR M68000 0000001000111100 data:16 \
                  !constraints { write_mov_ccr(rand(0x100)); 1; }
@@ -68,15 +72,13 @@ BFEXTU M68020 1110100111 000 Dx:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5 \
                                (!$Dw || $width < 8);             \
                              }
 # bfffo $dx,offset:width,$dy
-# there is a bug in 68040 with offset > 31
+# there is a bug in 68040 with D(offset) > 31
 BFFFO M68020 1110110111 000 Dx:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5    \
-                !constraints {                                        \
-                               if ($Dw == 1) { $width &= 0x7; ;}      \
-                               if ($Do == 1) {                        \
-                                   $offset &= 0x7;                    \
+                !constraints { if ($Do == 1 && $offset < 8) {         \
                                    write_mov_di($offset, rand(0x20)); \
                                }                                      \
-                               1;                                     \
+                               (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
                              }
 # bfins $dx,offset:width,$dy
 BFINS M68020 1110111111 000 Dx:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5 \
@@ -110,6 +112,8 @@ CMPA  M68000 1011 Ax:3 size:1 11 000 Dy:3
 # cmpi #Imm, $dx
 CMPIB M68000 00001100 00 000 Dx:3 00000000 data:8
 CMPIW M68000 00001100 01 000 Dx:3 data:16
+CMPIL M68000 00001100 10 000 Dx:3 \
+                 !post { insn32(rand(0xffffffff)); }
 # divs $dx,$dy
 DIVS  M68000 1000 Dy:3 111 000 Dx:3 \
                  !constraints { \
@@ -140,6 +144,8 @@ EOR   M68000 1011 Dx:3 1 size:2 000 Dy:3 \
 # eori #Imm, $dx
 EORIB M68000 00001010 00 000 Dx:3 00000000 data:8
 EORIW M68000 00001010 01 000 Dx:3 data:16
+EORIL M68000 00001010 10 000 Dx:3 \
+                 !post { insn32(rand(0xffffffff)); }
 # eori #imm,ccr
 EORICCR M68000 0000101000111100 data:16 \
                  !constraints { write_mov_ccr(rand(0x100)); 1; }
@@ -153,6 +159,26 @@ EXG   M68000 1100 Dx:3 1 01000 Ay:3
 EXT   M68000 0100100 opmode:3 000 Dx:3 \
                  !constraints { $opmode == 0b010 || $opmode == 0b011 }
 EXTB  M68020 0100100 111 000 Dx:3
+# lea <ea> (XXX: must test full extension word format)
+LEA   M68000 0100 Ax:3 111 mode:3 reg:3 \
+                 !constraints { $reg != 6 && $reg != 7 &&                    \
+                                ($mode == 0b010 || $mode == 0b101 ||         \
+                                $mode == 0b110 ||                            \
+                                ($mode == 0b111 && $reg == 0b000) ||         \
+                                ($mode == 0b111 && $reg == 0b001));          \
+                              }                                              \
+                 !post        { if ($mode == 0b101) {                        \
+                                    insn16(rand(0x10000));                   \
+                                } elsif ($mode == 0b110) {                   \
+                                    insn16(((rand(0x80) & 0b1000111) |       \
+                                            (rand(6) << 3)) << 9 |           \
+                                           rand(0x100));                     \
+                                } elsif ($mode == 0b111 && $reg == 0b000) {  \
+                                    insn16(rand(0x10000));                   \
+                                } elsif ($mode == 0b111 && $reg == 0b001) {  \
+                                    insn32(rand(0xffffffff));                \
+                                }                                            \
+                              }
 # lsl/lsr $dx,$dy , lsl/lsr #im3,$r
 LSx   M68000 1110 count:3 d:1 size:2 i:1 01 r:3 \
                  !constraints { $size != 0b11; }
@@ -199,6 +225,8 @@ OR    M68000 1000 Dy:3 0 size:2 000 Dx:3 \
 # ori #Imm, $dx
 ORIB M68000 00000000 00 000 Dx:3 00000000 data:8
 ORIW M68000 00000000 01 000 Dx:3 data:16
+ORIL M68000 00000000 10 000 Dx:3 \
+                 !post { insn32(rand(0xffffffff)); }
 # ori #imm,ccr
 ORICCR M68000 0000000000111100 data:16 \
                  !constraints { write_mov_ccr(rand(0x100)); 1; }
@@ -226,6 +254,8 @@ SUBA  M68000 1001 Ax:3 size:1 11 000 Dy:3
 # subi #Imm, $dx
 SUBIB M68000 00000100 00 000 Dx:3 00000000 data:8
 SUBIW M68000 00000100 01 000 Dx:3 data:16
+SUBIL M68000 00000100 10 000 Dx:3 \
+                 !post { insn32(rand(0xffffffff)); }
 # subq #Imm3n $dx
 SUBQ  M68000 0101 imm:3 1 size:2 000 Dx:3 \
                  !constraints { $size != 0b11; }
diff --git a/risugen b/risugen
index 77a550b..b46567c 100755
--- a/risugen
+++ b/risugen
@@ -34,7 +34,7 @@ my @pattern_re = ();            # include pattern
 my @not_pattern_re = ();        # exclude pattern
 
 # Valid block names (keys in blocks hash)
-my %valid_blockname = ( constraints => 1, memory => 1 );
+my %valid_blockname = ( constraints => 1, memory => 1, post => 1 );
 
 my $lastprog;
 my $proglen;
diff --git a/risugen_m68k.pm b/risugen_m68k.pm
index a9a4341..60223f0 100644
--- a/risugen_m68k.pm
+++ b/risugen_m68k.pm
@@ -161,6 +161,7 @@ sub gen_one_insn($$)
         my $fixedbits = $rec->{fixedbits};
         my $fixedbitmask = $rec->{fixedbitmask};
         my $constraint = $rec->{blocks}{"constraints"};
+        my $post = $rec->{blocks}{"post"};
         my $memblock = $rec->{blocks}{"memory"};
 
         $insn &= ~$fixedbitmask;
@@ -194,6 +195,9 @@ sub gen_one_insn($$)
         if ($insnwidth == 32) {
             insn16($insn & 0xffff);
         }
+        if (defined $post) {
+            eval_with_fields($insnname, $insn, $rec, "post", $post);
+        }
 
         return;
     }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [Qemu-devel] [PATCH 5/5] m68k: manage memory block
  2017-02-07 18:33 [Qemu-devel] [PATCH 0/5] risu: add m68k target support Laurent Vivier
                   ` (3 preceding siblings ...)
  2017-02-07 18:33 ` [Qemu-devel] [PATCH 4/5] m68k: add instruction needing an extended word Laurent Vivier
@ 2017-02-07 18:33 ` Laurent Vivier
  2017-02-10 15:25 ` [Qemu-devel] [PATCH 0/5] risu: add m68k target support Peter Maydell
  5 siblings, 0 replies; 12+ messages in thread
From: Laurent Vivier @ 2017-02-07 18:33 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel, Laurent Vivier

Add a new risu op to restore modified address register (OP_NORMALIZE)
and allow to manage several registers in the memory block

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 m68k.risu       | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 risu.h          |  1 +
 risu_m68k.c     |  5 +++
 risugen_m68k.pm | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 198 insertions(+), 3 deletions(-)

diff --git a/m68k.risu b/m68k.risu
index 4297283..dba9a5c 100644
--- a/m68k.risu
+++ b/m68k.risu
@@ -18,6 +18,9 @@ ABCD  M68000 1100 Dx:3 10000 0 Dy:3 \
 # add $dx,$dy
 ADD   M68000 1101 Dx:3 0 opmode:2 000 Dy:3 \
                  !constraints { $opmode != 0b11; }
+ADDm  M68000 1101 Dx:3 opmode:3 010 Ay:3 \
+                 !constraints { ($opmode & 0b11) != 0b11; } \
+                 !memory { reg($Ay); }
 # adda $dx, $ay
 ADDA  M68000 1101 Ax:3 size:1 11 000 Dy:3
 # addi #Imm, $dx
@@ -31,6 +34,9 @@ ADDQ  M68000 0101 imm:3 0 size:2 000 Dx:3 \
 # addx $dx,$dy
 ADDX  M68000 1101 Dx:3 1 size:2 00 0 Dy:3 \
                  !constraints { $size != 0b11; }
+ADDXm M68000 1101 Ax:3 1 size:2 00 1 Ay:3 \
+                 !constraints { $size != 0b11; } \
+                 !memory { reg($Ax); reg($Ay); } \
 # and $dx, $dy
 AND   M68000 1100 Dx:3 0 opmode:2 000 Dy:3 \
                  !constraints { $opmode != 0b11; }
@@ -48,29 +54,67 @@ ASx   M68000 1110 count:3 d:1 size:2 i:1 00 r:3 \
 # bchg $dx,$dy
 BCHG  M68000 0000 Dx:3 101 000 Dy:3
 BCHGI M68000 0000 100  001 000 Dx:3 0000000 data:9
+BCHGm M68000 0000 Dx:3 101 010 Ay:3 !memory { reg($Ay); }
 # blcr $dx,$dy
 BCLR  M68000 0000 Dx:3 110 000 Dy:3
 BCLRI M68000 0000 100  010 000 Dx:3 0000000 data:9
+BCLRm M68000 0000 Dx:3 110 010 Ay:3 !memory { reg($Ay); }
 # bfchg $dx,offset:width
 BFCHG M68020 1110101011 000 Dx:3 0000 Do:1 offset:5 Dw:1 width:5 \
                 !constraints { (!$Do || $offset < 8) &&          \
                                (!$Dw || $width < 8);             \
                              }
+BFCHGm M68020 1110101011 010 Ax:3 0000 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }                                   \
+                !memory { if ($Do) {                             \
+                              write_mov_di($offset, rand(2048) - 1024); \
+                          }                                             \
+                          reg($Ax);                                     \
+                        }
 # bfclr $dx,offset:width
 BFCLR M68020 1110110011 000 Dx:3 0000 Do:1 offset:5 Dw:1 width:5 \
                 !constraints { (!$Do || $offset < 8) &&          \
                                (!$Dw || $width < 8);             \
                              }
+BFCLRm M68020 1110110011 010 Ax:3 0000 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }                                   \
+                !memory { if ($Do) {                             \
+                              write_mov_di($offset, rand(2048) - 1024); \
+                          }                                             \
+                          reg($Ax);                                     \
+                        }
 # bfexts $dx,offset:width,$dy
 BFEXTS M68020 1110101111 000 Dx:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5 \
                 !constraints { (!$Do || $offset < 8) &&          \
                                (!$Dw || $width < 8);             \
                              }
+BFEXTSm M68020 1110101111 010 Ax:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }                                   \
+                !memory { if ($Do) {                             \
+                              write_mov_di($offset, rand(2048) - 1024); \
+                          }                                             \
+                          reg($Ax);                                     \
+                        }
 # bfextu $dx,offset:width,$dy
 BFEXTU M68020 1110100111 000 Dx:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5 \
                 !constraints { (!$Do || $offset < 8) &&          \
                                (!$Dw || $width < 8);             \
                              }
+BFEXTUm M68020 1110100111 010 Ax:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }                                   \
+                !memory { if ($Do) {                             \
+                              write_mov_di($offset, rand(2048) - 1024); \
+                          }                                             \
+                          reg($Ax);                                     \
+                        }
 # bfffo $dx,offset:width,$dy
 # there is a bug in 68040 with D(offset) > 31
 BFFFO M68020 1110110111 000 Dx:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5    \
@@ -80,27 +124,73 @@ BFFFO M68020 1110110111 000 Dx:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5    \
                                (!$Do || $offset < 8) &&          \
                                (!$Dw || $width < 8);             \
                              }
+BFFFOm M68020 1110110111 010 Ax:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5    \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }                                   \
+                !memory { if ($Do) {                             \
+                              write_mov_di($offset, rand(2048) - 1024); \
+                          }                                             \
+                          reg($Ax);                                     \
+                        }
 # bfins $dx,offset:width,$dy
 BFINS M68020 1110111111 000 Dx:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5 \
                 !constraints { (!$Do || $offset < 8) &&          \
                                (!$Dw || $width < 8);             \
                              }
+BFINSm M68020 1110111111 010 Ax:3 0 Dy:3 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }                                   \
+                !memory { if ($Do) {                             \
+                              write_mov_di($offset, rand(2048) - 1024); \
+                          }                                             \
+                          reg($Ax);                                     \
+                        }
 # bfset $dx,offset:width
 BFSET M68020 1110111011 000 Dx:3 0000 Do:1 offset:5 Dw:1 width:5 \
                 !constraints { (!$Do || $offset < 8) &&          \
                                (!$Dw || $width < 8);             \
                              }
+BFSETm M68020 1110111011 010 Ax:3 0000 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }                                   \
+                !memory { if ($Do) {                             \
+                              write_mov_di($offset, rand(2048) - 1024); \
+                          }                                             \
+                          reg($Ax);                                     \
+                        }
 # bftst $dx,offset:width
 BFTST M68020 1110100011 000 Dx:3 0000 Do:1 offset:5 Dw:1 width:5 \
                 !constraints { (!$Do || $offset < 8) &&          \
                                (!$Dw || $width < 8);             \
                              }
+BFTSTm M68020 1110100011 010 Ax:3 0000 Do:1 offset:5 Dw:1 width:5 \
+                !constraints { (!$Do || $offset < 8) &&          \
+                               (!$Dw || $width < 8);             \
+                             }                                   \
+                !memory { if ($Do == 1) {                    \
+                              write_mov_di($offset, rand(2048) - 1024); \
+                          }                                 \
+                          reg($Ax);                         \
+                        }                                   \
 # bset $dx,$dy
 BSET  M68000 0000 Dx:3 111 000 Dy:3
 BSETI M68000 0000 100  011 000 Dx:3 0000000 data:9
 # btst $dx,$dy
 BTST  M68000 0000 Dx:3 100 000 Dy:3
 BTSTI M68000 0000 100  000 000 Dx:3 0000000 data:9
+# cas $dc,$du,($ax)
+CAS   M68020 00001 size:2 011 010 Ax:3 0000000 Du:3 000 Dc:3 \
+                 !constraints { $size != 0b00; } \
+                 !memory { reg($Ax); }
+CAS2  M68020 00001 size:2 011111100 \
+                 !memory { reg(0); reg(1); } \
+                 !constraints { $size == 0b10 || $size == 0b11; } \
+                 !post { insn16(0x8000 | (rand(8) << 6) | rand(8)); \
+                         insn16(0x9000 | (rand(8) << 6) | rand(8)); \
+                       }
 # clr $dx
 CLR   M68000 01000010 size:2 000 Dx:3 \
                  !constraints { $size != 0b11; }
@@ -114,6 +204,9 @@ CMPIB M68000 00001100 00 000 Dx:3 00000000 data:8
 CMPIW M68000 00001100 01 000 Dx:3 data:16
 CMPIL M68000 00001100 10 000 Dx:3 \
                  !post { insn32(rand(0xffffffff)); }
+# cmpm ($ay)+,$(ax)+
+CMPM  M68000 1011 Ax:3 1 size:2 001 Ay:3         \
+                 !memory { reg($Ax); reg($Ay); }
 # divs $dx,$dy
 DIVS  M68000 1000 Dy:3 111 000 Dx:3 \
                  !constraints { \
@@ -192,6 +285,11 @@ MOVEA M68000 00 size:2 Ay:3 001 000 Dx:3 \
 MOVEFROMCCR  M68010 0100001011 000 Dx:3
 # move $dx,ccr
 MOVETOCCR M68000 0100010011 000 Dx:3
+# movem list,($ax) movem ($ax),list
+MOVEM     M68000 01001 dir:1 001 size:1 010 Ax:3 list:16 \
+                 !constraints { !($list & (0xc000 | (1 << ($Ax + 8)))); } \
+                 !memory { reg($Ax); }
+
 # moveq #Imm8, $dx
 MOVEQ M68000 0111 Dx:3 0 data:8
 # muls $dx,$dy
diff --git a/risu.h b/risu.h
index 26ed834..794b5f1 100644
--- a/risu.h
+++ b/risu.h
@@ -33,6 +33,7 @@ extern int test_fp_exc;
 #define OP_SETMEMBLOCK 2
 #define OP_GETMEMBLOCK 3
 #define OP_COMPAREMEM 4
+#define OP_NORMALIZE 5
 
 /* The memory block should be this long */
 #define MEMBLOCKLEN 8192
diff --git a/risu_m68k.c b/risu_m68k.c
index 15e30b1..f47132c 100644
--- a/risu_m68k.c
+++ b/risu_m68k.c
@@ -60,6 +60,8 @@ int send_register_info(int sock, void *uc)
         break;
     case OP_COMPAREMEM:
         return send_data_pkt(sock, memblock, MEMBLOCKLEN);
+    case OP_NORMALIZE:
+        set_a0(uc, ri.gregs[R_A0] - (uintptr_t)memblock);
         break;
     }
     return 0;
@@ -108,6 +110,9 @@ int recv_and_compare_register_info(int sock, void *uc)
         }
         send_response_byte(sock, resp);
         break;
+    case OP_NORMALIZE:
+        set_a0(uc, master_ri.gregs[R_A0] - (uintptr_t)memblock);
+        break;
     }
     return resp;
 }
diff --git a/risugen_m68k.pm b/risugen_m68k.pm
index 60223f0..d57224b 100644
--- a/risugen_m68k.pm
+++ b/risugen_m68k.pm
@@ -104,6 +104,13 @@ sub write_mov_ri($$)
     }
 }
 
+sub write_exg_aa($$)
+{
+    my ($reg0, $reg1) = @_;
+
+    insn16(0xc148 | ($reg0 << 9) | $reg1);
+}
+
 sub write_random_regdata()
 {
     # general purpose registers (except A6 (FP) and A7 (SP))
@@ -116,9 +123,10 @@ sub write_random_regdata()
 
 my $OP_COMPARE = 0;        # compare registers
 my $OP_TESTEND = 1;        # end of test, stop
-my $OP_SETMEMBLOCK = 2;    # r0 is address of memory block (8192 bytes)
-my $OP_GETMEMBLOCK = 3;    # add the address of memory block to r0
+my $OP_SETMEMBLOCK = 2;    # a0 is address of memory block (8192 bytes)
+my $OP_GETMEMBLOCK = 3;    # add the address of memory block to a0
 my $OP_COMPAREMEM = 4;     # compare memory block
+my $OP_NORMALIZE = 5;      # normalize a0 between master and apprentice
 
 sub write_random_register_data()
 {
@@ -126,6 +134,73 @@ sub write_random_register_data()
     write_risuop($OP_COMPARE);
 }
 
+sub write_pc_addr($$)
+{
+    my ($ad, $imm) = @_;
+
+    # lea (pc)len, Ad
+
+    insn16(0x41fa | ($ad << 9));
+    insn16($imm + 2);
+}
+
+sub write_jmp_fwd($)
+{
+    my ($len) = @_;
+
+    # bra (pc)len
+    insn16(0x6000);
+    insn16($len + 2);
+}
+
+sub write_memblock_setup()
+{
+    my $datalen = 8192;
+
+    write_pc_addr(0, 8);
+    write_risuop($OP_SETMEMBLOCK); # 4 bytes
+    write_jmp_fwd($datalen);       # 4 bytes
+    for (my $i = 0; $i < $datalen / 2; $i++) {
+        insn16(rand(0x10000));
+    }
+}
+
+sub write_get_offset()
+{
+    my $offset = (rand(2048 - 256) + 128) & ~1;
+    write_mov_ai(0, $offset);
+    write_risuop($OP_GETMEMBLOCK);
+}
+
+my @basereg;
+
+sub reg($)
+{
+    my ($reg) = @_;
+
+    if ($reg != 0) {
+        write_exg_aa($reg, 0);
+        write_get_offset();
+        write_exg_aa(0, $reg);
+    } else {
+        write_get_offset();
+    }
+    push @basereg, $reg;
+}
+
+sub normalize($)
+{
+    my ($reg) = @_;
+
+    if ($reg != 0) {
+        write_exg_aa($reg, 0);
+        write_risuop($OP_NORMALIZE);
+        write_exg_aa(0, $reg);
+    } else {
+        write_risuop($OP_NORMALIZE);
+    }
+}
+
 sub eval_with_fields($$$$$) {
     # Evaluate the given block in an environment with Perl variables
     # set corresponding to the variable fields for the insn.
@@ -191,6 +266,10 @@ sub gen_one_insn($$)
         # OK, we got a good one
         $constraintfailures = 0;
 
+
+        if (defined $memblock) {
+            eval_with_fields($insnname, $insn, $rec, "memory", $memblock);
+        }
         insn16($insn >> 16);
         if ($insnwidth == 32) {
             insn16($insn & 0xffff);
@@ -198,7 +277,19 @@ sub gen_one_insn($$)
         if (defined $post) {
             eval_with_fields($insnname, $insn, $rec, "post", $post);
         }
-
+        if (defined $memblock) {
+            my $r0;
+            $r0 = pop @basereg;
+            if (defined $r0) {
+                my $r1;
+                normalize($r0);
+                $r1 = pop @basereg;
+                if (defined $r1 && $r1 != $r0) {
+                    normalize($r1);
+                }
+            }
+            write_risuop($OP_COMPAREMEM);
+        }
         return;
     }
 }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 0/5] risu: add m68k target support
  2017-02-07 18:33 [Qemu-devel] [PATCH 0/5] risu: add m68k target support Laurent Vivier
                   ` (4 preceding siblings ...)
  2017-02-07 18:33 ` [Qemu-devel] [PATCH 5/5] m68k: manage memory block Laurent Vivier
@ 2017-02-10 15:25 ` Peter Maydell
  2017-02-10 15:33   ` Laurent Vivier
  5 siblings, 1 reply; 12+ messages in thread
From: Peter Maydell @ 2017-02-10 15:25 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: QEMU Developers

On 7 February 2017 at 18:33, Laurent Vivier <laurent@vivier.eu> wrote:
> This series add the files needed to test the m68k target.
>
> For the moment, it doesn't support FPU instructions.
>
> Laurent Vivier (5):
>   m68k: implement risugen module
>   m68k: implement server and client side
>   m68k: add risufile with m68k instructions.
>   m68k: add instruction needing an extended word
>   m68k: manage memory block

Thanks for this; I think patches 1-3 are good, and have
applied them to risu master. For 4 I wonder if we can
find a better way of handling variable-length instruction
sets than !post, and I haven't yet looked at 5.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 0/5] risu: add m68k target support
  2017-02-10 15:25 ` [Qemu-devel] [PATCH 0/5] risu: add m68k target support Peter Maydell
@ 2017-02-10 15:33   ` Laurent Vivier
  2017-02-10 17:32     ` Peter Maydell
  0 siblings, 1 reply; 12+ messages in thread
From: Laurent Vivier @ 2017-02-10 15:33 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

Le 10/02/2017 à 16:25, Peter Maydell a écrit :
> On 7 February 2017 at 18:33, Laurent Vivier <laurent@vivier.eu> wrote:
>> This series add the files needed to test the m68k target.
>>
>> For the moment, it doesn't support FPU instructions.
>>
>> Laurent Vivier (5):
>>   m68k: implement risugen module
>>   m68k: implement server and client side
>>   m68k: add risufile with m68k instructions.
>>   m68k: add instruction needing an extended word
>>   m68k: manage memory block
> 
> Thanks for this; I think patches 1-3 are good, and have
> applied them to risu master. For 4 I wonder if we can
> find a better way of handling variable-length instruction
> sets than !post, and I haven't yet looked at 5.

I think it should be possible but I don't know perl well enough to
propose a better solution.

Thanks,
Laurent

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 0/5] risu: add m68k target support
  2017-02-10 15:33   ` Laurent Vivier
@ 2017-02-10 17:32     ` Peter Maydell
  2017-02-10 17:37       ` Peter Maydell
  0 siblings, 1 reply; 12+ messages in thread
From: Peter Maydell @ 2017-02-10 17:32 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: QEMU Developers, Nikunj A Dadhania

On 10 February 2017 at 15:33, Laurent Vivier <laurent@vivier.eu> wrote:
> Le 10/02/2017 à 16:25, Peter Maydell a écrit :
>> Thanks for this; I think patches 1-3 are good, and have
>> applied them to risu master. For 4 I wonder if we can
>> find a better way of handling variable-length instruction
>> sets than !post, and I haven't yet looked at 5.
>
> I think it should be possible but I don't know perl well enough to
> propose a better solution.

Yeah; I'll have a think about it.

I got bored with the repetition between all the CPU backends,
by the way, so I've created a risugen_common.pm and moved
a bunch of the identical utility functions too it. (We can
probably share more, but this seemed like a good start.)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 0/5] risu: add m68k target support
  2017-02-10 17:32     ` Peter Maydell
@ 2017-02-10 17:37       ` Peter Maydell
  0 siblings, 0 replies; 12+ messages in thread
From: Peter Maydell @ 2017-02-10 17:37 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: QEMU Developers, Nikunj A Dadhania

On 10 February 2017 at 17:32, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 10 February 2017 at 15:33, Laurent Vivier <laurent@vivier.eu> wrote:
>> Le 10/02/2017 à 16:25, Peter Maydell a écrit :
>>> Thanks for this; I think patches 1-3 are good, and have
>>> applied them to risu master. For 4 I wonder if we can
>>> find a better way of handling variable-length instruction
>>> sets than !post, and I haven't yet looked at 5.
>>
>> I think it should be possible but I don't know perl well enough to
>> propose a better solution.
>
> Yeah; I'll have a think about it.
>
> I got bored with the repetition between all the CPU backends,
> by the way, so I've created a risugen_common.pm and moved
> a bunch of the identical utility functions too it. (We can
> probably share more, but this seemed like a good start.)

PS: I've been just writing and pushing code because this is
just a test program and it doesn't seem like it merits the
overhead of getting my own patches codereviewed here; but
if people would prefer to see the changes I make here first
let me know.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 2/5] m68k: implement server and client side
  2017-02-07 18:33 ` [Qemu-devel] [PATCH 2/5] m68k: implement server and client side Laurent Vivier
@ 2017-02-18 22:37   ` Peter Maydell
  2017-02-19 11:01     ` Laurent Vivier
  0 siblings, 1 reply; 12+ messages in thread
From: Peter Maydell @ 2017-02-18 22:37 UTC (permalink / raw)
  To: Laurent Vivier; +Cc: QEMU Developers

On 7 February 2017 at 18:33, Laurent Vivier <laurent@vivier.eu> wrote:
> This also adds the basic test file and the configuration update.
>
> This implementation can only test instructions with values in register and
> no memory access.
>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>

Hi; I got round to setting up my machine with an m68k cross
compiler so I can at least compile-test the other target
architectures, and I noticed this code generates compiler
warnings:

> +/* reginfo_dump: print state to a stream, returns nonzero on success */
> +void reginfo_dump(struct reginfo *ri, int is_master)
> +{
> +    int i;
> +    if (is_master) {
> +        fprintf(stderr, "  pc            \e[1;101;37m0x%08x\e[0m\n",
> +                ri->pc);
> +    }
> +    fprintf(stderr, "\tPC: %08x\n", ri->gregs[R_PC]);
> +    fprintf(stderr, "\tPS: %04x\n", ri->gregs[R_PS]);
> +
> +    for (i = 0; i < 8; i++) {
> +        fprintf(stderr, "\tD%d: %8x\tA%d: %8x\n", i, ri->gregs[i],
> +                i, ri->gregs[i + 8]);
> +    }
> +
> +
> +    for (i = 0; i < 8; i++) {
> +        fprintf(stderr, "\tFP%d: %08x %08x %08x\n", i,
> +                ri->fpregs.f_fpregs[i * 3], ri->fpregs.f_fpregs[i * 3 + 1],
> +                ri->fpregs.f_fpregs[i * 3 + 2]);

/home/pm215/risu/risu_reginfo_m68k.c:95:37: warning: format ‘%x’
expects argument of type ‘unsigned int’, but argument 4 has type ‘int
*’ [-Wformat=]
         fprintf(stderr, "\tFP%d: %08x %08x %08x\n", i,
                                     ^

and similarly for the other 3 f_fpregs[] arguments here
and in the fprintf calls in reginfo_dump_mismatch().

Looking at the m68k sys/ucontext.h its definition of
struct fpregset is
#ifdef __mcoldfire__
  int f_fpregs[8][2];
#else
  int f_fpregs[8][3];
#endif

so it's a 2d array, not a 1d array.

Any suggestions for how to fix the code? The whole file
seems to treat f_fpregs as a 1d array...

thanks
-- PMM

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Qemu-devel] [PATCH 2/5] m68k: implement server and client side
  2017-02-18 22:37   ` Peter Maydell
@ 2017-02-19 11:01     ` Laurent Vivier
  0 siblings, 0 replies; 12+ messages in thread
From: Laurent Vivier @ 2017-02-19 11:01 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

Le 18/02/2017 à 23:37, Peter Maydell a écrit :
> On 7 February 2017 at 18:33, Laurent Vivier <laurent@vivier.eu> wrote:
>> This also adds the basic test file and the configuration update.
>>
>> This implementation can only test instructions with values in register and
>> no memory access.
>>
>> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> 
> Hi; I got round to setting up my machine with an m68k cross
> compiler so I can at least compile-test the other target
> architectures, and I noticed this code generates compiler
> warnings:
> 
>> +/* reginfo_dump: print state to a stream, returns nonzero on success */
>> +void reginfo_dump(struct reginfo *ri, int is_master)
>> +{
>> +    int i;
>> +    if (is_master) {
>> +        fprintf(stderr, "  pc            \e[1;101;37m0x%08x\e[0m\n",
>> +                ri->pc);
>> +    }
>> +    fprintf(stderr, "\tPC: %08x\n", ri->gregs[R_PC]);
>> +    fprintf(stderr, "\tPS: %04x\n", ri->gregs[R_PS]);
>> +
>> +    for (i = 0; i < 8; i++) {
>> +        fprintf(stderr, "\tD%d: %8x\tA%d: %8x\n", i, ri->gregs[i],
>> +                i, ri->gregs[i + 8]);
>> +    }
>> +
>> +
>> +    for (i = 0; i < 8; i++) {
>> +        fprintf(stderr, "\tFP%d: %08x %08x %08x\n", i,
>> +                ri->fpregs.f_fpregs[i * 3], ri->fpregs.f_fpregs[i * 3 + 1],
>> +                ri->fpregs.f_fpregs[i * 3 + 2]);
> 
> /home/pm215/risu/risu_reginfo_m68k.c:95:37: warning: format ‘%x’
> expects argument of type ‘unsigned int’, but argument 4 has type ‘int
> *’ [-Wformat=]
>          fprintf(stderr, "\tFP%d: %08x %08x %08x\n", i,
>                                      ^
> 
> and similarly for the other 3 f_fpregs[] arguments here
> and in the fprintf calls in reginfo_dump_mismatch().
> 
> Looking at the m68k sys/ucontext.h its definition of
> struct fpregset is
> #ifdef __mcoldfire__
>   int f_fpregs[8][2];
> #else
>   int f_fpregs[8][3];
> #endif
> 
> so it's a 2d array, not a 1d array.

In fact, in etch-m68k, there are two definitions of fpregset:

/usr/include/sys/ucontext.h

typedef struct fpregset
{
  int f_fpregs[8][3];
  int f_pcr;
  int f_psr;
  int f_fpiaddr;
} fpregset_t;

/usr/include/asm/ucontext.h

typedef struct fpregset {
        int f_fpcntl[3];
        int f_fpregs[8*3];
} fpregset_t;

This is the one used by the kernel:

arch/m68k/include/asm/ucontext.h

typedef struct fpregset {
        int f_fpcntl[3];
        int f_fpregs[8*3];
} fpregset_t;

In the past, as the one from sys/ucontext.h was not compatible with the
one from the kernel, I have updated my system to use the one from the
kernel.

But in debian unstable, we have now:

typedef struct fpregset
{
  int f_pcr;
  int f_psr;
  int f_fpiaddr;
#ifdef __mcoldfire__
  int f_fpregs[8][2];
#else
  int f_fpregs[8][3];
#endif
} fpregset_t;

And this is compatible with the kernel one.

So I'm going to update the RISU code to use the 2d array.

Thanks,
Laurent

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-02-19 11:02 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-07 18:33 [Qemu-devel] [PATCH 0/5] risu: add m68k target support Laurent Vivier
2017-02-07 18:33 ` [Qemu-devel] [PATCH 1/5] m68k: implement risugen module Laurent Vivier
2017-02-07 18:33 ` [Qemu-devel] [PATCH 2/5] m68k: implement server and client side Laurent Vivier
2017-02-18 22:37   ` Peter Maydell
2017-02-19 11:01     ` Laurent Vivier
2017-02-07 18:33 ` [Qemu-devel] [PATCH 3/5] m68k: add risufile with m68k instructions Laurent Vivier
2017-02-07 18:33 ` [Qemu-devel] [PATCH 4/5] m68k: add instruction needing an extended word Laurent Vivier
2017-02-07 18:33 ` [Qemu-devel] [PATCH 5/5] m68k: manage memory block Laurent Vivier
2017-02-10 15:25 ` [Qemu-devel] [PATCH 0/5] risu: add m68k target support Peter Maydell
2017-02-10 15:33   ` Laurent Vivier
2017-02-10 17:32     ` Peter Maydell
2017-02-10 17:37       ` Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.