]> git.saurik.com Git - apple/objc4.git/blob - runtime/Messengers.subproj/objc-msg-arm.s
objc4-750.tar.gz
[apple/objc4.git] / runtime / Messengers.subproj / objc-msg-arm.s
1 /*
2 * @APPLE_LICENSE_HEADER_START@
3 *
4 * Copyright (c) 1999-2007 Apple Computer, Inc. All Rights Reserved.
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /********************************************************************
24 *
25 * objc-msg-arm.s - ARM code to support objc messaging
26 *
27 ********************************************************************/
28
29 #ifdef __arm__
30
31 #include <arm/arch.h>
32 #include "objc-config.h"
33 #include "isa.h"
34
35 #ifndef _ARM_ARCH_7
36 # error requires armv7
37 #endif
38
39 // Set FP=1 on architectures that pass parameters in floating-point registers
40 #if __ARM_ARCH_7K__
41 # define FP 1
42 #else
43 # define FP 0
44 #endif
45
46 #if FP
47
48 # if !__ARM_NEON__
49 # error sorry
50 # endif
51
52 # define FP_RETURN_ZERO \
53 vmov.i32 q0, #0 ; \
54 vmov.i32 q1, #0 ; \
55 vmov.i32 q2, #0 ; \
56 vmov.i32 q3, #0
57
58 # define FP_SAVE \
59 vpush {q0-q3}
60
61 # define FP_RESTORE \
62 vpop {q0-q3}
63
64 #else
65
66 # define FP_RETURN_ZERO
67 # define FP_SAVE
68 # define FP_RESTORE
69
70 #endif
71
72 .syntax unified
73
74 #define MI_EXTERN(var) \
75 .non_lazy_symbol_pointer ;\
76 L##var##$$non_lazy_ptr: ;\
77 .indirect_symbol var ;\
78 .long 0
79
80 #define MI_GET_EXTERN(reg,var) \
81 movw reg, :lower16:(L##var##$$non_lazy_ptr-7f-4) ;\
82 movt reg, :upper16:(L##var##$$non_lazy_ptr-7f-4) ;\
83 7: add reg, pc ;\
84 ldr reg, [reg]
85
86 #define MI_GET_ADDRESS(reg,var) \
87 movw reg, :lower16:(var-7f-4) ;\
88 movt reg, :upper16:(var-7f-4) ;\
89 7: add reg, pc ;\
90
91
92 .data
93
94 #if SUPPORT_INDEXED_ISA
95
96 .align 2
97 .globl _objc_indexed_classes
98 _objc_indexed_classes:
99 .fill ISA_INDEX_COUNT, 4, 0
100
101 #endif
102
103
104
105 // _objc_entryPoints and _objc_exitPoints are used by method dispatch
106 // caching code to figure out whether any threads are actively
107 // in the cache for dispatching. The labels surround the asm code
108 // that do cache lookups. The tables are zero-terminated.
109
110 .align 2
111 .private_extern _objc_entryPoints
112 _objc_entryPoints:
113 .long _cache_getImp
114 .long _objc_msgSend
115 .long _objc_msgSend_stret
116 .long _objc_msgSendSuper
117 .long _objc_msgSendSuper_stret
118 .long _objc_msgSendSuper2
119 .long _objc_msgSendSuper2_stret
120 .long _objc_msgLookup
121 .long _objc_msgLookup_stret
122 .long _objc_msgLookupSuper2
123 .long _objc_msgLookupSuper2_stret
124 .long 0
125
126 .private_extern _objc_exitPoints
127 _objc_exitPoints:
128 .long LExit_cache_getImp
129 .long LExit_objc_msgSend
130 .long LExit_objc_msgSend_stret
131 .long LExit_objc_msgSendSuper
132 .long LExit_objc_msgSendSuper_stret
133 .long LExit_objc_msgSendSuper2
134 .long LExit_objc_msgSendSuper2_stret
135 .long LExit_objc_msgLookup
136 .long LExit_objc_msgLookup_stret
137 .long LExit_objc_msgLookupSuper2
138 .long LExit_objc_msgLookupSuper2_stret
139 .long 0
140
141
142 /********************************************************************
143 * Names for relative labels
144 * DO NOT USE THESE LABELS ELSEWHERE
145 * Reserved labels: 6: 7: 8: 9:
146 ********************************************************************/
147 // 6: used by CacheLookup
148 // 7: used by MI_GET_ADDRESS etc
149 // 8: used by CacheLookup
150 #define LNilReceiver 9
151 #define LNilReceiver_f 9f
152 #define LNilReceiver_b 9b
153
154
155 /********************************************************************
156 * Macro parameters
157 ********************************************************************/
158
159 #define NORMAL 0
160 #define STRET 1
161
162
163 /********************************************************************
164 *
165 * Structure definitions.
166 *
167 ********************************************************************/
168
169 /* objc_super parameter to sendSuper */
170 #define RECEIVER 0
171 #define CLASS 4
172
173 /* Selected field offsets in class structure */
174 #define ISA 0
175 #define SUPERCLASS 4
176 #define CACHE 8
177 #define CACHE_MASK 12
178
179 /* Field offsets in method cache bucket */
180 #define CACHED_SEL 0
181 #define CACHED_IMP 4
182
183 /* Selected field offsets in method structure */
184 #define METHOD_NAME 0
185 #define METHOD_TYPES 4
186 #define METHOD_IMP 8
187
188
189 //////////////////////////////////////////////////////////////////////
190 //
191 // ENTRY functionName
192 //
193 // Assembly directives to begin an exported function.
194 //
195 // Takes: functionName - name of the exported function
196 //////////////////////////////////////////////////////////////////////
197
198 .macro ENTRY /* name */
199 .text
200 .thumb
201 .align 5
202 .globl $0
203 .thumb_func
204 $0:
205 .endmacro
206
207 .macro STATIC_ENTRY /*name*/
208 .text
209 .thumb
210 .align 5
211 .private_extern $0
212 .thumb_func
213 $0:
214 .endmacro
215
216
217 //////////////////////////////////////////////////////////////////////
218 //
219 // END_ENTRY functionName
220 //
221 // Assembly directives to end an exported function. Just a placeholder,
222 // a close-parenthesis for ENTRY, until it is needed for something.
223 //
224 // Takes: functionName - name of the exported function
225 //////////////////////////////////////////////////////////////////////
226
227 .macro END_ENTRY /* name */
228 LExit$0:
229 .endmacro
230
231
232 /////////////////////////////////////////////////////////////////////
233 //
234 // CacheLookup NORMAL|STRET
235 // CacheLookup2 NORMAL|STRET
236 //
237 // Locate the implementation for a selector in a class's method cache.
238 //
239 // Takes:
240 // $0 = NORMAL, STRET
241 // r0 or r1 (STRET) = receiver
242 // r1 or r2 (STRET) = selector
243 // r9 = class to search in
244 //
245 // On exit: r9 clobbered
246 // (found) continues after CacheLookup, IMP in r12, eq set
247 // (not found) continues after CacheLookup2
248 //
249 /////////////////////////////////////////////////////////////////////
250
251 .macro CacheLookup
252
253 ldrh r12, [r9, #CACHE_MASK] // r12 = mask
254 ldr r9, [r9, #CACHE] // r9 = buckets
255 .if $0 == STRET
256 and r12, r12, r2 // r12 = index = SEL & mask
257 .else
258 and r12, r12, r1 // r12 = index = SEL & mask
259 .endif
260 add r9, r9, r12, LSL #3 // r9 = bucket = buckets+index*8
261 ldr r12, [r9, #CACHED_SEL] // r12 = bucket->sel
262 6:
263 .if $0 == STRET
264 teq r12, r2
265 .else
266 teq r12, r1
267 .endif
268 bne 8f
269 ldr r12, [r9, #CACHED_IMP] // r12 = bucket->imp
270
271 .if $0 == STRET
272 tst r12, r12 // set ne for stret forwarding
273 .else
274 // eq already set for nonstret forwarding by `teq` above
275 .endif
276
277 .endmacro
278
279 .macro CacheLookup2
280 #if CACHED_SEL != 0
281 # error this code requires that SEL be at offset 0
282 #endif
283 8:
284 cmp r12, #1
285 blo 8f // if (bucket->sel == 0) cache miss
286 it eq // if (bucket->sel == 1) cache wrap
287 ldreq r9, [r9, #CACHED_IMP] // bucket->imp is before first bucket
288 ldr r12, [r9, #8]! // r12 = (++bucket)->sel
289 b 6b
290 8:
291
292 .endmacro
293
294 /////////////////////////////////////////////////////////////////////
295 //
296 // GetClassFromIsa return-type
297 //
298 // Given an Isa, return the class for the Isa.
299 //
300 // Takes:
301 // r9 = class
302 //
303 // On exit: r12 clobbered
304 // r9 contains the class for this Isa.
305 //
306 /////////////////////////////////////////////////////////////////////
307 .macro GetClassFromIsa
308
309 #if SUPPORT_INDEXED_ISA
310 // Note: We are doing a little wasted work here to load values we might not
311 // need. Branching turns out to be even worse when performance was measured.
312 MI_GET_ADDRESS(r12, _objc_indexed_classes)
313 tst.w r9, #ISA_INDEX_IS_NPI_MASK
314 itt ne
315 ubfxne r9, r9, #ISA_INDEX_SHIFT, #ISA_INDEX_BITS
316 ldrne.w r9, [r12, r9, lsl #2]
317 #endif
318
319 .endmacro
320
321
322 /********************************************************************
323 * IMP cache_getImp(Class cls, SEL sel)
324 *
325 * On entry: r0 = class whose cache is to be searched
326 * r1 = selector to search for
327 *
328 * If found, returns method implementation.
329 * If not found, returns NULL.
330 ********************************************************************/
331
332 STATIC_ENTRY _cache_getImp
333
334 mov r9, r0
335 CacheLookup NORMAL
336 // cache hit, IMP in r12
337 mov r0, r12
338 bx lr // return imp
339
340 CacheLookup2 GETIMP
341 // cache miss, return nil
342 mov r0, #0
343 bx lr
344
345 END_ENTRY _cache_getImp
346
347
348 /********************************************************************
349 *
350 * id objc_msgSend(id self, SEL _cmd, ...);
351 * IMP objc_msgLookup(id self, SEL _cmd, ...);
352 *
353 * objc_msgLookup ABI:
354 * IMP returned in r12
355 * Forwarding returned in Z flag
356 * r9 reserved for our use but not used
357 *
358 ********************************************************************/
359
360 ENTRY _objc_msgSend
361
362 cbz r0, LNilReceiver_f
363
364 ldr r9, [r0] // r9 = self->isa
365 GetClassFromIsa // r9 = class
366 CacheLookup NORMAL
367 // cache hit, IMP in r12, eq already set for nonstret forwarding
368 bx r12 // call imp
369
370 CacheLookup2 NORMAL
371 // cache miss
372 ldr r9, [r0] // r9 = self->isa
373 GetClassFromIsa // r9 = class
374 b __objc_msgSend_uncached
375
376 LNilReceiver:
377 // r0 is already zero
378 mov r1, #0
379 mov r2, #0
380 mov r3, #0
381 FP_RETURN_ZERO
382 bx lr
383
384 END_ENTRY _objc_msgSend
385
386
387 ENTRY _objc_msgLookup
388
389 cbz r0, LNilReceiver_f
390
391 ldr r9, [r0] // r9 = self->isa
392 GetClassFromIsa // r9 = class
393 CacheLookup NORMAL
394 // cache hit, IMP in r12, eq already set for nonstret forwarding
395 bx lr
396
397 CacheLookup2 NORMAL
398 // cache miss
399 ldr r9, [r0] // r9 = self->isa
400 GetClassFromIsa // r9 = class
401 b __objc_msgLookup_uncached
402
403 LNilReceiver:
404 MI_GET_ADDRESS(r12, __objc_msgNil)
405 bx lr
406
407 END_ENTRY _objc_msgLookup
408
409
410 STATIC_ENTRY __objc_msgNil
411
412 // r0 is already zero
413 mov r1, #0
414 mov r2, #0
415 mov r3, #0
416 FP_RETURN_ZERO
417 bx lr
418
419 END_ENTRY __objc_msgNil
420
421
422 /********************************************************************
423 * void objc_msgSend_stret(void *st_addr, id self, SEL op, ...);
424 * IMP objc_msgLookup_stret(void *st_addr, id self, SEL op, ...);
425 *
426 * objc_msgSend_stret is the struct-return form of msgSend.
427 * The ABI calls for r0 to be used as the address of the structure
428 * being returned, with the parameters in the succeeding registers.
429 *
430 * On entry: r0 is the address where the structure is returned,
431 * r1 is the message receiver,
432 * r2 is the selector
433 ********************************************************************/
434
435 ENTRY _objc_msgSend_stret
436
437 cbz r1, LNilReceiver_f
438
439 ldr r9, [r1] // r9 = self->isa
440 GetClassFromIsa // r9 = class
441 CacheLookup STRET
442 // cache hit, IMP in r12, ne already set for stret forwarding
443 bx r12
444
445 CacheLookup2 STRET
446 // cache miss
447 ldr r9, [r1] // r9 = self->isa
448 GetClassFromIsa // r9 = class
449 b __objc_msgSend_stret_uncached
450
451 LNilReceiver:
452 bx lr
453
454 END_ENTRY _objc_msgSend_stret
455
456
457 ENTRY _objc_msgLookup_stret
458
459 cbz r1, LNilReceiver_f
460
461 ldr r9, [r1] // r9 = self->isa
462 GetClassFromIsa // r9 = class
463 CacheLookup STRET
464 // cache hit, IMP in r12, ne already set for stret forwarding
465 bx lr
466
467 CacheLookup2 STRET
468 // cache miss
469 ldr r9, [r1] // r9 = self->isa
470 GetClassFromIsa // r9 = class
471 b __objc_msgLookup_stret_uncached
472
473 LNilReceiver:
474 MI_GET_ADDRESS(r12, __objc_msgNil_stret)
475 bx lr
476
477 END_ENTRY _objc_msgLookup_stret
478
479
480 STATIC_ENTRY __objc_msgNil_stret
481
482 bx lr
483
484 END_ENTRY __objc_msgNil_stret
485
486
487 /********************************************************************
488 * id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
489 *
490 * struct objc_super {
491 * id receiver;
492 * Class cls; // the class to search
493 * }
494 ********************************************************************/
495
496 ENTRY _objc_msgSendSuper
497
498 ldr r9, [r0, #CLASS] // r9 = struct super->class
499 CacheLookup NORMAL
500 // cache hit, IMP in r12, eq already set for nonstret forwarding
501 ldr r0, [r0, #RECEIVER] // load real receiver
502 bx r12 // call imp
503
504 CacheLookup2 NORMAL
505 // cache miss
506 ldr r9, [r0, #CLASS] // r9 = struct super->class
507 ldr r0, [r0, #RECEIVER] // load real receiver
508 b __objc_msgSend_uncached
509
510 END_ENTRY _objc_msgSendSuper
511
512
513 /********************************************************************
514 * id objc_msgSendSuper2(struct objc_super *super, SEL op, ...)
515 *
516 * struct objc_super {
517 * id receiver;
518 * Class cls; // SUBCLASS of the class to search
519 * }
520 ********************************************************************/
521
522 ENTRY _objc_msgSendSuper2
523
524 ldr r9, [r0, #CLASS] // class = struct super->class
525 ldr r9, [r9, #SUPERCLASS] // class = class->superclass
526 CacheLookup NORMAL
527 // cache hit, IMP in r12, eq already set for nonstret forwarding
528 ldr r0, [r0, #RECEIVER] // load real receiver
529 bx r12 // call imp
530
531 CacheLookup2 NORMAL
532 // cache miss
533 ldr r9, [r0, #CLASS] // class = struct super->class
534 ldr r9, [r9, #SUPERCLASS] // class = class->superclass
535 ldr r0, [r0, #RECEIVER] // load real receiver
536 b __objc_msgSend_uncached
537
538 END_ENTRY _objc_msgSendSuper2
539
540
541 ENTRY _objc_msgLookupSuper2
542
543 ldr r9, [r0, #CLASS] // class = struct super->class
544 ldr r9, [r9, #SUPERCLASS] // class = class->superclass
545 CacheLookup NORMAL
546 // cache hit, IMP in r12, eq already set for nonstret forwarding
547 ldr r0, [r0, #RECEIVER] // load real receiver
548 bx lr
549
550 CacheLookup2 NORMAL
551 // cache miss
552 ldr r9, [r0, #CLASS]
553 ldr r9, [r9, #SUPERCLASS] // r9 = class to search
554 ldr r0, [r0, #RECEIVER] // load real receiver
555 b __objc_msgLookup_uncached
556
557 END_ENTRY _objc_msgLookupSuper2
558
559
560 /********************************************************************
561 * void objc_msgSendSuper_stret(void *st_addr, objc_super *self, SEL op, ...);
562 *
563 * objc_msgSendSuper_stret is the struct-return form of msgSendSuper.
564 * The ABI calls for r0 to be used as the address of the structure
565 * being returned, with the parameters in the succeeding registers.
566 *
567 * On entry: r0 is the address where the structure is returned,
568 * r1 is the address of the objc_super structure,
569 * r2 is the selector
570 ********************************************************************/
571
572 ENTRY _objc_msgSendSuper_stret
573
574 ldr r9, [r1, #CLASS] // r9 = struct super->class
575 CacheLookup STRET
576 // cache hit, IMP in r12, ne already set for stret forwarding
577 ldr r1, [r1, #RECEIVER] // load real receiver
578 bx r12 // call imp
579
580 CacheLookup2 STRET
581 // cache miss
582 ldr r9, [r1, #CLASS] // r9 = struct super->class
583 ldr r1, [r1, #RECEIVER] // load real receiver
584 b __objc_msgSend_stret_uncached
585
586 END_ENTRY _objc_msgSendSuper_stret
587
588
589 /********************************************************************
590 * id objc_msgSendSuper2_stret
591 ********************************************************************/
592
593 ENTRY _objc_msgSendSuper2_stret
594
595 ldr r9, [r1, #CLASS] // class = struct super->class
596 ldr r9, [r9, #SUPERCLASS] // class = class->superclass
597 CacheLookup STRET
598 // cache hit, IMP in r12, ne already set for stret forwarding
599 ldr r1, [r1, #RECEIVER] // load real receiver
600 bx r12 // call imp
601
602 CacheLookup2 STRET
603 // cache miss
604 ldr r9, [r1, #CLASS] // class = struct super->class
605 ldr r9, [r9, #SUPERCLASS] // class = class->superclass
606 ldr r1, [r1, #RECEIVER] // load real receiver
607 b __objc_msgSend_stret_uncached
608
609 END_ENTRY _objc_msgSendSuper2_stret
610
611
612 ENTRY _objc_msgLookupSuper2_stret
613
614 ldr r9, [r1, #CLASS] // class = struct super->class
615 ldr r9, [r9, #SUPERCLASS] // class = class->superclass
616 CacheLookup STRET
617 // cache hit, IMP in r12, ne already set for stret forwarding
618 ldr r1, [r1, #RECEIVER] // load real receiver
619 bx lr
620
621 CacheLookup2 STRET
622 // cache miss
623 ldr r9, [r1, #CLASS]
624 ldr r9, [r9, #SUPERCLASS] // r9 = class to search
625 ldr r1, [r1, #RECEIVER] // load real receiver
626 b __objc_msgLookup_stret_uncached
627
628 END_ENTRY _objc_msgLookupSuper2_stret
629
630
631 /////////////////////////////////////////////////////////////////////
632 //
633 // MethodTableLookup NORMAL|STRET
634 //
635 // Locate the implementation for a selector in a class's method lists.
636 //
637 // Takes:
638 // $0 = NORMAL, STRET
639 // r0 or r1 (STRET) = receiver
640 // r1 or r2 (STRET) = selector
641 // r9 = class to search in
642 //
643 // On exit: IMP in r12, eq/ne set for forwarding
644 //
645 /////////////////////////////////////////////////////////////////////
646
647 .macro MethodTableLookup
648
649 stmfd sp!, {r0-r3,r7,lr}
650 add r7, sp, #16
651 sub sp, #8 // align stack
652 FP_SAVE
653
654 .if $0 == NORMAL
655 // receiver already in r0
656 // selector already in r1
657 .else
658 mov r0, r1 // receiver
659 mov r1, r2 // selector
660 .endif
661 mov r2, r9 // class to search
662
663 blx __class_lookupMethodAndLoadCache3
664 mov r12, r0 // r12 = IMP
665
666 .if $0 == NORMAL
667 cmp r12, r12 // set eq for nonstret forwarding
668 .else
669 tst r12, r12 // set ne for stret forwarding
670 .endif
671
672 FP_RESTORE
673 add sp, #8 // align stack
674 ldmfd sp!, {r0-r3,r7,lr}
675
676 .endmacro
677
678
679 /********************************************************************
680 *
681 * _objc_msgSend_uncached
682 * _objc_msgSend_stret_uncached
683 * _objc_msgLookup_uncached
684 * _objc_msgLookup_stret_uncached
685 * The uncached method lookup.
686 *
687 ********************************************************************/
688
689 STATIC_ENTRY __objc_msgSend_uncached
690
691 // THIS IS NOT A CALLABLE C FUNCTION
692 // Out-of-band r9 is the class to search
693
694 MethodTableLookup NORMAL // returns IMP in r12
695 bx r12
696
697 END_ENTRY __objc_msgSend_uncached
698
699
700 STATIC_ENTRY __objc_msgSend_stret_uncached
701
702 // THIS IS NOT A CALLABLE C FUNCTION
703 // Out-of-band r9 is the class to search
704
705 MethodTableLookup STRET // returns IMP in r12
706 bx r12
707
708 END_ENTRY __objc_msgSend_stret_uncached
709
710
711 STATIC_ENTRY __objc_msgLookup_uncached
712
713 // THIS IS NOT A CALLABLE C FUNCTION
714 // Out-of-band r9 is the class to search
715
716 MethodTableLookup NORMAL // returns IMP in r12
717 bx lr
718
719 END_ENTRY __objc_msgLookup_uncached
720
721
722 STATIC_ENTRY __objc_msgLookup_stret_uncached
723
724 // THIS IS NOT A CALLABLE C FUNCTION
725 // Out-of-band r9 is the class to search
726
727 MethodTableLookup STRET // returns IMP in r12
728 bx lr
729
730 END_ENTRY __objc_msgLookup_stret_uncached
731
732
733 /********************************************************************
734 *
735 * id _objc_msgForward(id self, SEL _cmd,...);
736 *
737 * _objc_msgForward and _objc_msgForward_stret are the externally-callable
738 * functions returned by things like method_getImplementation().
739 * _objc_msgForward_impcache is the function pointer actually stored in
740 * method caches.
741 *
742 ********************************************************************/
743
744 MI_EXTERN(__objc_forward_handler)
745 MI_EXTERN(__objc_forward_stret_handler)
746
747 STATIC_ENTRY __objc_msgForward_impcache
748 // Method cache version
749
750 // THIS IS NOT A CALLABLE C FUNCTION
751 // Out-of-band Z is 0 (EQ) for normal, 1 (NE) for stret
752
753 beq __objc_msgForward
754 b __objc_msgForward_stret
755
756 END_ENTRY __objc_msgForward_impcache
757
758
759 ENTRY __objc_msgForward
760 // Non-stret version
761
762 MI_GET_EXTERN(r12, __objc_forward_handler)
763 ldr r12, [r12]
764 bx r12
765
766 END_ENTRY __objc_msgForward
767
768
769 ENTRY __objc_msgForward_stret
770 // Struct-return version
771
772 MI_GET_EXTERN(r12, __objc_forward_stret_handler)
773 ldr r12, [r12]
774 bx r12
775
776 END_ENTRY __objc_msgForward_stret
777
778
779 ENTRY _objc_msgSend_noarg
780 b _objc_msgSend
781 END_ENTRY _objc_msgSend_noarg
782
783 ENTRY _objc_msgSend_debug
784 b _objc_msgSend
785 END_ENTRY _objc_msgSend_debug
786
787 ENTRY _objc_msgSendSuper2_debug
788 b _objc_msgSendSuper2
789 END_ENTRY _objc_msgSendSuper2_debug
790
791 ENTRY _objc_msgSend_stret_debug
792 b _objc_msgSend_stret
793 END_ENTRY _objc_msgSend_stret_debug
794
795 ENTRY _objc_msgSendSuper2_stret_debug
796 b _objc_msgSendSuper2_stret
797 END_ENTRY _objc_msgSendSuper2_stret_debug
798
799
800 ENTRY _method_invoke
801 // r1 is method triplet instead of SEL
802 ldr r12, [r1, #METHOD_IMP]
803 ldr r1, [r1, #METHOD_NAME]
804 bx r12
805 END_ENTRY _method_invoke
806
807
808 ENTRY _method_invoke_stret
809 // r2 is method triplet instead of SEL
810 ldr r12, [r2, #METHOD_IMP]
811 ldr r2, [r2, #METHOD_NAME]
812 bx r12
813 END_ENTRY _method_invoke_stret
814
815
816 .section __DATA,__objc_msg_break
817 .long 0
818 .long 0
819
820 #endif