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_entryPoints and _objc_exitPoints are used by objc
38 // to get the critical regions for which method caches
39 // cannot be garbage collected.
42 .private_extern _objc_entryPoints
46 .quad _objc_msgSend_fpret
47 .quad _objc_msgSend_fp2ret
48 .quad _objc_msgSend_stret
49 .quad _objc_msgSendSuper
50 .quad _objc_msgSendSuper_stret
51 .quad _objc_msgSendSuper2
52 .quad _objc_msgSendSuper2_stret
54 .quad _objc_msgLookup_fpret
55 .quad _objc_msgLookup_fp2ret
56 .quad _objc_msgLookup_stret
57 .quad _objc_msgLookupSuper2
58 .quad _objc_msgLookupSuper2_stret
61 .private_extern _objc_exitPoints
63 .quad LExit_cache_getImp
64 .quad LExit_objc_msgSend
65 .quad LExit_objc_msgSend_fpret
66 .quad LExit_objc_msgSend_fp2ret
67 .quad LExit_objc_msgSend_stret
68 .quad LExit_objc_msgSendSuper
69 .quad LExit_objc_msgSendSuper_stret
70 .quad LExit_objc_msgSendSuper2
71 .quad LExit_objc_msgSendSuper2_stret
72 .quad LExit_objc_msgLookup
73 .quad LExit_objc_msgLookup_fpret
74 .quad LExit_objc_msgLookup_fp2ret
75 .quad LExit_objc_msgLookup_stret
76 .quad LExit_objc_msgLookupSuper2
77 .quad LExit_objc_msgLookupSuper2_stret
81 /********************************************************************
82 * Recommended multi-byte NOP instructions
83 * (Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2B)
84 ********************************************************************/
85 #define nop1 .byte 0x90
86 #define nop2 .byte 0x66,0x90
87 #define nop3 .byte 0x0F,0x1F,0x00
88 #define nop4 .byte 0x0F,0x1F,0x40,0x00
89 #define nop5 .byte 0x0F,0x1F,0x44,0x00,0x00
90 #define nop6 .byte 0x66,0x0F,0x1F,0x44,0x00,0x00
91 #define nop7 .byte 0x0F,0x1F,0x80,0x00,0x00,0x00,0x00
92 #define nop8 .byte 0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
93 #define nop9 .byte 0x66,0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
96 /********************************************************************
97 * Names for parameter registers.
98 ********************************************************************/
116 /********************************************************************
117 * Names for relative labels
118 * DO NOT USE THESE LABELS ELSEWHERE
119 * Reserved labels: 6: 7: 8: 9:
120 ********************************************************************/
122 #define LCacheMiss_f 6f
123 #define LCacheMiss_b 6b
124 #define LGetIsaDone 7
125 #define LGetIsaDone_f 7f
126 #define LGetIsaDone_b 7b
127 #define LNilOrTagged 8
128 #define LNilOrTagged_f 8f
129 #define LNilOrTagged_b 8b
134 /********************************************************************
136 ********************************************************************/
148 /********************************************************************
150 * Structure definitions.
152 ********************************************************************/
154 // objc_super parameter to sendSuper
158 // Selected field offsets in class structure
159 // #define isa 0 USE GetIsa INSTEAD
162 #define method_name 0
163 #define method_imp 16
170 //////////////////////////////////////////////////////////////////////
172 // ENTRY functionName
174 // Assembly directives to begin an exported function.
176 // Takes: functionName - name of the exported function
177 //////////////////////////////////////////////////////////////////////
193 //////////////////////////////////////////////////////////////////////
195 // END_ENTRY functionName
197 // Assembly directives to end an exported function. Just a placeholder,
198 // a close-parenthesis for ENTRY, until it is needed for something.
200 // Takes: functionName - name of the exported function
201 //////////////////////////////////////////////////////////////////////
208 /********************************************************************
210 * Unwind info generation
211 ********************************************************************/
213 .section __LD,__compact_unwind,regular,debug
215 .set LUnwind$0, LExit$0 - $0
218 .quad 0 /* no personality */
219 .quad 0 /* no LSDA */
223 #define NoFrame 0x02010000 // no frame, no SP adjustment except return address
224 #define FrameWithNoSaves 0x01000000 // frame, no non-volatile saves
227 /////////////////////////////////////////////////////////////////////
229 // CacheLookup return-type, caller
231 // Locate the implementation for a class in a selector's method cache.
234 // $0 = NORMAL, FPRET, FP2RET, STRET
235 // $1 = CALL, LOOKUP, GETIMP
236 // a1 or a2 (STRET) = receiver
237 // a2 or a3 (STRET) = selector
238 // r10 = class to search
240 // On exit: r10 clobbered
241 // (found) calls or returns IMP in r11, eq/ne set for forwarding
242 // (not found) jumps to LCacheMiss, class still in r10
244 /////////////////////////////////////////////////////////////////////
248 // CacheHit must always be preceded by a not-taken `jne` instruction
249 // in order to set the correct flags for _objc_msgForward_impcache.
251 // r11 = found bucket
254 movq cached_imp(%r11), %rax // return imp
260 // eq already set for forwarding by `jne`
262 test %r11, %r11 // set ne for stret forwarding
266 jmp *cached_imp(%r11) // call imp
269 movq cached_imp(%r11), %r11 // return imp
283 movq %a2, %r11 // r11 = _cmd
285 movq %a3, %r11 // r11 = _cmd
287 andl 24(%r10), %r11d // r11 = _cmd & class->cache.mask
288 shlq $$4, %r11 // r11 = offset = (_cmd & mask)<<4
289 addq 16(%r10), %r11 // r11 = class->cache.buckets + offset
292 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
294 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
297 // CacheHit must always be preceded by a not-taken `jne` instruction
298 CacheHit $0, $1 // call or return imp
302 cmpq $$1, cached_sel(%r11)
303 jbe 3f // if (bucket->sel <= 1) wrap or miss
305 addq $$16, %r11 // bucket++
308 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
310 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
313 // CacheHit must always be preceded by a not-taken `jne` instruction
314 CacheHit $0, $1 // call or return imp
318 jb LCacheMiss_f // if (bucket->sel < 1) cache miss
320 movq cached_imp(%r11), %r11 // bucket->imp is really first bucket
323 // Clone scanning loop to miss instead of hang when cache is corrupt.
324 // The slow path may detect any corruption and halt later.
328 cmpq $$1, cached_sel(%r11)
329 jbe 3f // if (bucket->sel <= 1) wrap or miss
331 addq $$16, %r11 // bucket++
334 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
336 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
339 // CacheHit must always be preceded by a not-taken `jne` instruction
340 CacheHit $0, $1 // call or return imp
343 // double wrap or miss
349 /////////////////////////////////////////////////////////////////////
351 // MethodTableLookup NORMAL|STRET
353 // Takes: a1 or a2 (STRET) = receiver
354 // a2 or a3 (STRET) = selector to search for
355 // r10 = class to search
357 // On exit: imp in %r11, eq/ne set for forwarding
359 /////////////////////////////////////////////////////////////////////
361 .macro MethodTableLookup
366 sub $$0x80+8, %rsp // +8 for alignment
368 movdqa %xmm0, -0x80(%rbp)
369 push %rax // might be xmm parameter count
370 movdqa %xmm1, -0x70(%rbp)
372 movdqa %xmm2, -0x60(%rbp)
374 movdqa %xmm3, -0x50(%rbp)
376 movdqa %xmm4, -0x40(%rbp)
378 movdqa %xmm5, -0x30(%rbp)
380 movdqa %xmm6, -0x20(%rbp)
382 movdqa %xmm7, -0x10(%rbp)
384 // _class_lookupMethodAndLoadCache3(receiver, selector, class)
387 // receiver already in a1
388 // selector already in a2
394 call __class_lookupMethodAndLoadCache3
396 // IMP is now in %rax
399 movdqa -0x80(%rbp), %xmm0
401 movdqa -0x70(%rbp), %xmm1
403 movdqa -0x60(%rbp), %xmm2
405 movdqa -0x50(%rbp), %xmm3
407 movdqa -0x40(%rbp), %xmm4
409 movdqa -0x30(%rbp), %xmm5
411 movdqa -0x20(%rbp), %xmm6
413 movdqa -0x10(%rbp), %xmm7
416 cmp %r11, %r11 // set eq for nonstret forwarding
418 test %r11, %r11 // set ne for stret forwarding
426 /////////////////////////////////////////////////////////////////////
428 // GetIsaCheckNil return-type
429 // GetIsaSupport return-type
430 // NilTestReturnZero return-type
431 // NilTestReturnIMP return-type
433 // Sets r10 = obj->isa.
434 // Looks up the real class if receiver is a tagged pointer object.
435 // Returns zero or a zero-returning IMP if obj is nil.
437 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
438 // a1 or a2 (STRET) = receiver
440 // On exit from GetIsaCheckNil:
441 // r10 = receiver->isa
444 /////////////////////////////////////////////////////////////////////
453 .macro ZeroReturnFPRET
458 .macro ZeroReturnFP2RET
464 .macro ZeroReturnSTRET
465 // rax gets the struct-return address as passed in rdi
469 STATIC_ENTRY __objc_msgNil
472 END_ENTRY __objc_msgNil
474 STATIC_ENTRY __objc_msgNil_fpret
477 END_ENTRY __objc_msgNil_fpret
479 STATIC_ENTRY __objc_msgNil_fp2ret
482 END_ENTRY __objc_msgNil_fp2ret
484 STATIC_ENTRY __objc_msgNil_stret
487 END_ENTRY __objc_msgNil_stret
490 .macro GetIsaCheckNil
496 jle LNilOrTagged_f // MSB tagged pointer looks negative
499 movq (%a1), %r10 // r10 = isa
501 movq (%a2), %r10 // r10 = isa
511 jz LNil_f // flags set by GetIsaCheckNil
519 leaq _objc_debug_taggedpointer_classes(%rip), %r10
520 movq (%r10, %r11, 8), %r10 // read isa from table
521 leaq _OBJC_CLASS_$___NSUnrecognizedTaggedPointer(%rip), %r11
532 leaq _objc_debug_taggedpointer_ext_classes(%rip), %r10
533 movq (%r10, %r11, 8), %r10 // read isa from table
538 .macro NilTestReturnZero
555 .macro NilTestReturnIMP
558 leaq __objc_msgNil(%rip), %r11
560 leaq __objc_msgNil_fpret(%rip), %r11
562 leaq __objc_msgNil_fp2ret(%rip), %r11
564 leaq __objc_msgNil_stret(%rip), %r11
572 /********************************************************************
573 * IMP cache_getImp(Class cls, SEL sel)
575 * On entry: a1 = class whose cache is to be searched
576 * a2 = selector to search for
578 * If found, returns method implementation.
579 * If not found, returns NULL.
580 ********************************************************************/
582 STATIC_ENTRY _cache_getImp
585 movq %a1, %r10 // move class to r10 for CacheLookup
586 CacheLookup NORMAL, GETIMP // returns IMP on success
589 // cache miss, return nil
593 END_ENTRY _cache_getImp
596 /********************************************************************
598 * id objc_msgSend(id self, SEL _cmd,...);
599 * IMP objc_msgLookup(id self, SEL _cmd, ...);
601 * objc_msgLookup ABI:
602 * IMP returned in r11
603 * Forwarding returned in Z flag
604 * r10 reserved for our use but not used
606 ********************************************************************/
610 .globl _objc_debug_taggedpointer_classes
611 _objc_debug_taggedpointer_classes:
613 .globl _objc_debug_taggedpointer_ext_classes
614 _objc_debug_taggedpointer_ext_classes:
618 UNWIND _objc_msgSend, NoFrame
620 GetIsaCheckNil NORMAL // r10 = self->isa, or return zero
621 CacheLookup NORMAL, CALL // calls IMP on success
624 NilTestReturnZero NORMAL
626 // cache miss: go search the method lists
629 jmp __objc_msgSend_uncached
631 END_ENTRY _objc_msgSend
634 ENTRY _objc_msgLookup
636 GetIsaCheckNil NORMAL // r10 = self->isa, or return zero IMP
637 CacheLookup NORMAL, LOOKUP // returns IMP on success
640 NilTestReturnIMP NORMAL
642 // cache miss: go search the method lists
645 jmp __objc_msgLookup_uncached
647 END_ENTRY _objc_msgLookup
650 ENTRY _objc_msgSend_fixup
652 END_ENTRY _objc_msgSend_fixup
655 STATIC_ENTRY _objc_msgSend_fixedup
656 // Load _cmd from the message_ref
659 END_ENTRY _objc_msgSend_fixedup
662 /********************************************************************
664 * id objc_msgSendSuper(struct objc_super *super, SEL _cmd,...);
666 * struct objc_super {
670 ********************************************************************/
672 ENTRY _objc_msgSendSuper
673 UNWIND _objc_msgSendSuper, NoFrame
675 // search the cache (objc_super in %a1)
676 movq class(%a1), %r10 // class = objc_super->class
677 movq receiver(%a1), %a1 // load real receiver
678 CacheLookup NORMAL, CALL // calls IMP on success
680 // cache miss: go search the method lists
682 // class still in r10
683 jmp __objc_msgSend_uncached
685 END_ENTRY _objc_msgSendSuper
688 /********************************************************************
689 * id objc_msgSendSuper2
690 ********************************************************************/
692 ENTRY _objc_msgSendSuper2
693 UNWIND _objc_msgSendSuper2, NoFrame
695 // objc_super->class is superclass of class to search
697 // search the cache (objc_super in %a1)
698 movq class(%a1), %r10 // cls = objc_super->class
699 movq receiver(%a1), %a1 // load real receiver
700 movq 8(%r10), %r10 // cls = class->superclass
701 CacheLookup NORMAL, CALL // calls IMP on success
703 // cache miss: go search the method lists
705 // superclass still in r10
706 jmp __objc_msgSend_uncached
708 END_ENTRY _objc_msgSendSuper2
711 ENTRY _objc_msgLookupSuper2
713 // objc_super->class is superclass of class to search
715 // search the cache (objc_super in %a1)
716 movq class(%a1), %r10 // cls = objc_super->class
717 movq receiver(%a1), %a1 // load real receiver
718 movq 8(%r10), %r10 // cls = class->superclass
719 CacheLookup NORMAL, LOOKUP // returns IMP on success
721 // cache miss: go search the method lists
723 // superclass still in r10
724 jmp __objc_msgLookup_uncached
726 END_ENTRY _objc_msgLookupSuper2
729 ENTRY _objc_msgSendSuper2_fixup
731 END_ENTRY _objc_msgSendSuper2_fixup
734 STATIC_ENTRY _objc_msgSendSuper2_fixedup
735 // Load _cmd from the message_ref
737 jmp _objc_msgSendSuper2
738 END_ENTRY _objc_msgSendSuper2_fixedup
741 /********************************************************************
743 * double objc_msgSend_fpret(id self, SEL _cmd,...);
744 * Used for `long double` return only. `float` and `double` use objc_msgSend.
746 ********************************************************************/
748 ENTRY _objc_msgSend_fpret
749 UNWIND _objc_msgSend_fpret, NoFrame
751 GetIsaCheckNil FPRET // r10 = self->isa, or return zero
752 CacheLookup FPRET, CALL // calls IMP on success
755 NilTestReturnZero FPRET
757 // cache miss: go search the method lists
760 jmp __objc_msgSend_uncached
762 END_ENTRY _objc_msgSend_fpret
765 ENTRY _objc_msgLookup_fpret
767 GetIsaCheckNil FPRET // r10 = self->isa, or return zero IMP
768 CacheLookup FPRET, LOOKUP // returns IMP on success
771 NilTestReturnIMP FPRET
773 // cache miss: go search the method lists
776 jmp __objc_msgLookup_uncached
778 END_ENTRY _objc_msgLookup_fpret
781 ENTRY _objc_msgSend_fpret_fixup
783 END_ENTRY _objc_msgSend_fpret_fixup
786 STATIC_ENTRY _objc_msgSend_fpret_fixedup
787 // Load _cmd from the message_ref
789 jmp _objc_msgSend_fpret
790 END_ENTRY _objc_msgSend_fpret_fixedup
793 /********************************************************************
795 * double objc_msgSend_fp2ret(id self, SEL _cmd,...);
796 * Used for `complex long double` return only.
798 ********************************************************************/
800 ENTRY _objc_msgSend_fp2ret
801 UNWIND _objc_msgSend_fp2ret, NoFrame
803 GetIsaCheckNil FP2RET // r10 = self->isa, or return zero
804 CacheLookup FP2RET, CALL // calls IMP on success
807 NilTestReturnZero FP2RET
809 // cache miss: go search the method lists
812 jmp __objc_msgSend_uncached
814 END_ENTRY _objc_msgSend_fp2ret
817 ENTRY _objc_msgLookup_fp2ret
819 GetIsaCheckNil FP2RET // r10 = self->isa, or return zero IMP
820 CacheLookup FP2RET, LOOKUP // returns IMP on success
823 NilTestReturnIMP FP2RET
825 // cache miss: go search the method lists
828 jmp __objc_msgLookup_uncached
830 END_ENTRY _objc_msgLookup_fp2ret
833 ENTRY _objc_msgSend_fp2ret_fixup
835 END_ENTRY _objc_msgSend_fp2ret_fixup
838 STATIC_ENTRY _objc_msgSend_fp2ret_fixedup
839 // Load _cmd from the message_ref
841 jmp _objc_msgSend_fp2ret
842 END_ENTRY _objc_msgSend_fp2ret_fixedup
845 /********************************************************************
847 * void objc_msgSend_stret(void *st_addr, id self, SEL _cmd, ...);
849 * objc_msgSend_stret is the struct-return form of msgSend.
850 * The ABI calls for %a1 to be used as the address of the structure
851 * being returned, with the parameters in the succeeding locations.
853 * On entry: %a1 is the address where the structure is returned,
854 * %a2 is the message receiver,
855 * %a3 is the selector
856 ********************************************************************/
858 ENTRY _objc_msgSend_stret
859 UNWIND _objc_msgSend_stret, NoFrame
861 GetIsaCheckNil STRET // r10 = self->isa, or return zero
862 CacheLookup STRET, CALL // calls IMP on success
865 NilTestReturnZero STRET
867 // cache miss: go search the method lists
870 jmp __objc_msgSend_stret_uncached
872 END_ENTRY _objc_msgSend_stret
875 ENTRY _objc_msgLookup_stret
877 GetIsaCheckNil STRET // r10 = self->isa, or return zero IMP
878 CacheLookup STRET, LOOKUP // returns IMP on success
881 NilTestReturnIMP STRET
883 // cache miss: go search the method lists
886 jmp __objc_msgLookup_stret_uncached
888 END_ENTRY _objc_msgLookup_stret
891 ENTRY _objc_msgSend_stret_fixup
893 END_ENTRY _objc_msgSend_stret_fixup
896 STATIC_ENTRY _objc_msgSend_stret_fixedup
897 // Load _cmd from the message_ref
899 jmp _objc_msgSend_stret
900 END_ENTRY _objc_msgSend_stret_fixedup
903 /********************************************************************
905 * void objc_msgSendSuper_stret(void *st_addr, struct objc_super *super, SEL _cmd, ...);
907 * struct objc_super {
912 * objc_msgSendSuper_stret is the struct-return form of msgSendSuper.
913 * The ABI calls for (sp+4) to be used as the address of the structure
914 * being returned, with the parameters in the succeeding registers.
916 * On entry: %a1 is the address where the structure is returned,
917 * %a2 is the address of the objc_super structure,
918 * %a3 is the selector
920 ********************************************************************/
922 ENTRY _objc_msgSendSuper_stret
923 UNWIND _objc_msgSendSuper_stret, NoFrame
925 // search the cache (objc_super in %a2)
926 movq class(%a2), %r10 // class = objc_super->class
927 movq receiver(%a2), %a2 // load real receiver
928 CacheLookup STRET, CALL // calls IMP on success
930 // cache miss: go search the method lists
932 // class still in r10
933 jmp __objc_msgSend_stret_uncached
935 END_ENTRY _objc_msgSendSuper_stret
938 /********************************************************************
939 * id objc_msgSendSuper2_stret
940 ********************************************************************/
942 ENTRY _objc_msgSendSuper2_stret
943 UNWIND _objc_msgSendSuper2_stret, NoFrame
945 // search the cache (objc_super in %a2)
946 movq class(%a2), %r10 // class = objc_super->class
947 movq receiver(%a2), %a2 // load real receiver
948 movq 8(%r10), %r10 // class = class->superclass
949 CacheLookup STRET, CALL // calls IMP on success
951 // cache miss: go search the method lists
953 // superclass still in r10
954 jmp __objc_msgSend_stret_uncached
956 END_ENTRY _objc_msgSendSuper2_stret
959 ENTRY _objc_msgLookupSuper2_stret
961 // search the cache (objc_super in %a2)
962 movq class(%a2), %r10 // class = objc_super->class
963 movq receiver(%a2), %a2 // load real receiver
964 movq 8(%r10), %r10 // class = class->superclass
965 CacheLookup STRET, LOOKUP // returns IMP on success
967 // cache miss: go search the method lists
969 // superclass still in r10
970 jmp __objc_msgLookup_stret_uncached
972 END_ENTRY _objc_msgLookupSuper2_stret
975 ENTRY _objc_msgSendSuper2_stret_fixup
977 END_ENTRY _objc_msgSendSuper2_stret_fixup
980 STATIC_ENTRY _objc_msgSendSuper2_stret_fixedup
981 // Load _cmd from the message_ref
983 jmp _objc_msgSendSuper2_stret
984 END_ENTRY _objc_msgSendSuper2_stret_fixedup
987 /********************************************************************
989 * _objc_msgSend_uncached
990 * _objc_msgSend_stret_uncached
991 * The uncached method lookup.
993 ********************************************************************/
995 STATIC_ENTRY __objc_msgSend_uncached
996 UNWIND __objc_msgSend_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 NORMAL // r11 = IMP
1003 jmp *%r11 // goto *imp
1005 END_ENTRY __objc_msgSend_uncached
1008 STATIC_ENTRY __objc_msgSend_stret_uncached
1009 UNWIND __objc_msgSend_stret_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 STRET // r11 = IMP
1016 jmp *%r11 // goto *imp
1018 END_ENTRY __objc_msgSend_stret_uncached
1021 STATIC_ENTRY __objc_msgLookup_uncached
1022 UNWIND __objc_msgLookup_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 NORMAL // r11 = IMP
1031 END_ENTRY __objc_msgLookup_uncached
1034 STATIC_ENTRY __objc_msgLookup_stret_uncached
1035 UNWIND __objc_msgLookup_stret_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 STRET // r11 = IMP
1044 END_ENTRY __objc_msgLookup_stret_uncached
1047 /********************************************************************
1049 * id _objc_msgForward(id self, SEL _cmd,...);
1051 * _objc_msgForward and _objc_msgForward_stret are the externally-callable
1052 * functions returned by things like method_getImplementation().
1053 * _objc_msgForward_impcache is the function pointer actually stored in
1056 ********************************************************************/
1058 STATIC_ENTRY __objc_msgForward_impcache
1059 // Method cache version
1061 // THIS IS NOT A CALLABLE C FUNCTION
1062 // Out-of-band condition register is NE for stret, EQ otherwise.
1064 jne __objc_msgForward_stret
1065 jmp __objc_msgForward
1067 END_ENTRY __objc_msgForward_impcache
1070 ENTRY __objc_msgForward
1071 // Non-stret version
1073 movq __objc_forward_handler(%rip), %r11
1076 END_ENTRY __objc_msgForward
1079 ENTRY __objc_msgForward_stret
1080 // Struct-return version
1082 movq __objc_forward_stret_handler(%rip), %r11
1085 END_ENTRY __objc_msgForward_stret
1088 ENTRY _objc_msgSend_debug
1090 END_ENTRY _objc_msgSend_debug
1092 ENTRY _objc_msgSendSuper2_debug
1093 jmp _objc_msgSendSuper2
1094 END_ENTRY _objc_msgSendSuper2_debug
1096 ENTRY _objc_msgSend_stret_debug
1097 jmp _objc_msgSend_stret
1098 END_ENTRY _objc_msgSend_stret_debug
1100 ENTRY _objc_msgSendSuper2_stret_debug
1101 jmp _objc_msgSendSuper2_stret
1102 END_ENTRY _objc_msgSendSuper2_stret_debug
1104 ENTRY _objc_msgSend_fpret_debug
1105 jmp _objc_msgSend_fpret
1106 END_ENTRY _objc_msgSend_fpret_debug
1108 ENTRY _objc_msgSend_fp2ret_debug
1109 jmp _objc_msgSend_fp2ret
1110 END_ENTRY _objc_msgSend_fp2ret_debug
1113 ENTRY _objc_msgSend_noarg
1115 END_ENTRY _objc_msgSend_noarg
1118 ENTRY _method_invoke
1120 movq method_imp(%a2), %r11
1121 movq method_name(%a2), %a2
1124 END_ENTRY _method_invoke
1127 ENTRY _method_invoke_stret
1129 movq method_imp(%a3), %r11
1130 movq method_name(%a3), %a3
1133 END_ENTRY _method_invoke_stret
1136 .section __DATA,__objc_msg_break