restore.c revision 1.1
1/* This testcase is part of GDB, the GNU debugger.
2
3   Copyright 1998-2014 Free Software Foundation, Inc.
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 3 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18/* Test GDB's ability to restore saved registers from stack frames
19   when using the `return' command.
20   Jim Blandy <jimb@cygnus.com> --- December 1998 */
21
22#include <stdio.h>
23
24/* This is the Emacs Lisp expression I used to generate the functions
25   in this file.  If people modify the functions manually, instead of
26   changing this expression and re-running it, then evaluating this
27   expression could wipe out their work, so you probably shouldn't
28   re-run it.  But I leave it here for reference.
29
30   (defun callee (n) (format "callee%d" n))
31   (defun caller (n) (format "caller%d" n))
32   (defun local  (n) (format "l%d"  n))
33   (defun local-sum (n)
34     (if (zerop n) (insert "0")
35       (let ((j 1))
36         (while (<= j n)
37           (insert (local j))
38           (if (< j n) (insert "+"))
39           (setq j (1+ j))))))
40   (defun local-chain (n previous first-end)
41     (let ((j 1))
42       (while (<= j n)
43	 (insert "  register int " (local j)
44                 " = increment (" previous  ");")
45	 (if first-end
46	   (progn
47             (insert "  /" "* " first-end " prologue *" "/")
48             (setq first-end nil)))
49	 (insert "\n")
50	 (setq previous (local j))
51	 (setq j (1+ j))))
52     previous)
53
54   (save-excursion
55     (let ((limit 5))
56       (goto-char (point-max))
57       (search-backward "generated code starts here")
58       (forward-line 1)
59       (let ((start (point)))
60	 (search-forward "generated code ends here")
61	 (forward-line 0)
62	 (delete-region start (point)))
63
64       ;; Generate callee functions.
65       (let ((i 0))
66	 (while (<= i limit)
67           (insert (format "/%s Returns n * %d + %d %s/\n"
68                           "*" i (/ (+ i (* i i)) 2) "*"))
69	   (insert "int\n")
70	   (insert (callee i) " (int n)\n")
71	   (insert "{\n")
72	   (local-chain i "n" (callee i))
73	   (insert "  return ")
74	   (local-sum i)
75	   (insert ";\n")
76	   (insert "}\n\n")
77	   (setq i (1+ i))))
78
79       ;; Generate caller functions.
80       (let ((i 1))
81	 (while (<= i limit)
82	   (insert "int\n")
83	   (insert (caller i) " (void)\n")
84	   (insert "{\n")
85	   (let ((last (local-chain i "0x7eeb" (caller i))))
86	     (insert "  register int n;\n")
87	     (let ((j 0))
88	       (while (<= j limit)
89	         (insert "  n = " (callee j) " ("
90                         (if (> j 0) "n + " "")
91		         last ");\n")
92	         (setq j (1+ j)))))
93	   (insert "  return n+")
94	   (local-sum i)
95           (insert ";\n")
96	   (insert "}\n\n")
97	   (setq i (1+ i))))
98
99       ;; Generate driver function.
100       (insert "void\n")
101       (insert "driver (void)\n")
102       (insert "{\n")
103       (let ((i 1))
104	 (while (<= i limit)
105	   (insert "  printf (\"" (caller i) " () => %d\\n\", "
106		   (caller i) " ());\n")
107	   (setq i (1+ i))))
108       (insert "}\n\n")))
109
110	 */
111
112int
113increment (int n)
114{
115  return n + 1;
116}
117
118/* generated code starts here */
119/* Returns n * 0 + 0 */
120int
121callee0 (int n)
122{
123  return 0;
124}
125
126/* Returns n * 1 + 1 */
127int
128callee1 (int n)
129{
130  register int l1 = increment (n);  /* callee1 prologue */
131  return l1;
132}
133
134/* Returns n * 2 + 3 */
135int
136callee2 (int n)
137{
138  register int l1 = increment (n);  /* callee2 prologue */
139  register int l2 = increment (l1);
140  return l1+l2;
141}
142
143/* Returns n * 3 + 6 */
144int
145callee3 (int n)
146{
147  register int l1 = increment (n);  /* callee3 prologue */
148  register int l2 = increment (l1);
149  register int l3 = increment (l2);
150  return l1+l2+l3;
151}
152
153/* Returns n * 4 + 10 */
154int
155callee4 (int n)
156{
157  register int l1 = increment (n);  /* callee4 prologue */
158  register int l2 = increment (l1);
159  register int l3 = increment (l2);
160  register int l4 = increment (l3);
161  return l1+l2+l3+l4;
162}
163
164/* Returns n * 5 + 15 */
165int
166callee5 (int n)
167{
168  register int l1 = increment (n);  /* callee5 prologue */
169  register int l2 = increment (l1);
170  register int l3 = increment (l2);
171  register int l4 = increment (l3);
172  register int l5 = increment (l4);
173  return l1+l2+l3+l4+l5;
174}
175
176int
177caller1 (void)
178{
179  register int l1 = increment (0x7eeb);  /* caller1 prologue */
180  register int n;
181  n = callee0 (l1);
182  n = callee1 (n + l1);
183  n = callee2 (n + l1);
184  n = callee3 (n + l1);
185  n = callee4 (n + l1);
186  n = callee5 (n + l1);
187  return n+l1;
188}
189
190int
191caller2 (void)
192{
193  register int l1 = increment (0x7eeb);  /* caller2 prologue */
194  register int l2 = increment (l1);
195  register int n;
196  n = callee0 (l2);
197  n = callee1 (n + l2);
198  n = callee2 (n + l2);
199  n = callee3 (n + l2);
200  n = callee4 (n + l2);
201  n = callee5 (n + l2);
202  return n+l1+l2;
203}
204
205int
206caller3 (void)
207{
208  register int l1 = increment (0x7eeb);  /* caller3 prologue */
209  register int l2 = increment (l1);
210  register int l3 = increment (l2);
211  register int n;
212  n = callee0 (l3);
213  n = callee1 (n + l3);
214  n = callee2 (n + l3);
215  n = callee3 (n + l3);
216  n = callee4 (n + l3);
217  n = callee5 (n + l3);
218  return n+l1+l2+l3;
219}
220
221int
222caller4 (void)
223{
224  register int l1 = increment (0x7eeb);  /* caller4 prologue */
225  register int l2 = increment (l1);
226  register int l3 = increment (l2);
227  register int l4 = increment (l3);
228  register int n;
229  n = callee0 (l4);
230  n = callee1 (n + l4);
231  n = callee2 (n + l4);
232  n = callee3 (n + l4);
233  n = callee4 (n + l4);
234  n = callee5 (n + l4);
235  return n+l1+l2+l3+l4;
236}
237
238int
239caller5 (void)
240{
241  register int l1 = increment (0x7eeb);  /* caller5 prologue */
242  register int l2 = increment (l1);
243  register int l3 = increment (l2);
244  register int l4 = increment (l3);
245  register int l5 = increment (l4);
246  register int n;
247  n = callee0 (l5);
248  n = callee1 (n + l5);
249  n = callee2 (n + l5);
250  n = callee3 (n + l5);
251  n = callee4 (n + l5);
252  n = callee5 (n + l5);
253  return n+l1+l2+l3+l4+l5;
254}
255
256void
257driver (void)
258{
259  printf ("caller1 () => %d\n", caller1 ());
260  printf ("caller2 () => %d\n", caller2 ());
261  printf ("caller3 () => %d\n", caller3 ());
262  printf ("caller4 () => %d\n", caller4 ());
263  printf ("caller5 () => %d\n", caller5 ());
264}
265
266/* generated code ends here */
267
268int main ()
269{
270  register int local;
271  driver ();
272  printf("exiting\n");
273  return 0;
274}
275