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_MACCATALYST
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 ********************************************************************/
105 /********************************************************************
106 * Names for relative labels
107 * DO NOT USE THESE LABELS ELSEWHERE
108 * Reserved labels: 6: 7: 8: 9:
109 ********************************************************************/
111 #define LCacheMiss_f 6f
112 #define LCacheMiss_b 6b
113 #define LGetIsaDone 7
114 #define LGetIsaDone_f 7f
115 #define LGetIsaDone_b 7b
116 #define LNilOrTagged 8
117 #define LNilOrTagged_f 8f
118 #define LNilOrTagged_b 8b
123 /********************************************************************
125 ********************************************************************/
137 #define METHOD_INVOKE 201
138 #define METHOD_INVOKE_STRET 202
141 /********************************************************************
143 * Structure definitions.
145 ********************************************************************/
147 // objc_super parameter to sendSuper
151 // Selected field offsets in class structure
152 // #define isa 0 USE GetIsa INSTEAD
155 #define method_name 0
156 #define method_imp 16
163 //////////////////////////////////////////////////////////////////////
165 // ENTRY functionName
167 // Assembly directives to begin an exported function.
169 // Takes: functionName - name of the exported function
170 //////////////////////////////////////////////////////////////////////
186 //////////////////////////////////////////////////////////////////////
188 // END_ENTRY functionName
190 // Assembly directives to end an exported function. Just a placeholder,
191 // a close-parenthesis for ENTRY, until it is needed for something.
193 // Takes: functionName - name of the exported function
194 //////////////////////////////////////////////////////////////////////
201 /********************************************************************
203 * Unwind info generation
204 ********************************************************************/
206 .section __LD,__compact_unwind,regular,debug
208 .set LUnwind$0, LExit$0 - $0
211 .quad 0 /* no personality */
212 .quad 0 /* no LSDA */
216 #define NoFrame 0x02010000 // no frame, no SP adjustment except return address
217 #define FrameWithNoSaves 0x01000000 // frame, no non-volatile saves
220 //////////////////////////////////////////////////////////////////////
224 // Create a stack frame and save all argument registers in preparation
225 // for a function call.
226 //////////////////////////////////////////////////////////////////////
228 .macro SAVE_REGS kind
230 .if \kind != MSGSEND && \kind != METHOD_INVOKE && \kind != METHOD_INVOKE_STRET
238 movdqa %xmm0, -0x80(%rbp)
239 push %rax // might be xmm parameter count
240 movdqa %xmm1, -0x70(%rbp)
242 movdqa %xmm2, -0x60(%rbp)
243 .if \kind == MSGSEND || \kind == METHOD_INVOKE_STRET
246 movdqa %xmm3, -0x50(%rbp)
247 .if \kind == MSGSEND || \kind == METHOD_INVOKE
250 movdqa %xmm4, -0x40(%rbp)
252 movdqa %xmm5, -0x30(%rbp)
254 movdqa %xmm6, -0x20(%rbp)
256 movdqa %xmm7, -0x10(%rbp)
264 //////////////////////////////////////////////////////////////////////
268 // Restore all argument registers and pop the stack frame created by
270 //////////////////////////////////////////////////////////////////////
272 .macro RESTORE_REGS kind
276 orq $2, %r10 // for the sake of instrumentations, remember it was the slowpath
278 movdqa -0x80(%rbp), %xmm0
280 movdqa -0x70(%rbp), %xmm1
282 movdqa -0x60(%rbp), %xmm2
284 movdqa -0x50(%rbp), %xmm3
285 .if \kind == MSGSEND || \kind == METHOD_INVOKE
288 movdqa -0x40(%rbp), %xmm4
289 .if \kind == MSGSEND || \kind == METHOD_INVOKE_STRET
292 movdqa -0x30(%rbp), %xmm5
294 movdqa -0x20(%rbp), %xmm6
296 movdqa -0x10(%rbp), %xmm7
302 /////////////////////////////////////////////////////////////////////
304 // CacheLookup return-type, caller
306 // Locate the implementation for a class in a selector's method cache.
309 // $0 = NORMAL, FPRET, FP2RET, STRET
310 // $1 = CALL, LOOKUP, GETIMP
311 // a1 or a2 (STRET) = receiver
312 // a2 or a3 (STRET) = selector
313 // r10 = class to search
315 // On exit: r10 clobbered
316 // (found) calls or returns IMP in r11, eq/ne set for forwarding
317 // (not found) jumps to LCacheMiss, class still in r10
319 /////////////////////////////////////////////////////////////////////
323 // r11 = found bucket
326 movq cached_imp(%r11), %rax // return imp
328 jz 9f // don't xor a nil imp
329 xorq %r10, %rax // xor the isa with the imp
335 movq cached_imp(%r11), %r11 // load imp
336 xorq %r10, %r11 // xor imp and isa
338 // ne already set for forwarding by `xor`
340 cmp %r11, %r11 // set eq for stret forwarding
342 jmp *%r11 // call imp
345 movq cached_imp(%r11), %r11
346 xorq %r10, %r11 // return imp ^ isa
360 movq %a2, %r11 // r11 = _cmd
362 movq %a3, %r11 // r11 = _cmd
364 andl 24(%r10), %r11d // r11 = _cmd & class->cache.mask
365 shlq $$4, %r11 // r11 = offset = (_cmd & mask)<<4
366 addq 16(%r10), %r11 // r11 = class->cache.buckets + offset
369 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
371 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
374 CacheHit $0, $1 // call or return imp
378 cmpq $$1, cached_sel(%r11)
379 jbe 3f // if (bucket->sel <= 1) wrap or miss
381 addq $$16, %r11 // bucket++
384 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
386 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
389 CacheHit $0, $1 // call or return imp
393 jb LCacheMiss_f // if (bucket->sel < 1) cache miss
395 movq cached_imp(%r11), %r11 // bucket->imp is really first bucket
398 // Clone scanning loop to miss instead of hang when cache is corrupt.
399 // The slow path may detect any corruption and halt later.
403 cmpq $$1, cached_sel(%r11)
404 jbe 3f // if (bucket->sel <= 1) wrap or miss
406 addq $$16, %r11 // bucket++
409 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
411 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
414 CacheHit $0, $1 // call or return imp
417 // double wrap or miss
423 /////////////////////////////////////////////////////////////////////
425 // MethodTableLookup NORMAL|STRET
427 // Takes: a1 or a2 (STRET) = receiver
428 // a2 or a3 (STRET) = selector to search for
429 // r10 = class to search
431 // On exit: imp in %r11, eq/ne set for forwarding
433 /////////////////////////////////////////////////////////////////////
435 .macro MethodTableLookup
439 // lookUpImpOrForward(obj, sel, cls, LOOKUP_INITIALIZE | LOOKUP_RESOLVER)
441 // receiver already in a1
442 // selector already in a2
449 call _lookUpImpOrForward
451 // IMP is now in %rax
457 test %r11, %r11 // set ne for stret forwarding
459 cmp %r11, %r11 // set eq for nonstret forwarding
465 /////////////////////////////////////////////////////////////////////
467 // GetIsaCheckNil return-type
468 // GetIsaSupport return-type
469 // NilTestReturnZero return-type
470 // NilTestReturnIMP return-type
472 // Sets r10 = obj->isa.
473 // Looks up the real class if receiver is a tagged pointer object.
474 // Returns zero or a zero-returning IMP if obj is nil.
476 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
477 // a1 or a2 (STRET) = receiver
479 // On exit from GetIsaCheckNil:
480 // r10 = receiver->isa
483 /////////////////////////////////////////////////////////////////////
492 .macro ZeroReturnFPRET
497 .macro ZeroReturnFP2RET
503 .macro ZeroReturnSTRET
504 // rax gets the struct-return address as passed in rdi
508 STATIC_ENTRY __objc_msgNil
511 END_ENTRY __objc_msgNil
513 STATIC_ENTRY __objc_msgNil_fpret
516 END_ENTRY __objc_msgNil_fpret
518 STATIC_ENTRY __objc_msgNil_fp2ret
521 END_ENTRY __objc_msgNil_fp2ret
523 STATIC_ENTRY __objc_msgNil_stret
526 END_ENTRY __objc_msgNil_stret
529 .macro GetIsaCheckNil
535 jle LNilOrTagged_f // MSB tagged pointer looks negative
538 movq (%a1), %r10 // r10 = isa
540 movq (%a2), %r10 // r10 = isa
550 jz LNil_f // flags set by GetIsaCheckNil
558 leaq _objc_debug_taggedpointer_classes(%rip), %r10
559 movq (%r10, %r11, 8), %r10 // read isa from table
560 leaq _OBJC_CLASS_$___NSUnrecognizedTaggedPointer(%rip), %r11
571 leaq _objc_debug_taggedpointer_ext_classes(%rip), %r10
572 movq (%r10, %r11, 8), %r10 // read isa from table
577 .macro NilTestReturnZero
594 .macro NilTestReturnIMP
597 leaq __objc_msgNil(%rip), %r11
599 leaq __objc_msgNil_fpret(%rip), %r11
601 leaq __objc_msgNil_fp2ret(%rip), %r11
603 leaq __objc_msgNil_stret(%rip), %r11
611 /********************************************************************
612 * IMP cache_getImp(Class cls, SEL sel)
614 * On entry: a1 = class whose cache is to be searched
615 * a2 = selector to search for
617 * If found, returns method implementation.
618 * If not found, returns NULL.
619 ********************************************************************/
621 STATIC_ENTRY _cache_getImp
624 movq %a1, %r10 // move class to r10 for CacheLookup
625 CacheLookup NORMAL, GETIMP // returns IMP on success
628 // cache miss, return nil
632 END_ENTRY _cache_getImp
635 /********************************************************************
637 * id objc_msgSend(id self, SEL _cmd,...);
638 * IMP objc_msgLookup(id self, SEL _cmd, ...);
640 * objc_msgLookup ABI:
641 * IMP returned in r11
642 * Forwarding returned in Z flag
643 * r10 reserved for our use but not used
645 ********************************************************************/
649 .globl _objc_debug_taggedpointer_classes
650 _objc_debug_taggedpointer_classes:
652 .globl _objc_debug_taggedpointer_ext_classes
653 _objc_debug_taggedpointer_ext_classes:
657 UNWIND _objc_msgSend, NoFrame
659 GetIsaCheckNil NORMAL // r10 = self->isa, or return zero
660 CacheLookup NORMAL, CALL // calls IMP on success
663 NilTestReturnZero NORMAL
665 // cache miss: go search the method lists
668 jmp __objc_msgSend_uncached
670 END_ENTRY _objc_msgSend
673 ENTRY _objc_msgLookup
675 GetIsaCheckNil NORMAL // r10 = self->isa, or return zero IMP
676 CacheLookup NORMAL, LOOKUP // returns IMP on success
679 NilTestReturnIMP NORMAL
681 // cache miss: go search the method lists
684 jmp __objc_msgLookup_uncached
686 END_ENTRY _objc_msgLookup
689 ENTRY _objc_msgSend_fixup
691 END_ENTRY _objc_msgSend_fixup
694 STATIC_ENTRY _objc_msgSend_fixedup
695 // Load _cmd from the message_ref
698 END_ENTRY _objc_msgSend_fixedup
701 /********************************************************************
703 * id objc_msgSendSuper(struct objc_super *super, SEL _cmd,...);
705 * struct objc_super {
709 ********************************************************************/
711 ENTRY _objc_msgSendSuper
712 UNWIND _objc_msgSendSuper, NoFrame
714 // search the cache (objc_super in %a1)
715 movq class(%a1), %r10 // class = objc_super->class
716 movq receiver(%a1), %a1 // load real receiver
717 CacheLookup NORMAL, CALL // calls IMP on success
719 // cache miss: go search the method lists
721 // class still in r10
722 jmp __objc_msgSend_uncached
724 END_ENTRY _objc_msgSendSuper
727 /********************************************************************
728 * id objc_msgSendSuper2
729 ********************************************************************/
731 ENTRY _objc_msgSendSuper2
732 UNWIND _objc_msgSendSuper2, NoFrame
734 // objc_super->class is superclass of class to search
736 // search the cache (objc_super in %a1)
737 movq class(%a1), %r10 // cls = objc_super->class
738 movq receiver(%a1), %a1 // load real receiver
739 movq 8(%r10), %r10 // cls = class->superclass
740 CacheLookup NORMAL, CALL // calls IMP on success
742 // cache miss: go search the method lists
744 // superclass still in r10
745 jmp __objc_msgSend_uncached
747 END_ENTRY _objc_msgSendSuper2
750 ENTRY _objc_msgLookupSuper2
752 // objc_super->class is superclass of class to search
754 // search the cache (objc_super in %a1)
755 movq class(%a1), %r10 // cls = objc_super->class
756 movq receiver(%a1), %a1 // load real receiver
757 movq 8(%r10), %r10 // cls = class->superclass
758 CacheLookup NORMAL, LOOKUP // returns IMP on success
760 // cache miss: go search the method lists
762 // superclass still in r10
763 jmp __objc_msgLookup_uncached
765 END_ENTRY _objc_msgLookupSuper2
768 ENTRY _objc_msgSendSuper2_fixup
770 END_ENTRY _objc_msgSendSuper2_fixup
773 STATIC_ENTRY _objc_msgSendSuper2_fixedup
774 // Load _cmd from the message_ref
776 jmp _objc_msgSendSuper2
777 END_ENTRY _objc_msgSendSuper2_fixedup
780 /********************************************************************
782 * double objc_msgSend_fpret(id self, SEL _cmd,...);
783 * Used for `long double` return only. `float` and `double` use objc_msgSend.
785 ********************************************************************/
787 ENTRY _objc_msgSend_fpret
788 UNWIND _objc_msgSend_fpret, NoFrame
790 GetIsaCheckNil FPRET // r10 = self->isa, or return zero
791 CacheLookup FPRET, CALL // calls IMP on success
794 NilTestReturnZero FPRET
796 // cache miss: go search the method lists
799 jmp __objc_msgSend_uncached
801 END_ENTRY _objc_msgSend_fpret
804 ENTRY _objc_msgLookup_fpret
806 GetIsaCheckNil FPRET // r10 = self->isa, or return zero IMP
807 CacheLookup FPRET, LOOKUP // returns IMP on success
810 NilTestReturnIMP FPRET
812 // cache miss: go search the method lists
815 jmp __objc_msgLookup_uncached
817 END_ENTRY _objc_msgLookup_fpret
820 ENTRY _objc_msgSend_fpret_fixup
822 END_ENTRY _objc_msgSend_fpret_fixup
825 STATIC_ENTRY _objc_msgSend_fpret_fixedup
826 // Load _cmd from the message_ref
828 jmp _objc_msgSend_fpret
829 END_ENTRY _objc_msgSend_fpret_fixedup
832 /********************************************************************
834 * double objc_msgSend_fp2ret(id self, SEL _cmd,...);
835 * Used for `complex long double` return only.
837 ********************************************************************/
839 ENTRY _objc_msgSend_fp2ret
840 UNWIND _objc_msgSend_fp2ret, NoFrame
842 GetIsaCheckNil FP2RET // r10 = self->isa, or return zero
843 CacheLookup FP2RET, CALL // calls IMP on success
846 NilTestReturnZero FP2RET
848 // cache miss: go search the method lists
851 jmp __objc_msgSend_uncached
853 END_ENTRY _objc_msgSend_fp2ret
856 ENTRY _objc_msgLookup_fp2ret
858 GetIsaCheckNil FP2RET // r10 = self->isa, or return zero IMP
859 CacheLookup FP2RET, LOOKUP // returns IMP on success
862 NilTestReturnIMP FP2RET
864 // cache miss: go search the method lists
867 jmp __objc_msgLookup_uncached
869 END_ENTRY _objc_msgLookup_fp2ret
872 ENTRY _objc_msgSend_fp2ret_fixup
874 END_ENTRY _objc_msgSend_fp2ret_fixup
877 STATIC_ENTRY _objc_msgSend_fp2ret_fixedup
878 // Load _cmd from the message_ref
880 jmp _objc_msgSend_fp2ret
881 END_ENTRY _objc_msgSend_fp2ret_fixedup
884 /********************************************************************
886 * void objc_msgSend_stret(void *st_addr, id self, SEL _cmd, ...);
888 * objc_msgSend_stret is the struct-return form of msgSend.
889 * The ABI calls for %a1 to be used as the address of the structure
890 * being returned, with the parameters in the succeeding locations.
892 * On entry: %a1 is the address where the structure is returned,
893 * %a2 is the message receiver,
894 * %a3 is the selector
895 ********************************************************************/
897 ENTRY _objc_msgSend_stret
898 UNWIND _objc_msgSend_stret, NoFrame
900 GetIsaCheckNil STRET // r10 = self->isa, or return zero
901 CacheLookup STRET, CALL // calls IMP on success
904 NilTestReturnZero STRET
906 // cache miss: go search the method lists
909 jmp __objc_msgSend_stret_uncached
911 END_ENTRY _objc_msgSend_stret
914 ENTRY _objc_msgLookup_stret
916 GetIsaCheckNil STRET // r10 = self->isa, or return zero IMP
917 CacheLookup STRET, LOOKUP // returns IMP on success
920 NilTestReturnIMP STRET
922 // cache miss: go search the method lists
925 jmp __objc_msgLookup_stret_uncached
927 END_ENTRY _objc_msgLookup_stret
930 ENTRY _objc_msgSend_stret_fixup
932 END_ENTRY _objc_msgSend_stret_fixup
935 STATIC_ENTRY _objc_msgSend_stret_fixedup
936 // Load _cmd from the message_ref
938 jmp _objc_msgSend_stret
939 END_ENTRY _objc_msgSend_stret_fixedup
942 /********************************************************************
944 * void objc_msgSendSuper_stret(void *st_addr, struct objc_super *super, SEL _cmd, ...);
946 * struct objc_super {
951 * objc_msgSendSuper_stret is the struct-return form of msgSendSuper.
952 * The ABI calls for (sp+4) to be used as the address of the structure
953 * being returned, with the parameters in the succeeding registers.
955 * On entry: %a1 is the address where the structure is returned,
956 * %a2 is the address of the objc_super structure,
957 * %a3 is the selector
959 ********************************************************************/
961 ENTRY _objc_msgSendSuper_stret
962 UNWIND _objc_msgSendSuper_stret, NoFrame
964 // search the cache (objc_super in %a2)
965 movq class(%a2), %r10 // class = objc_super->class
966 movq receiver(%a2), %a2 // load real receiver
967 CacheLookup STRET, CALL // calls IMP on success
969 // cache miss: go search the method lists
971 // class still in r10
972 jmp __objc_msgSend_stret_uncached
974 END_ENTRY _objc_msgSendSuper_stret
977 /********************************************************************
978 * id objc_msgSendSuper2_stret
979 ********************************************************************/
981 ENTRY _objc_msgSendSuper2_stret
982 UNWIND _objc_msgSendSuper2_stret, NoFrame
984 // search the cache (objc_super in %a2)
985 movq class(%a2), %r10 // class = objc_super->class
986 movq receiver(%a2), %a2 // load real receiver
987 movq 8(%r10), %r10 // class = class->superclass
988 CacheLookup STRET, CALL // calls IMP on success
990 // cache miss: go search the method lists
992 // superclass still in r10
993 jmp __objc_msgSend_stret_uncached
995 END_ENTRY _objc_msgSendSuper2_stret
998 ENTRY _objc_msgLookupSuper2_stret
1000 // search the cache (objc_super in %a2)
1001 movq class(%a2), %r10 // class = objc_super->class
1002 movq receiver(%a2), %a2 // load real receiver
1003 movq 8(%r10), %r10 // class = class->superclass
1004 CacheLookup STRET, LOOKUP // returns IMP on success
1006 // cache miss: go search the method lists
1008 // superclass still in r10
1009 jmp __objc_msgLookup_stret_uncached
1011 END_ENTRY _objc_msgLookupSuper2_stret
1014 ENTRY _objc_msgSendSuper2_stret_fixup
1016 END_ENTRY _objc_msgSendSuper2_stret_fixup
1019 STATIC_ENTRY _objc_msgSendSuper2_stret_fixedup
1020 // Load _cmd from the message_ref
1022 jmp _objc_msgSendSuper2_stret
1023 END_ENTRY _objc_msgSendSuper2_stret_fixedup
1026 /********************************************************************
1028 * _objc_msgSend_uncached
1029 * _objc_msgSend_stret_uncached
1030 * The uncached method lookup.
1032 ********************************************************************/
1034 STATIC_ENTRY __objc_msgSend_uncached
1035 UNWIND __objc_msgSend_uncached, FrameWithNoSaves
1037 // THIS IS NOT A CALLABLE C FUNCTION
1038 // Out-of-band r10 is the searched class
1040 // r10 is already the class to search
1041 MethodTableLookup NORMAL // r11 = IMP
1042 jmp *%r11 // goto *imp
1044 END_ENTRY __objc_msgSend_uncached
1047 STATIC_ENTRY __objc_msgSend_stret_uncached
1048 UNWIND __objc_msgSend_stret_uncached, FrameWithNoSaves
1050 // THIS IS NOT A CALLABLE C FUNCTION
1051 // Out-of-band r10 is the searched class
1053 // r10 is already the class to search
1054 MethodTableLookup STRET // r11 = IMP
1055 jmp *%r11 // goto *imp
1057 END_ENTRY __objc_msgSend_stret_uncached
1060 STATIC_ENTRY __objc_msgLookup_uncached
1061 UNWIND __objc_msgLookup_uncached, FrameWithNoSaves
1063 // THIS IS NOT A CALLABLE C FUNCTION
1064 // Out-of-band r10 is the searched class
1066 // r10 is already the class to search
1067 MethodTableLookup NORMAL // r11 = IMP
1070 END_ENTRY __objc_msgLookup_uncached
1073 STATIC_ENTRY __objc_msgLookup_stret_uncached
1074 UNWIND __objc_msgLookup_stret_uncached, FrameWithNoSaves
1076 // THIS IS NOT A CALLABLE C FUNCTION
1077 // Out-of-band r10 is the searched class
1079 // r10 is already the class to search
1080 MethodTableLookup STRET // r11 = IMP
1083 END_ENTRY __objc_msgLookup_stret_uncached
1086 /********************************************************************
1088 * id _objc_msgForward(id self, SEL _cmd,...);
1090 * _objc_msgForward and _objc_msgForward_stret are the externally-callable
1091 * functions returned by things like method_getImplementation().
1092 * _objc_msgForward_impcache is the function pointer actually stored in
1095 ********************************************************************/
1097 STATIC_ENTRY __objc_msgForward_impcache
1098 // Method cache version
1100 // THIS IS NOT A CALLABLE C FUNCTION
1101 // Out-of-band condition register is NE for stret, EQ otherwise.
1103 je __objc_msgForward_stret
1104 jmp __objc_msgForward
1106 END_ENTRY __objc_msgForward_impcache
1109 ENTRY __objc_msgForward
1110 // Non-stret version
1112 movq __objc_forward_handler(%rip), %r11
1115 END_ENTRY __objc_msgForward
1118 ENTRY __objc_msgForward_stret
1119 // Struct-return version
1121 movq __objc_forward_stret_handler(%rip), %r11
1124 END_ENTRY __objc_msgForward_stret
1127 ENTRY _objc_msgSend_debug
1129 END_ENTRY _objc_msgSend_debug
1131 ENTRY _objc_msgSendSuper2_debug
1132 jmp _objc_msgSendSuper2
1133 END_ENTRY _objc_msgSendSuper2_debug
1135 ENTRY _objc_msgSend_stret_debug
1136 jmp _objc_msgSend_stret
1137 END_ENTRY _objc_msgSend_stret_debug
1139 ENTRY _objc_msgSendSuper2_stret_debug
1140 jmp _objc_msgSendSuper2_stret
1141 END_ENTRY _objc_msgSendSuper2_stret_debug
1143 ENTRY _objc_msgSend_fpret_debug
1144 jmp _objc_msgSend_fpret
1145 END_ENTRY _objc_msgSend_fpret_debug
1147 ENTRY _objc_msgSend_fp2ret_debug
1148 jmp _objc_msgSend_fp2ret
1149 END_ENTRY _objc_msgSend_fp2ret_debug
1152 ENTRY _objc_msgSend_noarg
1154 END_ENTRY _objc_msgSend_noarg
1157 ENTRY _method_invoke
1159 // See if this is a small method.
1161 jnz L_method_invoke_small
1163 // We can directly load the IMP from big methods.
1164 movq method_imp(%a2), %r11
1165 movq method_name(%a2), %a2
1168 L_method_invoke_small:
1169 // Small methods require a call to handle swizzling.
1170 SAVE_REGS METHOD_INVOKE
1172 call __method_getImplementationAndName
1175 RESTORE_REGS METHOD_INVOKE
1178 END_ENTRY _method_invoke
1181 ENTRY _method_invoke_stret
1183 // See if this is a small method.
1185 jnz L_method_invoke_stret_small
1187 // We can directly load the IMP from big methods.
1188 movq method_imp(%a3), %r11
1189 movq method_name(%a3), %a3
1192 L_method_invoke_stret_small:
1193 // Small methods require a call to handle swizzling.
1194 SAVE_REGS METHOD_INVOKE_STRET
1196 call __method_getImplementationAndName
1199 RESTORE_REGS METHOD_INVOKE_STRET
1202 END_ENTRY _method_invoke_stret
1205 .section __DATA,__objc_msg_break