/Modules/_ctypes/libffi/src/sh64/sysv.S

http://unladen-swallow.googlecode.com/ · Assembly · 526 lines · 442 code · 47 blank · 37 comment · 1 complexity · 25a539aed0fa1dd542f312656669c122 MD5 · raw file

  1. /* -----------------------------------------------------------------------
  2. sysv.S - Copyright (c) 2003, 2004 Kaz Kojima
  3. SuperH SHmedia Foreign Function Interface
  4. Permission is hereby granted, free of charge, to any person obtaining
  5. a copy of this software and associated documentation files (the
  6. ``Software''), to deal in the Software without restriction, including
  7. without limitation the rights to use, copy, modify, merge, publish,
  8. distribute, sublicense, and/or sell copies of the Software, and to
  9. permit persons to whom the Software is furnished to do so, subject to
  10. the following conditions:
  11. The above copyright notice and this permission notice shall be included
  12. in all copies or substantial portions of the Software.
  13. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
  14. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  15. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  16. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
  17. ANY CLAIM, DAMAGES OR
  18. OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. OTHER DEALINGS IN THE SOFTWARE.
  21. ----------------------------------------------------------------------- */
  22. #define LIBFFI_ASM
  23. #include <fficonfig.h>
  24. #include <ffi.h>
  25. #ifdef HAVE_MACHINE_ASM_H
  26. #include <machine/asm.h>
  27. #else
  28. /* XXX these lose for some platforms, I'm sure. */
  29. #define CNAME(x) x
  30. #define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
  31. #endif
  32. #ifdef __LITTLE_ENDIAN__
  33. #define OFS_FLT 0
  34. #else
  35. #define OFS_FLT 4
  36. #endif
  37. .section .text..SHmedia32,"ax"
  38. # r2: ffi_prep_args
  39. # r3: &ecif
  40. # r4: bytes
  41. # r5: flags
  42. # r6: flags2
  43. # r7: rvalue
  44. # r8: fn
  45. # This assumes we are using gas.
  46. .align 5
  47. ENTRY(ffi_call_SYSV)
  48. # Save registers
  49. .LFB1:
  50. addi.l r15, -48, r15
  51. .LCFI0:
  52. st.q r15, 40, r32
  53. st.q r15, 32, r31
  54. st.q r15, 24, r30
  55. st.q r15, 16, r29
  56. st.q r15, 8, r28
  57. st.l r15, 4, r18
  58. st.l r15, 0, r14
  59. .LCFI1:
  60. add.l r15, r63, r14
  61. .LCFI2:
  62. # add r4, r63, r28
  63. add r5, r63, r29
  64. add r6, r63, r30
  65. add r7, r63, r31
  66. add r8, r63, r32
  67. addi r4, (64 + 7), r4
  68. andi r4, ~7, r4
  69. sub.l r15, r4, r15
  70. ptabs/l r2, tr0
  71. add r15, r63, r2
  72. blink tr0, r18
  73. addi r15, 64, r22
  74. movi 0, r0
  75. movi 0, r1
  76. pt/l 1f, tr1
  77. bnei/l r29, FFI_TYPE_STRUCT, tr1
  78. ld.l r15, 0, r19
  79. addi r15, 8, r15
  80. addi r0, 1, r0
  81. 1:
  82. .L_pass:
  83. andi r30, 3, r20
  84. shlri r30, 2, r30
  85. pt/l .L_call_it, tr0
  86. pt/l .L_pass_i, tr1
  87. pt/l .L_pass_f, tr2
  88. beqi/l r20, FFI_TYPE_VOID, tr0
  89. beqi/l r20, FFI_TYPE_INT, tr1
  90. beqi/l r20, FFI_TYPE_FLOAT, tr2
  91. .L_pass_d:
  92. addi r0, 1, r0
  93. addi r1, 1, r1
  94. andi r1, ~1, r1
  95. pt/l 3f, tr0
  96. movi 12, r20
  97. bge/l r1, r20, tr0
  98. pt/l .L_pop_d, tr1
  99. pt/l 2f, tr0
  100. blink tr1, r63
  101. 2:
  102. addi.l r15, 8, r15
  103. 3:
  104. pt/l .L_pass, tr0
  105. addi r1, 2, r1
  106. blink tr0, r63
  107. .L_pop_d:
  108. pt/l .L_pop_d_tbl, tr1
  109. gettr tr1, r20
  110. shlli r1, 2, r21
  111. add r20, r21, r20
  112. ptabs/l r20, tr1
  113. blink tr1, r63
  114. .L_pop_d_tbl:
  115. fld.d r15, 0, dr0
  116. blink tr0, r63
  117. fld.d r15, 0, dr2
  118. blink tr0, r63
  119. fld.d r15, 0, dr4
  120. blink tr0, r63
  121. fld.d r15, 0, dr6
  122. blink tr0, r63
  123. fld.d r15, 0, dr8
  124. blink tr0, r63
  125. fld.d r15, 0, dr10
  126. blink tr0, r63
  127. .L_pass_f:
  128. addi r0, 1, r0
  129. pt/l 3f, tr0
  130. movi 12, r20
  131. bge/l r1, r20, tr0
  132. pt/l .L_pop_f, tr1
  133. pt/l 2f, tr0
  134. blink tr1, r63
  135. 2:
  136. addi.l r15, 8, r15
  137. 3:
  138. pt/l .L_pass, tr0
  139. addi r1, 1, r1
  140. blink tr0, r63
  141. .L_pop_f:
  142. pt/l .L_pop_f_tbl, tr1
  143. gettr tr1, r20
  144. shlli r1, 3, r21
  145. add r20, r21, r20
  146. ptabs/l r20, tr1
  147. blink tr1, r63
  148. .L_pop_f_tbl:
  149. fld.s r15, OFS_FLT, fr0
  150. blink tr0, r63
  151. fld.s r15, OFS_FLT, fr1
  152. blink tr0, r63
  153. fld.s r15, OFS_FLT, fr2
  154. blink tr0, r63
  155. fld.s r15, OFS_FLT, fr3
  156. blink tr0, r63
  157. fld.s r15, OFS_FLT, fr4
  158. blink tr0, r63
  159. fld.s r15, OFS_FLT, fr5
  160. blink tr0, r63
  161. fld.s r15, OFS_FLT, fr6
  162. blink tr0, r63
  163. fld.s r15, OFS_FLT, fr7
  164. blink tr0, r63
  165. fld.s r15, OFS_FLT, fr8
  166. blink tr0, r63
  167. fld.s r15, OFS_FLT, fr9
  168. blink tr0, r63
  169. fld.s r15, OFS_FLT, fr10
  170. blink tr0, r63
  171. fld.s r15, OFS_FLT, fr11
  172. blink tr0, r63
  173. .L_pass_i:
  174. pt/l 3f, tr0
  175. movi 8, r20
  176. bge/l r0, r20, tr0
  177. pt/l .L_pop_i, tr1
  178. pt/l 2f, tr0
  179. blink tr1, r63
  180. 2:
  181. addi.l r15, 8, r15
  182. 3:
  183. pt/l .L_pass, tr0
  184. addi r0, 1, r0
  185. blink tr0, r63
  186. .L_pop_i:
  187. pt/l .L_pop_i_tbl, tr1
  188. gettr tr1, r20
  189. shlli r0, 3, r21
  190. add r20, r21, r20
  191. ptabs/l r20, tr1
  192. blink tr1, r63
  193. .L_pop_i_tbl:
  194. ld.q r15, 0, r2
  195. blink tr0, r63
  196. ld.q r15, 0, r3
  197. blink tr0, r63
  198. ld.q r15, 0, r4
  199. blink tr0, r63
  200. ld.q r15, 0, r5
  201. blink tr0, r63
  202. ld.q r15, 0, r6
  203. blink tr0, r63
  204. ld.q r15, 0, r7
  205. blink tr0, r63
  206. ld.q r15, 0, r8
  207. blink tr0, r63
  208. ld.q r15, 0, r9
  209. blink tr0, r63
  210. .L_call_it:
  211. # call function
  212. pt/l 1f, tr1
  213. bnei/l r29, FFI_TYPE_STRUCT, tr1
  214. add r19, r63, r2
  215. 1:
  216. add r22, r63, r15
  217. ptabs/l r32, tr0
  218. blink tr0, r18
  219. pt/l .L_ret_i, tr0
  220. pt/l .L_ret_ll, tr1
  221. pt/l .L_ret_d, tr2
  222. pt/l .L_ret_f, tr3
  223. pt/l .L_epilogue, tr4
  224. beqi/l r29, FFI_TYPE_INT, tr0
  225. beqi/l r29, FFI_TYPE_UINT32, tr0
  226. beqi/l r29, FFI_TYPE_SINT64, tr1
  227. beqi/l r29, FFI_TYPE_UINT64, tr1
  228. beqi/l r29, FFI_TYPE_DOUBLE, tr2
  229. beqi/l r29, FFI_TYPE_FLOAT, tr3
  230. pt/l .L_ret_q, tr0
  231. pt/l .L_ret_h, tr1
  232. beqi/l r29, FFI_TYPE_UINT8, tr0
  233. beqi/l r29, FFI_TYPE_UINT16, tr1
  234. blink tr4, r63
  235. .L_ret_d:
  236. fst.d r31, 0, dr0
  237. blink tr4, r63
  238. .L_ret_ll:
  239. st.q r31, 0, r2
  240. blink tr4, r63
  241. .L_ret_f:
  242. fst.s r31, OFS_FLT, fr0
  243. blink tr4, r63
  244. .L_ret_q:
  245. st.b r31, 0, r2
  246. blink tr4, r63
  247. .L_ret_h:
  248. st.w r31, 0, r2
  249. blink tr4, r63
  250. .L_ret_i:
  251. st.l r31, 0, r2
  252. # Fall
  253. .L_epilogue:
  254. # Remove the space we pushed for the args
  255. add r14, r63, r15
  256. ld.l r15, 0, r14
  257. ld.l r15, 4, r18
  258. ld.q r15, 8, r28
  259. ld.q r15, 16, r29
  260. ld.q r15, 24, r30
  261. ld.q r15, 32, r31
  262. ld.q r15, 40, r32
  263. addi.l r15, 48, r15
  264. ptabs r18, tr0
  265. blink tr0, r63
  266. .LFE1:
  267. .ffi_call_SYSV_end:
  268. .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
  269. .align 5
  270. ENTRY(ffi_closure_SYSV)
  271. .LFB2:
  272. addi.l r15, -136, r15
  273. .LCFI3:
  274. st.l r15, 12, r18
  275. st.l r15, 8, r14
  276. st.l r15, 4, r12
  277. .LCFI4:
  278. add r15, r63, r14
  279. .LCFI5:
  280. /* Stack layout:
  281. ...
  282. 64 bytes (register parameters)
  283. 48 bytes (floating register parameters)
  284. 8 bytes (result)
  285. 4 bytes (r18)
  286. 4 bytes (r14)
  287. 4 bytes (r12)
  288. 4 bytes (for align)
  289. <- new stack pointer
  290. */
  291. fst.d r14, 24, dr0
  292. fst.d r14, 32, dr2
  293. fst.d r14, 40, dr4
  294. fst.d r14, 48, dr6
  295. fst.d r14, 56, dr8
  296. fst.d r14, 64, dr10
  297. st.q r14, 72, r2
  298. st.q r14, 80, r3
  299. st.q r14, 88, r4
  300. st.q r14, 96, r5
  301. st.q r14, 104, r6
  302. st.q r14, 112, r7
  303. st.q r14, 120, r8
  304. st.q r14, 128, r9
  305. add r1, r63, r2
  306. addi r14, 16, r3
  307. addi r14, 72, r4
  308. addi r14, 24, r5
  309. addi r14, 136, r6
  310. #ifdef PIC
  311. movi (((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) >> 16) & 65535), r12
  312. shori ((datalabel _GLOBAL_OFFSET_TABLE_-(.LPCS0-.)) & 65535), r12
  313. .LPCS0: ptrel/u r12, tr0
  314. movi ((ffi_closure_helper_SYSV@GOTPLT) & 65535), r1
  315. gettr tr0, r12
  316. ldx.l r1, r12, r1
  317. ptabs r1, tr0
  318. #else
  319. pt/l ffi_closure_helper_SYSV, tr0
  320. #endif
  321. blink tr0, r18
  322. shlli r2, 1, r1
  323. movi (((datalabel .L_table) >> 16) & 65535), r2
  324. shori ((datalabel .L_table) & 65535), r2
  325. ldx.w r2, r1, r1
  326. add r1, r2, r1
  327. pt/l .L_case_v, tr1
  328. ptabs r1, tr0
  329. blink tr0, r63
  330. .align 2
  331. .L_table:
  332. .word .L_case_v - datalabel .L_table /* FFI_TYPE_VOID */
  333. .word .L_case_i - datalabel .L_table /* FFI_TYPE_INT */
  334. .word .L_case_f - datalabel .L_table /* FFI_TYPE_FLOAT */
  335. .word .L_case_d - datalabel .L_table /* FFI_TYPE_DOUBLE */
  336. .word .L_case_d - datalabel .L_table /* FFI_TYPE_LONGDOUBLE */
  337. .word .L_case_uq - datalabel .L_table /* FFI_TYPE_UINT8 */
  338. .word .L_case_q - datalabel .L_table /* FFI_TYPE_SINT8 */
  339. .word .L_case_uh - datalabel .L_table /* FFI_TYPE_UINT16 */
  340. .word .L_case_h - datalabel .L_table /* FFI_TYPE_SINT16 */
  341. .word .L_case_i - datalabel .L_table /* FFI_TYPE_UINT32 */
  342. .word .L_case_i - datalabel .L_table /* FFI_TYPE_SINT32 */
  343. .word .L_case_ll - datalabel .L_table /* FFI_TYPE_UINT64 */
  344. .word .L_case_ll - datalabel .L_table /* FFI_TYPE_SINT64 */
  345. .word .L_case_v - datalabel .L_table /* FFI_TYPE_STRUCT */
  346. .word .L_case_i - datalabel .L_table /* FFI_TYPE_POINTER */
  347. .align 2
  348. .L_case_d:
  349. fld.d r14, 16, dr0
  350. blink tr1, r63
  351. .L_case_f:
  352. fld.s r14, 16, fr0
  353. blink tr1, r63
  354. .L_case_ll:
  355. ld.q r14, 16, r2
  356. blink tr1, r63
  357. .L_case_i:
  358. ld.l r14, 16, r2
  359. blink tr1, r63
  360. .L_case_q:
  361. ld.b r14, 16, r2
  362. blink tr1, r63
  363. .L_case_uq:
  364. ld.ub r14, 16, r2
  365. blink tr1, r63
  366. .L_case_h:
  367. ld.w r14, 16, r2
  368. blink tr1, r63
  369. .L_case_uh:
  370. ld.uw r14, 16, r2
  371. blink tr1, r63
  372. .L_case_v:
  373. add.l r14, r63, r15
  374. ld.l r15, 4, r12
  375. ld.l r15, 8, r14
  376. ld.l r15, 12, r18
  377. addi.l r15, 136, r15
  378. ptabs r18, tr0
  379. blink tr0, r63
  380. .LFE2:
  381. .ffi_closure_SYSV_end:
  382. .size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
  383. .section ".eh_frame","aw",@progbits
  384. __FRAME_BEGIN__:
  385. .4byte .LECIE1-.LSCIE1 /* Length of Common Information Entry */
  386. .LSCIE1:
  387. .4byte 0x0 /* CIE Identifier Tag */
  388. .byte 0x1 /* CIE Version */
  389. #ifdef PIC
  390. .ascii "zR\0" /* CIE Augmentation */
  391. #else
  392. .byte 0x0 /* CIE Augmentation */
  393. #endif
  394. .uleb128 0x1 /* CIE Code Alignment Factor */
  395. .sleb128 -4 /* CIE Data Alignment Factor */
  396. .byte 0x12 /* CIE RA Column */
  397. #ifdef PIC
  398. .uleb128 0x1 /* Augmentation size */
  399. .byte 0x10 /* FDE Encoding (pcrel) */
  400. #endif
  401. .byte 0xc /* DW_CFA_def_cfa */
  402. .uleb128 0xf
  403. .uleb128 0x0
  404. .align 2
  405. .LECIE1:
  406. .LSFDE1:
  407. .4byte datalabel .LEFDE1-datalabel .LASFDE1 /* FDE Length */
  408. .LASFDE1:
  409. .4byte datalabel .LASFDE1-datalabel __FRAME_BEGIN__
  410. #ifdef PIC
  411. .4byte .LFB1-. /* FDE initial location */
  412. #else
  413. .4byte .LFB1 /* FDE initial location */
  414. #endif
  415. .4byte datalabel .LFE1-datalabel .LFB1 /* FDE address range */
  416. #ifdef PIC
  417. .uleb128 0x0 /* Augmentation size */
  418. #endif
  419. .byte 0x4 /* DW_CFA_advance_loc4 */
  420. .4byte datalabel .LCFI0-datalabel .LFB1
  421. .byte 0xe /* DW_CFA_def_cfa_offset */
  422. .uleb128 0x30
  423. .byte 0x4 /* DW_CFA_advance_loc4 */
  424. .4byte datalabel .LCFI1-datalabel .LCFI0
  425. .byte 0x8e /* DW_CFA_offset, column 0xe */
  426. .uleb128 0xc
  427. .byte 0x92 /* DW_CFA_offset, column 0x12 */
  428. .uleb128 0xb
  429. .byte 0x9c /* DW_CFA_offset, column 0x1c */
  430. .uleb128 0xa
  431. .byte 0x9d /* DW_CFA_offset, column 0x1d */
  432. .uleb128 0x8
  433. .byte 0x9e /* DW_CFA_offset, column 0x1e */
  434. .uleb128 0x6
  435. .byte 0x9f /* DW_CFA_offset, column 0x1f */
  436. .uleb128 0x4
  437. .byte 0xa0 /* DW_CFA_offset, column 0x20 */
  438. .uleb128 0x2
  439. .byte 0x4 /* DW_CFA_advance_loc4 */
  440. .4byte datalabel .LCFI2-datalabel .LCFI1
  441. .byte 0xd /* DW_CFA_def_cfa_register */
  442. .uleb128 0xe
  443. .align 2
  444. .LEFDE1:
  445. .LSFDE3:
  446. .4byte datalabel .LEFDE3-datalabel .LASFDE3 /* FDE Length */
  447. .LASFDE3:
  448. .4byte datalabel .LASFDE3-datalabel __FRAME_BEGIN__
  449. #ifdef PIC
  450. .4byte .LFB2-. /* FDE initial location */
  451. #else
  452. .4byte .LFB2 /* FDE initial location */
  453. #endif
  454. .4byte datalabel .LFE2-datalabel .LFB2 /* FDE address range */
  455. #ifdef PIC
  456. .uleb128 0x0 /* Augmentation size */
  457. #endif
  458. .byte 0x4 /* DW_CFA_advance_loc4 */
  459. .4byte datalabel .LCFI3-datalabel .LFB2
  460. .byte 0xe /* DW_CFA_def_cfa_offset */
  461. .uleb128 0x88
  462. .byte 0x4 /* DW_CFA_advance_loc4 */
  463. .4byte datalabel .LCFI4-datalabel .LCFI3
  464. .byte 0x8c /* DW_CFA_offset, column 0xc */
  465. .uleb128 0x21
  466. .byte 0x8e /* DW_CFA_offset, column 0xe */
  467. .uleb128 0x20
  468. .byte 0x92 /* DW_CFA_offset, column 0x12 */
  469. .uleb128 0x1f
  470. .byte 0x4 /* DW_CFA_advance_loc4 */
  471. .4byte datalabel .LCFI5-datalabel .LCFI4
  472. .byte 0xd /* DW_CFA_def_cfa_register */
  473. .uleb128 0xe
  474. .align 2
  475. .LEFDE3: