Annotation of objc/objc-msg-hppa-copycache-lock.s, revision 1.1.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.