Port-mips archive

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

Re: Does umimplemnted insn emulation work in -current?



> > -   lw      a0, 0(a2)                       # a0 = coproc instruction
> > +   lw              a0, 4(a2)               # a0 = coproc instruction
 :
> I'll revert the above line in a few days if there is no objection.

The attached patch also fixes PR 35326 (FPU siginfo),
36251 and 42887 (FPEmul cvt_d_s).

---
Izumi Tsutsui

Index: mips/fp.S
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/fp.S,v
retrieving revision 1.37
diff -u -p -r1.37 fp.S
--- mips/fp.S   14 Dec 2009 00:46:06 -0000      1.37
+++ mips/fp.S   27 Jan 2011 13:11:13 -0000
@@ -847,6 +847,7 @@ bcemul_branch:
        jal     _C_LABEL(fuiword)
 
        move    a0, v0
+       move    a3, a2                  # save fpstat for bcemul_sigfpe()
        REG_L   a1, CALLFRAME_FRAME(sp)
        REG_L   a2, CALLFRAME_CAUSE(sp)
 
@@ -1813,6 +1814,8 @@ cvt_d_s:
        beq     t2, zero, result_fs_d           # is FS zero?
        jal     _C_LABEL(renorm_fs_s)
        move    t8, zero
+       sll     t3, t2, 32 - 3                  # convert S fraction to D
+       srl     t2, t2, 3
        b       norm_d
 2:
        addu    t1, t1, DEXP_BIAS - SEXP_BIAS   # bias exponent correctly
@@ -2762,6 +2765,7 @@ fpe_trap:
        #nop
        INT_S   a2, PCB_FPREGS+FRAME_FSR(v0)
 #endif
+       move    a3, a2                          # fpustat
        REG_L   a1, CALLFRAME_SIZ + 1*SZREG(sp) # frame
        REG_L   a2, CALLFRAME_SIZ + 2*SZREG(sp) # cause
        REG_L   ra, CALLFRAME_RA(sp)
@@ -5155,10 +5159,9 @@ STATIC_XLEAF(bcemul_sigill)
        REG_S   a2, FRAME_CAUSE(a1)
        REG_EPILOGUE
 
-       move    a2, a0                          # code = instruction
-       move    a0, MIPS_CURLWP                 # get current process
-       li      a1, SIGILL
-       j       _C_LABEL(fpemul_trapsignal)
+       move    a1, a0                          # 2nd arg: instruction
+       move    a0, MIPS_CURLWP                 # 1st arg: curlwp
+       j       _C_LABEL(mips_fpuillinst)
 END(fpemul_sigill)
 
 STATIC_LEAF(fpemul_sigfpe)
@@ -5169,10 +5172,9 @@ STATIC_LEAF(fpemul_sigfpe)
        REG_S   a2, FRAME_CAUSE(a1)
        REG_EPILOGUE
 
-       move    a2, a0                          # code = instruction
-       move    a0, MIPS_CURLWP                 # get current process
-       li      a1, SIGFPE
-       j       _C_LABEL(fpemul_trapsignal)
+       move    a1, a3                          # 2nd arg: fpstat
+       move    a0, MIPS_CURLWP                 # 1st arg: curlwp
+       j       _C_LABEL(mips_fpuexcept)
 END(fpemul_sigfpe)
 
 #ifdef SOFTFLOAT
@@ -5184,9 +5186,8 @@ STATIC_LEAF(bcemul_sigfpe)
        REG_S   a2, FRAME_CAUSE(a1)
        REG_EPILOGUE
 
-       move    a2, a0                          # code = instruction
-       move    a0, MIPS_CURLWP                 # get current process
-       li      a1, SIGFPE
-       j       _C_LABEL(fpemul_trapsignal)
+       move    a1, a3                          # 2nd arg: fpstat
+       move    a0, MIPS_CURLWP                 # 1st arg: current process
+       j       _C_LABEL(mips_fpuexcept)
 END(bcemul_sigfpe)
 #endif
