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

unix.superglobalmegacorp.com

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