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 ********************************************************************/
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 /********************************************************************
139 * Structure definitions.
141 ********************************************************************/
143 // objc_super parameter to sendSuper
147 // Selected field offsets in class structure
148 // #define isa 0 USE GetIsa INSTEAD
151 #define method_name 0
152 #define method_imp 16
159 //////////////////////////////////////////////////////////////////////
161 // ENTRY functionName
163 // Assembly directives to begin an exported function.
165 // Takes: functionName - name of the exported function
166 //////////////////////////////////////////////////////////////////////
182 //////////////////////////////////////////////////////////////////////
184 // END_ENTRY functionName
186 // Assembly directives to end an exported function. Just a placeholder,
187 // a close-parenthesis for ENTRY, until it is needed for something.
189 // Takes: functionName - name of the exported function
190 //////////////////////////////////////////////////////////////////////
197 /********************************************************************
199 * Unwind info generation
200 ********************************************************************/
202 .section __LD,__compact_unwind,regular,debug
204 .set LUnwind$0, LExit$0 - $0
207 .quad 0 /* no personality */
208 .quad 0 /* no LSDA */
212 #define NoFrame 0x02010000 // no frame, no SP adjustment except return address
213 #define FrameWithNoSaves 0x01000000 // frame, no non-volatile saves
216 //////////////////////////////////////////////////////////////////////
220 // Create a stack frame and save all argument registers in preparation
221 // for a function call.
222 //////////////////////////////////////////////////////////////////////
229 sub $$0x80+8, %rsp // +8 for alignment
231 movdqa %xmm0, -0x80(%rbp)
232 push %rax // might be xmm parameter count
233 movdqa %xmm1, -0x70(%rbp)
235 movdqa %xmm2, -0x60(%rbp)
237 movdqa %xmm3, -0x50(%rbp)
239 movdqa %xmm4, -0x40(%rbp)
241 movdqa %xmm5, -0x30(%rbp)
243 movdqa %xmm6, -0x20(%rbp)
245 movdqa %xmm7, -0x10(%rbp)
250 //////////////////////////////////////////////////////////////////////
254 // Restore all argument registers and pop the stack frame created by
256 //////////////////////////////////////////////////////////////////////
260 movdqa -0x80(%rbp), %xmm0
262 movdqa -0x70(%rbp), %xmm1
264 movdqa -0x60(%rbp), %xmm2
266 movdqa -0x50(%rbp), %xmm3
268 movdqa -0x40(%rbp), %xmm4
270 movdqa -0x30(%rbp), %xmm5
272 movdqa -0x20(%rbp), %xmm6
274 movdqa -0x10(%rbp), %xmm7
280 /////////////////////////////////////////////////////////////////////
282 // CacheLookup return-type, caller
284 // Locate the implementation for a class in a selector's method cache.
287 // $0 = NORMAL, FPRET, FP2RET, STRET
288 // $1 = CALL, LOOKUP, GETIMP
289 // a1 or a2 (STRET) = receiver
290 // a2 or a3 (STRET) = selector
291 // r10 = class to search
293 // On exit: r10 clobbered
294 // (found) calls or returns IMP in r11, eq/ne set for forwarding
295 // (not found) jumps to LCacheMiss, class still in r10
297 /////////////////////////////////////////////////////////////////////
301 // r11 = found bucket
304 movq cached_imp(%r11), %rax // return imp
306 jz 9f // don't xor a nil imp
307 xorq %r10, %rax // xor the isa with the imp
313 movq cached_imp(%r11), %r11 // load imp
314 xorq %r10, %r11 // xor imp and isa
316 // ne already set for forwarding by `xor`
318 cmp %r11, %r11 // set eq for stret forwarding
320 jmp *%r11 // call imp
323 movq cached_imp(%r11), %r11
324 xorq %r10, %r11 // return imp ^ isa
338 movq %a2, %r11 // r11 = _cmd
340 movq %a3, %r11 // r11 = _cmd
342 andl 24(%r10), %r11d // r11 = _cmd & class->cache.mask
343 shlq $$4, %r11 // r11 = offset = (_cmd & mask)<<4
344 addq 16(%r10), %r11 // r11 = class->cache.buckets + offset
347 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
349 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
352 CacheHit $0, $1 // call or return imp
356 cmpq $$1, cached_sel(%r11)
357 jbe 3f // if (bucket->sel <= 1) wrap or miss
359 addq $$16, %r11 // bucket++
362 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
364 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
367 CacheHit $0, $1 // call or return imp
371 jb LCacheMiss_f // if (bucket->sel < 1) cache miss
373 movq cached_imp(%r11), %r11 // bucket->imp is really first bucket
376 // Clone scanning loop to miss instead of hang when cache is corrupt.
377 // The slow path may detect any corruption and halt later.
381 cmpq $$1, cached_sel(%r11)
382 jbe 3f // if (bucket->sel <= 1) wrap or miss
384 addq $$16, %r11 // bucket++
387 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
389 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
392 CacheHit $0, $1 // call or return imp
395 // double wrap or miss
401 /////////////////////////////////////////////////////////////////////
403 // MethodTableLookup NORMAL|STRET
405 // Takes: a1 or a2 (STRET) = receiver
406 // a2 or a3 (STRET) = selector to search for
407 // r10 = class to search
409 // On exit: imp in %r11, eq/ne set for forwarding
411 /////////////////////////////////////////////////////////////////////
413 .macro MethodTableLookup
417 // lookUpImpOrForward(obj, sel, cls, LOOKUP_INITIALIZE | LOOKUP_RESOLVER)
419 // receiver already in a1
420 // selector already in a2
427 call _lookUpImpOrForward
429 // IMP is now in %rax
435 test %r11, %r11 // set ne for stret forwarding
437 cmp %r11, %r11 // set eq for nonstret forwarding
443 /////////////////////////////////////////////////////////////////////
445 // GetIsaCheckNil return-type
446 // GetIsaSupport return-type
447 // NilTestReturnZero return-type
448 // NilTestReturnIMP return-type
450 // Sets r10 = obj->isa.
451 // Looks up the real class if receiver is a tagged pointer object.
452 // Returns zero or a zero-returning IMP if obj is nil.
454 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
455 // a1 or a2 (STRET) = receiver
457 // On exit from GetIsaCheckNil:
458 // r10 = receiver->isa
461 /////////////////////////////////////////////////////////////////////
470 .macro ZeroReturnFPRET
475 .macro ZeroReturnFP2RET
481 .macro ZeroReturnSTRET
482 // rax gets the struct-return address as passed in rdi
486 STATIC_ENTRY __objc_msgNil
489 END_ENTRY __objc_msgNil
491 STATIC_ENTRY __objc_msgNil_fpret
494 END_ENTRY __objc_msgNil_fpret
496 STATIC_ENTRY __objc_msgNil_fp2ret
499 END_ENTRY __objc_msgNil_fp2ret
501 STATIC_ENTRY __objc_msgNil_stret
504 END_ENTRY __objc_msgNil_stret
507 .macro GetIsaCheckNil
513 jle LNilOrTagged_f // MSB tagged pointer looks negative
516 movq (%a1), %r10 // r10 = isa
518 movq (%a2), %r10 // r10 = isa
528 jz LNil_f // flags set by GetIsaCheckNil
536 leaq _objc_debug_taggedpointer_classes(%rip), %r10
537 movq (%r10, %r11, 8), %r10 // read isa from table
538 leaq _OBJC_CLASS_$___NSUnrecognizedTaggedPointer(%rip), %r11
549 leaq _objc_debug_taggedpointer_ext_classes(%rip), %r10
550 movq (%r10, %r11, 8), %r10 // read isa from table
555 .macro NilTestReturnZero
572 .macro NilTestReturnIMP
575 leaq __objc_msgNil(%rip), %r11
577 leaq __objc_msgNil_fpret(%rip), %r11
579 leaq __objc_msgNil_fp2ret(%rip), %r11
581 leaq __objc_msgNil_stret(%rip), %r11
589 /********************************************************************
590 * IMP cache_getImp(Class cls, SEL sel)
592 * On entry: a1 = class whose cache is to be searched
593 * a2 = selector to search for
595 * If found, returns method implementation.
596 * If not found, returns NULL.
597 ********************************************************************/
599 STATIC_ENTRY _cache_getImp
602 movq %a1, %r10 // move class to r10 for CacheLookup
603 CacheLookup NORMAL, GETIMP // returns IMP on success
606 // cache miss, return nil
610 END_ENTRY _cache_getImp
613 /********************************************************************
615 * id objc_msgSend(id self, SEL _cmd,...);
616 * IMP objc_msgLookup(id self, SEL _cmd, ...);
618 * objc_msgLookup ABI:
619 * IMP returned in r11
620 * Forwarding returned in Z flag
621 * r10 reserved for our use but not used
623 ********************************************************************/
627 .globl _objc_debug_taggedpointer_classes
628 _objc_debug_taggedpointer_classes:
630 .globl _objc_debug_taggedpointer_ext_classes
631 _objc_debug_taggedpointer_ext_classes:
635 UNWIND _objc_msgSend, NoFrame
637 GetIsaCheckNil NORMAL // r10 = self->isa, or return zero
638 CacheLookup NORMAL, CALL // calls IMP on success
641 NilTestReturnZero NORMAL
643 // cache miss: go search the method lists
646 jmp __objc_msgSend_uncached
648 END_ENTRY _objc_msgSend
651 ENTRY _objc_msgLookup
653 GetIsaCheckNil NORMAL // r10 = self->isa, or return zero IMP
654 CacheLookup NORMAL, LOOKUP // returns IMP on success
657 NilTestReturnIMP NORMAL
659 // cache miss: go search the method lists
662 jmp __objc_msgLookup_uncached
664 END_ENTRY _objc_msgLookup
667 ENTRY _objc_msgSend_fixup
669 END_ENTRY _objc_msgSend_fixup
672 STATIC_ENTRY _objc_msgSend_fixedup
673 // Load _cmd from the message_ref
676 END_ENTRY _objc_msgSend_fixedup
679 /********************************************************************
681 * id objc_msgSendSuper(struct objc_super *super, SEL _cmd,...);
683 * struct objc_super {
687 ********************************************************************/
689 ENTRY _objc_msgSendSuper
690 UNWIND _objc_msgSendSuper, NoFrame
692 // search the cache (objc_super in %a1)
693 movq class(%a1), %r10 // class = objc_super->class
694 movq receiver(%a1), %a1 // load real receiver
695 CacheLookup NORMAL, CALL // calls IMP on success
697 // cache miss: go search the method lists
699 // class still in r10
700 jmp __objc_msgSend_uncached
702 END_ENTRY _objc_msgSendSuper
705 /********************************************************************
706 * id objc_msgSendSuper2
707 ********************************************************************/
709 ENTRY _objc_msgSendSuper2
710 UNWIND _objc_msgSendSuper2, NoFrame
712 // objc_super->class is superclass of class to search
714 // search the cache (objc_super in %a1)
715 movq class(%a1), %r10 // cls = objc_super->class
716 movq receiver(%a1), %a1 // load real receiver
717 movq 8(%r10), %r10 // cls = class->superclass
718 CacheLookup NORMAL, CALL // calls IMP on success
720 // cache miss: go search the method lists
722 // superclass still in r10
723 jmp __objc_msgSend_uncached
725 END_ENTRY _objc_msgSendSuper2
728 ENTRY _objc_msgLookupSuper2
730 // objc_super->class is superclass of class to search
732 // search the cache (objc_super in %a1)
733 movq class(%a1), %r10 // cls = objc_super->class
734 movq receiver(%a1), %a1 // load real receiver
735 movq 8(%r10), %r10 // cls = class->superclass
736 CacheLookup NORMAL, LOOKUP // returns IMP on success
738 // cache miss: go search the method lists
740 // superclass still in r10
741 jmp __objc_msgLookup_uncached
743 END_ENTRY _objc_msgLookupSuper2
746 ENTRY _objc_msgSendSuper2_fixup
748 END_ENTRY _objc_msgSendSuper2_fixup
751 STATIC_ENTRY _objc_msgSendSuper2_fixedup
752 // Load _cmd from the message_ref
754 jmp _objc_msgSendSuper2
755 END_ENTRY _objc_msgSendSuper2_fixedup
758 /********************************************************************
760 * double objc_msgSend_fpret(id self, SEL _cmd,...);
761 * Used for `long double` return only. `float` and `double` use objc_msgSend.
763 ********************************************************************/
765 ENTRY _objc_msgSend_fpret
766 UNWIND _objc_msgSend_fpret, NoFrame
768 GetIsaCheckNil FPRET // r10 = self->isa, or return zero
769 CacheLookup FPRET, CALL // calls IMP on success
772 NilTestReturnZero FPRET
774 // cache miss: go search the method lists
777 jmp __objc_msgSend_uncached
779 END_ENTRY _objc_msgSend_fpret
782 ENTRY _objc_msgLookup_fpret
784 GetIsaCheckNil FPRET // r10 = self->isa, or return zero IMP
785 CacheLookup FPRET, LOOKUP // returns IMP on success
788 NilTestReturnIMP FPRET
790 // cache miss: go search the method lists
793 jmp __objc_msgLookup_uncached
795 END_ENTRY _objc_msgLookup_fpret
798 ENTRY _objc_msgSend_fpret_fixup
800 END_ENTRY _objc_msgSend_fpret_fixup
803 STATIC_ENTRY _objc_msgSend_fpret_fixedup
804 // Load _cmd from the message_ref
806 jmp _objc_msgSend_fpret
807 END_ENTRY _objc_msgSend_fpret_fixedup
810 /********************************************************************
812 * double objc_msgSend_fp2ret(id self, SEL _cmd,...);
813 * Used for `complex long double` return only.
815 ********************************************************************/
817 ENTRY _objc_msgSend_fp2ret
818 UNWIND _objc_msgSend_fp2ret, NoFrame
820 GetIsaCheckNil FP2RET // r10 = self->isa, or return zero
821 CacheLookup FP2RET, CALL // calls IMP on success
824 NilTestReturnZero FP2RET
826 // cache miss: go search the method lists
829 jmp __objc_msgSend_uncached
831 END_ENTRY _objc_msgSend_fp2ret
834 ENTRY _objc_msgLookup_fp2ret
836 GetIsaCheckNil FP2RET // r10 = self->isa, or return zero IMP
837 CacheLookup FP2RET, LOOKUP // returns IMP on success
840 NilTestReturnIMP FP2RET
842 // cache miss: go search the method lists
845 jmp __objc_msgLookup_uncached
847 END_ENTRY _objc_msgLookup_fp2ret
850 ENTRY _objc_msgSend_fp2ret_fixup
852 END_ENTRY _objc_msgSend_fp2ret_fixup
855 STATIC_ENTRY _objc_msgSend_fp2ret_fixedup
856 // Load _cmd from the message_ref
858 jmp _objc_msgSend_fp2ret
859 END_ENTRY _objc_msgSend_fp2ret_fixedup
862 /********************************************************************
864 * void objc_msgSend_stret(void *st_addr, id self, SEL _cmd, ...);
866 * objc_msgSend_stret is the struct-return form of msgSend.
867 * The ABI calls for %a1 to be used as the address of the structure
868 * being returned, with the parameters in the succeeding locations.
870 * On entry: %a1 is the address where the structure is returned,
871 * %a2 is the message receiver,
872 * %a3 is the selector
873 ********************************************************************/
875 ENTRY _objc_msgSend_stret
876 UNWIND _objc_msgSend_stret, NoFrame
878 GetIsaCheckNil STRET // r10 = self->isa, or return zero
879 CacheLookup STRET, CALL // calls IMP on success
882 NilTestReturnZero STRET
884 // cache miss: go search the method lists
887 jmp __objc_msgSend_stret_uncached
889 END_ENTRY _objc_msgSend_stret
892 ENTRY _objc_msgLookup_stret
894 GetIsaCheckNil STRET // r10 = self->isa, or return zero IMP
895 CacheLookup STRET, LOOKUP // returns IMP on success
898 NilTestReturnIMP STRET
900 // cache miss: go search the method lists
903 jmp __objc_msgLookup_stret_uncached
905 END_ENTRY _objc_msgLookup_stret
908 ENTRY _objc_msgSend_stret_fixup
910 END_ENTRY _objc_msgSend_stret_fixup
913 STATIC_ENTRY _objc_msgSend_stret_fixedup
914 // Load _cmd from the message_ref
916 jmp _objc_msgSend_stret
917 END_ENTRY _objc_msgSend_stret_fixedup
920 /********************************************************************
922 * void objc_msgSendSuper_stret(void *st_addr, struct objc_super *super, SEL _cmd, ...);
924 * struct objc_super {
929 * objc_msgSendSuper_stret is the struct-return form of msgSendSuper.
930 * The ABI calls for (sp+4) to be used as the address of the structure
931 * being returned, with the parameters in the succeeding registers.
933 * On entry: %a1 is the address where the structure is returned,
934 * %a2 is the address of the objc_super structure,
935 * %a3 is the selector
937 ********************************************************************/
939 ENTRY _objc_msgSendSuper_stret
940 UNWIND _objc_msgSendSuper_stret, NoFrame
942 // search the cache (objc_super in %a2)
943 movq class(%a2), %r10 // class = objc_super->class
944 movq receiver(%a2), %a2 // load real receiver
945 CacheLookup STRET, CALL // calls IMP on success
947 // cache miss: go search the method lists
949 // class still in r10
950 jmp __objc_msgSend_stret_uncached
952 END_ENTRY _objc_msgSendSuper_stret
955 /********************************************************************
956 * id objc_msgSendSuper2_stret
957 ********************************************************************/
959 ENTRY _objc_msgSendSuper2_stret
960 UNWIND _objc_msgSendSuper2_stret, NoFrame
962 // search the cache (objc_super in %a2)
963 movq class(%a2), %r10 // class = objc_super->class
964 movq receiver(%a2), %a2 // load real receiver
965 movq 8(%r10), %r10 // class = class->superclass
966 CacheLookup STRET, CALL // calls IMP on success
968 // cache miss: go search the method lists
970 // superclass still in r10
971 jmp __objc_msgSend_stret_uncached
973 END_ENTRY _objc_msgSendSuper2_stret
976 ENTRY _objc_msgLookupSuper2_stret
978 // search the cache (objc_super in %a2)
979 movq class(%a2), %r10 // class = objc_super->class
980 movq receiver(%a2), %a2 // load real receiver
981 movq 8(%r10), %r10 // class = class->superclass
982 CacheLookup STRET, LOOKUP // returns IMP on success
984 // cache miss: go search the method lists
986 // superclass still in r10
987 jmp __objc_msgLookup_stret_uncached
989 END_ENTRY _objc_msgLookupSuper2_stret
992 ENTRY _objc_msgSendSuper2_stret_fixup
994 END_ENTRY _objc_msgSendSuper2_stret_fixup
997 STATIC_ENTRY _objc_msgSendSuper2_stret_fixedup
998 // Load _cmd from the message_ref
1000 jmp _objc_msgSendSuper2_stret
1001 END_ENTRY _objc_msgSendSuper2_stret_fixedup
1004 /********************************************************************
1006 * _objc_msgSend_uncached
1007 * _objc_msgSend_stret_uncached
1008 * The uncached method lookup.
1010 ********************************************************************/
1012 STATIC_ENTRY __objc_msgSend_uncached
1013 UNWIND __objc_msgSend_uncached, FrameWithNoSaves
1015 // THIS IS NOT A CALLABLE C FUNCTION
1016 // Out-of-band r10 is the searched class
1018 // r10 is already the class to search
1019 MethodTableLookup NORMAL // r11 = IMP
1020 jmp *%r11 // goto *imp
1022 END_ENTRY __objc_msgSend_uncached
1025 STATIC_ENTRY __objc_msgSend_stret_uncached
1026 UNWIND __objc_msgSend_stret_uncached, FrameWithNoSaves
1028 // THIS IS NOT A CALLABLE C FUNCTION
1029 // Out-of-band r10 is the searched class
1031 // r10 is already the class to search
1032 MethodTableLookup STRET // r11 = IMP
1033 jmp *%r11 // goto *imp
1035 END_ENTRY __objc_msgSend_stret_uncached
1038 STATIC_ENTRY __objc_msgLookup_uncached
1039 UNWIND __objc_msgLookup_uncached, FrameWithNoSaves
1041 // THIS IS NOT A CALLABLE C FUNCTION
1042 // Out-of-band r10 is the searched class
1044 // r10 is already the class to search
1045 MethodTableLookup NORMAL // r11 = IMP
1048 END_ENTRY __objc_msgLookup_uncached
1051 STATIC_ENTRY __objc_msgLookup_stret_uncached
1052 UNWIND __objc_msgLookup_stret_uncached, FrameWithNoSaves
1054 // THIS IS NOT A CALLABLE C FUNCTION
1055 // Out-of-band r10 is the searched class
1057 // r10 is already the class to search
1058 MethodTableLookup STRET // r11 = IMP
1061 END_ENTRY __objc_msgLookup_stret_uncached
1064 /********************************************************************
1066 * id _objc_msgForward(id self, SEL _cmd,...);
1068 * _objc_msgForward and _objc_msgForward_stret are the externally-callable
1069 * functions returned by things like method_getImplementation().
1070 * _objc_msgForward_impcache is the function pointer actually stored in
1073 ********************************************************************/
1075 STATIC_ENTRY __objc_msgForward_impcache
1076 // Method cache version
1078 // THIS IS NOT A CALLABLE C FUNCTION
1079 // Out-of-band condition register is NE for stret, EQ otherwise.
1081 je __objc_msgForward_stret
1082 jmp __objc_msgForward
1084 END_ENTRY __objc_msgForward_impcache
1087 ENTRY __objc_msgForward
1088 // Non-stret version
1090 movq __objc_forward_handler(%rip), %r11
1093 END_ENTRY __objc_msgForward
1096 ENTRY __objc_msgForward_stret
1097 // Struct-return version
1099 movq __objc_forward_stret_handler(%rip), %r11
1102 END_ENTRY __objc_msgForward_stret
1105 ENTRY _objc_msgSend_debug
1107 END_ENTRY _objc_msgSend_debug
1109 ENTRY _objc_msgSendSuper2_debug
1110 jmp _objc_msgSendSuper2
1111 END_ENTRY _objc_msgSendSuper2_debug
1113 ENTRY _objc_msgSend_stret_debug
1114 jmp _objc_msgSend_stret
1115 END_ENTRY _objc_msgSend_stret_debug
1117 ENTRY _objc_msgSendSuper2_stret_debug
1118 jmp _objc_msgSendSuper2_stret
1119 END_ENTRY _objc_msgSendSuper2_stret_debug
1121 ENTRY _objc_msgSend_fpret_debug
1122 jmp _objc_msgSend_fpret
1123 END_ENTRY _objc_msgSend_fpret_debug
1125 ENTRY _objc_msgSend_fp2ret_debug
1126 jmp _objc_msgSend_fp2ret
1127 END_ENTRY _objc_msgSend_fp2ret_debug
1130 ENTRY _objc_msgSend_noarg
1132 END_ENTRY _objc_msgSend_noarg
1135 ENTRY _method_invoke
1137 // See if this is a small method.
1139 jnz L_method_invoke_small
1141 // We can directly load the IMP from big methods.
1142 movq method_imp(%a2), %r11
1143 movq method_name(%a2), %a2
1146 L_method_invoke_small:
1147 // Small methods require a call to handle swizzling.
1150 call __method_getImplementationAndName
1157 END_ENTRY _method_invoke
1160 ENTRY _method_invoke_stret
1162 // See if this is a small method.
1164 jnz L_method_invoke_stret_small
1166 // We can directly load the IMP from big methods.
1167 movq method_imp(%a3), %r11
1168 movq method_name(%a3), %a3
1171 L_method_invoke_stret_small:
1172 // Small methods require a call to handle swizzling.
1175 call __method_getImplementationAndName
1182 END_ENTRY _method_invoke_stret
1185 .section __DATA,__objc_msg_break