From 973cd1230d9538e7bcd6aa058565eb016728e6a9 Mon Sep 17 00:00:00 2001 From: kkojima Date: Sun, 11 Apr 2010 22:53:30 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158207 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 +++++ gcc/config/sh/predicates.md | 22 ++++++++++++++++++- gcc/config/sh/sh.md | 18 ++++++++++++++- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/sh/rte-delay-slot.c | 33 ++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/sh/rte-delay-slot.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c3de163654d..defa3bab4ea 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2010-04-11 Kaushik Phatak + + * 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 * config/i386/i386.md (any_shiftrt): New code iterator. diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md index 909b4a45768..b6508b70d68 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 4318c702b42..d8d6ca7fbc0 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 1c4c5de95eb..24eebcfd877 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-04-11 Kaushik Phatak + + * gcc.target/sh/rte-delay-slot.c: New test. + 2010-04-11 Eric Botcazou * 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 00000000000..eca5db94355 --- /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; +} -- 2.11.4.GIT