xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.arch/thumb-prologue.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* Unwinder test program.
2 
3    Copyright 2006-2023 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 void tpcs_frame (void);
21 void switch_stack_to_same (void);
22 void switch_stack_to_other (void);
23 
24 int
25 main (void)
26 {
27   tpcs_frame ();
28   switch_stack_to_same ();
29   switch_stack_to_other ();
30   return 0;
31 }
32 
33 /* Normally Thumb functions use r7 as the frame pointer.  However,
34    with the GCC option -mtpcs-frame, they may use fp instead.  Make
35    sure that the prologue analyzer can handle this.  */
36 
37 asm(".text\n"
38     "	.align 2\n"
39     "	.thumb_func\n"
40     "	.code 16\n"
41     "tpcs_frame_1:\n"
42     "	sub	sp, #16\n"
43     "	push	{r7}\n"
44     "	add	r7, sp, #20\n"
45     "	str	r7, [sp, #8]\n"
46     "	mov	r7, pc\n"
47     "	str	r7, [sp, #16]\n"
48     "	mov	r7, fp\n"
49     "	str	r7, [sp, #4]\n"
50     "	mov	r7, lr\n"
51     "	str	r7, [sp, #12]\n"
52     "	add	r7, sp, #16\n"
53     "	mov	fp, r7\n"
54     "	mov	r7, sl\n"
55     "	push	{r7}\n"
56 
57     /* We'll set a breakpoint at this call.  We can't hardcode a trap
58        instruction; the right instruction to use varies too much.  And
59        we can't use a global label, because GDB will think that's the
60        start of a new function.  So, this slightly convoluted
61        technique.  */
62     ".Ltpcs:\n"
63     "	nop\n"
64 
65     "	pop	{r2}\n"
66     "	mov	sl, r2\n"
67     "	pop	{r7}\n"
68     "	pop	{r1, r2}\n"
69     "	mov	fp, r1\n"
70     "	mov	sp, r2\n"
71     "	bx	lr\n"
72 
73     "	.align 2\n"
74     "	.type tpcs_offset, %object\n"
75     "tpcs_offset:\n"
76     "	.word .Ltpcs - tpcs_frame_1\n"
77 
78     "	.align 2\n"
79     "	.thumb_func\n"
80     "	.code 16\n"
81     "tpcs_frame:\n"
82     "	sub	sp, #16\n"
83     "	push	{r7}\n"
84     "	add	r7, sp, #20\n"
85     "	str	r7, [sp, #8]\n"
86     "	mov	r7, pc\n"
87     "	str	r7, [sp, #16]\n"
88     "	mov	r7, fp\n"
89     "	str	r7, [sp, #4]\n"
90     "	mov	r7, lr\n"
91     "	str	r7, [sp, #12]\n"
92     "	add	r7, sp, #16\n"
93     "	mov	fp, r7\n"
94     "	mov	r7, sl\n"
95     "	push	{r7}\n"
96 
97     /* Clobber saved regs around the call.  */
98     "	mov	r7, #0\n"
99     "	mov	lr, r7\n"
100     "	bl	tpcs_frame_1\n"
101 
102     "	pop	{r2}\n"
103     "	mov	sl, r2\n"
104     "	pop	{r7}\n"
105     "	pop	{r1, r2, r3}\n"
106     "	mov	fp, r1\n"
107     "	mov	sp, r2\n"
108     "	mov	lr, r3\n"
109     "	bx	lr\n"
110 );
111 
112 asm(".text\n"
113     "	.align 2\n"
114     "	.thumb_func\n"
115     "	.code 16\n"
116     "write_sp:\n"
117     "	mov	sp, r0\n"
118     "	bx	lr\n"
119 
120     "	.align 2\n"
121     "	.thumb_func\n"
122     "	.code 16\n"
123     "switch_stack_to_same:\n"
124     "	push	{lr}\n"
125     "	mov	r0, sp\n"
126     "	bl	write_sp\n"
127     "	pop	{r1}\n"
128     "	bx	r1\n"
129 
130     "	.align 2\n"
131     "	.thumb_func\n"
132     "	.code 16\n"
133     "switch_stack_to_other:\n"
134     "	push	{lr}\n"
135     "	mov	r7, sp\n"
136     "	mov	r0, #128\n"
137     "	bl	write_sp\n"
138     "	mov	sp, r7\n"
139     "	pop	{r1}\n"
140     "	bx	r1\n");
141