1 /* Checks proper behavior of __morestack function - specifically, GPR
2    values surviving, stack parameters being copied, and vararg
3    pointer being correct.  */
4 
5 /* { dg-do run } */
6 /* { dg-options "-O2 -fsplit-stack" } */
7 
8 #include <stdlib.h>
9 
10 void *orig_r15;
11 
12 /* 1. Function "test" saves registers, makes a stack frame, puts known
13  *    values in registers, and calls __morestack, telling it to jump to
14  *    testinner, with return address pointing to "testret".
15  * 2. "testinner" checks that parameter registers match what has been
16  *    passed from "test", stack parameters were copied properly to
17  *    the new stack, and the argument pointer matches the calling
18  *    function's stack pointer.  It then leaves new values in volatile
19  *    registers (including return value registers) and returns.
20  * 3. "testret" checks that return value registers contain the expected
21  *    return value, callee-saved GPRs match the values from "test",
22  *    and then returns to main. */
23 
24 extern unsigned long testparams[3];
25 
26 #ifdef __s390x__
27 
28 asm(
29   ".global test\n"
30   "test:\n"
31   ".type test, @function\n"
32   /* Save registers.  */
33   "stmg %r6, %r15, 0x30(%r15)\n"
34   /* Save original sp in a global.  */
35   "larl %r1, orig_r15\n"
36   "stg %r15, 0(%r1)\n"
37   /* Make a stack frame.  */
38   "aghi %r15, -168\n"
39   /* A stack parameter.  */
40   "lghi %r1, 0x1240\n"
41   "stg %r1, 160(%r15)\n"
42   /* Registers.  */
43   "lghi %r0, 0x1230\n"
44   "lghi %r2, 0x1232\n"
45   "lghi %r3, 0x1233\n"
46   "lghi %r4, 0x1234\n"
47   "lghi %r5, 0x1235\n"
48   "lghi %r6, 0x1236\n"
49   "lghi %r7, 0x1237\n"
50   "lghi %r8, 0x1238\n"
51   "lghi %r9, 0x1239\n"
52   "lghi %r10, 0x123a\n"
53   "lghi %r11, 0x123b\n"
54   "lghi %r12, 0x123c\n"
55   "lghi %r13, 0x123d\n"
56   /* Fake return address.  */
57   "larl %r14, testret\n"
58   /* Call morestack.  */
59   "larl %r1, testparams\n"
60   "jg __morestack\n"
61 
62   /* Entry point.  */
63   "testinner:\n"
64   /* Check registers.  */
65   "cghi %r0, 0x1230\n"
66   "jne testerr\n"
67   "cghi %r2, 0x1232\n"
68   "jne testerr\n"
69   "cghi %r3, 0x1233\n"
70   "jne testerr\n"
71   "cghi %r4, 0x1234\n"
72   "jne testerr\n"
73   "cghi %r5, 0x1235\n"
74   "jne testerr\n"
75   "cghi %r6, 0x1236\n"
76   "jne testerr\n"
77   /* Check stack param.  */
78   "lg %r0, 0xa0(%r15)\n"
79   "cghi %r0, 0x1240\n"
80   "jne testerr\n"
81   /* Check argument pointer.  */
82   "aghi %r1, 8\n"
83   "larl %r2, orig_r15\n"
84   "cg %r1, 0(%r2)\n"
85   "jne testerr\n"
86   /* Modify volatile registers.  */
87   "lghi %r0, 0x1250\n"
88   "lghi %r1, 0x1251\n"
89   "lghi %r2, 0x1252\n"
90   "lghi %r3, 0x1253\n"
91   "lghi %r4, 0x1254\n"
92   "lghi %r5, 0x1255\n"
93   /* Return.  */
94   "br %r14\n"
95 
96   /* Returns here.  */
97   "testret:\n"
98   /* Check return registers.  */
99   "cghi %r2, 0x1252\n"
100   "jne testerr\n"
101   /* Check callee-saved registers.  */
102   "cghi %r6, 0x1236\n"
103   "jne testerr\n"
104   "cghi %r7, 0x1237\n"
105   "jne testerr\n"
106   "cghi %r8, 0x1238\n"
107   "jne testerr\n"
108   "cghi %r9, 0x1239\n"
109   "jne testerr\n"
110   "cghi %r10, 0x123a\n"
111   "jne testerr\n"
112   "cghi %r11, 0x123b\n"
113   "jne testerr\n"
114   "cghi %r12, 0x123c\n"
115   "jne testerr\n"
116   "cghi %r13, 0x123d\n"
117   "jne testerr\n"
118   /* Return.  */
119   "lmg %r6, %r15, 0xd8(%r15)\n"
120   "br %r14\n"
121 
122   /* Parameters block.  */
123   ".section .data\n"
124   ".align 8\n"
125   "testparams:\n"
126   ".quad 160\n"
127   ".quad 8\n"
128   ".quad testinner-testparams\n"
129   ".text\n"
130 );
131 
132 #else
133 
134 asm(
135   ".global test\n"
136   "test:\n"
137   ".type test, @function\n"
138   /* Save registers.  */
139   "stm %r6, %r15, 0x18(%r15)\n"
140   /* Save original sp in a global.  */
141   "larl %r1, orig_r15\n"
142   "st %r15, 0(%r1)\n"
143   /* Make a stack frame.  */
144   "ahi %r15, -0x68\n"
145   /* A stack parameter.  */
146   "lhi %r1, 0x1240\n"
147   "st %r1, 0x60(%r15)\n"
148   "lhi %r1, 0x1241\n"
149   "st %r1, 0x64(%r15)\n"
150   /* Registers.  */
151   "lhi %r0, 0x1230\n"
152   "lhi %r2, 0x1232\n"
153   "lhi %r3, 0x1233\n"
154   "lhi %r4, 0x1234\n"
155   "lhi %r5, 0x1235\n"
156   "lhi %r6, 0x1236\n"
157   "lhi %r7, 0x1237\n"
158   "lhi %r8, 0x1238\n"
159   "lhi %r9, 0x1239\n"
160   "lhi %r10, 0x123a\n"
161   "lhi %r11, 0x123b\n"
162   "lhi %r12, 0x123c\n"
163   "lhi %r13, 0x123d\n"
164   /* Fake return address.  */
165   "larl %r14, testret\n"
166   /* Call morestack.  */
167   "larl %r1, testparams\n"
168   "jg __morestack\n"
169 
170   /* Entry point.  */
171   "testinner:\n"
172   /* Check registers.  */
173   "chi %r0, 0x1230\n"
174   "jne testerr\n"
175   "chi %r2, 0x1232\n"
176   "jne testerr\n"
177   "chi %r3, 0x1233\n"
178   "jne testerr\n"
179   "chi %r4, 0x1234\n"
180   "jne testerr\n"
181   "chi %r5, 0x1235\n"
182   "jne testerr\n"
183   "chi %r6, 0x1236\n"
184   "jne testerr\n"
185   /* Check stack param.  */
186   "l %r0, 0x60(%r15)\n"
187   "chi %r0, 0x1240\n"
188   "jne testerr\n"
189   "l %r0, 0x64(%r15)\n"
190   "chi %r0, 0x1241\n"
191   "jne testerr\n"
192   /* Check argument pointer.  */
193   "ahi %r1, 8\n"
194   "larl %r2, orig_r15\n"
195   "c %r1, 0(%r2)\n"
196   "jne testerr\n"
197   /* Modify volatile registers.  */
198   "lhi %r0, 0x1250\n"
199   "lhi %r1, 0x1251\n"
200   "lhi %r2, 0x1252\n"
201   "lhi %r3, 0x1253\n"
202   "lhi %r4, 0x1254\n"
203   "lhi %r5, 0x1255\n"
204   /* Return.  */
205   "br %r14\n"
206 
207   /* Returns here.  */
208   "testret:\n"
209   /* Check return registers.  */
210   "chi %r2, 0x1252\n"
211   "jne testerr\n"
212   "chi %r3, 0x1253\n"
213   "jne testerr\n"
214   /* Check callee-saved registers.  */
215   "chi %r6, 0x1236\n"
216   "jne testerr\n"
217   "chi %r7, 0x1237\n"
218   "jne testerr\n"
219   "chi %r8, 0x1238\n"
220   "jne testerr\n"
221   "chi %r9, 0x1239\n"
222   "jne testerr\n"
223   "chi %r10, 0x123a\n"
224   "jne testerr\n"
225   "chi %r11, 0x123b\n"
226   "jne testerr\n"
227   "chi %r12, 0x123c\n"
228   "jne testerr\n"
229   "chi %r13, 0x123d\n"
230   "jne testerr\n"
231   /* Return.  */
232   "lm %r6, %r15, 0x80(%r15)\n"
233   "br %r14\n"
234 
235   /* Parameters block.  */
236   ".section .data\n"
237   ".align 4\n"
238   "testparams:\n"
239   ".long 96\n"
240   ".long 8\n"
241   ".long testinner-testparams\n"
242   ".text\n"
243 );
244 
245 #endif
246 
testerr(void)247 _Noreturn void testerr (void) {
248   exit(1);
249 }
250 
251 extern void test (void);
252 
main(void)253 int main (void) {
254   test();
255   /* Now try again, with huge stack frame requested - to exercise
256      both paths in __morestack (new allocation needed or not).  */
257   testparams[0] = 1000000;
258   test();
259   return 0;
260 }
261