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 113int 114increment (int n) 115{ 116 return n + 1; 117} 118 119/* generated code starts here */ 120/* Returns n * 0 + 0 */ 121int 122callee0 (int n) 123{ 124 return 0; 125} 126 127/* Returns n * 1 + 1 */ 128int 129callee1 (int n) 130{ 131 register int l1 = increment (n); /* callee1 prologue */ 132 return l1; 133} 134 135/* Returns n * 2 + 3 */ 136int 137callee2 (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 */ 145int 146callee3 (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 */ 155int 156callee4 (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 */ 166int 167callee5 (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 177int 178caller1 (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 191int 192caller2 (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 206int 207caller3 (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 222int 223caller4 (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 239int 240caller5 (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 257void 258driver (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 269int main () 270{ 271 register int local; 272#ifdef usestubs 273 set_debug_traps(); 274 breakpoint(); 275#endif 276 driver (); 277 printf("exiting\n"); 278 return 0; 279} 280