diff options
Diffstat (limited to 'gdb/testsuite/gdb.base/restore.c')
-rw-r--r-- | gdb/testsuite/gdb.base/restore.c | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/gdb/testsuite/gdb.base/restore.c b/gdb/testsuite/gdb.base/restore.c new file mode 100644 index 00000000000..a65d648b9d0 --- /dev/null +++ b/gdb/testsuite/gdb.base/restore.c @@ -0,0 +1,260 @@ +/* Test GDB's ability to restore saved registers from stack frames + when using the `return' command. + Jim Blandy <jimb@cygnus.com> --- December 1998 */ + +#include <stdio.h> + +/* This is the Emacs Lisp expression I used to generate the functions + in this file. If people modify the functions manually, instead of + changing this expression and re-running it, then evaluating this + expression could wipe out their work, so you probably shouldn't + re-run it. But I leave it here for reference. + + (defun callee (n) (format "callee%d" n)) + (defun caller (n) (format "caller%d" n)) + (defun local (n) (format "l%d" n)) + (defun local-sum (n) + (let ((j 1)) + (while (<= j n) + (insert (local j)) + (if (< j n) (insert "+")) + (setq j (1+ j))))) + (defun local-chain (n previous first-end) + (let ((j 1)) + (while (<= j n) + (insert " register int " (local j) + " = increment (" previous ");") + (if first-end + (progn + (insert " /" "* " first-end " *" "/") + (setq first-end nil))) + (insert "\n") + (setq previous (local j)) + (setq j (1+ j)))) + previous) + + (save-excursion + (let ((limit 5)) + (goto-char (point-max)) + (search-backward "generated code starts here") + (forward-line 1) + (let ((start (point))) + (search-forward "generated code ends here") + (forward-line 0) + (delete-region start (point))) + + ;; Generate callee functions. + (let ((i 0)) + (while (<= i limit) + (insert (format "/%s Returns n * %d + %d %s/\n" + "*" i (/ (+ i (* i i)) 2) "*")) + (insert "int\n") + (insert (callee i) " (int n)\n") + (insert "{\n") + (local-chain i "n" (callee i)) + (insert " return ") + (if (<= i 0) (insert "n") + (local-sum i)) + (insert ";\n") + (insert "}\n\n") + (setq i (1+ i)))) + + ;; Generate caller functions. + (let ((i 1)) + (while (<= i limit) + (insert "int\n") + (insert (caller i) " (void)\n") + (insert "{\n") + (let ((last (local-chain i "0xfeeb" (caller i)))) + (insert " register int n;\n") + (let ((j 0)) + (while (<= j limit) + (insert " n = " (callee j) " (" + (if (> j 0) "n + " "") + last ");\n") + (setq j (1+ j))))) + (insert " return n+") + (local-sum i) + (insert ";\n") + (insert "}\n\n") + (setq i (1+ i)))) + + ;; Generate driver function. + (insert "void\n") + (insert "driver (void)\n") + (insert "{\n") + (let ((i 1)) + (while (<= i limit) + (insert " printf (\"" (caller i) " () => %d\\n\", " + (caller i) " ());\n") + (setq i (1+ i)))) + (insert "}\n\n"))) + + */ + +int +increment (int n) +{ + return n + 1; +} + +/* generated code starts here */ +/* Returns n * 0 + 0 */ +int +callee0 (int n) +{ + return n; +} + +/* Returns n * 1 + 1 */ +int +callee1 (int n) +{ + register int l1 = increment (n); /* callee1 */ + return l1; +} + +/* Returns n * 2 + 3 */ +int +callee2 (int n) +{ + register int l1 = increment (n); /* callee2 */ + register int l2 = increment (l1); + return l1+l2; +} + +/* Returns n * 3 + 6 */ +int +callee3 (int n) +{ + register int l1 = increment (n); /* callee3 */ + register int l2 = increment (l1); + register int l3 = increment (l2); + return l1+l2+l3; +} + +/* Returns n * 4 + 10 */ +int +callee4 (int n) +{ + register int l1 = increment (n); /* callee4 */ + register int l2 = increment (l1); + register int l3 = increment (l2); + register int l4 = increment (l3); + return l1+l2+l3+l4; +} + +/* Returns n * 5 + 15 */ +int +callee5 (int n) +{ + register int l1 = increment (n); /* callee5 */ + register int l2 = increment (l1); + register int l3 = increment (l2); + register int l4 = increment (l3); + register int l5 = increment (l4); + return l1+l2+l3+l4+l5; +} + +int +caller1 (void) +{ + register int l1 = increment (0xfeeb); /* caller1 */ + register int n; + n = callee0 (l1); + n = callee1 (n + l1); + n = callee2 (n + l1); + n = callee3 (n + l1); + n = callee4 (n + l1); + n = callee5 (n + l1); + return n+l1; +} + +int +caller2 (void) +{ + register int l1 = increment (0xfeeb); /* caller2 */ + register int l2 = increment (l1); + register int n; + n = callee0 (l2); + n = callee1 (n + l2); + n = callee2 (n + l2); + n = callee3 (n + l2); + n = callee4 (n + l2); + n = callee5 (n + l2); + return n+l1+l2; +} + +int +caller3 (void) +{ + register int l1 = increment (0xfeeb); /* caller3 */ + register int l2 = increment (l1); + register int l3 = increment (l2); + register int n; + n = callee0 (l3); + n = callee1 (n + l3); + n = callee2 (n + l3); + n = callee3 (n + l3); + n = callee4 (n + l3); + n = callee5 (n + l3); + return n+l1+l2+l3; +} + +int +caller4 (void) +{ + register int l1 = increment (0xfeeb); /* caller4 */ + register int l2 = increment (l1); + register int l3 = increment (l2); + register int l4 = increment (l3); + register int n; + n = callee0 (l4); + n = callee1 (n + l4); + n = callee2 (n + l4); + n = callee3 (n + l4); + n = callee4 (n + l4); + n = callee5 (n + l4); + return n+l1+l2+l3+l4; +} + +int +caller5 (void) +{ + register int l1 = increment (0xfeeb); /* caller5 */ + register int l2 = increment (l1); + register int l3 = increment (l2); + register int l4 = increment (l3); + register int l5 = increment (l4); + register int n; + n = callee0 (l5); + n = callee1 (n + l5); + n = callee2 (n + l5); + n = callee3 (n + l5); + n = callee4 (n + l5); + n = callee5 (n + l5); + return n+l1+l2+l3+l4+l5; +} + +void +driver (void) +{ + printf ("caller1 () => %d\n", caller1 ()); + printf ("caller2 () => %d\n", caller2 ()); + printf ("caller3 () => %d\n", caller3 ()); + printf ("caller4 () => %d\n", caller4 ()); + printf ("caller5 () => %d\n", caller5 ()); +} + +/* generated code ends here */ + +main () +{ + register int local; +#ifdef usestubs + set_debug_traps(); + breakpoint(); +#endif + driver (); + printf("exiting\n"); +} |