summaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.base/restore.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/testsuite/gdb.base/restore.c')
-rw-r--r--gdb/testsuite/gdb.base/restore.c260
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");
+}