public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [PATCH : RL78] Disable interrupts during hardware multiplication routines
@ 2016-01-12  7:21 Kaushik M Phatak
  2016-01-12 12:20 ` Nick Clifton
  2016-01-12 15:54 ` Mike Stump
  0 siblings, 2 replies; 13+ messages in thread
From: Kaushik M Phatak @ 2016-01-12  7:21 UTC (permalink / raw)
  To: Nick Clifton; +Cc: dj, Mike Stump, gcc-patches, kaushik.phatak

[-- Attachment #1: Type: text/plain, Size: 11064 bytes --]

Hi Nick,
Thanks for your detailed review.
Please find an updated version of this patch here. I have tried to modify
it as per your suggestions.

> I would suggest:
>  static bool
Done.

> +      if (recog_memoized (insn) == CODE_FOR_udivmodsi4_g13
> have an attribute on these insns, and then test for that here.
Done. Added attribute 'is_g13_muldiv_insn' which gets tested in this function.

> +          return 1;
> If you change the function to "bool" then return "true" here.
> +  return 0;
Done.

>    if (rl78_is_naked_func ())
>     return;
> -
> +
> Why are you adding a extraneous space here ?
Done. This was a typo while extracting the patch.

> +  if (MUST_SAVE_MDUC_REGISTER && (!crtl->is_leaf || check_mduc_usage ()))
> It would be nice to update the stack size computation performed
I have tried to add code to update 'fs' while checking for 'framesize_locals'.
Please let me know if this is OK.

> +      emit_insn (gen_push (gen_rtx_REG (HImode, AX_REG)));
> it would be cleaner to use a for loop and a small structure containing
> the address, mode and volatility to be saved.
I have created simple structure for this, though the volatility is always set
and may not need to be a separate member.
Please let me know if this is OK.

> Hence I would suggest:
> fprintf (file, "\t; preserves MDUC registers\n");
Done.

> +This is the default.
> It is *not* the default!
Updated this. However, the registers are saved when -mmul=g13 and
-mg13 is passed.

> +@item -msave-mduc-in-interrupts
> +@item -mno-save-mduc-in-interrupts
> +@opindex msave-mduc-in-interrupts
> You should also mention that even if this option is enabled
Added information regarding registers being saved based on certain
conditions being met.

Kindly review the updated patch and let me know if it is OK.
This is regression tested for rl78 -msim and -mg13 + -msave-mduc-in-interrupts

Best Regards,
Kaushik

gcc/ChangeLog
2016-01-12  Kaushik Phatak  <kaushik.phatak@kpit.com>

* config/rl78/rl78.c (rl78_expand_prologue): Save the MDUC related
registers in all interrupt handlers if necessary.
(rl78_option_override): Add warning.
(MUST_SAVE_MDUC_REGISTER): New macro.
(rl78_expand_epilogue): Restore the MDUC registers if necessary.
* config/rl78/rl78.c (check_mduc_usage): New function.
* config/rl78/rl78.c (mduc_regs): New structure to hold MDUC register data.
* config/rl78/rl78.md (is_g13_muldiv_insn): New attribute.
* config/rl78/rl78.md (mulsi3_g13): Add is_g13_muldiv_insn attribute.
* config/rl78/rl78.md (udivmodsi4_g13): Add is_g13_muldiv_insn attribute.
* config/rl78/rl78.md (mulhi3_g13): Add is_g13_muldiv_insn attribute.
* config/rl78/rl78.opt (msave-mduc-in-interrupts): New option.
(mno-save-mduc-in-interrupts): New option.
* doc/invoke.texi (@item -msave-mduc-in-interrupts): New item.
(@item -mno-save-mduc-in-interrupts): New item

Index: gcc/config/rl78/rl78.c
===================================================================
--- gcc/config/rl78/rl78.c(revision 2871)
+++ gcc/config/rl78/rl78.c(working copy)
@@ -83,6 +83,22 @@
   "sp", "ap", "psw", "es", "cs"
 };

+/* Structure for G13 MDUC registers.  */
+struct mduc_reg_type
+{
+  unsigned int address;
+  enum machine_mode mode;
+  bool is_volatile;
+};
+
+struct mduc_reg_type  mduc_regs[NUM_OF_MDUC_REGS] =
+  {{0xf00e8, QImode, true},
+   {0xffff0, HImode, true},
+   {0xffff2, HImode, true},
+   {0xf2224, HImode, true},
+   {0xf00e0, HImode, true},
+   {0xf00e2, HImode, true}};
+
 struct GTY(()) machine_function
 {
   /* If set, the rest of the fields have been computed.  */
@@ -342,6 +358,10 @@
 #undef  TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDErl78_option_override

+#define MUST_SAVE_MDUC_REGISTERS                         \
+  (!TARGET_NO_SAVE_MDUC_REGISTERS                        \
+   && (is_interrupt_func (NULL_TREE)) && RL78_MUL_G13)
+
 static void
 rl78_option_override (void)
 {
@@ -366,6 +386,9 @@
     /* Address spaces are currently only supported by C.  */
     error ("-mes0 can only be used with C");

+  if (TARGET_SAVE_MDUC_REGISTERS && !(TARGET_G13 || RL78_MUL_G13))
+    warning (0, "mduc registers only saved for G13 target");
+
   switch (rl78_cpu_type)
     {
     case CPU_UNINIT:
@@ -1307,6 +1330,23 @@
   return (lookup_attribute ("naked", DECL_ATTRIBUTES
(current_function_decl)) != NULL_TREE);
 }

+/* Check if the block uses mul/div insns for G13 target.  */
+static bool
+check_mduc_usage ()
+{
+  rtx insn;
+  basic_block bb;
+  FOR_EACH_BB_FN (bb, cfun)
+  {
+    FOR_BB_INSNS (bb, insn)
+    {
+      if (get_attr_is_g13_muldiv_insn (insn) == IS_G13_MULDIV_INSN_YES)
+        return true;
+    }
+  }
+  return false;
+}
+
 /* Expand the function prologue (from the prologue pattern).  */
 void
 rl78_expand_prologue (void)
@@ -1371,6 +1411,28 @@
       F (emit_insn (gen_push (ax)));
     }

+  /* Save MDUC registers inside interrupt routine.  */
+  if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
+    {
+      rtx mem_mduc;
+
+      for (int i = 0; i <NUM_OF_MDUC_REGS; i++)
+      {
+if (mduc_regs[i].mode == QImode)
+{
+  mem_mduc = gen_rtx_MEM (QImode, GEN_INT (mduc_regs[i].address));
+  MEM_VOLATILE_P (mem_mduc) = 1;
+  emit_insn (gen_movqi (gen_rtx_REG (QImode, A_REG), mem_mduc));
+}
+else
+{
+  mem_mduc = gen_rtx_MEM (HImode, GEN_INT (mduc_regs[i].address));
+  MEM_VOLATILE_P (mem_mduc) = 1;
+  emit_insn (gen_movqi (gen_rtx_REG (HImode, AX_REG), mem_mduc));
+}
+emit_insn (gen_push (gen_rtx_REG (HImode, AX_REG)));
+      }
+    }
   if (frame_pointer_needed)
     {
       F (emit_move_insn (ax, sp));
@@ -1378,6 +1440,8 @@
     }

   fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
+  if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
+    fs = fs + NUM_OF_MDUC_REGS * 2;
   if (fs > 0)
     {
       /* If we need to subtract more than 254*3 then it is faster and
@@ -1426,6 +1490,8 @@
   else
     {
       fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
+      if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
+fs = fs + NUM_OF_MDUC_REGS * 2;
       if (fs > 254 * 3)
 {
   emit_move_insn (ax, sp);
@@ -1444,6 +1510,29 @@
 }
     }

+  /* Restore MDUC registers from interrupt routine.  */
+  if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
+    {
+      rtx mem_mduc;
+
+      for (int i = NUM_OF_MDUC_REGS-1; i >= 0; i--)
+      {
+emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
+        if (mduc_regs[i].mode == QImode)
+        {
+          mem_mduc = gen_rtx_MEM (QImode, GEN_INT (mduc_regs[i].address));
+          MEM_VOLATILE_P (mem_mduc) = 1;
+  emit_insn (gen_movqi (mem_mduc, gen_rtx_REG (QImode, A_REG)));
+        }
+        else
+        {
+          mem_mduc = gen_rtx_MEM (HImode, GEN_INT (mduc_regs[i].address));
+          MEM_VOLATILE_P (mem_mduc) = 1;
+  emit_insn (gen_movhi (mem_mduc, gen_rtx_REG (HImode, AX_REG)));
+        }
+      }
+    }
+
   /* Save ES register inside interrupt functions.  */
   if (is_interrupt_func (cfun->decl) && cfun->machine->uses_es)
     {
@@ -1599,6 +1688,9 @@

   if (cfun->machine->uses_es)
     fprintf (file, "\t; uses ES register\n");
+
+  if (MUST_SAVE_MDUC_REGISTERS)
+    fprintf (file, "\t; preserves MDUC registers\n");
 }

 /* Return an RTL describing where a function return value of type RET_TYPE
Index: gcc/config/rl78/rl78.h
===================================================================
--- gcc/config/rl78/rl78.h(revision 2871)
+++ gcc/config/rl78/rl78.h(working copy)
@@ -28,6 +28,7 @@
 #define TARGET_G14(rl78_cpu_type == CPU_G14)


+#define NUM_OF_MDUC_REGS 6

 #define TARGET_CPU_CPP_BUILTINS()    \
   do                                                \
Index: gcc/config/rl78/rl78.md
===================================================================
--- gcc/config/rl78/rl78.md(revision 2871)
+++ gcc/config/rl78/rl78.md(working copy)
@@ -78,6 +78,7 @@
 (include "rl78-virt.md")
 (include "rl78-real.md")

+(define_attr "is_g13_muldiv_insn" "yes,no" (const_string "no"))

 ;; Function Prologue/Epilogue Instructions

@@ -416,7 +417,8 @@
 movw    ax, 0xffff6     ; MDBL
 movw    %h0, ax
         ; end of mulhi macro"
-  [(set_attr "valloc" "macax")]
+  [(set_attr "valloc" "macax")
+   (set_attr "is_g13_muldiv_insn" "yes")]
 )

 ;; 0xFFFF0 is MACR(L).  0xFFFF2 is MACR(H) but we don't care about it
@@ -496,7 +498,8 @@
 movwax, !0xf00e0; MDCL
 movw%H0, ax
 ; end of mulsi macro"
-  [(set_attr "valloc" "macax")]
+  [(set_attr "valloc" "macax")
+   (set_attr "is_g13_muldiv_insn" "yes")]
 )

 ;; start-sanitize-rl78
@@ -731,7 +734,8 @@
 movw%H3, ax\n\
 ; end of udivmodsi macro";
       }
-  [(set_attr "valloc" "macax")]
+  [(set_attr "valloc" "macax")
+   (set_attr "is_g13_muldiv_insn" "yes")]
 )
 (define_insn "mov1"
   [(set (match_operand:QI         0 "rl78_nonimmediate_operand"   "=vU")
Index: gcc/config/rl78/rl78.opt
===================================================================
--- gcc/config/rl78/rl78.opt(revision 2871)
+++ gcc/config/rl78/rl78.opt(working copy)
@@ -103,4 +103,10 @@
 Target Mask(ES0)
 Assume ES is zero throughout program execution, use ES: for read-only data.

+msave-mduc-in-interrupts
+Target Mask(SAVE_MDUC_REGISTERS)
+Stores the MDUC registers in interrupt handlers for G13 target.

+mno-save-mduc-in-interrupts
+Target RejectNegative Mask(NO_SAVE_MDUC_REGISTERS)
+Does not save the MDUC registers in interrupt handlers for G13 target.
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi(revision 2871)
+++ gcc/doc/invoke.texi(working copy)
@@ -18901,6 +18901,20 @@
 registers @code{r24..r31} are reserved for use in interrupt handlers.
 With this option enabled these registers can be used in ordinary
 functions as well.
+
+@item -msave-mduc-in-interrupts
+@item -mno-save-mduc-in-interrupts
+@opindex msave-mduc-in-interrupts
+@opindex mno-save-mduc-in-interrupts
+Specifies that interrupt handler functions should preserve the
+MDUC registers.  This is only necessary if normal code might use
+the MDUC registers, for example because it performs multiplication
+and division operations. The default is to ignore the MDUC registers
+as this makes the interrupt handlers faster. The target option -mg13
+needs to be passed for this to work as this feature is only available
+on the G13 target (S2 core). The option will not have any effect if
+the target does not have multiply hardware, or if the interrupt
+function does not call any other function.
 @end table

@node RS/6000 and PowerPC Options
================== END of Patch ==============

-----Original Message-----
From: Nick Clifton [mailto:nickc@redhat.com]
Sent: Thursday, January 07, 2016 5:33 PM
To: Kaushik M Phatak <kphatak@gmail.com>; dj@redhat.com
Cc: Mike Stump <mikestump@comcast.net>; gcc-patches@gcc.gnu.org;
Kaushik Phatak <Kaushik.Phatak@kpit.com>
Subject: Re: [PATCH : RL78] Disable interrupts during hardware
multiplication routines

Hi Kaushik,

   Just a few comments on the patch itself:

[-- Attachment #2: rl78_mduc_patch_2.diff --]
[-- Type: text/plain, Size: 7838 bytes --]

Index: gcc/config/rl78/rl78.c
===================================================================
--- gcc/config/rl78/rl78.c	(revision 2871)
+++ gcc/config/rl78/rl78.c	(working copy)
@@ -83,6 +83,22 @@
   "sp", "ap", "psw", "es", "cs"
 };
 
+/* Structure for G13 MDUC registers.  */
+struct mduc_reg_type
+{
+  unsigned int address;
+  enum machine_mode mode;
+  bool is_volatile;
+};
+
+struct mduc_reg_type  mduc_regs[NUM_OF_MDUC_REGS] =
+  {{0xf00e8, QImode, true},
+   {0xffff0, HImode, true},
+   {0xffff2, HImode, true},
+   {0xf2224, HImode, true},
+   {0xf00e0, HImode, true},
+   {0xf00e2, HImode, true}};
+
 struct GTY(()) machine_function
 {
   /* If set, the rest of the fields have been computed.  */
@@ -342,6 +358,10 @@
 #undef  TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE		rl78_option_override
 
+#define MUST_SAVE_MDUC_REGISTERS                         \
+  (!TARGET_NO_SAVE_MDUC_REGISTERS                        \
+   && (is_interrupt_func (NULL_TREE)) && RL78_MUL_G13)
+
 static void
 rl78_option_override (void)
 {
@@ -366,6 +386,9 @@
     /* Address spaces are currently only supported by C.  */
     error ("-mes0 can only be used with C");
 
+  if (TARGET_SAVE_MDUC_REGISTERS && !(TARGET_G13 || RL78_MUL_G13))
+    warning (0, "mduc registers only saved for G13 target");
+
   switch (rl78_cpu_type)
     {
     case CPU_UNINIT:
@@ -1307,6 +1330,23 @@
   return (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE);
 }
 
+/* Check if the block uses mul/div insns for G13 target.  */
+static bool
+check_mduc_usage ()
+{
+  rtx insn;
+  basic_block bb;
+  FOR_EACH_BB_FN (bb, cfun)
+  {
+    FOR_BB_INSNS (bb, insn)
+    {
+      if (get_attr_is_g13_muldiv_insn (insn) == IS_G13_MULDIV_INSN_YES)
+        return true;
+    }
+  }
+  return false;
+}
+
 /* Expand the function prologue (from the prologue pattern).  */
 void
 rl78_expand_prologue (void)
@@ -1371,6 +1411,28 @@
       F (emit_insn (gen_push (ax)));
     }
 
+  /* Save MDUC registers inside interrupt routine.  */
+  if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
+    {
+      rtx mem_mduc;
+
+      for (int i = 0; i <NUM_OF_MDUC_REGS; i++)
+      {
+	if (mduc_regs[i].mode == QImode)
+	{
+	  mem_mduc = gen_rtx_MEM (QImode, GEN_INT (mduc_regs[i].address));
+	  MEM_VOLATILE_P (mem_mduc) = 1;       
+	  emit_insn (gen_movqi (gen_rtx_REG (QImode, A_REG), mem_mduc));
+	}
+	else
+	{
+	  mem_mduc = gen_rtx_MEM (HImode, GEN_INT (mduc_regs[i].address));
+	  MEM_VOLATILE_P (mem_mduc) = 1;       
+	  emit_insn (gen_movqi (gen_rtx_REG (HImode, AX_REG), mem_mduc));
+	}
+	emit_insn (gen_push (gen_rtx_REG (HImode, AX_REG)));
+      }
+    }
   if (frame_pointer_needed)
     {
       F (emit_move_insn (ax, sp));
@@ -1378,6 +1440,8 @@
     }
 
   fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
+  if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
+    fs = fs + NUM_OF_MDUC_REGS * 2;
   if (fs > 0)
     {
       /* If we need to subtract more than 254*3 then it is faster and
@@ -1426,6 +1490,8 @@
   else
     {
       fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing;
+      if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
+	fs = fs + NUM_OF_MDUC_REGS * 2;
       if (fs > 254 * 3)
 	{
 	  emit_move_insn (ax, sp);
@@ -1444,6 +1510,29 @@
 	}
     }
 
+  /* Restore MDUC registers from interrupt routine.  */
+  if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
+    {
+      rtx mem_mduc;
+
+      for (int i = NUM_OF_MDUC_REGS-1; i >= 0; i--)
+      {
+	emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
+        if (mduc_regs[i].mode == QImode)
+        {
+          mem_mduc = gen_rtx_MEM (QImode, GEN_INT (mduc_regs[i].address));
+          MEM_VOLATILE_P (mem_mduc) = 1;
+	  emit_insn (gen_movqi (mem_mduc, gen_rtx_REG (QImode, A_REG)));
+        }
+        else
+        {
+          mem_mduc = gen_rtx_MEM (HImode, GEN_INT (mduc_regs[i].address));
+          MEM_VOLATILE_P (mem_mduc) = 1;
+	  emit_insn (gen_movhi (mem_mduc, gen_rtx_REG (HImode, AX_REG)));
+        }
+      }
+    }
+
   /* Save ES register inside interrupt functions.  */
   if (is_interrupt_func (cfun->decl) && cfun->machine->uses_es)
     {
@@ -1599,6 +1688,9 @@
 
   if (cfun->machine->uses_es)
     fprintf (file, "\t; uses ES register\n");
+
+  if (MUST_SAVE_MDUC_REGISTERS)
+    fprintf (file, "\t; preserves MDUC registers\n");
 }
 
 /* Return an RTL describing where a function return value of type RET_TYPE
Index: gcc/config/rl78/rl78.h
===================================================================
--- gcc/config/rl78/rl78.h	(revision 2871)
+++ gcc/config/rl78/rl78.h	(working copy)
@@ -28,6 +28,7 @@
 #define TARGET_G14	(rl78_cpu_type == CPU_G14)
 
 
+#define NUM_OF_MDUC_REGS 6
 
 #define TARGET_CPU_CPP_BUILTINS()		    \
   do                                                \
Index: gcc/config/rl78/rl78.md
===================================================================
--- gcc/config/rl78/rl78.md	(revision 2871)
+++ gcc/config/rl78/rl78.md	(working copy)
@@ -78,6 +78,7 @@
 (include "rl78-virt.md")
 (include "rl78-real.md")
 
+(define_attr "is_g13_muldiv_insn" "yes,no" (const_string "no"))
 
 ;; Function Prologue/Epilogue Instructions
 
@@ -416,7 +417,8 @@
 	movw    ax, 0xffff6     ; MDBL
 	movw    %h0, ax
         ; end of mulhi macro"
-  [(set_attr "valloc" "macax")]
+  [(set_attr "valloc" "macax")
+   (set_attr "is_g13_muldiv_insn" "yes")]
 )
 
 ;; 0xFFFF0 is MACR(L).  0xFFFF2 is MACR(H) but we don't care about it
@@ -496,7 +498,8 @@
 	movw	ax, !0xf00e0	; MDCL
 	movw	%H0, ax
 	; end of mulsi macro"
-  [(set_attr "valloc" "macax")]
+  [(set_attr "valloc" "macax")
+   (set_attr "is_g13_muldiv_insn" "yes")]
 )
 
 ;; start-sanitize-rl78
@@ -731,7 +734,8 @@
 	movw	%H3, ax		\n\
 	; end of udivmodsi macro";
       }
-  [(set_attr "valloc" "macax")]
+  [(set_attr "valloc" "macax")
+   (set_attr "is_g13_muldiv_insn" "yes")]
 )
 (define_insn "mov1"
   [(set (match_operand:QI         0 "rl78_nonimmediate_operand"   "=vU")
Index: gcc/config/rl78/rl78.opt
===================================================================
--- gcc/config/rl78/rl78.opt	(revision 2871)
+++ gcc/config/rl78/rl78.opt	(working copy)
@@ -103,4 +103,10 @@
 Target Mask(ES0)
 Assume ES is zero throughout program execution, use ES: for read-only data.
 
+msave-mduc-in-interrupts
+Target Mask(SAVE_MDUC_REGISTERS)
+Stores the MDUC registers in interrupt handlers for G13 target.
 
+mno-save-mduc-in-interrupts
+Target RejectNegative Mask(NO_SAVE_MDUC_REGISTERS)
+Does not save the MDUC registers in interrupt handlers for G13 target.
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 2871)
+++ gcc/doc/invoke.texi	(working copy)
@@ -18901,6 +18901,20 @@
 registers @code{r24..r31} are reserved for use in interrupt handlers.
 With this option enabled these registers can be used in ordinary
 functions as well.
+
+@item -msave-mduc-in-interrupts
+@item -mno-save-mduc-in-interrupts
+@opindex msave-mduc-in-interrupts
+@opindex mno-save-mduc-in-interrupts
+Specifies that interrupt handler functions should preserve the
+MDUC registers.  This is only necessary if normal code might use
+the MDUC registers, for example because it performs multiplication
+and division operations. The default is to ignore the MDUC registers
+as this makes the interrupt handlers faster. The target option -mg13
+needs to be passed for this to work as this feature is only available
+on the G13 target (S2 core). The option will not have any effect if
+the target does not have multiply hardware, or if the interrupt
+function does not call any other function.
 @end table
 
 @node RS/6000 and PowerPC Options

^ permalink raw reply	[flat|nested] 13+ messages in thread
* [PATCH : RL78] Disable interrupts during hardware multiplication routines
@ 2015-06-05  6:44 Kaushik Phatak
  2015-06-05  8:02 ` DJ Delorie
  0 siblings, 1 reply; 13+ messages in thread
From: Kaushik Phatak @ 2015-06-05  6:44 UTC (permalink / raw)
  To: 'gcc-patches@gcc.gnu.org'; +Cc: nick clifton (nickc@redhat.com)

[-- Attachment #1: Type: text/plain, Size: 3227 bytes --]

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.phatak@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 #2: rl78_mul_div.diff --]
[-- Type: application/octet-stream, Size: 2338 bytes --]

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")]

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2016-05-09 11:46 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CAJA2CV1y0Mk20KqgFbdFs19tyPCH7HvR_XGAwy=OyhYcgNLuWQ@mail.gmail.com>
     [not found] ` <C6735D72-E033-470D-A8B2-1949D7A04AEE@comcast.net>
2016-01-07 11:27   ` [PATCH : RL78] Disable interrupts during hardware multiplication routines Kaushik M Phatak
2016-01-07 12:03     ` Nick Clifton
2016-01-12  7:21 Kaushik M Phatak
2016-01-12 12:20 ` Nick Clifton
2016-01-12 15:54 ` Mike Stump
2016-05-04 11:47   ` Kaushik Phatak
2016-05-09 11:46     ` Nick Clifton
  -- strict thread matches above, loose matches on Subject: below --
2015-06-05  6:44 Kaushik Phatak
2015-06-05  8:02 ` DJ Delorie
2015-08-27 13:14   ` Kaushik Phatak
2015-08-27 17:11     ` Mike Stump
2015-08-27 17:25     ` DJ Delorie
2015-12-07 12:36       ` Kaushik Phatak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).