]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/bcm/vfp3.c
merge
[plan9front.git] / sys / src / 9 / bcm / vfp3.c
index b1c381274f09442ef2b40d6a5787030af861a0c7..cefeda2618ca51751f101685da8330ed7ab4128c 100644 (file)
@@ -163,7 +163,10 @@ fpcfg(void)
        static int printed;
 
        /* clear pending exceptions; no traps in vfp3; all v7 ops are scalar */
-       m->fpscr = Dn | Fz | FPRNR | (FPINVAL | FPZDIV | FPOVFL) & ~Alltraps;
+       m->fpscr = Dn | FPRNR | (FPINVAL | FPZDIV | FPOVFL) & ~Alltraps;
+       /* VFPv2 needs software support for underflows, so force them to zero */
+       if(m->havefp == VFPv2)
+               m->fpscr |= Fz;
        fpwr(Fpscr, m->fpscr);
        m->fpconfiged = 1;
 
@@ -278,7 +281,7 @@ fpuprocsave(Proc *p)
 {
        if(p->fpstate == FPactive){
                if(p->state == Moribund)
-                       fpclear();
+                       fpoff();
                else{
                        /*
                         * Fpsave() stores without handling pending
@@ -335,8 +338,12 @@ fpuprocfork(Proc *p)
 void
 fpusysprocsetup(Proc *p)
 {
+       int s;
+
+       s = splhi();
        p->fpstate = FPinit;
        fpoff();
+       splx(s);
 }
 
 static void
@@ -371,8 +378,6 @@ mathnote(void)
 static void
 mathemu(Ureg *)
 {
-       if(m->havefp == VFPv3 && !(fprd(Fpexc) & (Fpex|Fpdex)))
-               iprint("mathemu: not an FP exception but an unknown FP opcode\n");
        switch(up->fpstate){
        case FPemu:
                error("illegal instruction: VFP opcode in emulated mode");
@@ -472,6 +477,7 @@ fpuemu(Ureg* ureg)
 {
        int s, nfp, cop, op;
        uintptr pc;
+       static int already;
 
        if(waserror()){
                postnote(up, 1, up->errstr, NDebug);
@@ -484,16 +490,14 @@ fpuemu(Ureg* ureg)
        nfp = 0;
        pc = ureg->pc;
        validaddr(pc, 4, 0);
-       if(!condok(ureg->psr, *(ulong*)pc >> 28))
-               iprint("fpuemu: conditional instr shouldn't have got here\n");
        op  = (*(ulong *)pc >> 24) & MASK(4);
        cop = (*(ulong *)pc >>  8) & MASK(4);
        if(m->fpon)
                fpstuck(pc);            /* debugging; could move down 1 line */
        if (ISFPAOP(cop, op)) {         /* old arm 7500 fpa opcode? */
-//             iprint("fpuemu: fpa instr %#8.8lux at %#p\n", *(ulong *)pc, pc);
-//             error("illegal instruction: old arm 7500 fpa opcode");
                s = spllo();
+               if(!already++)
+                       pprint("warning: emulated arm7500 fpa instr %#8.8lux at %#p\n", *(ulong *)pc, pc);
                if(waserror()){
                        splx(s);
                        nexterror();
@@ -503,7 +507,7 @@ fpuemu(Ureg* ureg)
                        m->fppc = m->fpcnt = 0;
                splx(s);
                poperror();
-       } else if (ISVFPOP(cop, op)) {  /* if vfp, fpu must be off */
+       } else if (ISVFPOP(cop, op)) {  /* if vfp, fpu off or unsupported instruction */
                mathemu(ureg);          /* enable fpu & retry */
                nfp = 1;
        }