I would like to create my own exception handler for floating point
exceptions on an MPC8240 running VxWorks. I want to be able to record
exceptions such as "inexact" and "underflow" but continue executing my
code. The VxWorks exception handler for program intterupts (0x700) will
not allow me to do this.
To get around this I wrote my own exception handler in C using the
VxWorks function:
excConnect( (VOIDFUNCPTR *)_EXC_OFF_PROG, my_handler );
What I have found is that if I don't clear the FPSCR (and disable
floating point exceptions), I can't return to my code. That is, the
exception handler is called continuously once an exception occurs,
unless I disable all floating point exceptions from the exception
handler.
I tried to clear the FPSCR status bits to clear the exception, but this
does not work. I only return to my code my exception handler sets the
FPSCR to zero.
Am I missing something?
Sent via Deja.com http://www.deja.com/
Before you buy.
My guess (I'm not an expert on PPC) is that when it returns from your
exception handler, the CPU retries the FP instruction that caused it to
fail. Unless you've changed the conditions that caused the exception,
this retry is just going to make it happen again.
If I'm right, then you need to get that FP instruction executed with
exceptions turned off, then turn them on again for the next instruction.
Easier said than done, but possible.
- Andrew
--
Complexity comes for free, Simplicity you have to work for.
Also, when you enter the exception handler, SRR0 (the exception-time
program counter) will point to the instruction that caused the
exception. You need to add 4 to it before returning, unless your
version of VxWorks does that for you.
-=- Andrew Klossner (and...@teleport.com)
I just want to isolate the cause of the exception to a particular data
set, but the results in most cases are still usable (e.g. inexact or
underflow). The sticky bits tell me what I need to know so maybe I
don't even need to enable the exception in the MSR. Maybe I'll just let
the application clear the exceptions in the FPSCR before it starts, and
check for exceptions after it completes.
Thanks for the info.
In article <86ii7a$qqc$1...@user2.teleport.com>,
Andrew Klossner 이(가) <86ii7a$qqc$1...@user2.teleport.com> 메시지에서
작성하였습니다...
I don't know what an 8260 is. For 603, 8240, and 750, here's what
works for me in the exception handler:
// We have to work extra hard to get and save the FPSCR.
// Do this only if we took a program exception.
lwz r3,_PPC_ESF_VEC_OFF(r1) // set r3 = exception vector
cmpwi r3,0x700 // was it a floating point exception?
bne+ 1f // if not, skip this sequence
// If floating point was not enabled when the exception happened,
// don't bother to save the FPSCR. (Perhaps this machine has no
// floating point unit.)
// We saved SRR1 in r9 so that we could inspect the FP bit here.
andi. r0,r9,_PPC_MSR_FP // was the FP enable bit set?
beq+ 1f // if not, skip this sequence
// Enable floating point instructions.
stwu r1,-24(r1) // set up a sort of stack frame
mfmsr r4 // save old MSR to r4
ori r5,r4,_PPC_MSR_FP // turn on the FP enable bit
mtmsr r5
isync
// Get and save the FPSCR.
stfd 0,16(r1) // preserve FR0
mffs 0 // get FPSCR into FR0 bits 32..63
stfd 0,8(r1) // store garbage at 8(r1),
// and FPSCR at 12(r1)
lwz r5,12(r1) // load FPSCR contents into r5
stw r5,_PPC_ESF_FPSCR+24(r1)// save for exception report
// Clear FPSCR exception bits: AND with 0007f0ff.
// This is necessary so that the FP exception doesn't fire again
// when we attempt a floating point instruction.
addi r6,0,0x0007
ori r6,r6,0xf0ff // r6 = 0007f0ff
and r5,r5,r6 // clear other bits in r5
stw r5,12(r1)
lfd 0,8(r1) // get that value into FR0
mtfsf 255,0 // get that value into FPSCR
// Restore FR0 and MSR.
lfd 0,16(r1) // restore FR0
mtmsr r4 // restore old MSR
isync
addi r1,r1,24 // undo stack frame
1:
// End of code to get and save the FPSCR.
-=- Andrew Klossner (and...@teleport.com)