Commit | Line | Data |
---|---|---|
fe5f7374 AK |
1 | ; This testcase is part of GDB, the GNU debugger. |
2 | ||
b811d2c2 | 3 | ; Copyright 2017-2020 Free Software Foundation, Inc. |
fe5f7374 AK |
4 | |
5 | ; This program is free software; you can redistribute it and/or modify | |
6 | ; it under the terms of the GNU General Public License as published by | |
7 | ; the Free Software Foundation; either version 3 of the License, or | |
8 | ; (at your option) any later version. | |
9 | ; | |
10 | ; This program is distributed in the hope that it will be useful, | |
11 | ; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | ; GNU General Public License for more details. | |
14 | ; | |
15 | ; You should have received a copy of the GNU General Public License | |
16 | ; along with this program. If not, see <http://www.gnu.org/licenses/>. | |
17 | ||
18 | .section .data | |
19 | some_variable: | |
20 | .long 0xdeadbeef | |
21 | ||
22 | .section .text | |
23 | .global main | |
24 | .type main, @function | |
25 | ||
26 | ; Standard prologue. | |
27 | ||
28 | .align 4 | |
29 | standard_prologue: | |
30 | push blink | |
31 | sub sp,sp,12 | |
32 | st r13, [sp, 0] | |
33 | st r14, [sp, 4] | |
34 | st r18, [sp, 8] | |
35 | add r0, r1, r2 | |
36 | ld r18, [sp, 8] | |
37 | ld r14, [sp, 4] | |
38 | ld r13, [sp, 0] | |
39 | add sp,sp,12 | |
40 | pop blink | |
41 | j [blink] | |
42 | ||
43 | ; Standard prologue using short instructions. | |
44 | ||
45 | .align 4 | |
46 | mini_prologue: | |
47 | push_s blink | |
48 | sub_s sp,sp,12 | |
49 | ; ST_S can store only some of the core registers. | |
50 | st_s r13, [sp, 0] | |
51 | st_s r15, [sp, 4] | |
52 | st_s r14, [sp, 8] | |
53 | add r0, r1, r2 | |
54 | add sp,sp,16 | |
55 | j [blink] | |
56 | ||
57 | ; Standard prologue without `sub sp,sp,INTEGER`. | |
58 | ||
59 | .align 4 | |
60 | no_subsp_prologue: | |
61 | push blink | |
62 | push r13 | |
63 | push r20 | |
64 | push r25 | |
65 | add r0, r1, r2 | |
66 | pop r25 | |
67 | pop r20 | |
68 | pop r13 | |
69 | pop blink | |
70 | j [blink] | |
71 | ||
72 | ; Standard prologue of leaf function. | |
73 | ||
74 | .align 4 | |
75 | leaf_prologue: | |
76 | sub sp,sp,8 | |
77 | st r13, [sp, 0] | |
78 | st r15, [sp, 4] | |
79 | add r0, r1, r2 | |
80 | ld r13, [sp, 0] | |
81 | ld r15, [sp, 4] | |
82 | j.d [blink] | |
83 | add sp,sp,8 | |
84 | ||
85 | ; Prologue with `push fp`. | |
86 | ||
87 | .align 4 | |
88 | pushfp_prologue: | |
89 | push r13 | |
90 | push r14 | |
91 | push fp | |
92 | ; mov fp,sp is part of prologue, but this test will not verify that. | |
93 | ; It will be checked later in the "arg_regs_fp" test. | |
94 | mov fp, sp | |
95 | add r0, r1, r2 | |
96 | pop fp | |
97 | pop r14 | |
98 | pop r13 | |
99 | j [blink] | |
100 | ||
101 | ; Prologue with frame pointer and store relative to FP. | |
102 | ||
103 | .align 4 | |
104 | fp_prologue_with_store: | |
105 | push r13 | |
106 | push r14 | |
107 | push fp | |
108 | mov fp, sp | |
109 | sub_s sp,sp,4 | |
110 | st r15,[fp,-4] | |
111 | add r0, r1, r2 | |
112 | pop r15 | |
113 | pop fp | |
114 | pop r14 | |
115 | pop r13 | |
116 | j [blink] | |
117 | ||
118 | ; Verify that store of the non-callee saved registers is not part of prologue. | |
119 | ; Repeat this test for multiple registers, to check boundaries. Also check | |
120 | ; with both ST and PUSH (aka ST.AW). We have to use multiple functions for | |
121 | ; this, because GDB would stop analisys at the first instruction that is not | |
122 | ; part of prologue. | |
123 | ||
124 | .align 4 | |
125 | noncallee_saved_regs_r12_st: | |
126 | sub sp,sp,8 | |
127 | st r13, [sp, 4] | |
128 | st r12, [sp, 0] | |
129 | add r0, r1, r2 | |
130 | j.d [blink] | |
131 | add sp,sp,8 | |
132 | ||
133 | .align 4 | |
134 | noncallee_saved_regs_r12_push: | |
135 | push r13 | |
136 | push r12 | |
137 | add r0, r1, r2 | |
138 | j.d [blink] | |
139 | add sp,sp,8 | |
140 | ||
141 | .align 4 | |
142 | noncallee_saved_regs_r2_push: | |
143 | push r13 | |
144 | push r2 | |
145 | add r0, r1, r2 | |
146 | j.d [blink] | |
147 | add sp,sp,8 | |
148 | ||
149 | .align 4 | |
150 | noncallee_saved_regs_gp_push: | |
151 | push r25 | |
152 | push gp | |
153 | add r0, r1, r2 | |
154 | j.d [blink] | |
155 | add sp,sp,8 | |
156 | ||
157 | ; LP_COUNT is treated like a normal register. | |
158 | ||
159 | .align 4 | |
160 | noncallee_saved_regs_lp_count: | |
161 | push r25 | |
162 | push lp_count | |
163 | add r0, r1, r2 | |
164 | j.d [blink] | |
165 | add sp,sp,8 | |
166 | ||
167 | ; BLINK is saved, but after an instruction that is not part of prologue. | |
168 | ; Currently arc_analyze_prologue stops analisys at the first intstruction | |
169 | ; that is not a part of prologue. This might be not the best way, but it is | |
170 | ; what it is right now, so this test confirms this. | |
171 | ||
172 | .align 4 | |
173 | noncallee_saved_regs_blink_out_of_prologue: | |
174 | push r25 | |
175 | push gp | |
176 | push blink | |
177 | add r0, r1, r2 | |
178 | j.d [blink] | |
179 | add sp,sp,12 | |
180 | ||
181 | ; Saving arguments register via FP. | |
182 | ||
183 | .align 4 | |
184 | arg_regs_fp: | |
185 | push fp | |
186 | mov fp, sp | |
187 | sub sp, sp, 16 | |
188 | st r0, [fp, -4] | |
189 | st r1, [fp, -8] | |
190 | st r7, [fp, -12] | |
191 | st r8, [fp, -16] | |
192 | add r0, r1, r2 | |
193 | add sp,sp,16 | |
194 | pop fp | |
195 | j [blink] | |
196 | ||
197 | ; Like the previous, but with mov_s. | |
198 | ||
199 | .align 4 | |
200 | arg_regs_fp_mov_s: | |
201 | push fp | |
202 | mov_s fp, sp | |
203 | sub sp, sp, 8 | |
204 | st r0, [fp, -4] | |
205 | ; Not part of the prologue. | |
206 | st r8, [fp, -8] | |
207 | add r0, r1, r2 | |
208 | add sp,sp,8 | |
209 | pop fp | |
210 | j [blink] | |
211 | ||
212 | ; Saving arguments register without FP. | |
213 | ||
214 | .align 4 | |
215 | arg_regs_sp: | |
216 | sub sp, sp, 24 | |
217 | st r0, [sp, 0] | |
218 | st r1, [sp, 4] | |
219 | st r7, [sp, 8] | |
220 | ; Normally that would be done before saving args, but it is used as a | |
221 | ; marker that saving arguments relatively to SP is considered part of | |
222 | ; prologue. | |
223 | st r13, [sp, 16] | |
224 | ; Not part of the prologue. | |
225 | st r8, [sp, 12] | |
226 | st r14, [sp, 20] | |
227 | add r0, r1, r2 | |
228 | j.d [blink] | |
229 | add sp,sp,24 | |
230 | ||
231 | ; ENTER_S that does nothing. | |
232 | ||
233 | .align 4 | |
234 | enter_s_nop: | |
235 | ; Effectively a nop. | |
236 | enter_s 0 | |
237 | add r0,r1,r2 | |
238 | j [blink] | |
239 | ||
240 | ; ENTER_S that stores BLINK. | |
241 | ||
242 | .align 4 | |
243 | enter_s_blink: | |
244 | enter_s 32 | |
245 | add r0,r1,r2 | |
246 | j.d [blink] | |
247 | add sp,sp,4 | |
248 | ||
249 | ; ENTER_S that stores FP. | |
250 | ||
251 | .align 4 | |
252 | enter_s_fp: | |
253 | enter_s 16 | |
254 | add r0,r1,r2 | |
255 | j.d [blink] | |
256 | add sp,sp,4 | |
257 | ||
258 | ; ENTER_S that stores R13, FP and BLINK. | |
259 | ||
260 | .align 4 | |
261 | enter_s_r13: | |
262 | enter_s (32 + 16 + 1) | |
263 | add r0,r1,r2 | |
264 | j.d [blink] | |
265 | add sp,sp,12 | |
266 | ||
267 | ; ENTER_S that stores R13-R15 | |
268 | ||
269 | .align 4 | |
270 | enter_s_r15: | |
271 | enter_s 3 | |
272 | add r0,r1,r2 | |
273 | j.d [blink] | |
274 | add sp,sp,12 | |
275 | ||
276 | ; ENTER_S that stores everything it could. | |
277 | ||
278 | .align 4 | |
279 | enter_s_all: | |
280 | enter_s (32 + 16 + 14) | |
281 | add r0,r1,r2 | |
282 | j.d [blink] | |
283 | add sp,sp,64 | |
284 | ||
285 | ; Deeper nesting. | |
286 | ||
287 | .align 4 | |
288 | nested_prologue_inner: | |
289 | sub sp,sp,8 | |
290 | st r18, [sp, 4] | |
291 | st r13, [sp, 0] | |
292 | add r0, r1, r2 | |
293 | ld r18, [sp, 4] | |
294 | ld r13, [sp, 0] | |
295 | j.d [blink] | |
296 | add sp,sp,8 | |
297 | ||
298 | .align 4 | |
299 | nested_prologue_outer: | |
300 | push blink | |
301 | sub sp,sp,8 | |
302 | st r14, [sp, 0] | |
303 | st r15, [sp, 4] | |
304 | bl @nested_prologue_inner | |
305 | add r0, r1, r2 | |
306 | ld r14, [sp, 0] | |
307 | ld r15, [sp, 4] | |
308 | add sp,sp,8 | |
309 | pop blink | |
310 | j [blink] | |
311 | ||
312 | ; Prologue with maximum length. | |
313 | ; Expressions like (0xFFFFFFFF + 25) force assembler to use long immediate | |
314 | ; even for values that don't need it, thus letting us test maksimum prologue | |
315 | ; length without having huge frames. | |
316 | .align 4 | |
317 | max_length_prologue: | |
318 | ; Variadic args | |
319 | sub sp,sp,(0xFFFFFFFF + 25) ; 24 bytes | |
320 | push blink | |
321 | ; Allocate space for 13 callee-saved and 8 arg regs. | |
322 | sub sp,sp,(0xFFFFFFFF + 1 + 21 * 4) | |
323 | st r13, [sp, 0] | |
324 | st r14, [sp, 4] | |
325 | st r15, [sp, 8] | |
326 | st r16, [sp, 12] | |
327 | st r17, [sp, 16] | |
328 | st r18, [sp, 20] | |
329 | st r19, [sp, 24] | |
330 | st r20, [sp, 28] | |
331 | st r21, [sp, 32] | |
332 | st r22, [sp, 36] | |
333 | st r23, [sp, 40] | |
334 | st r24, [sp, 44] | |
335 | st r25, [sp, 48] | |
336 | st r0, [sp, 52] | |
337 | st r1, [sp, 56] | |
338 | st r2, [sp, 60] | |
339 | st r3, [sp, 64] | |
340 | st r4, [sp, 68] | |
341 | st r5, [sp, 72] | |
342 | st r6, [sp, 76] | |
343 | st r7, [sp, 80] | |
344 | push fp | |
345 | mov fp,sp | |
346 | sub sp,sp,(0xFFFFFFFF + 1 + 16) ; Space for local variables. | |
347 | ; End of prologue. | |
348 | add sp,sp,24 + 21 * 4 + 16 | |
349 | j [blink] | |
350 | ||
351 | ; Few tests that test that prologue analysis stops at branch. There are four | |
352 | ; types of "branches": conditional and non-conditional, relative branches and | |
353 | ; absolute jumps. | |
354 | ||
355 | .align 4 | |
356 | branch_in_prologue: | |
357 | push r13 | |
358 | b @.L1 | |
359 | ; This store on stack is not a prologue. | |
360 | push r14 | |
361 | .L1: | |
362 | add r0,r1,r2 | |
363 | j.d [blink] | |
364 | add sp,sp,4 | |
365 | ||
366 | .align 4 | |
367 | cond_branch_in_prologue: | |
368 | sub_s sp,sp,8 | |
369 | st_s r13,[sp,4] | |
370 | ; Doesn't matter if branch is taken or not. | |
371 | breq r0,r1,@.L2 | |
372 | ; This store on stack is not a prologue. | |
373 | st_s r14,[sp,0] | |
374 | .L2: | |
375 | add r0,r1,r2 | |
376 | pop fp | |
377 | j.d [blink] | |
378 | add sp,sp,8 | |
379 | ||
380 | .align 4 | |
381 | jump_in_prologue: | |
382 | push r13 | |
383 | j @.L3 | |
384 | ; This store on stack is not a prologue. | |
385 | push r14 | |
386 | .L3: | |
387 | add r0,r1,r2 | |
388 | j.d [blink] | |
389 | add sp,sp,4 | |
390 | ||
391 | .align 4 | |
392 | cond_jump_in_prologue: | |
393 | sub_s sp,sp,8 | |
394 | st_s r13,[sp,4] | |
395 | ; It doesn't matter if jump is taken or not - prologue analysis has to | |
396 | ; stop before `jeq` in any case. | |
397 | jeq @.L4 | |
398 | ; This store on stack is not a prologue. | |
399 | st_s r14,[sp,0] | |
400 | .L4: | |
401 | add r0,r1,r2 | |
402 | j.d [blink] | |
403 | add sp,sp,8 | |
404 | ||
405 | .align 4 | |
406 | predicated_insn: | |
407 | sub_s sp,sp,12 | |
408 | st_s r13,[sp,8] | |
409 | st_s r15,[sp,0] | |
410 | ; Use SUB SP,SP,0 because it is otherwise a valid instruction for | |
411 | ; prologue, so it will halt analysis purely because of its predicate. | |
412 | sub.eq sp,sp,0 ; This is not a prologue anymore. | |
413 | st_s r14,[sp,4] | |
414 | add sp,sp,12 | |
415 | j [blink] | |
416 | ||
417 | ; Loops should halt prologue analysis. | |
418 | ||
419 | .align 4 | |
420 | loop_in_prologue: | |
421 | push r25 | |
422 | push lp_count | |
423 | mov lp_count, 4 | |
424 | lp @.Lloop_end1 | |
425 | push r26 ; Not part of prologue. | |
426 | add r0, r1, r2 | |
427 | .Lloop_end1: | |
428 | add r1, r1, r2 | |
429 | pop r26 | |
430 | add sp,sp,8 | |
431 | pop r25 | |
432 | j [blink] | |
433 | ||
434 | ; Store of a constant value (not a register). | |
435 | ||
436 | .align 4 | |
437 | store_constant: | |
438 | sub_s sp,sp,12 | |
439 | st_s r13,[sp,8] | |
440 | st 0xdeadbeef,[sp,0] | |
441 | st_s r14,[sp,4] | |
442 | add sp,sp,12 | |
443 | j [blink] | |
444 | ||
445 | ; Test that store to immediate address halts prologue analysis. | |
446 | .align 4 | |
447 | st_c_limm: | |
448 | push r15 | |
449 | st r14,[@some_variable] | |
450 | push r13 | |
451 | add sp,sp,8 | |
452 | j [blink] | |
453 | ||
454 | ; Store with AB writeback mode. | |
455 | ||
456 | .align 4 | |
457 | st_ab_writeback: | |
458 | sub sp,sp,8 | |
459 | st r13,[sp,4] | |
460 | st.ab r14,[sp,-4] | |
461 | st r15,[sp,0] | |
462 | add sp,sp,12 | |
463 | j [blink] | |
464 | ||
465 | ; Store of a word with AS writeback mode. | |
466 | ||
467 | .align 4 | |
468 | st_as_writeback: | |
469 | sub sp,sp,12 | |
470 | st r13,[sp,8] | |
471 | st.as r14,[sp,1] ; ST.AS, hence address is (offset << 2). | |
472 | st r15,[sp,0] | |
473 | add sp,sp,12 | |
474 | j [blink] | |
475 | ||
476 | ; Store of a halfword with AS writeback mode. | |
477 | ||
478 | .align 4 | |
479 | sth_as_writeback: | |
480 | sub sp,sp,12 | |
481 | st r13,[sp,8] | |
482 | sth.as r14,[sp,2] ; STH.AS, hence address is (offset << 1). | |
483 | st r15,[sp,0] | |
484 | add sp,sp,12 | |
485 | j [blink] | |
486 | ||
487 | ; Store of a double word with AS writeback mode. Shift is still 2, like ST! | |
488 | ||
489 | .align 4 | |
490 | std_as_writeback: | |
491 | sub sp,sp,16 | |
492 | st r13,[sp,12] | |
493 | #ifdef __ARC_LL64__ | |
494 | std.as r14,[sp,1] ; STD.AS, hence address is (offset << 2). | |
495 | #else | |
496 | st.as r14,[sp,1] ; STD.AS, hence address is (offset << 2). | |
497 | st.as r15,[sp,2] ; STD.AS, hence address is (offset << 2). | |
498 | #endif | |
499 | st r16,[sp,0] | |
500 | add sp,sp,12 | |
501 | j [blink] | |
502 | ||
503 | ; Store of the halfword. R14 will not be reported as "saved". | |
504 | ||
505 | .align 4 | |
506 | st_halfword: | |
507 | sub sp,sp,12 | |
508 | st r13,[sp,8] | |
509 | sth r14,[sp,4] | |
510 | st r15,[sp,0] | |
511 | add sp,sp,12 | |
512 | j [blink] | |
513 | ||
514 | ; Store of the halfword. R14 will not be reported as "saved". | |
515 | ||
516 | .align 4 | |
517 | sts_halfword: | |
518 | sub sp,sp,12 | |
519 | st r13,[sp,8] | |
520 | mov r13,sp | |
521 | sth_s r14,[r13,4] | |
522 | st r15,[sp,0] | |
523 | add sp,sp,12 | |
524 | j [blink] | |
525 | ||
526 | ; Store of the byte. R14 will not be reported as "saved". | |
527 | ||
528 | .align 4 | |
529 | st_byte: | |
530 | sub sp,sp,12 | |
531 | st r13,[sp,8] | |
532 | stb r14,[sp,4] | |
533 | st r15,[sp,0] | |
534 | add sp,sp,12 | |
535 | j [blink] | |
536 | ||
537 | ; Store of the byte. R14 will not be reported as "saved". | |
538 | ||
539 | .align 4 | |
540 | sts_byte: | |
541 | sub sp,sp,12 | |
542 | st r13,[sp,8] | |
543 | mov r13,sp | |
544 | stb_s r14,[r13,4] | |
545 | st r15,[sp,0] | |
546 | add sp,sp,12 | |
547 | j [blink] | |
548 | ||
549 | ; Store of the byte. R14 will not be reported as "saved". | |
550 | ||
551 | .align 4 | |
552 | sts_byte_sp: | |
553 | sub sp,sp,12 | |
554 | st r13,[sp,8] | |
555 | stb_s r14,[sp,4] | |
556 | st r15,[sp,0] | |
557 | add sp,sp,12 | |
558 | j [blink] | |
559 | ||
560 | ; Double word store, optionally available for ARC HS. | |
561 | ||
562 | .align 4 | |
563 | st_double: | |
564 | sub sp,sp,8 | |
565 | #ifdef __ARC_LL64__ | |
566 | std r14,[sp,0] | |
567 | std.aw r18,[sp,-8] | |
568 | std.aw 0xdeadbeef,[sp,-8] | |
569 | #else | |
570 | st r14,[sp,0] | |
571 | st r15,[sp,4] | |
572 | st.aw r19,[sp,-4] | |
573 | st.aw r18,[sp,-4] | |
574 | sub sp,sp,8 | |
575 | #endif | |
576 | add sp,sp,24 | |
577 | j [blink] | |
578 | ||
579 | ; Store relative to some register with a known value. | |
580 | ||
581 | .align 4 | |
582 | r_relative_store: | |
583 | sub_s sp,sp,12 | |
584 | st_s r13,[sp,8] | |
585 | mov r13,sp | |
586 | ; Check for both mov and mov_s in one testcase. | |
587 | mov_s r12,r13 | |
588 | st r15,[r12,0] | |
589 | st_s r14,[sp,4] | |
590 | add sp,sp,12 | |
591 | j [blink] | |
592 | ||
593 | ; Store relative to some register with a known value using sub. | |
594 | ; Like a previous test, but register is assigned via sub, instead of mov. | |
595 | ||
596 | .align 4 | |
597 | r_relative_sub_store: | |
598 | ; Following is a complicated way to construct frame like this: | |
599 | ; sub_s sp,sp,12 | |
600 | ; st_s r13,[sp,8] | |
601 | ; st_s r14,[sp,4] | |
602 | ; st_s r15,[sp,0] | |
603 | sub_s sp,sp,12 | |
604 | st_s r13,[sp,8] | |
605 | sub r13,sp,4 | |
606 | st r14,[r13,8] | |
607 | st_s r15,[sp,0] | |
608 | add sp,sp,12 | |
609 | j [blink] | |
610 | ||
611 | ; Like r_relative_store, but using st_s c,[b,u7] which has different opcode. | |
612 | ||
613 | .align 4 | |
614 | r_relative_store_st_s: | |
615 | sub_s sp,sp,12 | |
616 | st_s r13,[sp,8] | |
617 | mov r13,sp | |
618 | st_s r15,[r13,4] | |
619 | st_s r14,[sp,0] | |
620 | add sp,sp,12 | |
621 | j [blink] | |
622 | ||
623 | ; Store relative to some register with a unknown value. | |
624 | ||
625 | .align 4 | |
626 | r_relative_store_unknown: | |
627 | sub_s sp,sp,12 | |
628 | st_s r13,[sp,8] | |
629 | st r15,[gp,0] ; GP value is not relative to SP. | |
630 | st_s r14,[sp,4] | |
631 | add sp,sp,12 | |
632 | j [blink] | |
633 | ||
634 | ; Store relative to some register with a unknown value, using st_s r0,[gp,s11]. | |
635 | ||
636 | .align 4 | |
637 | st_s_r0gp: | |
638 | sub_s sp,sp,12 | |
639 | st_s r13,[sp,8] | |
640 | st_s r0,[gp,0] ; GP value is not relative to SP. | |
641 | st_s r14,[sp,4] | |
642 | add sp,sp,12 | |
643 | j [blink] | |
644 | ||
645 | ; Check prologue that uses `push_s RR` instructions. `push_s b` and `push_s | |
646 | ; blink` use slightly different subopcodes. | |
647 | ||
648 | .align 4 | |
649 | push_s_prologue: | |
650 | push_s r12 | |
651 | push_s r0 | |
652 | push_s r3 | |
653 | push_s r13 | |
654 | push_s r1 | |
655 | push_s r14 | |
656 | push_s r15 | |
657 | push_s r2 | |
658 | push_s blink ; Also tested in mini_prologue (). | |
659 | add sp,sp,(4 * 9) | |
660 | j [blink] | |
661 | ||
662 | ; Check for SUB_S c,b,u3 presence - it doesn't affect prologue. | |
663 | ||
664 | .align 4 | |
665 | sub_s_cbu3: | |
666 | push_s r13 | |
667 | sub_s r0,r1,3 | |
668 | push_s r14 | |
669 | add sp,sp,8 | |
670 | j [blink] | |
671 | ||
672 | ; Check for SUB_S b,b,c presence - it doesn't affect prologue. | |
673 | ||
674 | .align 4 | |
675 | sub_s_bbc: | |
676 | push_s r13 | |
677 | sub_s r0,r0,r1 | |
678 | push_s r0 | |
679 | push_s r1 | |
680 | push_s r14 | |
681 | add sp,sp,16 | |
682 | j [blink] | |
683 | ||
684 | ; Check for SUB_S b,b,u5. | |
685 | ||
686 | .align 4 | |
687 | sub_s_bbu5: | |
688 | push_s r13 | |
689 | sub_s r2,r2,14 | |
690 | push_s r2 | |
691 | push_s r14 | |
692 | add sp,sp,12 | |
693 | j [blink] | |
694 | ||
695 | ; Check for SUB 0,b,c, which is effectively a noop (but it can set status | |
696 | ; flags). It shouldn't stop prologue analysis. | |
697 | ||
698 | .align 4 | |
699 | sub_0bc: | |
700 | push_s r13 | |
701 | sub 0,r1,r2 | |
702 | sub.f 0,r3,r4 | |
703 | push_s r14 | |
704 | add sp,sp,8 | |
705 | j [blink] | |
706 | ||
707 | ; Check for SUB a,limm,c. | |
708 | ||
709 | .align 4 | |
710 | sub_alimmb: | |
711 | push_s r13 | |
712 | sub r13,0xdeadbeef,r14 | |
713 | push_s r14 | |
714 | add sp,sp,8 | |
715 | j [blink] | |
716 | ||
717 | ; Check for sub_s.ne b,b,b. Has a condition code, hence should halt prologue. | |
718 | ||
719 | .align 4 | |
720 | sub_s_ne_bbb: | |
721 | push_s r13 | |
722 | sub_s.ne r13,r13,r13 | |
723 | push_s r14 | |
724 | add sp,sp,8 | |
725 | j [blink] | |
726 | ||
727 | ; Check MOV that uses LIMM values. | |
728 | ||
729 | .align 4 | |
730 | mov_limm: | |
731 | push_s r13 | |
732 | mov r13,0xdeadbeef | |
733 | push_s r14 | |
734 | add sp,sp,4 | |
735 | pop_s r13 | |
736 | j [blink] | |
737 | ||
738 | ; Check MOV 0,c. | |
739 | ||
740 | .align 4 | |
741 | mov0c_limm: | |
742 | push_s r13 | |
743 | mov 0,r13 | |
744 | push_s r14 | |
745 | add sp,sp,4 | |
746 | pop_s r13 | |
747 | j [blink] | |
748 | ||
749 | ; Check that MOV_S h,s3 doesn't prevent prologue analysis. | |
750 | ||
751 | .align 4 | |
752 | mov_s_hs3: | |
753 | push_s r13 | |
754 | mov_s r5,1 | |
755 | push_s r14 | |
756 | add sp,sp,8 | |
757 | j [blink] | |
758 | ||
759 | ; Check that MOV_S b,u8 doesn't prevent prologue analysis. | |
760 | ||
761 | .align 4 | |
762 | mov_s_bu8: | |
763 | push_s r13 | |
764 | mov_s r12,250 | |
765 | push_s r14 | |
766 | add sp,sp,8 | |
767 | j [blink] | |
768 | ||
769 | ; Check that `mov_s.ne b,h` halts prologue analysis. | |
770 | ||
771 | .align 4 | |
772 | mov_s_ne_bh: | |
773 | push_s r13 | |
774 | mov_s.ne r13,r5 | |
775 | push_s r14 | |
776 | add sp,sp,8 | |
777 | j [blink] | |
778 | ||
779 | ; Check that register R12 which original value is not stored will not pop-up in | |
780 | ; the "Saved registers" list. | |
781 | ||
782 | .align 4 | |
783 | unstored_reg: | |
784 | sub_s sp,sp,12 | |
785 | st_s r13,[sp,0] | |
786 | st_s r14,[sp,4] | |
787 | mov r12,0x42 | |
788 | st_s r12,[sp,8] | |
789 | add sp,sp,12 | |
790 | j [blink] | |
791 | ||
792 | ; Two stores at the same adddress. GDB should report only the R14. | |
793 | ||
794 | .align 4 | |
795 | double_store: | |
796 | sub_s sp,sp,4 | |
797 | st_s r13,[sp,0] | |
798 | st_s r14,[sp,0] | |
799 | add sp,sp,4 | |
800 | j [blink] | |
801 | ||
802 | ; Test for a case where callee has an alloca or anything else that might | |
803 | ; modify stack dynamically in the function body - after the prologue. | |
804 | ; This assumes that FP is set properly, so that GDB can use it - this holds | |
805 | ; true for frames generated by GCC. | |
806 | ||
807 | .align 4 | |
808 | alloca_outer: | |
809 | sub sp,sp,8 | |
810 | st blink,[sp,4] | |
811 | st fp,[sp,0] | |
812 | mov fp,sp | |
813 | add r0,r1,r2 ; Not a prologue anymore. | |
814 | sub sp,sp,8 | |
815 | bl @alloca_inner | |
816 | add sp,sp,8 | |
817 | ld fp,[sp,0] | |
818 | ld blink,[sp,4] | |
819 | j.d [blink] | |
820 | add sp,sp,8 | |
821 | ||
822 | .align 4 | |
823 | alloca_inner: | |
824 | push r13 | |
825 | push r14 | |
826 | add sp,sp,8 | |
827 | j [blink] | |
828 | ||
829 | ||
830 | .align 4 | |
831 | main: | |
832 | push blink | |
833 | # Create small section for GP-relative accesses. | |
834 | push gp | |
835 | sub sp,sp,16 | |
836 | add gp,sp,8 | |
837 | bl @standard_prologue | |
838 | bl @mini_prologue | |
839 | bl @no_subsp_prologue | |
840 | bl @leaf_prologue | |
841 | bl @pushfp_prologue | |
842 | bl @fp_prologue_with_store | |
843 | bl @noncallee_saved_regs_r12_st | |
844 | bl @noncallee_saved_regs_r12_push | |
845 | bl @noncallee_saved_regs_r2_push | |
846 | bl @noncallee_saved_regs_gp_push | |
847 | bl @noncallee_saved_regs_lp_count | |
848 | bl @noncallee_saved_regs_blink_out_of_prologue | |
849 | bl @arg_regs_fp | |
850 | bl @arg_regs_fp_mov_s | |
851 | bl @arg_regs_sp | |
852 | bl @enter_s_nop | |
853 | bl @enter_s_blink | |
854 | bl @enter_s_fp | |
855 | bl @enter_s_r13 | |
856 | bl @enter_s_r15 | |
857 | bl @enter_s_all | |
858 | bl @nested_prologue_outer | |
859 | bl @max_length_prologue | |
860 | bl @branch_in_prologue | |
861 | bl @cond_branch_in_prologue | |
862 | bl @jump_in_prologue | |
863 | bl @cond_jump_in_prologue | |
864 | bl @predicated_insn | |
865 | bl @loop_in_prologue | |
866 | bl @store_constant | |
867 | bl @st_c_limm | |
868 | bl @st_ab_writeback | |
869 | bl @st_as_writeback | |
870 | bl @sth_as_writeback | |
871 | bl @std_as_writeback | |
872 | bl @st_halfword | |
873 | bl @sts_halfword | |
874 | bl @st_byte | |
875 | bl @sts_byte | |
876 | bl @sts_byte_sp | |
877 | bl @st_double | |
878 | bl @r_relative_store | |
879 | bl @r_relative_sub_store | |
880 | bl @r_relative_store_st_s | |
881 | bl @r_relative_store_unknown | |
882 | bl @st_s_r0gp | |
883 | bl @push_s_prologue | |
884 | bl @sub_s_cbu3 | |
885 | bl @sub_s_bbc | |
886 | bl @sub_s_bbu5 | |
887 | bl @sub_0bc | |
888 | bl @sub_alimmb | |
889 | bl @sub_s_ne_bbb | |
890 | bl @mov_limm | |
891 | bl @mov0c_limm | |
892 | bl @mov_s_hs3 | |
893 | bl @mov_s_bu8 | |
894 | bl @mov_s_ne_bh | |
895 | bl @unstored_reg | |
896 | bl @double_store | |
897 | bl @alloca_outer | |
898 | add sp,sp,16 | |
899 | pop gp | |
900 | pop blink | |
901 | j_s [blink] | |
902 | ||
903 | .align 4 |