aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorKaushik Phatak <kaushik.phatak@kpitcummins.com>2010-04-11 22:53:30 +0000
committerKaz Kojima <kkojima@gcc.gnu.org>2010-04-11 22:53:30 +0000
commitc11c09f9beac5e556e0c27d898cdbfd9a309fea1 (patch)
tree94c019311ac9df0d6c29b9bc504e117305da107b /gcc
parentd72ebc16bbf1edcf8d772b9b5686d26a44ae166a (diff)
downloadgcc-c11c09f9beac5e556e0c27d898cdbfd9a309fea1.zip
gcc-c11c09f9beac5e556e0c27d898cdbfd9a309fea1.tar.gz
gcc-c11c09f9beac5e556e0c27d898cdbfd9a309fea1.tar.bz2
sh.md (*movqi_pop): New insn pattern.
* config/sh/sh.md (*movqi_pop): New insn pattern. * config/sh/predicates.md (sh_no_delay_pop_operand): New predicate. * gcc.target/sh/rte-delay-slot.c: New test. From-SVN: r158207
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/sh/predicates.md22
-rw-r--r--gcc/config/sh/sh.md18
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/sh/rte-delay-slot.c33
5 files changed, 80 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c3de163..defa3ba 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2010-04-11 Kaushik Phatak <kaushik.phatak@kpitcummins.com>
+
+ * config/sh/sh.md (*movqi_pop): New insn pattern.
+ * config/sh/predicates.md (sh_no_delay_pop_operand): New predicate.
+
2010-04-11 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (any_shiftrt): New code iterator.
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index 909b4a4..b6508b7 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -1,5 +1,6 @@
;; Predicate definitions for Renesas / SuperH SH.
-;; Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
;;
;; This file is part of GCC.
;;
@@ -421,6 +422,25 @@
return general_operand (op, mode);
})
+
+;; Returns 1 if OP is a POST_INC on stack pointer register.
+
+(define_predicate "sh_no_delay_pop_operand"
+ (match_code "mem")
+{
+ rtx inside;
+ inside = XEXP (op, 0);
+
+ if (GET_CODE (op) == MEM && GET_MODE (op) == SImode
+ && GET_CODE (inside) == POST_INC
+ && GET_CODE (XEXP (inside, 0)) == REG
+ && REGNO (XEXP (inside, 0)) == SP_REG)
+ return 1;
+
+ return 0;
+})
+
+
;; Returns 1 if OP is a MEM that can be source of a simple move operation.
(define_predicate "unaligned_load_operand"
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 4318c70..d8d6ca7 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -1,6 +1,7 @@
;;- Machine description for Renesas / SuperH SH.
;; Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-;; 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+;; 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+;; Free Software Foundation, Inc.
;; Contributed by Steve Chamberlain (sac@cygnus.com).
;; Improved by Jim Wilson (wilson@cygnus.com).
@@ -4836,6 +4837,21 @@ label:
"TARGET_SH1"
"sett")
+;; Define additional pop for SH1 and SH2 so it does not get
+;; placed in the delay slot.
+(define_insn "*movsi_pop"
+ [(set (match_operand:SI 0 "register_operand" "=r,x,l")
+ (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
+ "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
+ && ! TARGET_SH3"
+ "@
+ mov.l %1,%0
+ lds.l %1,%0
+ lds.l %1,%0"
+ [(set_attr "type" "load_si,mem_mac,pload")
+ (set_attr "length" "2,2,2")
+ (set_attr "in_delay_slot" "no,no,no")])
+
;; t/r must come after r/r, lest reload will try to reload stuff like
;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1c4c5de..24eebcf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2010-04-11 Kaushik Phatak <kaushik.phatak@kpitcummins.com>
+
+ * gcc.target/sh/rte-delay-slot.c: New test.
+
2010-04-11 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/pack9.adb: Remove -cargs option.
diff --git a/gcc/testsuite/gcc.target/sh/rte-delay-slot.c b/gcc/testsuite/gcc.target/sh/rte-delay-slot.c
new file mode 100644
index 0000000..eca5db9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/rte-delay-slot.c
@@ -0,0 +1,33 @@
+/* { dg-do compile { target "sh-*-*" } } */
+/* { dg-options "-O2" } */
+/* { dg-skip-if "" { "sh*-*-*" } "*" "-m1 -m2*" } */
+/* { dg-final { scan-assembler-not "\trte\t\n\tmov.l\t@r15\\+" } } */
+
+/* This test checks if the compiler generates a pop instruction
+ in the delay slot after rte. For the sh and sh2, the rte
+ instruction reads the return pc from the stack and any pop
+ in the delay slot crashes the hardware.
+
+ Incorrect code generated
+ mov.l @r15+,r1
+ rte
+ mov.l @r15+,r14
+
+ The right code should be
+
+ mov.l @r15+,r1
+ mov.l @r15+,r14
+ rte
+ nop
+*/
+void INT_MTU2_1_TGIA1 (void)
+ __attribute__ ((interrupt_handler));
+void
+INT_MTU2_1_TGIA1 (void)
+{
+ volatile int i = 0;
+ volatile int x, y;
+
+ for (i = 0; i < 10; i++)
+ y = y + x;
+}