Subject: Re: MIPS switched to new-toolchain
To: None <thorpej@wasabisystems.com>
From: enami tsugutomo <enami@sm.sony.co.jp>
List: port-mips
Date: 01/10/2002 17:27:45
Jason R Thorpe <thorpej@wasabisystems.com> writes:
> I think this is an FP emulation problem, not a compiler problem.
Actually, it was a bug in fpemu.c.
This is simplified test case:
enami@sigfpe% cat c.c
double e = 20;
int ok;
main()
{
ok = (e >= 20);
printf("%d\n", ok);
}
enami@sigfpe%
And whether the bug is appeared or not depends instruction in the
delay slot of `bc1t'. gcc -O2 emits ``sw'' while -O1 emits ``li''.
When bc1t ...; sw ...; case, finaly update_pc() in fpemu.c is called.
In the function, there is an expression
``curpcb->pcb_fpregs.r_regs[FSR]'' but FSR (defined as FPBASE + 32)
isn't right value to use as an index of r_regs[] here (and constant 32
instead FSR is used in other place!). And as a result, PC wasn't
updated correctly.
How about following change?
enami.
Index: include/pcb.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/mips/include/pcb.h,v
retrieving revision 1.12
diff -u -r1.12 pcb.h
--- include/pcb.h 2001/10/16 16:31:34 1.12
+++ include/pcb.h 2002/01/10 08:02:16
@@ -67,4 +67,6 @@
#ifdef _KERNEL
extern struct pcb *curpcb; /* the current running pcb */
extern struct segtab *segbase; /* current segtab base */
+
+#define PCB_FSR(pcb) ((pcb)->pcb_fpregs.r_regs[FSR - FPBASE])
#endif
Index: mips/db_interface.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/mips/mips/db_interface.c,v
retrieving revision 1.38
diff -u -r1.38 db_interface.c
--- mips/db_interface.c 2001/11/14 18:15:21 1.38
+++ mips/db_interface.c 2002/01/10 08:02:16
@@ -550,7 +550,7 @@
vaddr_t ra;
unsigned fpucsr;
- fpucsr = (curproc) ? curproc->p_addr->u_pcb.pcb_fpregs.r_regs[32] : 0;
+ fpucsr = curproc ? PCB_FSR(&curproc->p_addr->u_pcb) : 0;
ra = MachEmulateBranch((struct frame *)regs, pc, fpucsr, 0);
return ra;
}
Index: mips/fpemu.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/mips/mips/fpemu.c,v
retrieving revision 1.7
diff -u -r1.7 fpemu.c
--- mips/fpemu.c 2001/10/16 16:31:36 1.7
+++ mips/fpemu.c 2002/01/10 08:02:16
@@ -85,9 +85,10 @@
struct frame *frame;
u_int32_t cause;
{
+
if (cause & MIPS_CR_BR_DELAY)
frame->f_regs[PC] = MachEmulateBranch(frame, frame->f_regs[PC],
- curpcb->pcb_fpregs.r_regs[FSR], 0);
+ PCB_FSR(curpcb), 0);
else
frame->f_regs[PC] += 4;
}
Index: mips/trap.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/mips/mips/trap.c,v
retrieving revision 1.166
diff -u -r1.166 trap.c
--- mips/trap.c 2001/12/28 02:13:14 1.166
+++ mips/trap.c 2002/01/10 08:02:18
@@ -749,7 +749,7 @@
pc = (vaddr_t)f->f_regs[PC];
if (fuiword((void *)pc) != 0) /* not a NOP instruction */
va = MachEmulateBranch(f, pc,
- p->p_addr->u_pcb.pcb_fpregs.r_regs[32], 1);
+ PCB_FSR(&p->p_addr->u_pcb), 1);
else
va = pc + sizeof(int);
p->p_md.md_ss_addr = va;