Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 26 Apr 2002 20:36:16 -0700 (PDT)
From:      Jake Burkholder <jake@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 10343 for review
Message-ID:  <200204270336.g3R3aGI74416@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=10343

Change 10343 by jake@jake_sparc64 on 2002/04/26 20:35:21

	Emulate ldq and stq instructions.  gcc is now using these to load
	long doubles.  Also move the emulation of popc into userland.
	Shift some things around in the utrap code to make things more
	accessible.

Affected files ...

... //depot/projects/sparc64/lib/libc/sparc64/fpu/Makefile.inc#4 edit
... //depot/projects/sparc64/lib/libc/sparc64/fpu/fpu.c#10 edit
... //depot/projects/sparc64/lib/libc/sparc64/fpu/fpu_add.c#5 edit
... //depot/projects/sparc64/lib/libc/sparc64/fpu/fpu_explode.c#5 edit
... //depot/projects/sparc64/lib/libc/sparc64/fpu/fpu_extern.h#7 edit
... //depot/projects/sparc64/lib/libc/sparc64/fpu/fpu_implode.c#6 edit
... //depot/projects/sparc64/lib/libc/sparc64/fpu/fpu_subr.c#5 edit
... //depot/projects/sparc64/lib/libc/sparc64/sys/Makefile.inc#13 edit
... //depot/projects/sparc64/lib/libc/sparc64/sys/__sparc_utrap.c#7 edit
... //depot/projects/sparc64/lib/libc/sparc64/sys/__sparc_utrap_emul.c#1 add
... //depot/projects/sparc64/lib/libc/sparc64/sys/__sparc_utrap_private.h#6 edit
... //depot/projects/sparc64/lib/libc/sparc64/sys/__sparc_utrap_setup.c#5 edit

Differences ...

==== //depot/projects/sparc64/lib/libc/sparc64/fpu/Makefile.inc#4 (text+ko) ====

@@ -2,5 +2,7 @@
 
 .PATH: ${.CURDIR}/../libc/sparc64/fpu/
 
+CFLAGS+= -I${.CURDIR}/sparc64/sys
+
 SRCS+=	fpu.c fpu_add.c fpu_compare.c fpu_div.c fpu_explode.c fpu_implode.c \
 	fpu_mul.c fpu_reg.S fpu_sqrt.c fpu_subr.c

==== //depot/projects/sparc64/lib/libc/sparc64/fpu/fpu.c#10 (text+ko) ====

@@ -87,7 +87,7 @@
 #include <machine/pcb.h>
 #include <machine/tstate.h>
 
-#include "../sys/__sparc_utrap_private.h"
+#include "__sparc_utrap_private.h"
 #include "fpu_emu.h"
 #include "fpu_extern.h"
 
@@ -119,89 +119,52 @@
 #endif	/* FPU_DEBUG */
 
 static int __fpu_execute(struct utrapframe *, struct fpemu *, u_int32_t, u_long);
-static void utrap_write(char *);
-static void utrap_kill_self(int);
 
 /*
- * System call wrappers usable in an utrap environment.
- */
-static void
-utrap_write(char *str)
-{
-	int berrno;
-
-	berrno = errno;
-	__sys_write(STDERR_FILENO, str, strlen(str));
-	errno = berrno;
-}
-
-static void
-utrap_kill_self(sig)
-{
-	int berrno;
-
-	berrno = errno;
-	__sys_kill(__sys_getpid(), sig);
-	errno = berrno;
-}
-
-void
-__fpu_panic(char *msg)
-{
-
-	utrap_write(msg);
-	utrap_write("\n");
-	utrap_kill_self(SIGKILL);
-}
-
-/*
  * Need to use an fpstate on the stack; we could switch, so we cannot safely
  * modify the pcb one, it might get overwritten.
  */
