Any good 68k assembly programmers out there?? I'm using a commercial Green Hills compiler for a Motorola 68040 and I'm seeing some very strange behavior from the code. Sometimes, the code will do an if/else comparison, and take the wrong branch. For example:
float a = 1, b = 2;
if (a < b)
do c;
else
do d;
The code will sometimes to d!? I've found that whenvever this error occurs, there is always one particular ISR that interrupts the comparison. I took a look at the generated assembly for the ISR and saw a few things that don't make sense to me. First it looks like the floating point status registers, FPSR, FPCR, and FPIAR, are not saved in the ISR. This would explain why the if/elses are taking the wrong branch. The FPSR register is used to determine the result of a comparison, and if that register is overwritten in an ISR then the branch may take the wrong path. Following is the entry and exit assembly generated by the compiler:
isr_function:
FSAVE -(%SP)
LINK %A6,#-192
MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
FMOVEM %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)
; isr code ...
FMOVEM -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
UNLK %A6
FRESTORE (%SP)+
RTE
I looked through the Programmer's Reference Manual and I can't find anything that suggests that FSAVE, or FMOVEM, saves the FP status registers. Actually, I saw one comment that suggests that it does not, "The FSAVE does not save the programmerís model registers of the floating-point unit; it saves only the user invisible portion of the machine." So I added some assembly of my own to save away the registers at the start of the ISR, and restore them at the end, and this dramatically improved the performance, but I'm still seeing some problems. Following are the additions I made; the backup variables are typed as unsigned long in the C code