Index: mips/locore.S
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/locore.S,v
retrieving revision 1.175
diff -u -p -r1.175 locore.S
--- mips/locore.S       26 Jan 2011 01:18:54 -0000      1.175
+++ mips/locore.S       27 Jan 2011 13:11:13 -0000
@@ -639,17 +639,11 @@ END(mips_cp0_tlb_page_mask_probe)
  *     Handle a floating point interrupt (r3k) or trap (r4k).
  *     the handlers are indentical, only the reporting mechanisms differ.
  *
- *     MachFPInterrupt(status, cause, pc, frame)
- *             unsigned status;
- *             unsigned cause;
- *             unsigned pc;
- *             int *frame;
+ *     MachFPInterrupt(uint32_t status, uint32_t cause, vaddr_t pc,
+ *         struct frame *frame)
  *
- *     MachFPTrap(status, cause, pc, frame)
- *             unsigned status;
- *             unsigned cause;
- *             unsigned pc;
- *             int *frame;
+ *     MachFPTrap(uint32_t status, uint32_t cause, vaddr_t pc,
+ *         struct frame *frame)
  *
  * Results:
  *     None.
@@ -676,13 +670,11 @@ XNESTED(MachFPTrap)
        bgez            t2, 3f                  # no, normal trap
        nop
 /*
- * We got an unimplemented operation trap so
- * We received an unimplemented operation trap.
+ * We received an unimplemented operation trap so
+ * fetch the instruction and emulate the instruction.
  *
  * We check whether it's an unimplemented FP instruction here rather
  * than invoking MachEmulateInst(), since it is faster.
- *
- * fetch the instruction and emulate the instruction.
  */
        bgez            a1, 1f                  # Check the branch delay bit.
        nop
@@ -692,13 +684,11 @@ XNESTED(MachFPTrap)
        b               2f
        lw              a0, 4(a2)               # a0 = coproc instruction
 /*
- * This is not in the branch delay slot so calculate the resulting
- * PC (epc + 4) into v0 and continue to MachEmulateFP().
+ * This is not in the branch delay slot.
  */
 1:
-       lw              a0, 4(a2)               # a0 = coproc instruction
+       lw              a0, 0(a2)               # a0 = coproc instruction
 2:
-       move            a2, a1
 
 /*
  * Check to see if the instruction to be emulated is a floating-point
@@ -718,9 +708,9 @@ XNESTED(MachFPTrap)
        REG_S           a1, FRAME_CAUSE(a3)
        REG_EPILOGUE
 
-       move            a1, a0                          # code = instruction
+       move            a1, a0                          # 2nd arg: instruction
        jal             _C_LABEL(mips_fpuillinst)
-       move            a0, MIPS_CURLWP                 # get current LWP
+       move            a0, MIPS_CURLWP                 # 1st arg: curlwp
 
        b               FPReturn
        nop
@@ -737,9 +727,9 @@ XNESTED(MachFPTrap)
        and             a0, t0, ~MIPS_FPU_EXCEPTION_BITS
        ctc1            a0, MIPS_FPU_CSR
 
-       move            a1, t0                  # FPU status
+       move            a1, t0                  # 2nd arg: fpstat
        jal             _C_LABEL(mips_fpuexcept)
-       move            a0, MIPS_CURLWP         # get current LWP
+       move            a0, MIPS_CURLWP         # 1st arg: curlwp
 
        b               FPReturn
        nop
@@ -748,8 +738,10 @@ XNESTED(MachFPTrap)
  * Finally, we can call MachEmulateFP() where a0 is the instruction to emulate.
  */
 4:
+                                               # 1st arg: a0 = instruction
+       move            a2, a1                  # 3rd arg: cause
        jal             _C_LABEL(MachEmulateFP)
