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_entryPoints and _objc_exitPoints are used by objc
40 // to get the critical regions for which method caches
41 // cannot be garbage collected.
44 .private_extern _objc_entryPoints
48 .quad _objc_msgSend_fpret
49 .quad _objc_msgSend_fp2ret
50 .quad _objc_msgSend_stret
51 .quad _objc_msgSendSuper
52 .quad _objc_msgSendSuper_stret
53 .quad _objc_msgSendSuper2
54 .quad _objc_msgSendSuper2_stret
56 .quad _objc_msgLookup_fpret
57 .quad _objc_msgLookup_fp2ret
58 .quad _objc_msgLookup_stret
59 .quad _objc_msgLookupSuper2
60 .quad _objc_msgLookupSuper2_stret
63 .private_extern _objc_exitPoints
65 .quad LExit_cache_getImp
66 .quad LExit_objc_msgSend
67 .quad LExit_objc_msgSend_fpret
68 .quad LExit_objc_msgSend_fp2ret
69 .quad LExit_objc_msgSend_stret
70 .quad LExit_objc_msgSendSuper
71 .quad LExit_objc_msgSendSuper_stret
72 .quad LExit_objc_msgSendSuper2
73 .quad LExit_objc_msgSendSuper2_stret
74 .quad LExit_objc_msgLookup
75 .quad LExit_objc_msgLookup_fpret
76 .quad LExit_objc_msgLookup_fp2ret
77 .quad LExit_objc_msgLookup_stret
78 .quad LExit_objc_msgLookupSuper2
79 .quad LExit_objc_msgLookupSuper2_stret
83 /********************************************************************
84 * Recommended multi-byte NOP instructions
85 * (Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2B)
86 ********************************************************************/
87 #define nop1 .byte 0x90
88 #define nop2 .byte 0x66,0x90
89 #define nop3 .byte 0x0F,0x1F,0x00
90 #define nop4 .byte 0x0F,0x1F,0x40,0x00
91 #define nop5 .byte 0x0F,0x1F,0x44,0x00,0x00
92 #define nop6 .byte 0x66,0x0F,0x1F,0x44,0x00,0x00
93 #define nop7 .byte 0x0F,0x1F,0x80,0x00,0x00,0x00,0x00
94 #define nop8 .byte 0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
95 #define nop9 .byte 0x66,0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
98 /********************************************************************
99 * Harmless branch prefix hint for instruction alignment
100 ********************************************************************/
102 #define PN .byte 0x2e
105 /********************************************************************
106 * Names for parameter registers.
107 ********************************************************************/
125 /********************************************************************
126 * Names for relative labels
127 * DO NOT USE THESE LABELS ELSEWHERE
128 * Reserved labels: 6: 7: 8: 9:
129 ********************************************************************/
131 #define LCacheMiss_f 6f
132 #define LCacheMiss_b 6b
133 #define LNilTestSlow 7
134 #define LNilTestSlow_f 7f
135 #define LNilTestSlow_b 7b
136 #define LGetIsaDone 8
137 #define LGetIsaDone_f 8f
138 #define LGetIsaDone_b 8b
139 #define LGetIsaSlow 9
140 #define LGetIsaSlow_f 9f
141 #define LGetIsaSlow_b 9b
143 /********************************************************************
145 ********************************************************************/
157 /********************************************************************
159 * Structure definitions.
161 ********************************************************************/
163 // objc_super parameter to sendSuper
167 // Selected field offsets in class structure
168 // #define isa 0 USE GetIsa INSTEAD
171 #define method_name 0
172 #define method_imp 16
179 //////////////////////////////////////////////////////////////////////
181 // ENTRY functionName
183 // Assembly directives to begin an exported function.
185 // Takes: functionName - name of the exported function
186 //////////////////////////////////////////////////////////////////////
202 //////////////////////////////////////////////////////////////////////
204 // END_ENTRY functionName
206 // Assembly directives to end an exported function. Just a placeholder,
207 // a close-parenthesis for ENTRY, until it is needed for something.
209 // Takes: functionName - name of the exported function
210 //////////////////////////////////////////////////////////////////////
217 /********************************************************************
219 * Unwind info generation
220 ********************************************************************/
222 .section __LD,__compact_unwind,regular,debug
224 .set LUnwind$0, LExit$0 - $0
227 .quad 0 /* no personality */
228 .quad 0 /* no LSDA */
232 #define NoFrame 0x02010000 // no frame, no SP adjustment except return address
233 #define FrameWithNoSaves 0x01000000 // frame, no non-volatile saves
236 /////////////////////////////////////////////////////////////////////
238 // CacheLookup return-type, caller
240 // Locate the implementation for a class in a selector's method cache.
243 // $0 = NORMAL, FPRET, FP2RET, STRET
244 // $1 = CALL, LOOKUP, GETIMP
245 // a1 or a2 (STRET) = receiver
246 // a2 or a3 (STRET) = selector
247 // r10 = class to search
249 // On exit: r10 clobbered
250 // (found) calls or returns IMP in r11, eq/ne set for forwarding
251 // (not found) jumps to LCacheMiss, class still in r10
253 /////////////////////////////////////////////////////////////////////
257 // CacheHit must always be preceded by a not-taken `jne` instruction
258 // in order to set the correct flags for _objc_msgForward_impcache.
260 // r11 = found bucket
263 movq cached_imp(%r11), %rax // return imp
269 // eq already set for forwarding by `jne`
271 test %r11, %r11 // set ne for stret forwarding
275 jmp *cached_imp(%r11) // call imp
278 movq cached_imp(%r11), %r11 // return imp
292 movq %a2, %r11 // r11 = _cmd
294 movq %a3, %r11 // r11 = _cmd
296 andl 24(%r10), %r11d // r11 = _cmd & class->cache.mask
297 shlq $$4, %r11 // r11 = offset = (_cmd & mask)<<4
298 addq 16(%r10), %r11 // r11 = class->cache.buckets + offset
301 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
303 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
306 // CacheHit must always be preceded by a not-taken `jne` instruction
307 CacheHit $0, $1 // call or return imp
311 cmpq $$1, cached_sel(%r11)
312 jbe 3f // if (bucket->sel <= 1) wrap or miss
314 addq $$16, %r11 // bucket++
317 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
319 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
322 // CacheHit must always be preceded by a not-taken `jne` instruction
323 CacheHit $0, $1 // call or return imp
327 jb LCacheMiss_f // if (bucket->sel < 1) cache miss
329 movq cached_imp(%r11), %r11 // bucket->imp is really first bucket
332 // Clone scanning loop to miss instead of hang when cache is corrupt.
333 // The slow path may detect any corruption and halt later.
337 cmpq $$1, cached_sel(%r11)
338 jbe 3f // if (bucket->sel <= 1) wrap or miss
340 addq $$16, %r11 // bucket++
343 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
345 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
348 // CacheHit must always be preceded by a not-taken `jne` instruction
349 CacheHit $0, $1 // call or return imp
352 // double wrap or miss
358 /////////////////////////////////////////////////////////////////////
360 // MethodTableLookup NORMAL|STRET
362 // Takes: a1 or a2 (STRET) = receiver
363 // a2 or a3 (STRET) = selector to search for
364 // r10 = class to search
366 // On exit: imp in %r11, eq/ne set for forwarding
368 /////////////////////////////////////////////////////////////////////
370 .macro MethodTableLookup
375 sub $$0x80+8, %rsp // +8 for alignment
377 movdqa %xmm0, -0x80(%rbp)
378 push %rax // might be xmm parameter count
379 movdqa %xmm1, -0x70(%rbp)
381 movdqa %xmm2, -0x60(%rbp)
383 movdqa %xmm3, -0x50(%rbp)
385 movdqa %xmm4, -0x40(%rbp)
387 movdqa %xmm5, -0x30(%rbp)
389 movdqa %xmm6, -0x20(%rbp)
391 movdqa %xmm7, -0x10(%rbp)
393 // _class_lookupMethodAndLoadCache3(receiver, selector, class)
396 // receiver already in a1
397 // selector already in a2
403 call __class_lookupMethodAndLoadCache3
405 // IMP is now in %rax
408 movdqa -0x80(%rbp), %xmm0
410 movdqa -0x70(%rbp), %xmm1
412 movdqa -0x60(%rbp), %xmm2
414 movdqa -0x50(%rbp), %xmm3
416 movdqa -0x40(%rbp), %xmm4
418 movdqa -0x30(%rbp), %xmm5
420 movdqa -0x20(%rbp), %xmm6
422 movdqa -0x10(%rbp), %xmm7
425 cmp %r11, %r11 // set eq for nonstret forwarding
427 test %r11, %r11 // set ne for stret forwarding
435 /////////////////////////////////////////////////////////////////////
437 // GetIsaFast return-type
438 // GetIsaSupport return-type
440 // Sets r10 = obj->isa. Consults the tagged isa table if necessary.
442 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
443 // a1 or a2 (STRET) = receiver
445 // On exit: r10 = receiver->isa
448 /////////////////////////////////////////////////////////////////////
455 movq $$ ISA_MASK, %r10
461 movq $$ ISA_MASK, %r10
476 leaq _objc_debug_taggedpointer_classes(%rip), %r10
477 movq (%r10, %r11, 8), %r10 // read isa from table
478 leaq _OBJC_CLASS_$___NSUnrecognizedTaggedPointer(%rip), %r11
489 leaq _objc_debug_taggedpointer_ext_classes(%rip), %r10
490 movq (%r10, %r11, 8), %r10 // read isa from table
495 /////////////////////////////////////////////////////////////////////
497 // NilTest return-type
499 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
500 // %a1 or %a2 (STRET) = receiver
502 // On exit: Loads non-nil receiver in %a1 or %a2 (STRET)
505 // NilTestReturnZero return-type
507 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
508 // %a1 or %a2 (STRET) = receiver
510 // On exit: Loads non-nil receiver in %a1 or %a2 (STRET)
513 // NilTestReturnIMP return-type
515 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
516 // %a1 or %a2 (STRET) = receiver
518 // On exit: Loads non-nil receiver in %a1 or %a2 (STRET)
519 // or returns an IMP in r11 that returns zero.
521 /////////////////////////////////////////////////////////////////////
530 .macro ZeroReturnFPRET
535 .macro ZeroReturnFP2RET
541 .macro ZeroReturnSTRET
542 // rax gets the struct-return address as passed in rdi
546 STATIC_ENTRY __objc_msgNil
549 END_ENTRY __objc_msgNil
551 STATIC_ENTRY __objc_msgNil_fpret
554 END_ENTRY __objc_msgNil_fpret
556 STATIC_ENTRY __objc_msgNil_fp2ret
559 END_ENTRY __objc_msgNil_fp2ret
561 STATIC_ENTRY __objc_msgNil_stret
564 END_ENTRY __objc_msgNil_stret
578 .macro NilTestReturnZero
597 .macro NilTestReturnIMP
602 leaq __objc_msgNil(%rip), %r11
604 leaq __objc_msgNil_fpret(%rip), %r11
606 leaq __objc_msgNil_fp2ret(%rip), %r11
608 leaq __objc_msgNil_stret(%rip), %r11
616 /********************************************************************
617 * IMP cache_getImp(Class cls, SEL sel)
619 * On entry: a1 = class whose cache is to be searched
620 * a2 = selector to search for
622 * If found, returns method implementation.
623 * If not found, returns NULL.
624 ********************************************************************/
626 STATIC_ENTRY _cache_getImp
629 movq %a1, %r10 // move class to r10 for CacheLookup
630 CacheLookup NORMAL, GETIMP // returns IMP on success
633 // cache miss, return nil
637 END_ENTRY _cache_getImp
640 /********************************************************************
642 * id objc_msgSend(id self, SEL _cmd,...);
643 * IMP objc_msgLookup(id self, SEL _cmd, ...);
645 * objc_msgLookup ABI:
646 * IMP returned in r11
647 * Forwarding returned in Z flag
648 * r10 reserved for our use but not used
650 ********************************************************************/
654 .globl _objc_debug_taggedpointer_classes
655 _objc_debug_taggedpointer_classes:
657 .globl _objc_debug_taggedpointer_ext_classes
658 _objc_debug_taggedpointer_ext_classes:
662 UNWIND _objc_msgSend, NoFrame
666 GetIsaFast NORMAL // r10 = self->isa
667 CacheLookup NORMAL, CALL // calls IMP on success
669 NilTestReturnZero NORMAL
673 // cache miss: go search the method lists
676 jmp __objc_msgSend_uncached
678 END_ENTRY _objc_msgSend
681 ENTRY _objc_msgLookup
685 GetIsaFast NORMAL // r10 = self->isa
686 CacheLookup NORMAL, LOOKUP // returns IMP on success
688 NilTestReturnIMP NORMAL
692 // cache miss: go search the method lists
695 jmp __objc_msgLookup_uncached
697 END_ENTRY _objc_msgLookup
700 ENTRY _objc_msgSend_fixup
702 END_ENTRY _objc_msgSend_fixup
705 STATIC_ENTRY _objc_msgSend_fixedup
706 // Load _cmd from the message_ref
709 END_ENTRY _objc_msgSend_fixedup
712 /********************************************************************
714 * id objc_msgSendSuper(struct objc_super *super, SEL _cmd,...);
716 * struct objc_super {
720 ********************************************************************/
722 ENTRY _objc_msgSendSuper
723 UNWIND _objc_msgSendSuper, NoFrame
725 // search the cache (objc_super in %a1)
726 movq class(%a1), %r10 // class = objc_super->class
727 movq receiver(%a1), %a1 // load real receiver
728 CacheLookup NORMAL, CALL // calls IMP on success
730 // cache miss: go search the method lists
732 // class still in r10
733 jmp __objc_msgSend_uncached
735 END_ENTRY _objc_msgSendSuper
738 /********************************************************************
739 * id objc_msgSendSuper2
740 ********************************************************************/
742 ENTRY _objc_msgSendSuper2
743 UNWIND _objc_msgSendSuper2, NoFrame
745 // objc_super->class is superclass of class to search
747 // search the cache (objc_super in %a1)
748 movq class(%a1), %r10 // cls = objc_super->class
749 movq receiver(%a1), %a1 // load real receiver
750 movq 8(%r10), %r10 // cls = class->superclass
751 CacheLookup NORMAL, CALL // calls IMP on success
753 // cache miss: go search the method lists
755 // superclass still in r10
756 jmp __objc_msgSend_uncached
758 END_ENTRY _objc_msgSendSuper2
761 ENTRY _objc_msgLookupSuper2
763 // objc_super->class is superclass of class to search
765 // search the cache (objc_super in %a1)
766 movq class(%a1), %r10 // cls = objc_super->class
767 movq receiver(%a1), %a1 // load real receiver
768 movq 8(%r10), %r10 // cls = class->superclass
769 CacheLookup NORMAL, LOOKUP // returns IMP on success
771 // cache miss: go search the method lists
773 // superclass still in r10
774 jmp __objc_msgLookup_uncached
776 END_ENTRY _objc_msgLookupSuper2
779 ENTRY _objc_msgSendSuper2_fixup
781 END_ENTRY _objc_msgSendSuper2_fixup
784 STATIC_ENTRY _objc_msgSendSuper2_fixedup
785 // Load _cmd from the message_ref
787 jmp _objc_msgSendSuper2
788 END_ENTRY _objc_msgSendSuper2_fixedup
791 /********************************************************************
793 * double objc_msgSend_fpret(id self, SEL _cmd,...);
794 * Used for `long double` return only. `float` and `double` use objc_msgSend.
796 ********************************************************************/
798 ENTRY _objc_msgSend_fpret
799 UNWIND _objc_msgSend_fpret, NoFrame
803 GetIsaFast FPRET // r10 = self->isa
804 CacheLookup FPRET, CALL // calls IMP on success
806 NilTestReturnZero FPRET
810 // cache miss: go search the method lists
813 jmp __objc_msgSend_uncached
815 END_ENTRY _objc_msgSend_fpret
818 ENTRY _objc_msgLookup_fpret
822 GetIsaFast FPRET // r10 = self->isa
823 CacheLookup FPRET, LOOKUP // returns IMP on success
825 NilTestReturnIMP FPRET
829 // cache miss: go search the method lists
832 jmp __objc_msgLookup_uncached
834 END_ENTRY _objc_msgLookup_fpret
837 ENTRY _objc_msgSend_fpret_fixup
839 END_ENTRY _objc_msgSend_fpret_fixup
842 STATIC_ENTRY _objc_msgSend_fpret_fixedup
843 // Load _cmd from the message_ref
845 jmp _objc_msgSend_fpret
846 END_ENTRY _objc_msgSend_fpret_fixedup
849 /********************************************************************
851 * double objc_msgSend_fp2ret(id self, SEL _cmd,...);
852 * Used for `complex long double` return only.
854 ********************************************************************/
856 ENTRY _objc_msgSend_fp2ret
857 UNWIND _objc_msgSend_fp2ret, NoFrame
861 GetIsaFast FP2RET // r10 = self->isa
862 CacheLookup FP2RET, CALL // calls IMP on success
864 NilTestReturnZero FP2RET
868 // cache miss: go search the method lists
871 jmp __objc_msgSend_uncached
873 END_ENTRY _objc_msgSend_fp2ret
876 ENTRY _objc_msgLookup_fp2ret
880 GetIsaFast FP2RET // r10 = self->isa
881 CacheLookup FP2RET, LOOKUP // returns IMP on success
883 NilTestReturnIMP FP2RET
887 // cache miss: go search the method lists
890 jmp __objc_msgLookup_uncached
892 END_ENTRY _objc_msgLookup_fp2ret
895 ENTRY _objc_msgSend_fp2ret_fixup
897 END_ENTRY _objc_msgSend_fp2ret_fixup
900 STATIC_ENTRY _objc_msgSend_fp2ret_fixedup
901 // Load _cmd from the message_ref
903 jmp _objc_msgSend_fp2ret
904 END_ENTRY _objc_msgSend_fp2ret_fixedup
907 /********************************************************************
909 * void objc_msgSend_stret(void *st_addr, id self, SEL _cmd, ...);
911 * objc_msgSend_stret is the struct-return form of msgSend.
912 * The ABI calls for %a1 to be used as the address of the structure
913 * being returned, with the parameters in the succeeding locations.
915 * On entry: %a1 is the address where the structure is returned,
916 * %a2 is the message receiver,
917 * %a3 is the selector
918 ********************************************************************/
920 ENTRY _objc_msgSend_stret
921 UNWIND _objc_msgSend_stret, NoFrame
925 GetIsaFast STRET // r10 = self->isa
926 CacheLookup STRET, CALL // calls IMP on success
928 NilTestReturnZero STRET
932 // cache miss: go search the method lists
935 jmp __objc_msgSend_stret_uncached
937 END_ENTRY _objc_msgSend_stret
940 ENTRY _objc_msgLookup_stret
944 GetIsaFast STRET // r10 = self->isa
945 CacheLookup STRET, LOOKUP // returns IMP on success
947 NilTestReturnIMP STRET
951 // cache miss: go search the method lists
954 jmp __objc_msgLookup_stret_uncached
956 END_ENTRY _objc_msgLookup_stret
959 ENTRY _objc_msgSend_stret_fixup
961 END_ENTRY _objc_msgSend_stret_fixup
964 STATIC_ENTRY _objc_msgSend_stret_fixedup
965 // Load _cmd from the message_ref
967 jmp _objc_msgSend_stret
968 END_ENTRY _objc_msgSend_stret_fixedup
971 /********************************************************************
973 * void objc_msgSendSuper_stret(void *st_addr, struct objc_super *super, SEL _cmd, ...);
975 * struct objc_super {
980 * objc_msgSendSuper_stret is the struct-return form of msgSendSuper.
981 * The ABI calls for (sp+4) to be used as the address of the structure
982 * being returned, with the parameters in the succeeding registers.
984 * On entry: %a1 is the address where the structure is returned,
985 * %a2 is the address of the objc_super structure,
986 * %a3 is the selector
988 ********************************************************************/
990 ENTRY _objc_msgSendSuper_stret
991 UNWIND _objc_msgSendSuper_stret, NoFrame
993 // search the cache (objc_super in %a2)
994 movq class(%a2), %r10 // class = objc_super->class
995 movq receiver(%a2), %a2 // load real receiver
996 CacheLookup STRET, CALL // calls IMP on success
998 // cache miss: go search the method lists
1000 // class still in r10
1001 jmp __objc_msgSend_stret_uncached
1003 END_ENTRY _objc_msgSendSuper_stret
1006 /********************************************************************
1007 * id objc_msgSendSuper2_stret
1008 ********************************************************************/
1010 ENTRY _objc_msgSendSuper2_stret
1011 UNWIND _objc_msgSendSuper2_stret, NoFrame
1013 // search the cache (objc_super in %a2)
1014 movq class(%a2), %r10 // class = objc_super->class
1015 movq receiver(%a2), %a2 // load real receiver
1016 movq 8(%r10), %r10 // class = class->superclass
1017 CacheLookup STRET, CALL // calls IMP on success
1019 // cache miss: go search the method lists
1021 // superclass still in r10
1022 jmp __objc_msgSend_stret_uncached
1024 END_ENTRY _objc_msgSendSuper2_stret
1027 ENTRY _objc_msgLookupSuper2_stret
1029 // search the cache (objc_super in %a2)
1030 movq class(%a2), %r10 // class = objc_super->class
1031 movq receiver(%a2), %a2 // load real receiver
1032 movq 8(%r10), %r10 // class = class->superclass
1033 CacheLookup STRET, LOOKUP // returns IMP on success
1035 // cache miss: go search the method lists
1037 // superclass still in r10
1038 jmp __objc_msgLookup_stret_uncached
1040 END_ENTRY _objc_msgLookupSuper2_stret
1043 ENTRY _objc_msgSendSuper2_stret_fixup
1045 END_ENTRY _objc_msgSendSuper2_stret_fixup
1048 STATIC_ENTRY _objc_msgSendSuper2_stret_fixedup
1049 // Load _cmd from the message_ref
1051 jmp _objc_msgSendSuper2_stret
1052 END_ENTRY _objc_msgSendSuper2_stret_fixedup
1055 /********************************************************************
1057 * _objc_msgSend_uncached
1058 * _objc_msgSend_stret_uncached
1059 * _objc_msgLookup_uncached
1060 * _objc_msgLookup_stret_uncached
1062 * The uncached method lookup.
1064 ********************************************************************/
1066 STATIC_ENTRY __objc_msgSend_uncached
1067 UNWIND __objc_msgSend_uncached, FrameWithNoSaves
1069 // THIS IS NOT A CALLABLE C FUNCTION
1070 // Out-of-band r10 is the searched class
1072 // r10 is already the class to search
1073 MethodTableLookup NORMAL // r11 = IMP
1074 jmp *%r11 // goto *imp
1076 END_ENTRY __objc_msgSend_uncached
1079 STATIC_ENTRY __objc_msgSend_stret_uncached
1080 UNWIND __objc_msgSend_stret_uncached, FrameWithNoSaves
1082 // THIS IS NOT A CALLABLE C FUNCTION
1083 // Out-of-band r10 is the searched class
1085 // r10 is already the class to search
1086 MethodTableLookup STRET // r11 = IMP
1087 jmp *%r11 // goto *imp
1089 END_ENTRY __objc_msgSend_stret_uncached
1092 STATIC_ENTRY __objc_msgLookup_uncached
1093 UNWIND __objc_msgLookup_uncached, FrameWithNoSaves
1095 // THIS IS NOT A CALLABLE C FUNCTION
1096 // Out-of-band r10 is the searched class
1098 // r10 is already the class to search
1099 MethodTableLookup NORMAL // r11 = IMP
1102 END_ENTRY __objc_msgLookup_uncached
1105 STATIC_ENTRY __objc_msgLookup_stret_uncached
1106 UNWIND __objc_msgLookup_stret_uncached, FrameWithNoSaves
1108 // THIS IS NOT A CALLABLE C FUNCTION
1109 // Out-of-band r10 is the searched class
1111 // r10 is already the class to search
1112 MethodTableLookup STRET // r11 = IMP
1115 END_ENTRY __objc_msgLookup_stret_uncached
1118 /********************************************************************
1120 * id _objc_msgForward(id self, SEL _cmd,...);
1122 * _objc_msgForward and _objc_msgForward_stret are the externally-callable
1123 * functions returned by things like method_getImplementation().
1124 * _objc_msgForward_impcache is the function pointer actually stored in
1127 ********************************************************************/
1129 STATIC_ENTRY __objc_msgForward_impcache
1130 // Method cache version
1132 // THIS IS NOT A CALLABLE C FUNCTION
1133 // Out-of-band condition register is NE for stret, EQ otherwise.
1135 jne __objc_msgForward_stret
1136 jmp __objc_msgForward
1138 END_ENTRY __objc_msgForward_impcache
1141 ENTRY __objc_msgForward
1142 // Non-stret version
1144 movq __objc_forward_handler(%rip), %r11
1147 END_ENTRY __objc_msgForward
1150 ENTRY __objc_msgForward_stret
1151 // Struct-return version
1153 movq __objc_forward_stret_handler(%rip), %r11
1156 END_ENTRY __objc_msgForward_stret
1159 ENTRY _objc_msgSend_debug
1161 END_ENTRY _objc_msgSend_debug
1163 ENTRY _objc_msgSendSuper2_debug
1164 jmp _objc_msgSendSuper2
1165 END_ENTRY _objc_msgSendSuper2_debug
1167 ENTRY _objc_msgSend_stret_debug
1168 jmp _objc_msgSend_stret
1169 END_ENTRY _objc_msgSend_stret_debug
1171 ENTRY _objc_msgSendSuper2_stret_debug
1172 jmp _objc_msgSendSuper2_stret
1173 END_ENTRY _objc_msgSendSuper2_stret_debug
1175 ENTRY _objc_msgSend_fpret_debug
1176 jmp _objc_msgSend_fpret
1177 END_ENTRY _objc_msgSend_fpret_debug
1179 ENTRY _objc_msgSend_fp2ret_debug
1180 jmp _objc_msgSend_fp2ret
1181 END_ENTRY _objc_msgSend_fp2ret_debug
1184 ENTRY _objc_msgSend_noarg
1186 END_ENTRY _objc_msgSend_noarg
1189 ENTRY _method_invoke
1191 movq method_imp(%a2), %r11
1192 movq method_name(%a2), %a2
1195 END_ENTRY _method_invoke
1198 ENTRY _method_invoke_stret
1200 movq method_imp(%a3), %r11
1201 movq method_name(%a3), %a3
1204 END_ENTRY _method_invoke_stret
1207 .section __DATA,__objc_msg_break