support.S revision 219841
1/*- 2 * Copyright (c) 1998 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/ia64/ia64/support.S 219841 2011-03-21 18:20:53Z marcel $ 27 */ 28/*- 29 * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. 30 * All rights reserved. 31 * 32 * Author: Chris G. Demetriou 33 * 34 * Permission to use, copy, modify and distribute this software and 35 * its documentation is hereby granted, provided that both the copyright 36 * notice and this permission notice appear in all copies of the 37 * software, derivative works or modified versions, and any portions 38 * thereof, and that both notices appear in supporting documentation. 39 * 40 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 41 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 42 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 43 * 44 * Carnegie Mellon requests users of this software to return to 45 * 46 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 47 * School of Computer Science 48 * Carnegie Mellon University 49 * Pittsburgh PA 15213-3890 50 * 51 * any improvements or extensions that they make and grant Carnegie the 52 * rights to redistribute these changes. 53 */ 54 55#include <machine/asm.h> 56#include <machine/ia64_cpu.h> 57#include <assym.s> 58 59 .text 60 61ENTRY(fusufault, 0) 62{ .mib 63 st8.rel [r15]=r0 // Clear onfault. 64 add ret0=-1,r0 65 br.ret.sptk rp 66 ;; 67} 68END(fusufault) 69 70/* 71 * casuword(u_long *p, u_long old, u_long new) 72 * Perform a compare-exchange in user space. 73 */ 74ENTRY(casuword, 3) 75{ .mlx 76 add r15=PC_CURTHREAD,r13 77 movl r14=VM_MAXUSER_ADDRESS 78 ;; 79} 80{ .mib 81 ld8 r15=[r15] // r15 = curthread 82 cmp.geu p6,p0=in0,r14 83(p6) br.dpnt.few 1f 84 ;; 85} 86{ .mlx 87 add r15=TD_PCB,r15 88 movl r14=fusufault 89 ;; 90} 91{ .mmi 92 ld8 r15=[r15] // r15 = PCB 93 ;; 94 mov ar.ccv=in1 95 add r15=PCB_ONFAULT,r15 96 ;; 97} 98{ .mmi 99 st8 [r15]=r14 // Set onfault 100 ;; 101 cmpxchg8.rel ret0=[in0],in2,ar.ccv 102 nop 0 103 ;; 104} 105{ .mib 106 st8.rel [r15]=r0 // Clear onfault 107 nop 0 108 br.ret.sptk rp 109 ;; 110} 1111: 112{ .mib 113 add ret0=-1,r0 114 nop 0 115 br.ret.sptk rp 116 ;; 117} 118END(casuword) 119 120/* 121 * casuword32(uint32_t *p, uint32_t old, uint32_t new) 122 * Perform a 32-bit compare-exchange in user space. 123 */ 124ENTRY(casuword32, 3) 125{ .mlx 126 add r15=PC_CURTHREAD,r13 127 movl r14=VM_MAXUSER_ADDRESS 128 ;; 129} 130{ .mib 131 ld8 r15=[r15] // r15 = curthread 132 cmp.geu p6,p0=in0,r14 133(p6) br.dpnt.few 1f 134 ;; 135} 136{ .mlx 137 add r15=TD_PCB,r15 138 movl r14=fusufault 139 ;; 140} 141{ .mmi 142 ld8 r15=[r15] // r15 = PCB 143 ;; 144 mov ar.ccv=in1 145 add r15=PCB_ONFAULT,r15 146 ;; 147} 148{ .mmi 149 st8 [r15]=r14 // Set onfault 150 ;; 151 cmpxchg4.rel ret0=[in0],in2,ar.ccv 152 nop 0 153 ;; 154} 155{ .mib 156 st8.rel [r15]=r0 // Clear onfault 157 nop 0 158 br.ret.sptk rp 159 ;; 160} 1611: 162{ .mib 163 add ret0=-1,r0 164 nop 0 165 br.ret.sptk rp 166 ;; 167} 168END(casuword32) 169 170/* 171 * subyte(void *addr, int byte) 172 * suword16(void *addr, int word) 173 * suword32(void *addr, int word) 174 * suword64|suword(void *addr, long word) 175 * Store in user space 176 */ 177 178ENTRY(subyte, 2) 179{ .mlx 180 add r15=PC_CURTHREAD,r13 181 movl r14=VM_MAXUSER_ADDRESS 182 ;; 183} 184{ .mib 185 ld8 r15=[r15] // r15 = curthread 186 cmp.geu p6,p0=in0,r14 187(p6) br.dpnt.few 1f 188 ;; 189} 190{ .mlx 191 add r15=TD_PCB,r15 192 movl r14=fusufault 193 ;; 194} 195{ .mmi 196 ld8 r15=[r15] // r15 = PCB 197 ;; 198 nop 0 199 add r15=PCB_ONFAULT,r15 200 ;; 201} 202{ .mmi 203 st8 [r15]=r14 // Set onfault 204 ;; 205 st1.rel [in0]=in1 206 nop 0 207 ;; 208} 209{ .mib 210 st8.rel [r15]=r0 // Clear onfault 211 mov ret0=r0 212 br.ret.sptk rp 213 ;; 214} 2151: 216{ .mib 217 add ret0=-1,r0 218 nop 0 219 br.ret.sptk rp 220 ;; 221} 222END(subyte) 223 224ENTRY(suword16, 2) 225{ .mlx 226 add r15=PC_CURTHREAD,r13 227 movl r14=VM_MAXUSER_ADDRESS 228 ;; 229} 230{ .mib 231 ld8 r15=[r15] // r15 = curthread 232 cmp.geu p6,p0=in0,r14 233(p6) br.dpnt.few 1f 234 ;; 235} 236{ .mlx 237 add r15=TD_PCB,r15 238 movl r14=fusufault 239 ;; 240} 241{ .mmi 242 ld8 r15=[r15] // r15 = PCB 243 ;; 244 nop 0 245 add r15=PCB_ONFAULT,r15 246 ;; 247} 248{ .mmi 249 st8 [r15]=r14 // Set onfault 250 ;; 251 st2.rel [in0]=in1 252 nop 0 253 ;; 254} 255{ .mib 256 st8.rel [r15]=r0 // Clear onfault 257 mov ret0=r0 258 br.ret.sptk rp 259 ;; 260} 2611: 262{ .mib 263 add ret0=-1,r0 264 nop 0 265 br.ret.sptk rp 266 ;; 267} 268END(suword16) 269 270ENTRY(suword32, 2) 271{ .mlx 272 add r15=PC_CURTHREAD,r13 273 movl r14=VM_MAXUSER_ADDRESS 274 ;; 275} 276{ .mib 277 ld8 r15=[r15] // r15 = curthread 278 cmp.geu p6,p0=in0,r14 279(p6) br.dpnt.few 1f 280 ;; 281} 282{ .mlx 283 add r15=TD_PCB,r15 284 movl r14=fusufault 285 ;; 286} 287{ .mmi 288 ld8 r15=[r15] // r15 = PCB 289 ;; 290 nop 0 291 add r15=PCB_ONFAULT,r15 292 ;; 293} 294{ .mmi 295 st8 [r15]=r14 // Set onfault 296 ;; 297 st4.rel [in0]=in1 298 nop 0 299 ;; 300} 301{ .mib 302 st8.rel [r15]=r0 // Clear onfault 303 mov ret0=r0 304 br.ret.sptk rp 305 ;; 306} 3071: 308{ .mib 309 add ret0=-1,r0 310 nop 0 311 br.ret.sptk rp 312 ;; 313} 314END(suword32) 315 316ENTRY(suword64, 2) 317XENTRY(suword) 318{ .mlx 319 add r15=PC_CURTHREAD,r13 320 movl r14=VM_MAXUSER_ADDRESS 321 ;; 322} 323{ .mib 324 ld8 r15=[r15] // r15 = curthread 325 cmp.geu p6,p0=in0,r14 326(p6) br.dpnt.few 1f 327 ;; 328} 329{ .mlx 330 add r15=TD_PCB,r15 331 movl r14=fusufault 332 ;; 333} 334{ .mmi 335 ld8 r15=[r15] // r15 = PCB 336 ;; 337 nop 0 338 add r15=PCB_ONFAULT,r15 339 ;; 340} 341{ .mmi 342 st8 [r15]=r14 // Set onfault 343 ;; 344 st8.rel [in0]=in1 345 nop 0 346 ;; 347} 348{ .mib 349 st8.rel [r15]=r0 // Clear onfault 350 mov ret0=r0 351 br.ret.sptk rp 352 ;; 353} 3541: 355{ .mib 356 add ret0=-1,r0 357 nop 0 358 br.ret.sptk rp 359 ;; 360} 361END(suword64) 362 363/* 364 * fubyte(void *addr, int byte) 365 * fuword16(void *addr, int word) 366 * fuword32(void *addr, int word) 367 * fuword64|fuword(void *addr, long word) 368 * Fetch from user space 369 */ 370 371ENTRY(fubyte, 1) 372{ .mlx 373 add r15=PC_CURTHREAD,r13 374 movl r14=VM_MAXUSER_ADDRESS 375 ;; 376} 377{ .mib 378 ld8 r15=[r15] // r15 = curthread 379 cmp.geu p6,p0=in0,r14 380(p6) br.dpnt.few 1f 381 ;; 382} 383{ .mlx 384 add r15=TD_PCB,r15 385 movl r14=fusufault 386 ;; 387} 388{ .mmi 389 ld8 r15=[r15] // r15 = PCB 390 ;; 391 nop 0 392 add r15=PCB_ONFAULT,r15 393 ;; 394} 395{ .mmi 396 st8 [r15]=r14 // Set onfault 397 ;; 398 mf 399 nop 0 400 ;; 401} 402{ .mmb 403 ld1 ret0=[in0] 404 st8.rel [r15]=r0 // Clear onfault 405 br.ret.sptk rp 406 ;; 407} 4081: 409{ .mib 410 add ret0=-1,r0 411 nop 0 412 br.ret.sptk rp 413 ;; 414} 415END(fubyte) 416 417ENTRY(fuword16, 2) 418{ .mlx 419 add r15=PC_CURTHREAD,r13 420 movl r14=VM_MAXUSER_ADDRESS 421 ;; 422} 423{ .mib 424 ld8 r15=[r15] // r15 = curthread 425 cmp.geu p6,p0=in0,r14 426(p6) br.dpnt.few 1f 427 ;; 428} 429{ .mlx 430 add r15=TD_PCB,r15 431 movl r14=fusufault 432 ;; 433} 434{ .mmi 435 ld8 r15=[r15] // r15 = PCB 436 ;; 437 nop 0 438 add r15=PCB_ONFAULT,r15 439 ;; 440} 441{ .mmi 442 st8 [r15]=r14 // Set onfault 443 ;; 444 mf 445 nop 0 446 ;; 447} 448{ .mmb 449 ld2 ret0=[in0] 450 st8.rel [r15]=r0 // Clear onfault 451 br.ret.sptk rp 452 ;; 453} 4541: 455{ .mib 456 add ret0=-1,r0 457 nop 0 458 br.ret.sptk rp 459 ;; 460} 461END(fuword16) 462 463ENTRY(fuword32, 2) 464{ .mlx 465 add r15=PC_CURTHREAD,r13 466 movl r14=VM_MAXUSER_ADDRESS 467 ;; 468} 469{ .mib 470 ld8 r15=[r15] // r15 = curthread 471 cmp.geu p6,p0=in0,r14 472(p6) br.dpnt.few 1f 473 ;; 474} 475{ .mlx 476 add r15=TD_PCB,r15 477 movl r14=fusufault 478 ;; 479} 480{ .mmi 481 ld8 r15=[r15] // r15 = PCB 482 ;; 483 nop 0 484 add r15=PCB_ONFAULT,r15 485 ;; 486} 487{ .mmi 488 st8 [r15]=r14 // Set onfault 489 ;; 490 mf 491 nop 0 492 ;; 493} 494{ .mmb 495 ld4 ret0=[in0] 496 st8.rel [r15]=r0 // Clear onfault 497 br.ret.sptk rp 498 ;; 499} 5001: 501{ .mib 502 add ret0=-1,r0 503 nop 0 504 br.ret.sptk rp 505 ;; 506} 507END(fuword32) 508 509ENTRY(fuword64, 2) 510XENTRY(fuword) 511{ .mlx 512 add r15=PC_CURTHREAD,r13 513 movl r14=VM_MAXUSER_ADDRESS 514 ;; 515} 516{ .mib 517 ld8 r15=[r15] // r15 = curthread 518 cmp.geu p6,p0=in0,r14 519(p6) br.dpnt.few 1f 520 ;; 521} 522{ .mlx 523 add r15=TD_PCB,r15 524 movl r14=fusufault 525 ;; 526} 527{ .mmi 528 ld8 r15=[r15] // r15 = PCB 529 ;; 530 nop 0 531 add r15=PCB_ONFAULT,r15 532 ;; 533} 534{ .mmi 535 st8 [r15]=r14 // Set onfault 536 ;; 537 mf 538 nop 0 539 ;; 540} 541{ .mmb 542 ld8 ret0=[in0] 543 st8.rel [r15]=r0 // Clear onfault 544 br.ret.sptk rp 545 ;; 546} 5471: 548{ .mib 549 add ret0=-1,r0 550 nop 0 551 br.ret.sptk rp 552 ;; 553} 554END(fuword64) 555 556/* 557 * fuswintr(void *addr) 558 * suswintr(void *addr) 559 */ 560 561ENTRY(fuswintr, 1) 562{ .mib 563 add ret0=-1,r0 564 nop 0 565 br.ret.sptk rp 566 ;; 567} 568END(fuswintr) 569 570ENTRY(suswintr, 0) 571{ .mib 572 add ret0=-1,r0 573 nop 0 574 br.ret.sptk rp 575 ;; 576} 577END(suswintr) 578 579/**************************************************************************/ 580 581/* 582 * Copy a null-terminated string within the kernel's address space. 583 * If lenp is not NULL, store the number of chars copied in *lenp 584 * 585 * int copystr(char *from, char *to, size_t len, size_t *lenp); 586 */ 587ENTRY(copystr, 4) 588 mov r14=in2 // r14 = i = len 589 cmp.eq p6,p0=r0,in2 590(p6) br.cond.spnt.few 2f // if (len == 0), bail out 591 5921: ld1 r15=[in0],1 // read one byte 593 ;; 594 st1 [in1]=r15,1 // write that byte 595 add in2=-1,in2 // len-- 596 ;; 597 cmp.eq p6,p0=r0,r15 598 cmp.ne p7,p0=r0,in2 599 ;; 600(p6) br.cond.spnt.few 2f // if (*from == 0), bail out 601(p7) br.cond.sptk.few 1b // if (len != 0) copy more 602 6032: cmp.eq p6,p0=r0,in3 604(p6) br.cond.dpnt.few 3f // if (lenp != NULL) 605 sub r14=r14,in2 // *lenp = (i - len) 606 ;; 607 st8 [in3]=r14 608 6093: cmp.eq p6,p0=r0,r15 610(p6) br.cond.spnt.few 4f // *from == '\0'; leave quietly 611 612 mov ret0=ENAMETOOLONG // *from != '\0'; error. 613 br.ret.sptk.few rp 614 6154: mov ret0=0 // return 0. 616 br.ret.sptk.few rp 617END(copystr) 618 619ENTRY(copyinstr, 4) 620 .prologue 621 .regstk 4, 3, 4, 0 622 .save ar.pfs,loc0 623 alloc loc0=ar.pfs,4,3,4,0 624 .save rp,loc1 625 mov loc1=rp 626 .body 627 628 movl loc2=VM_MAXUSER_ADDRESS // make sure that src addr 629 ;; 630 cmp.geu p6,p0=in0,loc2 // is in user space. 631 ;; 632(p6) br.cond.spnt.few copyerr // if it's not, error out. 633 movl r14=copyerr // set up fault handler. 634 add r15=PC_CURTHREAD,r13 // find curthread 635 ;; 636 ld8 r15=[r15] 637 ;; 638 add r15=TD_PCB,r15 // find pcb 639 ;; 640 ld8 r15=[r15] 641 ;; 642 add loc2=PCB_ONFAULT,r15 643 ;; 644 st8 [loc2]=r14 645 ;; 646 mov out0=in0 647 mov out1=in1 648 mov out2=in2 649 mov out3=in3 650 ;; 651 br.call.sptk.few rp=copystr // do the copy. 652 st8 [loc2]=r0 // kill the fault handler. 653 mov ar.pfs=loc0 // restore ar.pfs 654 mov rp=loc1 // restore ra. 655 br.ret.sptk.few rp // ret0 left over from copystr 656END(copyinstr) 657 658/* 659 * Not the fastest bcopy in the world. 660 */ 661ENTRY(bcopy, 3) 662 mov ret0=r0 // return zero for copy{in,out} 663 ;; 664 cmp.le p6,p0=in2,r0 // bail if len <= 0 665(p6) br.ret.spnt.few rp 666 667 sub r14=in1,in0 ;; // check for overlap 668 cmp.ltu p6,p0=r14,in2 // dst-src < len 669(p6) br.cond.spnt.few 5f 670 671 extr.u r14=in0,0,3 // src & 7 672 extr.u r15=in1,0,3 ;; // dst & 7 673 cmp.eq p6,p0=r14,r15 // different alignment? 674(p6) br.cond.spnt.few 2f // branch if same alignment 675 6761: ld1 r14=[in0],1 ;; // copy bytewise 677 st1 [in1]=r14,1 678 add in2=-1,in2 ;; // len-- 679 cmp.ne p6,p0=r0,in2 680(p6) br.cond.dptk.few 1b // loop 681 br.ret.sptk.few rp // done 682 6832: cmp.eq p6,p0=r14,r0 // aligned? 684(p6) br.cond.sptk.few 4f 685 6863: ld1 r14=[in0],1 ;; // copy bytewise 687 st1 [in1]=r14,1 688 extr.u r15=in0,0,3 // src & 7 689 add in2=-1,in2 ;; // len-- 690 cmp.eq p6,p0=r0,in2 // done? 691 cmp.eq p7,p0=r0,r15 ;; // aligned now? 692(p6) br.ret.spnt.few rp // return if done 693(p7) br.cond.spnt.few 4f // go to main copy 694 br.cond.sptk.few 3b // more bytes to copy 695 696 // At this point, in2 is non-zero 697 6984: mov r14=8 ;; 699 cmp.ltu p6,p0=in2,r14 ;; // len < 8? 700(p6) br.cond.spnt.few 1b // byte copy the end 701 ld8 r15=[in0],8 ;; // copy word 702 st8 [in1]=r15,8 703 add in2=-8,in2 ;; // len -= 8 704 cmp.ne p6,p0=r0,in2 // done? 705(p6) br.cond.spnt.few 4b // again 706 707 br.ret.sptk.few rp // return 708 709 // Don't bother optimising overlap case 710 7115: add in0=in0,in2 712 add in1=in1,in2 ;; 713 add in0=-1,in0 714 add in1=-1,in1 ;; 715 7166: ld1 r14=[in0],-1 ;; 717 st1 [in1]=r14,-1 718 add in2=-1,in2 ;; 719 cmp.ne p6,p0=r0,in2 720(p6) br.cond.spnt.few 6b 721 722 br.ret.sptk.few rp 723END(bcopy) 724 725ENTRY(memcpy,3) 726 mov r14=in0 ;; 727 mov in0=in1 ;; 728 mov in1=r14 729 br.cond.sptk.few bcopy 730END(memcpy) 731 732ENTRY(copyin, 3) 733 .prologue 734 .regstk 3, 3, 3, 0 735 .save ar.pfs,loc0 736 alloc loc0=ar.pfs,3,3,3,0 737 .save rp,loc1 738 mov loc1=rp 739 .body 740 741 movl loc2=VM_MAXUSER_ADDRESS // make sure that src addr 742 ;; 743 cmp.geu p6,p0=in0,loc2 // is in user space. 744 ;; 745(p6) br.cond.spnt.few copyerr // if it's not, error out. 746 movl r14=copyerr // set up fault handler. 747 add r15=PC_CURTHREAD,r13 // find curthread 748 ;; 749 ld8 r15=[r15] 750 ;; 751 add r15=TD_PCB,r15 // find pcb 752 ;; 753 ld8 r15=[r15] 754 ;; 755 add loc2=PCB_ONFAULT,r15 756 ;; 757 st8 [loc2]=r14 758 ;; 759 mov out0=in0 760 mov out1=in1 761 mov out2=in2 762 ;; 763 br.call.sptk.few rp=bcopy // do the copy. 764 st8 [loc2]=r0 // kill the fault handler. 765 mov ar.pfs=loc0 // restore ar.pfs 766 mov rp=loc1 // restore ra. 767 br.ret.sptk.few rp // ret0 left over from bcopy 768END(copyin) 769 770ENTRY(copyout, 3) 771 .prologue 772 .regstk 3, 3, 3, 0 773 .save ar.pfs,loc0 774 alloc loc0=ar.pfs,3,3,3,0 775 .save rp,loc1 776 mov loc1=rp 777 .body 778 779 movl loc2=VM_MAXUSER_ADDRESS // make sure that dest addr 780 ;; 781 cmp.geu p6,p0=in1,loc2 // is in user space. 782 ;; 783(p6) br.cond.spnt.few copyerr // if it's not, error out. 784 movl r14=copyerr // set up fault handler. 785 add r15=PC_CURTHREAD,r13 // find curthread 786 ;; 787 ld8 r15=[r15] 788 ;; 789 add r15=TD_PCB,r15 // find pcb 790 ;; 791 ld8 r15=[r15] 792 ;; 793 add loc2=PCB_ONFAULT,r15 794 ;; 795 st8 [loc2]=r14 796 ;; 797 mov out0=in0 798 mov out1=in1 799 mov out2=in2 800 ;; 801 br.call.sptk.few rp=bcopy // do the copy. 802 st8 [loc2]=r0 // kill the fault handler. 803 mov ar.pfs=loc0 // restore ar.pfs 804 mov rp=loc1 // restore ra. 805 br.ret.sptk.few rp // ret0 left over from bcopy 806END(copyout) 807 808ENTRY(copyerr, 0) 809 add r14=PC_CURTHREAD,r13 ;; // find curthread 810 ld8 r14=[r14] ;; 811 add r14=TD_PCB,r14 ;; // curthread->td_addr 812 ld8 r14=[r14] ;; 813 add r14=PCB_ONFAULT,r14 ;; // &curthread->td_pcb->pcb_onfault 814 st8 [r14]=r0 // reset fault handler 815 816 mov ret0=EFAULT // return EFAULT 817 br.ret.sptk.few rp 818END(copyerr) 819 820#if defined(GPROF) 821/* 822 * Important registers: 823 * r8 structure return address 824 * rp our return address 825 * in0 caller's ar.pfs 826 * in1 caller's gp 827 * in2 caller's rp 828 * in3 GOT entry 829 * ar.pfs our pfs 830 */ 831ENTRY_NOPROFILE(_mcount, 4) 832 alloc loc0 = ar.pfs, 4, 3, 2, 0 833 mov loc1 = r8 834 mov loc2 = rp 835 ;; 836 mov out0 = in2 837 mov out1 = rp 838 br.call.sptk rp = __mcount 839 ;; 8401: 841 mov gp = in1 842 mov r14 = ip 843 mov b7 = loc2 844 ;; 845 add r14 = 2f - 1b, r14 846 mov ar.pfs = loc0 847 mov rp = in2 848 ;; 849 mov b7 = r14 850 mov b6 = loc2 851 mov r8 = loc1 852 mov r14 = in0 853 br.ret.sptk b7 854 ;; 8552: 856 mov ar.pfs = r14 857 br.sptk b6 858 ;; 859END(_mcount) 860#endif 861