-void
+int
 __fpu_exception(struct utrapframe *uf)
 {
 	struct fpemu fe;
 	u_long fsr, tstate;
 	u_int insn;
-	int rv;
+	int sig;
 
 	fsr = uf->uf_fsr;
 
 	switch (FSR_GET_FTT(fsr)) {
 	case FSR_FTT_NONE:
-		utrap_write("lost FPU trap type\n");
-		return;
+		__utrap_write("lost FPU trap type\n");
+		return (0);
 	case FSR_FTT_IEEE:
-		goto fatal;
+		return (SIGFPE);
 	case FSR_FTT_SEQERR:
-		utrap_write("FPU sequence error\n");
-		goto fatal;
+		__utrap_write("FPU sequence error\n");
+		return (SIGFPE);
 	case FSR_FTT_HWERR:
-		utrap_write("FPU hardware error\n");
-		goto fatal;
+		__utrap_write("FPU hardware error\n");
+		return (SIGFPE);
 	case FSR_FTT_UNFIN:
 	case FSR_FTT_UNIMP:
 		break;
 	default:
-		utrap_write("unknown FPU error\n");
-		goto fatal;
+		__utrap_write("unknown FPU error\n");
+		return (SIGFPE);
 	}
 
 	fe.fe_fsr = fsr & ~FSR_FTT_MASK;
 	insn = *(u_int32_t *)uf->uf_pc;
 	if (IF_OP(insn) != IOP_MISC || (IF_F3_OP3(insn) != INS2_FPop1 &&
 	    IF_F3_OP3(insn) != INS2_FPop2))
-		__fpu_panic("bogus FP fault");
+		__utrap_panic("bogus FP fault");
 	tstate = uf->uf_state;
-	rv = __fpu_execute(uf, &fe, insn, tstate);
-	if (rv != 0)
-		utrap_kill_self(rv);
+	sig = __fpu_execute(uf, &fe, insn, tstate);
+	if (sig != 0)
+		return (sig);
 	__asm __volatile("ldx %0, %%fsr" : : "m" (fe.fe_fsr));
-	return;
-fatal:
-	utrap_kill_self(SIGFPE);
-	return;
+	return (0);
 }
 
 #ifdef FPU_DEBUG
@@ -223,29 +186,6 @@
 }
 #endif
 
-static u_long
-fetch_reg(struct utrapframe *uf, int reg)
-{
-	u_long offs;
-	struct frame *frm;
-
-	if (reg == IREG_G0)
-		return (0);
-	else if (reg < IREG_O0)	/* global */
-		return (uf->uf_global[reg]);
-	else if (reg < IREG_L0)	/* out */
-		return (uf->uf_out[reg - IREG_O0]);
-	else {			/* local, in */
-		/*
-		 * The in registers are immediately after the locals in
-		 * the frame.
-		 */
-		frm = (struct frame *)(uf->uf_out[6] + SPOFF);
-		return (frm->fr_local[reg - IREG_L0]);
-	}
-	__fpu_panic("fetch_reg: bogus register");
-}
-
 static void
 __fpu_mov(struct fpemu *fe, int type, int rd, int rs1, int rs2)
 {
@@ -361,32 +301,32 @@
 		    (tstate & TSTATE_XCC_MASK) >> (TSTATE_XCC_SHIFT));
 		return (0);
 	case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_Z)):
-		reg = fetch_reg(uf, IF_F4_RS1(insn));
+		reg = __emul_fetch_reg(uf, IF_F4_RS1(insn));
 		if (reg == 0)
 			__fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
 		return (0);
 	case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_LEZ)):
-		reg = fetch_reg(uf, IF_F4_RS1(insn));
+		reg = __emul_fetch_reg(uf, IF_F4_RS1(insn));
 		if (reg <= 0)
 			__fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
 		return (0);
 	case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_LZ)):
-		reg = fetch_reg(uf, IF_F4_RS1(insn));
+		reg = __emul_fetch_reg(uf, IF_F4_RS1(insn));
 		if (reg < 0)
 			__fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
 		return (0);
 	case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_NZ)):
-		reg = fetch_reg(uf, IF_F4_RS1(insn));
+		reg = __emul_fetch_reg(uf, IF_F4_RS1(insn));
 		if (reg != 0)
 			__fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
 		return (0);
 	case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_GZ)):
-		reg = fetch_reg(uf, IF_F4_RS1(insn));
+		reg = __emul_fetch_reg(uf, IF_F4_RS1(insn));
 		if (reg > 0)
 			__fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
 		return (0);
 	case FOP(INS2_FPop2, INSFP2_FMOV_RC(IRCOND_GEZ)):
-		reg = fetch_reg(uf, IF_F4_RS1(insn));
+		reg = __emul_fetch_reg(uf, IF_F4_RS1(insn));
 		if (reg >= 0)
 			__fpu_mov(fe, type, rd, __fpu_getreg(rs2), rs2);
 		return (0);

==== //depot/projects/sparc64/lib/libc/sparc64/fpu/fpu_add.c#5 (text+ko) ====

@@ -62,6 +62,7 @@
 #include "fpu_arith.h"
 #include "fpu_emu.h"
 #include "fpu_extern.h"
+#include "__sparc_utrap_private.h"
 
 struct fpn *
 __fpu_add(fe)
