From owner-p4-projects Fri Apr 26 20:37: 2 2002 Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C7CC737B423; Fri, 26 Apr 2002 20:36:19 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 01DE937B416 for ; Fri, 26 Apr 2002 20:36:17 -0700 (PDT) Received: (from perforce@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id g3R3aGI74416 for perforce@freebsd.org; Fri, 26 Apr 2002 20:36:16 -0700 (PDT) (envelope-from jake@freebsd.org) Date: Fri, 26 Apr 2002 20:36:16 -0700 (PDT) Message-Id: <200204270336.g3R3aGI74416@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: perforce set sender to jake@freebsd.org using -f From: Jake Burkholder Subject: PERFORCE change 10343 for review To: Perforce Change Reviews Sender: owner-p4-projects@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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 #include -#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 #include +#include +#include #include #include +#include #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