|
|
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: /* ! 25: * Copyright 1988-1996 NeXT Software, Inc. ! 26: * ! 27: * objc-msg-ppc.s ! 28: * ! 29: * 1-May-97 Umesh Vaishampayan ([email protected]) ! 30: * Incorporated locking code fixes from David Harrison ([email protected]) ! 31: * ! 32: * 2-Apr-97 Umesh Vaishampayan ([email protected]) ! 33: * Incarporated changes for messanger with struct return ! 34: * Cleaned up the labels to use local labels ! 35: * Fixed bug in the msgSendSuper that did not do the locking. ! 36: * ! 37: * 31-Dec-96 Umesh Vaishampayan ([email protected]) ! 38: * Created from m98k. ! 39: * ! 40: */ ! 41: ! 42: #define STACK_ALIGN_MASK 0xfff0 ! 43: ! 44: #ifndef KERNEL ! 45: ; _objc_entryPoints and _objc_exitPoints are used by moninitobjc() to setup ! 46: ; objective-C messages for profiling. The are made private_externs when in ! 47: ; a shared library. ! 48: .reference _moninitobjc ! 49: .const ! 50: .align 2 ! 51: .globl _objc_entryPoints ! 52: _objc_entryPoints: ! 53: .long _objc_msgSend ! 54: .long _objc_msgSendSuper ! 55: .long _objc_msgSendv ! 56: .long _objc_msgSend_stret ! 57: .long _objc_msgSendSuper_stret ! 58: .long 0 ! 59: ! 60: .globl _objc_exitPoints ! 61: _objc_exitPoints: ! 62: .long Lexit1 ! 63: .long Lexit2 ! 64: .long Lexit3 ! 65: .long Lexit4 ! 66: .long Lexit5 ! 67: .long Lexit6 ! 68: .long Lexit7 ! 69: .long Lexit8 ! 70: .long LRexit1 ! 71: .long LRexit2 ! 72: .long LRexit3 ! 73: .long LRexit4 ! 74: .long LRexit5 ! 75: .long LRexit6 ! 76: .long LRexit7 ! 77: .long LRexit8 ! 78: .long 0 ! 79: #endif /* ! KERNEL */ ! 80: ! 81: isa = 0 ! 82: cache = 32 ! 83: mask = 0 ! 84: buckets = 8 ! 85: method_name = 0 ! 86: method_imp = 8 ! 87: ! 88: .text ! 89: .align 2 ! 90: .globl _objc_msgSend ! 91: _objc_msgSend: ! 92: stw r7, 40(r1) ; save r7 through r10 for use as temps ! 93: stw r8, 44(r1) ! 94: stw r9, 48(r1) ! 95: stw r10,52(r1) ! 96: ! 97: addis r7,0,hi16(__objc_multithread_mask) ! 98: ori r7,r7,lo16(__objc_multithread_mask) ! 99: lwz r7,0(r7) ! 100: and. r7,r3,r7 ! 101: bne cr0,L0 ; branch to the "normal" case, ! 102: ; no locking, id != nil ! 103: ! 104: cmplwi cr0,r3,0 ; if id == nil ! 105: bne cr0,LL0 ; LL0 is the "locking" case ! 106: b L3 ; L3 is the return nil case ! 107: L0: ! 108: lwz r10,isa(r3) ; class = self->isa; ! 109: lwz r10,cache(r10) ; cache = class->cache ! 110: lwz r11,mask(r10) ; mask = cache->mask ! 111: addi r9,r10,buckets ; buckets = cache->buckets ! 112: and r10,r4,r11 ; index = selector & mask; ! 113: L1: ! 114: slwi r0,r10,2 ; ! 115: lwzx r7,r9,r0 ; method = cache->buckets[index]; ! 116: cmplwi cr0,r7,0 ; if (method == NULL) ! 117: beq cr0,L2 ; ! 118: addi r10,r10,1 ; index++; ! 119: lwz r8,method_name(r7) ; name = method->method_name; ! 120: and r10,r10,r11 ; index &= mask ! 121: lwz r7,method_imp(r7) ; imp = method->method_imp; ! 122: cmpw r4,r8 ; if (name != selector) ! 123: bne cr0,L1 ; goto loop; ! 124: mtspr ctr,r7 ; ! 125: lwz r7, 40(r1) ; restore r7 through r10 ! 126: lwz r8, 44(r1) ! 127: lwz r9, 48(r1) ; ! 128: lwz r10,52(r1) ; ! 129: Lexit1: ! 130: bctr ; goto *imp; ! 131: .space 112 ; /* area for moninitobjc to write */ ! 132: L2: ; ! 133: lwz r10,isa(r3) ; class = self->isa; ! 134: ! 135: stw r3, 24(r1) ; save the other register parameters ! 136: stw r4, 28(r1) ; ! 137: stw r5, 32(r1) ; ! 138: stw r6, 36(r1) ; ! 139: ! 140: mflr r0 ; save LR ! 141: stw r0,8(r1) ; ! 142: stwu r1,-64(r1) ; grow the stack ! 143: ! 144: ori r3,r10,0 ; first arg is the isa pointer ! 145: bl __class_lookupMethodAndLoadCache ! 146: mtspr ctr,r3 ! 147: lwz r1,0(r1) ; restore the stack pointer ! 148: ! 149: lwz r0,8(r1) ; ! 150: mtlr r0 ; restore return pc ! 151: lwz r3, 24(r1) ; ! 152: lwz r4, 28(r1) ; ! 153: lwz r5, 32(r1) ; ! 154: lwz r6, 36(r1) ; ! 155: lwz r7, 40(r1) ; ! 156: lwz r8, 44(r1) ; ! 157: lwz r9, 48(r1) ; ! 158: lwz r10,52(r1) ; ! 159: Lexit2: ! 160: bctr ; goto *imp; ! 161: .space 112 ; /* area for moninitobjc to write */ ! 162: L3: ; ! 163: addi r3,0,0 ; (return value is nil) ! 164: blr ; (return) ! 165: ! 166: LL0: ! 167: stw r6, 36(r1) ; save r6 ! 168: addis r6,0,hi16(_messageLock) ! 169: ori r6,r6,lo16(_messageLock) ! 170: ! 171: Lgetit: ! 172: lwarx r0,0,r6 ; try to get the lock ! 173: cmpwi cr0,r0,0 ! 174: bne- Lgetit ! 175: addi r0,0,1 ! 176: sync ; Bugfix for 3.2 and older cpus ! 177: stwcx. r0,0,r6 ! 178: bne- Lgetit ! 179: isync ! 180: ! 181: lwz r10,isa(r3) ; class = self->isa; ! 182: lwz r10,cache(r10) ; cache = class->cache ! 183: lwz r11,mask(r10) ; mask = cache->mask ! 184: addi r9,r10,buckets ; buckets = cache->buckets ! 185: and r10,r4,r11 ; index = selector & mask; ! 186: LL1: ! 187: slwi r0,r10,2 ; ! 188: lwzx r7,r9,r0 ; method = cache->buckets[index]; ! 189: cmplwi cr0,r7,0 ; if (method == NULL) ! 190: beq cr0,LL2 ; ! 191: addi r10,r10,1 ; index++; ! 192: lwz r8,method_name(r7) ; name = method->method_name; ! 193: and r10,r10,r11 ; index &= mask ! 194: lwz r7,method_imp(r7) ; imp = method->method_imp; ! 195: cmpw r4,r8 ; if (name != selector) ! 196: bne cr0,LL1 ; goto loop; ! 197: mtspr ctr,r7 ; ! 198: lwz r7, 40(r1) ; restore r7 through r10 ! 199: lwz r8, 44(r1) ! 200: lwz r9, 48(r1) ; ! 201: lwz r10,52(r1) ; ! 202: ! 203: sync ; release the lock ! 204: addi r0,0,0 ! 205: stw r0,0(r6) ! 206: lwz r6,36(r1); ; restore r6 ! 207: ! 208: Lexit3: ! 209: bctr ; goto *imp; ! 210: .space 112 ; /* area for moninitobjc to write */ ! 211: LL2: ; ! 212: lwz r10,isa(r3) ; class = self->isa; ! 213: ! 214: stw r3, 24(r1) ; save the other register parameters ! 215: stw r4, 28(r1) ; ! 216: stw r5, 32(r1) ; ! 217: ! 218: mflr r0 ; move LR to r0 ! 219: stw r0,8(r1) ; save LR ! 220: stwu r1,-64(r1) ; grow the stack ! 221: ! 222: ori r3,r10,0 ; first arg is the isa pointer ! 223: bl __class_lookupMethodAndLoadCache ! 224: mtspr ctr,r3 ! 225: lwz r1,0(r1) ; restore the stack pointer ! 226: ! 227: lwz r0,8(r1) ; ! 228: mtlr r0 ; restore return pc ! 229: lwz r3, 24(r1) ; ! 230: lwz r4, 28(r1) ; ! 231: lwz r5, 32(r1) ; ! 232: ! 233: sync ; release the lock ! 234: addis r6,0,hi16(_messageLock) ! 235: ori r6,r6,lo16(_messageLock) ! 236: addi r0,0,0 ! 237: stw r0,0(r6) ! 238: ! 239: lwz r6, 36(r1) ; ! 240: lwz r7, 40(r1) ; ! 241: lwz r8, 44(r1) ; ! 242: lwz r9, 48(r1) ; ! 243: lwz r10,52(r1) ; ! 244: Lexit4: ! 245: bctr ; goto *imp; ! 246: .space 112 ; /* area for moninitobjc to write */ ! 247: ! 248: ! 249: receiver = 0 ! 250: class = 4 ! 251: ! 252: .text ! 253: .align 2 ! 254: .globl _objc_msgSendSuper ! 255: _objc_msgSendSuper: ! 256: stw r7, 40(r1) ; save r7 through r10 for use as temps ! 257: stw r8, 44(r1) ! 258: stw r9, 48(r1) ! 259: stw r10,52(r1) ! 260: ! 261: addis r7,0,hi16(__objc_multithread_mask) ! 262: ori r7,r7,lo16(__objc_multithread_mask) ! 263: lwz r7,0(r7) ! 264: cmplwi cr0,r7,0 ! 265: beq cr0,LSL0 ; branch to the "locking" case, ! 266: ; normal case, id != nil ! 267: lwz r10,class(r3) ; class = super->class; ! 268: lwz r10,cache(r10) ; cache = class->cache ! 269: lwz r11,mask(r10) ; mask = cache->mask ! 270: addi r9,r10,buckets ; buckets = cache->buckets ! 271: and r10,r4,r11 ; index = selector & mask; ! 272: LS1: ; ! 273: slwi r0,r10,2 ! 274: lwzx r7,r9,r0 ; method = cache->buckets[index]; ! 275: cmplwi cr0,r7,0 ; if (method == NULL) ! 276: beq cr0,LS2 ; ! 277: addi r10,r10,1 ; index++; ! 278: lwz r8,method_name(r7) ; name = method->method_name; ! 279: and r10,r10,r11 ; index &= mask ! 280: lwz r7,method_imp(r7) ; imp = method->method_imp; ! 281: cmpw r4,r8 ; if (name != selector) ! 282: bne cr0,LS1 ; goto loop; ! 283: mtspr ctr,r7 ; ! 284: lwz r7, 40(r1) ; restore r7 through r10 ! 285: lwz r8, 44(r1) ! 286: lwz r9, 48(r1) ; ! 287: lwz r10,52(r1) ; ! 288: lwz r3,receiver(r3) ; restore the receiver ! 289: Lexit5: bctr ; goto *imp; ! 290: .space 112 ; /* area for moninitobjc to write */ ! 291: LS2: ; ! 292: lwz r10,class(r3) ; class = self->class; ! 293: lwz r3,receiver(r3) ; restore the receiver ! 294: ! 295: stw r3, 24(r1) ; save the other register parameters ! 296: stw r4, 28(r1) ; ! 297: stw r5, 32(r1) ; ! 298: stw r6, 36(r1) ; ! 299: ! 300: mflr r0 ; save LR ! 301: stw r0,8(r1) ; ! 302: stwu r1,-64(r1) ; grow the stack ! 303: ! 304: ori r3,r10,0 ; first arg is the isa pointer ! 305: bl __class_lookupMethodAndLoadCache ! 306: mtspr ctr,r3 ! 307: lwz r1,0(r1) ; restore the stack pointer ! 308: ! 309: lwz r0,8(r1) ; ! 310: mtlr r0 ; restore return pc ! 311: lwz r3, 24(r1) ; ! 312: lwz r4, 28(r1) ; ! 313: lwz r5, 32(r1) ; ! 314: lwz r6, 36(r1) ; ! 315: lwz r7, 40(r1) ; ! 316: lwz r8, 44(r1) ; ! 317: lwz r9, 48(r1) ; ! 318: lwz r10,52(r1) ; ! 319: Lexit6: ! 320: bctr ; goto *imp; ! 321: .space 112 ; /* area for moninitobjc to write */ ! 322: ! 323: LSL0: ; Locking case for _objc_msgSendSuper ! 324: stw r6,36(r1) ; save r6 ! 325: addis r6,0,hi16(_messageLock) ! 326: ori r6,r6,lo16(_messageLock) ! 327: ! 328: LSgetit: ! 329: lwarx r0,0,r6 ; try to get the lock ! 330: cmpwi cr0,r0,0 ! 331: bne- LSgetit ! 332: addi r0,0,1 ! 333: sync ; Bugfix for 3.2 and older cpus ! 334: stwcx. r0,0,r6 ! 335: bne- LSgetit ! 336: isync ! 337: ! 338: lwz r10,class(r3) ; class = super->class; ! 339: lwz r10,cache(r10) ; cache = class->cache ! 340: lwz r11,mask(r10) ; mask = cache->mask ! 341: addi r9,r10,buckets ; buckets = cache->buckets ! 342: and r10,r4,r11 ; index = selector & mask; ! 343: LSL1: ; ! 344: slwi r0,r10,2 ! 345: lwzx r7,r9,r0 ; method = cache->buckets[index]; ! 346: cmplwi cr0,r7,0 ; if (method == NULL) ! 347: beq cr0,LSL2 ; ! 348: addi r10,r10,1 ; index++; ! 349: lwz r8,method_name(r7) ; name = method->method_name; ! 350: and r10,r10,r11 ; index &= mask ! 351: lwz r7,method_imp(r7) ; imp = method->method_imp; ! 352: cmpw r4,r8 ; if (name != selector) ! 353: bne cr0,LSL1 ; goto loop; ! 354: mtspr ctr,r7 ; ! 355: lwz r7, 40(r1) ; restore r7 through r10 ! 356: lwz r8, 44(r1) ; ! 357: lwz r9, 48(r1) ; ! 358: lwz r10,52(r1) ; ! 359: ! 360: sync ; release the lock ! 361: addi r0,0,0 ! 362: stw r0,0(r6) ! 363: lwz r6,36(r1); ; restore r6 ! 364: lwz r3,receiver(r3) ; r3 = self ! 365: ! 366: Lexit7: ! 367: bctr ; goto *imp; ! 368: .space 112 ; /* area for moninitobjc to write */ ! 369: LSL2: ; ! 370: lwz r10,class(r3) ; class = self->class; ! 371: lwz r3,receiver(r3) ; r3 = self for implementation ! 372: ! 373: stw r3, 24(r1) ; save the other register parameters ! 374: stw r4, 28(r1) ; ! 375: stw r5, 32(r1) ; ! 376: ! 377: mflr r0 ; save LR ! 378: stw r0,8(r1) ; ! 379: stwu r1,-64(r1) ; grow the stack ! 380: ! 381: ori r3,r10,0 ; first arg is the isa pointer ! 382: bl __class_lookupMethodAndLoadCache ! 383: mtspr ctr,r3 ! 384: lwz r1,0(r1) ; restore the stack pointer ! 385: ! 386: lwz r0,8(r1) ; ! 387: mtlr r0 ; restore return pc ! 388: lwz r3, 24(r1) ; ! 389: lwz r4, 28(r1) ; ! 390: lwz r5, 32(r1) ; ! 391: ! 392: sync ; release the lock ! 393: addis r6,0,hi16(_messageLock) ! 394: ori r6,r6,lo16(_messageLock) ! 395: addi r0,0,0 ! 396: stw r0,0(r6) ! 397: ! 398: lwz r6, 36(r1) ; ! 399: lwz r7, 40(r1) ; ! 400: lwz r8, 44(r1) ; ! 401: lwz r9, 48(r1) ; ! 402: lwz r10,52(r1) ; ! 403: Lexit8: ! 404: bctr ; goto *imp; ! 405: .space 112 ; /* area for moninitobjc to write */ ! 406: ! 407: ! 408: ;-------------------------------------------------------------------- ! 409: ; ! 410: ; _objc_msgSend_stret is the [Apple/Rhapsody] PowerPC struct-return ! 411: ; version. The ABI calls for r3 to be used as the address of ! 412: ; the structure being returned; and the other args are in the ! 413: ; next couple of registers. ! 414: ; ! 415: ; This is a pasted copy of _objc_msgSend above, mutatis mutandis. ! 416: ; ! 417: ; ! 418: ; On entry: r3 is the address in which the returned struct is put, ! 419: ; r4 is the message receiver, ! 420: ; r5 is the selector ! 421: ; ! 422: .text ! 423: .align 2 ! 424: .globl _objc_msgSend_stret ! 425: _objc_msgSend_stret: ! 426: stw r7, 40(r1) ; save r7 through r10 for use as temps ! 427: stw r8, 44(r1) ! 428: stw r9, 48(r1) ! 429: stw r10,52(r1) ! 430: ! 431: addis r7,0,hi16(__objc_multithread_mask) ! 432: ori r7,r7,lo16(__objc_multithread_mask) ! 433: lwz r7,0(r7) ! 434: and. r7,r4,r7 ! 435: bne cr0,LR0 ; branch to the "normal" case, ! 436: ; no locking, id != nil ! 437: ! 438: cmplwi cr0,r4,0 ; if id == nil ! 439: bne cr0,LRL0 ; LRL0 is the "locking" case ! 440: b LR3 ; LR3 is the return nil case ! 441: LR0: ! 442: lwz r10,isa(r4) ; class = self->isa; ! 443: lwz r10,cache(r10) ; cache = class->cache ! 444: lwz r11,mask(r10) ; mask = cache->mask ! 445: addi r9,r10,buckets ; buckets = cache->buckets ! 446: and r10,r5,r11 ; index = selector & mask; ! 447: LR1: ! 448: slwi r0,r10,2 ; ! 449: lwzx r7,r9,r0 ; method = cache->buckets[index]; ! 450: cmplwi cr0,r7,0 ; if (method == NULL) ! 451: beq cr0,LR2 ; ! 452: addi r10,r10,1 ; index++; ! 453: lwz r8,method_name(r7) ; name = method->method_name; ! 454: and r10,r10,r11 ; index &= mask ! 455: lwz r7,method_imp(r7) ; imp = method->method_imp; ! 456: cmpw r5,r8 ; if (name != selector) ! 457: bne cr0,LR1 ; goto loop; ! 458: mtspr ctr,r7 ; ! 459: lwz r7, 40(r1) ; restore r7 through r10 ! 460: lwz r8, 44(r1) ! 461: lwz r9, 48(r1) ; ! 462: lwz r10,52(r1) ; ! 463: LRexit1: ! 464: bctr ; goto *imp; ! 465: .space 112 ; /* area for moninitobjc to write */ ! 466: LR2: ; ! 467: lwz r10,isa(r4) ; class = self->isa; ! 468: ! 469: stw r3, 24(r1) ; save the other register parameters ! 470: stw r4, 28(r1) ; ! 471: stw r5, 32(r1) ; ! 472: stw r6, 36(r1) ; ! 473: ! 474: mflr r0 ; save LR ! 475: stw r0,8(r1) ; ! 476: stwu r1,-64(r1) ; grow the stack ! 477: ! 478: ori r3,r10,0 ; first arg is the isa pointer ! 479: ori r4,r5,0 ; second arg is the selector ! 480: bl __class_lookupMethodAndLoadCache ! 481: mtspr ctr,r3 ! 482: lwz r1,0(r1) ; restore the stack pointer ! 483: ! 484: lwz r0,8(r1) ; ! 485: mtlr r0 ; restore return pc ! 486: lwz r3, 24(r1) ; ! 487: lwz r4, 28(r1) ; ! 488: lwz r5, 32(r1) ; ! 489: lwz r6, 36(r1) ; ! 490: lwz r7, 40(r1) ; ! 491: lwz r8, 44(r1) ; ! 492: lwz r9, 48(r1) ; ! 493: lwz r10,52(r1) ; ! 494: LRexit2: ! 495: bctr ; goto *imp; ! 496: .space 112 ; /* area for moninitobjc to write */ ! 497: LR3: ; ! 498: addi r3,0,0 ; (return value is nil) ! 499: blr ; (return) ! 500: ! 501: LRL0: ! 502: stw r6, 36(r1) ; save r6 ! 503: addis r6,0,hi16(_messageLock) ! 504: ori r6,r6,lo16(_messageLock) ! 505: ! 506: LRgetit: ! 507: lwarx r0,0,r6 ; try to get the lock ! 508: cmpwi cr0,r0,0 ! 509: bne- LRgetit ! 510: addi r0,0,1 ! 511: sync ; Bugfix for 3.2 and older cpus ! 512: stwcx. r0,0,r6 ! 513: bne- LRgetit ! 514: isync ! 515: ! 516: lwz r10,isa(r4) ; class = self->isa; ! 517: lwz r10,cache(r10) ; cache = class->cache ! 518: lwz r11,mask(r10) ; mask = cache->mask ! 519: addi r9,r10,buckets ; buckets = cache->buckets ! 520: and r10,r5,r11 ; index = selector & mask; ! 521: LRL1: ! 522: slwi r0,r10,2 ; ! 523: lwzx r7,r9,r0 ; method = cache->buckets[index]; ! 524: cmplwi cr0,r7,0 ; if (method == NULL) ! 525: beq cr0,LRL2 ; ! 526: addi r10,r10,1 ; index++; ! 527: lwz r8,method_name(r7) ; name = method->method_name; ! 528: and r10,r10,r11 ; index &= mask ! 529: lwz r7,method_imp(r7) ; imp = method->method_imp; ! 530: cmpw r5,r8 ; if (name != selector) ! 531: bne cr0,LRL1 ; goto loop; ! 532: mtspr ctr,r7 ; ! 533: lwz r7, 40(r1) ; restore r7 through r10 ! 534: lwz r8, 44(r1) ! 535: lwz r9, 48(r1) ; ! 536: lwz r10,52(r1) ; ! 537: ! 538: sync ; release the lock ! 539: addi r0,0,0 ! 540: stw r0,0(r6) ! 541: lwz r6,36(r1); ; restore r6 ! 542: ! 543: LRexit3: ! 544: bctr ; goto *imp; ! 545: .space 112 ; /* area for moninitobjc to write */ ! 546: LRL2: ; ! 547: lwz r10,isa(r4) ; class = self->isa; ! 548: ! 549: stw r3, 24(r1) ; save the other register parameters ! 550: stw r4, 28(r1) ; ! 551: stw r5, 32(r1) ; ! 552: ! 553: mflr r0 ; save LR ! 554: stw r0,8(r1) ; ! 555: stwu r1,-64(r1) ; grow the stack ! 556: ! 557: ori r3,r10,0 ; first arg is the isa pointer ! 558: ori r4,r5,0 ; second arg is the selector ! 559: bl __class_lookupMethodAndLoadCache ! 560: mtspr ctr,r3 ! 561: lwz r1,0(r1) ; restore the stack pointer ! 562: ! 563: lwz r0,8(r1) ; ! 564: mtlr r0 ; restore return pc ! 565: lwz r3, 24(r1) ; ! 566: lwz r4, 28(r1) ; ! 567: lwz r5, 32(r1) ; ! 568: ! 569: sync ; release the lock ! 570: addis r6,0,hi16(_messageLock) ! 571: ori r6,r6,lo16(_messageLock) ! 572: addi r0,0,0 ! 573: stw r0,0(r6) ! 574: ! 575: lwz r6, 36(r1) ; ! 576: lwz r7, 40(r1) ; ! 577: lwz r8, 44(r1) ; ! 578: lwz r9, 48(r1) ; ! 579: lwz r10,52(r1) ; ! 580: LRexit4: ! 581: bctr ; goto *imp; ! 582: .space 112 ; /* area for moninitobjc to write */ ! 583: ! 584: ! 585: .text ! 586: .align 2 ! 587: .globl _objc_msgSendSuper_stret ! 588: _objc_msgSendSuper_stret: ! 589: stw r7, 40(r1) ; save r7 through r10 for use as temps ! 590: stw r8, 44(r1) ! 591: stw r9, 48(r1) ! 592: stw r10,52(r1) ! 593: ! 594: addis r7,0,hi16(__objc_multithread_mask) ! 595: ori r7,r7,lo16(__objc_multithread_mask) ! 596: lwz r7,0(r7) ! 597: cmplwi cr0,r7,0 ! 598: beq cr0,LRSL0 ; branch to the "locking" case ! 599: ; "normal" case, no locking, id != nil ! 600: lwz r10,class(r4) ; class = super->class; ! 601: lwz r10,cache(r10) ; cache = class->cache ! 602: lwz r11,mask(r10) ; mask = cache->mask ! 603: addi r9,r10,buckets ; buckets = cache->buckets ! 604: and r10,r5,r11 ; index = selector & mask; ! 605: LRS1: ; ! 606: slwi r0,r10,2 ! 607: lwzx r7,r9,r0 ; method = cache->buckets[index]; ! 608: cmplwi cr0,r7,0 ; if (method == NULL) ! 609: beq cr0,LRS2 ; ! 610: addi r10,r10,1 ; index++; ! 611: lwz r8,method_name(r7) ; name = method->method_name; ! 612: and r10,r10,r11 ; index &= mask ! 613: lwz r7,method_imp(r7) ; imp = method->method_imp; ! 614: cmpw r5,r8 ; if (name != selector) ! 615: bne cr0,LRS1 ; goto loop; ! 616: mtspr ctr,r7 ; ! 617: lwz r7, 40(r1) ; restore r7 through r10 ! 618: lwz r8, 44(r1) ! 619: lwz r9, 48(r1) ; ! 620: lwz r10,52(r1) ; ! 621: lwz r4,receiver(r4) ; restore the receiver ! 622: LRexit5: ! 623: bctr ; goto *imp; ! 624: .space 112 ; /* area for moninitobjc to write */ ! 625: LRS2: ; ! 626: lwz r10,class(r4) ; class = self->class; ! 627: lwz r4,receiver(r4) ; restore the receiver ! 628: ! 629: stw r3, 24(r1) ; save the other register parameters ! 630: stw r4, 28(r1) ; ! 631: stw r5, 32(r1) ; ! 632: stw r6, 36(r1) ; ! 633: ! 634: mflr r0 ; save LR ! 635: stw r0,8(r1) ; ! 636: stwu r1,-64(r1) ; grow the stack ! 637: ! 638: ori r3,r10,0 ; first arg is the isa pointer ! 639: ori r4,r5,0 ; second arg is the selector ! 640: bl __class_lookupMethodAndLoadCache ! 641: mtspr ctr,r3 ! 642: lwz r1,0(r1) ; restore the stack pointer ! 643: ! 644: lwz r0,8(r1) ; ! 645: mtlr r0 ; restore return pc ! 646: lwz r3, 24(r1) ; ! 647: lwz r4, 28(r1) ; ! 648: lwz r5, 32(r1) ; ! 649: lwz r6, 36(r1) ; ! 650: lwz r7, 40(r1) ; ! 651: lwz r8, 44(r1) ; ! 652: lwz r9, 48(r1) ; ! 653: lwz r10,52(r1) ; ! 654: LRexit6: ! 655: bctr ; goto *imp; ! 656: .space 112 ; /* area for moninitobjc to write */ ! 657: ! 658: LRSL0: ; Locking case _objc_msgSendSuper_stret ! 659: stw r6,36(r1) ; save r6 ! 660: addis r6,0,hi16(_messageLock) ! 661: ori r6,r6,lo16(_messageLock) ! 662: ! 663: LRSgetit: ! 664: lwarx r0,0,r6 ; try to get the lock ! 665: cmpwi cr0,r0,0 ! 666: bne- LRSgetit ! 667: addi r0,0,1 ! 668: sync ; Bugfix for 3.2 and older cpus ! 669: stwcx. r0,0,r6 ! 670: bne- LRSgetit ! 671: isync ! 672: ! 673: lwz r10,class(r4) ; class = super->class; ! 674: lwz r10,cache(r10) ; cache = class->cache ! 675: lwz r11,mask(r10) ; mask = cache->mask ! 676: addi r9,r10,buckets ; buckets = cache->buckets ! 677: and r10,r5,r11 ; index = selector & mask; ! 678: LRSL1: ; ! 679: slwi r0,r10,2 ! 680: lwzx r7,r9,r0 ; method = cache->buckets[index]; ! 681: cmplwi cr0,r7,0 ; if (method == NULL) ! 682: beq cr0,LRSL2 ; ! 683: addi r10,r10,1 ; index++; ! 684: lwz r8,method_name(r7) ; name = method->method_name; ! 685: and r10,r10,r11 ; index &= mask ! 686: lwz r7,method_imp(r7) ; imp = method->method_imp; ! 687: cmpw r5,r8 ; if (name != selector) ! 688: bne cr0,LRSL1 ; goto loop; ! 689: mtspr ctr,r7 ; ! 690: lwz r7, 40(r1) ; restore r7 through r10 ! 691: lwz r8, 44(r1) ; ! 692: lwz r9, 48(r1) ; ! 693: lwz r10,52(r1) ; ! 694: ! 695: sync ; release the lock ! 696: addi r0,0,0 ! 697: stw r0,0(r6) ! 698: lwz r6,36(r1); ; restore r6 ! 699: lwz r4,receiver(r4) ; r4 = self for implementation ! 700: ! 701: LRexit7: ! 702: bctr ; goto *imp; ! 703: .space 112 ; /* area for moninitobjc to write */ ! 704: LRSL2: ; ! 705: lwz r10,class(r4) ; class = super->class; ! 706: lwz r4,receiver(r4) ; r4 = self for implementation ! 707: ! 708: stw r3, 24(r1) ; save the other register parameters ! 709: stw r4, 28(r1) ; ! 710: stw r5, 32(r1) ; ! 711: ! 712: mflr r0 ; save LR ! 713: stw r0,8(r1) ; ! 714: stwu r1,-64(r1) ; grow the stack ! 715: ! 716: ori r3,r10,0 ; first arg is the isa pointer ! 717: ori r4,r5,0 ; second arg is the selector ! 718: bl __class_lookupMethodAndLoadCache ! 719: mtspr ctr,r3 ! 720: lwz r1,0(r1) ; restore the stack pointer ! 721: ! 722: lwz r0,8(r1) ; ! 723: lwz r3, 24(r1) ; ! 724: lwz r4, 28(r1) ; ! 725: lwz r5, 32(r1) ; ! 726: ! 727: sync ; release the lock ! 728: addis r6,0,hi16(_messageLock) ! 729: ori r6,r6,lo16(_messageLock) ! 730: addi r0,0,0 ! 731: stw r0,0(r6) ! 732: ! 733: lwz r6, 36(r1) ; ! 734: lwz r7, 40(r1) ; ! 735: lwz r8, 44(r1) ; ! 736: lwz r9, 48(r1) ; ! 737: lwz r10,52(r1) ; ! 738: LRexit8: ! 739: bctr ; goto *imp; ! 740: .space 112 ; /* area for moninitobjc to write */ ! 741: ! 742: ; ! 743: ; End of code duplicated for struct-returns ! 744: ;-------------------------------------------------------------------- ! 745: ! 746: # Location L30 contains the string forward:: ! 747: # Location L31 contains a pointer to L30, that can be changed ! 748: # to point to another forward:: string for selector uniquing ! 749: # purposes. ALWAYS dereference L31 to get to forward:: !! ! 750: .objc_meth_var_names ! 751: .align 1 ! 752: L30: .ascii "forward::\0" ! 753: ! 754: .objc_message_refs ! 755: .align 2 ! 756: L31: .long L30 ! 757: ! 758: .cstring ! 759: .align 1 ! 760: L32: .ascii "Does not recognize selector %s\0" ! 761: ! 762: .text ! 763: .align 2 ! 764: .globl __objc_msgForward ! 765: __objc_msgForward: ! 766: #if defined(KERNEL) ! 767: trap ; this code isnt ready yet!!!!!!!!!!! ! 768: #else ! 769: addis r11,0,hi16(L31) ; ! 770: addi r11,r11,lo16(L31) ; ! 771: cmpw cr0,r11,r4 ; if (sel == @selector (forward::)) ! 772: bne L_error ; ! 773: ! 774: stw r3, 24(r1) ; home the register arguments, is there a "float" problem? ! 775: stw r4, 28(r1) ! 776: stw r5, 32(r1) ! 777: stw r6, 36(r1) ! 778: stw r7, 40(r1) ! 779: stw r8, 44(r1) ! 780: stw r9, 48(r1) ! 781: stw r10,52(r1) ! 782: ; (first arg remains self) ! 783: addis r4,0,hi16(L30) ; (second arg is "forward:") ! 784: addi r4,r4,lo16(L30) ! 785: andi. r5,r4,0 ; (third arg is previous selector) ! 786: addi r6,r1,24 ; (forth arg is &self) ! 787: ! 788: addi r1,r1,64 ; (grow the stack) ! 789: bl _objc_msgSend ; [self forward: sel : &self] ! 790: addi r1,r1,-64 ; (deallocate storage) ! 791: blr ; return ! 792: L_error: ! 793: addis r4,0,hi16(L32) ! 794: addi r4,r4,lo16(L32) ! 795: addis r5,0,hi16(L30) ! 796: addi r5,r5,lo16(L30) ! 797: bl ___objc_error ; ! 798: #endif /* ! KERNEL */ ! 799: ! 800: .text ! 801: .align 2 ! 802: .globl _objc_msgSendv ! 803: _objc_msgSendv: ! 804: #if defined(KERNEL) ! 805: trap ; this code isnt ready yet!!!!!!!!!!! ! 806: #else ! 807: mflr r0 ! 808: stw r0,8(r1) ; (save return pc) ! 809: addi r1,r1,32 ; (allocate storage) ! 810: ! 811: cmpwi cr0,r5,0 ! 812: bgt cr0,L34 ; if (size > 0) ... ! 813: ! 814: lwz r10,28(r6) ; (restore some of the args) ! 815: lwz r9, 24(r6) ! 816: lwz r8, 20(r6) ! 817: lwz r7, 16(r6) ! 818: lwz r1,0(r1) ; restore stack pointer ! 819: lwz r0,8(r1) ; restore return pc ! 820: ! 821: bl _objc_msgSend ; objc_msgSend (self, selector, ...) ! 822: ! 823: subi r31,r30,32 ; (deallocate variable storage) ! 824: addi r31,r31,16 ; (deallocate storage) ! 825: lwz r0,8(r1) ! 826: mtlr r0 ! 827: blr ; return ! 828: #endif /* ! KERNEL */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.