Annotation of objc/objc-msg-hppa-nolock.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 0
                     37: 
                     38: .globl _objc_exitPoints
                     39: _objc_exitPoints:
                     40:        .long Lexit1
                     41:        .long Lexit5
                     42:        .long 0
                     43:        
                     44: #define OBJC_LOCK_ROUTINE _spin_lock
                     45: #endif /* KERNEL */
                     46: 
                     47: #define isa 0
                     48: #define cache 32
                     49: #define mask  0
                     50: #define buckets 8
                     51: #define method_name 0
                     52: #define method_imp 8
                     53: 
                     54: 
                     55: ; optimized for hppa: 20? clocks (best case) + 6 clocks / probe
                     56: 
                     57:         .text
                     58:        .align 4
                     59:        .globl _objc_msgSend
                     60:        
                     61: _objc_msgSend:
                     62:         comib,<>,n  0,%r26,L0          ; if (self) goto normalcase
                     63:        nop
                     64:         bv      0(%r2)                  ; else return null
                     65:         copy    0,%r28                  ; <delay slot> return val = 0
                     66: L0:     
                     67:         ldw      isa(0,%r26),%r19       ;     class = self->isa;
                     68:         ldw      cache(0,%r19),%r20     ;     cache = class->cache
                     69:         ldw      mask(0,%r20),%r21      ;     mask = cache->mask
                     70:         ldo      buckets(%r20),%r20     ;     buckets = cache->buckets
                     71:         and      %r21,%r25,%r22         ;     index = selector & mask;
                     72: L1:
                     73:         ldwx,s   %r22(0,%r20),%r19     ;     method = cache->buckets[index];
                     74:         comib,=,n 0,%r19,cacheMiss     ;     if (method == NULL)
                     75:         ldw     method_name(0,%r19),%r1 ; 
                     76:         addi    1,%r22,%r22             ; ++index
                     77:         comb,<> %r1, %r25, L1          ; if (name!=sel) continue loop
                     78:         and     %r21,%r22,%r22          ; <delay slot> index &=mask
                     79:         ldw     method_imp(0,%r19),%r19
                     80: Lexit1:
                     81:         bv,n     0(%r19)                ;    goto *imp;  (nullify delay)
                     82: 
                     83: #ifdef MONINIT
                     84:         .space 128                      ; /* area for moninitobjc to write */
                     85: #endif
                     86: 
                     87: cacheMiss:
                     88: ; We have to save all the register based arguments (including floating
                     89: ; point) before calling _class_lookupMethodAndLoadCache.  This is because
                     90: ; we do not know what arguments were passed to us, and the arguments are
                     91: ; not guaranteed to be saved across procedure calls (they are all caller-saved)
                     92: ; We also have to save the return address (since we did not save it on entry).
                     93: 
                     94: 
                     95:         copy    %r30,%r19
                     96:         ldo     128(%r30),%r30          ; Allocate space on stack
                     97:         stwm    %r2,4(0,%r19)           ; Save return pointer
                     98:         stwm    %r23,4(0,%r19)          ; Save old args
                     99:         stwm    %r24,4(0,%r19)          ;
                    100:         stwm    %r25,4(0,%r19)          ;
                    101:         stwm    %r26,4(0,%r19)          ;
                    102: #ifndef KERNEL
                    103:         fstds,mb  %fr4,4(0,%r19)        ; Save floating point args
                    104:         fstds,mb  %fr5,8(0,%r19)        ;    mb (modify before) is used instead
                    105:         fstds,mb  %fr6,8(0,%r19)        ;    of ma (as is implicit in above
                    106:         fstds,mb  %fr7,8(0,%r19)        ;    stores) with an initial value of 4
                    107:                                         ;    so that doubles are aligned
                    108:                                         ;    to 8 byte boundaries.
                    109:                                         ; Arg 1 (selector) is the same
                    110: #endif /* KERNEL */            
                    111: 
                    112:         stw     %r28,8(0,%r19)          ; save return struct ptr
                    113:         jbsr      __class_lookupMethodAndLoadCache,%r2,0f
                    114:         ldw      isa(0,%r26),%r26       ; <delay slot> arg 0 = self->isa
                    115: 
                    116:         ldo     -128(%r30),%r30         ;   deallocate
                    117:         copy    %r30,%r19               ;
                    118:         ldwm    4(0,%r19),%r2           ; restore everything
                    119:         ldwm    4(0,%r19),%r23          ; 
                    120:         ldwm    4(0,%r19),%r24          ;
                    121:         ldwm    4(0,%r19),%r25          ;
                    122:         ldwm    4(0,%r19),%r26          ;
                    123: #ifndef KERNEL
                    124:         fldds,mb  4(0,%r19),%fr4        ; see comment above about alignment
                    125:         fldds,mb  8(0,%r19),%fr5        ;
                    126:         fldds,mb  8(0,%r19),%fr6        ;
                    127:         fldds,mb  8(0,%r19),%fr7        ;
                    128: #endif /* KERNEL */            
                    129:         ldw     8(0,%r19),%r20          ; get ret structure ptr
                    130: 
                    131:         copy    %r28,%r19
                    132:         copy    %r20,%r28               ; restore ret structure ptr
                    133: Lexit2:
                    134:         bv,n    0(%r19)                 ;  goto *imp   (nullify delay)
                    135: 
                    136: ; stub for far call
                    137: 
                    138: 0:      ldil L`__class_lookupMethodAndLoadCache,%r1
                    139:         ble,n R`__class_lookupMethodAndLoadCache(4,%r1)
                    140: 
                    141: #ifdef MONINIT
                    142:         .space 128                      ; /* area for moninitobjc to write */
                    143: #endif
                    144: 
                    145: 
                    146: 
                    147: 
                    148: 
                    149: #define receiver 0
                    150: #define class 4
                    151: 
                    152:         .globl _objc_msgSendSuper
                    153: _objc_msgSendSuper:
                    154:         ldw      class(0,%r26),%r19     ;     class = caller->class;
                    155:         ldw      cache(0,%r19),%r20     ;     cache = class->cache
                    156:         ldw      mask(0,%r20),%r21      ;     mask = cache->mask
                    157:         ldo      buckets(%r20),%r20     ;     buckets = cache->buckets
                    158:         and      %r21,%r25,%r22         ;     index = selector & mask;
                    159: LS1:                                   ;
                    160:         ldwx,s   %r22(0,%r20),%r19      ;     method = cache->buckets[index];
                    161:         comib,=,n 0,%r19,LS2           ;     if (method == NULL)
                    162:         ldw     method_name(0,%r19),%r1; 
                    163:         addi    1,%r22,%r22             ; ++index
                    164:         comb,<> %r1, %r25, LS1          ; if (name!=sel) continue loop
                    165:         and     %r21,%r22,%r22          ; <delay slot> index &=mask
                    166:         ldw     method_imp(0,%r19),%r19
                    167:         ldw     receiver(0,%r26),%r26   ;     self = caller->receiver;
                    168: Lexit5:  
                    169:         bv,n     0(%r19)                ;    goto *imp;  (nullify delay)
                    170: #ifdef MONINIT
                    171:         .space 128                      ; /* area for moninitobjc to write */
                    172: #endif
                    173: 
                    174:                                         ;
                    175: LS2:                                   ;
                    176:         copy    %r30,%r19
                    177:         ldo     128(%r30),%r30          ; Allocate space on stack
                    178:         stwm    %r2,4(0,%r19)           ; Save return pointer
                    179:         stwm    %r23,4(0,%r19)          ; Save old args
                    180:         stwm    %r24,4(0,%r19)          ;
                    181:         stwm    %r25,4(0,%r19)          ;
                    182:         stwm    %r26,4(0,%r19)          ;
                    183: #ifndef KERNEL         
                    184:         fstds,mb  %fr4,4(0,%r19)        ; Save floating point args
                    185:         fstds,mb  %fr5,8(0,%r19)        ;    mb (modify before) is used instead
                    186:         fstds,mb  %fr6,8(0,%r19)        ;    of ma (as is implicit in above
                    187:         fstds,mb  %fr7,8(0,%r19)        ;    stores) with an initial value of 4
                    188:                                         ;    so that doubles are aligned
                    189:                                         ;    to 8 byte boundaries.
                    190:                                         ; Arg 1 (selector) is the same
                    191: #endif /* KERNEL */                                                                            
                    192:         stw     %r28,8(0,%r19)          ; save return struct ptr
                    193:         jbsr      __class_lookupMethodAndLoadCache,%r2,0f
                    194:         ldw      class(0,%r26),%r26     ; <delay slot> arg 0 = caller->class;
                    195:         ldo     -128(%r30),%r30         ;   deallocate
                    196:         copy    %r30,%r19               ;
                    197:         ldwm    4(0,%r19),%r2           ; restore everything
                    198:         ldwm    4(0,%r19),%r23          ; 
                    199:         ldwm    4(0,%r19),%r24          ;
                    200:         ldwm    4(0,%r19),%r25          ;
                    201:         ldwm    4(0,%r19),%r26          ;
                    202: #ifndef KERNEL                         
                    203:         fldds,mb  4(0,%r19),%fr4        ; see comment above about alignment
                    204:         fldds,mb  8(0,%r19),%fr5        ;
                    205:         fldds,mb  8(0,%r19),%fr6        ;
                    206:         fldds,mb  8(0,%r19),%fr7        ;
                    207: #endif /* KERNEL */                                                                            
                    208:         ldw     8(0,%r19),%r20          ; get ret structure ptr
                    209:         ldw      receiver(0,%r26),%r26  ;     self = caller->receiver;
                    210:         copy    %r28,%r19
                    211:         copy    %r20,%r28
                    212: Lexit6:  bv,n    0(%r19)                 ;  goto *imp   (nullify delay)
                    213: 
                    214: ; stub for far call
                    215: 
                    216: 0:      ldil L`__class_lookupMethodAndLoadCache,%r1
                    217:         ble,n R`__class_lookupMethodAndLoadCache(4,%r1)
                    218: 
                    219: #ifdef MONINIT
                    220:         .space 128                      ; /* area for moninitobjc to write */
                    221: #endif
                    222: 
                    223:         
                    224: .objc_meth_var_names
                    225: .align 1
                    226: L30:    .ascii "forward::\0"
                    227: 
                    228: .objc_message_refs
                    229: .align 2
                    230: L31:    .long L30
                    231: 
                    232: .cstring
                    233: .align 1
                    234: L32:    .ascii "Does not recognize selector %s\0"
                    235: 
                    236: .text
                    237: .align 1
                    238: ;
                    239: ; NOTE: Because the stack grows from low mem to high mem on this machine
                    240: ; and the args go the other way, the marg_list pointer is to the first argument
                    241: ; and subsequent arguments are at NEGATIVE offsets from the marg_list.
                    242: ; This means that marg_getValue() and related macros will have to be adjusted
                    243: ; appropriately.
                    244: ;
                    245:        .globl __objc_msgForward
                    246: __objc_msgForward:
                    247:         stw     %r2,-20(0,%r30)         ; save rp
                    248:         ldo     64(%r30),%r30           ; create frame area (no locals needed)
                    249:         ldil    L`L31,%r1
                    250:         ldo     R`L31(%r1),%r19
                    251:         ldw     0(0,%r19),%r19
                    252:         combt,=,n %r19, %r25,L34       ; if (sel==@selector(forward::))
                    253:         ldo     -112(%r30),%r20         ; ptr to arg3 homing area
                    254:         stwm    %r23,4(0,%r20)          ; Mirror registers onto stack
                    255:         stwm    %r24,4(0,%r20)          ;
                    256:         stwm    %r25,4(0,%r20)          ;
                    257:         stwm    %r26,4(0,%r20)          ;
                    258:         
                    259:         copy    %r25,%r24
                    260:         copy    %r19,%r25               ; [self forward:sel :marg_list]
                    261: 
                    262:         bl      _objc_msgSend,%r2
                    263:         copy    %r20,%r23               ; <delay slot> copy original sel
                    264: 
                    265:         ldo     -64(%r30),%r30         ; deallocate
                    266:         ldw     -20(0,%r30),%r2                ; restore rp
                    267:         bv,n    0(%r2)                 ; return
                    268: L34:
                    269:         ldil    L`L32,%r1
                    270:         ldo     R`L32(%r1),%r25
                    271:         ldil   L`__objc_error,%r1
                    272:        be      R`__objc_error(%sr4,%r1) ; __objc_error never returns, so no
                    273:         copy    %r19,%r24                ; need to clean up.
                    274: 
                    275: 
                    276: ; Algorithm is as follows:
                    277: ; . Calculate how much stack size is needed for any arguments not in the
                    278: ;   general registers and allocate space on stack.
                    279: ; . Restore general argument regs from the bottom of the marg_list.
                    280: ; . Restore fp argument regs from the same area.
                    281: ;   (The first two args in the marg list are always old obj and old SEL.)
                    282: ; . Call the new method.
                    283:        .globl _objc_msgSendv
                    284: _objc_msgSendv:
                    285:                                         ; objc_msgSendv(self, sel, size, margs)
                    286:         stw     %r2,-20(0,%r30)         ; Save rp
                    287:         stw     %r4,-36(0,%r30)         ; Save callee-saved r4 
                    288:         copy    %r30,%r4                ; Save old sp vale
                    289:         ldo     95(%r24),%r19           ; Calculate frame size, rounded
                    290:         depi    0,31,6,%r19             ; up to 64 byte boundary...
                    291: 
                    292:         add     %r19,%r30,%r30          ; Allocate frame area (no locals)
                    293:         copy    %r24,%r20               ; r20 now holds arg size
                    294:         ldo     -16(%r23),%r21          ; r21 now holds marg_list+16
                    295:         ldws    0(0,%r21),%r23          ; Get old general register args (dont
                    296:         ldws    4(0,%r21),%r24          ; need first two: always self & SEL)
                    297: #ifndef KERNEL         
                    298:         fldds   0(0,%r21),%fr7          ; Mirror to fp regs
                    299:         fldws   4(0,%r21),%fr6          ; 
                    300: #endif /* KERNEL */            
                    301: 
                    302:         ldo     -52(%r30),%r22          ; newly allocated stack area.
                    303:         ldo     -8(%r20),%r20           ; Size -= 8
                    304:         comibf,<,n 0,%r20,L36
                    305: L35:    ldws,mb -4(0,%r21),%r19         ; while(size>0)
                    306:         addibf,<= -4,%r20,L35          ;  { *(dest--) = *(src--); size-=4; }
                    307:         stws,ma %r19,-4(0,%r22)         ; <delay slot>
                    308: L36:    bl      _objc_msgSend,%r2
                    309:         nop
                    310:         copy    %r4,%r30                ; deallocate
                    311:         ldw     -36(0,%r30), %r4
                    312:         ldw     -20(0,%r30), %r2
                    313: Lexit9:
                    314:         bv,n    0(%r2)
                    315: 
                    316: 

unix.superglobalmegacorp.com

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