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