* [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.