400-mips-pr17565.patch 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. [committed] Fix target/17565: asms in delay slots
  2. * From: Richard Sandiford <rsandifo at redhat dot com>
  3. * To: gcc-patches at gcc dot gnu dot org
  4. * Date: Mon, 20 Sep 2004 07:55:58 +0100
  5. * Subject: [committed] Fix target/17565: asms in delay slots
  6. The MIPS port was allowing asms to be put into delay slots if the
  7. compiler guesses they are only one instruction long. This is wrong
  8. because of the possibility of it containing macros.
  9. The problem can be reproduced as an assembler warning
  10. in the following testcase:
  11. int foo (int n)
  12. {
  13. register int k asm ("$16") = n;
  14. if (k > 0)
  15. {
  16. bar ();
  17. asm ("li %0,0x12345678" : "=r" (k));
  18. }
  19. return k;
  20. }
  21. because the multi-instruction asm statement goes into the delay
  22. slot of the call to bar().
  23. This is reduced from a much more serious linux problem. Linux is fond
  24. of using empty asm statements, and since gcc estimates empty asms to be
  25. one instruction long, they too might be put into delay slots. This
  26. actually has the effect of putting the following instruction into the
  27. delay slot instead. Since there's no assembler warning, the problem was
  28. only detected as a run-time failure.
  29. The fix is simple: set the asm value of "can_delay" to "no".
  30. Tested on mipsisa64-elf, applied to mainline.
  31. This problem goes back to at least 2.95, so it isn't technically a
  32. regression. On the other hand, it's the kind of bug that could trigger
  33. for different types of code in different releases, so I'm sure there's
  34. a testcase that fails (say) in 3.4 and not in 2.95. Will probably ask
  35. Mark for permission to backport to 3.4.
  36. Richard
  37. PR target/17565
  38. * config/mips/mips.md (define_asm_attributes): Set can_delay to no.
  39. testsuite/
  40. * gcc.target/mips/asm-1.c: New test.
  41. Index: config/mips/mips.md
  42. ===================================================================
  43. RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.md,v
  44. retrieving revision 1.306
  45. diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.306 mips.md
  46. *** gcc/gcc/config/mips/mips.md 13 Sep 2004 19:32:05 -0000 1.306
  47. --- gcc/gcc/config/mips/mips.md 20 Sep 2004 06:52:31 -0000
  48. *************** (define_attr "may_clobber_hilo" "no,yes"
  49. *** 266,272 ****
  50. ;; Describe a user's asm statement.
  51. (define_asm_attributes
  52. ! [(set_attr "type" "multi")])
  53. ;; .........................
  54. ;;
  55. --- 266,273 ----
  56. ;; Describe a user's asm statement.
  57. (define_asm_attributes
  58. ! [(set_attr "type" "multi")
  59. ! (set_attr "can_delay" "no")])
  60. ;; .........................
  61. ;;
  62. Index: testsuite/gcc.target/mips/asm-1.c
  63. ===================================================================
  64. RCS file: testsuite/gcc.target/mips/asm-1.c
  65. diff -N testsuite/gcc.target/mips/asm-1.c
  66. *** gcc/gcc/testsuite/gcc.target/mips/asm-1.c 1 Jan 1970 00:00:00 -0000
  67. --- gcc/gcc/testsuite/gcc.target/mips/asm-1.c 20 Sep 2004 06:52:31 -0000
  68. ***************
  69. *** 0 ****
  70. --- 1,14 ----
  71. + /* PR target/17565. GCC used to put the asm into the delay slot
  72. + of the call. */
  73. + /* { dg-do assemble } */
  74. + /* { dg-options "-O" } */
  75. + int foo (int n)
  76. + {
  77. + register int k asm ("$16") = n;
  78. + if (k > 0)
  79. + {
  80. + bar ();
  81. + asm ("li %0,0x12345678" : "=r" (k));
  82. + }
  83. + return k;
  84. + }