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
next prev parent 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).