]>
Commit | Line | Data |
---|---|---|
b5b0b447 ER |
1 | 2005-11-28 Jakub Jelinek <jakub@redhat.com> |
2 | ||
3 | * config/rs6000/rs6000.c (rs6000_return_addr): If COUNT == 0, | |
4 | read word RETURN_ADDRESS_OFFSET bytes above arg_pointer_rtx | |
5 | instead of doing an extran indirection from frame_pointer_rtx. | |
6 | ||
7 | * gcc.dg/20051128-1.c: New test. | |
8 | ||
9 | --- gcc/config/rs6000/rs6000.c.jj 2005-11-26 14:38:01.000000000 +0100 | |
10 | +++ gcc/config/rs6000/rs6000.c 2005-11-28 20:32:18.000000000 +0100 | |
11 | @@ -20970,18 +20970,22 @@ rs6000_return_addr (int count, rtx frame | |
12 | if (count != 0 | |
13 | || ((DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN) && flag_pic)) | |
14 | { | |
15 | + rtx x; | |
16 | cfun->machine->ra_needs_full_frame = 1; | |
17 | ||
18 | - return | |
19 | - gen_rtx_MEM | |
20 | - (Pmode, | |
21 | - memory_address | |
22 | - (Pmode, | |
23 | - plus_constant (Pmode, | |
24 | - copy_to_reg | |
25 | - (gen_rtx_MEM (Pmode, | |
26 | - memory_address (Pmode, frame))), | |
27 | - RETURN_ADDRESS_OFFSET))); | |
28 | + if (count == 0) | |
29 | + { | |
30 | + gcc_assert (frame == frame_pointer_rtx); | |
31 | + x = arg_pointer_rtx; | |
32 | + } | |
33 | + else | |
34 | + { | |
35 | + x = memory_address (Pmode, frame); | |
36 | + x = copy_to_reg (gen_rtx_MEM (Pmode, x)); | |
37 | + } | |
38 | + | |
39 | + x = plus_constant (Pmode, x, RETURN_ADDRESS_OFFSET); | |
40 | + return gen_rtx_MEM (Pmode, memory_address (Pmode, x)); | |
41 | } | |
42 | ||
43 | cfun->machine->ra_need_lr = 1; | |
44 | --- gcc/testsuite/gcc.dg/20051128-1.c.jj 2005-10-10 11:21:41.096999000 +0200 | |
45 | +++ gcc/testsuite/gcc.dg/20051128-1.c 2005-11-28 12:30:57.000000000 +0100 | |
46 | @@ -0,0 +1,41 @@ | |
47 | +/* { dg-do run } */ | |
48 | +/* { dg-options "-O2 -fpic" } */ | |
49 | + | |
50 | +extern void exit (int); | |
51 | +extern void abort (void); | |
52 | + | |
53 | +int b; | |
54 | + | |
55 | +struct A | |
56 | +{ | |
57 | + void *pad[147]; | |
58 | + void *ra, *h; | |
59 | + long o; | |
60 | +}; | |
61 | + | |
62 | +void | |
63 | +__attribute__((noinline)) | |
64 | +foo (struct A *a, void *x) | |
65 | +{ | |
66 | + __builtin_memset (a, 0, sizeof (a)); | |
67 | + if (!b) | |
68 | + exit (0); | |
69 | +} | |
70 | + | |
71 | +void | |
72 | +__attribute__((noinline)) | |
73 | +bar (void) | |
74 | +{ | |
75 | + struct A a; | |
76 | + | |
77 | + __builtin_unwind_init (); | |
78 | + foo (&a, __builtin_return_address (0)); | |
79 | +} | |
80 | + | |
81 | +int | |
82 | +main (void) | |
83 | +{ | |
84 | + bar (); | |
85 | + abort (); | |
86 | + return 0; | |
87 | +} |