@@ -198,7 +199,7 @@
 			 */
 #ifdef DIAGNOSTIC
 			if (x->fp_exp != y->fp_exp || r->fp_sticky)
-				__fpu_panic("fpu_add");
+				__utrap_panic("fpu_add");
 #endif
 			r->fp_sign = y->fp_sign;
 			FPU_SUBS(r3, 0, r3);

==== //depot/projects/sparc64/lib/libc/sparc64/fpu/fpu_explode.c#5 (text+ko) ====

@@ -62,6 +62,7 @@
 #include "fpu_arith.h"
 #include "fpu_emu.h"
 #include "fpu_extern.h"
+#include "__sparc_utrap_private.h"
 
 /*
  * N.B.: in all of the following, we assume the FP format is
@@ -278,7 +279,7 @@
 		break;
 
 	default:
-		__fpu_panic("fpu_explode");
+		__utrap_panic("fpu_explode");
 	}
 
 	if (s == FPC_QNAN && (fp->fp_mant[0] & FP_QUIETBIT) == 0) {

==== //depot/projects/sparc64/lib/libc/sparc64/fpu/fpu_extern.h#7 (text+ko) ====

@@ -40,16 +40,13 @@
 #ifndef _SPARC64_FPU_FPU_EXTERN_H_
 #define _SPARC64_FPU_FPU_EXTERN_H_
 
-struct proc;
-struct fpstate;
 struct utrapframe;
 union instr;
 struct fpemu;
 struct fpn;
 
 /* fpu.c */
-void __fpu_exception(struct utrapframe *tf);
-void __fpu_panic(char *msg);
+int __fpu_exception(struct utrapframe *tf);
 
 /* fpu_add.c */
 struct fpn *__fpu_add(struct fpemu *);

==== //depot/projects/sparc64/lib/libc/sparc64/fpu/fpu_implode.c#6 (text+ko) ====

@@ -62,6 +62,7 @@
 #include "fpu_arith.h"
 #include "fpu_emu.h"
 #include "fpu_extern.h"
+#include "__sparc_utrap_private.h"
 
 static int round(struct fpemu *, struct fpn *);
 static int toinf(struct fpemu *, int);
@@ -354,7 +355,7 @@
 	(void) __fpu_shr(fp, FP_NMANT - FP_NG - 1 - SNG_FRACBITS);
 #ifdef DIAGNOSTIC
 	if ((fp->fp_mant[3] & SNG_EXP(1 << FP_NG)) == 0)
-		__fpu_panic("fpu_ftos");
+		__utrap_panic("fpu_ftos");
 #endif
 	if (round(fe, fp) && fp->fp_mant[3] == SNG_EXP(2))
 		exp++;
@@ -529,7 +530,7 @@
 		break;
 
 	default:
-		__fpu_panic("fpu_implode");
+		__utrap_panic("fpu_implode");
 	}
 	DPRINTF(FPE_REG, ("fpu_implode: %x %x %x %x\n",
 		space[0], space[1], space[2], space[3]));

==== //depot/projects/sparc64/lib/libc/sparc64/fpu/fpu_subr.c#5 (text+ko) ====

@@ -60,6 +60,7 @@
 #include "fpu_arith.h"
 #include "fpu_emu.h"
 #include "fpu_extern.h"
