mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-25 14:53:08 +02:00
3d80c3754b
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@197 3c298f89-4303-0410-b956-a3cf2f4a3e73
103 lines
3.1 KiB
Diff
103 lines
3.1 KiB
Diff
[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;
|
||
+ }
|
||
|