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

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.0 (the 'License').  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License."
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: #ifdef KERNEL
        !            25: #define OBJC_LOCK_ROUTINE _simple_lock
        !            26: #else
        !            27: ; _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.