aboutsummaryrefslogtreecommitdiff
path: root/sim/testsuite/common
diff options
context:
space:
mode:
authorStan Shebs <shebs@codesourcery.com>1999-04-16 01:35:26 +0000
committerStan Shebs <shebs@codesourcery.com>1999-04-16 01:35:26 +0000
commitc906108c21474dfb4ed285bcc0ac6fe02cd400cc (patch)
treea0015aa5cedc19ccbab307251353a41722a3ae13 /sim/testsuite/common
parentcd946cff9ede3f30935803403f06f6ed30cad136 (diff)
downloadgdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.zip
gdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.tar.gz
gdb-c906108c21474dfb4ed285bcc0ac6fe02cd400cc.tar.bz2
Initial creation of sourceware repositorygdb-4_18-branchpoint
Diffstat (limited to 'sim/testsuite/common')
-rw-r--r--sim/testsuite/common/Make-common.in90
-rw-r--r--sim/testsuite/common/Makefile.in53
-rw-r--r--sim/testsuite/common/alu-n-tst.h260
-rw-r--r--sim/testsuite/common/alu-tst.c104
-rw-r--r--sim/testsuite/common/bits-gen.c319
-rw-r--r--sim/testsuite/common/bits-tst.c408
-rw-r--r--sim/testsuite/common/fpu-tst.c538
7 files changed, 1772 insertions, 0 deletions
diff --git a/sim/testsuite/common/Make-common.in b/sim/testsuite/common/Make-common.in
new file mode 100644
index 0000000..7afef4a
--- /dev/null
+++ b/sim/testsuite/common/Make-common.in
@@ -0,0 +1,90 @@
+AS_FOR_TARGET = `\
+ if [ -x ../../../gas/as-new ]; then \
+ echo ../../../gas/as-new ; \
+ else \
+ echo $(target_alias)-as ; \
+ fi`
+
+LD_FOR_TARGET = `\
+ if [ -x ../../../ld/ld-new ]; then \
+ echo ../../../ld/ld-new ; \
+ else \
+ echo $(target_alias)-ld ; \
+ fi`
+
+RUN_FOR_TARGET = `\
+ if [ -x ../../../sim/v850/run ]; then \
+ echo ../../../sim/v850/run ; \
+ else \
+ echo $(target_alias)-run ; \
+ fi`
+
+
+check: sanity $(TESTS)
+sanity:
+ @eval echo AS_FOR_TARGET=$(AS_FOR_TARGET)
+ @eval echo LD_FOR_TARGET=$(LD_FOR_TARGET)
+ @eval echo RUN_FOR_TARGET=$(RUN_FOR_TARGET)
+
+clean:
+ rm -f $(TESTS)
+ rm -f *.run *.o
+ rm -f core *.core
+
+# Rules for running the tests
+
+.SUFFIXES: .ok .run .hi .ko .ti
+.run.ok:
+ rm -f tmp-$* $*.hi
+ ulimit -t 5 ; \
+ $(RUN_FOR_TARGET) $(RUNFLAGS_FOR_TARGET) $*.run > tmp-$*
+ mv tmp-$* $*.ok
+.run.hi:
+ rm -f tmp-$* $*.hi diff-$*
+ ulimit -t 5 ; \
+ $(RUN_FOR_TARGET) $(RUNFLAGS_FOR_TARGET) $*.run > tmp-$*
+ echo 'Hello World!' | diff - tmp-$* > diff-$*
+ cat tmp-$* diff-$* > $*.hi
+.run.ko:
+ rm -f tmp-$* $*.ko
+ set +e ; \
+ ulimit -t 5 ; \
+ $(RUN_FOR_TARGET) $(RUNFLAGS_FOR_TARGET) $*.run > tmp-$* ; \
+ if [ $$? -eq 47 ] ; then \
+ exit 0 ; \
+ else \
+ exit 1 ; \
+ fi
+ mv tmp-$* $*.ko
+.run.ti:
+ rm -f tmp-$* $*.ti
+ set +e ; \
+ ulimit -t 5 ; \
+ $(RUN_FOR_TARGET) $(RUNFLAGS_FOR_TARGET) $(INTFLAGS_FOR_TARGET) $*.run > tmp-$*
+ test `cat tmp-$* | wc -l` -eq 10 < /dev/null
+ test `grep Tick tmp-$* | wc -l` -eq 10 < /dev/null
+ mv tmp-$* $*.ti
+
+
+# Rules for building the test
+# Preference is for obtaining the executable (.run) from a prebuilt image
+
+.SUFFIXES: .uue .s .S .run
+.uue.run:
+ head $* | grep $*.run > /dev/null
+ uudecode $*.uue
+.run.u:
+ uuencode < $*.run $*.run > $*.u
+.o.run:
+ $(LD_FOR_TARGET) $(LDFLAGS_FOR_TARGET) -o $*.run $*.o
+.s.o:
+ $(AS_FOR_TARGET) $(ASFLAGS_FOR_TARGET) -I$(srcdir) $(srcdir)/$*.s -o $*.o
+.S.o:
+ $(AS_FOR_TARGET) $(ASFLAGS_FOR_TARGET) -I$(srcdir) $(srcdir)/$*.S -o $*.o
+
+
+Makefile: Makefile.in config.status
+ $(SHELL) ./config.status
+
+config.status: configure
+ $(SHELL) ./config.status --recheck
diff --git a/sim/testsuite/common/Makefile.in b/sim/testsuite/common/Makefile.in
new file mode 100644
index 0000000..d088501
--- /dev/null
+++ b/sim/testsuite/common/Makefile.in
@@ -0,0 +1,53 @@
+CC=gcc
+CFLAGS = -Wall -Werror -I../../common -I../../../include -g
+default: check
+
+
+# Verify SIM-BITS
+
+check: bits32m0.ok bits32m31.ok bits64m0.ok bits64m63.ok
+all: bits32m0 bits32m31 bits64m0 bits64m63
+
+bits32m0.c: bits-gen bits-tst.c
+ ./bits-gen 32 0 big > tmp-bits32m0.c
+ cat bits-tst.c >> tmp-bits32m0.c
+ mv tmp-bits32m0.c bits32m0.c
+bits32m31.c: bits-gen bits-tst.c
+ ./bits-gen 32 31 little > tmp-bits32m31.c
+ cat bits-tst.c >> tmp-bits32m31.c
+ mv tmp-bits32m31.c bits32m31.c
+bits64m0.c: bits-gen bits-tst.c
+ ./bits-gen 64 0 big > tmp-bits64m0.c
+ cat bits-tst.c >> tmp-bits64m0.c
+ mv tmp-bits64m0.c bits64m0.c
+bits64m63.c: bits-gen bits-tst.c
+ ./bits-gen 64 63 little > tmp-bits64m63.c
+ cat bits-tst.c >> tmp-bits64m63.c
+ mv tmp-bits64m63.c bits64m63.c
+
+
+
+# Verify SIM-FPU
+#
+#check: fpu-tst.ok
+#all: fpu-tst
+
+
+
+# Verify SIM-ALU
+
+check: alu-tst.ok
+all: alu-tst
+alu-tst.o: alu-tst.c alu-n-tst.h
+
+clean:
+ rm -f *.o
+ rm -f *.ok
+ rm -f bits32m0 bits32m31 bits64m0 bits64m63 bits-gen
+ rm -f tmp-*
+ rm -f alu-tst
+
+.SUFIXES: .ok
+%.ok: %
+ ./$<
+ touch $<.ok
diff --git a/sim/testsuite/common/alu-n-tst.h b/sim/testsuite/common/alu-n-tst.h
new file mode 100644
index 0000000..cd218d4
--- /dev/null
+++ b/sim/testsuite/common/alu-n-tst.h
@@ -0,0 +1,260 @@
+#ifndef N
+#error "N must be #defined"
+#endif
+
+#include "symcat.h"
+
+/* NOTE: see end of file for #undef of these macros */
+#define unsignedN XCONCAT2(unsigned,N)
+#define MAX_INT XCONCAT2(MAX_INT,N)
+#define MIN_INT XCONCAT2(MIN_INT,N)
+#define alu_N_tests XCONCAT3(alu_,N,_tests)
+#define do_alu_N_tests XCONCAT3(do_alu_,N,_tests)
+#define OP_BEGIN XCONCAT3(ALU,N,_BEGIN)
+#define OP_ADDC XCONCAT3(ALU,N,_ADDC)
+#define OP_ADDC_C XCONCAT3(ALU,N,_ADDC_C)
+#define OP_SUBC XCONCAT3(ALU,N,_SUBC)
+#define OP_SUBB XCONCAT3(ALU,N,_SUBB)
+#define OP_SUBB_B XCONCAT3(ALU,N,_SUBB_B)
+#define OP_SUBC_X XCONCAT3(ALU,N,_SUBC_X)
+#define OP_NEGC XCONCAT3(ALU,N,_NEGC)
+#define OP_NEGB XCONCAT3(ALU,N,_NEGB)
+#define HAD_CARRY_BORROW (XCONCAT3(ALU,N,_HAD_CARRY_BORROW) != 0)
+#define HAD_OVERFLOW (XCONCAT3(ALU,N,_HAD_OVERFLOW) != 0)
+#define RESULT XCONCAT3(ALU,N,_RESULT)
+#define CARRY_BORROW_RESULT XCONCAT3(ALU,N,_CARRY_BORROW_RESULT)
+#define OVERFLOW_RESULT XCONCAT3(ALU,N,_OVERFLOW_RESULT)
+#define do_op_N XCONCAT2(do_op_,N)
+
+
+void
+do_op_N (const alu_test *tst)
+{
+ const alu_op *op;
+ int borrow_p = 0;
+ OP_BEGIN (tst->begin);
+ print_hex (tst->begin, N);
+ for (op = tst->ops; op->op != NULL; op++)
+ {
+ printf (" %s ", op->op);
+ print_hex (op->arg, N);
+ if (strcmp (op->op, "ADDC") == 0)
+ OP_ADDC (op->arg);
+ else if (strcmp (op->op, "ADDC_C0") == 0)
+ OP_ADDC_C (op->arg, 0);
+ else if (strcmp (op->op, "ADDC_C1") == 0)
+ OP_ADDC_C (op->arg, 1);
+ else if (strcmp (op->op, "SUBC") == 0)
+ OP_SUBC (op->arg);
+ else if (strcmp (op->op, "SUBC_X0") == 0)
+ OP_SUBC_X (op->arg, 0);
+ else if (strcmp (op->op, "SUBC_X1") == 0)
+ OP_SUBC_X (op->arg, 1);
+ else if (strcmp (op->op, "SUBB") == 0)
+ {
+ OP_SUBB (op->arg);
+ borrow_p ++;
+ }
+ else if (strcmp (op->op, "SUBB_B0") == 0)
+ {
+ OP_SUBB_B (op->arg, 0);
+ borrow_p ++;
+ }
+ else if (strcmp (op->op, "SUBB_B1") == 0)
+ {
+ OP_SUBB_B (op->arg, 1);
+ borrow_p ++;
+ }
+ else if (strcmp (op->op, "NEGC") == 0)
+ OP_NEGC ();
+ else if (strcmp (op->op, "NEGB") == 0)
+ {
+ OP_NEGB ();
+ borrow_p ++;
+ }
+ else
+ {
+ printf (" -- operator unknown\n");
+ abort ();
+ }
+ }
+ printf (" = ");
+ print_hex (tst->result, N);
+ if (borrow_p)
+ printf (" B:%d", tst->carry_borrow);
+ else
+ printf (" C:%d", tst->carry_borrow);
+ printf (" V:%d", tst->overflow);
+ if (tst->carry_borrow != HAD_CARRY_BORROW)
+ {
+ if (borrow_p)
+ printf (" -- borrow (%d) wrong", HAD_CARRY_BORROW);
+ else
+ printf (" -- carry (%d) wrong", HAD_CARRY_BORROW);
+ errors ++;
+ }
+ if (tst->overflow != HAD_OVERFLOW)
+ {
+ printf (" -- overflow (%d) wrong", HAD_OVERFLOW);
+ errors ++;
+ }
+ if ((unsignedN) CARRY_BORROW_RESULT != (unsignedN) tst->result)
+ {
+ printf (" -- result for carry/borrow wrong ");
+ print_hex (CARRY_BORROW_RESULT, N);
+ errors ++;
+ }
+ if ((unsignedN) OVERFLOW_RESULT != (unsignedN) tst->result)
+ {
+ printf (" -- result for overflow wrong ");
+ print_hex (OVERFLOW_RESULT, N);
+ errors ++;
+ }
+ if ((unsignedN) RESULT != (unsignedN) tst->result)
+ {
+ printf (" -- result wrong ");
+ print_hex (RESULT, N);
+ errors ++;
+ }
+ printf ("\n");
+}
+
+
+const alu_test alu_N_tests[] = {
+
+ /* 0 + 0; 0 + 1; 1 + 0; 1 + 1 */
+ { 0, { { "ADDC", 0 }, }, 0, 0, 0, },
+ { 0, { { "ADDC", 1 }, }, 1, 0, 0, },
+ { 1, { { "ADDC", 0 }, }, 1, 0, 0, },
+ { 1, { { "ADDC", 1 }, }, 2, 0, 0, },
+
+ /* 0 + 0 + 0; 0 + 0 + 1; 0 + 1 + 0; 0 + 1 + 1 */
+ /* 1 + 0 + 0; 1 + 0 + 1; 1 + 1 + 0; 1 + 1 + 1 */
+ { 0, { { "ADDC_C0", 0 }, }, 0, 0, 0, },
+ { 0, { { "ADDC_C0", 1 }, }, 1, 0, 0, },
+ { 0, { { "ADDC_C1", 0 }, }, 1, 0, 0, },
+ { 0, { { "ADDC_C1", 1 }, }, 2, 0, 0, },
+ { 1, { { "ADDC_C0", 0 }, }, 1, 0, 0, },
+ { 1, { { "ADDC_C0", 1 }, }, 2, 0, 0, },
+ { 1, { { "ADDC_C1", 0 }, }, 2, 0, 0, },
+ { 1, { { "ADDC_C1", 1 }, }, 3, 0, 0, },
+
+ /* */
+ { MAX_INT, { { "ADDC", 1 }, }, MIN_INT, 0, 1, },
+ { MIN_INT, { { "ADDC", -1 }, }, MAX_INT, 1, 1, },
+ { MAX_INT, { { "ADDC", MIN_INT }, }, -1, 0, 0, },
+ { MIN_INT, { { "ADDC", MAX_INT }, }, -1, 0, 0, },
+ { MAX_INT, { { "ADDC", MAX_INT }, }, MAX_INT << 1, 0, 1, },
+ { MIN_INT, { { "ADDC", MIN_INT }, }, 0, 1, 1, },
+ /* */
+ { 0, { { "ADDC_C1", -1 }, }, 0, 1, 0, },
+ { 0, { { "ADDC_C1", -2 }, }, -1, 0, 0, },
+ { -1, { { "ADDC_C1", 0 }, }, 0, 1, 0, },
+ { 0, { { "ADDC_C0", 0 }, }, 0, 0, 0, },
+ { -1, { { "ADDC_C1", -1 }, }, -1, 1, 0, },
+ { -1, { { "ADDC_C1", 1 }, }, 1, 1, 0, },
+ { 0, { { "ADDC_C1", MAX_INT }, }, MIN_INT, 0, 1, },
+ { MAX_INT, { { "ADDC_C1", 1 }, }, MIN_INT + 1, 0, 1, },
+ { MAX_INT, { { "ADDC_C1", MIN_INT }, }, 0, 1, 0, },
+ { MAX_INT, { { "ADDC_C1", MAX_INT }, }, (MAX_INT << 1) + 1, 0, 1, },
+ { MAX_INT, { { "ADDC_C0", MAX_INT }, }, MAX_INT << 1, 0, 1, },
+
+ /* 0 - 0 */
+ { 0, { { "SUBC", 0 }, }, 0, 1, 0, },
+ { 0, { { "SUBB", 0 }, }, 0, 0, 0, },
+
+ /* 0 - 1 */
+ { 0, { { "SUBC", 1 }, }, -1, 0, 0, },
+ { 0, { { "SUBB", 1 }, }, -1, 1, 0, },
+
+ /* 1 - 0 */
+ { 1, { { "SUBC", 0 }, }, 1, 1, 0, },
+ { 1, { { "SUBB", 0 }, }, 1, 0, 0, },
+
+ /* 1 - 1 */
+ { 1, { { "SUBC", 1 }, }, 0, 1, 0, },
+ { 1, { { "SUBB", 1 }, }, 0, 0, 0, },
+
+ /* 0 - 0 - 0 */
+ { 0, { { "SUBC_X0", 0 }, }, -1, 0, 0, },
+ { 0, { { "SUBB_B0", 0 }, }, 0, 0, 0, },
+
+ /* 0 - 0 - 1 */
+ { 0, { { "SUBC_X0", 1 }, }, -2, 0, 0, },
+ { 0, { { "SUBB_B0", 1 }, }, -1, 1, 0, },
+
+ /* 0 - 1 - 0 */
+ { 0, { { "SUBC_X1", 0 }, }, 0, 1, 0, },
+ { 0, { { "SUBB_B1", 0 }, }, -1, 1, 0, },
+
+ /* 0 - 1 - 1 */
+ { 0, { { "SUBC_X1", 1 }, }, -1, 0, 0, },
+ { 0, { { "SUBB_B1", 1 }, }, -2, 1, 0, },
+
+ /* 1 - 0 - 0 */
+ { 1, { { "SUBC_X0", 0 }, }, 0, 1, 0, },
+ { 1, { { "SUBB_B0", 0 }, }, 1, 0, 0, },
+
+ /* 1 - 0 - 1 */
+ { 1, { { "SUBC_X0", 1 }, }, -1, 0, 0, },
+ { 1, { { "SUBB_B0", 1 }, }, 0, 0, 0, },
+
+ /* 1 - 1 - 0 */
+ { 1, { { "SUBC_X1", 0 }, }, 1, 1, 0, },
+ { 1, { { "SUBB_B1", 0 }, }, 0, 0, 0, },
+
+ /* 1 - 1 - 1 */
+ { 1, { { "SUBC_X1", 1 }, }, 0, 1, 0, },
+ { 1, { { "SUBB_B1", 1 }, }, -1, 1, 0, },
+
+ /* */
+ { 0, { { "SUBC", MIN_INT }, }, MIN_INT, 0, 1, },
+ { MIN_INT, { { "SUBC", 1 }, }, MAX_INT, 1, 1, },
+ { MAX_INT, { { "SUBC", MAX_INT }, }, 0, 1, 0, },
+
+ /* */
+ { 0, { { "SUBC_X0", MIN_INT }, }, MAX_INT, 0, 0, },
+ { MIN_INT, { { "SUBC_X1", 0 }, }, MIN_INT, 1, 0, },
+ { MAX_INT, { { "SUBC_X0", MAX_INT }, }, -1, 0, 0, },
+
+ /* */
+ { MAX_INT, { { "NEGC", 0 }, }, MIN_INT + 1, 0, 0, },
+ { MAX_INT, { { "NEGC", 0 }, }, MIN_INT + 1, 0, 0, },
+ { MIN_INT, { { "NEGC", 0 }, }, MIN_INT, 0, 1, },
+ { 0, { { "NEGC", 0 }, }, 0, 1, 0, },
+ { -1, { { "NEGC", 0 }, }, 1, 0, 0, },
+ { 1, { { "NEGC", 0 }, }, -1, 0, 0, },
+};
+
+
+static void
+do_alu_N_tests (void)
+{
+ int i;
+ for (i = 0; i < sizeof (alu_N_tests) / sizeof (*alu_N_tests); i++)
+ {
+ const alu_test *tst = &alu_N_tests[i];
+ do_op_N (tst);
+ }
+}
+
+
+#undef OP_BEGIN
+#undef OP_ADDC
+#undef OP_ADDC_C
+#undef OP_SUBB
+#undef OP_SUBC
+#undef OP_SUBC_X
+#undef OP_SUBB_B
+#undef HAD_OVERFLOW
+#undef HAD_CARRY_BORROW
+#undef OVERFLOW_RESULT
+#undef CARRY_BORROW_RESULT
+#undef RESULT
+#undef do_op_N
+#undef unsignedN
+#undef MAX_INT
+#undef MIN_INT
+#undef alu_N_tests
+#undef do_alu_N_tests
+
diff --git a/sim/testsuite/common/alu-tst.c b/sim/testsuite/common/alu-tst.c
new file mode 100644
index 0000000..e7fffe5
--- /dev/null
+++ b/sim/testsuite/common/alu-tst.c
@@ -0,0 +1,104 @@
+#define WITH_TARGET_WORD_MSB 0
+#define WITH_TARGET_WORD_BITSIZE 64
+#define WITH_HOST_WORD_BITSIZE (sizeof (int) * 8)
+#define WITH_TARGET_BYTE_ORDER BIG_ENDIAN /* does not matter */
+
+#define ASSERT(EXPRESSION) \
+{ \
+ if (!(EXPRESSION)) { \
+ fprintf (stderr, "%s:%d: assertion failed - %s\n", \
+ __FILE__, __LINE__, #EXPRESSION); \
+ abort (); \
+ } \
+}
+
+#define SIM_BITS_INLINE (INCLUDE_MODULE | INCLUDED_BY_MODULE)
+
+#include <string.h>
+
+#include "sim-basics.h"
+
+#include "sim-alu.h"
+
+#include <stdio.h>
+
+typedef struct {
+ char *op;
+ unsigned64 arg;
+} alu_op;
+
+typedef struct {
+ unsigned64 begin;
+ alu_op ops[4];
+ unsigned64 result;
+ int carry_borrow;
+ int overflow;
+} alu_test;
+
+#define MAX_INT8 UNSIGNED64 (127)
+#define MIN_INT8 UNSIGNED64 (128)
+
+#define MAX_INT16 UNSIGNED64 (32767)
+#define MIN_INT16 UNSIGNED64 (32768)
+
+#define MAX_INT32 UNSIGNED64 (0x7fffffff)
+#define MIN_INT32 UNSIGNED64 (0x80000000)
+
+#define MAX_INT64 UNSIGNED64 (0x7fffffffffffffff)
+#define MIN_INT64 UNSIGNED64 (0x8000000000000000)
+
+static void
+print_hex (unsigned64 val, int nr_bits)
+{
+ switch (nr_bits)
+ {
+ case 8:
+ printf ("0x%02lx", (long) (unsigned8) (val));
+ break;
+ case 16:
+ printf ("0x%04lx", (long) (unsigned16) (val));
+ break;
+ case 32:
+ printf ("0x%08lx", (long) (unsigned32) (val));
+ break;
+ case 64:
+ printf ("0x%08lx%08lx",
+ (long) (unsigned32) (val >> 32),
+ (long) (unsigned32) (val));
+ break;
+ default:
+ abort ();
+ }
+}
+
+
+int errors = 0;
+
+
+#define N 8
+#include "alu-n-tst.h"
+#undef N
+
+#define N 16
+#include "alu-n-tst.h"
+#undef N
+
+#define N 32
+#include "alu-n-tst.h"
+#undef N
+
+#define N 64
+#include "alu-n-tst.h"
+#undef N
+
+
+
+int
+main ()
+{
+ do_alu_8_tests ();
+ do_alu_16_tests ();
+ do_alu_32_tests ();
+ do_alu_64_tests ();
+ return (errors != 0);
+}
diff --git a/sim/testsuite/common/bits-gen.c b/sim/testsuite/common/bits-gen.c
new file mode 100644
index 0000000..71ddef3
--- /dev/null
+++ b/sim/testsuite/common/bits-gen.c
@@ -0,0 +1,319 @@
+/* Miscellaneous simulator utilities.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ Contributed by Cygnus Support.
+
+This file is part of GDB, the GNU debugger.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#include <stdio.h>
+
+
+void
+gen_struct (void)
+{
+ printf ("\n");
+ printf ("typedef struct _test_tuples {\n");
+ printf (" int line;\n");
+ printf (" int row;\n");
+ printf (" int col;\n");
+ printf (" long long val;\n");
+ printf (" long long check;\n");
+ printf ("} test_tuples;\n");
+ printf ("\n");
+ printf ("typedef struct _test_spec {\n");
+ printf (" const char *file;\n");
+ printf (" const char *macro;\n");
+ printf (" int nr_rows;\n");
+ printf (" int nr_cols;\n");
+ printf (" test_tuples *tuples;\n");
+ printf ("} test_spec;\n");
+}
+
+
+void
+gen_bit (int bitsize,
+ int msb,
+ const char *macro,
+ int nr_bits)
+{
+ int i;
+
+ printf ("\n/* Test the %s macro */\n", macro);
+ printf ("test_tuples %s_tuples[%d] = {\n", macro, nr_bits);
+ for (i = 0; i < nr_bits; i++)
+ {
+ /* compute what we think the value is */
+ unsigned long long bit = 1;
+ if (msb == 0)
+ bit <<= nr_bits - i - 1;
+ else
+ bit <<= i;
+ if (bitsize == 32)
+ bit = (unsigned) bit; /* truncate it! */
+ /* write it out */
+ printf (" { __LINE__, ");
+ printf ("%d, %2d, ", -1, i);
+ printf ("%s (%2d), ", macro, i);
+ printf ("UNSIGNED64 (0x%08lx%08lx), ",
+ (long) (bit >> 32), (long) bit);
+ printf ("},\n");
+ }
+ printf ("};\n");
+ printf ("\n");
+ printf ("test_spec %s_test = { __FILE__, \"%s\", 1, %d, %s_tuples, };\n",
+ macro, macro, nr_bits, macro);
+ printf ("\n");
+}
+
+
+void
+gen_enum (const char *macro,
+ int nr_bits)
+{
+ int i;
+
+ printf ("\n/* Test the %s macro in an enum */\n", macro);
+ printf ("enum enum_%s {\n", macro);
+ for (i = 0; i < nr_bits; i++)
+ {
+ printf (" elem_%s_%d = %s (%d),\n", macro, i, macro, i);
+ }
+ printf ("};\n");
+ printf ("\n");
+}
+
+
+void
+gen_mask (int bitsize,
+ const char *msb,
+ const char *macro,
+ int nr_bits)
+{
+ int l;
+ int h;
+ printf ("\n/* Test the %s%s macro */\n", msb, macro);
+ printf ("test_tuples %s_tuples[%d][%d] = {\n", macro, nr_bits, nr_bits);
+ for (l = 0; l < nr_bits; l++)
+ {
+ printf (" {\n");
+ for (h = 0; h < nr_bits; h++)
+ {
+ printf (" { __LINE__, ");
+ if ((strcmp (msb, "MS") == 0 && l <= h)
+ || (strcmp (msb, "MS") != 0 && l >= h)
+ || (strcmp (macro, "") == 0))
+ {
+ /* compute the mask */
+ unsigned long long mask = 0;
+ int b;
+ for (b = 0; b < nr_bits; b++)
+ {
+ unsigned long long bit = 1;
+ if (strcmp (msb, "MS") == 0)
+ {
+ if ((l <= b && b <= h)
+ || (h < l && (b <= h || b >= l)))
+ bit <<= (nr_bits - b - 1);
+ else
+ bit = 0;
+ }
+ else
+ {
+ if ((l >= b && b >= h)
+ || (h > l && (b >= h || b <= l)))
+ bit <<= b;
+ else
+ bit = 0;
+ }
+ mask |= bit;
+ }
+ if (bitsize == 32)
+ mask = (unsigned long) mask;
+ printf ("%d, %d, ", l, h);
+ printf ("%s%s (%2d, %2d), ", msb, macro, l, h);
+ printf ("UNSIGNED64 (0x%08lx%08lx), ",
+ (long) (mask >> 32), (long) mask);
+ }
+ else
+ printf ("-1, -1, ");
+ printf ("},\n");
+ }
+ printf (" },\n");
+ }
+ printf ("};\n");
+ printf ("\n");
+ printf ("test_spec %s_test = { __FILE__, \"%s%s\", %d, %d, &%s_tuples[0][0], };\n",
+ macro, msb, macro, nr_bits, nr_bits, macro);
+ printf ("\n");
+}
+
+
+void
+usage (int reason)
+{
+ fprintf (stderr, "Usage:\n");
+ fprintf (stderr, " bits-gen <nr-bits> <msb> <byte-order>\n");
+ fprintf (stderr, "Generate a test case for the simulator bit manipulation code\n");
+ fprintf (stderr, " <nr-bits> = { 32 | 64 }\n");
+ fprintf (stderr, " <msb> = { 0 | { 31 | 63 } }\n");
+ fprintf (stderr, " <byte-order> = { big | little }\n");
+
+ switch (reason)
+ {
+ case 1: fprintf (stderr, "Wrong number of arguments\n");
+ break;
+ case 2:
+ fprintf (stderr, "Invalid <nr-bits> argument\n");
+ break;
+ case 3:
+ fprintf (stderr, "Invalid <msb> argument\n");
+ break;
+ case 4:
+ fprintf (stderr, "Invalid <byte-order> argument\n");
+ break;
+ default:
+ }
+
+ exit (1);
+}
+
+
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int bitsize;
+ int msb;
+ char *ms;
+ int big_endian;
+
+ if (argc != 4)
+ usage (1);
+
+ if (strcmp (argv [1], "32") == 0)
+ bitsize = 32;
+ else if (strcmp (argv [1], "64") == 0)
+ bitsize = 64;
+ else
+ usage (2);
+
+ if (strcmp (argv [2], "0") == 0)
+ msb = 0;
+ else if (strcmp (argv [2], "31") == 0 && bitsize == 32)
+ msb = 31;
+ else if (strcmp (argv [2], "63") == 0 && bitsize == 64)
+ msb = 63;
+ else
+ usage (3);
+ if (msb == 0)
+ ms = "MS";
+ else
+ ms = "LS";
+
+ if (strcmp (argv [3], "big") == 0)
+ big_endian = 1;
+ else if (strcmp (argv [3], "little") == 0)
+ big_endian = 0;
+ else
+ usage (4);
+
+ printf ("#define WITH_TARGET_WORD_BITSIZE %d\n", bitsize);
+ printf ("#define WITH_TARGET_WORD_MSB %d\n", msb);
+ printf ("#define WITH_HOST_WORD_BITSIZE %d\n", sizeof (int) * 8);
+ printf ("#define WITH_TARGET_BYTE_ORDER %s\n", big_endian ? "BIG_ENDIAN" : "LITTLE_ENDIAN");
+ printf ("\n");
+ printf ("#define SIM_BITS_INLINE (ALL_H_INLINE)\n");
+ printf ("\n");
+ printf ("#define ASSERT(X) do { if (!(X)) abort(); } while (0)\n");
+ printf ("\n");
+ printf ("#include \"sim-basics.h\"\n");
+
+ gen_struct ();
+
+
+
+ printf ("#define DO_BIT_TESTS\n");
+ gen_bit ( 4, msb, "BIT4", 4);
+ gen_bit ( 5, msb, "BIT5", 5);
+ gen_bit ( 8, msb, "BIT8", 8);
+ gen_bit (10, msb, "BIT10", 10);
+ gen_bit (16, msb, "BIT16", 16);
+ gen_bit (32, msb, "BIT32", 32);
+ gen_bit (64, msb, "BIT64", 64);
+ gen_bit (bitsize, msb, "BIT", 64);
+
+ gen_bit ( 8, 8 - 1, "LSBIT8", 8);
+ gen_bit (16, 16 - 1, "LSBIT16", 16);
+ gen_bit (32, 32 - 1, "LSBIT32", 32);
+ gen_bit (64, 64 - 1, "LSBIT64", 64);
+ gen_bit (bitsize, bitsize - 1, "LSBIT", 64);
+
+ gen_bit ( 8, 0, "MSBIT8", 8);
+ gen_bit (16, 0, "MSBIT16", 16);
+ gen_bit (32, 0, "MSBIT32", 32);
+ gen_bit (64, 0, "MSBIT64", 64);
+ gen_bit (bitsize, 0, "MSBIT", 64);
+
+ printf ("test_spec *(bit_tests[]) = {\n");
+ printf (" &BIT4_test,\n");
+ printf (" &BIT5_test,\n");
+ printf (" &BIT8_test,\n");
+ printf (" &BIT10_test,\n");
+ printf (" &BIT16_test,\n");
+ printf (" &BIT32_test,\n");
+ printf (" &BIT64_test,\n");
+ printf (" &BIT_test,\n");
+ printf (" &LSBIT8_test,\n");
+ printf (" &LSBIT16_test,\n");
+ printf (" &LSBIT32_test,\n");
+ printf (" &LSBIT64_test,\n");
+ printf (" &LSBIT_test,\n");
+ printf (" &MSBIT8_test,\n");
+ printf (" &MSBIT16_test,\n");
+ printf (" &MSBIT32_test,\n");
+ printf (" &MSBIT64_test,\n");
+ printf (" &MSBIT_test,\n");
+ printf (" 0,\n");
+ printf ("};\n\n");
+
+ gen_enum ("BIT", 64);
+ gen_enum ("LSBIT", 64);
+ gen_enum ("MSBIT", 64);
+ gen_enum ("BIT32", 32);
+ gen_enum ("LSBIT32", 32);
+ gen_enum ("MSBIT32", 32);
+
+ printf ("#define DO_MASK_TESTS\n");
+ gen_mask ( 8, ms, "MASK8", 8);
+ gen_mask (16, ms, "MASK16", 16);
+ gen_mask (32, ms, "MASK32", 32);
+ gen_mask (64, ms, "MASK64", 64);
+ gen_mask (bitsize, ms, "MASK", 64);
+
+ printf ("test_spec *(mask_tests[]) = {\n");
+ printf (" &MASK8_test,\n");
+ printf (" &MASK16_test,\n");
+ printf (" &MASK32_test,\n");
+ printf (" &MASK64_test,\n");
+ printf (" &MASK_test,\n");
+ printf (" 0,\n");
+ printf ("};\n\n");
+
+ return 0;
+}
diff --git a/sim/testsuite/common/bits-tst.c b/sim/testsuite/common/bits-tst.c
new file mode 100644
index 0000000..5a4210a
--- /dev/null
+++ b/sim/testsuite/common/bits-tst.c
@@ -0,0 +1,408 @@
+# 2 "bits-tst.c"
+
+/* Drive the bit test routines */
+
+
+long long
+calc (const char *call,
+ long long val,
+ int row,
+ int col)
+{
+ if (strcmp (call, "MASK") == 0)
+ return MASKED (val, row, col);
+ if (strcmp (call, "MASK8") == 0)
+ return MASKED8 (val, row, col);
+ if (strcmp (call, "MASK16") == 0)
+ return MASKED16 (val, row, col);
+ if (strcmp (call, "MASK32") == 0)
+ return MASKED32 (val, row, col);
+ if (strcmp (call, "MASK64") == 0)
+ return MASKED64 (val, row, col);
+
+ if (strcmp (call, "EXTRACT") == 0)
+ return EXTRACTED (val, row, col);
+ if (strcmp (call, "EXTRACT8") == 0)
+ return EXTRACTED8 (val, row, col);
+ if (strcmp (call, "EXTRACT16") == 0)
+ return EXTRACTED16 (val, row, col);
+ if (strcmp (call, "EXTRACT32") == 0)
+ return EXTRACTED32 (val, row, col);
+ if (strcmp (call, "EXTRACT64") == 0)
+ return EXTRACTED64 (val, row, col);
+
+ if (strcmp (call, "LSEXTRACT") == 0)
+ return LSEXTRACTED (val, row, col);
+ if (strcmp (call, "LSEXTRACT8") == 0)
+ return LSEXTRACTED8 (val, row, col);
+ if (strcmp (call, "LSEXTRACT16") == 0)
+ return LSEXTRACTED16 (val, row, col);
+ if (strcmp (call, "LSEXTRACT32") == 0)
+ return LSEXTRACTED32 (val, row, col);
+ if (strcmp (call, "LSEXTRACT64") == 0)
+ return LSEXTRACTED64 (val, row, col);
+
+ if (strcmp (call, "MSEXTRACT") == 0)
+ return MSEXTRACTED (val, row, col);
+ if (strcmp (call, "MSEXTRACT8") == 0)
+ return MSEXTRACTED8 (val, row, col);
+ if (strcmp (call, "MSEXTRACT16") == 0)
+ return MSEXTRACTED16 (val, row, col);
+ if (strcmp (call, "MSEXTRACT32") == 0)
+ return MSEXTRACTED32 (val, row, col);
+ if (strcmp (call, "MSEXTRACT64") == 0)
+ return MSEXTRACTED64 (val, row, col);
+
+ if (strcmp (call, "INSERT") == 0)
+ return INSERTED (val, row, col);
+ if (strcmp (call, "INSERT8") == 0)
+ return INSERTED8 (val, row, col);
+ if (strcmp (call, "INSERT16") == 0)
+ return INSERTED16 (val, row, col);
+ if (strcmp (call, "INSERT32") == 0)
+ return INSERTED32 (val, row, col);
+ if (strcmp (call, "INSERT64") == 0)
+ return INSERTED64 (val, row, col);
+
+ if (strcmp (call, "LSINSERT") == 0)
+ return LSINSERTED (val, row, col);
+ if (strcmp (call, "LSINSERT8") == 0)
+ return LSINSERTED8 (val, row, col);
+ if (strcmp (call, "LSINSERT16") == 0)
+ return LSINSERTED16 (val, row, col);
+ if (strcmp (call, "LSINSERT32") == 0)
+ return LSINSERTED32 (val, row, col);
+ if (strcmp (call, "LSINSERT64") == 0)
+ return LSINSERTED64 (val, row, col);
+
+ if (strcmp (call, "MSINSERT") == 0)
+ return MSINSERTED (val, row, col);
+ if (strcmp (call, "MSINSERT8") == 0)
+ return MSINSERTED8 (val, row, col);
+ if (strcmp (call, "MSINSERT16") == 0)
+ return MSINSERTED16 (val, row, col);
+ if (strcmp (call, "MSINSERT32") == 0)
+ return MSINSERTED32 (val, row, col);
+ if (strcmp (call, "MSINSERT64") == 0)
+ return MSINSERTED64 (val, row, col);
+
+ if (strcmp (call, "MSMASK") == 0)
+ return MSMASKED (val, row, col);
+ if (strcmp (call, "MSMASK8") == 0)
+ return MSMASKED8 (val, row, col);
+ if (strcmp (call, "MSMASK16") == 0)
+ return MSMASKED16 (val, row, col);
+ if (strcmp (call, "MSMASK32") == 0)
+ return MSMASKED32 (val, row, col);
+ if (strcmp (call, "MSMASK64") == 0)
+ return MSMASKED64 (val, row, col);
+
+ if (strcmp (call, "LSMASK") == 0)
+ return LSMASKED (val, row, col);
+ if (strcmp (call, "LSMASK8") == 0)
+ return LSMASKED8 (val, row, col);
+ if (strcmp (call, "LSMASK16") == 0)
+ return LSMASKED16 (val, row, col);
+ if (strcmp (call, "LSMASK32") == 0)
+ return LSMASKED32 (val, row, col);
+ if (strcmp (call, "LSMASK64") == 0)
+ return LSMASKED64 (val, row, col);
+
+ if (strcmp (call, "ROT64") == 0)
+ return ROT64 (val, col);
+ if (strcmp (call, "ROT8") == 0)
+ return ROT8 (val, col);
+ if (strcmp (call, "ROT16") == 0)
+ return ROT16 (val, col);
+ if (strcmp (call, "ROT32") == 0)
+ return ROT32 (val, col);
+
+ if (strcmp (call, "SEXT") == 0)
+ return SEXT (val, col);
+ if (strcmp (call, "SEXT8") == 0)
+ return SEXT8 (val, col);
+ if (strcmp (call, "SEXT16") == 0)
+ return SEXT16 (val, col);
+ if (strcmp (call, "SEXT32") == 0)
+ return SEXT32 (val, col);
+ if (strcmp (call, "SEXT64") == 0)
+ return SEXT64 (val, col);
+
+ if (strcmp (call, "LSSEXT") == 0)
+ return LSSEXT (val, col);
+ if (strcmp (call, "LSSEXT8") == 0)
+ return LSSEXT8 (val, col);
+ if (strcmp (call, "LSSEXT16") == 0)
+ return LSSEXT16 (val, col);
+ if (strcmp (call, "LSSEXT32") == 0)
+ return LSSEXT32 (val, col);
+ if (strcmp (call, "LSSEXT64") == 0)
+ return LSSEXT64 (val, col);
+
+ if (strcmp (call, "MSSEXT8") == 0)
+ return MSSEXT8 (val, col);
+ if (strcmp (call, "MSSEXT16") == 0)
+ return MSSEXT16 (val, col);
+ if (strcmp (call, "MSSEXT32") == 0)
+ return MSSEXT32 (val, col);
+ if (strcmp (call, "MSSEXT64") == 0)
+ return MSSEXT64 (val, col);
+ if (strcmp (call, "MSSEXT") == 0)
+ return MSSEXT (val, col);
+
+ else
+ {
+ fprintf (stderr,
+ "Unknown call passed to calc (%s, 0x%08lx%08lx, %d, %d)\n",
+ call, (long)(val >> 32), (long)val, row, col);
+ abort ();
+ return val;
+ }
+}
+
+
+int
+check_sext (int nr_bits,
+ int msb_nr,
+ const char *sexted,
+ const char *masked,
+ const char *msmasked)
+{
+ int errors = 0;
+ int col;
+ for (col = 0; col < nr_bits; col ++)
+ {
+ long long mask = calc (masked, -1, col, col);
+ long long msmask = calc (msmasked, -1,
+ 0, (msb_nr ? nr_bits - col - 1 : col));
+ long long sext = calc (sexted, mask, -1, col);
+ long long mask_1 = mask >> 1;
+ long long sext_1 = calc (sexted, mask_1, -1, col);
+ long long mask_0 = (mask << 1) | mask_1;
+ long long sext_0 = calc (sexted, mask_0, -1, col);
+ if (sext_0 != mask_1)
+ {
+ fprintf (stderr,
+ "%s:%d: ", __FILE__, __LINE__);
+ fprintf (stderr,
+ " %s(0x%08lx%08lx,%d) == 0x%08lx%08lx wrong, != 0x%08lx%08lx\n",
+ sexted, (long)(mask_0 >> 32), (long)mask_0, col,
+ (long)(sext_0 >> 32), (long)sext_0,
+ (long)(mask_1 >> 32), (long)mask_1);
+ errors ++;
+ }
+ if (sext_1 != mask_1)
+ {
+ fprintf (stderr,
+ "%s:%d: ", __FILE__, __LINE__);
+ fprintf (stderr,
+ " %s(0x%08lx%08lx,%d) == 0x%08lx%08lx wrong, != 0x%08lx%08lx\n",
+ sexted, (long)(mask_1 >> 32), (long)mask_1, col,
+ (long)(sext_1 >> 32), (long)sext_1,
+ (long)(mask_1 >> 32), (long)mask_1);
+ errors ++;
+ }
+ if (sext != msmask)
+ {
+ fprintf (stderr,
+ "%s:%d: ", __FILE__, __LINE__);
+ fprintf (stderr,
+ " %s(0x%08lx%08lx,%d) == 0x%08lx%08lx wrong, != 0x%08lx%08lx (%s(%d,%d))\n",
+ sexted, (long)(mask >> 32), (long)mask, col,
+ (long)(sext >> 32), (long)sext,
+ (long)(msmask >> 32), (long)msmask,
+ msmasked, 0, (msb_nr ? nr_bits - col - 1 : col));
+ errors ++;
+ }
+
+ }
+ return errors;
+}
+
+
+int
+check_rot (int nr_bits,
+ const char *roted,
+ const char *masked)
+{
+ int errors = 0;
+ int row;
+ int col;
+ for (row = 0; row < nr_bits; row++)
+ for (col = 0; col < nr_bits; col++)
+ if ((WITH_TARGET_WORD_MSB == 0 && row <= col)
+ || (WITH_TARGET_WORD_MSB != 0 && row >= col))
+ {
+ long long mask = calc (masked, -1, row, col);
+ int shift;
+ for (shift = -nr_bits + 1; shift < nr_bits; shift ++)
+ {
+ long long rot = calc (roted, mask, -1, shift);
+ long long urot = calc (roted, rot, -1, -shift);
+ if (mask != urot
+ || (shift == 0 && rot != mask)
+ || (shift != 0 && rot == mask && abs(row - col) != (nr_bits - 1)))
+ {
+ fprintf (stderr, "%s:%d: ", __FILE__, __LINE__);
+ fprintf (stderr, " %s(%s(0x%08lx%08lx,%d) == 0x%08lx%08lx, %d) failed\n",
+ roted, roted,
+ (long)(mask >> 32), (long)mask, shift,
+ (long)(urot >> 32), (long)urot, -shift);
+ errors ++;
+ }
+ }
+ }
+ return errors;
+}
+
+
+int
+check_extract (int nr_bits,
+ const char *extracted,
+ const char *inserted,
+ const char *masked)
+{
+ int errors = 0;
+ int row;
+ int col;
+ for (row = 0; row < nr_bits; row++)
+ for (col = 0; col < nr_bits; col ++)
+ if ((WITH_TARGET_WORD_MSB == 0 && row <= col)
+ || (WITH_TARGET_WORD_MSB != 0 && row >= col))
+ {
+ long long mask = calc (masked, -1, row, col);
+ long long extr = calc (extracted, mask, row, col);
+ long long inst = calc (inserted, extr, row, col);
+ if (mask != inst)
+ {
+ fprintf (stderr, "%s:%d: ", __FILE__, __LINE__);
+ fprintf (stderr, " %s(%d,%d)=0x%08lx%08lx -> %s=0x%08lx%08lx -> %s=0x%08lx%08lx failed\n",
+ masked, row, col, (long)(mask >> 32), (long)mask,
+ extracted, (long)(extr >> 32), (long)extr,
+ inserted, (long)(inst >> 32), (long)inst);
+ errors ++;
+ }
+ }
+ return errors;
+}
+
+
+int
+check_bits (int call,
+ test_spec **tests)
+{
+ int r;
+ int c;
+ int errors = 0;
+ while (*tests != NULL)
+ {
+ int nr_rows = (*tests)->nr_rows;
+ int nr_cols = (*tests)->nr_cols;
+ test_tuples *tuples = (*tests)->tuples;
+ for (r = 0; r < nr_rows; r++)
+ for (c = 0; c < nr_cols; c++)
+ {
+ int i = r * nr_rows + c;
+ test_tuples *tuple = &tuples[i];
+ if (tuple->col >= 0)
+ {
+ long long val = (!call ? tuple->val : calc ((*tests)->macro, -1,
+ tuple->row, tuple->col));
+ long long check = tuple->check;
+ if (val != check)
+ {
+ fprintf (stderr, "%s:%d:", (*tests)->file, tuple->line);
+ fprintf (stderr, " %s", (*tests)->macro);
+ if (tuple->row >= 0)
+ fprintf (stderr, " (%d, %d)", tuple->row, tuple->col);
+ else
+ fprintf (stderr, " (%d)", tuple->col);
+ fprintf (stderr, " == 0x%08lx%08lx wrong, != 0x%08lx%08lx\n",
+ (long) (val >> 32), (long) val,
+ (long) (check >> 32), (long) check);
+ errors ++;
+ }
+ }
+ }
+ tests ++;
+ }
+ return errors;
+}
+
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int errors = 0;
+
+
+#if defined (DO_BIT_TESTS)
+ printf ("Checking BIT*\n");
+ errors += check_bits (0, bit_tests);
+#endif
+
+
+#if defined (DO_MASK_TESTS)
+ printf ("Checking MASK*\n");
+ errors += check_bits (0, mask_tests);
+
+ printf ("Checking MASKED*\n");
+ errors += check_bits (1, mask_tests);
+#endif
+
+
+#if defined (DO_LSMASK_TESTS)
+ printf ("Checking LSMASK*\n");
+ errors += check_bits (0, lsmask_tests);
+
+ printf ("Checking LSMASKED*\n");
+ errors += check_bits (1, lsmask_tests);
+#endif
+
+
+#if defined (DO_MSMASK_TESTS)
+ printf ("Checking MSMASK*\n");
+ errors += check_bits (0, msmask_tests);
+
+ printf ("Checking MSMASKED*\n");
+ errors += check_bits (1, msmask_tests);
+#endif
+
+
+ printf ("Checking EXTRACTED*\n");
+ errors += check_extract ( 8, "EXTRACT8", "INSERT8", "MASK8");
+ errors += check_extract (16, "EXTRACT16", "INSERT16", "MASK16");
+ errors += check_extract (32, "EXTRACT32", "INSERT32", "MASK32");
+ errors += check_extract (64, "EXTRACT64", "INSERT64", "MASK64");
+ errors += check_extract (64, "EXTRACT", "INSERT", "MASK");
+
+ printf ("Checking SEXT*\n");
+ errors += check_sext ( 8, WITH_TARGET_WORD_MSB, "SEXT8", "MASK8", "MSMASK8");
+ errors += check_sext (16, WITH_TARGET_WORD_MSB, "SEXT16", "MASK16", "MSMASK16");
+ errors += check_sext (32, WITH_TARGET_WORD_MSB, "SEXT32", "MASK32", "MSMASK32");
+ errors += check_sext (64, WITH_TARGET_WORD_MSB, "SEXT64", "MASK64", "MSMASK64");
+ errors += check_sext (64, WITH_TARGET_WORD_MSB, "SEXT", "MASK", "MSMASK");
+
+ printf ("Checking LSSEXT*\n");
+ errors += check_sext ( 8, 8 - 1, "LSSEXT8", "LSMASK8", "MSMASK8");
+ errors += check_sext (16, 16 - 1, "LSSEXT16", "LSMASK16", "MSMASK16");
+ errors += check_sext (32, 32 - 1, "LSSEXT32", "LSMASK32", "MSMASK32");
+ errors += check_sext (64, 64 - 1, "LSSEXT64", "LSMASK64", "MSMASK64");
+ errors += check_sext (64, WITH_TARGET_WORD_BITSIZE - 1, "LSSEXT", "LSMASK", "MSMASK");
+
+ printf ("Checking MSSEXT*\n");
+ errors += check_sext (8, 0, "MSSEXT8", "MSMASK8", "MSMASK8");
+ errors += check_sext (16, 0, "MSSEXT16", "MSMASK16", "MSMASK16");
+ errors += check_sext (32, 0, "MSSEXT32", "MSMASK32", "MSMASK32");
+ errors += check_sext (64, 0, "MSSEXT64", "MSMASK64", "MSMASK64");
+ errors += check_sext (64, 0, "MSSEXT", "MSMASK", "MSMASK");
+
+ printf ("Checking ROT*\n");
+ errors += check_rot (16, "ROT16", "MASK16");
+ errors += check_rot (32, "ROT32", "MASK32");
+ errors += check_rot (64, "ROT64", "MASK64");
+
+ return errors != 0;
+}
diff --git a/sim/testsuite/common/fpu-tst.c b/sim/testsuite/common/fpu-tst.c
new file mode 100644
index 0000000..d347e12
--- /dev/null
+++ b/sim/testsuite/common/fpu-tst.c
@@ -0,0 +1,538 @@
+#define ASSERT(EXPRESSION) \
+do { \
+ if (!(EXPRESSION)) { \
+ fprintf (stderr, "%s:%d: assertion failed - %s\n", \
+ __FILE__, __LINE__, #EXPRESSION); \
+ abort (); \
+ } \
+} while (0)
+
+#define SIM_BITS_INLINE (INCLUDE_MODULE | INCLUDED_BY_MODULE)
+
+#include "milieu.h"
+#include "softfloat.h"
+#include "systfloat.h"
+#include "systmodes.h"
+
+/* #define SIM_FPU_INLINE (INCLUDE_MODULE | INCLUDED_BY_MODULE) */
+
+
+#include "sim-bits.h"
+#include "sim-fpu.h"
+#include "sim-fpu.c"
+
+
+
+static int flags;
+
+int8
+syst_float_flags_clear ()
+{
+ int old_flags = 0;
+ int i = 1;
+ while (flags >= i)
+ {
+ switch ((sim_fpu_status) (flags & i))
+ {
+ case sim_fpu_status_denorm:
+ break;
+ case sim_fpu_status_invalid_snan:
+ case sim_fpu_status_invalid_qnan:
+ case sim_fpu_status_invalid_isi:
+ case sim_fpu_status_invalid_idi:
+ case sim_fpu_status_invalid_zdz:
+ case sim_fpu_status_invalid_imz:
+ case sim_fpu_status_invalid_cvi:
+ case sim_fpu_status_invalid_cmp:
+ case sim_fpu_status_invalid_sqrt:
+ old_flags |= float_flag_invalid; /* v */
+ break;
+ case sim_fpu_status_inexact:
+ old_flags |= float_flag_inexact; /* x */
+ break;
+ case sim_fpu_status_overflow:
+ old_flags |= float_flag_overflow; /* o */
+ break;
+ case sim_fpu_status_underflow:
+ old_flags |= float_flag_underflow; /* u */
+ break;
+ case sim_fpu_status_invalid_div0:
+ old_flags |= float_flag_divbyzero; /* z */
+ break;
+ case sim_fpu_status_rounded:
+ break;
+ }
+ i <<= 1;
+ }
+ flags = 0;
+ return old_flags;
+}
+
+
+sim_fpu_round rounding_mode;
+
+void
+syst_float_set_rounding_mode(int8 mode)
+{
+ switch (mode)
+ {
+ case float_round_nearest_even:
+ rounding_mode = sim_fpu_round_near;
+ break;
+ case float_round_down:
+ rounding_mode = sim_fpu_round_down;
+ break;
+ case float_round_up:
+ rounding_mode = sim_fpu_round_up;
+ break;
+ case float_round_to_zero:
+ rounding_mode = sim_fpu_round_zero;
+ break;
+ }
+}
+
+
+float32
+syst_int32_to_float32(int32 a)
+{
+ float32 z;
+ sim_fpu s;
+ flags |= sim_fpu_i32to (&s, a, rounding_mode);
+ flags |= sim_fpu_round_32 (&s, rounding_mode, 0);
+ sim_fpu_to32 (&z, &s);
+ return z;
+}
+
+float64
+syst_int32_to_float64( int32 a )
+{
+ float64 z;
+ sim_fpu s;
+ flags |= sim_fpu_i32to (&s, a, rounding_mode);
+ sim_fpu_to64 (&z, &s);
+ return z;
+}
+
+int32
+syst_float32_to_int32_round_to_zero( float32 a )
+{
+ int32 z;
+ sim_fpu s;
+ sim_fpu_32to (&s, a);
+ flags |= sim_fpu_to32i (&z, &s, sim_fpu_round_zero);
+ return z;
+}
+
+float64
+syst_float32_to_float64 (float32 a)
+{
+ float64 z;
+ sim_fpu s;
+ sim_fpu_32to (&s, a);
+ flags |= sim_fpu_round_64 (&s, rounding_mode, 0);
+ sim_fpu_to64 (&z, &s);
+ return z;
+}
+
+float32 syst_float32_add( float32 a, float32 b )
+{
+ float32 z;
+ sim_fpu A;
+ sim_fpu B;
+ sim_fpu ans;
+ sim_fpu_32to (&A, a);
+ sim_fpu_32to (&B, b);
+#if 0
+ fprintf (stdout, "\n ");
+ sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, "\n+ ");
+ sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, "\n= ");
+#endif
+ flags |= sim_fpu_add (&ans, &A, &B);
+ flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
+#if 0
+ sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, "\n");
+#endif
+ sim_fpu_to32 (&z, &ans);
+ return z;
+}
+
+float32 syst_float32_sub( float32 a, float32 b )
+{
+ float32 z;
+ sim_fpu A;
+ sim_fpu B;
+ sim_fpu ans;
+ sim_fpu_32to (&A, a);
+ sim_fpu_32to (&B, b);
+#if 0
+ sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " + ");
+ sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " = ");
+#endif
+ flags |= sim_fpu_sub (&ans, &A, &B);
+ flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
+#if 0
+ sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, "\n");
+#endif
+ sim_fpu_to32 (&z, &ans);
+ return z;
+}
+
+float32 syst_float32_mul( float32 a, float32 b )
+{
+ float32 z;
+ sim_fpu A;
+ sim_fpu B;
+ sim_fpu ans;
+ sim_fpu_32to (&A, a);
+ sim_fpu_32to (&B, b);
+#if 0
+ sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " + ");
+ sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " = ");
+#endif
+ flags |= sim_fpu_mul (&ans, &A, &B);
+#if 0
+ sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
+#endif
+ flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
+#if 0
+ sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, "\n");
+#endif
+ sim_fpu_to32 (&z, &ans);
+ return z;
+}
+
+float32 syst_float32_div( float32 a, float32 b )
+{
+ float32 z;
+ sim_fpu A;
+ sim_fpu B;
+ sim_fpu ans;
+ sim_fpu_32to (&A, a);
+ sim_fpu_32to (&B, b);
+ flags |= sim_fpu_div (&ans, &A, &B);
+ flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
+ sim_fpu_to32 (&z, &ans);
+ return z;
+}
+
+float32 syst_float32_sqrt( float32 a )
+{
+ float32 z;
+ sim_fpu A;
+ sim_fpu ans;
+ sim_fpu_32to (&A, a);
+#if 0
+ sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " sqrt> ");
+#endif
+ flags |= sim_fpu_sqrt (&ans, &A);
+#if 0
+ sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
+#endif
+ flags |= sim_fpu_round_32 (&ans, rounding_mode, 0);
+#if 0
+ fprintf (stdout, " (%x)\n", flags);
+#endif
+ sim_fpu_to32 (&z, &ans);
+ return z;
+}
+
+flag syst_float32_eq( float32 a, float32 b )
+{
+ sim_fpu A;
+ sim_fpu B;
+ int is;
+ sim_fpu_32to (&A, a);
+ sim_fpu_32to (&B, b);
+ flags |= (sim_fpu_eq (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
+ return is;
+}
+
+flag syst_float32_eq_signaling( float32 a, float32 b )
+{
+ sim_fpu A;
+ sim_fpu B;
+ int is;
+ sim_fpu_32to (&A, a);
+ sim_fpu_32to (&B, b);
+ flags |= sim_fpu_eq (&is, &A, &B);
+ return is;
+}
+
+flag syst_float32_le( float32 a, float32 b )
+{
+ sim_fpu A;
+ sim_fpu B;
+ int is;
+ sim_fpu_32to (&A, a);
+ sim_fpu_32to (&B, b);
+ flags |= sim_fpu_le (&is, &A, &B);
+ return is;
+}
+
+flag syst_float32_le_quiet( float32 a, float32 b )
+{
+ sim_fpu A;
+ sim_fpu B;
+ int is;
+ sim_fpu_32to (&A, a);
+ sim_fpu_32to (&B, b);
+ flags |= (sim_fpu_le (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
+ return is;
+}
+
+flag syst_float32_lt( float32 a, float32 b )
+{
+ sim_fpu A;
+ sim_fpu B;
+ int is;
+ sim_fpu_32to (&A, a);
+ sim_fpu_32to (&B, b);
+ flags |= sim_fpu_lt (&is, &A, &B);
+ return is;
+}
+
+flag syst_float32_lt_quiet( float32 a, float32 b )
+{
+ sim_fpu A;
+ sim_fpu B;
+ int is;
+ sim_fpu_32to (&A, a);
+ sim_fpu_32to (&B, b);
+ flags |= (sim_fpu_lt (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
+ return is;
+}
+
+int32 syst_float64_to_int32_round_to_zero( float64 a )
+{
+ int32 z;
+ sim_fpu s;
+ sim_fpu_64to (&s, a);
+ flags |= sim_fpu_to32i (&z, &s, sim_fpu_round_zero);
+ return z;
+}
+
+float32 syst_float64_to_float32( float64 a )
+{
+ float32 z;
+ sim_fpu s;
+ sim_fpu_64to (&s, a);
+#if 0
+ sim_fpu_print_fpu (&s, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " -> ");
+#endif
+ flags |= sim_fpu_round_32 (&s, rounding_mode, 0);
+#if 0
+ sim_fpu_print_fpu (&s, (sim_fpu_print_func*) fprintf, stdout);
+ sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
+ printf ("\n");
+#endif
+ sim_fpu_to32 (&z, &s);
+ return z;
+}
+
+float64 syst_float64_add( float64 a, float64 b )
+{
+ float64 z;
+ sim_fpu A;
+ sim_fpu B;
+ sim_fpu ans;
+ sim_fpu_64to (&A, a);
+ sim_fpu_64to (&B, b);
+#if 0
+ sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " + ");
+ sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " = ");
+#endif
+ flags |= sim_fpu_add (&ans, &A, &B);
+#if 0
+ sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
+#endif
+ flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
+#if 0
+ fprintf (stdout, " (%x)\n", flags);
+#endif
+ sim_fpu_to64 (&z, &ans);
+ return z;
+}
+
+float64 syst_float64_sub( float64 a, float64 b )
+{
+ float64 z;
+ sim_fpu A;
+ sim_fpu B;
+ sim_fpu ans;
+ sim_fpu_64to (&A, a);
+ sim_fpu_64to (&B, b);
+#if 0
+ sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " + ");
+ sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " = ");
+#endif
+ flags |= sim_fpu_sub (&ans, &A, &B);
+#if 0
+ sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
+#endif
+ flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
+#if 0
+ fprintf (stdout, " (%x)\n", flags);
+#endif
+ sim_fpu_to64 (&z, &ans);
+ return z;
+}
+
+float64 syst_float64_mul( float64 a, float64 b )
+{
+ float64 z;
+ sim_fpu A;
+ sim_fpu B;
+ sim_fpu ans;
+ sim_fpu_64to (&A, a);
+ sim_fpu_64to (&B, b);
+#if 0
+ sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " * ");
+ sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " = ");
+#endif
+ flags |= sim_fpu_mul (&ans, &A, &B);
+#if 0
+ sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
+#endif
+ flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
+#if 0
+ sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, "\n");
+#endif
+ sim_fpu_to64 (&z, &ans);
+ return z;
+}
+
+float64 syst_float64_div( float64 a, float64 b )
+{
+ float64 z;
+ sim_fpu A;
+ sim_fpu B;
+ sim_fpu ans;
+ sim_fpu_64to (&A, a);
+ sim_fpu_64to (&B, b);
+#if 0
+ sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " + ");
+ sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, " = ");
+#endif
+ flags |= sim_fpu_div (&ans, &A, &B);
+#if 0
+ sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
+#endif
+ flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
+#if 0
+ sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, "\n");
+#endif
+ sim_fpu_to64 (&z, &ans);
+ return z;
+}
+
+float64 syst_float64_sqrt( float64 a )
+{
+ float64 z;
+ sim_fpu A;
+ sim_fpu ans;
+ sim_fpu_64to (&A, a);
+#if 0
+ sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout);
+ printf (" sqrt> ");
+ printf ("\n");
+#endif
+ flags |= sim_fpu_sqrt (&ans, &A);
+#if 0
+ sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout);
+#endif
+ flags |= sim_fpu_round_64 (&ans, rounding_mode, 0);
+#if 0
+ sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout);
+ fprintf (stdout, "\n");
+#endif
+ sim_fpu_to64 (&z, &ans);
+ return z;
+}
+
+flag syst_float64_eq( float64 a, float64 b )
+{
+ sim_fpu A;
+ sim_fpu B;
+ int is;
+ sim_fpu_64to (&A, a);
+ sim_fpu_64to (&B, b);
+ flags |= (sim_fpu_eq (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
+ return is;
+}
+
+flag syst_float64_eq_signaling( float64 a, float64 b )
+{
+ sim_fpu A;
+ sim_fpu B;
+ int is;
+ sim_fpu_64to (&A, a);
+ sim_fpu_64to (&B, b);
+ flags |= sim_fpu_eq (&is, &A, &B);
+ return is;
+}
+
+flag syst_float64_le( float64 a, float64 b )
+{
+ sim_fpu A;
+ sim_fpu B;
+ int is;
+ sim_fpu_64to (&A, a);
+ sim_fpu_64to (&B, b);
+ flags |= sim_fpu_le (&is, &A, &B);
+ return is;
+}
+
+flag syst_float64_le_quiet( float64 a, float64 b )
+{
+ sim_fpu A;
+ sim_fpu B;
+ int is;
+ sim_fpu_64to (&A, a);
+ sim_fpu_64to (&B, b);
+ flags |= (sim_fpu_le (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
+ return is;
+}
+
+flag syst_float64_lt( float64 a, float64 b )
+{
+ sim_fpu A;
+ sim_fpu B;
+ int is;
+ sim_fpu_64to (&A, a);
+ sim_fpu_64to (&B, b);
+ flags |= sim_fpu_lt (&is, &A, &B);
+ return is;
+}
+
+flag syst_float64_lt_quiet( float64 a, float64 b )
+{
+ sim_fpu A;
+ sim_fpu B;
+ int is;
+ sim_fpu_64to (&A, a);
+ sim_fpu_64to (&B, b);
+ flags |= (sim_fpu_lt (&is, &A, &B) & ~sim_fpu_status_invalid_qnan);
+ return is;
+}
+