Annotation of objc/objc-msg-hppa-copycache-lock.s, revision 1.1

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: #ifdef DYLIB
        !            28: #define OBJC_LOCK_ROUTINE _spin_lock$non_lazy_ptr
        !            29: #else
        !            30: #define OBJC_LOCK_ROUTINE _spin_lock
        !            31: #endif
        !            32: #endif /* KERNEL */
        !            33: 
        !            34: #define isa 0
        !            35: #define cache 32
        !            36: #define mask  0
        !            37: #define buckets 8
        !            38: #define method_name 0
        !            39: #define method_imp 4
        !            40: 
        !            41: ;; Optimized specifically for HP7100 (Gecko architecture)
        !            42: ;; It is assumed, that the cache line containing __objc_multithread_mask
        !            43: ;; is not missing.  This version has only two (2) back-to-back insn
        !            44: ;; output dependencies, of which one is in the inner loop at 2:.
        !            45: ;; This version has also no read insns with output dependency on the
        !            46: ;; following insn.  It is optimized with regard to branch prediction for
        !            47: ;; hit in the first probe (average probe length assumed to be .45), that
        !            48: ;; is why the final branch is moved before _objc_msgSend.
        !            49: 
        !            50: ;;  non-pic: 14 clocks best case, 4 clock / probe
        !            51: ;;           (4miss + 1hit) + (2hit) / probe
        !            52: 
        !            53: ;;      pic: 16 clocks best case, 4 clocks / probe
        !            54: ;;          (4miss + 2hit) + (2hit) / probe
        !            55: 
        !            56:         .text
        !            57:        .align 2
        !            58:        .globl _objc_msgSend
        !            59:        
        !            60: LX0:   bv,n     0(%r1)                 ;     goto *imp;  (nullify delay)
        !            61: _objc_msgSend:
        !            62:        comib,=,n 0,%r26, Lnull         ;     <?not taken?>
        !            63: #ifdef DYLIB
        !            64:        bl      LX1,%r21
        !            65:        ldw     isa(0,%r26),%r19        ;     class = self->isa;
        !            66: LX1:
        !            67:         depi   0,31,2,%r21
        !            68:         addil  L`__objc_multithread_mask$non_lazy_ptr-LX1,%r21
        !            69:         ldw     cache(0,%r19),%r20             ;     cache = class->cache
        !            70:        ldw     R`__objc_multithread_mask$non_lazy_ptr-LX1(%r1),%r22 
        !            71:         ldw     mask(0,%r20),%r21              ;     mask = cache->mask
        !            72:        ldw     0(%r22),%r22            ;     <indirect non lazy pointer>
        !            73:        ldo     buckets(%r20),%r20      ;     buckets = cache->buckets
        !            74:        comib,=,n 0,%r22, SendLocking   ;     <?not taken?>
        !            75: #else  
        !            76:        ldil    L`__objc_multithread_mask,%r1
        !            77:        ldw     isa(0,%r26),%r19        ;     class = self->isa;
        !            78:        ldw     R`__objc_multithread_mask(%r1),%r22
        !            79:         ldw     cache(0,%r19),%r20             ;     cache = class->cache
        !            80:        comib,=,n 0,%r22, SendLocking   ;     <?not taken?>
        !            81:         ldw     mask(0,%r20),%r21              ;     mask = cache->mask
        !            82:        ldo     buckets(%r20),%r20      ;     buckets = cache->buckets
        !            83: #endif
        !            84: 
        !            85:         and     %r21,%r25,%r22          ;     index = selector & mask;
        !            86: 2:     sh3add %r22,%r20,%r1            ;     bucket = (index * 4) + buckets
        !            87:         ldw method_name(0,%r1),%r19    ;     op = bucket->selector_name
        !            88: 
        !            89:         ldo 1(%r22),%r22               ;     index += 1
        !            90:         comb,= %r25,%r19,LX0           ;     if (selector == op) goto Lexit1 <?taken?>
        !            91:         ldw method_imp(0,%r1),%r1      ;     <delay slot> imp = bucket->selector_imp
        !            92:         comib,<> 0,%r19,2b             ;     if (op != 0) goto 2 <?taken?>
        !            93: 
        !            94:         and %r22,%r21,%r22             ;     <delay slot> index &= mask
        !            95:        b,n L2                          ;     else goto cacheMiss
        !            96: L2:
        !            97: ; We have to save all the register based arguments (including floating
        !            98: ; point) before calling _class_lookupMethodAndLoadCache.  This is because
        !            99: ; we do not know what arguments were passed to us, and the arguments are
        !           100: ; not guaranteed to be saved across procedure calls (they are all caller-saved)
        !           101: ; We also have to save the return address (since we did not save it on entry).
        !           102: 
        !           103: 
        !           104:         copy    %r30,%r19
        !           105:         ldo     128(%r30),%r30          ; Allocate space on stack
        !           106:         stwm    %r2,4(0,%r19)           ; Save return pointer
        !           107:         stwm    %r23,4(0,%r19)          ; Save old args
        !           108:         stwm    %r24,4(0,%r19)          ;
        !           109:         stwm    %r25,4(0,%r19)          ;
        !           110:         stwm    %r26,4(0,%r19)          ;
        !           111: #ifndef KERNEL
        !           112:         fstds,mb  %fr4,4(0,%r19)        ; Save floating point args
        !           113:         fstds,mb  %fr5,8(0,%r19)        ;    mb (modify before) is used instead
        !           114:         fstds,mb  %fr6,8(0,%r19)        ;    of ma (as is implicit in above
        !           115:         fstds,mb  %fr7,8(0,%r19)        ;    stores) with an initial value of 4
        !           116:                                         ;    so that doubles are aligned
        !           117:                                         ;    to 8 byte boundaries.
        !           118:                                         ; Arg 1 (selector) is the same
        !           119: #endif /* KERNEL */            
        !           120: 
        !           121:         stw     %r28,8(0,%r19)          ; save return struct ptr
        !           122:         jbsr      __class_lookupMethodAndLoadCache,%r2,0f
        !           123:         ldw      isa(0,%r26),%r26       ; <delay slot> arg 0 = self->isa
        !           124: 
        !           125:         ldo     -128(%r30),%r30         ;   deallocate
        !           126:         copy    %r30,%r19               ;
        !           127:         ldwm    4(0,%r19),%r2           ; restore everything
        !           128:         ldwm    4(0,%r19),%r23          ; 
        !           129:         ldwm    4(0,%r19),%r24          ;
        !           130:         ldwm    4(0,%r19),%r25          ;
        !           131:         ldwm    4(0,%r19),%r26          ;
        !           132: #ifndef KERNEL
        !           133:         fldds,mb  4(0,%r19),%fr4        ; see comment above about alignment
        !           134:         fldds,mb  8(0,%r19),%fr5        ;
        !           135:         fldds,mb  8(0,%r19),%fr6        ;
        !           136:         fldds,mb  8(0,%r19),%fr7        ;
        !           137: #endif /* KERNEL */            
        !           138:         ldw     8(0,%r19),%r20          ; get ret structure ptr
        !           139: 
        !           140:         copy    %r28,%r19
        !           141:         copy    %r20,%r28               ; restore ret structure ptr
        !           142: 
        !           143:         bv,n    0(%r19)                 ;  goto *imp   (nullify delay)
        !           144: 
        !           145: ; stub for far call
        !           146: 
        !           147:        .align 2
        !           148: #ifdef DYLIB
        !           149: 0:     bl   LX5,%r1
        !           150:        nop
        !           151: LX5:   depi    0,31,2,%r1
        !           152:        addil L`__class_lookupMethodAndLoadCache$non_lazy_ptr-LX5,%r1
        !           153:        ldw R`__class_lookupMethodAndLoadCache$non_lazy_ptr-LX5(%r1),%r1
        !           154:        be,n 0(4,%r1)
        !           155: #else
        !           156: 0:      ldil L`__class_lookupMethodAndLoadCache,%r1
        !           157:         be,n R`__class_lookupMethodAndLoadCache(4,%r1)
        !           158: #endif
        !           159: 
        !           160:        .align 2
        !           161: Lnull:
        !           162:         bv      0(%r2)                  ; return null
        !           163:         copy    0,%r28                  ; <delay slot> return val = 0
        !           164: 
        !           165: 
        !           166: 
        !           167: ; Locking version of objc_msgSend
        !           168: ; uses spin_lock() to lock the mutex.
        !           169: 
        !           170:        .align 2
        !           171: SendLocking:
        !           172:         copy    %r30,%r19
        !           173:         ldo     128(%r30),%r30          ; Allocate space on stack
        !           174:         stwm    %r2,4(0,%r19)           ; Save return pointer
        !           175:         stwm    %r23,4(0,%r19)          ; Save old args
        !           176: 
        !           177:         stwm    %r24,4(0,%r19)          ;
        !           178:         stwm    %r25,4(0,%r19)          ;
        !           179:         stwm    %r26,4(0,%r19)          ;
        !           180:         stwm    %r28,4(0,%r19)          ; save return struct ptr
        !           181: 
        !           182: #ifndef KERNEL         
        !           183:         fstds,ma  %fr4,8(0,%r19)        ; Save floating point args
        !           184:         fstds,ma  %fr5,8(0,%r19)        ;
        !           185:         fstds,ma  %fr6,8(0,%r19)        ;
        !           186:         fstds,ma  %fr7,8(0,%r19)        ;
        !           187: #endif /* KERNEL */            
        !           188:        
        !           189: #ifdef DYLIB
        !           190: 0:     bl   LX6,%r24
        !           191:        nop
        !           192: LX6:   depi    0,31,2,%r24
        !           193:        addil   L`_messageLock$non_lazy_ptr-LX6,%r24
        !           194:        ldw     R`_messageLock$non_lazy_ptr-LX6(%r1),%r26
        !           195:        addil   L`OBJC_LOCK_ROUTINE -LX6,%r24   ; call spin_lock() with _messageLock
        !           196:        ldw     R`OBJC_LOCK_ROUTINE -LX6(%r1),%r24
        !           197:        ble     0(%sr4,%r24)
        !           198: #else
        !           199:        ldil    L`_messageLock,%r1
        !           200:        ldo     R`_messageLock(%r1),%r26
        !           201:        ldil    L`OBJC_LOCK_ROUTINE,%r1 ; call spin_lock() with _messageLock
        !           202:        ble     R`OBJC_LOCK_ROUTINE(%sr4,%r1)
        !           203: #endif
        !           204: 
        !           205:        copy    %r31,%r2
        !           206:         ldw    -112(%r30),%r26         ; restore arg0 
        !           207:        ldw     -108(%r30),%r28         ; and ret0
        !           208:        ldw      isa(0,%r26),%r19       ;     class = self->isa;
        !           209: 
        !           210:         ldw      cache(0,%r19),%r20     ;     cache = class->cache
        !           211:         ldw      mask(0,%r20),%r21      ;     mask = cache->mask
        !           212:         ldo      buckets(%r20),%r20     ;     buckets = cache->buckets
        !           213:         and      %r21,%r25,%r22         ;     index = selector & mask;
        !           214: 
        !           215: LL1:   sh3add %r22,%r20,%r1            ;     bucket = (index * 4) + buckets
        !           216:        ldw method_name(0,%r1),%r19     ;     op = bucket->selector_name
        !           217:         ldo 1(%r22),%r22               ;     index += 1
        !           218:        comb,=,n %r25,%r19,LLhit1       ;     if (selector == op) goto LLhit1
        !           219: 
        !           220:         comib,<> 0,%r19,LL1            ;     if (op != 0) goto LL1
        !           221:         and %r22,%r21,%r22             ;     <delay slot> index &= mask
        !           222:        b,n LL2                         ;     else goto cacheMiss
        !           223: LLhit1:
        !           224:        ldw method_imp(0,%r1),%r19      ;     imp = bucket->selector_imp
        !           225: #if KERNEL
        !           226:        ldil    L`_messageLock,%r1
        !           227:        ldo     R`_messageLock(%r1),%r20
        !           228:        addi        0xc,%r20,%r20
        !           229:        depi        0,31,4,%r20
        !           230:        zdepi       1,31,1,%r1
        !           231:        stw         %r1,0(0,%r20)
        !           232: #else
        !           233: #ifdef DYLIB
        !           234:        bl   LX7,%r21
        !           235:        nop
        !           236: LX7:   depi    0,31,2,%r21
        !           237:        addil   L`_messageLock$non_lazy_ptr-LX7,%r21
        !           238:        ldw     R`_messageLock$non_lazy_ptr-LX7(%r1),%r21
        !           239:        stw     %r0,0(%r21) ; unlock the lock
        !           240: #else
        !           241:        ldil    L`_messageLock,%r1
        !           242:        stw     %r0,R`_messageLock(%r1) ; unlock the lock
        !           243: #endif
        !           244: #endif 
        !           245:        ldwm    -128(%r30),%r2          ; restore original rp and deallocate
        !           246:        bv,n     0(%r19)                ;    goto *imp;  (nullify delay)
        !           247: 
        !           248: LL2:
        !           249:         jbsr      __class_lookupMethodAndLoadCache,%r2,0f
        !           250:         ldw      isa(0,%r26),%r26       ; <delay slot> arg 0 = self->isa
        !           251: 
        !           252:         ldo     -128(%r30),%r30         ;   deallocate
        !           253:         copy    %r30,%r19               ;
        !           254:         ldwm    4(0,%r19),%r2           ; restore everything
        !           255:         ldwm    4(0,%r19),%r23          ; 
        !           256:         ldwm    4(0,%r19),%r24          ;
        !           257:         ldwm    4(0,%r19),%r25          ;
        !           258:         ldwm    4(0,%r19),%r26          ;
        !           259:         ldwm    4(0,%r19),%r20          ; get ret structure ptr
        !           260: #ifndef KERNEL         
        !           261:         fldds,ma  8(0,%r19),%fr4        ;
        !           262:         fldds,ma  8(0,%r19),%fr5        ;
        !           263:         fldds,ma  8(0,%r19),%fr6        ;
        !           264:         fldds,ma  8(0,%r19),%fr7        ;
        !           265: #endif /* KERNEL */            
        !           266:  
        !           267:         copy    %r28,%r19
        !           268:         copy    %r20,%r28               ; restore ret structure ptr
        !           269: #if KERNEL
        !           270:        ldil    L`_messageLock,%r1
        !           271:        ldo     R`_messageLock(%r1),%r20
        !           272:        addi        0xc,%r20,%r20
        !           273:        depi        0,31,4,%r20
        !           274:        zdepi       1,31,1,%r1
        !           275:        stw         %r1,0(0,%r20)
        !           276: #else
        !           277: #ifdef DYLIB
        !           278:        bl   LX8,%r19
        !           279:        nop
        !           280: LX8:   depi    0,31,2,%r19
        !           281:        addil   L`_messageLock$non_lazy_ptr-LX8,%r19
        !           282:        ldw     _messageLock$non_lazy_ptr-LX8(%r1),%r19
        !           283:        stw     %r0,0(%r19)      ; unlock the lock
        !           284: #else
        !           285:        ldil    L`_messageLock,%r1
        !           286:        stw     %r0,R`_messageLock(%r1) ; unlock the lock
        !           287: #endif
        !           288: #endif
        !           289:         bv,n    0(%r19)                 ;  goto *imp   (nullify delay)
        !           290: 
        !           291: ; stub for far call
        !           292: 
        !           293:        .align 2
        !           294: #ifdef DYLIB
        !           295: 0:     bl   LX2,%r1
        !           296:        nop
        !           297: LX2:   depi    0,31,2,%r1
        !           298:        addil L`__class_lookupMethodAndLoadCache$non_lazy_ptr-LX2,%r1
        !           299:        ldw R`__class_lookupMethodAndLoadCache$non_lazy_ptr-LX2(%r1),%r1
        !           300:        be,n 0(4,%r1)
        !           301: #else
        !           302: 0:      ldil L`__class_lookupMethodAndLoadCache,%r1
        !           303:         be,n R`__class_lookupMethodAndLoadCache(4,%r1)
        !           304: #endif
        !           305: 
        !           306: 
        !           307: #define receiver 0
        !           308: #define class 4
        !           309: 
        !           310:         .globl _objc_msgSendSuper
        !           311:        .align 2
        !           312: _objc_msgSendSuper:
        !           313:        ldil    L`__objc_multithread_mask,%r1
        !           314:        ldw     R`__objc_multithread_mask(%r1),%r19
        !           315:        combt,= %r0,%r19,SuperLocking   ; 
        !           316:         ldw      class(0,%r26),%r19     ;     class = caller->class;
        !           317: 
        !           318:         ldw      cache(0,%r19),%r20     ;     cache = class->cache
        !           319:         ldw      mask(0,%r20),%r21      ;     mask = cache->mask
        !           320:         ldo      buckets(%r20),%r20     ;     buckets = cache->buckets
        !           321:         and      %r21,%r25,%r22         ;     index = selector & mask;
        !           322: 
        !           323: LS1:    sh3add %r22,%r20,%r1           ;     bucket = (index * 4) + buckets
        !           324:         ldw method_name(0,%r1),%r19    ;     op = bucket->selector_name
        !           325:         ldo 1(%r22),%r22               ;     index += 1
        !           326:         comb,= %r25,%r19,LShit1        ;     if (selector == op) goto LShit1
        !           327: 
        !           328:         ldw method_imp(0,%r1),%r1      ;     <delay slot> imp = bucket->selector_imp
        !           329:         comib,<> 0,%r19,LS1            ;     if (op != 0) goto LS1
        !           330:         and %r22,%r21,%r22             ;     <delay slot> index &= mask
        !           331:        b,n LS2                         ;     else goto cacheMiss
        !           332: 
        !           333: LShit1:
        !           334:         bv       0(%r1)                        ;    goto *imp;  (nullify delay)
        !           335:         ldw      receiver(0,%r26),%r26 ;    <delay slot> self = caller->receiver;
        !           336:                                         ;
        !           337: LS2:                                   ;
        !           338:         copy    %r30,%r19
        !           339:         ldo     128(%r30),%r30          ; Allocate space on stack
        !           340:         stwm    %r2,4(0,%r19)           ; Save return pointer
        !           341:         stwm    %r23,4(0,%r19)          ; Save old args
        !           342:         stwm    %r24,4(0,%r19)          ;
        !           343:         stwm    %r25,4(0,%r19)          ;
        !           344:         stwm    %r26,4(0,%r19)          ;
        !           345: #ifndef KERNEL         
        !           346:         fstds,mb  %fr4,4(0,%r19)        ; Save floating point args
        !           347:         fstds,mb  %fr5,8(0,%r19)        ;    mb (modify before) is used instead
        !           348:         fstds,mb  %fr6,8(0,%r19)        ;    of ma (as is implicit in above
        !           349:         fstds,mb  %fr7,8(0,%r19)        ;    stores) with an initial value of 4
        !           350:                                         ;    so that doubles are aligned
        !           351:                                         ;    to 8 byte boundaries.
        !           352:                                         ; Arg 1 (selector) is the same
        !           353: #endif /* KERNEL */                                                                            
        !           354:         stw     %r28,8(0,%r19)          ; save return struct ptr
        !           355:         jbsr      __class_lookupMethodAndLoadCache,%r2,0f
        !           356:         ldw      class(0,%r26),%r26     ; <delay slot> arg 0 = caller->class;
        !           357:         ldo     -128(%r30),%r30         ;   deallocate
        !           358:         copy    %r30,%r19               ;
        !           359:         ldwm    4(0,%r19),%r2           ; restore everything
        !           360:         ldwm    4(0,%r19),%r23          ; 
        !           361:         ldwm    4(0,%r19),%r24          ;
        !           362:         ldwm    4(0,%r19),%r25          ;
        !           363:         ldwm    4(0,%r19),%r26          ;
        !           364: #ifndef KERNEL                         
        !           365:         fldds,mb  4(0,%r19),%fr4        ; see comment above about alignment
        !           366:         fldds,mb  8(0,%r19),%fr5        ;
        !           367:         fldds,mb  8(0,%r19),%fr6        ;
        !           368:         fldds,mb  8(0,%r19),%fr7        ;
        !           369: #endif /* KERNEL */                                                                            
        !           370:         ldw     8(0,%r19),%r20          ; get ret structure ptr
        !           371:         ldw      receiver(0,%r26),%r26  ;     self = caller->receiver;
        !           372:         copy    %r28,%r19
        !           373:         copy    %r20,%r28
        !           374:        bv,n    0(%r19)                 ;  goto *imp   (nullify delay)
        !           375: 
        !           376: ; stub for far call
        !           377: 
        !           378:        .align 2
        !           379: #ifdef DYLIB
        !           380: 0:     bl   LX3,%r1
        !           381:        nop
        !           382: LX3:   depi    0,31,2,%r1
        !           383:        addil L`__class_lookupMethodAndLoadCache$non_lazy_ptr-LX3,%r1
        !           384:        ldw R`__class_lookupMethodAndLoadCache$non_lazy_ptr-LX3(%r1),%r1
        !           385:        be,n 0(4,%r1)
        !           386: #else
        !           387: 0:      ldil L`__class_lookupMethodAndLoadCache,%r1
        !           388:         be,n R`__class_lookupMethodAndLoadCache(4,%r1)
        !           389: #endif
        !           390: 
        !           391: 
        !           392: 
        !           393: 
        !           394: ; locking version of objc_msgSendSuper
        !           395: ; uses spin_lock() to lock the lock.
        !           396: 
        !           397:        .align 2
        !           398: SuperLocking:
        !           399:         copy    %r30,%r19
        !           400:         ldo     128(%r30),%r30          ; Allocate space on stack
        !           401:         stwm    %r2,4(0,%r19)           ; Save return pointer
        !           402:         stwm    %r23,4(0,%r19)          ; Save old args
        !           403:         stwm    %r24,4(0,%r19)          ;
        !           404:         stwm    %r25,4(0,%r19)          ;
        !           405:         stwm    %r26,4(0,%r19)          ;
        !           406:         stwm    %r28,4(0,%r19)          ; save return struct ptr
        !           407: #ifndef KERNEL         
        !           408:         fstds,ma  %fr4,8(0,%r19)        ; Save floating point args
        !           409:         fstds,ma  %fr5,8(0,%r19)        ;
        !           410:         fstds,ma  %fr6,8(0,%r19)        ;
        !           411:         fstds,ma  %fr7,8(0,%r19)        ;
        !           412: #endif /* KERNEL */                                                                            
        !           413: #ifdef DYLIB
        !           414: 0:     bl   LX9,%r24
        !           415:        nop
        !           416: LX9:   depi    0,31,2,%r24
        !           417:        addil   L`_messageLock$non_lazy_ptr-LX9,%r24
        !           418:        ldw     R`_messageLock$non_lazy_ptr-LX9(%r1),%r26
        !           419:        addil   L`OBJC_LOCK_ROUTINE-LX9,%r24    ; call spin_lock() with _messageLock
        !           420:        ldw     R`OBJC_LOCK_ROUTINE-LX9(%r1),%r24
        !           421:        ble     0(%sr4,%r24)
        !           422: #else
        !           423:        ldil    L`_messageLock,%r1
        !           424:        ldo     R`_messageLock(%r1),%r26
        !           425:        ldil    L`OBJC_LOCK_ROUTINE,%r1 ; call spin_lock() with _messageLock
        !           426:        ble     R`OBJC_LOCK_ROUTINE(%sr4,%r1)
        !           427: #endif
        !           428:        copy    %r31,%r2
        !           429:         ldw    -112(%r30),%r26         ; restore arg0 
        !           430:        ldw     -108(%r30),%r28         ; and ret0 (spin_lock doesnt
        !           431:                                        ; touch anything else)
        !           432:         ldw      class(0,%r26),%r19     ;     class = caller->class;
        !           433:         ldw      cache(0,%r19),%r20     ;     cache = class->cache
        !           434:         ldw      mask(0,%r20),%r21      ;     mask = cache->mask
        !           435:         ldo      buckets(%r20),%r20     ;     buckets = cache->buckets
        !           436:         and      %r21,%r25,%r22         ;     index = selector & mask;
        !           437: 
        !           438: LLS1:   sh3add %r22,%r20,%r1           ;     bucket = (index * 4) + buckets
        !           439:         ldw method_name(0,%r1),%r19    ;     op = bucket->selector_name
        !           440:         ldo 1(%r22),%r22               ;     index += 1
        !           441:         comb,=,n %r25,%r19,LLShit1      ;     if (selector == op) goto LShit1
        !           442: 
        !           443:         comib,<> 0,%r19,LLS1           ;     if (op != 0) goto LS1
        !           444:         and %r22,%r21,%r22             ;     <delay slot> index &= mask
        !           445:        b,n LLS2                        ;     else goto cacheMiss
        !           446: 
        !           447: LLShit1:
        !           448:         ldw method_imp(0,%r1),%r19     ;     imp = bucket->selector_imp
        !           449:         ldw receiver(0,%r26),%r26      ;     self = caller->receiver;
        !           450: 
        !           451: #if KERNEL
        !           452:        ldil    L`_messageLock,%r1
        !           453:        ldo     R`_messageLock(%r1),%r20
        !           454:        addi        0xc,%r20,%r20
        !           455:        depi        0,31,4,%r20
        !           456:        zdepi       1,31,1,%r1
        !           457:     stw         %r1,0(0,%r20)
        !           458: #else
        !           459: #ifdef DYLIB
        !           460:        bl   LX10,%r19
        !           461:        nop
        !           462: LX10:  depi    0,31,2,%r19
        !           463:        addil   L`_messageLock$non_lazy_ptr-LX10,%r19
        !           464:        ldw     R`_messageLock$non_lazy_ptr-LX10(%r1),%r19
        !           465:        stw     %r0,0(%r19) ; unlock the lock
        !           466: #else
        !           467:        ldil    L`_messageLock,%r1
        !           468:        stw     %r0,R`_messageLock(%r1) ; unlock the lock
        !           469: #endif
        !           470: #endif
        !           471:        ldwm    -128(%r30),%r2          ; restore original rp and deallocate
        !           472:         bv,n     0(%r19)                ;    goto *imp;  (nullify delay)
        !           473: #ifdef MONINIT
        !           474:         .space 128                      ; /* area for moninitobjc to write */
        !           475: #endif
        !           476: 
        !           477:                                         ;
        !           478: LLS2:                                  ;
        !           479:         jbsr    __class_lookupMethodAndLoadCache,%r2,0f
        !           480:         ldw     class(0,%r26),%r26     ; <delay slot> arg 0 = caller->class;
        !           481:         ldo     -128(%r30),%r30         ;   deallocate
        !           482:         copy    %r30,%r19               ;
        !           483:         ldwm    4(0,%r19),%r2           ; restore everything
        !           484:         ldwm    4(0,%r19),%r23          ; 
        !           485:         ldwm    4(0,%r19),%r24          ;
        !           486:         ldwm    4(0,%r19),%r25          ;
        !           487:         ldwm    4(0,%r19),%r26          ;
        !           488:         ldwm    4(0,%r19),%r20          ; get ret structure ptr
        !           489: #ifndef KERNEL
        !           490:         fldds,ma  8(0,%r19),%fr4        ; 
        !           491:         fldds,ma  8(0,%r19),%fr5        ;
        !           492:         fldds,ma  8(0,%r19),%fr6        ;
        !           493:         fldds,ma  8(0,%r19),%fr7        ;
        !           494: #endif /* KERNEL */                                                                                            
        !           495:         ldw      receiver(0,%r26),%r26  ;     self = caller->receiver;
        !           496:         copy    %r28,%r19
        !           497:         copy    %r20,%r28
        !           498: #if KERNEL
        !           499:        ldil    L`_messageLock,%r1
        !           500:        ldo     R`_messageLock(%r1),%r20
        !           501:        addi        0xc,%r20,%r20
        !           502:        depi        0,31,4,%r20
        !           503:        zdepi       1,31,1,%r1
        !           504:        stw         %r1,0(0,%r20)
        !           505: #else
        !           506:         ldil   L`_messageLock,%r1
        !           507:        stw     %r0,R`_messageLock(%r1) ; unlock the lock
        !           508: #endif
        !           509:        bv,n    0(%r19)                 ;  goto *imp   (nullify delay)
        !           510: 
        !           511: ; stub for far call
        !           512: 
        !           513:        .align 2
        !           514: #ifdef DYLIB
        !           515: 0:     bl   LX4,%r1
        !           516:        nop
        !           517: LX4:   depi    0,31,2,%r1
        !           518:        addil L`__class_lookupMethodAndLoadCache$non_lazy_ptr-LX4,%r1
        !           519:        ldw R`__class_lookupMethodAndLoadCache$non_lazy_ptr-LX4(%r1),%r1
        !           520:        be,n 0(4,%r1)
        !           521: #else
        !           522: 0:      ldil L`__class_lookupMethodAndLoadCache,%r1
        !           523:         be,n R`__class_lookupMethodAndLoadCache(4,%r1)
        !           524: #endif
        !           525: 
        !           526:         
        !           527:         .objc_meth_var_names
        !           528: L30:    .ascii "forward::\0"
        !           529: 
        !           530:         .objc_message_refs
        !           531:        .align 2
        !           532: L31:    .long L30
        !           533: 
        !           534:         .cstring
        !           535: L32:    .ascii "Does not recognize selector %s\0"
        !           536: 
        !           537:         .text
        !           538:         .align 2
        !           539: ;
        !           540: ; NOTE: Because the stack grows from low mem to high mem on this machine
        !           541: ; and the args go the other way, the marg_list pointer is to the first argument
        !           542: ; and subsequent arguments are at NEGATIVE offsets from the marg_list.
        !           543: ; This means that marg_getValue() and related macros will have to be adjusted
        !           544: ; appropriately.
        !           545: ;
        !           546:        .globl __objc_msgForward
        !           547: __objc_msgForward:
        !           548:         stw     %r2,-20(0,%r30)         ; save rp
        !           549:         ldo     64(%r30),%r30           ; create frame area (no locals needed)
        !           550:         ldil    L`L31,%r1
        !           551:         ldo     R`L31(%r1),%r19
        !           552:         ldw     0(0,%r19),%r19
        !           553:         combt,=,n %r19, %r25,L34       ; if (sel==@selector(forward::))
        !           554:         ldo     -112(%r30),%r20         ; ptr to arg3 homing area
        !           555:         stwm    %r23,4(0,%r20)          ; Mirror registers onto stack
        !           556:         stwm    %r24,4(0,%r20)          ;
        !           557:         stwm    %r25,4(0,%r20)          ;
        !           558:         stwm    %r26,4(0,%r20)          ;
        !           559:         
        !           560:         copy    %r25,%r24
        !           561:         copy    %r19,%r25               ; [self forward:sel :marg_list]
        !           562: 
        !           563:         bl      _objc_msgSend,%r2
        !           564:         copy    %r20,%r23               ; <delay slot> copy original sel
        !           565: 
        !           566:         ldo     -64(%r30),%r30         ; deallocate
        !           567:         ldw     -20(0,%r30),%r2                ; restore rp
        !           568:         bv,n    0(%r2)                 ; return
        !           569: L34:
        !           570:         ldil    L`L32,%r1
        !           571:         ldo     R`L32(%r1),%r25
        !           572:         ldil   L`__objc_error,%r1
        !           573:        be      R`__objc_error(%sr4,%r1) ; __objc_error never returns, so no
        !           574:         copy    %r19,%r24                ; need to clean up.
        !           575: 
        !           576: 
        !           577: ; Algorithm is as follows:
        !           578: ; . Calculate how much stack size is needed for any arguments not in the
        !           579: ;   general registers and allocate space on stack.
        !           580: ; . Restore general argument regs from the bottom of the marg_list.
        !           581: ; . Restore fp argument regs from the same area.
        !           582: ;   (The first two args in the marg list are always old obj and old SEL.)
        !           583: ; . Copy any remaining args from the marg_list to the new frame
        !           584: ; . Call the new method.
        !           585:        .align 2
        !           586:        .globl _objc_msgSendv
        !           587: _objc_msgSendv:
        !           588:                                         ; objc_msgSendv(self, sel, size, margs)
        !           589:         stw     %r2,-20(0,%r30)         ;
        !           590:         copy   %r4, %r1                ; stanard prologue
        !           591:         copy    %r30,%r4                ;
        !           592:        stw     %r1,0(0,%r4)            ;
        !           593:         ldo     99(%r24),%r19           ; Calculate frame size, rounded
        !           594:         depi    0,31,6,%r19             ; up to 64 byte boundary...
        !           595: 
        !           596:         add     %r19,%r30,%r30          ; Allocate frame area (no locals)
        !           597:         copy    %r24,%r20               ; r20 now holds arg size
        !           598:         ldo     -16(%r23),%r21          ; r21 now holds marg_list+16
        !           599:         ldws    0(0,%r21),%r23          ; Get old general register args (dont
        !           600:         ldws    4(0,%r21),%r24          ; need first two: always self & SEL)
        !           601: #ifndef KERNEL         
        !           602:         fldds   0(0,%r21),%fr7          ; Mirror to fp regs
        !           603:         fldws   4(0,%r21),%fr6          ; 
        !           604: #endif /* KERNEL */            
        !           605: 
        !           606:         ldo     -52(%r30),%r22          ; newly allocated stack area.
        !           607:         ldo     -16(%r20),%r20          ; Size -= 16
        !           608:         comibf,<,n 0,%r20,L36
        !           609: L35:    ldws,mb -4(0,%r21),%r19         ; while(size>0)
        !           610:         addibf,<= -4,%r20,L35          ;  { *(dest--) = *(src--); size-=4; }
        !           611:         stws,ma %r19,-4(0,%r22)         ; <delay slot>
        !           612: L36:    bl      _objc_msgSend,%r2
        !           613:         nop
        !           614:         copy    %r4,%r30                ; deallocate
        !           615:         ldw     -20(0,%r30), %r2
        !           616:         bv     0(%r2)
        !           617:         ldw     0(0,%r30), %r4
        !           618: 
        !           619: #ifdef DYLIB
        !           620: .non_lazy_symbol_pointer
        !           621: _messageLock$non_lazy_ptr:
        !           622:         .indirect_symbol _messageLock
        !           623:         .long 0
        !           624: _spin_lock$non_lazy_ptr:
        !           625:         .indirect_symbol _spin_lock
        !           626:         .long 0
        !           627: __objc_multithread_mask$non_lazy_ptr:
        !           628:        .indirect_symbol __objc_multithread_mask
        !           629:        .long 0
        !           630: __class_lookupMethodAndLoadCache$non_lazy_ptr:
        !           631:        .indirect_symbol __class_lookupMethodAndLoadCache
        !           632:        .long 0
        !           633: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.