RL78 problem with hardware multiplier/divider accumulator in G13 CPUs with GCC compiler V15.01

 
I have some code in an INTERRUPT service routine that multiplies two 16 bit values into a 32 bit result
 
I also have some code in the main loop that multiplies two 16 bit values into a 32 bit result
 
Looking at the Interrupt function I see that it uses the Hardware multiplier/divider accumulator to do the grunt work
Looking at the main loop Code I see that it uses the Hardware multiplier/divider accumulator to do the grunt work
==>> The problem I have noticed is that the main loop sometimes gets wrong results
 
I am using the GCC Compiler V15.01
 
Solution 1 ) how to tell the GCC C Compiler to NOT use the Hardware multiplier/divider accumulator in INTERRUPT functions !!!!
Solution 2) Turn off and back on INTs in the main loop around the Hardware multiplier/divider accumulator code  to prevent ISR getting in the middle
Solution 3) Use a software shift and Add method to do the multiply 
 
My preference is to use Solution 1)
   
Parents
  • The problem turned out to be due to the fact that the hardware multiply uses several instructions and registers to do the work. So if an ISR occures part way through the process, the ISR is NOT storing the hardware multiply status registers and restoring them at the end of the ISR.

    Therefore the main loop and ISR cannot BOTH use the hardware multiply.  So the best option is (3) where the ISR uses a software multiply.

    GCC currently ONLY allows the hardware multiply to be turn on or off at a file level so I have 2 choices

    1) put ISR into a new file and make all variables external   (NOT desirable)

    2) write my own software multiply and use that in ISRs that need it

    I have implemented option (2)

    I hope this helps other ppl

    Ray

  • A third possibility would be to disable interrupts while doing the multiplication. To do this you could pack the call for multiplication in a macro like this:

    #define MULTIPLY(IN1, IN2, OUT) \

    __builtin_rl78_di ();  \

    OUT = IN1 * IN2;  \

    __builtin_rl78_ei ();

Reply Children
No Data