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