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