Hi,
Please find attached a patch which disables interrupts during inline hardware 
multiplication routines.
These routines use up several control registers which are not saved/restored in 
interrupt routines.
This causes corruption of result in case multiplication/division registers are 
used in main code as well as interrupts.

This patch has been regression tested with simulator as well as hardware.
Please review the same and let me know if OK to commit?

Best Regards,
Kaushik Phatak

2015-06-05  Kaushik Phatak  <kaushik.pha...@kpit.com>
        * config/rl78/rl78.md (mulhi3_g13): Disable interrupts in
                routine.
        (mulsi3_g14): Likewise.
        (mulsi3_g13): Likewise.
                (udivmodsi4_g13): Likewise.
                
Index: gcc/config/rl78/rl78.md
===================================================================
--- gcc/config/rl78/rl78.md     (revision 224145)
+++ gcc/config/rl78/rl78.md     (working copy)
@@ -372,6 +372,7 @@
   ]
   "RL78_MUL_G13"
   "; G13 mulhi macro %0 = %1 * %2
+       di
        mov     a, #0x00
        mov     !0xf00e8, a     ; MDUC
        movw    ax, %h1
@@ -381,6 +382,7 @@
        nop     ; mdb = mdal * mdah
        movw    ax, 0xffff6     ; MDBL
        movw    %h0, ax
+       ei
         ; end of mulhi macro"
   [(set_attr "valloc" "macax")]
 )
@@ -397,6 +399,7 @@
   ]
   "RL78_MUL_G14"
   "; G14 mulsi macro %0 = %1 * %2
+       di
        movw    ax, %h1
        movw    bc, %h2
        MULHU   ; bcax = bc * ax
@@ -411,6 +414,7 @@
        MACHU   ; MACR += bc * ax
        movw    ax, 0xffff0
        movw    %H0, ax
+       ei
        ; end of mulsi macro"
   [(set_attr "valloc" "macax")]
   )
@@ -429,6 +433,7 @@
   ]
   "RL78_MUL_G13"
   "; G13 mulsi macro %0 = %1 * %2
+       di
        mov     a, #0x00
        mov     !0xf00e8, a     ; MDUC
        movw    ax, %h1
@@ -461,6 +466,7 @@
        nop     ; Additional nop for MAC
        movw    ax, !0xf00e0    ; MDCL
        movw    %H0, ax
+       ei
        ; end of mulsi macro"
   [(set_attr "valloc" "macax")]
 )
@@ -629,6 +635,7 @@
   {
     if (find_reg_note (insn, REG_UNUSED, operands[3]))
       return "; G13 udivsi macro %0 = %1 / %2 \n\
+       di      \n\
        mov     a, #0xC0        ; Set DIVMODE=1 and MACMODE=1 \n\
        mov     !0xf00e8, a     ; This preps the peripheral for division 
without interrupt generation \n\
        movw    ax, %H1         \n\
@@ -647,9 +654,11 @@
        movw    %h0, ax         \n\
        movw    ax, 0xffff2     \n\
        movw    %H0, ax         \n\
+       ei      \n\
        ; end of udivsi macro";
     else if (find_reg_note (insn, REG_UNUSED, operands[0]))
       return "; G13 umodsi macro %3 = %1 %% %2 \n\
+       di      \n\
        mov     a, #0xC0        ; Set DIVMODE=1 and MACMODE=1 \n\
        mov     !0xf00e8, a     ; This preps the peripheral for division 
without interrupt generation \n\
        movw    ax, %H1         \n\
@@ -668,9 +677,11 @@
        movw    %h3, ax         \n\
        movw    ax, !0xf00e2    \n\
        movw    %H3, ax         \n\
+       ei      \n\
        ; end of umodsi macro";
     else
       return "; G13 udivmodsi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\
+       di      \n\
        mov     a, #0xC0        ; Set DIVMODE=1 and MACMODE=1 \n\
        mov     !0xf00e8, a     ; This preps the peripheral for division 
without interrupt generation \n\
        movw    ax, %H1         \n\
@@ -693,6 +704,7 @@
        movw    %h3, ax         \n\
        movw    ax, !0xf00e2    \n\
        movw    %H3, ax         \n\
+       ei      \n\
        ; end of udivmodsi macro";
       }
   [(set_attr "valloc" "macax")]
                
/* End of Patch  */

Best Regards,
Kaushik Phatak


Attachment: rl78_mul_div.diff
Description: rl78_mul_div.diff

Reply via email to