|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.0 (the 'License'). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License." ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: #ifdef KERNEL ! 25: #define OBJC_LOCK_ROUTINE _simple_lock ! 26: #else ! 27: ; _objc_entryPoints and _objc_exitPoints are used by moninitobjc() to setup ! 28: ; objective-C messages for profiling. The are made private_externs when in ! 29: ; a shared library. ! 30: .reference _moninitobjc ! 31: .const ! 32: .globl _objc_entryPoints ! 33: _objc_entryPoints: ! 34: .long _objc_msgSend ! 35: .long _objc_msgSendSuper ! 36: .long _objc_msgSendv ! 37: .long 0 ! 38: ! 39: .globl _objc_exitPoints ! 40: _objc_exitPoints: ! 41: .long Lexit1 ! 42: .long Lexit2 ! 43: .long Lexit3 ! 44: .long Lexit4 ! 45: .long Lexit5 ! 46: .long Lexit6 ! 47: .long Lexit7 ! 48: .long Lexit8 ! 49: .long 0 ! 50: ! 51: #define OBJC_LOCK_ROUTINE _spin_lock ! 52: #endif /* KERNEL */ ! 53: ! 54: #define isa 0 ! 55: #define cache 32 ! 56: #define mask 0 ! 57: #define buckets 8 ! 58: #define method_name 0 ! 59: #define method_imp 8 ! 60: ! 61: ! 62: ; optimized for hppa: 20? clocks (best case) + 6 clocks / probe ! 63: ! 64: .text ! 65: .align 4 ! 66: .globl _objc_msgSend ! 67: ! 68: _objc_msgSend: ! 69: ldil L`__objc_multithread_mask,%r1 ! 70: ldw R`__objc_multithread_mask(%r1),%r19 ! 71: and,= %r19,%r26,%r19 ! 72: b,n L0 ; if (self & multi) goto normalcase ! 73: comiclr,= 0,%r26,0 ! 74: b,n SendLocking ; else if (self) goto lockingcase ! 75: nop ! 76: bv 0(%r2) ; else return null ! 77: copy 0,%r28 ; <delay slot> return val = 0 ! 78: L0: ! 79: ldw isa(0,%r26),%r19 ; class = self->isa; ! 80: ldw cache(0,%r19),%r20 ; cache = class->cache ! 81: ldw mask(0,%r20),%r21 ; mask = cache->mask ! 82: ldo buckets(%r20),%r20 ; buckets = cache->buckets ! 83: and %r21,%r25,%r22 ; index = selector & mask; ! 84: L1: ! 85: ldwx,s %r22(0,%r20),%r19 ; method = cache->buckets[index]; ! 86: comib,=,n 0,%r19,cacheMiss ; if (method == NULL) ! 87: ldw method_name(0,%r19),%r1 ; ! 88: addi 1,%r22,%r22 ; ++index ! 89: comb,<> %r1, %r25, L1 ; if (name!=sel) continue loop ! 90: and %r21,%r22,%r22 ; <delay slot> index &=mask ! 91: ldw method_imp(0,%r19),%r19 ! 92: Lexit1: ! 93: bv,n 0(%r19) ; goto *imp; (nullify delay) ! 94: ! 95: #ifdef MONINIT ! 96: .space 128 ; /* area for moninitobjc to write */ ! 97: #endif ! 98: ! 99: cacheMiss: ! 100: ; We have to save all the register based arguments (including floating ! 101: ; point) before calling _class_lookupMethodAndLoadCache. This is because ! 102: ; we do not know what arguments were passed to us, and the arguments are ! 103: ; not guaranteed to be saved across procedure calls (they are all caller-saved) ! 104: ; We also have to save the return address (since we did not save it on entry). ! 105: ! 106: ! 107: copy %r30,%r19 ! 108: ldo 128(%r30),%r30 ; Allocate space on stack ! 109: stwm %r2,4(0,%r19) ; Save return pointer ! 110: stwm %r23,4(0,%r19) ; Save old args ! 111: stwm %r24,4(0,%r19) ; ! 112: stwm %r25,4(0,%r19) ; ! 113: stwm %r26,4(0,%r19) ; ! 114: #ifndef KERNEL ! 115: fstds,mb %fr4,4(0,%r19) ; Save floating point args ! 116: fstds,mb %fr5,8(0,%r19) ; mb (modify before) is used instead ! 117: fstds,mb %fr6,8(0,%r19) ; of ma (as is implicit in above ! 118: fstds,mb %fr7,8(0,%r19) ; stores) with an initial value of 4 ! 119: ; so that doubles are aligned ! 120: ; to 8 byte boundaries. ! 121: ; Arg 1 (selector) is the same ! 122: #endif /* KERNEL */ ! 123: ! 124: stw %r28,8(0,%r19) ; save return struct ptr ! 125: jbsr __class_lookupMethodAndLoadCache,%r2,0f ! 126: ldw isa(0,%r26),%r26 ; <delay slot> arg 0 = self->isa ! 127: ! 128: ldo -128(%r30),%r30 ; deallocate ! 129: copy %r30,%r19 ; ! 130: ldwm 4(0,%r19),%r2 ; restore everything ! 131: ldwm 4(0,%r19),%r23 ; ! 132: ldwm 4(0,%r19),%r24 ; ! 133: ldwm 4(0,%r19),%r25 ; ! 134: ldwm 4(0,%r19),%r26 ; ! 135: #ifndef KERNEL ! 136: fldds,mb 4(0,%r19),%fr4 ; see comment above about alignment ! 137: fldds,mb 8(0,%r19),%fr5 ; ! 138: fldds,mb 8(0,%r19),%fr6 ; ! 139: fldds,mb 8(0,%r19),%fr7 ; ! 140: #endif /* KERNEL */ ! 141: ldw 8(0,%r19),%r20 ; get ret structure ptr ! 142: ! 143: copy %r28,%r19 ! 144: copy %r20,%r28 ; restore ret structure ptr ! 145: Lexit2: ! 146: bv,n 0(%r19) ; goto *imp (nullify delay) ! 147: ! 148: ; stub for far call ! 149: ! 150: 0: ldil L`__class_lookupMethodAndLoadCache,%r1 ! 151: ble,n R`__class_lookupMethodAndLoadCache(4,%r1) ! 152: ! 153: #ifdef MONINIT ! 154: .space 128 ; /* area for moninitobjc to write */ ! 155: #endif ! 156: ! 157: ! 158: ! 159: ; Locking version of objc_msgSend ! 160: ; uses spin_lock() to lock the mutex. ! 161: ! 162: SendLocking: ! 163: copy %r30,%r19 ! 164: ldo 128(%r30),%r30 ; Allocate space on stack ! 165: stwm %r2,4(0,%r19) ; Save return pointer ! 166: stwm %r23,4(0,%r19) ; Save old args ! 167: stwm %r24,4(0,%r19) ; ! 168: stwm %r25,4(0,%r19) ; ! 169: stwm %r26,4(0,%r19) ; ! 170: stwm %r28,4(0,%r19) ; save return struct ptr ! 171: #ifndef KERNEL ! 172: fstds,ma %fr4,8(0,%r19) ; Save floating point args ! 173: fstds,ma %fr5,8(0,%r19) ; ! 174: fstds,ma %fr6,8(0,%r19) ; ! 175: fstds,ma %fr7,8(0,%r19) ; ! 176: #endif /* KERNEL */ ! 177: ! 178: ldil L`_messageLock,%r1 ! 179: ldo R`_messageLock(%r1),%r26 ! 180: ldil L`OBJC_LOCK_ROUTINE,%r1 ; call spin_lock() with _messageLock ! 181: ble R`OBJC_LOCK_ROUTINE(%sr4,%r1) ! 182: copy %r31,%r2 ! 183: ldw -112(%r30),%r26 ; restore arg0 ! 184: ldw -108(%r30),%r28 ; and ret0 (spin_lock doesnt ! 185: ; touch anything else important) ! 186: ldw isa(0,%r26),%r19 ; class = self->isa; ! 187: ldw cache(0,%r19),%r20 ; cache = class->cache ! 188: ldw mask(0,%r20),%r21 ; mask = cache->mask ! 189: ldo buckets(%r20),%r20 ; buckets = cache->buckets ! 190: and %r21,%r25,%r22 ; index = selector & mask; ! 191: LL1: ! 192: ldwx,s %r22(0,%r20),%r19 ; method = cache->buckets[index]; ! 193: comib,=,n 0,%r19,LL2 ; if (method == NULL) ! 194: ldw method_name(0,%r19),%r1 ; ! 195: addi 1,%r22,%r22 ; ++index ! 196: comb,<> %r1, %r25, LL1 ; if (name!=sel) continue loop ! 197: and %r21,%r22,%r22 ; <delay slot> index &=mask ! 198: ldw method_imp(0,%r19),%r19 ! 199: #if KERNEL ! 200: ldil L`_messageLock,%r1 ! 201: ldo R`_messageLock(%r1),%r20 ! 202: addi 0xc,%r20,%r20 ! 203: depi 0,31,4,%r20 ! 204: zdepi 1,31,1,%r1 ! 205: stw %r1,0(0,%r20) ! 206: #else ! 207: ldil L`_messageLock,%r1 ! 208: stw %r0,R`_messageLock(%r1) ; unlock the lock ! 209: #endif ! 210: ldwm -128(%r30),%r2 ; restore original rp and deallocate ! 211: Lexit3: ! 212: bv,n 0(%r19) ; goto *imp; (nullify delay) ! 213: ! 214: #ifdef MONINIT ! 215: .space 128 ; /* area for moninitobjc to write */ ! 216: #endif ! 217: ! 218: LL2: ! 219: jbsr __class_lookupMethodAndLoadCache,%r2,0f ! 220: ldw isa(0,%r26),%r26 ; <delay slot> arg 0 = self->isa ! 221: ! 222: ldo -128(%r30),%r30 ; deallocate ! 223: copy %r30,%r19 ; ! 224: ldwm 4(0,%r19),%r2 ; restore everything ! 225: ldwm 4(0,%r19),%r23 ; ! 226: ldwm 4(0,%r19),%r24 ; ! 227: ldwm 4(0,%r19),%r25 ; ! 228: ldwm 4(0,%r19),%r26 ; ! 229: ldwm 4(0,%r19),%r20 ; get ret structure ptr ! 230: #ifndef KERNEL ! 231: fldds,ma 8(0,%r19),%fr4 ; ! 232: fldds,ma 8(0,%r19),%fr5 ; ! 233: fldds,ma 8(0,%r19),%fr6 ; ! 234: fldds,ma 8(0,%r19),%fr7 ; ! 235: #endif /* KERNEL */ ! 236: ! 237: copy %r28,%r19 ! 238: copy %r20,%r28 ; restore ret structure ptr ! 239: #if KERNEL ! 240: ldil L`_messageLock,%r1 ! 241: ldo R`_messageLock(%r1),%r20 ! 242: addi 0xc,%r20,%r20 ! 243: depi 0,31,4,%r20 ! 244: zdepi 1,31,1,%r1 ! 245: stw %r1,0(0,%r20) ! 246: #else ! 247: ldil L`_messageLock,%r1 ! 248: stw %r0,R`_messageLock(%r1) ; unlock the lock ! 249: #endif ! 250: Lexit4: ! 251: bv,n 0(%r19) ; goto *imp (nullify delay) ! 252: ! 253: ; stub for far call ! 254: ! 255: 0: ldil L`__class_lookupMethodAndLoadCache,%r1 ! 256: ble,n R`__class_lookupMethodAndLoadCache(4,%r1) ! 257: ! 258: #ifdef MONINIT ! 259: .space 128 ; /* area for moninitobjc to write */ ! 260: #endif ! 261: ! 262: ! 263: ! 264: ! 265: ! 266: #define receiver 0 ! 267: #define class 4 ! 268: ! 269: .globl _objc_msgSendSuper ! 270: _objc_msgSendSuper: ! 271: ldil L`__objc_multithread_mask,%r1 ! 272: ldw R`__objc_multithread_mask(%r1),%r19 ! 273: combt,= %r0,%r19,SuperLocking ; ! 274: ldw class(0,%r26),%r19 ; class = caller->class; ! 275: ldw cache(0,%r19),%r20 ; cache = class->cache ! 276: ldw mask(0,%r20),%r21 ; mask = cache->mask ! 277: ldo buckets(%r20),%r20 ; buckets = cache->buckets ! 278: and %r21,%r25,%r22 ; index = selector & mask; ! 279: LS1: ; ! 280: ldwx,s %r22(0,%r20),%r19 ; method = cache->buckets[index]; ! 281: comib,=,n 0,%r19,LS2 ; if (method == NULL) ! 282: ldw method_name(0,%r19),%r1; ! 283: addi 1,%r22,%r22 ; ++index ! 284: comb,<> %r1, %r25, LS1 ; if (name!=sel) continue loop ! 285: and %r21,%r22,%r22 ; <delay slot> index &=mask ! 286: ldw method_imp(0,%r19),%r19 ! 287: ldw receiver(0,%r26),%r26 ; self = caller->receiver; ! 288: Lexit5: ! 289: bv,n 0(%r19) ; goto *imp; (nullify delay) ! 290: #ifdef MONINIT ! 291: .space 128 ; /* area for moninitobjc to write */ ! 292: #endif ! 293: ! 294: ; ! 295: LS2: ; ! 296: copy %r30,%r19 ! 297: ldo 128(%r30),%r30 ; Allocate space on stack ! 298: stwm %r2,4(0,%r19) ; Save return pointer ! 299: stwm %r23,4(0,%r19) ; Save old args ! 300: stwm %r24,4(0,%r19) ; ! 301: stwm %r25,4(0,%r19) ; ! 302: stwm %r26,4(0,%r19) ; ! 303: #ifndef KERNEL ! 304: fstds,mb %fr4,4(0,%r19) ; Save floating point args ! 305: fstds,mb %fr5,8(0,%r19) ; mb (modify before) is used instead ! 306: fstds,mb %fr6,8(0,%r19) ; of ma (as is implicit in above ! 307: fstds,mb %fr7,8(0,%r19) ; stores) with an initial value of 4 ! 308: ; so that doubles are aligned ! 309: ; to 8 byte boundaries. ! 310: ; Arg 1 (selector) is the same ! 311: #endif /* KERNEL */ ! 312: stw %r28,8(0,%r19) ; save return struct ptr ! 313: jbsr __class_lookupMethodAndLoadCache,%r2,0f ! 314: ldw class(0,%r26),%r26 ; <delay slot> arg 0 = caller->class; ! 315: ldo -128(%r30),%r30 ; deallocate ! 316: copy %r30,%r19 ; ! 317: ldwm 4(0,%r19),%r2 ; restore everything ! 318: ldwm 4(0,%r19),%r23 ; ! 319: ldwm 4(0,%r19),%r24 ; ! 320: ldwm 4(0,%r19),%r25 ; ! 321: ldwm 4(0,%r19),%r26 ; ! 322: #ifndef KERNEL ! 323: fldds,mb 4(0,%r19),%fr4 ; see comment above about alignment ! 324: fldds,mb 8(0,%r19),%fr5 ; ! 325: fldds,mb 8(0,%r19),%fr6 ; ! 326: fldds,mb 8(0,%r19),%fr7 ; ! 327: #endif /* KERNEL */ ! 328: ldw 8(0,%r19),%r20 ; get ret structure ptr ! 329: ldw receiver(0,%r26),%r26 ; self = caller->receiver; ! 330: copy %r28,%r19 ! 331: copy %r20,%r28 ! 332: Lexit6: bv,n 0(%r19) ; goto *imp (nullify delay) ! 333: ! 334: ; stub for far call ! 335: ! 336: 0: ldil L`__class_lookupMethodAndLoadCache,%r1 ! 337: ble,n R`__class_lookupMethodAndLoadCache(4,%r1) ! 338: ! 339: #ifdef MONINIT ! 340: .space 128 ; /* area for moninitobjc to write */ ! 341: #endif ! 342: ! 343: ! 344: ! 345: ! 346: ! 347: ; locking version of objc_msgSendSuper ! 348: ; uses spin_lock() to lock the lock. ! 349: ! 350: ! 351: SuperLocking: ! 352: copy %r30,%r19 ! 353: ldo 128(%r30),%r30 ; Allocate space on stack ! 354: stwm %r2,4(0,%r19) ; Save return pointer ! 355: stwm %r23,4(0,%r19) ; Save old args ! 356: stwm %r24,4(0,%r19) ; ! 357: stwm %r25,4(0,%r19) ; ! 358: stwm %r26,4(0,%r19) ; ! 359: stwm %r28,4(0,%r19) ; save return struct ptr ! 360: #ifndef KERNEL ! 361: fstds,ma %fr4,8(0,%r19) ; Save floating point args ! 362: fstds,ma %fr5,8(0,%r19) ; ! 363: fstds,ma %fr6,8(0,%r19) ; ! 364: fstds,ma %fr7,8(0,%r19) ; ! 365: #endif /* KERNEL */ ! 366: ldil L`_messageLock,%r1 ! 367: ldo R`_messageLock(%r1),%r26 ! 368: ldil L`OBJC_LOCK_ROUTINE,%r1 ; call spin_lock() with _messageLock ! 369: ble R`OBJC_LOCK_ROUTINE(%sr4,%r1) ! 370: copy %r31,%r2 ! 371: ldw -112(%r30),%r26 ; restore arg0 ! 372: ldw -108(%r30),%r28 ; and ret0 (spin_lock doesnt ! 373: ; touch anything else) ! 374: ldw class(0,%r26),%r19 ; class = caller->class; ! 375: ldw cache(0,%r19),%r20 ; cache = class->cache ! 376: ldw mask(0,%r20),%r21 ; mask = cache->mask ! 377: ldo buckets(%r20),%r20 ; buckets = cache->buckets ! 378: and %r21,%r25,%r22 ; index = selector & mask; ! 379: LLS1: ; ! 380: ldwx,s %r22(0,%r20),%r19 ; method = cache->buckets[index]; ! 381: comib,=,n 0,%r19,LLS2 ; if (method == NULL) ! 382: ldw method_name(0,%r19),%r1; ! 383: addi 1,%r22,%r22 ; ++index ! 384: comb,<> %r1, %r25, LLS1 ; if (name!=sel) continue loop ! 385: and %r21,%r22,%r22 ; <delay slot> index &=mask ! 386: ldw method_imp(0,%r19),%r19 ! 387: ldw receiver(0,%r26),%r26 ; self = caller->receiver; ! 388: #if KERNEL ! 389: ldil L`_messageLock,%r1 ! 390: ldo R`_messageLock(%r1),%r20 ! 391: addi 0xc,%r20,%r20 ! 392: depi 0,31,4,%r20 ! 393: zdepi 1,31,1,%r1 ! 394: stw %r1,0(0,%r20) ! 395: #else ! 396: ldil L`_messageLock,%r1 ! 397: stw %r0,R`_messageLock(%r1) ; unlock the lock ! 398: #endif ! 399: ldwm -128(%r30),%r2 ; restore original rp and deallocate ! 400: Lexit7: ! 401: bv,n 0(%r19) ; goto *imp; (nullify delay) ! 402: #ifdef MONINIT ! 403: .space 128 ; /* area for moninitobjc to write */ ! 404: #endif ! 405: ! 406: ; ! 407: LLS2: ; ! 408: jbsr __class_lookupMethodAndLoadCache,%r2,0f ! 409: ldw class(0,%r26),%r26 ; <delay slot> arg 0 = caller->class; ! 410: ldo -128(%r30),%r30 ; deallocate ! 411: copy %r30,%r19 ; ! 412: ldwm 4(0,%r19),%r2 ; restore everything ! 413: ldwm 4(0,%r19),%r23 ; ! 414: ldwm 4(0,%r19),%r24 ; ! 415: ldwm 4(0,%r19),%r25 ; ! 416: ldwm 4(0,%r19),%r26 ; ! 417: ldwm 4(0,%r19),%r20 ; get ret structure ptr ! 418: #ifndef KERNEL ! 419: fldds,ma 8(0,%r19),%fr4 ; ! 420: fldds,ma 8(0,%r19),%fr5 ; ! 421: fldds,ma 8(0,%r19),%fr6 ; ! 422: fldds,ma 8(0,%r19),%fr7 ; ! 423: #endif /* KERNEL */ ! 424: ldw receiver(0,%r26),%r26 ; self = caller->receiver; ! 425: copy %r28,%r19 ! 426: copy %r20,%r28 ! 427: #if KERNEL ! 428: ldil L`_messageLock,%r1 ! 429: ldo R`_messageLock(%r1),%r20 ! 430: addi 0xc,%r20,%r20 ! 431: depi 0,31,4,%r20 ! 432: zdepi 1,31,1,%r1 ! 433: stw %r1,0(0,%r20) ! 434: #else ! 435: ldil L`_messageLock,%r1 ! 436: stw %r0,R`_messageLock(%r1) ; unlock the lock ! 437: #endif ! 438: Lexit8: bv,n 0(%r19) ; goto *imp (nullify delay) ! 439: ! 440: ; stub for far call ! 441: ! 442: 0: ldil L`__class_lookupMethodAndLoadCache,%r1 ! 443: ble,n R`__class_lookupMethodAndLoadCache(4,%r1) ! 444: ! 445: ! 446: #ifdef MONINIT ! 447: .space 128 ; /* area for moninitobjc to write */ ! 448: #endif ! 449: ! 450: ! 451: ! 452: ! 453: .objc_meth_var_names ! 454: .align 1 ! 455: L30: .ascii "forward::\0" ! 456: ! 457: .objc_message_refs ! 458: .align 2 ! 459: L31: .long L30 ! 460: ! 461: .cstring ! 462: .align 1 ! 463: L32: .ascii "Does not recognize selector %s\0" ! 464: ! 465: .text ! 466: .align 1 ! 467: ; ! 468: ; NOTE: Because the stack grows from low mem to high mem on this machine ! 469: ; and the args go the other way, the marg_list pointer is to the first argument ! 470: ; and subsequent arguments are at NEGATIVE offsets from the marg_list. ! 471: ; This means that marg_getValue() and related macros will have to be adjusted ! 472: ; appropriately. ! 473: ; ! 474: .globl __objc_msgForward ! 475: __objc_msgForward: ! 476: stw %r2,-20(0,%r30) ; save rp ! 477: ldo 64(%r30),%r30 ; create frame area (no locals needed) ! 478: ldil L`L31,%r1 ! 479: ldo R`L31(%r1),%r19 ! 480: ldw 0(0,%r19),%r19 ! 481: combt,=,n %r19, %r25,L34 ; if (sel==@selector(forward::)) ! 482: ldo -112(%r30),%r20 ; ptr to arg3 homing area ! 483: stwm %r23,4(0,%r20) ; Mirror registers onto stack ! 484: stwm %r24,4(0,%r20) ; ! 485: stwm %r25,4(0,%r20) ; ! 486: stwm %r26,4(0,%r20) ; ! 487: ! 488: copy %r25,%r24 ! 489: copy %r19,%r25 ; [self forward:sel :marg_list] ! 490: ! 491: bl _objc_msgSend,%r2 ! 492: copy %r20,%r23 ; <delay slot> copy original sel ! 493: ! 494: ldo -64(%r30),%r30 ; deallocate ! 495: ldw -20(0,%r30),%r2 ; restore rp ! 496: bv,n 0(%r2) ; return ! 497: L34: ! 498: ldil L`L32,%r1 ! 499: ldo R`L32(%r1),%r25 ! 500: ldil L`__objc_error,%r1 ! 501: be R`__objc_error(%sr4,%r1) ; __objc_error never returns, so no ! 502: copy %r19,%r24 ; need to clean up. ! 503: ! 504: ! 505: ; Algorithm is as follows: ! 506: ; . Calculate how much stack size is needed for any arguments not in the ! 507: ; general registers and allocate space on stack. ! 508: ; . Restore general argument regs from the bottom of the marg_list. ! 509: ; . Restore fp argument regs from the same area. ! 510: ; (The first two args in the marg list are always old obj and old SEL.) ! 511: ; . Call the new method. ! 512: .globl _objc_msgSendv ! 513: _objc_msgSendv: ! 514: ; objc_msgSendv(self, sel, size, margs) ! 515: stw %r2,-20(0,%r30) ; Save rp ! 516: stw %r4,-36(0,%r30) ; Save callee-saved r4 ! 517: copy %r30,%r4 ; Save old sp vale ! 518: ldo 95(%r24),%r19 ; Calculate frame size, rounded ! 519: depi 0,31,6,%r19 ; up to 64 byte boundary... ! 520: ! 521: add %r19,%r30,%r30 ; Allocate frame area (no locals) ! 522: copy %r24,%r20 ; r20 now holds arg size ! 523: ldo -16(%r23),%r21 ; r21 now holds marg_list+16 ! 524: ldws 0(0,%r21),%r23 ; Get old general register args (dont ! 525: ldws 4(0,%r21),%r24 ; need first two: always self & SEL) ! 526: #ifndef KERNEL ! 527: fldds 0(0,%r21),%fr7 ; Mirror to fp regs ! 528: fldws 4(0,%r21),%fr6 ; ! 529: #endif /* KERNEL */ ! 530: ! 531: ldo -52(%r30),%r22 ; newly allocated stack area. ! 532: ldo -8(%r20),%r20 ; Size -= 8 ! 533: comibf,<,n 0,%r20,L36 ! 534: L35: ldws,mb -4(0,%r21),%r19 ; while(size>0) ! 535: addibf,<= -4,%r20,L35 ; { *(dest--) = *(src--); size-=4; } ! 536: stws,ma %r19,-4(0,%r22) ; <delay slot> ! 537: L36: bl _objc_msgSend,%r2 ! 538: nop ! 539: copy %r4,%r30 ; deallocate ! 540: ldw -36(0,%r30), %r4 ! 541: ldw -20(0,%r30), %r2 ! 542: bv,n 0(%r2) ! 543: ! 544:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.