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
rl78_mul_div.diff
Description: rl78_mul_div.diff