xref: /netbsd-src/external/gpl3/gdb/dist/gdb/testsuite/gdb.base/restore.c (revision 6a493d6bc668897c91594964a732d38505b70cbb)
1 /* This testcase is part of GDB, the GNU debugger.
2 
3    Copyright 1998-2013 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 }
276