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_IPHONE_SIMULATOR
27 /********************************************************************
28 ********************************************************************
30 ** objc-msg-x86_64.s - x86-64 code to support objc messaging.
32 ********************************************************************
33 ********************************************************************/
35 /********************************************************************
36 * Data used by the ObjC runtime.
38 ********************************************************************/
42 // _objc_entryPoints and _objc_exitPoints are used by objc
43 // to get the critical regions for which method caches
44 // cannot be garbage collected.
46 .private_extern _objc_entryPoints
50 .quad _objc_msgSend_fpret
51 .quad _objc_msgSend_fp2ret
52 .quad _objc_msgSend_stret
53 .quad _objc_msgSendSuper
54 .quad _objc_msgSendSuper_stret
55 .quad _objc_msgSendSuper2
56 .quad _objc_msgSendSuper2_stret
59 .private_extern _objc_exitPoints
61 .quad LExit_cache_getImp
62 .quad LExit_objc_msgSend
63 .quad LExit_objc_msgSend_fpret
64 .quad LExit_objc_msgSend_fp2ret
65 .quad LExit_objc_msgSend_stret
66 .quad LExit_objc_msgSendSuper
67 .quad LExit_objc_msgSendSuper_stret
68 .quad LExit_objc_msgSendSuper2
69 .quad LExit_objc_msgSendSuper2_stret
73 /********************************************************************
74 * List every exit insn from every messenger for debugger use.
77 * 1 word instruction's address
78 * 1 word type (ENTER or FAST_EXIT or SLOW_EXIT or NIL_EXIT)
82 * ENTER is the start of a dispatcher
83 * FAST_EXIT is method dispatch
84 * SLOW_EXIT is uncached method lookup
85 * NIL_EXIT is returning zero from a message sent to nil
86 * These must match objc-gdb.h.
87 ********************************************************************/
94 .section __DATA,__objc_msg_break
95 .globl _gdb_objc_messenger_breakpoints
96 _gdb_objc_messenger_breakpoints:
97 // contents populated by the macros below
99 .macro MESSENGER_START
101 .section __DATA,__objc_msg_break
106 .macro MESSENGER_END_FAST
108 .section __DATA,__objc_msg_break
113 .macro MESSENGER_END_SLOW
115 .section __DATA,__objc_msg_break
120 .macro MESSENGER_END_NIL
122 .section __DATA,__objc_msg_break
129 /********************************************************************
130 * Recommended multi-byte NOP instructions
131 * (Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2B)
132 ********************************************************************/
133 #define nop1 .byte 0x90
134 #define nop2 .byte 0x66,0x90
135 #define nop3 .byte 0x0F,0x1F,0x00
136 #define nop4 .byte 0x0F,0x1F,0x40,0x00
137 #define nop5 .byte 0x0F,0x1F,0x44,0x00,0x00
138 #define nop6 .byte 0x66,0x0F,0x1F,0x44,0x00,0x00
139 #define nop7 .byte 0x0F,0x1F,0x80,0x00,0x00,0x00,0x00
140 #define nop8 .byte 0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
141 #define nop9 .byte 0x66,0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
144 /********************************************************************
145 * Harmless branch prefix hint for instruction alignment
146 ********************************************************************/
148 #define PN .byte 0x2e
151 /********************************************************************
152 * Names for parameter registers.
153 ********************************************************************/
171 /********************************************************************
172 * Names for relative labels
173 * DO NOT USE THESE LABELS ELSEWHERE
174 * Reserved labels: 6: 7: 8: 9:
175 ********************************************************************/
177 #define LCacheMiss_f 6f
178 #define LCacheMiss_b 6b
179 #define LNilTestSlow 7
180 #define LNilTestSlow_f 7f
181 #define LNilTestSlow_b 7b
182 #define LGetIsaDone 8
183 #define LGetIsaDone_f 8f
184 #define LGetIsaDone_b 8b
185 #define LGetIsaSlow 9
186 #define LGetIsaSlow_f 9f
187 #define LGetIsaSlow_b 9b
189 /********************************************************************
191 ********************************************************************/
199 #define SUPER_STRET 6
201 #define SUPER2_STRET 8
204 /********************************************************************
206 * Structure definitions.
208 ********************************************************************/
210 // objc_super parameter to sendSuper
214 // Selected field offsets in class structure
215 // #define isa 0 USE GetIsa INSTEAD
218 #define method_name 0
219 #define method_imp 16
222 // uint128_t floatingPointArgs[8]; // xmm0..xmm7
223 // long linkageArea[4]; // r10, rax, ebp, ret
224 // long registerArgs[6]; // a1..a6
225 // long stackArgs[0]; // variable-size
228 #define LINK_AREA (FP_AREA+8*16)
229 #define REG_AREA (LINK_AREA+4*8)
230 #define STACK_AREA (REG_AREA+6*8)
233 //////////////////////////////////////////////////////////////////////
235 // ENTRY functionName
237 // Assembly directives to begin an exported function.
239 // Takes: functionName - name of the exported function
240 //////////////////////////////////////////////////////////////////////
258 //////////////////////////////////////////////////////////////////////
260 // END_ENTRY functionName
262 // Assembly directives to end an exported function. Just a placeholder,
263 // a close-parenthesis for ENTRY, until it is needed for something.
265 // Takes: functionName - name of the exported function
266 //////////////////////////////////////////////////////////////////////
274 /////////////////////////////////////////////////////////////////////
278 // Pushes a stack frame and saves all registers that might contain
285 // %rsp is 16-byte aligned
287 /////////////////////////////////////////////////////////////////////
292 .cfi_def_cfa_offset 16
296 .cfi_def_cfa_register rbp
298 sub $$0x80+8, %rsp // +8 for alignment
300 movdqa %xmm0, -0x80(%rbp)
301 push %rax // might be xmm parameter count
302 movdqa %xmm1, -0x70(%rbp)
304 movdqa %xmm2, -0x60(%rbp)
306 movdqa %xmm3, -0x50(%rbp)
308 movdqa %xmm4, -0x40(%rbp)
310 movdqa %xmm5, -0x30(%rbp)
312 movdqa %xmm6, -0x20(%rbp)
314 movdqa %xmm7, -0x10(%rbp)
318 /////////////////////////////////////////////////////////////////////
322 // Pops a stack frame pushed by SaveRegisters
325 // %rbp unchanged since SaveRegisters
330 /////////////////////////////////////////////////////////////////////
332 .macro RestoreRegisters
334 movdqa -0x80(%rbp), %xmm0
336 movdqa -0x70(%rbp), %xmm1
338 movdqa -0x60(%rbp), %xmm2
340 movdqa -0x50(%rbp), %xmm3
342 movdqa -0x40(%rbp), %xmm4
344 movdqa -0x30(%rbp), %xmm5
346 movdqa -0x20(%rbp), %xmm6
348 movdqa -0x10(%rbp), %xmm7
357 /////////////////////////////////////////////////////////////////////
359 // CacheLookup return-type, caller
361 // Locate the implementation for a class in a selector's method cache.
364 // $0 = NORMAL, FPRET, FP2RET, STRET, SUPER, SUPER_STRET, SUPER2, SUPER2_STRET, GETIMP
365 // a2 or a3 (STRET) = selector a.k.a. cache
366 // r11 = class to search
368 // On exit: r10 clobbered
369 // (found) calls or returns IMP, eq/ne/r11 set for forwarding
370 // (not found) jumps to LCacheMiss, class still in r11
372 /////////////////////////////////////////////////////////////////////
376 // CacheHit must always be preceded by a not-taken `jne` instruction
377 // in order to set the correct flags for _objc_msgForward_impcache.
379 // r10 = found bucket
382 movq 8(%r10), %rax // return imp
383 leaq __objc_msgSend_uncached_impcache(%rip), %r11
386 xorl %eax, %eax // don't return msgSend_uncached
388 .elseif $0 == NORMAL || $0 == FPRET || $0 == FP2RET
389 // eq already set for forwarding by `jne`
391 jmp *8(%r10) // call imp
394 movq receiver(%a1), %a1 // load real receiver
395 cmp %r10, %r10 // set eq for non-stret forwarding
397 jmp *8(%r10) // call imp
400 movq receiver(%a1), %a1 // load real receiver
401 cmp %r10, %r10 // set eq for non-stret forwarding
403 jmp *8(%r10) // call imp
406 test %r10, %r10 // set ne for stret forwarding
408 jmp *8(%r10) // call imp
410 .elseif $0 == SUPER_STRET
411 movq receiver(%a2), %a2 // load real receiver
412 test %r10, %r10 // set ne for stret forwarding
414 jmp *8(%r10) // call imp
416 .elseif $0 == SUPER2_STRET
417 movq receiver(%a2), %a2 // load real receiver
418 test %r10, %r10 // set ne for stret forwarding
420 jmp *8(%r10) // call imp
429 .if $0 != STRET && $0 != SUPER_STRET && $0 != SUPER2_STRET
430 movq %a2, %r10 // r10 = _cmd
432 movq %a3, %r10 // r10 = _cmd
434 andl 24(%r11), %r10d // r10 = _cmd & class->cache.mask
435 shlq $$4, %r10 // r10 = offset = (_cmd & mask)<<4
436 addq 16(%r11), %r10 // r10 = class->cache.buckets + offset
438 .if $0 != STRET && $0 != SUPER_STRET && $0 != SUPER2_STRET
439 cmpq (%r10), %a2 // if (bucket->sel != _cmd)
441 cmpq (%r10), %a3 // if (bucket->sel != _cmd)
444 // CacheHit must always be preceded by a not-taken `jne` instruction
445 CacheHit $0 // call or return imp
450 je LCacheMiss_f // if (bucket->sel == 0) cache miss
452 je 3f // if (bucket == cache->buckets) wrap
454 subq $$16, %r10 // bucket--
456 .if $0 != STRET && $0 != SUPER_STRET && $0 != SUPER2_STRET
457 cmpq (%r10), %a2 // if (bucket->sel != _cmd)
459 cmpq (%r10), %a3 // if (bucket->sel != _cmd)
462 // CacheHit must always be preceded by a not-taken `jne` instruction
463 CacheHit $0 // call or return imp
467 movl 24(%r11), %r10d // r10 = mask a.k.a. last bucket index
468 shlq $$4, %r10 // r10 = offset = mask<<4
469 addq 16(%r11), %r10 // r10 = &cache->buckets[mask]
472 // clone scanning loop to crash instead of hang when cache is corrupt
477 je LCacheMiss_f // if (bucket->sel == 0) cache miss
479 je 3f // if (bucket == cache->buckets) wrap
481 subq $$16, %r10 // bucket--
483 .if $0 != STRET && $0 != SUPER_STRET && $0 != SUPER2_STRET
484 cmpq (%r10), %a2 // if (bucket->sel != _cmd)
486 cmpq (%r10), %a3 // if (bucket->sel != _cmd)
489 // CacheHit must always be preceded by a not-taken `jne` instruction
490 CacheHit $0 // call or return imp
493 // double wrap - busted
494 .if $0 == STRET || $0 == SUPER_STRET || $0 == SUPER2_STRET
502 movq %r11, %a3 // a3 = isa
504 jmp _cache_getImp_corrupt_cache_error
506 jmp _objc_msgSend_corrupt_cache_error
512 /////////////////////////////////////////////////////////////////////
514 // MethodTableLookup classRegister, selectorRegister
516 // Takes: $0 = class to search (a1 or a2 or r10 ONLY)
517 // $1 = selector to search for (a2 or a3 ONLY)
518 // r11 = class to search
520 // On exit: imp in %r11
522 /////////////////////////////////////////////////////////////////////
523 .macro MethodTableLookup
529 // _class_lookupMethodAndLoadCache3(receiver, selector, class)
534 call __class_lookupMethodAndLoadCache3
536 // IMP is now in %rax
543 /////////////////////////////////////////////////////////////////////
545 // GetIsaFast return-type
546 // GetIsaSupport return-type
548 // Sets r11 = obj->isa. Consults the tagged isa table if necessary.
550 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
551 // a1 or a2 (STRET) = receiver
553 // On exit: r11 = receiver->isa
556 /////////////////////////////////////////////////////////////////////
563 movq $$0x00007ffffffffff8, %r11
569 movq $$0x00007ffffffffff8, %r11
575 .macro GetIsaSupport2
577 leaq _objc_debug_taggedpointer_classes(%rip), %r11
584 movq (%r11, %r10, 8), %r11 // read isa from table
600 /////////////////////////////////////////////////////////////////////
602 // NilTest return-type
604 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
605 // %a1 or %a2 (STRET) = receiver
607 // On exit: Loads non-nil receiver in %a1 or %a2 (STRET), or returns zero.
609 // NilTestSupport return-type
611 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
612 // %a1 or %a2 (STRET) = receiver
614 // On exit: Loads non-nil receiver in %a1 or %a2 (STRET), or returns zero.
616 /////////////////////////////////////////////////////////////////////
619 .if $0 == SUPER || $0 == SUPER_STRET
620 error super dispatch does not test for nil
632 .macro NilTestSupport
654 /********************************************************************
655 * IMP cache_getImp(Class cls, SEL sel)
657 * On entry: a1 = class whose cache is to be searched
658 * a2 = selector to search for
660 * If found, returns method implementation.
661 * If not found, returns NULL.
662 ********************************************************************/
664 STATIC_ENTRY _cache_getImp
667 movq %a1, %r11 // move class to r11 for CacheLookup
668 CacheLookup GETIMP // returns IMP on success
671 // cache miss, return nil
676 END_ENTRY _cache_getImp
679 /********************************************************************
681 * id objc_msgSend(id self, SEL _cmd,...);
683 ********************************************************************/
687 .globl _objc_debug_taggedpointer_classes
688 _objc_debug_taggedpointer_classes:
696 GetIsaFast NORMAL // r11 = self->isa
697 CacheLookup NORMAL // calls IMP on success
699 NilTestSupport NORMAL
703 // cache miss: go search the method lists
706 MethodTableLookup %a1, %a2 // r11 = IMP
707 cmp %r11, %r11 // set eq (nonstret) for forwarding
708 jmp *%r11 // goto *imp
710 END_ENTRY _objc_msgSend
713 ENTRY _objc_msgSend_fixup
715 END_ENTRY _objc_msgSend_fixup
718 STATIC_ENTRY _objc_msgSend_fixedup
719 // Load _cmd from the message_ref
722 END_ENTRY _objc_msgSend_fixedup
725 /********************************************************************
727 * id objc_msgSendSuper(struct objc_super *super, SEL _cmd,...);
729 * struct objc_super {
733 ********************************************************************/
735 ENTRY _objc_msgSendSuper
738 // search the cache (objc_super in %a1)
739 movq class(%a1), %r11 // class = objc_super->class
740 CacheLookup SUPER // calls IMP on success
742 // cache miss: go search the method lists
744 // class still in r11
745 movq receiver(%a1), %r10
746 MethodTableLookup %r10, %a2 // r11 = IMP
747 movq receiver(%a1), %a1 // load real receiver
748 cmp %r11, %r11 // set eq (nonstret) for forwarding
749 jmp *%r11 // goto *imp
751 END_ENTRY _objc_msgSendSuper
754 /********************************************************************
755 * id objc_msgSendSuper2
756 ********************************************************************/
758 ENTRY _objc_msgSendSuper2
761 // objc_super->class is superclass of class to search
763 // search the cache (objc_super in %a1)
764 movq class(%a1), %r11 // cls = objc_super->class
765 movq 8(%r11), %r11 // cls = class->superclass
766 CacheLookup SUPER2 // calls IMP on success
768 // cache miss: go search the method lists
770 // superclass still in r11
771 movq receiver(%a1), %r10
772 MethodTableLookup %r10, %a2 // r11 = IMP
773 movq receiver(%a1), %a1 // load real receiver
774 cmp %r11, %r11 // set eq (nonstret) for forwarding
775 jmp *%r11 // goto *imp
777 END_ENTRY _objc_msgSendSuper2
780 ENTRY _objc_msgSendSuper2_fixup
782 END_ENTRY _objc_msgSendSuper2_fixup
785 STATIC_ENTRY _objc_msgSendSuper2_fixedup
786 // Load _cmd from the message_ref
788 jmp _objc_msgSendSuper2
789 END_ENTRY _objc_msgSendSuper2_fixedup
792 /********************************************************************
794 * double objc_msgSend_fpret(id self, SEL _cmd,...);
795 * Used for `long double` return only. `float` and `double` use objc_msgSend.
797 ********************************************************************/
799 ENTRY _objc_msgSend_fpret
804 GetIsaFast FPRET // r11 = self->isa
805 CacheLookup FPRET // calls IMP on success
811 // cache miss: go search the method lists
814 MethodTableLookup %a1, %a2 // r11 = IMP
815 cmp %r11, %r11 // set eq (nonstret) for forwarding
816 jmp *%r11 // goto *imp
818 END_ENTRY _objc_msgSend_fpret
821 ENTRY _objc_msgSend_fpret_fixup
823 END_ENTRY _objc_msgSend_fpret_fixup
826 STATIC_ENTRY _objc_msgSend_fpret_fixedup
827 // Load _cmd from the message_ref
829 jmp _objc_msgSend_fpret
830 END_ENTRY _objc_msgSend_fpret_fixedup
833 /********************************************************************
835 * double objc_msgSend_fp2ret(id self, SEL _cmd,...);
836 * Used for `complex long double` return only.
838 ********************************************************************/
840 ENTRY _objc_msgSend_fp2ret
845 GetIsaFast FP2RET // r11 = self->isa
846 CacheLookup FP2RET // calls IMP on success
848 NilTestSupport FP2RET
852 // cache miss: go search the method lists
855 MethodTableLookup %a1, %a2 // r11 = IMP
856 cmp %r11, %r11 // set eq (nonstret) for forwarding
857 jmp *%r11 // goto *imp
859 END_ENTRY _objc_msgSend_fp2ret
862 ENTRY _objc_msgSend_fp2ret_fixup
864 END_ENTRY _objc_msgSend_fp2ret_fixup
867 STATIC_ENTRY _objc_msgSend_fp2ret_fixedup
868 // Load _cmd from the message_ref
870 jmp _objc_msgSend_fp2ret
871 END_ENTRY _objc_msgSend_fp2ret_fixedup
874 /********************************************************************
876 * void objc_msgSend_stret(void *st_addr, id self, SEL _cmd, ...);
878 * objc_msgSend_stret is the struct-return form of msgSend.
879 * The ABI calls for %a1 to be used as the address of the structure
880 * being returned, with the parameters in the succeeding locations.
882 * On entry: %a1 is the address where the structure is returned,
883 * %a2 is the message receiver,
884 * %a3 is the selector
885 ********************************************************************/
887 ENTRY _objc_msgSend_stret
892 GetIsaFast STRET // r11 = self->isa
893 CacheLookup STRET // calls IMP on success
899 // cache miss: go search the method lists
902 MethodTableLookup %a2, %a3 // r11 = IMP
903 test %r11, %r11 // set ne (stret) for forward; r11!=0
904 jmp *%r11 // goto *imp
906 END_ENTRY _objc_msgSend_stret
909 ENTRY _objc_msgSend_stret_fixup
911 END_ENTRY _objc_msgSend_stret_fixup
914 STATIC_ENTRY _objc_msgSend_stret_fixedup
915 // Load _cmd from the message_ref
917 jmp _objc_msgSend_stret
918 END_ENTRY _objc_msgSend_stret_fixedup
921 /********************************************************************
923 * void objc_msgSendSuper_stret(void *st_addr, struct objc_super *super, SEL _cmd, ...);
925 * struct objc_super {
930 * objc_msgSendSuper_stret is the struct-return form of msgSendSuper.
931 * The ABI calls for (sp+4) to be used as the address of the structure
932 * being returned, with the parameters in the succeeding registers.
934 * On entry: %a1 is the address where the structure is returned,
935 * %a2 is the address of the objc_super structure,
936 * %a3 is the selector
938 ********************************************************************/
940 ENTRY _objc_msgSendSuper_stret
943 // search the cache (objc_super in %a2)
944 movq class(%a2), %r11 // class = objc_super->class
945 CacheLookup SUPER_STRET // calls IMP on success
947 // cache miss: go search the method lists
949 // class still in r11
950 movq receiver(%a2), %r10
951 MethodTableLookup %r10, %a3 // r11 = IMP
952 movq receiver(%a2), %a2 // load real receiver
953 test %r11, %r11 // set ne (stret) for forward; r11!=0
954 jmp *%r11 // goto *imp
956 END_ENTRY _objc_msgSendSuper_stret
959 /********************************************************************
960 * id objc_msgSendSuper2_stret
961 ********************************************************************/
963 ENTRY _objc_msgSendSuper2_stret
966 // search the cache (objc_super in %a2)
967 movq class(%a2), %r11 // class = objc_super->class
968 movq 8(%r11), %r11 // class = class->superclass
969 CacheLookup SUPER2_STRET // calls IMP on success
971 // cache miss: go search the method lists
973 // superclass still in r11
974 movq receiver(%a2), %r10
975 MethodTableLookup %r10, %a3 // r11 = IMP
976 movq receiver(%a2), %a2 // load real receiver
977 test %r11, %r11 // set ne (stret) for forward; r11!=0
978 jmp *%r11 // goto *imp
980 END_ENTRY _objc_msgSendSuper2_stret
983 ENTRY _objc_msgSendSuper2_stret_fixup
985 END_ENTRY _objc_msgSendSuper2_stret_fixup
988 STATIC_ENTRY _objc_msgSendSuper2_stret_fixedup
989 // Load _cmd from the message_ref
991 jmp _objc_msgSendSuper2_stret
992 END_ENTRY _objc_msgSendSuper2_stret_fixedup
995 /********************************************************************
997 * _objc_msgSend_uncached_impcache
998 * _objc_msgSend_uncached
999 * _objc_msgSend_stret_uncached
1001 * Used to erase method cache entries in-place by
1002 * bouncing them to the uncached lookup.
1004 ********************************************************************/
1006 STATIC_ENTRY __objc_msgSend_uncached_impcache
1007 // Method cache version
1009 // THIS IS NOT A CALLABLE C FUNCTION
1010 // Out-of-band condition register is NE for stret, EQ otherwise.
1011 // Out-of-band r11 is the searched class
1017 jne __objc_msgSend_stret_uncached
1018 jmp __objc_msgSend_uncached
1020 END_ENTRY __objc_msgSend_uncached_impcache
1023 STATIC_ENTRY __objc_msgSend_uncached
1025 // THIS IS NOT A CALLABLE C FUNCTION
1026 // Out-of-band r11 is the searched class
1028 // r11 is already the class to search
1029 MethodTableLookup %a1, %a2 // r11 = IMP
1030 cmp %r11, %r11 // set eq (nonstret) for forwarding
1031 jmp *%r11 // goto *imp
1033 END_ENTRY __objc_msgSend_uncached
1036 STATIC_ENTRY __objc_msgSend_stret_uncached
1037 // THIS IS NOT A CALLABLE C FUNCTION
1038 // Out-of-band r11 is the searched class
1040 // r11 is already the class to search
1041 MethodTableLookup %a2, %a3 // r11 = IMP
1042 test %r11, %r11 // set ne (stret) for forward; r11!=0
1043 jmp *%r11 // goto *imp
1045 END_ENTRY __objc_msgSend_stret_uncached
1048 /********************************************************************
1050 * id _objc_msgForward(id self, SEL _cmd,...);
1052 * _objc_msgForward and _objc_msgForward_stret are the externally-callable
1053 * functions returned by things like method_getImplementation().
1054 * _objc_msgForward_impcache is the function pointer actually stored in
1057 ********************************************************************/
1059 STATIC_ENTRY __objc_msgForward_impcache
1060 // Method cache version
1062 // THIS IS NOT A CALLABLE C FUNCTION
1063 // Out-of-band condition register is NE for stret, EQ otherwise.
1069 jne __objc_msgForward_stret
1070 jmp __objc_msgForward
1072 END_ENTRY __objc_msgForward_impcache
1075 ENTRY __objc_msgForward
1076 // Non-stret version
1078 movq __objc_forward_handler(%rip), %r11
1081 END_ENTRY __objc_msgForward
1084 ENTRY __objc_msgForward_stret
1085 // Struct-return version
1087 movq __objc_forward_stret_handler(%rip), %r11
1090 END_ENTRY __objc_msgForward_stret
1093 ENTRY _objc_msgSend_debug
1095 END_ENTRY _objc_msgSend_debug
1097 ENTRY _objc_msgSendSuper2_debug
1098 jmp _objc_msgSendSuper2
1099 END_ENTRY _objc_msgSendSuper2_debug
1101 ENTRY _objc_msgSend_stret_debug
1102 jmp _objc_msgSend_stret
1103 END_ENTRY _objc_msgSend_stret_debug
1105 ENTRY _objc_msgSendSuper2_stret_debug
1106 jmp _objc_msgSendSuper2_stret
1107 END_ENTRY _objc_msgSendSuper2_stret_debug
1109 ENTRY _objc_msgSend_fpret_debug
1110 jmp _objc_msgSend_fpret
1111 END_ENTRY _objc_msgSend_fpret_debug
1113 ENTRY _objc_msgSend_fp2ret_debug
1114 jmp _objc_msgSend_fp2ret
1115 END_ENTRY _objc_msgSend_fp2ret_debug
1118 ENTRY _objc_msgSend_noarg
1120 END_ENTRY _objc_msgSend_noarg
1123 ENTRY _method_invoke
1125 movq method_imp(%a2), %r11
1126 movq method_name(%a2), %a2
1129 END_ENTRY _method_invoke
1132 ENTRY _method_invoke_stret
1134 movq method_imp(%a3), %r11
1135 movq method_name(%a3), %a3
1138 END_ENTRY _method_invoke_stret
1141 STATIC_ENTRY __objc_ignored_method
1146 END_ENTRY __objc_ignored_method
1149 .section __DATA,__objc_msg_break