2 * Copyright (c) 1999-2007 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <TargetConditionals.h>
25 #if __x86_64__ && !(TARGET_OS_SIMULATOR && !TARGET_OS_IOSMAC)
29 /********************************************************************
30 ********************************************************************
32 ** objc-msg-x86_64.s - x86-64 code to support objc messaging.
34 ********************************************************************
35 ********************************************************************/
39 // _objc_restartableRanges is used by method dispatch
40 // to get the critical regions for which method caches
41 // cannot be garbage collected.
43 .macro RestartableEntry
45 .short LLookupEnd$0 - LLookupStart$0
46 .short LCacheMiss$0 - LLookupStart$0
51 .private_extern _objc_restartableRanges
52 _objc_restartableRanges:
53 RestartableEntry _cache_getImp
54 RestartableEntry _objc_msgSend
55 RestartableEntry _objc_msgSend_fpret
56 RestartableEntry _objc_msgSend_fp2ret
57 RestartableEntry _objc_msgSend_stret
58 RestartableEntry _objc_msgSendSuper
59 RestartableEntry _objc_msgSendSuper_stret
60 RestartableEntry _objc_msgSendSuper2
61 RestartableEntry _objc_msgSendSuper2_stret
62 RestartableEntry _objc_msgLookup
63 RestartableEntry _objc_msgLookup_fpret
64 RestartableEntry _objc_msgLookup_fp2ret
65 RestartableEntry _objc_msgLookup_stret
66 RestartableEntry _objc_msgLookupSuper2
67 RestartableEntry _objc_msgLookupSuper2_stret
71 /********************************************************************
72 * Recommended multi-byte NOP instructions
73 * (Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2B)
74 ********************************************************************/
75 #define nop1 .byte 0x90
76 #define nop2 .byte 0x66,0x90
77 #define nop3 .byte 0x0F,0x1F,0x00
78 #define nop4 .byte 0x0F,0x1F,0x40,0x00
79 #define nop5 .byte 0x0F,0x1F,0x44,0x00,0x00
80 #define nop6 .byte 0x66,0x0F,0x1F,0x44,0x00,0x00
81 #define nop7 .byte 0x0F,0x1F,0x80,0x00,0x00,0x00,0x00
82 #define nop8 .byte 0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
83 #define nop9 .byte 0x66,0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
86 /********************************************************************
87 * Harmless branch prefix hint for instruction alignment
88 ********************************************************************/
93 /********************************************************************
94 * Names for parameter registers.
95 ********************************************************************/
113 /********************************************************************
114 * Names for relative labels
115 * DO NOT USE THESE LABELS ELSEWHERE
116 * Reserved labels: 6: 7: 8: 9:
117 ********************************************************************/
118 #define LNilTestSlow 7
119 #define LNilTestSlow_f 7f
120 #define LNilTestSlow_b 7b
121 #define LGetIsaDone 8
122 #define LGetIsaDone_f 8f
123 #define LGetIsaDone_b 8b
124 #define LGetIsaSlow 9
125 #define LGetIsaSlow_f 9f
126 #define LGetIsaSlow_b 9b
128 /********************************************************************
130 ********************************************************************/
142 /********************************************************************
144 * Structure definitions.
146 ********************************************************************/
148 // objc_super parameter to sendSuper
152 // Selected field offsets in class structure
153 // #define isa 0 USE GetIsa INSTEAD
156 #define method_name 0
157 #define method_imp 16
164 //////////////////////////////////////////////////////////////////////
166 // ENTRY functionName
168 // Assembly directives to begin an exported function.
170 // Takes: functionName - name of the exported function
171 //////////////////////////////////////////////////////////////////////
187 //////////////////////////////////////////////////////////////////////
189 // END_ENTRY functionName
191 // Assembly directives to end an exported function. Just a placeholder,
192 // a close-parenthesis for ENTRY, until it is needed for something.
194 // Takes: functionName - name of the exported function
195 //////////////////////////////////////////////////////////////////////
202 /********************************************************************
204 * Unwind info generation
205 ********************************************************************/
207 .section __LD,__compact_unwind,regular,debug
209 .set LUnwind$0, LExit$0 - $0
212 .quad 0 /* no personality */
213 .quad 0 /* no LSDA */
217 #define NoFrame 0x02010000 // no frame, no SP adjustment except return address
218 #define FrameWithNoSaves 0x01000000 // frame, no non-volatile saves
221 /////////////////////////////////////////////////////////////////////
223 // CacheLookup return-type, caller, function
225 // Locate the implementation for a class in a selector's method cache.
227 // When this is used in a function that doesn't hold the runtime lock,
228 // this represents the critical section that may access dead memory.
229 // If the kernel causes one of these functions to go down the recovery
230 // path, we pretend the lookup failed by jumping the JumpMiss branch.
233 // $0 = NORMAL, FPRET, FP2RET, STRET
234 // $1 = CALL, LOOKUP, GETIMP
235 // a1 or a2 (STRET) = receiver
236 // a2 or a3 (STRET) = selector
237 // r10 = class to search
239 // On exit: r10 clobbered
240 // (found) calls or returns IMP in r11, eq/ne set for forwarding
241 // (not found) jumps to LCacheMiss, class still in r10
243 /////////////////////////////////////////////////////////////////////
247 // r11 = found bucket
250 movq cached_imp(%r11), %rax // return imp
252 jz 9f // don't xor a nil imp
253 xorq %r10, %rax // xor the isa with the imp
259 movq cached_imp(%r11), %r11 // load imp
260 xorq %r10, %r11 // xor imp and isa
262 // ne already set for forwarding by `xor`
264 cmp %r11, %r11 // set eq for stret forwarding
266 jmp *%r11 // call imp
269 movq cached_imp(%r11), %r11
270 xorq %r10, %r11 // return imp ^ isa
286 // As soon as we're past the LLookupStart$1 label we may have loaded
287 // an invalid cache pointer or mask.
289 // When task_restartable_ranges_synchronize() is called,
290 // (or when a signal hits us) before we're past LLookupEnd$1,
291 // then our PC will be reset to LCacheMiss$1 which forcefully
292 // jumps to the cache-miss codepath which have the following
296 // The cache-miss is just returning NULL (setting %rax to 0)
299 // - a1 or a2 (STRET) contains the receiver
300 // - a2 or a3 (STRET) contains the selector
301 // - r10 contains the isa
302 // - other registers are set as per calling conventions
307 movq %a2, %r11 // r11 = _cmd
309 movq %a3, %r11 // r11 = _cmd
311 andl 24(%r10), %r11d // r11 = _cmd & class->cache.mask
312 shlq $$4, %r11 // r11 = offset = (_cmd & mask)<<4
313 addq 16(%r10), %r11 // r11 = class->cache.buckets + offset
316 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
318 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
321 CacheHit $0, $1 // call or return imp
325 cmpq $$1, cached_sel(%r11)
326 jbe 3f // if (bucket->sel <= 1) wrap or miss
328 addq $$16, %r11 // bucket++
331 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
333 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
336 CacheHit $0, $1 // call or return imp
340 jb LCacheMiss$2 // if (bucket->sel < 1) cache miss
342 movq cached_imp(%r11), %r11 // bucket->imp is really first bucket
345 // Clone scanning loop to miss instead of hang when cache is corrupt.
346 // The slow path may detect any corruption and halt later.
350 cmpq $$1, cached_sel(%r11)
351 jbe 3f // if (bucket->sel <= 1) wrap or miss
353 addq $$16, %r11 // bucket++
356 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
358 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
361 CacheHit $0, $1 // call or return imp
364 // double wrap or miss
371 /////////////////////////////////////////////////////////////////////
373 // MethodTableLookup NORMAL|STRET
375 // Takes: a1 or a2 (STRET) = receiver
376 // a2 or a3 (STRET) = selector to search for
377 // r10 = class to search
379 // On exit: imp in %r11, eq/ne set for forwarding
381 /////////////////////////////////////////////////////////////////////
383 .macro MethodTableLookup
388 sub $$0x80+8, %rsp // +8 for alignment
390 movdqa %xmm0, -0x80(%rbp)
391 push %rax // might be xmm parameter count
392 movdqa %xmm1, -0x70(%rbp)
394 movdqa %xmm2, -0x60(%rbp)
396 movdqa %xmm3, -0x50(%rbp)
398 movdqa %xmm4, -0x40(%rbp)
400 movdqa %xmm5, -0x30(%rbp)
402 movdqa %xmm6, -0x20(%rbp)
404 movdqa %xmm7, -0x10(%rbp)
406 // lookUpImpOrForward(obj, sel, cls, LOOKUP_INITIALIZE | LOOKUP_RESOLVER)
408 // receiver already in a1
409 // selector already in a2
416 call _lookUpImpOrForward
418 // IMP is now in %rax
421 movdqa -0x80(%rbp), %xmm0
423 movdqa -0x70(%rbp), %xmm1
425 movdqa -0x60(%rbp), %xmm2
427 movdqa -0x50(%rbp), %xmm3
429 movdqa -0x40(%rbp), %xmm4
431 movdqa -0x30(%rbp), %xmm5
433 movdqa -0x20(%rbp), %xmm6
435 movdqa -0x10(%rbp), %xmm7
438 test %r11, %r11 // set ne for nonstret forwarding
440 cmp %r11, %r11 // set eq for stret forwarding
448 /////////////////////////////////////////////////////////////////////
450 // GetIsaFast return-type
451 // GetIsaSupport return-type
453 // Sets r10 = obj->isa. Consults the tagged isa table if necessary.
455 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
456 // a1 or a2 (STRET) = receiver
458 // On exit: r10 = receiver->isa
461 /////////////////////////////////////////////////////////////////////
468 movq $$ ISA_MASK, %r10
474 movq $$ ISA_MASK, %r10
489 leaq _objc_debug_taggedpointer_classes(%rip), %r10
490 movq (%r10, %r11, 8), %r10 // read isa from table
491 leaq _OBJC_CLASS_$___NSUnrecognizedTaggedPointer(%rip), %r11
502 leaq _objc_debug_taggedpointer_ext_classes(%rip), %r10
503 movq (%r10, %r11, 8), %r10 // read isa from table
508 /////////////////////////////////////////////////////////////////////
510 // NilTest return-type
512 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
513 // %a1 or %a2 (STRET) = receiver
515 // On exit: Loads non-nil receiver in %a1 or %a2 (STRET)
518 // NilTestReturnZero return-type
520 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
521 // %a1 or %a2 (STRET) = receiver
523 // On exit: Loads non-nil receiver in %a1 or %a2 (STRET)
526 // NilTestReturnIMP return-type
528 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
529 // %a1 or %a2 (STRET) = receiver
531 // On exit: Loads non-nil receiver in %a1 or %a2 (STRET)
532 // or returns an IMP in r11 that returns zero.
534 /////////////////////////////////////////////////////////////////////
543 .macro ZeroReturnFPRET
548 .macro ZeroReturnFP2RET
554 .macro ZeroReturnSTRET
555 // rax gets the struct-return address as passed in rdi
559 STATIC_ENTRY __objc_msgNil
562 END_ENTRY __objc_msgNil
564 STATIC_ENTRY __objc_msgNil_fpret
567 END_ENTRY __objc_msgNil_fpret
569 STATIC_ENTRY __objc_msgNil_fp2ret
572 END_ENTRY __objc_msgNil_fp2ret
574 STATIC_ENTRY __objc_msgNil_stret
577 END_ENTRY __objc_msgNil_stret
591 .macro NilTestReturnZero
610 .macro NilTestReturnIMP
615 leaq __objc_msgNil(%rip), %r11
617 leaq __objc_msgNil_fpret(%rip), %r11
619 leaq __objc_msgNil_fp2ret(%rip), %r11
621 leaq __objc_msgNil_stret(%rip), %r11
629 /********************************************************************
630 * IMP cache_getImp(Class cls, SEL sel)
632 * On entry: a1 = class whose cache is to be searched
633 * a2 = selector to search for
635 * If found, returns method implementation.
636 * If not found, returns NULL.
637 ********************************************************************/
639 STATIC_ENTRY _cache_getImp
642 movq %a1, %r10 // move class to r10 for CacheLookup
643 // returns IMP on success
644 CacheLookup NORMAL, GETIMP, _cache_getImp
646 LCacheMiss_cache_getImp:
647 // cache miss, return nil
651 END_ENTRY _cache_getImp
654 /********************************************************************
656 * id objc_msgSend(id self, SEL _cmd,...);
657 * IMP objc_msgLookup(id self, SEL _cmd, ...);
659 * objc_msgLookup ABI:
660 * IMP returned in r11
661 * Forwarding returned in Z flag
662 * r10 reserved for our use but not used
664 ********************************************************************/
668 .globl _objc_debug_taggedpointer_classes
669 _objc_debug_taggedpointer_classes:
671 .globl _objc_debug_taggedpointer_ext_classes
672 _objc_debug_taggedpointer_ext_classes:
676 UNWIND _objc_msgSend, NoFrame
680 GetIsaFast NORMAL // r10 = self->isa
681 // calls IMP on success
682 CacheLookup NORMAL, CALL, _objc_msgSend
684 NilTestReturnZero NORMAL
688 // cache miss: go search the method lists
689 LCacheMiss_objc_msgSend:
691 jmp __objc_msgSend_uncached
693 END_ENTRY _objc_msgSend
696 ENTRY _objc_msgLookup
700 GetIsaFast NORMAL // r10 = self->isa
701 // returns IMP on success
702 CacheLookup NORMAL, LOOKUP, _objc_msgLookup
704 NilTestReturnIMP NORMAL
708 // cache miss: go search the method lists
709 LCacheMiss_objc_msgLookup:
711 jmp __objc_msgLookup_uncached
713 END_ENTRY _objc_msgLookup
716 ENTRY _objc_msgSend_fixup
718 END_ENTRY _objc_msgSend_fixup
721 STATIC_ENTRY _objc_msgSend_fixedup
722 // Load _cmd from the message_ref
725 END_ENTRY _objc_msgSend_fixedup
728 /********************************************************************
730 * id objc_msgSendSuper(struct objc_super *super, SEL _cmd,...);
732 * struct objc_super {
736 ********************************************************************/
738 ENTRY _objc_msgSendSuper
739 UNWIND _objc_msgSendSuper, NoFrame
741 // search the cache (objc_super in %a1)
742 movq class(%a1), %r10 // class = objc_super->class
743 movq receiver(%a1), %a1 // load real receiver
744 // calls IMP on success
745 CacheLookup NORMAL, CALL, _objc_msgSendSuper
747 // cache miss: go search the method lists
748 LCacheMiss_objc_msgSendSuper:
749 // class still in r10
750 jmp __objc_msgSend_uncached
752 END_ENTRY _objc_msgSendSuper
755 /********************************************************************
756 * id objc_msgSendSuper2
757 ********************************************************************/
759 ENTRY _objc_msgSendSuper2
760 UNWIND _objc_msgSendSuper2, NoFrame
762 // objc_super->class is superclass of class to search
764 // search the cache (objc_super in %a1)
765 movq class(%a1), %r10 // cls = objc_super->class
766 movq receiver(%a1), %a1 // load real receiver
767 movq 8(%r10), %r10 // cls = class->superclass
768 // calls IMP on success
769 CacheLookup NORMAL, CALL, _objc_msgSendSuper2
771 // cache miss: go search the method lists
772 LCacheMiss_objc_msgSendSuper2:
773 // superclass still in r10
774 jmp __objc_msgSend_uncached
776 END_ENTRY _objc_msgSendSuper2
779 ENTRY _objc_msgLookupSuper2
781 // objc_super->class is superclass of class to search
783 // search the cache (objc_super in %a1)
784 movq class(%a1), %r10 // cls = objc_super->class
785 movq receiver(%a1), %a1 // load real receiver
786 movq 8(%r10), %r10 // cls = class->superclass
787 // returns IMP on success
788 CacheLookup NORMAL, LOOKUP, _objc_msgLookupSuper2
790 // cache miss: go search the method lists
791 LCacheMiss_objc_msgLookupSuper2:
792 // superclass still in r10
793 jmp __objc_msgLookup_uncached
795 END_ENTRY _objc_msgLookupSuper2
798 ENTRY _objc_msgSendSuper2_fixup
800 END_ENTRY _objc_msgSendSuper2_fixup
803 STATIC_ENTRY _objc_msgSendSuper2_fixedup
804 // Load _cmd from the message_ref
806 jmp _objc_msgSendSuper2
807 END_ENTRY _objc_msgSendSuper2_fixedup
810 /********************************************************************
812 * double objc_msgSend_fpret(id self, SEL _cmd,...);
813 * Used for `long double` return only. `float` and `double` use objc_msgSend.
815 ********************************************************************/
817 ENTRY _objc_msgSend_fpret
818 UNWIND _objc_msgSend_fpret, NoFrame
822 GetIsaFast FPRET // r10 = self->isa
823 // calls IMP on success
824 CacheLookup FPRET, CALL, _objc_msgSend_fpret
826 NilTestReturnZero FPRET
830 // cache miss: go search the method lists
831 LCacheMiss_objc_msgSend_fpret:
833 jmp __objc_msgSend_uncached
835 END_ENTRY _objc_msgSend_fpret
838 ENTRY _objc_msgLookup_fpret
842 GetIsaFast FPRET // r10 = self->isa
843 // returns IMP on success
844 CacheLookup FPRET, LOOKUP, _objc_msgLookup_fpret
846 NilTestReturnIMP FPRET
850 // cache miss: go search the method lists
851 LCacheMiss_objc_msgLookup_fpret:
853 jmp __objc_msgLookup_uncached
855 END_ENTRY _objc_msgLookup_fpret
858 ENTRY _objc_msgSend_fpret_fixup
860 END_ENTRY _objc_msgSend_fpret_fixup
863 STATIC_ENTRY _objc_msgSend_fpret_fixedup
864 // Load _cmd from the message_ref
866 jmp _objc_msgSend_fpret
867 END_ENTRY _objc_msgSend_fpret_fixedup
870 /********************************************************************
872 * double objc_msgSend_fp2ret(id self, SEL _cmd,...);
873 * Used for `complex long double` return only.
875 ********************************************************************/
877 ENTRY _objc_msgSend_fp2ret
878 UNWIND _objc_msgSend_fp2ret, NoFrame
882 GetIsaFast FP2RET // r10 = self->isa
883 // calls IMP on success
884 CacheLookup FP2RET, CALL, _objc_msgSend_fp2ret
886 NilTestReturnZero FP2RET
890 // cache miss: go search the method lists
891 LCacheMiss_objc_msgSend_fp2ret:
893 jmp __objc_msgSend_uncached
895 END_ENTRY _objc_msgSend_fp2ret
898 ENTRY _objc_msgLookup_fp2ret
902 GetIsaFast FP2RET // r10 = self->isa
903 // returns IMP on success
904 CacheLookup FP2RET, LOOKUP, _objc_msgLookup_fp2ret
906 NilTestReturnIMP FP2RET
910 // cache miss: go search the method lists
911 LCacheMiss_objc_msgLookup_fp2ret:
913 jmp __objc_msgLookup_uncached
915 END_ENTRY _objc_msgLookup_fp2ret
918 ENTRY _objc_msgSend_fp2ret_fixup
920 END_ENTRY _objc_msgSend_fp2ret_fixup
923 STATIC_ENTRY _objc_msgSend_fp2ret_fixedup
924 // Load _cmd from the message_ref
926 jmp _objc_msgSend_fp2ret
927 END_ENTRY _objc_msgSend_fp2ret_fixedup
930 /********************************************************************
932 * void objc_msgSend_stret(void *st_addr, id self, SEL _cmd, ...);
934 * objc_msgSend_stret is the struct-return form of msgSend.
935 * The ABI calls for %a1 to be used as the address of the structure
936 * being returned, with the parameters in the succeeding locations.
938 * On entry: %a1 is the address where the structure is returned,
939 * %a2 is the message receiver,
940 * %a3 is the selector
941 ********************************************************************/
943 ENTRY _objc_msgSend_stret
944 UNWIND _objc_msgSend_stret, NoFrame
948 GetIsaFast STRET // r10 = self->isa
949 // calls IMP on success
950 CacheLookup STRET, CALL, _objc_msgSend_stret
952 NilTestReturnZero STRET
956 // cache miss: go search the method lists
957 LCacheMiss_objc_msgSend_stret:
959 jmp __objc_msgSend_stret_uncached
961 END_ENTRY _objc_msgSend_stret
964 ENTRY _objc_msgLookup_stret
968 GetIsaFast STRET // r10 = self->isa
969 // returns IMP on success
970 CacheLookup STRET, LOOKUP, _objc_msgLookup_stret
972 NilTestReturnIMP STRET
976 // cache miss: go search the method lists
977 LCacheMiss_objc_msgLookup_stret:
979 jmp __objc_msgLookup_stret_uncached
981 END_ENTRY _objc_msgLookup_stret
984 ENTRY _objc_msgSend_stret_fixup
986 END_ENTRY _objc_msgSend_stret_fixup
989 STATIC_ENTRY _objc_msgSend_stret_fixedup
990 // Load _cmd from the message_ref
992 jmp _objc_msgSend_stret
993 END_ENTRY _objc_msgSend_stret_fixedup
996 /********************************************************************
998 * void objc_msgSendSuper_stret(void *st_addr, struct objc_super *super, SEL _cmd, ...);
1000 * struct objc_super {
1005 * objc_msgSendSuper_stret is the struct-return form of msgSendSuper.
1006 * The ABI calls for (sp+4) to be used as the address of the structure
1007 * being returned, with the parameters in the succeeding registers.
1009 * On entry: %a1 is the address where the structure is returned,
1010 * %a2 is the address of the objc_super structure,
1011 * %a3 is the selector
1013 ********************************************************************/
1015 ENTRY _objc_msgSendSuper_stret
1016 UNWIND _objc_msgSendSuper_stret, NoFrame
1018 // search the cache (objc_super in %a2)
1019 movq class(%a2), %r10 // class = objc_super->class
1020 movq receiver(%a2), %a2 // load real receiver
1021 // calls IMP on success
1022 CacheLookup STRET, CALL, _objc_msgSendSuper_stret
1024 // cache miss: go search the method lists
1025 LCacheMiss_objc_msgSendSuper_stret:
1026 // class still in r10
1027 jmp __objc_msgSend_stret_uncached
1029 END_ENTRY _objc_msgSendSuper_stret
1032 /********************************************************************
1033 * id objc_msgSendSuper2_stret
1034 ********************************************************************/
1036 ENTRY _objc_msgSendSuper2_stret
1037 UNWIND _objc_msgSendSuper2_stret, NoFrame
1039 // search the cache (objc_super in %a2)
1040 movq class(%a2), %r10 // class = objc_super->class
1041 movq receiver(%a2), %a2 // load real receiver
1042 movq 8(%r10), %r10 // class = class->superclass
1043 // calls IMP on success
1044 CacheLookup STRET, CALL, _objc_msgSendSuper2_stret
1046 // cache miss: go search the method lists
1047 LCacheMiss_objc_msgSendSuper2_stret:
1048 // superclass still in r10
1049 jmp __objc_msgSend_stret_uncached
1051 END_ENTRY _objc_msgSendSuper2_stret
1054 ENTRY _objc_msgLookupSuper2_stret
1056 // search the cache (objc_super in %a2)
1057 movq class(%a2), %r10 // class = objc_super->class
1058 movq receiver(%a2), %a2 // load real receiver
1059 movq 8(%r10), %r10 // class = class->superclass
1060 // returns IMP on success
1061 CacheLookup STRET, LOOKUP, _objc_msgLookupSuper2_stret
1063 // cache miss: go search the method lists
1064 LCacheMiss_objc_msgLookupSuper2_stret:
1065 // superclass still in r10
1066 jmp __objc_msgLookup_stret_uncached
1068 END_ENTRY _objc_msgLookupSuper2_stret
1071 ENTRY _objc_msgSendSuper2_stret_fixup
1073 END_ENTRY _objc_msgSendSuper2_stret_fixup
1076 STATIC_ENTRY _objc_msgSendSuper2_stret_fixedup
1077 // Load _cmd from the message_ref
1079 jmp _objc_msgSendSuper2_stret
1080 END_ENTRY _objc_msgSendSuper2_stret_fixedup
1083 /********************************************************************
1085 * _objc_msgSend_uncached
1086 * _objc_msgSend_stret_uncached
1087 * _objc_msgLookup_uncached
1088 * _objc_msgLookup_stret_uncached
1090 * The uncached method lookup.
1092 ********************************************************************/
1094 STATIC_ENTRY __objc_msgSend_uncached
1095 UNWIND __objc_msgSend_uncached, FrameWithNoSaves
1097 // THIS IS NOT A CALLABLE C FUNCTION
1098 // Out-of-band r10 is the searched class
1100 // r10 is already the class to search
1101 MethodTableLookup NORMAL // r11 = IMP
1102 jmp *%r11 // goto *imp
1104 END_ENTRY __objc_msgSend_uncached
1107 STATIC_ENTRY __objc_msgSend_stret_uncached
1108 UNWIND __objc_msgSend_stret_uncached, FrameWithNoSaves
1110 // THIS IS NOT A CALLABLE C FUNCTION
1111 // Out-of-band r10 is the searched class
1113 // r10 is already the class to search
1114 MethodTableLookup STRET // r11 = IMP
1115 jmp *%r11 // goto *imp
1117 END_ENTRY __objc_msgSend_stret_uncached
1120 STATIC_ENTRY __objc_msgLookup_uncached
1121 UNWIND __objc_msgLookup_uncached, FrameWithNoSaves
1123 // THIS IS NOT A CALLABLE C FUNCTION
1124 // Out-of-band r10 is the searched class
1126 // r10 is already the class to search
1127 MethodTableLookup NORMAL // r11 = IMP
1130 END_ENTRY __objc_msgLookup_uncached
1133 STATIC_ENTRY __objc_msgLookup_stret_uncached
1134 UNWIND __objc_msgLookup_stret_uncached, FrameWithNoSaves
1136 // THIS IS NOT A CALLABLE C FUNCTION
1137 // Out-of-band r10 is the searched class
1139 // r10 is already the class to search
1140 MethodTableLookup STRET // r11 = IMP
1143 END_ENTRY __objc_msgLookup_stret_uncached
1146 /********************************************************************
1148 * id _objc_msgForward(id self, SEL _cmd,...);
1150 * _objc_msgForward and _objc_msgForward_stret are the externally-callable
1151 * functions returned by things like method_getImplementation().
1152 * _objc_msgForward_impcache is the function pointer actually stored in
1155 ********************************************************************/
1157 STATIC_ENTRY __objc_msgForward_impcache
1158 // Method cache version
1160 // THIS IS NOT A CALLABLE C FUNCTION
1161 // Out-of-band condition register is NE for stret, EQ otherwise.
1163 je __objc_msgForward_stret
1164 jmp __objc_msgForward
1166 END_ENTRY __objc_msgForward_impcache
1169 ENTRY __objc_msgForward
1170 // Non-stret version
1172 movq __objc_forward_handler(%rip), %r11
1175 END_ENTRY __objc_msgForward
1178 ENTRY __objc_msgForward_stret
1179 // Struct-return version
1181 movq __objc_forward_stret_handler(%rip), %r11
1184 END_ENTRY __objc_msgForward_stret
1187 ENTRY _objc_msgSend_debug
1189 END_ENTRY _objc_msgSend_debug
1191 ENTRY _objc_msgSendSuper2_debug
1192 jmp _objc_msgSendSuper2
1193 END_ENTRY _objc_msgSendSuper2_debug
1195 ENTRY _objc_msgSend_stret_debug
1196 jmp _objc_msgSend_stret
1197 END_ENTRY _objc_msgSend_stret_debug
1199 ENTRY _objc_msgSendSuper2_stret_debug
1200 jmp _objc_msgSendSuper2_stret
1201 END_ENTRY _objc_msgSendSuper2_stret_debug
1203 ENTRY _objc_msgSend_fpret_debug
1204 jmp _objc_msgSend_fpret
1205 END_ENTRY _objc_msgSend_fpret_debug
1207 ENTRY _objc_msgSend_fp2ret_debug
1208 jmp _objc_msgSend_fp2ret
1209 END_ENTRY _objc_msgSend_fp2ret_debug
1212 ENTRY _objc_msgSend_noarg
1214 END_ENTRY _objc_msgSend_noarg
1217 ENTRY _method_invoke
1219 movq method_imp(%a2), %r11
1220 movq method_name(%a2), %a2
1223 END_ENTRY _method_invoke
1226 ENTRY _method_invoke_stret
1228 movq method_imp(%a3), %r11
1229 movq method_name(%a3), %a3
1232 END_ENTRY _method_invoke_stret
1235 .section __DATA,__objc_msg_break