public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Kaushik Phatak <Kaushik.Phatak@kpit.com>
To: DJ Delorie <dj@redhat.com>
Cc: "'gcc-patches@gcc.gnu.org'" <gcc-patches@gcc.gnu.org>,
	"nick clifton (nickc@redhat.com)" <nickc@redhat.com>
Subject: RE: [PATCH : RL78] Disable interrupts during hardware multiplication routines
Date: Thu, 27 Aug 2015 13:14:00 -0000	[thread overview]
Message-ID: <HK2PR03MB138012713E3B01220DD3E2DEFC6F0@HK2PR03MB1380.apcprd03.prod.outlook.com> (raw)
In-Reply-To: <201506050644.t556igDi027743@greed.delorie.com>

Hi DJ,
Thanks for your feedback comments. Sorry it took me a while to get back on this.

>> Have you compared the latency of the multiply instructions to the overhead of
>> saving those registers in the interrupt handler?
>> What about the case where performance is priority, and the developer knows that
>> the interrupt handlers don't use the multiply registers?
>> Also, your code doesn't properly handle the case where the interrupts are alread
>> disabled when those functions are called.  It would re-enable interrupts before 
>> the main code was prepared for it.

Yes, I agree the patch does not handle the case where interrupts are disabled. 
Also, the code performance would suffer when the 'di/ei' instructions are placed 
inline with the multiplication code.

I have worked out an updated patch, which would save the MDUC specific registers
in the interrupt routine when the option '-msave-mduc-in-interrupts' is passed.
This gets active only for the G13 targets.
This patch will save and restore the MDUC specific registers: mduc,mdal/h,mdbl/h and mdcl/h
This option does add about 56 bytes of code to the interrupt service routine due
to the saves/restores via push/pop.
Kindly review this patch and let me know if it would be useful for the RL78 port 
(either in current state or with modifications)
The other option/solution would be for the end user to disable/enable interrupts during the
mul/div routines in project as per their requirement.

This has been regression tested for ""-mg13 -msim -msave-mduc-in-interrupts"

Best Regards,
Kaushik

gcc/ChangeLog
2015-08-27  Kaushik Phatak  <kaushik.phatak@kpit.com>

	* config/rl78/rl78-real.md (movqi_from_mduc,movhi_from_mdal,
	movhi_from_mdah,movhi_from_mdbl,movhi_from_mdbh,movhi_from_mdcl,
	movhi_from_mdch,movqi_to_mduc,movhi_to_mdal,movhi_to_mdah,
	movhi_to_mdbl,movhi_to_mdbh,movhi_to_mdcl,movhi_to_mdch): New patterns.
	* config/rl78/rl78.c (rl78_expand_prologue): Save the MDUC related
	register 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.opt (msave-mduc-in-interrupts): New option.
	* doc/invoke.texi (@item -msave-mduc-in-interrupts): New item.
	
Index: gcc/config/rl78/rl78-real.md
===================================================================
--- gcc/config/rl78/rl78-real.md	(revision 227024)
+++ gcc/config/rl78/rl78-real.md	(working copy)
@@ -37,6 +37,55 @@
 
 ;;---------- Moving ------------------------
 
+(define_insn "movqi_from_mduc"
+  [(set (match_operand:QI 0 "register_operand" "=a")
+	(unspec_volatile:QI [(match_operand:QI 1 "" "")] UNS_BUILTIN_MDUC))]
+  ""
+  "mov\t%0, !0xf00e8"
+)
+
+(define_insn "movhi_from_mdal"
+  [(set (match_operand:HI 0 "register_operand" "=A")
+	(unspec_volatile:HI [(match_operand:HI 1 "" "")] UNS_BUILTIN_MDAL))]
+  ""
+  "movw\t%0, !0xffff0"
+)
+
+(define_insn "movhi_from_mdah"
+  [(set (match_operand:HI 0 "register_operand" "=A")
+	(unspec_volatile:HI [(match_operand:HI 1 "" "")] UNS_BUILTIN_MDAH))]
+  ""
+  "movw\t%0, !0xffff2"
+)
+
+(define_insn "movhi_from_mdbl"
+  [(set (match_operand:HI 0 "register_operand" "=A")
+	(unspec_volatile:HI [(match_operand 1)] UNS_BUILTIN_MDBL))]
+  ""
+  "movw\t%0, !0xffff4"
+)
+
+(define_insn "movhi_from_mdbh"
+  [(set (match_operand:HI 0 "register_operand" "=A")
+	(unspec_volatile:HI [(match_operand 1)] UNS_BUILTIN_MDBH))]
+  ""
+  "movw\t%0, !0xffff6"
+)
+
+(define_insn "movhi_from_mdcl"
+  [(set (match_operand:HI 0 "register_operand" "=A")
+	(unspec_volatile:HI [(match_operand 1)] UNS_BUILTIN_MDCL))]
+  ""
+  "movw\t%0, !0xf00e0"
+)
+
+(define_insn "movhi_from_mdch"
+  [(set (match_operand:HI 0 "register_operand" "=A")
+	(unspec_volatile:HI [(match_operand 1)] UNS_BUILTIN_MDCH))]
+  ""
+  "movw\t%0, !0xf00e2"
+)
+
 (define_insn "movqi_to_es"
   [(set (reg:QI ES_REG)
 	(match_operand:QI 0 "register_operand" "a"))]
@@ -51,6 +100,62 @@
   "mov\t%0, es"
 )
 
