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

http://unladen-swallow.googlecode.com/ · Assembly · 434 lines · 362 code · 46 blank · 26 comment · 1 complexity · 273cd90e92230866c6c662b3f5cced06 MD5 · raw file

  1. /* -----------------------------------------------------------------------
  2. sysv.S - Copyright (c) 2000 Software AG
  3. Copyright (c) 2008 Red Hat, Inc.
  4. S390 Foreign Function Interface
  5. Permission is hereby granted, free of charge, to any person obtaining
  6. a copy of this software and associated documentation files (the
  7. ``Software''), to deal in the Software without restriction, including
  8. without limitation the rights to use, copy, modify, merge, publish,
  9. distribute, sublicense, and/or sell copies of the Software, and to
  10. permit persons to whom the Software is furnished to do so, subject to
  11. the following conditions:
  12. The above copyright notice and this permission notice shall be included
  13. in all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
  15. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  19. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21. DEALINGS IN THE SOFTWARE.
  22. ----------------------------------------------------------------------- */
  23. #define LIBFFI_ASM
  24. #include <fficonfig.h>
  25. #include <ffi.h>
  26. #ifndef __s390x__
  27. .text
  28. # r2: cif->bytes
  29. # r3: &ecif
  30. # r4: ffi_prep_args
  31. # r5: ret_type
  32. # r6: ecif.rvalue
  33. # ov: fn
  34. # This assumes we are using gas.
  35. .globl ffi_call_SYSV
  36. .type ffi_call_SYSV,%function
  37. ffi_call_SYSV:
  38. .LFB1:
  39. stm %r6,%r15,24(%r15) # Save registers
  40. .LCFI0:
  41. basr %r13,0 # Set up base register
  42. .Lbase:
  43. lr %r11,%r15 # Set up frame pointer
  44. .LCFI1:
  45. sr %r15,%r2
  46. ahi %r15,-96-48 # Allocate stack
  47. lr %r8,%r6 # Save ecif.rvalue
  48. sr %r9,%r9
  49. ic %r9,.Ltable-.Lbase(%r13,%r5) # Load epilog address
  50. l %r7,96(%r11) # Load function address
  51. st %r11,0(%r15) # Set up back chain
  52. ahi %r11,-48 # Register save area
  53. .LCFI2:
  54. la %r2,96(%r15) # Save area
  55. # r3 already holds &ecif
  56. basr %r14,%r4 # Call ffi_prep_args
  57. lm %r2,%r6,0(%r11) # Load arguments
  58. ld %f0,32(%r11)
  59. ld %f2,40(%r11)
  60. la %r14,0(%r13,%r9) # Set return address
  61. br %r7 # ... and call function
  62. .LretNone: # Return void
  63. l %r4,48+56(%r11)
  64. lm %r6,%r15,48+24(%r11)
  65. br %r4
  66. .LretFloat:
  67. l %r4,48+56(%r11)
  68. ste %f0,0(%r8) # Return float
  69. lm %r6,%r15,48+24(%r11)
  70. br %r4
  71. .LretDouble:
  72. l %r4,48+56(%r11)
  73. std %f0,0(%r8) # Return double
  74. lm %r6,%r15,48+24(%r11)
  75. br %r4
  76. .LretInt32:
  77. l %r4,48+56(%r11)
  78. st %r2,0(%r8) # Return int
  79. lm %r6,%r15,48+24(%r11)
  80. br %r4
  81. .LretInt64:
  82. l %r4,48+56(%r11)
  83. stm %r2,%r3,0(%r8) # Return long long
  84. lm %r6,%r15,48+24(%r11)
  85. br %r4
  86. .Ltable:
  87. .byte .LretNone-.Lbase # FFI390_RET_VOID
  88. .byte .LretNone-.Lbase # FFI390_RET_STRUCT
  89. .byte .LretFloat-.Lbase # FFI390_RET_FLOAT
  90. .byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
  91. .byte .LretInt32-.Lbase # FFI390_RET_INT32
  92. .byte .LretInt64-.Lbase # FFI390_RET_INT64
  93. .LFE1:
  94. .ffi_call_SYSV_end:
  95. .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
  96. .globl ffi_closure_SYSV
  97. .type ffi_closure_SYSV,%function
  98. ffi_closure_SYSV:
  99. .LFB2:
  100. stm %r12,%r15,48(%r15) # Save registers
  101. .LCFI10:
  102. basr %r13,0 # Set up base register
  103. .Lcbase:
  104. stm %r2,%r6,8(%r15) # Save arguments
  105. std %f0,64(%r15)
  106. std %f2,72(%r15)
  107. lr %r1,%r15 # Set up stack frame
  108. ahi %r15,-96
  109. .LCFI11:
  110. l %r12,.Lchelper-.Lcbase(%r13) # Get helper function
  111. lr %r2,%r0 # Closure
  112. la %r3,8(%r1) # GPRs
  113. la %r4,64(%r1) # FPRs
  114. la %r5,96(%r1) # Overflow
  115. st %r1,0(%r15) # Set up back chain
  116. bas %r14,0(%r12,%r13) # Call helper
  117. l %r4,96+56(%r15)
  118. ld %f0,96+64(%r15) # Load return registers
  119. lm %r2,%r3,96+8(%r15)
  120. lm %r12,%r15,96+48(%r15)
  121. br %r4
  122. .align 4
  123. .Lchelper:
  124. .long ffi_closure_helper_SYSV-.Lcbase
  125. .LFE2:
  126. .ffi_closure_SYSV_end:
  127. .size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
  128. .section .eh_frame,EH_FRAME_FLAGS,@progbits
  129. .Lframe1:
  130. .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
  131. .LSCIE1:
  132. .4byte 0x0 # CIE Identifier Tag
  133. .byte 0x1 # CIE Version
  134. .ascii "zR\0" # CIE Augmentation
  135. .uleb128 0x1 # CIE Code Alignment Factor
  136. .sleb128 -4 # CIE Data Alignment Factor
  137. .byte 0xe # CIE RA Column
  138. .uleb128 0x1 # Augmentation size
  139. .byte 0x1b # FDE Encoding (pcrel sdata4)
  140. .byte 0xc # DW_CFA_def_cfa
  141. .uleb128 0xf
  142. .uleb128 0x60
  143. .align 4
  144. .LECIE1:
  145. .LSFDE1:
  146. .4byte .LEFDE1-.LASFDE1 # FDE Length
  147. .LASFDE1:
  148. .4byte .LASFDE1-.Lframe1 # FDE CIE offset
  149. .4byte .LFB1-. # FDE initial location
  150. .4byte .LFE1-.LFB1 # FDE address range
  151. .uleb128 0x0 # Augmentation size
  152. .byte 0x4 # DW_CFA_advance_loc4
  153. .4byte .LCFI0-.LFB1
  154. .byte 0x8f # DW_CFA_offset, column 0xf
  155. .uleb128 0x9
  156. .byte 0x8e # DW_CFA_offset, column 0xe
  157. .uleb128 0xa
  158. .byte 0x8d # DW_CFA_offset, column 0xd
  159. .uleb128 0xb
  160. .byte 0x8c # DW_CFA_offset, column 0xc
  161. .uleb128 0xc
  162. .byte 0x8b # DW_CFA_offset, column 0xb
  163. .uleb128 0xd
  164. .byte 0x8a # DW_CFA_offset, column 0xa
  165. .uleb128 0xe
  166. .byte 0x89 # DW_CFA_offset, column 0x9
  167. .uleb128 0xf
  168. .byte 0x88 # DW_CFA_offset, column 0x8
  169. .uleb128 0x10
  170. .byte 0x87 # DW_CFA_offset, column 0x7
  171. .uleb128 0x11
  172. .byte 0x86 # DW_CFA_offset, column 0x6
  173. .uleb128 0x12
  174. .byte 0x4 # DW_CFA_advance_loc4
  175. .4byte .LCFI1-.LCFI0
  176. .byte 0xd # DW_CFA_def_cfa_register
  177. .uleb128 0xb
  178. .byte 0x4 # DW_CFA_advance_loc4
  179. .4byte .LCFI2-.LCFI1
  180. .byte 0xe # DW_CFA_def_cfa_offset
  181. .uleb128 0x90
  182. .align 4
  183. .LEFDE1:
  184. .LSFDE2:
  185. .4byte .LEFDE2-.LASFDE2 # FDE Length
  186. .LASFDE2:
  187. .4byte .LASFDE2-.Lframe1 # FDE CIE offset
  188. .4byte .LFB2-. # FDE initial location
  189. .4byte .LFE2-.LFB2 # FDE address range
  190. .uleb128 0x0 # Augmentation size
  191. .byte 0x4 # DW_CFA_advance_loc4
  192. .4byte .LCFI10-.LFB2
  193. .byte 0x8f # DW_CFA_offset, column 0xf
  194. .uleb128 0x9
  195. .byte 0x8e # DW_CFA_offset, column 0xe
  196. .uleb128 0xa
  197. .byte 0x8d # DW_CFA_offset, column 0xd
  198. .uleb128 0xb
  199. .byte 0x8c # DW_CFA_offset, column 0xc
  200. .uleb128 0xc
  201. .byte 0x4 # DW_CFA_advance_loc4
  202. .4byte .LCFI11-.LCFI10
  203. .byte 0xe # DW_CFA_def_cfa_offset
  204. .uleb128 0xc0
  205. .align 4
  206. .LEFDE2:
  207. #else
  208. .text
  209. # r2: cif->bytes
  210. # r3: &ecif
  211. # r4: ffi_prep_args
  212. # r5: ret_type
  213. # r6: ecif.rvalue
  214. # ov: fn
  215. # This assumes we are using gas.
  216. .globl ffi_call_SYSV
  217. .type ffi_call_SYSV,%function
  218. ffi_call_SYSV:
  219. .LFB1:
  220. stmg %r6,%r15,48(%r15) # Save registers
  221. .LCFI0:
  222. larl %r13,.Lbase # Set up base register
  223. lgr %r11,%r15 # Set up frame pointer
  224. .LCFI1:
  225. sgr %r15,%r2
  226. aghi %r15,-160-80 # Allocate stack
  227. lgr %r8,%r6 # Save ecif.rvalue
  228. llgc %r9,.Ltable-.Lbase(%r13,%r5) # Load epilog address
  229. lg %r7,160(%r11) # Load function address
  230. stg %r11,0(%r15) # Set up back chain
  231. aghi %r11,-80 # Register save area
  232. .LCFI2:
  233. la %r2,160(%r15) # Save area
  234. # r3 already holds &ecif
  235. basr %r14,%r4 # Call ffi_prep_args
  236. lmg %r2,%r6,0(%r11) # Load arguments
  237. ld %f0,48(%r11)
  238. ld %f2,56(%r11)
  239. ld %f4,64(%r11)
  240. ld %f6,72(%r11)
  241. la %r14,0(%r13,%r9) # Set return address
  242. br %r7 # ... and call function
  243. .Lbase:
  244. .LretNone: # Return void
  245. lg %r4,80+112(%r11)
  246. lmg %r6,%r15,80+48(%r11)
  247. br %r4
  248. .LretFloat:
  249. lg %r4,80+112(%r11)
  250. ste %f0,0(%r8) # Return float
  251. lmg %r6,%r15,80+48(%r11)
  252. br %r4
  253. .LretDouble:
  254. lg %r4,80+112(%r11)
  255. std %f0,0(%r8) # Return double
  256. lmg %r6,%r15,80+48(%r11)
  257. br %r4
  258. .LretInt32:
  259. lg %r4,80+112(%r11)
  260. st %r2,0(%r8) # Return int
  261. lmg %r6,%r15,80+48(%r11)
  262. br %r4
  263. .LretInt64:
  264. lg %r4,80+112(%r11)
  265. stg %r2,0(%r8) # Return long
  266. lmg %r6,%r15,80+48(%r11)
  267. br %r4
  268. .Ltable:
  269. .byte .LretNone-.Lbase # FFI390_RET_VOID
  270. .byte .LretNone-.Lbase # FFI390_RET_STRUCT
  271. .byte .LretFloat-.Lbase # FFI390_RET_FLOAT
  272. .byte .LretDouble-.Lbase # FFI390_RET_DOUBLE
  273. .byte .LretInt32-.Lbase # FFI390_RET_INT32
  274. .byte .LretInt64-.Lbase # FFI390_RET_INT64
  275. .LFE1:
  276. .ffi_call_SYSV_end:
  277. .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
  278. .globl ffi_closure_SYSV
  279. .type ffi_closure_SYSV,%function
  280. ffi_closure_SYSV:
  281. .LFB2:
  282. stmg %r14,%r15,112(%r15) # Save registers
  283. .LCFI10:
  284. stmg %r2,%r6,16(%r15) # Save arguments
  285. std %f0,128(%r15)
  286. std %f2,136(%r15)
  287. std %f4,144(%r15)
  288. std %f6,152(%r15)
  289. lgr %r1,%r15 # Set up stack frame
  290. aghi %r15,-160
  291. .LCFI11:
  292. lgr %r2,%r0 # Closure
  293. la %r3,16(%r1) # GPRs
  294. la %r4,128(%r1) # FPRs
  295. la %r5,160(%r1) # Overflow
  296. stg %r1,0(%r15) # Set up back chain
  297. brasl %r14,ffi_closure_helper_SYSV # Call helper
  298. lg %r14,160+112(%r15)
  299. ld %f0,160+128(%r15) # Load return registers
  300. lg %r2,160+16(%r15)
  301. la %r15,160(%r15)
  302. br %r14
  303. .LFE2:
  304. .ffi_closure_SYSV_end:
  305. .size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
  306. .section .eh_frame,EH_FRAME_FLAGS,@progbits
  307. .Lframe1:
  308. .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
  309. .LSCIE1:
  310. .4byte 0x0 # CIE Identifier Tag
  311. .byte 0x1 # CIE Version
  312. .ascii "zR\0" # CIE Augmentation
  313. .uleb128 0x1 # CIE Code Alignment Factor
  314. .sleb128 -8 # CIE Data Alignment Factor
  315. .byte 0xe # CIE RA Column
  316. .uleb128 0x1 # Augmentation size
  317. .byte 0x1b # FDE Encoding (pcrel sdata4)
  318. .byte 0xc # DW_CFA_def_cfa
  319. .uleb128 0xf
  320. .uleb128 0xa0
  321. .align 8
  322. .LECIE1:
  323. .LSFDE1:
  324. .4byte .LEFDE1-.LASFDE1 # FDE Length
  325. .LASFDE1:
  326. .4byte .LASFDE1-.Lframe1 # FDE CIE offset
  327. .4byte .LFB1-. # FDE initial location
  328. .4byte .LFE1-.LFB1 # FDE address range
  329. .uleb128 0x0 # Augmentation size
  330. .byte 0x4 # DW_CFA_advance_loc4
  331. .4byte .LCFI0-.LFB1
  332. .byte 0x8f # DW_CFA_offset, column 0xf
  333. .uleb128 0x5
  334. .byte 0x8e # DW_CFA_offset, column 0xe
  335. .uleb128 0x6
  336. .byte 0x8d # DW_CFA_offset, column 0xd
  337. .uleb128 0x7
  338. .byte 0x8c # DW_CFA_offset, column 0xc
  339. .uleb128 0x8
  340. .byte 0x8b # DW_CFA_offset, column 0xb
  341. .uleb128 0x9
  342. .byte 0x8a # DW_CFA_offset, column 0xa
  343. .uleb128 0xa
  344. .byte 0x89 # DW_CFA_offset, column 0x9
  345. .uleb128 0xb
  346. .byte 0x88 # DW_CFA_offset, column 0x8
  347. .uleb128 0xc
  348. .byte 0x87 # DW_CFA_offset, column 0x7
  349. .uleb128 0xd
  350. .byte 0x86 # DW_CFA_offset, column 0x6
  351. .uleb128 0xe
  352. .byte 0x4 # DW_CFA_advance_loc4
  353. .4byte .LCFI1-.LCFI0
  354. .byte 0xd # DW_CFA_def_cfa_register
  355. .uleb128 0xb
  356. .byte 0x4 # DW_CFA_advance_loc4
  357. .4byte .LCFI2-.LCFI1
  358. .byte 0xe # DW_CFA_def_cfa_offset
  359. .uleb128 0xf0
  360. .align 8
  361. .LEFDE1:
  362. .LSFDE2:
  363. .4byte .LEFDE2-.LASFDE2 # FDE Length
  364. .LASFDE2:
  365. .4byte .LASFDE2-.Lframe1 # FDE CIE offset
  366. .4byte .LFB2-. # FDE initial location
  367. .4byte .LFE2-.LFB2 # FDE address range
  368. .uleb128 0x0 # Augmentation size
  369. .byte 0x4 # DW_CFA_advance_loc4
  370. .4byte .LCFI10-.LFB2
  371. .byte 0x8f # DW_CFA_offset, column 0xf
  372. .uleb128 0x5
  373. .byte 0x8e # DW_CFA_offset, column 0xe
  374. .uleb128 0x6
  375. .byte 0x4 # DW_CFA_advance_loc4
  376. .4byte .LCFI11-.LCFI10
  377. .byte 0xe # DW_CFA_def_cfa_offset
  378. .uleb128 0x140
  379. .align 8
  380. .LEFDE2:
  381. #endif
  382. #if defined __ELF__ && defined __linux__
  383. .section .note.GNU-stack,"",@progbits
  384. #endif