objc-msg-arm.s 20 KB

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