@@ -8192,7 +8192,8 @@
[(parallel [(call (match_operand 0 "memory_operand" "")
(match_operand 1 "general_operand" ""))
(return)
- (use (match_operand 2 "" ""))])])
+ (use (match_operand 2 "" ""))
+ (use (match_dup 0))])])
;; We may also be able to do sibcalls for Thumb, but it's much harder...
(define_expand "sibcall"
@@ -8225,7 +8226,8 @@
(call (match_operand 1 "memory_operand" "")
(match_operand 2 "general_operand" "")))
(return)
- (use (match_operand 3 "" ""))])])
+ (use (match_operand 3 "" ""))
+ (use (match_dup 1))])])
(define_expand "sibcall_value"
[(parallel [(set (match_operand 0 "" "")
@@ -8258,7 +8260,8 @@
[(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US"))
(match_operand 1 "" ""))
(return)
- (use (match_operand 2 "" ""))]
+ (use (match_operand 2 "" ""))
+ (use (match_operand 3 "" ""))]
"TARGET_32BIT && SIBLING_CALL_P (insn)"
"*
if (which_alternative == 1)
@@ -8279,7 +8282,8 @@
(call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US"))
(match_operand 2 "" "")))
(return)
- (use (match_operand 3 "" ""))]
+ (use (match_operand 3 "" ""))
+ (use (match_operand 4 "" ""))]
"TARGET_32BIT && SIBLING_CALL_P (insn)"
"*
if (which_alternative == 1)
new file mode 100644
@@ -0,0 +1,57 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#include <string.h>
+
+struct table_s
+ {
+ void (*fun0)
+ ( void );
+ void (*fun1)
+ ( void );
+ void (*fun2)
+ ( void );
+ void (*fun3)
+ ( void );
+ void (*fun4)
+ ( void );
+ void (*fun5)
+ ( void );
+ void (*fun6)
+ ( void );
+ void (*fun7)
+ ( void );
+ } table;
+
+void callback0(){__asm("mov r0, r0 \n\t");}
+void callback1(){__asm("mov r0, r0 \n\t");}
+void callback2(){__asm("mov r0, r0 \n\t");}
+void callback3(){__asm("mov r0, r0 \n\t");}
+void callback4(){__asm("mov r0, r0 \n\t");}
+
+void test (void) {
+ memset(&table, 0, sizeof table);
+
+ asm volatile ("" : : : "r3");
+
+ table.fun0 = callback0;
+ table.fun1 = callback1;
+ table.fun2 = callback2;
+ table.fun3 = callback3;
+ table.fun4 = callback4;
+ table.fun0();
+}
+
+void foo (void)
+{
+ __builtin_abort ();
+}
+
+int main (void)
+{
+ unsigned long p = (unsigned long) &foo;
+ asm volatile ("mov r3, %0" : : "r" (p));
+ test ();
+
+ return 0;
+}