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