summaryrefslogtreecommitdiff
path: root/openwrt/toolchain/gcc/3.4.2/400-mips-pr17565.patch
diff options
context:
space:
mode:
authormbm <mbm@3c298f89-4303-0410-b956-a3cf2f4a3e73>2005-01-16 11:43:02 +0000
committermbm <mbm@3c298f89-4303-0410-b956-a3cf2f4a3e73>2005-01-16 11:43:02 +0000
commit3d80c3754b3421428b47f89ce26f07adf10e7501 (patch)
tree986493f1905c17f3a385831d60709492c4c5ed7a /openwrt/toolchain/gcc/3.4.2/400-mips-pr17565.patch
parentf93f63a886f8fb0adcbc15fa0630e6ab9e7adc02 (diff)
Initial revision
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@197 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'openwrt/toolchain/gcc/3.4.2/400-mips-pr17565.patch')
-rw-r--r--openwrt/toolchain/gcc/3.4.2/400-mips-pr17565.patch102
1 files changed, 102 insertions, 0 deletions
diff --git a/openwrt/toolchain/gcc/3.4.2/400-mips-pr17565.patch b/openwrt/toolchain/gcc/3.4.2/400-mips-pr17565.patch
new file mode 100644
index 0000000000..7ae6aa56f6
--- /dev/null
+++ b/openwrt/toolchain/gcc/3.4.2/400-mips-pr17565.patch
@@ -0,0 +1,102 @@
+[committed] Fix target/17565: asms in delay slots
+
+ * From: Richard Sandiford <rsandifo at redhat dot com>
+ * To: gcc-patches at gcc dot gnu dot org
+ * Date: Mon, 20 Sep 2004 07:55:58 +0100
+ * Subject: [committed] Fix target/17565: asms in delay slots
+
+The MIPS port was allowing asms to be put into delay slots if the
+compiler guesses they are only one instruction long. This is wrong
+because of the possibility of it containing macros.
+
+The problem can be reproduced as an assembler warning
+in the following testcase:
+
+int foo (int n)
+{
+ register int k asm ("$16") = n;
+ if (k > 0)
+ {
+ bar ();
+ asm ("li %0,0x12345678" : "=r" (k));
+ }
+ return k;
+}
+
+because the multi-instruction asm statement goes into the delay
+slot of the call to bar().
+
+This is reduced from a much more serious linux problem. Linux is fond
+of using empty asm statements, and since gcc estimates empty asms to be
+one instruction long, they too might be put into delay slots. This
+actually has the effect of putting the following instruction into the
+delay slot instead. Since there's no assembler warning, the problem was
+only detected as a run-time failure.
+
+The fix is simple: set the asm value of "can_delay" to "no".
+Tested on mipsisa64-elf, applied to mainline.
+
+This problem goes back to at least 2.95, so it isn't technically a
+regression. On the other hand, it's the kind of bug that could trigger
+for different types of code in different releases, so I'm sure there's
+a testcase that fails (say) in 3.4 and not in 2.95. Will probably ask
+Mark for permission to backport to 3.4.
+
+Richard
+
+
+ PR target/17565
+ * config/mips/mips.md (define_asm_attributes): Set can_delay to no.
+
+testsuite/
+ * gcc.target/mips/asm-1.c: New test.
+
+Index: config/mips/mips.md
+===================================================================
+RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.md,v
+retrieving revision 1.306
+diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.306 mips.md
+*** gcc/gcc/config/mips/mips.md 13 Sep 2004 19:32:05 -0000 1.306
+--- gcc/gcc/config/mips/mips.md 20 Sep 2004 06:52:31 -0000
+*************** (define_attr "may_clobber_hilo" "no,yes"
+*** 266,272 ****
+
+ ;; Describe a user's asm statement.
+ (define_asm_attributes
+! [(set_attr "type" "multi")])
+
+ ;; .........................
+ ;;
+--- 266,273 ----
+
+ ;; Describe a user's asm statement.
+ (define_asm_attributes
+! [(set_attr "type" "multi")
+! (set_attr "can_delay" "no")])
+
+ ;; .........................
+ ;;
+Index: testsuite/gcc.target/mips/asm-1.c
+===================================================================
+RCS file: testsuite/gcc.target/mips/asm-1.c
+diff -N testsuite/gcc.target/mips/asm-1.c
+*** gcc/gcc/testsuite/gcc.target/mips/asm-1.c 1 Jan 1970 00:00:00 -0000
+--- gcc/gcc/testsuite/gcc.target/mips/asm-1.c 20 Sep 2004 06:52:31 -0000
+***************
+*** 0 ****
+--- 1,14 ----
++ /* PR target/17565. GCC used to put the asm into the delay slot
++ of the call. */
++ /* { dg-do assemble } */
++ /* { dg-options "-O" } */
++ int foo (int n)
++ {
++ register int k asm ("$16") = n;
++ if (k > 0)
++ {
++ bar ();
++ asm ("li %0,0x12345678" : "=r" (k));
++ }
++ return k;
++ }
+