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
27 /********************************************************************
28 ********************************************************************
30 ** objc-msg-x86_64.s - x86-64 code to support objc messaging.
32 ********************************************************************
33 ********************************************************************/
37 // _objc_restartableRanges is used by method dispatch
38 // to get the critical regions for which method caches
39 // cannot be garbage collected.
41 .macro RestartableEntry
44 .short 0xffff // The simulator doesn't support kernel based recovery
49 .private_extern _objc_restartableRanges
50 _objc_restartableRanges:
51 RestartableEntry _cache_getImp
52 RestartableEntry _objc_msgSend
53 RestartableEntry _objc_msgSend_fpret
54 RestartableEntry _objc_msgSend_fp2ret
55 RestartableEntry _objc_msgSend_stret
56 RestartableEntry _objc_msgSendSuper
57 RestartableEntry _objc_msgSendSuper_stret
58 RestartableEntry _objc_msgSendSuper2
59 RestartableEntry _objc_msgSendSuper2_stret
60 RestartableEntry _objc_msgLookup
61 RestartableEntry _objc_msgLookup_fpret
62 RestartableEntry _objc_msgLookup_fp2ret
63 RestartableEntry _objc_msgLookup_stret
64 RestartableEntry _objc_msgLookupSuper2
65 RestartableEntry _objc_msgLookupSuper2_stret
69 /********************************************************************
70 * Recommended multi-byte NOP instructions
71 * (Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2B)
72 ********************************************************************/
73 #define nop1 .byte 0x90
74 #define nop2 .byte 0x66,0x90
75 #define nop3 .byte 0x0F,0x1F,0x00
76 #define nop4 .byte 0x0F,0x1F,0x40,0x00
77 #define nop5 .byte 0x0F,0x1F,0x44,0x00,0x00
78 #define nop6 .byte 0x66,0x0F,0x1F,0x44,0x00,0x00
79 #define nop7 .byte 0x0F,0x1F,0x80,0x00,0x00,0x00,0x00
80 #define nop8 .byte 0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
81 #define nop9 .byte 0x66,0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
84 /********************************************************************
85 * Names for parameter registers.
86 ********************************************************************/
104 /********************************************************************
105 * Names for relative labels
106 * DO NOT USE THESE LABELS ELSEWHERE
107 * Reserved labels: 6: 7: 8: 9:
108 ********************************************************************/
110 #define LCacheMiss_f 6f
111 #define LCacheMiss_b 6b
112 #define LGetIsaDone 7
113 #define LGetIsaDone_f 7f
114 #define LGetIsaDone_b 7b
115 #define LNilOrTagged 8
116 #define LNilOrTagged_f 8f
117 #define LNilOrTagged_b 8b
122 /********************************************************************
124 ********************************************************************/
136 /********************************************************************
138 * Structure definitions.
140 ********************************************************************/
142 // objc_super parameter to sendSuper
146 // Selected field offsets in class structure
147 // #define isa 0 USE GetIsa INSTEAD
150 #define method_name 0
151 #define method_imp 16
158 //////////////////////////////////////////////////////////////////////
160 // ENTRY functionName
162 // Assembly directives to begin an exported function.
164 // Takes: functionName - name of the exported function
165 //////////////////////////////////////////////////////////////////////
181 //////////////////////////////////////////////////////////////////////
183 // END_ENTRY functionName
185 // Assembly directives to end an exported function. Just a placeholder,
186 // a close-parenthesis for ENTRY, until it is needed for something.
188 // Takes: functionName - name of the exported function
189 //////////////////////////////////////////////////////////////////////
196 /********************************************************************
198 * Unwind info generation
199 ********************************************************************/
201 .section __LD,__compact_unwind,regular,debug
203 .set LUnwind$0, LExit$0 - $0
206 .quad 0 /* no personality */
207 .quad 0 /* no LSDA */
211 #define NoFrame 0x02010000 // no frame, no SP adjustment except return address
212 #define FrameWithNoSaves 0x01000000 // frame, no non-volatile saves
215 /////////////////////////////////////////////////////////////////////
217 // CacheLookup return-type, caller
219 // Locate the implementation for a class in a selector's method cache.
222 // $0 = NORMAL, FPRET, FP2RET, STRET
223 // $1 = CALL, LOOKUP, GETIMP
224 // a1 or a2 (STRET) = receiver
225 // a2 or a3 (STRET) = selector
226 // r10 = class to search
228 // On exit: r10 clobbered
229 // (found) calls or returns IMP in r11, eq/ne set for forwarding
230 // (not found) jumps to LCacheMiss, class still in r10
232 /////////////////////////////////////////////////////////////////////
236 // r11 = found bucket
239 movq cached_imp(%r11), %rax // return imp
241 jz 9f // don't xor a nil imp
242 xorq %r10, %rax // xor the isa with the imp
248 movq cached_imp(%r11), %r11 // load imp
249 xorq %r10, %r11 // xor imp and isa
251 // ne already set for forwarding by `xor`
253 cmp %r11, %r11 // set eq for stret forwarding
255 jmp *%r11 // call imp
258 movq cached_imp(%r11), %r11
259 xorq %r10, %r11 // return imp ^ isa
273 movq %a2, %r11 // r11 = _cmd
275 movq %a3, %r11 // r11 = _cmd
277 andl 24(%r10), %r11d // r11 = _cmd & class->cache.mask
278 shlq $$4, %r11 // r11 = offset = (_cmd & mask)<<4
279 addq 16(%r10), %r11 // r11 = class->cache.buckets + offset
282 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
284 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
287 CacheHit $0, $1 // call or return imp
291 cmpq $$1, cached_sel(%r11)
292 jbe 3f // if (bucket->sel <= 1) wrap or miss
294 addq $$16, %r11 // bucket++
297 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
299 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
302 CacheHit $0, $1 // call or return imp
306 jb LCacheMiss_f // if (bucket->sel < 1) cache miss
308 movq cached_imp(%r11), %r11 // bucket->imp is really first bucket
311 // Clone scanning loop to miss instead of hang when cache is corrupt.
312 // The slow path may detect any corruption and halt later.
316 cmpq $$1, cached_sel(%r11)
317 jbe 3f // if (bucket->sel <= 1) wrap or miss
319 addq $$16, %r11 // bucket++
322 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
324 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
327 CacheHit $0, $1 // call or return imp
330 // double wrap or miss
336 /////////////////////////////////////////////////////////////////////
338 // MethodTableLookup NORMAL|STRET
340 // Takes: a1 or a2 (STRET) = receiver
341 // a2 or a3 (STRET) = selector to search for
342 // r10 = class to search
344 // On exit: imp in %r11, eq/ne set for forwarding
346 /////////////////////////////////////////////////////////////////////
348 .macro MethodTableLookup
353 sub $$0x80+8, %rsp // +8 for alignment
355 movdqa %xmm0, -0x80(%rbp)
356 push %rax // might be xmm parameter count
357 movdqa %xmm1, -0x70(%rbp)
359 movdqa %xmm2, -0x60(%rbp)
361 movdqa %xmm3, -0x50(%rbp)
363 movdqa %xmm4, -0x40(%rbp)
365 movdqa %xmm5, -0x30(%rbp)
367 movdqa %xmm6, -0x20(%rbp)
369 movdqa %xmm7, -0x10(%rbp)
371 // lookUpImpOrForward(obj, sel, cls, LOOKUP_INITIALIZE | LOOKUP_RESOLVER)
373 // receiver already in a1
374 // selector already in a2
381 call _lookUpImpOrForward
383 // IMP is now in %rax
386 movdqa -0x80(%rbp), %xmm0
388 movdqa -0x70(%rbp), %xmm1
390 movdqa -0x60(%rbp), %xmm2
392 movdqa -0x50(%rbp), %xmm3
394 movdqa -0x40(%rbp), %xmm4
396 movdqa -0x30(%rbp), %xmm5
398 movdqa -0x20(%rbp), %xmm6
400 movdqa -0x10(%rbp), %xmm7
403 test %r11, %r11 // set ne for stret forwarding
405 cmp %r11, %r11 // set eq for nonstret forwarding
413 /////////////////////////////////////////////////////////////////////
415 // GetIsaCheckNil return-type
416 // GetIsaSupport return-type
417 // NilTestReturnZero return-type
418 // NilTestReturnIMP return-type
420 // Sets r10 = obj->isa.
421 // Looks up the real class if receiver is a tagged pointer object.
422 // Returns zero or a zero-returning IMP if obj is nil.
424 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
425 // a1 or a2 (STRET) = receiver
427 // On exit from GetIsaCheckNil:
428 // r10 = receiver->isa
431 /////////////////////////////////////////////////////////////////////
440 .macro ZeroReturnFPRET
445 .macro ZeroReturnFP2RET
451 .macro ZeroReturnSTRET
452 // rax gets the struct-return address as passed in rdi
456 STATIC_ENTRY __objc_msgNil
459 END_ENTRY __objc_msgNil
461 STATIC_ENTRY __objc_msgNil_fpret
464 END_ENTRY __objc_msgNil_fpret
466 STATIC_ENTRY __objc_msgNil_fp2ret
469 END_ENTRY __objc_msgNil_fp2ret
471 STATIC_ENTRY __objc_msgNil_stret
474 END_ENTRY __objc_msgNil_stret
477 .macro GetIsaCheckNil
483 jle LNilOrTagged_f // MSB tagged pointer looks negative
486 movq (%a1), %r10 // r10 = isa
488 movq (%a2), %r10 // r10 = isa
498 jz LNil_f // flags set by GetIsaCheckNil
506 leaq _objc_debug_taggedpointer_classes(%rip), %r10
507 movq (%r10, %r11, 8), %r10 // read isa from table
508 leaq _OBJC_CLASS_$___NSUnrecognizedTaggedPointer(%rip), %r11
519 leaq _objc_debug_taggedpointer_ext_classes(%rip), %r10
520 movq (%r10, %r11, 8), %r10 // read isa from table
525 .macro NilTestReturnZero
542 .macro NilTestReturnIMP
545 leaq __objc_msgNil(%rip), %r11
547 leaq __objc_msgNil_fpret(%rip), %r11
549 leaq __objc_msgNil_fp2ret(%rip), %r11
551 leaq __objc_msgNil_stret(%rip), %r11
559 /********************************************************************
560 * IMP cache_getImp(Class cls, SEL sel)
562 * On entry: a1 = class whose cache is to be searched
563 * a2 = selector to search for
565 * If found, returns method implementation.
566 * If not found, returns NULL.
567 ********************************************************************/
569 STATIC_ENTRY _cache_getImp
572 movq %a1, %r10 // move class to r10 for CacheLookup
573 CacheLookup NORMAL, GETIMP // returns IMP on success
576 // cache miss, return nil
580 END_ENTRY _cache_getImp
583 /********************************************************************
585 * id objc_msgSend(id self, SEL _cmd,...);
586 * IMP objc_msgLookup(id self, SEL _cmd, ...);
588 * objc_msgLookup ABI:
589 * IMP returned in r11
590 * Forwarding returned in Z flag
591 * r10 reserved for our use but not used
593 ********************************************************************/
597 .globl _objc_debug_taggedpointer_classes
598 _objc_debug_taggedpointer_classes:
600 .globl _objc_debug_taggedpointer_ext_classes
601 _objc_debug_taggedpointer_ext_classes:
605 UNWIND _objc_msgSend, NoFrame
607 GetIsaCheckNil NORMAL // r10 = self->isa, or return zero
608 CacheLookup NORMAL, CALL // calls IMP on success
611 NilTestReturnZero NORMAL
613 // cache miss: go search the method lists
616 jmp __objc_msgSend_uncached
618 END_ENTRY _objc_msgSend
621 ENTRY _objc_msgLookup
623 GetIsaCheckNil NORMAL // r10 = self->isa, or return zero IMP
624 CacheLookup NORMAL, LOOKUP // returns IMP on success
627 NilTestReturnIMP NORMAL
629 // cache miss: go search the method lists
632 jmp __objc_msgLookup_uncached
634 END_ENTRY _objc_msgLookup
637 ENTRY _objc_msgSend_fixup
639 END_ENTRY _objc_msgSend_fixup
642 STATIC_ENTRY _objc_msgSend_fixedup
643 // Load _cmd from the message_ref
646 END_ENTRY _objc_msgSend_fixedup
649 /********************************************************************
651 * id objc_msgSendSuper(struct objc_super *super, SEL _cmd,...);
653 * struct objc_super {
657 ********************************************************************/
659 ENTRY _objc_msgSendSuper
660 UNWIND _objc_msgSendSuper, NoFrame
662 // search the cache (objc_super in %a1)
663 movq class(%a1), %r10 // class = objc_super->class
664 movq receiver(%a1), %a1 // load real receiver
665 CacheLookup NORMAL, CALL // calls IMP on success
667 // cache miss: go search the method lists
669 // class still in r10
670 jmp __objc_msgSend_uncached
672 END_ENTRY _objc_msgSendSuper
675 /********************************************************************
676 * id objc_msgSendSuper2
677 ********************************************************************/
679 ENTRY _objc_msgSendSuper2
680 UNWIND _objc_msgSendSuper2, NoFrame
682 // objc_super->class is superclass of class to search
684 // search the cache (objc_super in %a1)
685 movq class(%a1), %r10 // cls = objc_super->class
686 movq receiver(%a1), %a1 // load real receiver
687 movq 8(%r10), %r10 // cls = class->superclass
688 CacheLookup NORMAL, CALL // calls IMP on success
690 // cache miss: go search the method lists
692 // superclass still in r10
693 jmp __objc_msgSend_uncached
695 END_ENTRY _objc_msgSendSuper2
698 ENTRY _objc_msgLookupSuper2
700 // objc_super->class is superclass of class to search
702 // search the cache (objc_super in %a1)
703 movq class(%a1), %r10 // cls = objc_super->class
704 movq receiver(%a1), %a1 // load real receiver
705 movq 8(%r10), %r10 // cls = class->superclass
706 CacheLookup NORMAL, LOOKUP // returns IMP on success
708 // cache miss: go search the method lists
710 // superclass still in r10
711 jmp __objc_msgLookup_uncached
713 END_ENTRY _objc_msgLookupSuper2
716 ENTRY _objc_msgSendSuper2_fixup
718 END_ENTRY _objc_msgSendSuper2_fixup
721 STATIC_ENTRY _objc_msgSendSuper2_fixedup
722 // Load _cmd from the message_ref
724 jmp _objc_msgSendSuper2
725 END_ENTRY _objc_msgSendSuper2_fixedup
728 /********************************************************************
730 * double objc_msgSend_fpret(id self, SEL _cmd,...);
731 * Used for `long double` return only. `float` and `double` use objc_msgSend.
733 ********************************************************************/
735 ENTRY _objc_msgSend_fpret
736 UNWIND _objc_msgSend_fpret, NoFrame
738 GetIsaCheckNil FPRET // r10 = self->isa, or return zero
739 CacheLookup FPRET, CALL // calls IMP on success
742 NilTestReturnZero FPRET
744 // cache miss: go search the method lists
747 jmp __objc_msgSend_uncached
749 END_ENTRY _objc_msgSend_fpret
752 ENTRY _objc_msgLookup_fpret
754 GetIsaCheckNil FPRET // r10 = self->isa, or return zero IMP
755 CacheLookup FPRET, LOOKUP // returns IMP on success
758 NilTestReturnIMP FPRET
760 // cache miss: go search the method lists
763 jmp __objc_msgLookup_uncached
765 END_ENTRY _objc_msgLookup_fpret
768 ENTRY _objc_msgSend_fpret_fixup
770 END_ENTRY _objc_msgSend_fpret_fixup
773 STATIC_ENTRY _objc_msgSend_fpret_fixedup
774 // Load _cmd from the message_ref
776 jmp _objc_msgSend_fpret
777 END_ENTRY _objc_msgSend_fpret_fixedup
780 /********************************************************************
782 * double objc_msgSend_fp2ret(id self, SEL _cmd,...);
783 * Used for `complex long double` return only.
785 ********************************************************************/
787 ENTRY _objc_msgSend_fp2ret
788 UNWIND _objc_msgSend_fp2ret, NoFrame
790 GetIsaCheckNil FP2RET // r10 = self->isa, or return zero
791 CacheLookup FP2RET, CALL // calls IMP on success
794 NilTestReturnZero FP2RET
796 // cache miss: go search the method lists
799 jmp __objc_msgSend_uncached
801 END_ENTRY _objc_msgSend_fp2ret
804 ENTRY _objc_msgLookup_fp2ret
806 GetIsaCheckNil FP2RET // r10 = self->isa, or return zero IMP
807 CacheLookup FP2RET, LOOKUP // returns IMP on success
810 NilTestReturnIMP FP2RET
812 // cache miss: go search the method lists
815 jmp __objc_msgLookup_uncached
817 END_ENTRY _objc_msgLookup_fp2ret
820 ENTRY _objc_msgSend_fp2ret_fixup
822 END_ENTRY _objc_msgSend_fp2ret_fixup
825 STATIC_ENTRY _objc_msgSend_fp2ret_fixedup
826 // Load _cmd from the message_ref
828 jmp _objc_msgSend_fp2ret
829 END_ENTRY _objc_msgSend_fp2ret_fixedup
832 /********************************************************************
834 * void objc_msgSend_stret(void *st_addr, id self, SEL _cmd, ...);
836 * objc_msgSend_stret is the struct-return form of msgSend.
837 * The ABI calls for %a1 to be used as the address of the structure
838 * being returned, with the parameters in the succeeding locations.
840 * On entry: %a1 is the address where the structure is returned,
841 * %a2 is the message receiver,
842 * %a3 is the selector
843 ********************************************************************/
845 ENTRY _objc_msgSend_stret
846 UNWIND _objc_msgSend_stret, NoFrame
848 GetIsaCheckNil STRET // r10 = self->isa, or return zero
849 CacheLookup STRET, CALL // calls IMP on success
852 NilTestReturnZero STRET
854 // cache miss: go search the method lists
857 jmp __objc_msgSend_stret_uncached
859 END_ENTRY _objc_msgSend_stret
862 ENTRY _objc_msgLookup_stret
864 GetIsaCheckNil STRET // r10 = self->isa, or return zero IMP
865 CacheLookup STRET, LOOKUP // returns IMP on success
868 NilTestReturnIMP STRET
870 // cache miss: go search the method lists
873 jmp __objc_msgLookup_stret_uncached
875 END_ENTRY _objc_msgLookup_stret
878 ENTRY _objc_msgSend_stret_fixup
880 END_ENTRY _objc_msgSend_stret_fixup
883 STATIC_ENTRY _objc_msgSend_stret_fixedup
884 // Load _cmd from the message_ref
886 jmp _objc_msgSend_stret
887 END_ENTRY _objc_msgSend_stret_fixedup
890 /********************************************************************
892 * void objc_msgSendSuper_stret(void *st_addr, struct objc_super *super, SEL _cmd, ...);
894 * struct objc_super {
899 * objc_msgSendSuper_stret is the struct-return form of msgSendSuper.
900 * The ABI calls for (sp+4) to be used as the address of the structure
901 * being returned, with the parameters in the succeeding registers.
903 * On entry: %a1 is the address where the structure is returned,
904 * %a2 is the address of the objc_super structure,
905 * %a3 is the selector
907 ********************************************************************/
909 ENTRY _objc_msgSendSuper_stret
910 UNWIND _objc_msgSendSuper_stret, NoFrame
912 // search the cache (objc_super in %a2)
913 movq class(%a2), %r10 // class = objc_super->class
914 movq receiver(%a2), %a2 // load real receiver
915 CacheLookup STRET, CALL // calls IMP on success
917 // cache miss: go search the method lists
919 // class still in r10
920 jmp __objc_msgSend_stret_uncached
922 END_ENTRY _objc_msgSendSuper_stret
925 /********************************************************************
926 * id objc_msgSendSuper2_stret
927 ********************************************************************/
929 ENTRY _objc_msgSendSuper2_stret
930 UNWIND _objc_msgSendSuper2_stret, NoFrame
932 // search the cache (objc_super in %a2)
933 movq class(%a2), %r10 // class = objc_super->class
934 movq receiver(%a2), %a2 // load real receiver
935 movq 8(%r10), %r10 // class = class->superclass
936 CacheLookup STRET, CALL // calls IMP on success
938 // cache miss: go search the method lists
940 // superclass still in r10
941 jmp __objc_msgSend_stret_uncached
943 END_ENTRY _objc_msgSendSuper2_stret
946 ENTRY _objc_msgLookupSuper2_stret
948 // search the cache (objc_super in %a2)
949 movq class(%a2), %r10 // class = objc_super->class
950 movq receiver(%a2), %a2 // load real receiver
951 movq 8(%r10), %r10 // class = class->superclass
952 CacheLookup STRET, LOOKUP // returns IMP on success
954 // cache miss: go search the method lists
956 // superclass still in r10
957 jmp __objc_msgLookup_stret_uncached
959 END_ENTRY _objc_msgLookupSuper2_stret
962 ENTRY _objc_msgSendSuper2_stret_fixup
964 END_ENTRY _objc_msgSendSuper2_stret_fixup
967 STATIC_ENTRY _objc_msgSendSuper2_stret_fixedup
968 // Load _cmd from the message_ref
970 jmp _objc_msgSendSuper2_stret
971 END_ENTRY _objc_msgSendSuper2_stret_fixedup
974 /********************************************************************
976 * _objc_msgSend_uncached
977 * _objc_msgSend_stret_uncached
978 * The uncached method lookup.
980 ********************************************************************/
982 STATIC_ENTRY __objc_msgSend_uncached
983 UNWIND __objc_msgSend_uncached, FrameWithNoSaves
985 // THIS IS NOT A CALLABLE C FUNCTION
986 // Out-of-band r10 is the searched class
988 // r10 is already the class to search
989 MethodTableLookup NORMAL // r11 = IMP
990 jmp *%r11 // goto *imp
992 END_ENTRY __objc_msgSend_uncached
995 STATIC_ENTRY __objc_msgSend_stret_uncached
996 UNWIND __objc_msgSend_stret_uncached, FrameWithNoSaves
998 // THIS IS NOT A CALLABLE C FUNCTION
999 // Out-of-band r10 is the searched class
1001 // r10 is already the class to search
1002 MethodTableLookup STRET // r11 = IMP
1003 jmp *%r11 // goto *imp
1005 END_ENTRY __objc_msgSend_stret_uncached
1008 STATIC_ENTRY __objc_msgLookup_uncached
1009 UNWIND __objc_msgLookup_uncached, FrameWithNoSaves
1011 // THIS IS NOT A CALLABLE C FUNCTION
1012 // Out-of-band r10 is the searched class
1014 // r10 is already the class to search
1015 MethodTableLookup NORMAL // r11 = IMP
1018 END_ENTRY __objc_msgLookup_uncached
1021 STATIC_ENTRY __objc_msgLookup_stret_uncached
1022 UNWIND __objc_msgLookup_stret_uncached, FrameWithNoSaves
1024 // THIS IS NOT A CALLABLE C FUNCTION
1025 // Out-of-band r10 is the searched class
1027 // r10 is already the class to search
1028 MethodTableLookup STRET // r11 = IMP
1031 END_ENTRY __objc_msgLookup_stret_uncached
1034 /********************************************************************
1036 * id _objc_msgForward(id self, SEL _cmd,...);
1038 * _objc_msgForward and _objc_msgForward_stret are the externally-callable
1039 * functions returned by things like method_getImplementation().
1040 * _objc_msgForward_impcache is the function pointer actually stored in
1043 ********************************************************************/
1045 STATIC_ENTRY __objc_msgForward_impcache
1046 // Method cache version
1048 // THIS IS NOT A CALLABLE C FUNCTION
1049 // Out-of-band condition register is NE for stret, EQ otherwise.
1051 je __objc_msgForward_stret
1052 jmp __objc_msgForward
1054 END_ENTRY __objc_msgForward_impcache
1057 ENTRY __objc_msgForward
1058 // Non-stret version
1060 movq __objc_forward_handler(%rip), %r11
1063 END_ENTRY __objc_msgForward
1066 ENTRY __objc_msgForward_stret
1067 // Struct-return version
1069 movq __objc_forward_stret_handler(%rip), %r11
1072 END_ENTRY __objc_msgForward_stret
1075 ENTRY _objc_msgSend_debug
1077 END_ENTRY _objc_msgSend_debug
1079 ENTRY _objc_msgSendSuper2_debug
1080 jmp _objc_msgSendSuper2
1081 END_ENTRY _objc_msgSendSuper2_debug
1083 ENTRY _objc_msgSend_stret_debug
1084 jmp _objc_msgSend_stret
1085 END_ENTRY _objc_msgSend_stret_debug
1087 ENTRY _objc_msgSendSuper2_stret_debug
1088 jmp _objc_msgSendSuper2_stret
1089 END_ENTRY _objc_msgSendSuper2_stret_debug
1091 ENTRY _objc_msgSend_fpret_debug
1092 jmp _objc_msgSend_fpret
1093 END_ENTRY _objc_msgSend_fpret_debug
1095 ENTRY _objc_msgSend_fp2ret_debug
1096 jmp _objc_msgSend_fp2ret
1097 END_ENTRY _objc_msgSend_fp2ret_debug
1100 ENTRY _objc_msgSend_noarg
1102 END_ENTRY _objc_msgSend_noarg
1105 ENTRY _method_invoke
1107 movq method_imp(%a2), %r11
1108 movq method_name(%a2), %a2
1111 END_ENTRY _method_invoke
1114 ENTRY _method_invoke_stret
1116 movq method_imp(%a3), %r11
1117 movq method_name(%a3), %a3
1120 END_ENTRY _method_invoke_stret
1123 .section __DATA,__objc_msg_break