+#include "__sparc_utrap_private.h"
 
 /*
  * Shift the given number right rsh bits.  Any bits that `fall off' will get
@@ -75,7 +76,7 @@
 
 #ifdef DIAGNOSTIC
 	if (rsh <= 0 || (fp->fp_class != FPC_NUM && !ISNAN(fp)))
-		__fpu_panic("fpu_rightshift 1");
+		__utrap_panic("fpu_rightshift 1");
 #endif
 
 	m0 = fp->fp_mant[0];
@@ -87,7 +88,7 @@
 	if (rsh >= FP_NMANT) {
 #ifdef DIAGNOSTIC
 		if ((m0 | m1 | m2 | m3) == 0)
-			__fpu_panic("fpu_rightshift 2");
+			__utrap_panic("fpu_rightshift 2");
 #endif
 		fp->fp_mant[0] = 0;
 		fp->fp_mant[1] = 0;

==== //depot/projects/sparc64/lib/libc/sparc64/sys/Makefile.inc#13 (text+ko) ====

@@ -1,7 +1,9 @@
 # $FreeBSD: src/lib/libc/sparc64/sys/Makefile.inc,v 1.3 2002/01/01 21:59:53 jake Exp $
 
-SRCS+=	__sparc_utrap.c __sparc_utrap_fp_disabled.S __sparc_utrap_gen.S \
-	__sparc_utrap_install.c __sparc_utrap_setup.c
+SRCS+=	__sparc_utrap.c __sparc_utrap_emul.c __sparc_utrap_fp_disabled.S \
+	__sparc_utrap_gen.S __sparc_utrap_install.c __sparc_utrap_setup.c
+
+CFLAGS+= -I${.CURDIR}/sparc64/fpu
 
 MDASM+=	brk.S cerror.S exect.S pipe.S ptrace.S sbrk.S setlogin.S
 

==== //depot/projects/sparc64/lib/libc/sparc64/sys/__sparc_utrap.c#7 (text+ko) ====

@@ -32,8 +32,11 @@
 #include <machine/utrap.h>
 #include <machine/sysarch.h>
 
+#include <errno.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 
 #include "__sparc_utrap_private.h"
 
@@ -77,23 +80,56 @@
 void
 __sparc_utrap(struct utrapframe *uf)
 {
+	int sig;
 
 	switch (uf->uf_type) {
 	case UT_FP_EXCEPTION_IEEE_754:
 	case UT_FP_EXCEPTION_OTHER:
-		__fpu_exception(uf);
-		UF_DONE(uf);
-		return;
+		sig = __fpu_exception(uf);
+		break;
 	case UT_ILLEGAL_INSTRUCTION:
+		sig = __emul_insn(uf);
+		break;
 	case UT_MEM_ADDRESS_NOT_ALIGNED:
 		break;
-	case UT_TRAP_INSTRUCTION_16:
-		UF_DONE(uf);
-		return;
 	default:
 		break;
 	}
-	printf("__sparc_utrap: type=%s pc=%#lx npc=%#lx\n",
-	    utrap_msg[uf->uf_type], uf->uf_pc, uf->uf_npc);
-	abort();
+	if (sig) {
+		__utrap_write("__sparc_utrap: fatal ");
+		__utrap_write(utrap_msg[uf->uf_type]);
+		__utrap_write("\n");
+		__utrap_kill_self(sig);
+		/* NOTREACHED */
+	}
+	UF_DONE(uf);
+}
+
+void
+__utrap_write(const char *str)
+{
+	int berrno;
+
+	berrno = errno;
+	__sys_write(STDERR_FILENO, str, strlen(str));
+	errno = berrno;
+}
+
+void
+__utrap_kill_self(sig)
+{
+	int berrno;
+
+	berrno = errno;
+	__sys_kill(__sys_getpid(), sig);
+	errno = berrno;
+}
+
+void
+__utrap_panic(const char *msg)
+{
+
+	__utrap_write(msg);
+	__utrap_write("\n");
+	__utrap_kill_self(SIGKILL);
 }

==== //depot/projects/sparc64/lib/libc/sparc64/sys/__sparc_utrap_private.h#6 (text+ko) ====

@@ -50,6 +50,16 @@
 extern char __sparc_utrap_fp_disabled[];
 extern char __sparc_utrap_gen[];
 
+int __emul_insn(struct utrapframe *uf);
+u_long __emul_fetch_reg(struct utrapframe *uf, int reg);
+void __emul_store_reg(struct utrapframe *uf, int reg, u_long val);
+u_long __emul_f3_op2(struct utrapframe *uf, u_int insn);
+u_long __emul_f3_memop_addr(struct utrapframe *uf, u_int insn);
+
 void __sparc_utrap(struct utrapframe *);
 
+void __utrap_write(const char *);
+void __utrap_kill_self(int);
+void __utrap_panic(const char *);
+
 #endif

==== //depot/projects/sparc64/lib/libc/sparc64/sys/__sparc_utrap_setup.c#5 (text+ko) ====

@@ -40,8 +40,8 @@
 	{ UT_FP_DISABLED, __sparc_utrap_fp_disabled, NULL, NULL, NULL },
 	{ UT_FP_EXCEPTION_IEEE_754, __sparc_utrap_gen, NULL, NULL, NULL },
 	{ UT_FP_EXCEPTION_OTHER, __sparc_utrap_gen, NULL, NULL, NULL },
+	{ UT_ILLEGAL_INSTRUCTION, __sparc_utrap_gen, NULL, NULL, NULL },
 #if 0
-	{ UT_ILLEGAL_INSTRUCTION, __sparc_utrap_gen, NULL, NULL, NULL },
 	{ UT_MEM_ADDRESS_NOT_ALIGNED, __sparc_utrap_gen, NULL, NULL, NULL },
 #endif
 	{ UT_TRAP_INSTRUCTION_16, __sparc_utrap_gen, NULL, NULL, NULL },

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200204270336.g3R3aGI74416>