+(define_insn "movqi_to_mduc"
+  [(set (reg:QI 0 )
+   	(unspec_volatile:QI [(match_operand:QI 0)] UNS_BUILTIN_MDUC))
+			     (match_operand:QI 1 "register_operand" "A")]
+  ""
+  "mov\t!0xf00e8, %1"
+)
+
+(define_insn "movhi_to_mdal"
+  [(set (reg:HI 0 )
+	(unspec_volatile:HI [(match_operand:HI 0)] UNS_BUILTIN_MDAL))
+			     (match_operand:HI 1 "register_operand" "A")]
+  ""
+  "movw\t!0xffff0, %1"
+)
+
+(define_insn "movhi_to_mdah"
+  [(set (reg:HI 0 )
+	(unspec_volatile:HI [(match_operand:HI 0)] UNS_BUILTIN_MDAH))
+			     (match_operand:HI 1 "register_operand" "A")]
+  ""
+  "movw\t!0xffff2, %1"
+)
+
+(define_insn "movhi_to_mdbl"
+  [(set (reg:HI 0 )
+	(unspec_volatile:HI [(match_operand:HI 0)] UNS_BUILTIN_MDBL))
+			     (match_operand:HI 1 "register_operand" "A")]
+  ""
+  "movw\t!0xffff4, %1"
+)
+
+(define_insn "movhi_to_mdbh"
+  [(set (reg:HI 0 )
+	(unspec_volatile:HI [(match_operand:HI 0)] UNS_BUILTIN_MDBH))
+			     (match_operand:HI 1 "register_operand" "A")]
+  ""
+  "movw\t!0xffff6, %1"
+)
+
+(define_insn "movhi_to_mdcl"
+  [(set (reg:HI 0 )
+	(unspec_volatile:HI [(match_operand:HI 0)] UNS_BUILTIN_MDCL))
+			     (match_operand:HI 1 "register_operand" "A")]
+  ""
+  "movw\t!0xf00e0, %1"
+)
+
+(define_insn "movhi_to_mdch"
+  [(set (reg:HI 0 ) 
+	(unspec_volatile:HI [(match_operand:HI 0)] UNS_BUILTIN_MDCH))
+			     (match_operand:HI 1 "register_operand" "A")]
+  ""
+  "movw\t!0xf00e2, %1"
+)
+
 (define_insn "movqi_cs"
   [(set (reg:QI CS_REG)
 	(match_operand:QI 0 "register_operand" "a"))]
Index: gcc/config/rl78/rl78.c
===================================================================
--- gcc/config/rl78/rl78.c	(revision 227024)
+++ gcc/config/rl78/rl78.c	(working copy)
@@ -338,6 +338,10 @@
 #undef  TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE		rl78_option_override
 
+#define MUST_SAVE_MDUC_REGISTER                  \
+  (TARGET_SAVE_MDUC_REGISTER                     \
+   && (is_interrupt_func (NULL_TREE)) && RL78_MUL_G13)
+
 static void
 rl78_option_override (void)
 {
@@ -365,6 +369,9 @@
     /* Address spaces are currently only supported by C.  */
     error ("-mes0 can only be used with C");
 
+  if (TARGET_SAVE_MDUC_REGISTER && !(TARGET_G13 || RL78_MUL_G13))
+    warning (0, "mduc registers only saved for G13 target");
+
   switch (rl78_cpu_type)
     {
     case CPU_UNINIT:
@@ -1273,6 +1280,7 @@
   int i, fs;
   rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM);
   rtx ax = gen_rtx_REG (HImode, AX_REG);
+  rtx operand1;
   int rb = 0;
 
   if (rl78_is_naked_func ())
@@ -1330,6 +1338,39 @@
       F (emit_insn (gen_push (ax)));
     }
 
+  /* Save MDUC register from interrupt routine.  */
+  if (MUST_SAVE_MDUC_REGISTER)
+    {
+      emit_insn (gen_movqi_from_mduc (gen_rtx_REG (QImode, A_REG),
+				      gen_rtx_UNSPEC_VOLATILE (QImode, gen_rtvec (1, operand1),
+							       UNS_BUILTIN_MDUC)));
+      F (emit_insn (gen_push (ax)));
+      emit_insn (gen_movhi_from_mdal (gen_rtx_REG (HImode, AX_REG),
+				      gen_rtx_UNSPEC_VOLATILE (HImode, gen_rtvec (1, operand1),
+				      UNS_BUILTIN_MDAL)));
+      F (emit_insn (gen_push (ax)));
+      emit_insn (gen_movhi_from_mdah (gen_rtx_REG (HImode, AX_REG),
+				      gen_rtx_UNSPEC_VOLATILE (HImode, gen_rtvec (1, operand1),
+				      UNS_BUILTIN_MDAH)));
+      F (emit_insn (gen_push (ax)));
+      emit_insn (gen_movhi_from_mdbl (gen_rtx_REG (HImode, AX_REG),
+				      gen_rtx_UNSPEC_VOLATILE (HImode, gen_rtvec (1, operand1),
+				      UNS_BUILTIN_MDBL)));
+      F (emit_insn (gen_push (ax)));
+      emit_insn (gen_movhi_from_mdbh (gen_rtx_REG (HImode, AX_REG),
+				      gen_rtx_UNSPEC_VOLATILE (HImode, gen_rtvec (1, operand1),
+				      UNS_BUILTIN_MDBH)));
+      F (emit_insn (gen_push (ax)));
+      emit_insn (gen_movhi_from_mdcl (gen_rtx_REG (HImode, AX_REG),
+				      gen_rtx_UNSPEC_VOLATILE (HImode, gen_rtvec (1, operand1),
+				      UNS_BUILTIN_MDCL)));
+      F (emit_insn (gen_push (ax)));
+      emit_insn (gen_movhi_from_mdch (gen_rtx_REG (HImode, AX_REG),
+				      gen_rtx_UNSPEC_VOLATILE (HImode, gen_rtvec (1, operand1),
+				      UNS_BUILTIN_MDCH)));
+      F (emit_insn (gen_push (ax)));
+    }
+
   if (frame_pointer_needed)
     {
       F (emit_move_insn (ax, sp));
@@ -1372,6 +1413,7 @@
   int i, fs;
   rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM);
   rtx ax = gen_rtx_REG (HImode, AX_REG);
+  rtx operand1;
   int rb = 0;
 
   if (rl78_is_naked_func ())
@@ -1403,6 +1445,39 @@
 	}
     }
 
