6def1cc63d3e6999eef985f9a7345cbac478db32
[external/binutils.git] / gdb / testsuite / gdb.arch / thumb-prologue.c
1 /* Unwinder test program.
2
3    Copyright 2006-2016 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");