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