+  /* Restore MDUC register from interrupt routine  */
+  if (MUST_SAVE_MDUC_REGISTER)
+    {
+      emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
+      emit_insn (gen_movhi_to_mdch (gen_rtx_UNSPEC_VOLATILE (HImode,
+				    gen_rtvec (1, operand1),UNS_BUILTIN_MDCH),
+				    gen_rtx_REG (HImode, AX_REG)));
+      emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
+      emit_insn (gen_movhi_to_mdcl (gen_rtx_UNSPEC_VOLATILE (HImode,
+				    gen_rtvec (1, operand1),UNS_BUILTIN_MDCL),
+				    gen_rtx_REG (HImode, AX_REG)));
+      emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
+      emit_insn (gen_movhi_to_mdbh (gen_rtx_UNSPEC_VOLATILE (HImode,
+				    gen_rtvec (1, operand1),UNS_BUILTIN_MDBH),
+				    gen_rtx_REG (HImode, AX_REG)));
+      emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
+      emit_insn (gen_movhi_to_mdbl (gen_rtx_UNSPEC_VOLATILE (HImode,
+				    gen_rtvec (1, operand1),UNS_BUILTIN_MDBL),
+				    gen_rtx_REG (HImode, AX_REG)));
+      emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
+      emit_insn (gen_movhi_to_mdah (gen_rtx_UNSPEC_VOLATILE (HImode,
+				    gen_rtvec (1, operand1),UNS_BUILTIN_MDAH),
+				    gen_rtx_REG (HImode, AX_REG)));
+      emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
+      emit_insn (gen_movhi_to_mdal (gen_rtx_UNSPEC_VOLATILE (HImode,
+				    gen_rtvec (1, operand1),UNS_BUILTIN_MDAL),
+				    gen_rtx_REG (HImode, AX_REG)));
+      emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
+      emit_insn (gen_movqi_to_mduc (gen_rtx_UNSPEC_VOLATILE (QImode,
+				    gen_rtvec (1, operand1),UNS_BUILTIN_MDUC),
+				    gen_rtx_REG (QImode, A_REG)));
+    }
+
   if (is_interrupt_func (cfun->decl) && cfun->machine->uses_es)
     {
       emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
@@ -1498,6 +1573,9 @@
 
   if (cfun->machine->uses_es)
     fprintf (file, "\t; uses ES register\n");
+
+  if (MUST_SAVE_MDUC_REGISTER)
+    fprintf (file, "\t; uses MDUC register\n");
 }
 
 /* Return an RTL describing where a function return value of type RET_TYPE
Index: gcc/config/rl78/rl78.md
===================================================================
--- gcc/config/rl78/rl78.md	(revision 227024)
+++ gcc/config/rl78/rl78.md	(working copy)
@@ -50,6 +50,13 @@
    (UNS_TRAMPOLINE_INIT		20)
    (UNS_TRAMPOLINE_UNINIT	21)
    (UNS_NONLOCAL_GOTO		22)
+   (UNS_BUILTIN_MDUC           35)
+   (UNS_BUILTIN_MDAL           36)
+   (UNS_BUILTIN_MDAH           37)
+   (UNS_BUILTIN_MDBL           38)
+   (UNS_BUILTIN_MDBH           39)
+   (UNS_BUILTIN_MDCL           40)
+   (UNS_BUILTIN_MDCH           41)
 
    ])
 
Index: gcc/config/rl78/rl78.opt
===================================================================
--- gcc/config/rl78/rl78.opt	(revision 227024)
+++ gcc/config/rl78/rl78.opt	(working copy)
@@ -91,3 +91,7 @@
 mes0
 Target Mask(ES0)
 Assume ES is zero throughout program execution, use ES: for read-only data.
+
+msave-mduc-in-interrupts
+Target Mask(SAVE_MDUC_REGISTER)
+Specifies whether interrupt functions should save and restore the MDUC register.
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 227024)
+++ gcc/doc/invoke.texi	(working copy)
@@ -19026,6 +19026,14 @@
 or 32 bits (@option{-m32bit-doubles}) in size.  The default is
 @option{-m32bit-doubles}.
 
+@item -msave-mduc-in-interrupts
+@opindex msave-mduc-in-interrupts
+Specifies that interrupt handler functions should preserve the
+MDUC registers.  This is only necessary if normal code might use
+the MDUC register, 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
+
 @end table
 
 @node RS/6000 and PowerPC Options

-----Original Message-----
From: DJ Delorie [mailto:dj@redhat.com] 
Sent: Friday, June 05, 2015 12:15 PM
To: Kaushik Phatak <Kaushik.Phatak@kpit.com>
Cc: gcc-patches@gcc.gnu.org; nickc@redhat.com
Subject: Re: [PATCH : RL78] Disable interrupts during hardware multiplication routines


  reply	other threads:[~2015-08-27 13:14 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-05  6:44 Kaushik Phatak
2015-06-05  8:02 ` DJ Delorie
2015-08-27 13:14   ` Kaushik Phatak [this message]
2015-08-27 17:11     ` Mike Stump
2015-08-27 17:25     ` DJ Delorie
2015-12-07 12:36       ` Kaushik Phatak
     [not found] <CAJA2CV1y0Mk20KqgFbdFs19tyPCH7HvR_XGAwy=OyhYcgNLuWQ@mail.gmail.com>
     [not found] ` <C6735D72-E033-470D-A8B2-1949D7A04AEE@comcast.net>
2016-01-07 11:27   ` 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=HK2PR03MB138012713E3B01220DD3E2DEFC6F0@HK2PR03MB1380.apcprd03.prod.outlook.com \
    --to=kaushik.phatak@kpit.com \
    --cc=dj@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=nickc@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).