Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sparc/fpu merge in ultrasparc changes



details:   https://anonhg.NetBSD.org/src/rev/504edd24f98d
branches:  trunk
changeset: 488096:504edd24f98d
user:      mrg <mrg%NetBSD.org@localhost>
date:      Sun Jun 18 06:54:17 2000 +0000

description:
merge in ultrasparc changes

diffstat:

 sys/arch/sparc/fpu/fpu.c         |  178 ++++++++++++++++++++++++++++++++++++++-
 sys/arch/sparc/fpu/fpu_emu.h     |    7 +-
 sys/arch/sparc/fpu/fpu_explode.c |   39 ++++++++-
 sys/arch/sparc/fpu/fpu_extern.h  |   18 +++-
 sys/arch/sparc/fpu/fpu_implode.c |   61 +++++++++++++-
 5 files changed, 296 insertions(+), 7 deletions(-)

diffs (truncated from 512 to 300 lines):

diff -r 61ebcb5e7cd4 -r 504edd24f98d sys/arch/sparc/fpu/fpu.c
--- a/sys/arch/sparc/fpu/fpu.c  Sun Jun 18 05:20:27 2000 +0000
+++ b/sys/arch/sparc/fpu/fpu.c  Sun Jun 18 06:54:17 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu.c,v 1.6 1997/07/29 10:09:51 fair Exp $ */
+/*     $NetBSD: fpu.c,v 1.7 2000/06/18 06:54:17 mrg Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -98,7 +98,11 @@
 void
 fpu_cleanup(p, fs)
        register struct proc *p;
+#ifndef SUN4U
        register struct fpstate *fs;
+#else /* SUN4U */
+       register struct fpstate64 *fs;
+#endif /* SUN4U */
 {
        register int i, fsr = fs->fs_fsr, error;
        union instr instr;
@@ -107,7 +111,7 @@
        switch ((fsr >> FSR_FTT_SHIFT) & FSR_FTT_MASK) {
 
        case FSR_TT_NONE:
-               panic("fpu_cleanup 1"); /* ??? */
+               panic("fpu_cleanup: No fault"); /* ??? */
                break;
 
        case FSR_TT_IEEE:
@@ -118,9 +122,18 @@
                break;          /* XXX should return, but queue remains */
 
        case FSR_TT_UNFIN:
+#ifdef SUN4U
+               if (fs->fs_qsize == 0) {
+                       printf("fpu_cleanup: unfinished fpop");
+                       /* The book sez reexecute or emulate. */
+                       return;
+               }
+               break;
+
+#endif /* SUN4U */
        case FSR_TT_UNIMP:
                if (fs->fs_qsize == 0)
-                       panic("fpu_cleanup 2");
+                       panic("fpu_cleanup: unimplemented fpop");
                break;
 
        case FSR_TT_SEQ:
@@ -159,6 +172,12 @@
                        break;
 
                case NOTFPU:
+#ifdef SUN4U
+#ifdef DEBUG
+                       printf("fpu_cleanup: not an FPU error -- sending SIGILL\n", p);
+                       Debugger();
+#endif
+#endif /* SUN4U */
                        trapsignal(p, SIGILL, 0);       /* ??? code?  */
                        break;
 
@@ -183,7 +202,11 @@
 fpu_emulate(p, tf, fs)
        struct proc *p;
        register struct trapframe *tf;
+#ifndef SUN4U
        register struct fpstate *fs;
+#else /* SUN4U */
+       register struct fpstate64 *fs;
+#endif /* SUN4U */
 {
 
        do {
@@ -234,8 +257,13 @@
        union instr instr;
 {
        register struct fpn *fp;
+#ifndef SUN4U
        register int opf, rs1, rs2, rd, type, mask, fsr, cx;
        register struct fpstate *fs;
+#else /* SUN4U */
+       register int opf, rs1, rs2, rd, type, mask, fsr, cx, i, cond;
+       register struct fpstate64 *fs;
+#endif /* SUN4U */
        u_int space[4];
 
        /*
@@ -256,6 +284,119 @@
        fs = fe->fe_fpstate;
        fe->fe_fsr = fs->fs_fsr & ~FSR_CX;
        fe->fe_cx = 0;
+#ifdef SUN4U
+       /*
+        * Check to see if we're dealing with a fancy cmove and handle
+        * it first.
+        */
+       if (instr.i_op3.i_op3 == IOP3_FPop2 && (opf&0xff0) != (FCMP&0xff0)) {
+               switch (opf >>= 2) {
+               case FMVFC0 >> 2:
+                       cond = (fs->fs_fsr>>FSR_FCC_SHIFT)&FSR_FCC_MASK;
+                       if (instr.i_fmovcc.i_cond != cond) return(0); /* success */
+                       rs1 = fs->fs_regs[rs2];
+                       goto mov;
+               case FMVFC1 >> 2:
+                       cond = (fs->fs_fsr>>FSR_FCC1_SHIFT)&FSR_FCC_MASK;
+                       if (instr.i_fmovcc.i_cond != cond) return(0); /* success */
+                       rs1 = fs->fs_regs[rs2];
+                       goto mov;
+               case FMVFC2 >> 2:
+                       cond = (fs->fs_fsr>>FSR_FCC2_SHIFT)&FSR_FCC_MASK;
+                       if (instr.i_fmovcc.i_cond != cond) return(0); /* success */
+                       rs1 = fs->fs_regs[rs2];
+                       goto mov;
+               case FMVFC3 >> 2:
+                       cond = (fs->fs_fsr>>FSR_FCC3_SHIFT)&FSR_FCC_MASK;
+                       if (instr.i_fmovcc.i_cond != cond) return(0); /* success */
+                       rs1 = fs->fs_regs[rs2];
+                       goto mov;
+               case FMVIC >> 2:
+                       /* Presume we're curproc */
+                       cond = (curproc->p_md.md_tf->tf_tstate>>TSTATE_CCR_SHIFT)&PSR_ICC;
+                       if (instr.i_fmovcc.i_cond != cond) return(0); /* success */
+                       rs1 = fs->fs_regs[rs2];
+                       goto mov;                       
+               case FMVXC >> 2:
+                       /* Presume we're curproc */
+                       cond = (curproc->p_md.md_tf->tf_tstate>>(TSTATE_CCR_SHIFT+XCC_SHIFT))&PSR_ICC;
+                       if (instr.i_fmovcc.i_cond != cond) return(0); /* success */
+                       rs1 = fs->fs_regs[rs2];
+                       goto mov;                       
+               case FMVRZ >> 2:
+                       /* Presume we're curproc */
+                       rs1 = instr.i_fmovr.i_rs1;
+                       if (rs1 != 0 && (int64_t)curproc->p_md.md_tf->tf_global[rs1] != 0)
+                               return (0); /* success */
+                       rs1 = fs->fs_regs[rs2];
+                       goto mov;                       
+               case FMVRLEZ >> 2:
+                       /* Presume we're curproc */
+                       rs1 = instr.i_fmovr.i_rs1;
+                       if (rs1 != 0 && (int64_t)curproc->p_md.md_tf->tf_global[rs1] > 0)
+                               return (0); /* success */
+                       rs1 = fs->fs_regs[rs2];
+                       goto mov;                       
+               case FMVRLZ >> 2:
+                       /* Presume we're curproc */
+                       rs1 = instr.i_fmovr.i_rs1;
+                       if (rs1 == 0 || (int64_t)curproc->p_md.md_tf->tf_global[rs1] >= 0)
+                               return (0); /* success */
+                       rs1 = fs->fs_regs[rs2];
+                       goto mov;                       
+               case FMVRNZ >> 2:
+                       /* Presume we're curproc */
+                       rs1 = instr.i_fmovr.i_rs1;
+                       if (rs1 == 0 || (int64_t)curproc->p_md.md_tf->tf_global[rs1] == 0)
+                               return (0); /* success */
+                       rs1 = fs->fs_regs[rs2];
+                       goto mov;                       
+               case FMVRGZ >> 2:
+                       /* Presume we're curproc */
+                       rs1 = instr.i_fmovr.i_rs1;
+                       if (rs1 == 0 || (int64_t)curproc->p_md.md_tf->tf_global[rs1] <= 0)
+                               return (0); /* success */
+                       rs1 = fs->fs_regs[rs2];
+                       goto mov;                       
+               case FMVRGEZ >> 2:
+                       /* Presume we're curproc */
+                       rs1 = instr.i_fmovr.i_rs1;
+                       if (rs1 != 0 && (int64_t)curproc->p_md.md_tf->tf_global[rs1] < 0)
+                               return (0); /* success */
+                       rs1 = fs->fs_regs[rs2];
+                       goto mov;                       
+               case FCMP >> 2:
+                       fpu_explode(fe, &fe->fe_f1, type, rs1);
+                       fpu_explode(fe, &fe->fe_f2, type, rs2);
+                       fpu_compare(fe, 0);
+                       goto cmpdone;
+                       
+               case FCMPE >> 2:
+                       fpu_explode(fe, &fe->fe_f1, type, rs1);
+                       fpu_explode(fe, &fe->fe_f2, type, rs2);
+                       fpu_compare(fe, 1);
+               cmpdone:
+                       /*
+                        * The only possible exception here is NV; catch it
+                        * early and get out, as there is no result register.
+                        */
+                       cx = fe->fe_cx;
+                       fsr = fe->fe_fsr | (cx << FSR_CX_SHIFT);
+                       if (cx != 0) {
+                               if (fsr & (FSR_NV << FSR_TEM_SHIFT)) {
+                                       fs->fs_fsr = (fsr & ~FSR_FTT) |
+                                               (FSR_TT_IEEE << FSR_FTT_SHIFT);
+                                       return (FPE);
+                               }
+                               fsr |= FSR_NV << FSR_AX_SHIFT;
+                       }
+                       fs->fs_fsr = fsr;
+                       return (0);
+               default:
+                       return (NOTFPU);
+               }
+       }
+#endif /* SUN4U */
        switch (opf >>= 2) {
 
        default:
@@ -272,7 +413,14 @@
        case FABS >> 2:
                rs1 = fs->fs_regs[rs2] & ~(1 << 31);
        mov:
+#ifndef SUN4U
                fs->fs_regs[rd] = rs1;
+#else /* SUN4U */
+               i = 1<<type;
+               fs->fs_regs[rd++] = rs1;
+               while (--i) 
+                       fs->fs_regs[rd++] = fs->fs_regs[++rs2];
+#endif /* SUN4U */
                fs->fs_fsr = fe->fe_fsr;
                return (0);     /* success */
 
@@ -305,6 +453,7 @@
                fp = fpu_div(fe);
                break;
 
+#ifndef SUN4U
        case FCMP >> 2:
                fpu_explode(fe, &fe->fe_f1, type, rs1);
                fpu_explode(fe, &fe->fe_f2, type, rs2);
@@ -333,6 +482,7 @@
                fs->fs_fsr = fsr;
                return (0);
 
+#endif /* not SUN4U */
        case FSMULD >> 2:
        case FDMULX >> 2:
                if (type == FTYPE_EXT)
@@ -343,9 +493,27 @@
                fp = fpu_mul(fe);
                break;
 
+#ifdef SUN4U
+       case FXTOS >> 2:
+       case FXTOD >> 2:
+       case FXTOQ >> 2:
+               type = FTYPE_LNG;
+               fpu_explode(fe, fp = &fe->fe_f1, type, rs2);
+               type = opf & 3; /* sneaky; depends on instruction encoding */
+               break;
+
+       case FTOX >> 2:
+               fpu_explode(fe, fp = &fe->fe_f1, type, rs2);
+               type = FTYPE_LNG;
+#endif /* SUN4U */
+
        case FTOS >> 2:
        case FTOD >> 2:
+#ifndef SUN4U
        case FTOX >> 2:
+#else /* SUN4U */
+       case FTOQ >> 2:
+#endif /* SUN4U */
        case FTOI >> 2:
                fpu_explode(fe, fp = &fe->fe_f1, type, rs2);
                type = opf & 3; /* sneaky; depends on instruction encoding */
@@ -374,7 +542,11 @@
        }
        fs->fs_fsr = fsr;
        fs->fs_regs[rd] = space[0];
+#ifndef SUN4U
        if (type >= FTYPE_DBL) {
+#else /* SUN4U */
+       if (type >= FTYPE_DBL || type == FTYPE_LNG) {
+#endif /* SUN4U */
                fs->fs_regs[rd + 1] = space[1];
                if (type > FTYPE_DBL) {
                        fs->fs_regs[rd + 2] = space[2];
diff -r 61ebcb5e7cd4 -r 504edd24f98d sys/arch/sparc/fpu/fpu_emu.h
--- a/sys/arch/sparc/fpu/fpu_emu.h      Sun Jun 18 05:20:27 2000 +0000
+++ b/sys/arch/sparc/fpu/fpu_emu.h      Sun Jun 18 06:54:17 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu_emu.h,v 1.2 1994/11/20 20:52:39 deraadt Exp $ */
+/*     $NetBSD: fpu_emu.h,v 1.3 2000/06/18 06:54:17 mrg Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -90,6 +90,7 @@
 #define        FP_NMANT        115             /* total bits in mantissa (incl g,r) */
 #define        FP_NG           2               /* number of low-order guard bits */
 #define        FP_LG           ((FP_NMANT - 1) & 31)   /* log2(1.0) for fp_mant[0] */
+#define        FP_LG2          ((FP_NMANT - 1) & 63)   /* log2(1.0) for fp_mant[0] and fp_mant[1] */
 #define        FP_QUIETBIT     (1 << (FP_LG - 1))      /* Quiet bit in NaNs (0.5) */
 #define        FP_1            (1 << FP_LG)            /* 1.0 in fp_mant[0] */
 #define        FP_2            (1 << (FP_LG + 1))      /* 2.0 in fp_mant[0] */
@@ -138,7 +139,11 @@
  * Emulator state.
  */



Home | Main Index | Thread Index | Old Index