summaryrefslogtreecommitdiff
path: root/regress/sys/arch
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2003-07-12 04:08:34 +0000
committerJason Wright <jason@cvs.openbsd.org>2003-07-12 04:08:34 +0000
commit888b504a38781ed60d6c13e7c305ee541deb0acc (patch)
tree437ddb20b567056888805ffefeff865beabb10c6 /regress/sys/arch
parentb0fbb592bec58ecb83c2728466504684b8884a67 (diff)
simplistic regression tests for ldq/stq
badfreg: attempts to execute invalid opcodes (invalid floating point regs) goodfreg: runs through all valid fp regs
Diffstat (limited to 'regress/sys/arch')
-rw-r--r--regress/sys/arch/sparc64/Makefile4
-rw-r--r--regress/sys/arch/sparc64/emul-ldqstq/Makefile5
-rw-r--r--regress/sys/arch/sparc64/emul-ldqstq/badfreg/Makefile219
-rw-r--r--regress/sys/arch/sparc64/emul-ldqstq/badfreg/main.c221
-rw-r--r--regress/sys/arch/sparc64/emul-ldqstq/badfreg/test.S351
-rw-r--r--regress/sys/arch/sparc64/emul-ldqstq/goodfreg/Makefile8
-rw-r--r--regress/sys/arch/sparc64/emul-ldqstq/goodfreg/fpregs.S137
-rw-r--r--regress/sys/arch/sparc64/emul-ldqstq/goodfreg/fpregs.h35
-rw-r--r--regress/sys/arch/sparc64/emul-ldqstq/goodfreg/goodfreg.c331
-rw-r--r--regress/sys/arch/sparc64/emul-ldqstq/goodfreg/test_asm.S159
10 files changed, 1468 insertions, 2 deletions
diff --git a/regress/sys/arch/sparc64/Makefile b/regress/sys/arch/sparc64/Makefile
index 1b7790ab8ea..dbc806192f2 100644
--- a/regress/sys/arch/sparc64/Makefile
+++ b/regress/sys/arch/sparc64/Makefile
@@ -1,7 +1,7 @@
-# $OpenBSD: Makefile,v 1.1 2003/07/10 14:40:42 jason Exp $
+# $OpenBSD: Makefile,v 1.2 2003/07/12 04:08:33 jason Exp $
.if ${MACHINE_ARCH} == "sparc64"
-SUBDIR=emul-popc
+SUBDIR=emul-popc emul-ldqstq
.endif
.include <bsd.subdir.mk>
diff --git a/regress/sys/arch/sparc64/emul-ldqstq/Makefile b/regress/sys/arch/sparc64/emul-ldqstq/Makefile
new file mode 100644
index 00000000000..9f0a6e971d4
--- /dev/null
+++ b/regress/sys/arch/sparc64/emul-ldqstq/Makefile
@@ -0,0 +1,5 @@
+# $OpenBSD: Makefile,v 1.1 2003/07/12 04:08:33 jason Exp $
+
+SUBDIR=badfreg goodfreg
+
+.include <bsd.subdir.mk>
diff --git a/regress/sys/arch/sparc64/emul-ldqstq/badfreg/Makefile b/regress/sys/arch/sparc64/emul-ldqstq/badfreg/Makefile
new file mode 100644
index 00000000000..49a5efcbc70
--- /dev/null
+++ b/regress/sys/arch/sparc64/emul-ldqstq/badfreg/Makefile
@@ -0,0 +1,219 @@
+# $OpenBSD: Makefile,v 1.1 2003/07/12 04:08:33 jason Exp $
+
+PROG=badfpreg
+CFLAGS+=-Wall
+NOMAN=
+SRCS=test.S main.c
+
+REGRESS_TARGETS= \
+ t_ld_f2_imm t_st_f2_imm t_ld_f2_reg t_st_f2_reg \
+ t_ld_f6_imm t_st_f6_imm t_ld_f6_reg t_st_f6_reg \
+ t_ld_f10_imm t_st_f10_imm t_ld_f10_reg t_st_f10_reg \
+ t_ld_f14_imm t_st_f14_imm t_ld_f14_reg t_st_f14_reg \
+ t_ld_f18_imm t_st_f18_imm t_ld_f18_reg t_st_f18_reg \
+ t_ld_f22_imm t_st_f22_imm t_ld_f22_reg t_st_f22_reg \
+ t_ld_f26_imm t_st_f26_imm t_ld_f26_reg t_st_f26_reg \
+ t_ld_f30_imm t_st_f30_imm t_ld_f30_reg t_st_f30_reg \
+ t_ld_f34_imm t_st_f34_imm t_ld_f34_reg t_st_f34_reg \
+ t_ld_f38_imm t_st_f38_imm t_ld_f38_reg t_st_f38_reg \
+ t_ld_f42_imm t_st_f42_imm t_ld_f42_reg t_st_f42_reg \
+ t_ld_f46_imm t_st_f46_imm t_ld_f46_reg t_st_f46_reg \
+ t_ld_f50_imm t_st_f50_imm t_ld_f50_reg t_st_f50_reg \
+ t_ld_f54_imm t_st_f54_imm t_ld_f54_reg t_st_f54_reg \
+ t_ld_f58_imm t_st_f58_imm t_ld_f58_reg t_st_f58_reg \
+ t_ld_f62_imm t_st_f62_imm t_ld_f62_reg t_st_f62_reg
+
+.include <bsd.regress.mk>
+
+t_ld_f2_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 2 ld imm
+
+t_st_f2_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 2 st imm
+
+t_ld_f2_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 2 ld reg
+
+t_st_f2_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 2 st reg
+
+t_ld_f6_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 6 ld imm
+
+t_st_f6_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 6 st imm
+
+t_ld_f6_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 6 ld reg
+
+t_st_f6_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 6 st reg
+
+t_ld_f10_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 10 ld imm
+
+t_st_f10_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 10 st imm
+
+t_ld_f10_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 10 ld reg
+
+t_st_f10_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 10 st reg
+
+t_ld_f14_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 14 ld imm
+
+t_st_f14_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 14 st imm
+
+t_ld_f14_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 14 ld reg
+
+t_st_f14_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 14 st reg
+
+t_ld_f18_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 18 ld imm
+
+t_st_f18_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 18 st imm
+
+t_ld_f18_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 18 ld reg
+
+t_st_f18_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 18 st reg
+
+t_ld_f22_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 22 ld imm
+
+t_st_f22_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 22 st imm
+
+t_ld_f22_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 22 ld reg
+
+t_st_f22_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 22 st reg
+
+t_ld_f26_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 26 ld imm
+
+t_st_f26_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 26 st imm
+
+t_ld_f26_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 26 ld reg
+
+t_st_f26_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 26 st reg
+
+t_ld_f30_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 30 ld imm
+
+t_st_f30_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 30 st imm
+
+t_ld_f30_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 30 ld reg
+
+t_st_f30_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 30 st reg
+
+t_ld_f34_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 34 ld imm
+
+t_st_f34_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 34 st imm
+
+t_ld_f34_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 34 ld reg
+
+t_st_f34_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 34 st reg
+
+t_ld_f38_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 38 ld imm
+
+t_st_f38_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 38 st imm
+
+t_ld_f38_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 38 ld reg
+
+t_st_f38_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 38 st reg
+
+t_ld_f42_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 42 ld imm
+
+t_st_f42_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 42 st imm
+
+t_ld_f42_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 42 ld reg
+
+t_st_f42_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 42 st reg
+
+t_ld_f46_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 46 ld imm
+
+t_st_f46_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 46 st imm
+
+t_ld_f46_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 46 ld reg
+
+t_st_f46_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 46 st reg
+
+t_ld_f50_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 50 ld imm
+
+t_st_f50_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 50 st imm
+
+t_ld_f50_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 50 ld reg
+
+t_st_f50_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 50 st reg
+
+t_ld_f54_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 54 ld imm
+
+t_st_f54_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 54 st imm
+
+t_ld_f54_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 54 ld reg
+
+t_st_f54_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 54 st reg
+
+t_ld_f58_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 58 ld imm
+
+t_st_f58_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 58 st imm
+
+t_ld_f58_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 58 ld reg
+
+t_st_f58_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 58 st reg
+
+t_ld_f62_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 62 ld imm
+
+t_st_f62_imm: ${PROG}
+ ${.OBJDIR}/${PROG} 62 st imm
+
+t_ld_f62_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 62 ld reg
+
+t_st_f62_reg: ${PROG}
+ ${.OBJDIR}/${PROG} 62 st reg
+
diff --git a/regress/sys/arch/sparc64/emul-ldqstq/badfreg/main.c b/regress/sys/arch/sparc64/emul-ldqstq/badfreg/main.c
new file mode 100644
index 00000000000..00fa9344bc5
--- /dev/null
+++ b/regress/sys/arch/sparc64/emul-ldqstq/badfreg/main.c
@@ -0,0 +1,221 @@
+/* $OpenBSD: main.c,v 1.1 2003/07/12 04:08:33 jason Exp $ */
+
+/*
+ * Copyright (c) 2003 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/types.h>
+#include <signal.h>
+#include <stdio.h>
+#include <err.h>
+#include <string.h>
+#include <unistd.h>
+
+struct fpquad {
+ u_int64_t x1;
+ u_int64_t x2;
+ u_int64_t x3;
+ u_int64_t x4;
+};
+
+void test_ldq_f2_g0(struct fpquad *);
+void test_ldq_f2_simm13(struct fpquad *);
+void test_stq_f2_g0(struct fpquad *);
+void test_stq_f2_simm13(struct fpquad *);
+void test_ldq_f6_g0(struct fpquad *);
+void test_ldq_f6_simm13(struct fpquad *);
+void test_stq_f6_g0(struct fpquad *);
+void test_stq_f6_simm13(struct fpquad *);
+void test_ldq_f10_g0(struct fpquad *);
+void test_ldq_f10_simm13(struct fpquad *);
+void test_stq_f10_g0(struct fpquad *);
+void test_stq_f10_simm13(struct fpquad *);
+void test_ldq_f14_g0(struct fpquad *);
+void test_ldq_f14_simm13(struct fpquad *);
+void test_stq_f14_g0(struct fpquad *);
+void test_stq_f14_simm13(struct fpquad *);
+void test_ldq_f18_g0(struct fpquad *);
+void test_ldq_f18_simm13(struct fpquad *);
+void test_stq_f18_g0(struct fpquad *);
+void test_stq_f18_simm13(struct fpquad *);
+void test_ldq_f22_g0(struct fpquad *);
+void test_ldq_f22_simm13(struct fpquad *);
+void test_stq_f22_g0(struct fpquad *);
+void test_stq_f22_simm13(struct fpquad *);
+void test_ldq_f26_g0(struct fpquad *);
+void test_ldq_f26_simm13(struct fpquad *);
+void test_stq_f26_g0(struct fpquad *);
+void test_stq_f26_simm13(struct fpquad *);
+void test_ldq_f30_g0(struct fpquad *);
+void test_ldq_f30_simm13(struct fpquad *);
+void test_stq_f30_g0(struct fpquad *);
+void test_stq_f30_simm13(struct fpquad *);
+void test_ldq_f34_g0(struct fpquad *);
+void test_ldq_f34_simm13(struct fpquad *);
+void test_stq_f34_g0(struct fpquad *);
+void test_stq_f34_simm13(struct fpquad *);
+void test_ldq_f38_g0(struct fpquad *);
+void test_ldq_f38_simm13(struct fpquad *);
+void test_stq_f38_g0(struct fpquad *);
+void test_stq_f38_simm13(struct fpquad *);
+void test_ldq_f42_g0(struct fpquad *);
+void test_ldq_f42_simm13(struct fpquad *);
+void test_stq_f42_g0(struct fpquad *);
+void test_stq_f42_simm13(struct fpquad *);
+void test_ldq_f46_g0(struct fpquad *);
+void test_ldq_f46_simm13(struct fpquad *);
+void test_stq_f46_g0(struct fpquad *);
+void test_stq_f46_simm13(struct fpquad *);
+void test_ldq_f50_g0(struct fpquad *);
+void test_ldq_f50_simm13(struct fpquad *);
+void test_stq_f50_g0(struct fpquad *);
+void test_stq_f50_simm13(struct fpquad *);
+void test_ldq_f54_g0(struct fpquad *);
+void test_ldq_f54_simm13(struct fpquad *);
+void test_stq_f54_g0(struct fpquad *);
+void test_stq_f54_simm13(struct fpquad *);
+void test_ldq_f58_g0(struct fpquad *);
+void test_ldq_f58_simm13(struct fpquad *);
+void test_stq_f58_g0(struct fpquad *);
+void test_stq_f58_simm13(struct fpquad *);
+void test_ldq_f62_g0(struct fpquad *);
+void test_ldq_f62_simm13(struct fpquad *);
+void test_stq_f62_g0(struct fpquad *);
+void test_stq_f62_simm13(struct fpquad *);
+
+struct fptest {
+ char *reg;
+ char *ldst;
+ char *dir;
+ void (*func)(struct fpquad *);
+} thetests[] = {
+ {"2", "st", "reg", test_stq_f2_g0},
+ {"2", "ld", "reg", test_ldq_f2_g0},
+ {"2", "st", "imm", test_stq_f2_simm13},
+ {"2", "ld", "imm", test_ldq_f2_simm13},
+ {"6", "st", "reg", test_stq_f6_g0},
+ {"6", "ld", "reg", test_ldq_f6_g0},
+ {"6", "st", "imm", test_stq_f6_simm13},
+ {"6", "ld", "imm", test_ldq_f6_simm13},
+ {"10", "st", "reg", test_stq_f10_g0},
+ {"10", "ld", "reg", test_ldq_f10_g0},
+ {"10", "st", "imm", test_stq_f10_simm13},
+ {"10", "ld", "imm", test_ldq_f10_simm13},
+ {"14", "st", "reg", test_stq_f14_g0},
+ {"14", "ld", "reg", test_ldq_f14_g0},
+ {"14", "st", "imm", test_stq_f14_simm13},
+ {"14", "ld", "imm", test_ldq_f14_simm13},
+ {"18", "st", "reg", test_stq_f18_g0},
+ {"18", "ld", "reg", test_ldq_f18_g0},
+ {"18", "st", "imm", test_stq_f18_simm13},
+ {"18", "ld", "imm", test_ldq_f18_simm13},
+ {"22", "st", "reg", test_stq_f22_g0},
+ {"22", "ld", "reg", test_ldq_f22_g0},
+ {"22", "st", "imm", test_stq_f22_simm13},
+ {"22", "ld", "imm", test_ldq_f22_simm13},
+ {"26", "st", "reg", test_stq_f26_g0},
+ {"26", "ld", "reg", test_ldq_f26_g0},
+ {"26", "st", "imm", test_stq_f26_simm13},
+ {"26", "ld", "imm", test_ldq_f26_simm13},
+ {"30", "st", "reg", test_stq_f30_g0},
+ {"30", "ld", "reg", test_ldq_f30_g0},
+ {"30", "st", "imm", test_stq_f30_simm13},
+ {"30", "ld", "imm", test_ldq_f30_simm13},
+ {"34", "st", "reg", test_stq_f34_g0},
+ {"34", "ld", "reg", test_ldq_f34_g0},
+ {"34", "st", "imm", test_stq_f34_simm13},
+ {"34", "ld", "imm", test_ldq_f34_simm13},
+ {"38", "st", "reg", test_stq_f38_g0},
+ {"38", "ld", "reg", test_ldq_f38_g0},
+ {"38", "st", "imm", test_stq_f38_simm13},
+ {"38", "ld", "imm", test_ldq_f38_simm13},
+ {"42", "st", "reg", test_stq_f42_g0},
+ {"42", "ld", "reg", test_ldq_f42_g0},
+ {"42", "st", "imm", test_stq_f42_simm13},
+ {"42", "ld", "imm", test_ldq_f42_simm13},
+ {"46", "st", "reg", test_stq_f46_g0},
+ {"46", "ld", "reg", test_ldq_f46_g0},
+ {"46", "st", "imm", test_stq_f46_simm13},
+ {"46", "ld", "imm", test_ldq_f46_simm13},
+ {"50", "st", "reg", test_stq_f50_g0},
+ {"50", "ld", "reg", test_ldq_f50_g0},
+ {"50", "st", "imm", test_stq_f50_simm13},
+ {"50", "ld", "imm", test_ldq_f50_simm13},
+ {"54", "st", "reg", test_stq_f54_g0},
+ {"54", "ld", "reg", test_ldq_f54_g0},
+ {"54", "st", "imm", test_stq_f54_simm13},
+ {"54", "ld", "imm", test_ldq_f54_simm13},
+ {"58", "st", "reg", test_stq_f58_g0},
+ {"58", "ld", "reg", test_ldq_f58_g0},
+ {"58", "st", "imm", test_stq_f58_simm13},
+ {"58", "ld", "imm", test_ldq_f58_simm13},
+ {"62", "st", "reg", test_stq_f62_g0},
+ {"62", "ld", "reg", test_ldq_f62_g0},
+ {"62", "st", "imm", test_stq_f62_simm13},
+ {"62", "ld", "imm", test_ldq_f62_simm13},
+};
+#define NTESTS (sizeof(thetests)/sizeof(thetests[0]))
+
+void ill_catcher(int, siginfo_t *, void *);
+
+int
+main(int argc, char *argv[])
+{
+ struct fptest *fpt;
+ struct fpquad fpq;
+ struct sigaction sa;
+ int i;
+
+ if (argc != 4) {
+ fprintf(stderr, "badreg regnum [ld|st] [reg|imm]\n");
+ return (1);
+ }
+
+ for (i = 0; i < NTESTS; i++) {
+ fpt = thetests + i;
+ if (strcmp(fpt->reg, argv[1]) == 0 &&
+ strcmp(fpt->ldst, argv[2]) == 0 &&
+ strcmp(fpt->dir, argv[3]) == 0)
+ break;
+ }
+ if (i == NTESTS)
+ errx(1, "unknown test: %s %s %s", argv[1], argv[2], argv[3]);
+
+ sa.sa_sigaction = ill_catcher;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO;
+
+ if (sigaction(SIGILL, &sa, NULL) == -1)
+ err(1, "sigaction");
+
+ (*fpt->func)(&fpq);
+ err(1, "%s %s %s did not generate sigill", argv[1], argv[2], argv[3]);
+ return (0);
+}
+
+void
+ill_catcher(int sig, siginfo_t *si, void *v)
+{
+ _exit(0);
+}
diff --git a/regress/sys/arch/sparc64/emul-ldqstq/badfreg/test.S b/regress/sys/arch/sparc64/emul-ldqstq/badfreg/test.S
new file mode 100644
index 00000000000..4735ebeb68c
--- /dev/null
+++ b/regress/sys/arch/sparc64/emul-ldqstq/badfreg/test.S
@@ -0,0 +1,351 @@
+/* $OpenBSD: test.S,v 1.1 2003/07/12 04:08:33 jason Exp $ */
+
+/*
+ * Copyright (c) 2003 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+#include <machine/trap.h>
+#include <machine/frame.h>
+
+ENTRY(test_ldq_f2_simm13)
+ .word 0xc5122000 ! ldq [%o0 + 0], %f2
+ retl
+ nop
+
+ENTRY(test_ldq_f2_g0)
+ .word 0xc5120000 ! ldq [%o0 + %g0], %f2
+ retl
+ nop
+
+ENTRY(test_stq_f2_simm13)
+ .word 0xc5322000 ! stq %f2, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f2_g0)
+ .word 0xc5320000 ! stq %f2, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f6_simm13)
+ .word 0xcd122000 ! ldq [%o0 + 0], %f6
+ retl
+ nop
+
+ENTRY(test_ldq_f6_g0)
+ .word 0xcd120000 ! ldq [%o0 + %g0], %f6
+ retl
+ nop
+
+ENTRY(test_stq_f6_simm13)
+ .word 0xcd322000 ! stq %f6, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f6_g0)
+ .word 0xcd320000 ! stq %f6, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f10_simm13)
+ .word 0xd5122000 ! ldq [%o0 + 0], %f10
+ retl
+ nop
+
+ENTRY(test_ldq_f10_g0)
+ .word 0xd5120000 ! ldq [%o0 + %g0], %f10
+ retl
+ nop
+
+ENTRY(test_stq_f10_simm13)
+ .word 0xd5322000 ! stq %f10, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f10_g0)
+ .word 0xd5320000 ! stq %f10, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f14_simm13)
+ .word 0xdd122000 ! ldq [%o0 + 0], %f14
+ retl
+ nop
+
+ENTRY(test_ldq_f14_g0)
+ .word 0xdd120000 ! ldq [%o0 + %g0], %f14
+ retl
+ nop
+
+ENTRY(test_stq_f14_simm13)
+ .word 0xdd322000 ! stq %f14, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f14_g0)
+ .word 0xdd320000 ! stq %f14, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f18_simm13)
+ .word 0xe5122000 ! ldq [%o0 + 0], %f18
+ retl
+ nop
+
+ENTRY(test_ldq_f18_g0)
+ .word 0xe5120000 ! ldq [%o0 + %g0], %f18
+ retl
+ nop
+
+ENTRY(test_stq_f18_simm13)
+ .word 0xe5322000 ! stq %f18, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f18_g0)
+ .word 0xe5320000 ! stq %f18, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f22_simm13)
+ .word 0xed122000 ! ldq [%o0 + 0], %f22
+ retl
+ nop
+
+ENTRY(test_ldq_f22_g0)
+ .word 0xed120000 ! ldq [%o0 + %g0], %f22
+ retl
+ nop
+
+ENTRY(test_stq_f22_simm13)
+ .word 0xed322000 ! stq %f22, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f22_g0)
+ .word 0xed320000 ! stq %f22, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f26_simm13)
+ .word 0xf5122000 ! ldq [%o0 + 0], %f26
+ retl
+ nop
+
+ENTRY(test_ldq_f26_g0)
+ .word 0xf5120000 ! ldq [%o0 + %g0], %f26
+ retl
+ nop
+
+ENTRY(test_stq_f26_simm13)
+ .word 0xf5322000 ! stq %f26, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f26_g0)
+ .word 0xf5320000 ! stq %f26, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f30_simm13)
+ .word 0xfd122000 ! ldq [%o0 + 0], %f30
+ retl
+ nop
+
+ENTRY(test_ldq_f30_g0)
+ .word 0xfd120000 ! ldq [%o0 + %g0], %f30
+ retl
+ nop
+
+ENTRY(test_stq_f30_simm13)
+ .word 0xfd322000 ! stq %f30, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f30_g0)
+ .word 0xfd320000 ! stq %f30, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f34_simm13)
+ .word 0xc7122000 ! ldq [%o0 + 0], %f34
+ retl
+ nop
+
+ENTRY(test_ldq_f34_g0)
+ .word 0xc7120000 ! ldq [%o0 + %g0], %f34
+ retl
+ nop
+
+ENTRY(test_stq_f34_simm13)
+ .word 0xc7322000 ! stq %f34, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f34_g0)
+ .word 0xc7320000 ! stq %f34, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f38_simm13)
+ .word 0xcf122000 ! ldq [%o0 + 0], %f38
+ retl
+ nop
+
+ENTRY(test_ldq_f38_g0)
+ .word 0xcf120000 ! ldq [%o0 + %g0], %f38
+ retl
+ nop
+
+ENTRY(test_stq_f38_simm13)
+ .word 0xcf322000 ! stq %f38, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f38_g0)
+ .word 0xcf320000 ! stq %f38, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f42_simm13)
+ .word 0xd7122000 ! ldq [%o0 + 0], %f42
+ retl
+ nop
+
+ENTRY(test_ldq_f42_g0)
+ .word 0xd7120000 ! ldq [%o0 + %g0], %f42
+ retl
+ nop
+
+ENTRY(test_stq_f42_simm13)
+ .word 0xd7322000 ! stq %f42, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f42_g0)
+ .word 0xd7320000 ! stq %f42, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f46_simm13)
+ .word 0xdf122000 ! ldq [%o0 + 0], %f46
+ retl
+ nop
+
+ENTRY(test_ldq_f46_g0)
+ .word 0xdf120000 ! ldq [%o0 + %g0], %f46
+ retl
+ nop
+
+ENTRY(test_stq_f46_simm13)
+ .word 0xdf322000 ! stq %f46, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f46_g0)
+ .word 0xdf320000 ! stq %f46, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f50_simm13)
+ .word 0xe7122000 ! ldq [%o0 + 0], %f50
+ retl
+ nop
+
+ENTRY(test_ldq_f50_g0)
+ .word 0xe7120000 ! ldq [%o0 + %g0], %f50
+ retl
+ nop
+
+ENTRY(test_stq_f50_simm13)
+ .word 0xe7322000 ! stq %f50, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f50_g0)
+ .word 0xe7320000 ! stq %f50, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f54_simm13)
+ .word 0xef122000 ! ldq [%o0 + 0], %f54
+ retl
+ nop
+
+ENTRY(test_ldq_f54_g0)
+ .word 0xef120000 ! ldq [%o0 + %g0], %f54
+ retl
+ nop
+
+ENTRY(test_stq_f54_simm13)
+ .word 0xef322000 ! stq %f54, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f54_g0)
+ .word 0xef320000 ! stq %f54, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f58_simm13)
+ .word 0xf7122000 ! ldq [%o0 + 0], %f58
+ retl
+ nop
+
+ENTRY(test_ldq_f58_g0)
+ .word 0xf7120000 ! ldq [%o0 + %g0], %f58
+ retl
+ nop
+
+ENTRY(test_stq_f58_simm13)
+ .word 0xf7322000 ! stq %f58, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f58_g0)
+ .word 0xf7320000 ! stq %f58, [%o0 + %g0]
+ retl
+ nop
+
+ENTRY(test_ldq_f62_simm13)
+ .word 0xff122000 ! ldq [%o0 + 0], %f62
+ retl
+ nop
+
+ENTRY(test_ldq_f62_g0)
+ .word 0xff120000 ! ldq [%o0 + %g0], %f62
+ retl
+ nop
+
+ENTRY(test_stq_f62_simm13)
+ .word 0xff322000 ! stq %f62, [%o0 + 0]
+ retl
+ nop
+
+ENTRY(test_stq_f62_g0)
+ .word 0xff320000 ! stq %f62, [%o0 + %g0]
+ retl
+ nop
diff --git a/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/Makefile b/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/Makefile
new file mode 100644
index 00000000000..835d60a1055
--- /dev/null
+++ b/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/Makefile
@@ -0,0 +1,8 @@
+# $OpenBSD: Makefile,v 1.1 2003/07/12 04:08:33 jason Exp $
+
+PROG=goodfreg
+NOMAN=
+SRCS=fpregs.S goodfreg.c test_asm.S
+CFLAGS+=-Wall -g
+
+.include <bsd.regress.mk>
diff --git a/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/fpregs.S b/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/fpregs.S
new file mode 100644
index 00000000000..edf64c16439
--- /dev/null
+++ b/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/fpregs.S
@@ -0,0 +1,137 @@
+/* $OpenBSD: fpregs.S,v 1.1 2003/07/12 04:08:33 jason Exp $ */
+
+/*
+ * Copyright (c) 2003 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+#include <machine/trap.h>
+#include <machine/frame.h>
+
+ENTRY(loadfpregs)
+ ldd [%o0 + 0 * 8], %f0
+ ldd [%o0 + 1 * 8], %f2
+ ldd [%o0 + 2 * 8], %f4
+ ldd [%o0 + 3 * 8], %f6
+ ldd [%o0 + 4 * 8], %f8
+ ldd [%o0 + 5 * 8], %f10
+ ldd [%o0 + 6 * 8], %f12
+ ldd [%o0 + 7 * 8], %f14
+ ldd [%o0 + 8 * 8], %f16
+ ldd [%o0 + 9 * 8], %f18
+ ldd [%o0 + 10 * 8], %f20
+ ldd [%o0 + 11 * 8], %f22
+ ldd [%o0 + 12 * 8], %f24
+ ldd [%o0 + 13 * 8], %f26
+ ldd [%o0 + 14 * 8], %f28
+ ldd [%o0 + 15 * 8], %f30
+ ldd [%o0 + 16 * 8], %f32
+ ldd [%o0 + 17 * 8], %f34
+ ldd [%o0 + 18 * 8], %f36
+ ldd [%o0 + 19 * 8], %f38
+ ldd [%o0 + 20 * 8], %f40
+ ldd [%o0 + 21 * 8], %f42
+ ldd [%o0 + 22 * 8], %f44
+ ldd [%o0 + 23 * 8], %f46
+ ldd [%o0 + 24 * 8], %f48
+ ldd [%o0 + 25 * 8], %f50
+ ldd [%o0 + 26 * 8], %f52
+ ldd [%o0 + 27 * 8], %f54
+ ldd [%o0 + 28 * 8], %f56
+ ldd [%o0 + 29 * 8], %f58
+ ldd [%o0 + 30 * 8], %f60
+ retl
+ ldd [%o0 + 31 * 8], %f62
+
+ENTRY(savefpregs)
+ std %f0, [%o0 + 0 * 8]
+ std %f2, [%o0 + 1 * 8]
+ std %f4, [%o0 + 2 * 8]
+ std %f6, [%o0 + 3 * 8]
+ std %f8, [%o0 + 4 * 8]
+ std %f10, [%o0 + 5 * 8]
+ std %f12, [%o0 + 6 * 8]
+ std %f14, [%o0 + 7 * 8]
+ std %f16, [%o0 + 8 * 8]
+ std %f18, [%o0 + 9 * 8]
+ std %f20, [%o0 + 10 * 8]
+ std %f22, [%o0 + 11 * 8]
+ std %f24, [%o0 + 12 * 8]
+ std %f26, [%o0 + 13 * 8]
+ std %f28, [%o0 + 14 * 8]
+ std %f30, [%o0 + 15 * 8]
+ std %f32, [%o0 + 16 * 8]
+ std %f34, [%o0 + 17 * 8]
+ std %f36, [%o0 + 18 * 8]
+ std %f38, [%o0 + 19 * 8]
+ std %f40, [%o0 + 20 * 8]
+ std %f42, [%o0 + 21 * 8]
+ std %f44, [%o0 + 22 * 8]
+ std %f46, [%o0 + 23 * 8]
+ std %f48, [%o0 + 24 * 8]
+ std %f50, [%o0 + 25 * 8]
+ std %f52, [%o0 + 26 * 8]
+ std %f54, [%o0 + 27 * 8]
+ std %f56, [%o0 + 28 * 8]
+ std %f58, [%o0 + 29 * 8]
+ std %f60, [%o0 + 30 * 8]
+ retl
+ std %f62, [%o0 + 31 * 8]
+
+ENTRY(initfpregs)
+ not %g0, %o1
+ stx %o1, [%o0 + 0 * 8]
+ stx %o1, [%o0 + 1 * 8]
+ stx %o1, [%o0 + 2 * 8]
+ stx %o1, [%o0 + 3 * 8]
+ stx %o1, [%o0 + 4 * 8]
+ stx %o1, [%o0 + 5 * 8]
+ stx %o1, [%o0 + 6 * 8]
+ stx %o1, [%o0 + 7 * 8]
+ stx %o1, [%o0 + 8 * 8]
+ stx %o1, [%o0 + 9 * 8]
+ stx %o1, [%o0 + 10 * 8]
+ stx %o1, [%o0 + 11 * 8]
+ stx %o1, [%o0 + 12 * 8]
+ stx %o1, [%o0 + 13 * 8]
+ stx %o1, [%o0 + 14 * 8]
+ stx %o1, [%o0 + 15 * 8]
+ stx %o1, [%o0 + 16 * 8]
+ stx %o1, [%o0 + 17 * 8]
+ stx %o1, [%o0 + 18 * 8]
+ stx %o1, [%o0 + 19 * 8]
+ stx %o1, [%o0 + 20 * 8]
+ stx %o1, [%o0 + 21 * 8]
+ stx %o1, [%o0 + 22 * 8]
+ stx %o1, [%o0 + 23 * 8]
+ stx %o1, [%o0 + 24 * 8]
+ stx %o1, [%o0 + 25 * 8]
+ stx %o1, [%o0 + 26 * 8]
+ stx %o1, [%o0 + 27 * 8]
+ stx %o1, [%o0 + 28 * 8]
+ stx %o1, [%o0 + 29 * 8]
+ stx %o1, [%o0 + 30 * 8]
+ retl
+ stx %o1, [%o0 + 31 * 8]
diff --git a/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/fpregs.h b/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/fpregs.h
new file mode 100644
index 00000000000..4a46fa8fa91
--- /dev/null
+++ b/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/fpregs.h
@@ -0,0 +1,35 @@
+/* $OpenBSD: fpregs.h,v 1.1 2003/07/12 04:08:33 jason Exp $ */
+
+/*
+ * Copyright (c) 2003 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+union fpregs {
+ u_int64_t f_reg64[32];
+ u_int32_t f_reg32[64];
+};
+
+void loadfpregs(union fpregs *);
+void savefpregs(union fpregs *);
+void initfpregs(union fpregs *);
diff --git a/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/goodfreg.c b/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/goodfreg.c
new file mode 100644
index 00000000000..31734e5f988
--- /dev/null
+++ b/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/goodfreg.c
@@ -0,0 +1,331 @@
+/* $OpenBSD: goodfreg.c,v 1.1 2003/07/12 04:08:33 jason Exp $ */
+
+/*
+ * Copyright (c) 2003 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <err.h>
+#include "fpregs.h"
+
+struct fpquad {
+ u_int32_t x1;
+ u_int32_t x2;
+ u_int32_t x3;
+ u_int32_t x4;
+};
+
+void asm_ldq_f0(struct fpquad *);
+void asm_ldq_f4(struct fpquad *);
+void asm_ldq_f8(struct fpquad *);
+void asm_ldq_f12(struct fpquad *);
+void asm_ldq_f16(struct fpquad *);
+void asm_ldq_f20(struct fpquad *);
+void asm_ldq_f24(struct fpquad *);
+void asm_ldq_f28(struct fpquad *);
+void asm_ldq_f32(struct fpquad *);
+void asm_ldq_f36(struct fpquad *);
+void asm_ldq_f40(struct fpquad *);
+void asm_ldq_f44(struct fpquad *);
+void asm_ldq_f48(struct fpquad *);
+void asm_ldq_f52(struct fpquad *);
+void asm_ldq_f56(struct fpquad *);
+void asm_ldq_f60(struct fpquad *);
+
+void asm_stq_f0(struct fpquad *);
+void asm_stq_f4(struct fpquad *);
+void asm_stq_f8(struct fpquad *);
+void asm_stq_f12(struct fpquad *);
+void asm_stq_f16(struct fpquad *);
+void asm_stq_f20(struct fpquad *);
+void asm_stq_f24(struct fpquad *);
+void asm_stq_f28(struct fpquad *);
+void asm_stq_f32(struct fpquad *);
+void asm_stq_f36(struct fpquad *);
+void asm_stq_f40(struct fpquad *);
+void asm_stq_f44(struct fpquad *);
+void asm_stq_f48(struct fpquad *);
+void asm_stq_f52(struct fpquad *);
+void asm_stq_f56(struct fpquad *);
+void asm_stq_f60(struct fpquad *);
+
+int
+compare_regs(union fpregs *fr1, union fpregs *fr2)
+{
+ return (memcmp(fr1, fr2, sizeof(*fr2)));
+}
+
+void
+dump_reg(union fpregs *fr)
+{
+ int i;
+
+ for (i = 0; i < 64; i++) {
+ if ((i & 3) == 0)
+ printf("f%-2d:", i);
+ printf(" %08x", fr->f_reg32[i]);
+ if ((i & 3) == 3)
+ printf("\n");
+ }
+}
+
+void
+dump_regs(union fpregs *fr1, union fpregs *fr2, union fpregs *fr3)
+{
+ printf("BEFORE ASM\n");
+ dump_reg(fr1);
+ printf("AFTER ASM\n");
+ dump_reg(fr2);
+ printf("MANUAL\n");
+ dump_reg(fr3);
+}
+
+int
+compare_quads(struct fpquad *q1, struct fpquad *q2)
+{
+ return (memcmp(q1, q2, sizeof(*q2)));
+}
+
+/*
+ * Verify that savefpregs, loadfpregs, and initfpregs actually seem to work.
+ */
+void
+check_saves(union fpregs *fr1, union fpregs *fr2, union fpregs *fr3)
+{
+ memset(fr1, 0x55, sizeof(*fr1));
+ memset(fr2, 0x55, sizeof(*fr2));
+ memset(fr3, 0x55, sizeof(*fr3));
+ loadfpregs(fr1);
+ if (compare_regs(fr1, fr2))
+ errx(1, "check_saves: loadfpregs1 differs");
+
+ savefpregs(fr2);
+ if (compare_regs(fr1, fr2) || compare_regs(fr2, fr3))
+ errx(1, "check_saves: savefpregs1 differs");
+
+ memset(fr1, 0xaa, sizeof(*fr1));
+ memset(fr2, 0xaa, sizeof(*fr2));
+ memset(fr3, 0xaa, sizeof(*fr3));
+ loadfpregs(fr1);
+ if (compare_regs(fr1, fr2))
+ errx(1, "check_saves: loadfpregs2 differs");
+
+ savefpregs(fr2);
+ if (compare_regs(fr1, fr2) || compare_regs(fr2, fr3))
+ errx(1, "check_saves: savefpregs2 differs");
+
+ memset(fr1, 0xff, sizeof(*fr1));
+ initfpregs(fr2);
+ if (compare_regs(fr1, fr2))
+ errx(1, "check_saves: initfpregs differs");
+}
+
+void
+c_stq(union fpregs *frp, int freg, struct fpquad *q)
+{
+ q->x1 = frp->f_reg32[freg];
+ q->x2 = frp->f_reg32[freg + 1];
+ q->x3 = frp->f_reg32[freg + 2];
+ q->x4 = frp->f_reg32[freg + 3];
+}
+
+void
+c_ldq(union fpregs *frp, int freg, struct fpquad *q)
+{
+ frp->f_reg32[freg] = q->x1;
+ frp->f_reg32[freg + 1] = q->x2;
+ frp->f_reg32[freg + 2] = q->x3;
+ frp->f_reg32[freg + 3] = q->x4;
+}
+
+void
+asm_ldq(int freg, struct fpquad *q)
+{
+ switch (freg) {
+ case 0:
+ asm_ldq_f0(q);
+ break;
+ case 4:
+ asm_ldq_f4(q);
+ break;
+ case 8:
+ asm_ldq_f8(q);
+ break;
+ case 12:
+ asm_ldq_f12(q);
+ break;
+ case 16:
+ asm_ldq_f16(q);
+ break;
+ case 20:
+ asm_ldq_f20(q);
+ break;
+ case 24:
+ asm_ldq_f24(q);
+ break;
+ case 28:
+ asm_ldq_f28(q);
+ break;
+ case 32:
+ asm_ldq_f32(q);
+ break;
+ case 36:
+ asm_ldq_f36(q);
+ break;
+ case 40:
+ asm_ldq_f40(q);
+ break;
+ case 44:
+ asm_ldq_f44(q);
+ break;
+ case 48:
+ asm_ldq_f48(q);
+ break;
+ case 52:
+ asm_ldq_f52(q);
+ break;
+ case 56:
+ asm_ldq_f56(q);
+ break;
+ case 60:
+ asm_ldq_f60(q);
+ break;
+ default:
+ errx(1, "asm_ldq: bad freg %d", freg);
+ }
+}
+
+void
+asm_stq(int freg, struct fpquad *q)
+{
+ switch (freg) {
+ case 0:
+ asm_stq_f0(q);
+ break;
+ case 4:
+ asm_stq_f4(q);
+ break;
+ case 8:
+ asm_stq_f8(q);
+ break;
+ case 12:
+ asm_stq_f12(q);
+ break;
+ case 16:
+ asm_stq_f16(q);
+ break;
+ case 20:
+ asm_stq_f20(q);
+ break;
+ case 24:
+ asm_stq_f24(q);
+ break;
+ case 28:
+ asm_stq_f28(q);
+ break;
+ case 32:
+ asm_stq_f32(q);
+ break;
+ case 36:
+ asm_stq_f36(q);
+ break;
+ case 40:
+ asm_stq_f40(q);
+ break;
+ case 44:
+ asm_stq_f44(q);
+ break;
+ case 48:
+ asm_stq_f48(q);
+ break;
+ case 52:
+ asm_stq_f52(q);
+ break;
+ case 56:
+ asm_stq_f56(q);
+ break;
+ case 60:
+ asm_stq_f60(q);
+ break;
+ default:
+ errx(1, "asm_stq: bad freg %d", freg);
+ }
+}
+
+void
+check_reg(int freg, union fpregs *fr1, union fpregs *fr2, union fpregs *fr3)
+ {
+ struct fpquad q1, q2, q3;
+
+ initfpregs(fr1);
+ initfpregs(fr2);
+ initfpregs(fr3);
+
+ loadfpregs(fr1);
+ q1.x1 = 0x01234567;
+ q1.x2 = 0x89abcdef;
+ q1.x3 = 0x55aa55aa;
+ q1.x4 = 0xa5a5a5a5;
+ asm_ldq(freg, &q1);
+ savefpregs(fr2);
+
+ c_ldq(fr3, freg, &q1);
+
+ if (compare_regs(fr2, fr3)) {
+ errx(1, "ldq: c/asm differ");
+ dump_regs(fr1, fr2, fr3);
+ }
+
+ q2.x1 = q2.x2 = q2.x3 = q2.x4 = 0;
+ q3.x1 = q3.x2 = q3.x3 = q3.x4 = 1;
+ asm_stq(freg, &q2);
+ c_stq(fr3, freg, &q3);
+
+ if (compare_quads(&q1, &q3))
+ errx(1, "c_stq %d differs...", freg);
+
+ if (compare_quads(&q1, &q2))
+ errx(1, "asm_stq %d differs...", freg);
+}
+
+void
+check_regs(union fpregs *fr1, union fpregs *fr2, union fpregs *fr3)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ check_reg(i * 4, fr1, fr2, fr3);
+}
+
+int
+main()
+{
+ union fpregs fr1, fr2, fr3;
+
+ check_saves(&fr1, &fr2, &fr3);
+ check_regs(&fr1, &fr2, &fr3);
+ return (0);
+}
diff --git a/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/test_asm.S b/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/test_asm.S
new file mode 100644
index 00000000000..73b518c5545
--- /dev/null
+++ b/regress/sys/arch/sparc64/emul-ldqstq/goodfreg/test_asm.S
@@ -0,0 +1,159 @@
+/* $OpenBSD: test_asm.S,v 1.1 2003/07/12 04:08:33 jason Exp $ */
+
+/*
+ * Copyright (c) 2003 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+#include <machine/trap.h>
+#include <machine/frame.h>
+
+ENTRY(asm_ldq_f0)
+ retl
+ ldq [%o0], %f0
+
+ENTRY(asm_ldq_f4)
+ retl
+ ldq [%o0], %f4
+
+ENTRY(asm_ldq_f8)
+ retl
+ ldq [%o0], %f8
+
+ENTRY(asm_ldq_f12)
+ retl
+ ldq [%o0], %f12
+
+ENTRY(asm_ldq_f16)
+ retl
+ ldq [%o0], %f16
+
+ENTRY(asm_ldq_f20)
+ retl
+ ldq [%o0], %f20
+
+ENTRY(asm_ldq_f24)
+ retl
+ ldq [%o0], %f24
+
+ENTRY(asm_ldq_f28)
+ retl
+ ldq [%o0], %f28
+
+ENTRY(asm_ldq_f32)
+ retl
+ ldq [%o0], %f32
+
+ENTRY(asm_ldq_f36)
+ retl
+ ldq [%o0], %f36
+
+ENTRY(asm_ldq_f40)
+ retl
+ ldq [%o0], %f40
+
+ENTRY(asm_ldq_f44)
+ retl
+ ldq [%o0], %f44
+
+ENTRY(asm_ldq_f48)
+ retl
+ ldq [%o0], %f48
+
+ENTRY(asm_ldq_f52)
+ retl
+ ldq [%o0], %f52
+
+ENTRY(asm_ldq_f56)
+ retl
+ ldq [%o0], %f56
+
+ENTRY(asm_ldq_f60)
+ retl
+ ldq [%o0], %f60
+
+ENTRY(asm_stq_f0)
+ retl
+ stq %f0, [%o0]
+
+ENTRY(asm_stq_f4)
+ retl
+ stq %f4, [%o0]
+
+ENTRY(asm_stq_f8)
+ retl
+ stq %f8, [%o0]
+
+ENTRY(asm_stq_f12)
+ retl
+ stq %f12, [%o0]
+
+ENTRY(asm_stq_f16)
+ retl
+ stq %f16, [%o0]
+
+ENTRY(asm_stq_f20)
+ retl
+ stq %f20, [%o0]
+
+ENTRY(asm_stq_f24)
+ retl
+ stq %f24, [%o0]
+
+ENTRY(asm_stq_f28)
+ retl
+ stq %f28, [%o0]
+
+ENTRY(asm_stq_f32)
+ retl
+ stq %f32, [%o0]
+
+ENTRY(asm_stq_f36)
+ retl
+ stq %f36, [%o0]
+
+ENTRY(asm_stq_f40)
+ retl
+ stq %f40, [%o0]
+
+ENTRY(asm_stq_f44)
+ retl
+ stq %f44, [%o0]
+
+ENTRY(asm_stq_f48)
+ retl
+ stq %f48, [%o0]
+
+ENTRY(asm_stq_f52)
+ retl
+ stq %f52, [%o0]
+
+ENTRY(asm_stq_f56)
+ retl
+ stq %f56, [%o0]
+
+ENTRY(asm_stq_f60)
+ retl
+ stq %f60, [%o0]