Any good 68k build programmers out there? I use the commercial Green Hills compiler for Motorola 68040, and I see very strange behavior in the code. Sometimes the code does an if / else comparison and accepts the wrong branch. For example:
float a = 1, b = 2; if (a < b) do c; else do d;
The code will sometimes be d !? I found that when this error occurs, there is always one particular ISR that interrupts the comparison. I looked at the generated build for ISR and saw a few things that didn't make sense to me. At first it looks like floating point status registers, FPSR, FPCR and FPIAR, are not stored in the ISR. This explains why if / elses accept the wrong branch. The FPSR register is used to determine the result of the comparison, and if this register is overwritten in the ISR, then the branch may take the wrong path. The following is the input and output assembly generated by the compiler:
isr_function: FSAVE -(%SP) LINK %A6,
I looked through the programmers reference manual and I can’t find anything that says FSAVE or FMOVEM saves FP status registers. In fact, I saw one comment that suggests that this is not the case: "FSAVE does not save the model registers of the programmer of the floating point module, it only saves the user invisible part of the machine." So I added some of my own assemblies to save registers at the beginning of the ISR and restore them at the end, and this greatly improved performance, but I still see some problems. The following are the additions that I made; backup variables are typed as unsigned long in the C code:
isr_function: FSAVE -(%SP) LINK %A6,
It was hard for me to believe that the compiler had an error without preserving the registers. So I started looking at the FPx and Dx values to make sure they are restored to the correct value, and it looks like they are not. However, I am not 100% sure that I am not changing the assembly code with my changes. Below is the code I added to save the registers; debug variables print as unsigned longs:
isr_function: FMOVE %FP0,debug3 FMOVE %FP1,debug5 FMOVE %FP2,debug7 FMOVE %FP3,debug9 FMOVE %FP4,debug11 FMOVE %FP5,debug13 FMOVE %FP6,debug15 FMOVE %FP7,debug17 FMOVE %FPCR,debug19 FMOVE %FPIAR,debug23 FMOVE %FPSR,debug25 FSAVE -(%SP) LINK %A6,
In short, my questions are:
1) there is a problem with the generated assembly in that it does not save the FPSR, FPCR and FPIAR registers, but
2) Do I save register values correctly when entering and exiting ISR?
It would be great if I had a different compiler for comparison. Unfortunately, I cannot connect the debugger to the code. I have a lot of experience in C / C ++ / C # / Java / Python / PHP / etc., But I'm far from a build specialist.
Any ideas appreciated!