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;
|
|||
|
+ }
|
|||
|
|