xref: /netbsd-src/external/gpl3/gdb/dist/gdb/testsuite/gdb.base/restore.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /* This testcase is part of GDB, the GNU debugger.
2 
3    Copyright 1998-2020 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 
112 int
113 increment (int n)
114 {
115   return n + 1;
116 }
117 
118 /* generated code starts here */
119 /* Returns n * 0 + 0 */
120 int
121 callee0 (int n)
122 {
123   return 0;
124 }
125 
126 /* Returns n * 1 + 1 */
127 int
128 callee1 (int n)
129 {
130   register int l1 = increment (n);  /* callee1 prologue */
131   return l1;
132 }
133 
134 /* Returns n * 2 + 3 */
135 int
136 callee2 (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 */
144 int
145 callee3 (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 */
154 int
155 callee4 (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 */
165 int
166 callee5 (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 
176 int
177 caller1 (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 
190 int
191 caller2 (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 
205 int
206 caller3 (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 
221 int
222 caller4 (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 
238 int
239 caller5 (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 
256 void
257 driver (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 
268 int main ()
269 {
270   register int local;
271   driver ();
272   printf("exiting\n");
273   return 0;
274 }
275