]> git.saurik.com Git - apple/objc4.git/blame - runtime/Messengers.subproj/objc-msg-x86_64.s
objc4-723.tar.gz
[apple/objc4.git] / runtime / Messengers.subproj / objc-msg-x86_64.s
CommitLineData
b3962a83
A
1/*
2 * Copyright (c) 1999-2007 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
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 */
7af964d1 23
8070259c 24#include <TargetConditionals.h>
c1e772c4 25#if __x86_64__ && !TARGET_OS_SIMULATOR
7af964d1 26
b3962a83
A
27/********************************************************************
28 ********************************************************************
29 **
30 ** objc-msg-x86_64.s - x86-64 code to support objc messaging.
31 **
32 ********************************************************************
33 ********************************************************************/
34
b3962a83 35.data
b3962a83
A
36
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.
40
31875a97 41.align 4
8972963c 42.private_extern _objc_entryPoints
b3962a83 43_objc_entryPoints:
7257e56c 44 .quad _cache_getImp
b3962a83
A
45 .quad _objc_msgSend
46 .quad _objc_msgSend_fpret
47 .quad _objc_msgSend_fp2ret
48 .quad _objc_msgSend_stret
49 .quad _objc_msgSendSuper
50 .quad _objc_msgSendSuper_stret
8972963c
A
51 .quad _objc_msgSendSuper2
52 .quad _objc_msgSendSuper2_stret
c1e772c4
A
53 .quad _objc_msgLookup
54 .quad _objc_msgLookup_fpret
55 .quad _objc_msgLookup_fp2ret
56 .quad _objc_msgLookup_stret
57 .quad _objc_msgLookupSuper2
58 .quad _objc_msgLookupSuper2_stret
b3962a83
A
59 .quad 0
60
8972963c 61.private_extern _objc_exitPoints
b3962a83 62_objc_exitPoints:
7257e56c 63 .quad LExit_cache_getImp
8972963c
A
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
c1e772c4
A
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
b3962a83
A
78 .quad 0
79
80
7257e56c
A
81/********************************************************************
82* List every exit insn from every messenger for debugger use.
83* Format:
84* (
85* 1 word instruction's address
86* 1 word type (ENTER or FAST_EXIT or SLOW_EXIT or NIL_EXIT)
87* )
88* 1 word zero
89*
90* ENTER is the start of a dispatcher
91* FAST_EXIT is method dispatch
92* SLOW_EXIT is uncached method lookup
93* NIL_EXIT is returning zero from a message sent to nil
94* These must match objc-gdb.h.
95********************************************************************/
96
97#define ENTER 1
98#define FAST_EXIT 2
99#define SLOW_EXIT 3
100#define NIL_EXIT 4
101
102.section __DATA,__objc_msg_break
103.globl _gdb_objc_messenger_breakpoints
104_gdb_objc_messenger_breakpoints:
105// contents populated by the macros below
106
107.macro MESSENGER_START
1084:
109 .section __DATA,__objc_msg_break
110 .quad 4b
111 .quad ENTER
112 .text
113.endmacro
114.macro MESSENGER_END_FAST
1154:
116 .section __DATA,__objc_msg_break
117 .quad 4b
118 .quad FAST_EXIT
119 .text
120.endmacro
121.macro MESSENGER_END_SLOW
1224:
123 .section __DATA,__objc_msg_break
124 .quad 4b
125 .quad SLOW_EXIT
126 .text
127.endmacro
128.macro MESSENGER_END_NIL
1294:
130 .section __DATA,__objc_msg_break
131 .quad 4b
132 .quad NIL_EXIT
133 .text
134.endmacro
135
136
b3962a83 137/********************************************************************
8972963c
A
138 * Recommended multi-byte NOP instructions
139 * (Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2B)
140 ********************************************************************/
141#define nop1 .byte 0x90
142#define nop2 .byte 0x66,0x90
143#define nop3 .byte 0x0F,0x1F,0x00
144#define nop4 .byte 0x0F,0x1F,0x40,0x00
145#define nop5 .byte 0x0F,0x1F,0x44,0x00,0x00
146#define nop6 .byte 0x66,0x0F,0x1F,0x44,0x00,0x00
147#define nop7 .byte 0x0F,0x1F,0x80,0x00,0x00,0x00,0x00
148#define nop8 .byte 0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
149#define nop9 .byte 0x66,0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
150
151
7257e56c
A
152/********************************************************************
153 * Harmless branch prefix hint for instruction alignment
154 ********************************************************************/
155
156#define PN .byte 0x2e
157
158
8972963c 159/********************************************************************
b3962a83 160 * Names for parameter registers.
b3962a83
A
161 ********************************************************************/
162
8972963c
A
163#define a1 rdi
164#define a1d edi
165#define a1b dil
166#define a2 rsi
167#define a2d esi
168#define a2b sil
169#define a3 rdx
170#define a3d edx
171#define a4 rcx
172#define a4d ecx
173#define a5 r8
174#define a5d r8d
175#define a6 r9
b3962a83
A
176#define a6d r9d
177
178
8972963c
A
179/********************************************************************
180 * Names for relative labels
181 * DO NOT USE THESE LABELS ELSEWHERE
8070259c 182 * Reserved labels: 6: 7: 8: 9:
8972963c 183 ********************************************************************/
8070259c
A
184#define LCacheMiss 6
185#define LCacheMiss_f 6f
186#define LCacheMiss_b 6b
8972963c
A
187#define LNilTestSlow 7
188#define LNilTestSlow_f 7f
189#define LNilTestSlow_b 7b
190#define LGetIsaDone 8
191#define LGetIsaDone_f 8f
192#define LGetIsaDone_b 8b
193#define LGetIsaSlow 9
194#define LGetIsaSlow_f 9f
195#define LGetIsaSlow_b 9b
196
197/********************************************************************
198 * Macro parameters
199 ********************************************************************/
200
8972963c
A
201#define NORMAL 0
202#define FPRET 1
203#define FP2RET 2
c1e772c4
A
204#define STRET 3
205
206#define CALL 100
207#define GETIMP 101
208#define LOOKUP 102
209
8972963c 210
b3962a83
A
211/********************************************************************
212 *
213 * Structure definitions.
214 *
215 ********************************************************************/
216
217// objc_super parameter to sendSuper
8972963c
A
218#define receiver 0
219#define class 8
b3962a83
A
220
221// Selected field offsets in class structure
8972963c 222// #define isa 0 USE GetIsa INSTEAD
b3962a83
A
223
224// Method descriptor
8972963c
A
225#define method_name 0
226#define method_imp 16
b3962a83 227
b3962a83 228
b3962a83
A
229//////////////////////////////////////////////////////////////////////
230//
231// ENTRY functionName
232//
233// Assembly directives to begin an exported function.
234//
235// Takes: functionName - name of the exported function
236//////////////////////////////////////////////////////////////////////
237
238.macro ENTRY
239 .text
240 .globl $0
8972963c
A
241 .align 6, 0x90
242$0:
243.endmacro
244
245.macro STATIC_ENTRY
246 .text
247 .private_extern $0
b3962a83
A
248 .align 2, 0x90
249$0:
250.endmacro
251
252//////////////////////////////////////////////////////////////////////
253//
254// END_ENTRY functionName
255//
256// Assembly directives to end an exported function. Just a placeholder,
257// a close-parenthesis for ENTRY, until it is needed for something.
258//
259// Takes: functionName - name of the exported function
260//////////////////////////////////////////////////////////////////////
261
262.macro END_ENTRY
8070259c 263LExit$0:
b3962a83
A
264.endmacro
265
266
c1e772c4
A
267 /********************************************************************
268 * UNWIND name, flags
269 * Unwind info generation
270 ********************************************************************/
271.macro UNWIND
272 .section __LD,__compact_unwind,regular,debug
273 .quad $0
274 .set LUnwind$0, LExit$0 - $0
275 .long LUnwind$0
276 .long $1
277 .quad 0 /* no personality */
278 .quad 0 /* no LSDA */
279 .text
b3962a83
A
280.endmacro
281
c1e772c4
A
282#define NoFrame 0x02010000 // no frame, no SP adjustment except return address
283#define FrameWithNoSaves 0x01000000 // frame, no non-volatile saves
b3962a83
A
284
285
286/////////////////////////////////////////////////////////////////////
287//
cd5f04f5 288// CacheLookup return-type, caller
b3962a83 289//
7257e56c 290// Locate the implementation for a class in a selector's method cache.
b3962a83
A
291//
292// Takes:
c1e772c4
A
293// $0 = NORMAL, FPRET, FP2RET, STRET
294// $1 = CALL, LOOKUP, GETIMP
295// a1 or a2 (STRET) = receiver
296// a2 or a3 (STRET) = selector
297// r10 = class to search
b3962a83 298//
7257e56c 299// On exit: r10 clobbered
c1e772c4
A
300// (found) calls or returns IMP in r11, eq/ne set for forwarding
301// (not found) jumps to LCacheMiss, class still in r10
8972963c 302//
b3962a83
A
303/////////////////////////////////////////////////////////////////////
304
7257e56c 305.macro CacheHit
b3962a83 306
7257e56c
A
307 // CacheHit must always be preceded by a not-taken `jne` instruction
308 // in order to set the correct flags for _objc_msgForward_impcache.
309
c1e772c4 310 // r11 = found bucket
cd5f04f5 311
c1e772c4
A
312.if $1 == GETIMP
313 movq 8(%r11), %rax // return imp
314 ret
315
316.else
317
318.if $0 != STRET
7257e56c 319 // eq already set for forwarding by `jne`
c1e772c4
A
320.else
321 test %r11, %r11 // set ne for stret forwarding
322.endif
323
324.if $1 == CALL
7257e56c 325 MESSENGER_END_FAST
c1e772c4 326 jmp *8(%r11) // call imp
7257e56c 327
c1e772c4
A
328.elseif $1 == LOOKUP
329 movq 8(%r11), %r11 // return imp
330 ret
7257e56c 331
8972963c 332.else
7257e56c 333.abort oops
8972963c 334.endif
c1e772c4
A
335
336.endif
337
7257e56c
A
338.endmacro
339
8070259c 340
7257e56c 341.macro CacheLookup
c1e772c4
A
342.if $0 != STRET
343 movq %a2, %r11 // r11 = _cmd
7257e56c 344.else
c1e772c4 345 movq %a3, %r11 // r11 = _cmd
7257e56c 346.endif
c1e772c4
A
347 andl 24(%r10), %r11d // r11 = _cmd & class->cache.mask
348 shlq $$4, %r11 // r11 = offset = (_cmd & mask)<<4
349 addq 16(%r10), %r11 // r11 = class->cache.buckets + offset
7257e56c 350
c1e772c4
A
351.if $0 != STRET
352 cmpq (%r11), %a2 // if (bucket->sel != _cmd)
7257e56c 353.else
c1e772c4 354 cmpq (%r11), %a3 // if (bucket->sel != _cmd)
7257e56c
A
355.endif
356 jne 1f // scan more
357 // CacheHit must always be preceded by a not-taken `jne` instruction
c1e772c4 358 CacheHit $0, $1 // call or return imp
7257e56c 359
8972963c 3601:
7257e56c 361 // loop
c1e772c4 362 cmpq $$1, (%r11)
31875a97 363 jbe 3f // if (bucket->sel <= 1) wrap or miss
7257e56c 364
c1e772c4 365 addq $$16, %r11 // bucket++
8070259c 3662:
c1e772c4
A
367.if $0 != STRET
368 cmpq (%r11), %a2 // if (bucket->sel != _cmd)
8972963c 369.else
c1e772c4 370 cmpq (%r11), %a3 // if (bucket->sel != _cmd)
8972963c 371.endif
7257e56c
A
372 jne 1b // scan more
373 // CacheHit must always be preceded by a not-taken `jne` instruction
c1e772c4 374 CacheHit $0, $1 // call or return imp
b3962a83 375
7257e56c 3763:
31875a97
A
377 // wrap or miss
378 jb LCacheMiss_f // if (bucket->sel < 1) cache miss
7257e56c 379 // wrap
c1e772c4 380 movq 8(%r11), %r11 // bucket->imp is really first bucket
7257e56c 381 jmp 2f
8972963c 382
31875a97
A
383 // Clone scanning loop to miss instead of hang when cache is corrupt.
384 // The slow path may detect any corruption and halt later.
7257e56c
A
385
3861:
387 // loop
c1e772c4 388 cmpq $$1, (%r11)
31875a97 389 jbe 3f // if (bucket->sel <= 1) wrap or miss
7257e56c 390
c1e772c4 391 addq $$16, %r11 // bucket++
7257e56c 3922:
c1e772c4
A
393.if $0 != STRET
394 cmpq (%r11), %a2 // if (bucket->sel != _cmd)
8972963c 395.else
c1e772c4 396 cmpq (%r11), %a3 // if (bucket->sel != _cmd)
8972963c 397.endif
7257e56c
A
398 jne 1b // scan more
399 // CacheHit must always be preceded by a not-taken `jne` instruction
c1e772c4 400 CacheHit $0, $1 // call or return imp
b3962a83 401
7257e56c 4023:
31875a97
A
403 // double wrap or miss
404 jmp LCacheMiss_f
8070259c 405
b3962a83
A
406.endmacro
407
408
409/////////////////////////////////////////////////////////////////////
410//
c1e772c4 411// MethodTableLookup NORMAL|STRET
b3962a83 412//
c1e772c4
A
413// Takes: a1 or a2 (STRET) = receiver
414// a2 or a3 (STRET) = selector to search for
415// r10 = class to search
b3962a83 416//
c1e772c4 417// On exit: imp in %r11, eq/ne set for forwarding
b3962a83
A
418//
419/////////////////////////////////////////////////////////////////////
c1e772c4 420
b3962a83 421.macro MethodTableLookup
7257e56c 422
c1e772c4
A
423 push %rbp
424 mov %rsp, %rbp
cd5f04f5 425
c1e772c4
A
426 sub $$0x80+8, %rsp // +8 for alignment
427
428 movdqa %xmm0, -0x80(%rbp)
429 push %rax // might be xmm parameter count
430 movdqa %xmm1, -0x70(%rbp)
431 push %a1
432 movdqa %xmm2, -0x60(%rbp)
433 push %a2
434 movdqa %xmm3, -0x50(%rbp)
435 push %a3
436 movdqa %xmm4, -0x40(%rbp)
437 push %a4
438 movdqa %xmm5, -0x30(%rbp)
439 push %a5
440 movdqa %xmm6, -0x20(%rbp)
441 push %a6
442 movdqa %xmm7, -0x10(%rbp)
b3962a83 443
8972963c 444 // _class_lookupMethodAndLoadCache3(receiver, selector, class)
b3962a83 445
c1e772c4
A
446.if $0 == NORMAL
447 // receiver already in a1
448 // selector already in a2
449.else
450 movq %a2, %a1
451 movq %a3, %a2
452.endif
453 movq %r10, %a3
8972963c 454 call __class_lookupMethodAndLoadCache3
b3962a83
A
455
456 // IMP is now in %rax
457 movq %rax, %r11
458
c1e772c4
A
459 movdqa -0x80(%rbp), %xmm0
460 pop %a6
461 movdqa -0x70(%rbp), %xmm1
462 pop %a5
463 movdqa -0x60(%rbp), %xmm2
464 pop %a4
465 movdqa -0x50(%rbp), %xmm3
466 pop %a3
467 movdqa -0x40(%rbp), %xmm4
468 pop %a2
469 movdqa -0x30(%rbp), %xmm5
470 pop %a1
471 movdqa -0x20(%rbp), %xmm6
472 pop %rax
473 movdqa -0x10(%rbp), %xmm7
474
475.if $0 == NORMAL
476 cmp %r11, %r11 // set eq for nonstret forwarding
477.else
478 test %r11, %r11 // set ne for stret forwarding
479.endif
480
481 leave
b3962a83
A
482
483.endmacro
484
c1e772c4 485
8972963c
A
486/////////////////////////////////////////////////////////////////////
487//
8972963c
A
488// GetIsaFast return-type
489// GetIsaSupport return-type
490//
c1e772c4 491// Sets r10 = obj->isa. Consults the tagged isa table if necessary.
8972963c
A
492//
493// Takes: $0 = NORMAL or FPRET or FP2RET or STRET
494// a1 or a2 (STRET) = receiver
495//
c1e772c4
A
496// On exit: r10 = receiver->isa
497// r11 is clobbered
8972963c
A
498//
499/////////////////////////////////////////////////////////////////////
8972963c
A
500
501.macro GetIsaFast
502.if $0 != STRET
503 testb $$1, %a1b
7257e56c 504 PN
8972963c 505 jnz LGetIsaSlow_f
c1e772c4
A
506 movq $$0x00007ffffffffff8, %r10
507 andq (%a1), %r10
8972963c
A
508.else
509 testb $$1, %a2b
7257e56c 510 PN
8972963c 511 jnz LGetIsaSlow_f
c1e772c4
A
512 movq $$0x00007ffffffffff8, %r10
513 andq (%a2), %r10
8972963c
A
514.endif
515LGetIsaDone:
516.endmacro
517
c1e772c4 518.macro GetIsaSupport
8972963c 519LGetIsaSlow:
8972963c 520.if $0 != STRET
c1e772c4 521 movl %a1d, %r11d
8972963c 522.else
c1e772c4 523 movl %a2d, %r11d
8972963c 524.endif
c1e772c4
A
525 andl $$0xF, %r11d
526 cmp $$0xF, %r11d
527 je 1f
528 // basic tagged
529 leaq _objc_debug_taggedpointer_classes(%rip), %r10
530 movq (%r10, %r11, 8), %r10 // read isa from table
531 jmp LGetIsaDone_b
5321:
533 // extended tagged
534.if $0 != STRET
535 movl %a1d, %r11d
536.else
537 movl %a2d, %r11d
538.endif
539 shrl $$4, %r11d
540 andl $$0xFF, %r11d
541 leaq _objc_debug_taggedpointer_ext_classes(%rip), %r10
542 movq (%r10, %r11, 8), %r10 // read isa from table
8972963c 543 jmp LGetIsaDone_b
7257e56c
A
544.endmacro
545
8972963c
A
546
547/////////////////////////////////////////////////////////////////////
548//
549// NilTest return-type
550//
551// Takes: $0 = NORMAL or FPRET or FP2RET or STRET
552// %a1 or %a2 (STRET) = receiver
553//
c1e772c4
A
554// On exit: Loads non-nil receiver in %a1 or %a2 (STRET)
555// or returns.
8972963c 556//
c1e772c4 557// NilTestReturnZero return-type
8972963c
A
558//
559// Takes: $0 = NORMAL or FPRET or FP2RET or STRET
560// %a1 or %a2 (STRET) = receiver
561//
c1e772c4
A
562// On exit: Loads non-nil receiver in %a1 or %a2 (STRET)
563// or returns zero.
564//
565// NilTestReturnIMP return-type
566//
567// Takes: $0 = NORMAL or FPRET or FP2RET or STRET
568// %a1 or %a2 (STRET) = receiver
569//
570// On exit: Loads non-nil receiver in %a1 or %a2 (STRET)
571// or returns an IMP in r11 that returns zero.
8972963c
A
572//
573/////////////////////////////////////////////////////////////////////
574
c1e772c4
A
575.macro ZeroReturn
576 xorl %eax, %eax
577 xorl %edx, %edx
578 xorps %xmm0, %xmm0
579 xorps %xmm1, %xmm1
580.endmacro
581
582.macro ZeroReturnFPRET
583 fldz
584 ZeroReturn
585.endmacro
7257e56c 586
c1e772c4
A
587.macro ZeroReturnFP2RET
588 fldz
589 fldz
590 ZeroReturn
591.endmacro
592
593.macro ZeroReturnSTRET
594 // rax gets the struct-return address as passed in rdi
595 movq %rdi, %rax
596.endmacro
597
598 STATIC_ENTRY __objc_msgNil
599 ZeroReturn
600 ret
601 END_ENTRY __objc_msgNil
602
603 STATIC_ENTRY __objc_msgNil_fpret
604 ZeroReturnFPRET
605 ret
606 END_ENTRY __objc_msgNil_fpret
607
608 STATIC_ENTRY __objc_msgNil_fp2ret
609 ZeroReturnFP2RET
610 ret
611 END_ENTRY __objc_msgNil_fp2ret
612
613 STATIC_ENTRY __objc_msgNil_stret
614 ZeroReturnSTRET
615 ret
616 END_ENTRY __objc_msgNil_stret
617
618
619.macro NilTest
8972963c
A
620.if $0 != STRET
621 testq %a1, %a1
622.else
623 testq %a2, %a2
624.endif
7257e56c 625 PN
8972963c 626 jz LNilTestSlow_f
8972963c
A
627.endmacro
628
c1e772c4
A
629
630.macro NilTestReturnZero
8972963c
A
631 .align 3
632LNilTestSlow:
c1e772c4
A
633
634.if $0 == NORMAL
635 ZeroReturn
636.elseif $0 == FPRET
637 ZeroReturnFPRET
8972963c 638.elseif $0 == FP2RET
c1e772c4
A
639 ZeroReturnFP2RET
640.elseif $0 == STRET
641 ZeroReturnSTRET
7257e56c 642.else
c1e772c4 643.abort oops
8972963c 644.endif
7257e56c 645 MESSENGER_END_NIL
c1e772c4
A
646 ret
647.endmacro
648
649
650.macro NilTestReturnIMP
651 .align 3
652LNilTestSlow:
653
654.if $0 == NORMAL
655 leaq __objc_msgNil(%rip), %r11
656.elseif $0 == FPRET
657 leaq __objc_msgNil_fpret(%rip), %r11
658.elseif $0 == FP2RET
659 leaq __objc_msgNil_fp2ret(%rip), %r11
660.elseif $0 == STRET
661 leaq __objc_msgNil_stret(%rip), %r11
662.else
663.abort oops
664.endif
8972963c
A
665 ret
666.endmacro
b3962a83
A
667
668
669/********************************************************************
7257e56c 670 * IMP cache_getImp(Class cls, SEL sel)
b3962a83
A
671 *
672 * On entry: a1 = class whose cache is to be searched
673 * a2 = selector to search for
674 *
675 * If found, returns method implementation.
676 * If not found, returns NULL.
677 ********************************************************************/
678
7257e56c 679 STATIC_ENTRY _cache_getImp
b3962a83
A
680
681// do lookup
c1e772c4
A
682 movq %a1, %r10 // move class to r10 for CacheLookup
683 CacheLookup NORMAL, GETIMP // returns IMP on success
b3962a83 684
8972963c 685LCacheMiss:
b3962a83 686// cache miss, return nil
8972963c 687 xorl %eax, %eax
b3962a83
A
688 ret
689
c1e772c4 690 END_ENTRY _cache_getImp
b3962a83
A
691
692
693/********************************************************************
694 *
695 * id objc_msgSend(id self, SEL _cmd,...);
c1e772c4
A
696 * IMP objc_msgLookup(id self, SEL _cmd, ...);
697 *
698 * objc_msgLookup ABI:
699 * IMP returned in r11
700 * Forwarding returned in Z flag
701 * r10 reserved for our use but not used
b3962a83
A
702 *
703 ********************************************************************/
704
8972963c
A
705 .data
706 .align 3
7257e56c
A
707 .globl _objc_debug_taggedpointer_classes
708_objc_debug_taggedpointer_classes:
8972963c 709 .fill 16, 8, 0
c1e772c4
A
710 .globl _objc_debug_taggedpointer_ext_classes
711_objc_debug_taggedpointer_ext_classes:
712 .fill 256, 8, 0
8972963c 713
c1e772c4
A
714 ENTRY _objc_msgSend
715 UNWIND _objc_msgSend, NoFrame
7257e56c 716 MESSENGER_START
b3962a83 717
8972963c 718 NilTest NORMAL
b3962a83 719
c1e772c4
A
720 GetIsaFast NORMAL // r10 = self->isa
721 CacheLookup NORMAL, CALL // calls IMP on success
b3962a83 722
c1e772c4 723 NilTestReturnZero NORMAL
b3962a83 724
c1e772c4 725 GetIsaSupport NORMAL
b3962a83 726
8972963c
A
727// cache miss: go search the method lists
728LCacheMiss:
c1e772c4
A
729 // isa still in r10
730 MESSENGER_END_SLOW
731 jmp __objc_msgSend_uncached
b3962a83 732
c1e772c4
A
733 END_ENTRY _objc_msgSend
734
735
736 ENTRY _objc_msgLookup
737
738 NilTest NORMAL
739
740 GetIsaFast NORMAL // r10 = self->isa
741 CacheLookup NORMAL, LOOKUP // returns IMP on success
742
743 NilTestReturnIMP NORMAL
744
745 GetIsaSupport NORMAL
746
747// cache miss: go search the method lists
748LCacheMiss:
749 // isa still in r10
750 jmp __objc_msgLookup_uncached
751
752 END_ENTRY _objc_msgLookup
b3962a83 753
8972963c 754
7257e56c
A
755 ENTRY _objc_msgSend_fixup
756 int3
757 END_ENTRY _objc_msgSend_fixup
b3962a83 758
b3962a83 759
8972963c 760 STATIC_ENTRY _objc_msgSend_fixedup
b3962a83
A
761 // Load _cmd from the message_ref
762 movq 8(%a2), %a2
763 jmp _objc_msgSend
764 END_ENTRY _objc_msgSend_fixedup
b3962a83
A
765
766
767/********************************************************************
768 *
769 * id objc_msgSendSuper(struct objc_super *super, SEL _cmd,...);
770 *
771 * struct objc_super {
772 * id receiver;
773 * Class class;
774 * };
775 ********************************************************************/
776
c1e772c4
A
777 ENTRY _objc_msgSendSuper
778 UNWIND _objc_msgSendSuper, NoFrame
7257e56c
A
779 MESSENGER_START
780
b3962a83 781// search the cache (objc_super in %a1)
c1e772c4
A
782 movq class(%a1), %r10 // class = objc_super->class
783 movq receiver(%a1), %a1 // load real receiver
784 CacheLookup NORMAL, CALL // calls IMP on success
b3962a83
A
785
786// cache miss: go search the method lists
8972963c 787LCacheMiss:
c1e772c4
A
788 // class still in r10
789 MESSENGER_END_SLOW
790 jmp __objc_msgSend_uncached
b3962a83 791
c1e772c4 792 END_ENTRY _objc_msgSendSuper
b3962a83 793
8972963c
A
794
795/********************************************************************
796 * id objc_msgSendSuper2
797 ********************************************************************/
798
7af964d1 799 ENTRY _objc_msgSendSuper2
c1e772c4 800 UNWIND _objc_msgSendSuper2, NoFrame
7257e56c
A
801 MESSENGER_START
802
7af964d1 803 // objc_super->class is superclass of class to search
8972963c
A
804
805// search the cache (objc_super in %a1)
c1e772c4
A
806 movq class(%a1), %r10 // cls = objc_super->class
807 movq receiver(%a1), %a1 // load real receiver
808 movq 8(%r10), %r10 // cls = class->superclass
809 CacheLookup NORMAL, CALL // calls IMP on success
8972963c
A
810
811// cache miss: go search the method lists
812LCacheMiss:
c1e772c4
A
813 // superclass still in r10
814 MESSENGER_END_SLOW
815 jmp __objc_msgSend_uncached
816
817 END_ENTRY _objc_msgSendSuper2
818
819
820 ENTRY _objc_msgLookupSuper2
821
822 // objc_super->class is superclass of class to search
8972963c 823
c1e772c4
A
824// search the cache (objc_super in %a1)
825 movq class(%a1), %r10 // cls = objc_super->class
826 movq receiver(%a1), %a1 // load real receiver
827 movq 8(%r10), %r10 // cls = class->superclass
828 CacheLookup NORMAL, LOOKUP // returns IMP on success
7257e56c 829
c1e772c4
A
830// cache miss: go search the method lists
831LCacheMiss:
832 // superclass still in r10
833 jmp __objc_msgLookup_uncached
7257e56c 834
c1e772c4
A
835 END_ENTRY _objc_msgLookupSuper2
836
837
7257e56c
A
838 ENTRY _objc_msgSendSuper2_fixup
839 int3
840 END_ENTRY _objc_msgSendSuper2_fixup
841
842
843 STATIC_ENTRY _objc_msgSendSuper2_fixedup
844 // Load _cmd from the message_ref
845 movq 8(%a2), %a2
846 jmp _objc_msgSendSuper2
847 END_ENTRY _objc_msgSendSuper2_fixedup
b3962a83
A
848
849
850/********************************************************************
851 *
852 * double objc_msgSend_fpret(id self, SEL _cmd,...);
853 * Used for `long double` return only. `float` and `double` use objc_msgSend.
854 *
855 ********************************************************************/
856
c1e772c4
A
857 ENTRY _objc_msgSend_fpret
858 UNWIND _objc_msgSend_fpret, NoFrame
7257e56c
A
859 MESSENGER_START
860
8972963c 861 NilTest FPRET
b3962a83 862
c1e772c4
A
863 GetIsaFast FPRET // r10 = self->isa
864 CacheLookup FPRET, CALL // calls IMP on success
b3962a83 865
c1e772c4 866 NilTestReturnZero FPRET
b3962a83 867
c1e772c4 868 GetIsaSupport FPRET
b3962a83 869
8972963c
A
870// cache miss: go search the method lists
871LCacheMiss:
c1e772c4
A
872 // isa still in r10
873 MESSENGER_END_SLOW
874 jmp __objc_msgSend_uncached
875
876 END_ENTRY _objc_msgSend_fpret
b3962a83 877
c1e772c4
A
878
879 ENTRY _objc_msgLookup_fpret
880
881 NilTest FPRET
882
883 GetIsaFast FPRET // r10 = self->isa
884 CacheLookup FPRET, LOOKUP // returns IMP on success
885
886 NilTestReturnIMP FPRET
887
888 GetIsaSupport FPRET
889
890// cache miss: go search the method lists
891LCacheMiss:
892 // isa still in r10
893 jmp __objc_msgLookup_uncached
894
895 END_ENTRY _objc_msgLookup_fpret
7257e56c 896
b3962a83 897
b3962a83 898 ENTRY _objc_msgSend_fpret_fixup
7257e56c
A
899 int3
900 END_ENTRY _objc_msgSend_fpret_fixup
b3962a83 901
b3962a83 902
8972963c 903 STATIC_ENTRY _objc_msgSend_fpret_fixedup
b3962a83
A
904 // Load _cmd from the message_ref
905 movq 8(%a2), %a2
906 jmp _objc_msgSend_fpret
907 END_ENTRY _objc_msgSend_fpret_fixedup
b3962a83
A
908
909
910/********************************************************************
911 *
912 * double objc_msgSend_fp2ret(id self, SEL _cmd,...);
913 * Used for `complex long double` return only.
914 *
915 ********************************************************************/
916
c1e772c4
A
917 ENTRY _objc_msgSend_fp2ret
918 UNWIND _objc_msgSend_fp2ret, NoFrame
7257e56c
A
919 MESSENGER_START
920
8972963c 921 NilTest FP2RET
b3962a83 922
c1e772c4
A
923 GetIsaFast FP2RET // r10 = self->isa
924 CacheLookup FP2RET, CALL // calls IMP on success
b3962a83 925
c1e772c4 926 NilTestReturnZero FP2RET
8972963c 927
c1e772c4 928 GetIsaSupport FP2RET
8972963c 929
b3962a83 930// cache miss: go search the method lists
8972963c 931LCacheMiss:
c1e772c4
A
932 // isa still in r10
933 MESSENGER_END_SLOW
934 jmp __objc_msgSend_uncached
935
936 END_ENTRY _objc_msgSend_fp2ret
937
938
939 ENTRY _objc_msgLookup_fp2ret
940
941 NilTest FP2RET
b3962a83 942
c1e772c4
A
943 GetIsaFast FP2RET // r10 = self->isa
944 CacheLookup FP2RET, LOOKUP // returns IMP on success
945
946 NilTestReturnIMP FP2RET
947
948 GetIsaSupport FP2RET
949
950// cache miss: go search the method lists
951LCacheMiss:
952 // isa still in r10
953 jmp __objc_msgLookup_uncached
954
955 END_ENTRY _objc_msgLookup_fp2ret
b3962a83 956
b3962a83 957
7257e56c
A
958 ENTRY _objc_msgSend_fp2ret_fixup
959 int3
960 END_ENTRY _objc_msgSend_fp2ret_fixup
b3962a83 961
b3962a83 962
8972963c 963 STATIC_ENTRY _objc_msgSend_fp2ret_fixedup
b3962a83
A
964 // Load _cmd from the message_ref
965 movq 8(%a2), %a2
966 jmp _objc_msgSend_fp2ret
967 END_ENTRY _objc_msgSend_fp2ret_fixedup
b3962a83
A
968
969
970/********************************************************************
971 *
972 * void objc_msgSend_stret(void *st_addr, id self, SEL _cmd, ...);
973 *
974 * objc_msgSend_stret is the struct-return form of msgSend.
975 * The ABI calls for %a1 to be used as the address of the structure
976 * being returned, with the parameters in the succeeding locations.
977 *
978 * On entry: %a1 is the address where the structure is returned,
979 * %a2 is the message receiver,
980 * %a3 is the selector
981 ********************************************************************/
982
c1e772c4
A
983 ENTRY _objc_msgSend_stret
984 UNWIND _objc_msgSend_stret, NoFrame
7257e56c
A
985 MESSENGER_START
986
8972963c
A
987 NilTest STRET
988
c1e772c4
A
989 GetIsaFast STRET // r10 = self->isa
990 CacheLookup STRET, CALL // calls IMP on success
8972963c 991
c1e772c4 992 NilTestReturnZero STRET
8972963c 993
c1e772c4 994 GetIsaSupport STRET
b3962a83
A
995
996// cache miss: go search the method lists
8972963c 997LCacheMiss:
c1e772c4
A
998 // isa still in r10
999 MESSENGER_END_SLOW
1000 jmp __objc_msgSend_stret_uncached
1001
1002 END_ENTRY _objc_msgSend_stret
1003
b3962a83 1004
c1e772c4
A
1005 ENTRY _objc_msgLookup_stret
1006
1007 NilTest STRET
1008
1009 GetIsaFast STRET // r10 = self->isa
1010 CacheLookup STRET, LOOKUP // returns IMP on success
1011
1012 NilTestReturnIMP STRET
1013
1014 GetIsaSupport STRET
1015
1016// cache miss: go search the method lists
1017LCacheMiss:
1018 // isa still in r10
1019 jmp __objc_msgLookup_stret_uncached
1020
1021 END_ENTRY _objc_msgLookup_stret
b3962a83 1022
b3962a83 1023
7257e56c
A
1024 ENTRY _objc_msgSend_stret_fixup
1025 int3
1026 END_ENTRY _objc_msgSend_stret_fixup
b3962a83
A
1027
1028
8972963c 1029 STATIC_ENTRY _objc_msgSend_stret_fixedup
b3962a83
A
1030 // Load _cmd from the message_ref
1031 movq 8(%a3), %a3
1032 jmp _objc_msgSend_stret
1033 END_ENTRY _objc_msgSend_stret_fixedup
b3962a83
A
1034
1035
1036/********************************************************************
1037 *
1038 * void objc_msgSendSuper_stret(void *st_addr, struct objc_super *super, SEL _cmd, ...);
1039 *
1040 * struct objc_super {
1041 * id receiver;
1042 * Class class;
1043 * };
1044 *
1045 * objc_msgSendSuper_stret is the struct-return form of msgSendSuper.
1046 * The ABI calls for (sp+4) to be used as the address of the structure
1047 * being returned, with the parameters in the succeeding registers.
1048 *
1049 * On entry: %a1 is the address where the structure is returned,
1050 * %a2 is the address of the objc_super structure,
1051 * %a3 is the selector
1052 *
1053 ********************************************************************/
1054
c1e772c4
A
1055 ENTRY _objc_msgSendSuper_stret
1056 UNWIND _objc_msgSendSuper_stret, NoFrame
7257e56c
A
1057 MESSENGER_START
1058
b3962a83 1059// search the cache (objc_super in %a2)
c1e772c4
A
1060 movq class(%a2), %r10 // class = objc_super->class
1061 movq receiver(%a2), %a2 // load real receiver
1062 CacheLookup STRET, CALL // calls IMP on success
b3962a83
A
1063
1064// cache miss: go search the method lists
8972963c 1065LCacheMiss:
c1e772c4
A
1066 // class still in r10
1067 MESSENGER_END_SLOW
1068 jmp __objc_msgSend_stret_uncached
1069
1070 END_ENTRY _objc_msgSendSuper_stret
b3962a83 1071
8972963c
A
1072
1073/********************************************************************
1074 * id objc_msgSendSuper2_stret
1075 ********************************************************************/
1076
c1e772c4
A
1077 ENTRY _objc_msgSendSuper2_stret
1078 UNWIND _objc_msgSendSuper2_stret, NoFrame
7257e56c
A
1079 MESSENGER_START
1080
8972963c 1081// search the cache (objc_super in %a2)
c1e772c4
A
1082 movq class(%a2), %r10 // class = objc_super->class
1083 movq receiver(%a2), %a2 // load real receiver
1084 movq 8(%r10), %r10 // class = class->superclass
1085 CacheLookup STRET, CALL // calls IMP on success
8972963c
A
1086
1087// cache miss: go search the method lists
1088LCacheMiss:
c1e772c4
A
1089 // superclass still in r10
1090 MESSENGER_END_SLOW
1091 jmp __objc_msgSend_stret_uncached
1092
1093 END_ENTRY _objc_msgSendSuper2_stret
1094
1095
1096 ENTRY _objc_msgLookupSuper2_stret
1097
1098// search the cache (objc_super in %a2)
1099 movq class(%a2), %r10 // class = objc_super->class
8972963c 1100 movq receiver(%a2), %a2 // load real receiver
c1e772c4
A
1101 movq 8(%r10), %r10 // class = class->superclass
1102 CacheLookup STRET, LOOKUP // returns IMP on success
1103
1104// cache miss: go search the method lists
1105LCacheMiss:
1106 // superclass still in r10
1107 jmp __objc_msgLookup_stret_uncached
8972963c 1108
c1e772c4 1109 END_ENTRY _objc_msgLookupSuper2_stret
7257e56c
A
1110
1111
1112 ENTRY _objc_msgSendSuper2_stret_fixup
1113 int3
1114 END_ENTRY _objc_msgSendSuper2_stret_fixup
1115
1116
1117 STATIC_ENTRY _objc_msgSendSuper2_stret_fixedup
1118 // Load _cmd from the message_ref
1119 movq 8(%a3), %a3
1120 jmp _objc_msgSendSuper2_stret
1121 END_ENTRY _objc_msgSendSuper2_stret_fixedup
b3962a83
A
1122
1123
7257e56c
A
1124/********************************************************************
1125 *
7257e56c
A
1126 * _objc_msgSend_uncached
1127 * _objc_msgSend_stret_uncached
c1e772c4
A
1128 * _objc_msgLookup_uncached
1129 * _objc_msgLookup_stret_uncached
1130 *
1131 * The uncached method lookup.
7257e56c
A
1132 *
1133 ********************************************************************/
7257e56c
A
1134
1135 STATIC_ENTRY __objc_msgSend_uncached
c1e772c4
A
1136 UNWIND __objc_msgSend_uncached, FrameWithNoSaves
1137
7257e56c 1138 // THIS IS NOT A CALLABLE C FUNCTION
c1e772c4 1139 // Out-of-band r10 is the searched class
7257e56c 1140
c1e772c4
A
1141 // r10 is already the class to search
1142 MethodTableLookup NORMAL // r11 = IMP
7257e56c
A
1143 jmp *%r11 // goto *imp
1144
7257e56c
A
1145 END_ENTRY __objc_msgSend_uncached
1146
1147
1148 STATIC_ENTRY __objc_msgSend_stret_uncached
c1e772c4
A
1149 UNWIND __objc_msgSend_stret_uncached, FrameWithNoSaves
1150
7257e56c 1151 // THIS IS NOT A CALLABLE C FUNCTION
c1e772c4 1152 // Out-of-band r10 is the searched class
7257e56c 1153
c1e772c4
A
1154 // r10 is already the class to search
1155 MethodTableLookup STRET // r11 = IMP
7257e56c
A
1156 jmp *%r11 // goto *imp
1157
7257e56c
A
1158 END_ENTRY __objc_msgSend_stret_uncached
1159
1160
c1e772c4
A
1161 STATIC_ENTRY __objc_msgLookup_uncached
1162 UNWIND __objc_msgLookup_uncached, FrameWithNoSaves
1163
1164 // THIS IS NOT A CALLABLE C FUNCTION
1165 // Out-of-band r10 is the searched class
1166
1167 // r10 is already the class to search
1168 MethodTableLookup NORMAL // r11 = IMP
1169 ret
1170
1171 END_ENTRY __objc_msgLookup_uncached
1172
1173
1174 STATIC_ENTRY __objc_msgLookup_stret_uncached
1175 UNWIND __objc_msgLookup_stret_uncached, FrameWithNoSaves
1176
1177 // THIS IS NOT A CALLABLE C FUNCTION
1178 // Out-of-band r10 is the searched class
1179
1180 // r10 is already the class to search
1181 MethodTableLookup STRET // r11 = IMP
1182 ret
1183
1184 END_ENTRY __objc_msgLookup_stret_uncached
1185
1186
b3962a83 1187/********************************************************************
8070259c
A
1188*
1189* id _objc_msgForward(id self, SEL _cmd,...);
1190*
1191* _objc_msgForward and _objc_msgForward_stret are the externally-callable
1192* functions returned by things like method_getImplementation().
1193* _objc_msgForward_impcache is the function pointer actually stored in
1194* method caches.
1195*
1196********************************************************************/
b3962a83 1197
c1e772c4 1198 STATIC_ENTRY __objc_msgForward_impcache
7af964d1
A
1199 // Method cache version
1200
1201 // THIS IS NOT A CALLABLE C FUNCTION
1202 // Out-of-band condition register is NE for stret, EQ otherwise.
b3962a83 1203
7257e56c
A
1204 MESSENGER_START
1205 nop
1206 MESSENGER_END_SLOW
1207
7af964d1
A
1208 jne __objc_msgForward_stret
1209 jmp __objc_msgForward
1210
c1e772c4 1211 END_ENTRY __objc_msgForward_impcache
7af964d1
A
1212
1213
c1e772c4 1214 ENTRY __objc_msgForward
7af964d1 1215 // Non-stret version
b3962a83 1216
b3962a83 1217 movq __objc_forward_handler(%rip), %r11
8070259c 1218 jmp *%r11
b3962a83 1219
c1e772c4 1220 END_ENTRY __objc_msgForward
b3962a83
A
1221
1222
c1e772c4 1223 ENTRY __objc_msgForward_stret
7af964d1 1224 // Struct-return version
b3962a83 1225
8070259c
A
1226 movq __objc_forward_stret_handler(%rip), %r11
1227 jmp *%r11
b3962a83 1228
c1e772c4 1229 END_ENTRY __objc_msgForward_stret
b3962a83
A
1230
1231
8972963c
A
1232 ENTRY _objc_msgSend_debug
1233 jmp _objc_msgSend
1234 END_ENTRY _objc_msgSend_debug
1235
1236 ENTRY _objc_msgSendSuper2_debug
1237 jmp _objc_msgSendSuper2
1238 END_ENTRY _objc_msgSendSuper2_debug
1239
1240 ENTRY _objc_msgSend_stret_debug
1241 jmp _objc_msgSend_stret
1242 END_ENTRY _objc_msgSend_stret_debug
1243
1244 ENTRY _objc_msgSendSuper2_stret_debug
1245 jmp _objc_msgSendSuper2_stret
1246 END_ENTRY _objc_msgSendSuper2_stret_debug
1247
1248 ENTRY _objc_msgSend_fpret_debug
1249 jmp _objc_msgSend_fpret
1250 END_ENTRY _objc_msgSend_fpret_debug
1251
1252 ENTRY _objc_msgSend_fp2ret_debug
1253 jmp _objc_msgSend_fp2ret
1254 END_ENTRY _objc_msgSend_fp2ret_debug
1255
1256
1257 ENTRY _objc_msgSend_noarg
1258 jmp _objc_msgSend
1259 END_ENTRY _objc_msgSend_noarg
1260
1261
b3962a83
A
1262 ENTRY _method_invoke
1263
1264 movq method_imp(%a2), %r11
1265 movq method_name(%a2), %a2
1266 jmp *%r11
1267
1268 END_ENTRY _method_invoke
1269
1270
1271 ENTRY _method_invoke_stret
1272
1273 movq method_imp(%a3), %r11
1274 movq method_name(%a3), %a3
1275 jmp *%r11
1276
1277 END_ENTRY _method_invoke_stret
7af964d1 1278
8972963c 1279
7257e56c
A
1280.section __DATA,__objc_msg_break
1281.quad 0
1282.quad 0
7af964d1
A
1283
1284#endif