-       move            a1, a3
+       move            a1, a3                  # 2nd arg: frame
 
 /*
  * Turn off the floating point coprocessor and return.
Index: mips/mips_fputrap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/mips_fputrap.c,v
retrieving revision 1.6
diff -u -p -r1.6 mips_fputrap.c
--- mips/mips_fputrap.c 14 Dec 2009 00:46:06 -0000      1.6
+++ mips/mips_fputrap.c 27 Jan 2011 13:11:13 -0000
@@ -34,33 +34,45 @@
 #include <mips/cpuregs.h>
 #include <mips/regnum.h>
 
-#ifndef SOFTFLOAT
-void mips_fpuexcept(struct lwp *, unsigned int);
-void mips_fpuillinst(struct lwp *, unsigned int, unsigned long);
-static int fpustat2sicode(unsigned int);
+/* #define FPE_DEBUG */
+
+void mips_fpuexcept(struct lwp *, uint32_t);
+void mips_fpuillinst(struct lwp *, uint32_t);
+static int fpustat2sicode(uint32_t);
 
 void
-mips_fpuexcept(struct lwp *l, unsigned int fpustat)
+mips_fpuexcept(struct lwp *l, uint32_t fpustat)
 {
        ksiginfo_t ksi;
 
+#ifdef FPE_DEBUG
+       printf("%s(%x,%#"PRIxREGISTER")\n",
+           __func__, fpustat, l->l_md.md_regs->f_regs[_R_PC]);
+#endif
+
        KSI_INIT_TRAP(&ksi);
        ksi.ksi_signo = SIGFPE;
        ksi.ksi_code = fpustat2sicode(fpustat);
        ksi.ksi_trap = fpustat;
+       ksi.ksi_addr = (void *)l->l_md.md_regs->f_regs[_R_PC];
        (*l->l_proc->p_emul->e_trapsignal)(l, &ksi);
 }
 
 void
-mips_fpuillinst(struct lwp *l, unsigned int opcode, unsigned long vaddr)
+mips_fpuillinst(struct lwp *l, uint32_t opcode)
 {
        ksiginfo_t ksi;
 
+#ifdef FPE_DEBUG
+       printf("%s(%x,%#"PRIxREGISTER")\n",
+           __func__, opcode, l->l_md.md_regs->f_regs[_R_PC]);
+#endif
+
        KSI_INIT_TRAP(&ksi);
        ksi.ksi_signo = SIGILL;
        ksi.ksi_code = ILL_ILLOPC;
        ksi.ksi_trap = opcode;
-       ksi.ksi_addr = (void *)vaddr;
+       ksi.ksi_addr = (void *)l->l_md.md_regs->f_regs[_R_PC];
        (*l->l_proc->p_emul->e_trapsignal)(l, &ksi);
 }
 
@@ -77,7 +89,7 @@ static struct {
 };
 
 static int
-fpustat2sicode(unsigned int fpustat)
+fpustat2sicode(uint32_t fpustat)
 {
        int i;
 
@@ -86,23 +98,3 @@ fpustat2sicode(unsigned int fpustat)
                        return (fpecodes[i].code);
        return (FPE_FLTINV);
 }
-#endif /* !SOFTFLOAT */
-
-void fpemul_trapsignal(struct lwp *, unsigned int, unsigned int);
-
-void
-fpemul_trapsignal(struct lwp *l, unsigned int sig, unsigned int code)
-{
-       ksiginfo_t ksi;
-
-#if DEBUG
-       printf("fpemul_trapsignal(%x,%x,%#"PRIxREGISTER")\n",
-          sig, code, l->l_md.md_regs->f_regs[_R_PC]);
-#endif
-
-       KSI_INIT_TRAP(&ksi);
-       ksi.ksi_signo = sig;
-       ksi.ksi_code = 1; /* XXX */
-       ksi.ksi_trap = code;
-       (*l->l_proc->p_emul->e_trapsignal)(l, &ksi);
-}



Home | Main Index | Thread Index | Old Index