/Modules/_ctypes/libffi/src/pa/hpux32.S

http://unladen-swallow.googlecode.com/ · Assembly · 368 lines · 249 code · 43 blank · 76 comment · 0 complexity · f3279dc3ee2648b08c274f2457d17660 MD5 · raw file

  1. /* -----------------------------------------------------------------------
  2. hpux32.S - Copyright (c) 2006 Free Software Foundation, Inc.
  3. (c) 2008 Red Hat, Inc.
  4. based on src/pa/linux.S
  5. HP-UX PA Foreign Function Interface
  6. Permission is hereby granted, free of charge, to any person obtaining
  7. a copy of this software and associated documentation files (the
  8. ``Software''), to deal in the Software without restriction, including
  9. without limitation the rights to use, copy, modify, merge, publish,
  10. distribute, sublicense, and/or sell copies of the Software, and to
  11. permit persons to whom the Software is furnished to do so, subject to
  12. the following conditions:
  13. The above copyright notice and this permission notice shall be included
  14. in all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
  16. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  18. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19. OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20. ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21. OTHER DEALINGS IN THE SOFTWARE.
  22. ----------------------------------------------------------------------- */
  23. #define LIBFFI_ASM
  24. #include <fficonfig.h>
  25. #include <ffi.h>
  26. .LEVEL 1.1
  27. .SPACE $PRIVATE$
  28. .IMPORT $global$,DATA
  29. .IMPORT $$dyncall,MILLICODE
  30. .SUBSPA $DATA$
  31. .align 4
  32. /* void ffi_call_pa32(void (*)(char *, extended_cif *),
  33. extended_cif *ecif,
  34. unsigned bytes,
  35. unsigned flags,
  36. unsigned *rvalue,
  37. void (*fn)(void));
  38. */
  39. .export ffi_call_pa32,ENTRY,PRIV_LEV=3
  40. .import ffi_prep_args_pa32,CODE
  41. .SPACE $TEXT$
  42. .SUBSPA $CODE$
  43. .align 4
  44. L$FB1
  45. ffi_call_pa32
  46. .proc
  47. .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4
  48. .entry
  49. stw %rp, -20(%sp)
  50. copy %r3, %r1
  51. L$CFI11
  52. copy %sp, %r3
  53. L$CFI12
  54. /* Setup the stack for calling prep_args...
  55. We want the stack to look like this:
  56. [ Previous stack ] <- %r3
  57. [ 64-bytes register save area ] <- %r4
  58. [ Stack space for actual call, passed as ] <- %arg0
  59. [ arg0 to ffi_prep_args_pa32 ]
  60. [ Stack for calling prep_args ] <- %sp
  61. */
  62. stwm %r1, 64(%sp)
  63. stw %r4, 12(%r3)
  64. L$CFI13
  65. copy %sp, %r4
  66. addl %arg2, %r4, %arg0 ; arg stack
  67. stw %arg3, -48(%r3) ; save flags we need it later
  68. /* Call prep_args:
  69. %arg0(stack) -- set up above
  70. %arg1(ecif) -- same as incoming param
  71. %arg2(bytes) -- same as incoming param */
  72. bl ffi_prep_args_pa32,%r2
  73. ldo 64(%arg0), %sp
  74. ldo -64(%sp), %sp
  75. /* now %sp should point where %arg0 was pointing. */
  76. /* Load the arguments that should be passed in registers
  77. The fp args are loaded by the prep_args function. */
  78. ldw -36(%sp), %arg0
  79. ldw -40(%sp), %arg1
  80. ldw -44(%sp), %arg2
  81. ldw -48(%sp), %arg3
  82. /* in case the function is going to return a structure
  83. we need to give it a place to put the result. */
  84. ldw -52(%r3), %ret0 ; %ret0 <- rvalue
  85. ldw -56(%r3), %r22 ; %r22 <- function to call
  86. bl $$dyncall, %r31 ; Call the user function
  87. copy %r31, %rp
  88. /* Prepare to store the result; we need to recover flags and rvalue. */
  89. ldw -48(%r3), %r21 ; r21 <- flags
  90. ldw -52(%r3), %r20 ; r20 <- rvalue
  91. /* Store the result according to the return type. The most
  92. likely types should come first. */
  93. L$checkint
  94. comib,<>,n FFI_TYPE_INT, %r21, L$checkint8
  95. b L$done
  96. stw %ret0, 0(%r20)
  97. L$checkint8
  98. comib,<>,n FFI_TYPE_UINT8, %r21, L$checkint16
  99. b L$done
  100. stb %ret0, 0(%r20)
  101. L$checkint16
  102. comib,<>,n FFI_TYPE_UINT16, %r21, L$checkdbl
  103. b L$done
  104. sth %ret0, 0(%r20)
  105. L$checkdbl
  106. comib,<>,n FFI_TYPE_DOUBLE, %r21, L$checkfloat
  107. b L$done
  108. fstd %fr4,0(%r20)
  109. L$checkfloat
  110. comib,<>,n FFI_TYPE_FLOAT, %r21, L$checkll
  111. b L$done
  112. fstw %fr4L,0(%r20)
  113. L$checkll
  114. comib,<>,n FFI_TYPE_UINT64, %r21, L$checksmst2
  115. stw %ret0, 0(%r20)
  116. b L$done
  117. stw %ret1, 4(%r20)
  118. L$checksmst2
  119. comib,<>,n FFI_TYPE_SMALL_STRUCT2, %r21, L$checksmst3
  120. /* 2-byte structs are returned in ret0 as ????xxyy. */
  121. extru %ret0, 23, 8, %r22
  122. stbs,ma %r22, 1(%r20)
  123. b L$done
  124. stb %ret0, 0(%r20)
  125. L$checksmst3
  126. comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, L$checksmst4
  127. /* 3-byte structs are returned in ret0 as ??xxyyzz. */
  128. extru %ret0, 15, 8, %r22
  129. stbs,ma %r22, 1(%r20)
  130. extru %ret0, 23, 8, %r22
  131. stbs,ma %r22, 1(%r20)
  132. b L$done
  133. stb %ret0, 0(%r20)
  134. L$checksmst4
  135. comib,<>,n FFI_TYPE_SMALL_STRUCT4, %r21, L$checksmst5
  136. /* 4-byte structs are returned in ret0 as wwxxyyzz. */
  137. extru %ret0, 7, 8, %r22
  138. stbs,ma %r22, 1(%r20)
  139. extru %ret0, 15, 8, %r22
  140. stbs,ma %r22, 1(%r20)
  141. extru %ret0, 23, 8, %r22
  142. stbs,ma %r22, 1(%r20)
  143. b L$done
  144. stb %ret0, 0(%r20)
  145. L$checksmst5
  146. comib,<>,n FFI_TYPE_SMALL_STRUCT5, %r21, L$checksmst6
  147. /* 5 byte values are returned right justified:
  148. ret0 ret1
  149. 5: ??????aa bbccddee */
  150. stbs,ma %ret0, 1(%r20)
  151. extru %ret1, 7, 8, %r22
  152. stbs,ma %r22, 1(%r20)
  153. extru %ret1, 15, 8, %r22
  154. stbs,ma %r22, 1(%r20)
  155. extru %ret1, 23, 8, %r22
  156. stbs,ma %r22, 1(%r20)
  157. b L$done
  158. stb %ret1, 0(%r20)
  159. L$checksmst6
  160. comib,<>,n FFI_TYPE_SMALL_STRUCT6, %r21, L$checksmst7
  161. /* 6 byte values are returned right justified:
  162. ret0 ret1
  163. 6: ????aabb ccddeeff */
  164. extru %ret0, 23, 8, %r22
  165. stbs,ma %r22, 1(%r20)
  166. stbs,ma %ret0, 1(%r20)
  167. extru %ret1, 7, 8, %r22
  168. stbs,ma %r22, 1(%r20)
  169. extru %ret1, 15, 8, %r22
  170. stbs,ma %r22, 1(%r20)
  171. extru %ret1, 23, 8, %r22
  172. stbs,ma %r22, 1(%r20)
  173. b L$done
  174. stb %ret1, 0(%r20)
  175. L$checksmst7
  176. comib,<>,n FFI_TYPE_SMALL_STRUCT7, %r21, L$checksmst8
  177. /* 7 byte values are returned right justified:
  178. ret0 ret1
  179. 7: ??aabbcc ddeeffgg */
  180. extru %ret0, 15, 8, %r22
  181. stbs,ma %r22, 1(%r20)
  182. extru %ret0, 23, 8, %r22
  183. stbs,ma %r22, 1(%r20)
  184. stbs,ma %ret0, 1(%r20)
  185. extru %ret1, 7, 8, %r22
  186. stbs,ma %r22, 1(%r20)
  187. extru %ret1, 15, 8, %r22
  188. stbs,ma %r22, 1(%r20)
  189. extru %ret1, 23, 8, %r22
  190. stbs,ma %r22, 1(%r20)
  191. b L$done
  192. stb %ret1, 0(%r20)
  193. L$checksmst8
  194. comib,<>,n FFI_TYPE_SMALL_STRUCT8, %r21, L$done
  195. /* 8 byte values are returned right justified:
  196. ret0 ret1
  197. 8: aabbccdd eeffgghh */
  198. extru %ret0, 7, 8, %r22
  199. stbs,ma %r22, 1(%r20)
  200. extru %ret0, 15, 8, %r22
  201. stbs,ma %r22, 1(%r20)
  202. extru %ret0, 23, 8, %r22
  203. stbs,ma %r22, 1(%r20)
  204. stbs,ma %ret0, 1(%r20)
  205. extru %ret1, 7, 8, %r22
  206. stbs,ma %r22, 1(%r20)
  207. extru %ret1, 15, 8, %r22
  208. stbs,ma %r22, 1(%r20)
  209. extru %ret1, 23, 8, %r22
  210. stbs,ma %r22, 1(%r20)
  211. stb %ret1, 0(%r20)
  212. L$done
  213. /* all done, return */
  214. copy %r4, %sp ; pop arg stack
  215. ldw 12(%r3), %r4
  216. ldwm -64(%sp), %r3 ; .. and pop stack
  217. ldw -20(%sp), %rp
  218. bv %r0(%rp)
  219. nop
  220. .exit
  221. .procend
  222. L$FE1
  223. /* void ffi_closure_pa32(void);
  224. Called with closure argument in %r21 */
  225. .SPACE $TEXT$
  226. .SUBSPA $CODE$
  227. .export ffi_closure_pa32,ENTRY,PRIV_LEV=3,RTNVAL=GR
  228. .import ffi_closure_inner_pa32,CODE
  229. .align 4
  230. L$FB2
  231. ffi_closure_pa32
  232. .proc
  233. .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
  234. .entry
  235. stw %rp, -20(%sp)
  236. copy %r3, %r1
  237. L$CFI21
  238. copy %sp, %r3
  239. L$CFI22
  240. stwm %r1, 64(%sp)
  241. /* Put arguments onto the stack and call ffi_closure_inner. */
  242. stw %arg0, -36(%r3)
  243. stw %arg1, -40(%r3)
  244. stw %arg2, -44(%r3)
  245. stw %arg3, -48(%r3)
  246. copy %r21, %arg0
  247. bl ffi_closure_inner_pa32, %r2
  248. copy %r3, %arg1
  249. ldwm -64(%sp), %r3
  250. ldw -20(%sp), %rp
  251. ldw -36(%sp), %ret0
  252. bv %r0(%rp)
  253. ldw -40(%sp), %ret1
  254. .exit
  255. .procend
  256. L$FE2:
  257. .SPACE $PRIVATE$
  258. .SUBSPA $DATA$
  259. .align 4
  260. .EXPORT _GLOBAL__F_ffi_call_pa32,DATA
  261. _GLOBAL__F_ffi_call_pa32
  262. L$frame1:
  263. .word L$ECIE1-L$SCIE1 ;# Length of Common Information Entry
  264. L$SCIE1:
  265. .word 0x0 ;# CIE Identifier Tag
  266. .byte 0x1 ;# CIE Version
  267. .ascii "\0" ;# CIE Augmentation
  268. .uleb128 0x1 ;# CIE Code Alignment Factor
  269. .sleb128 4 ;# CIE Data Alignment Factor
  270. .byte 0x2 ;# CIE RA Column
  271. .byte 0xc ;# DW_CFA_def_cfa
  272. .uleb128 0x1e
  273. .uleb128 0x0
  274. .align 4
  275. L$ECIE1:
  276. L$SFDE1:
  277. .word L$EFDE1-L$ASFDE1 ;# FDE Length
  278. L$ASFDE1:
  279. .word L$ASFDE1-L$frame1 ;# FDE CIE offset
  280. .word L$FB1 ;# FDE initial location
  281. .word L$FE1-L$FB1 ;# FDE address range
  282. .byte 0x4 ;# DW_CFA_advance_loc4
  283. .word L$CFI11-L$FB1
  284. .byte 0x83 ;# DW_CFA_offset, column 0x3
  285. .uleb128 0x0
  286. .byte 0x11 ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]
  287. .uleb128 0x2
  288. .sleb128 -5
  289. .byte 0x4 ;# DW_CFA_advance_loc4
  290. .word L$CFI12-L$CFI11
  291. .byte 0xd ;# DW_CFA_def_cfa_register = r3
  292. .uleb128 0x3
  293. .byte 0x4 ;# DW_CFA_advance_loc4
  294. .word L$CFI13-L$CFI12
  295. .byte 0x84 ;# DW_CFA_offset, column 0x4
  296. .uleb128 0x3
  297. .align 4
  298. L$EFDE1:
  299. L$SFDE2:
  300. .word L$EFDE2-L$ASFDE2 ;# FDE Length
  301. L$ASFDE2:
  302. .word L$ASFDE2-L$frame1 ;# FDE CIE offset
  303. .word L$FB2 ;# FDE initial location
  304. .word L$FE2-L$FB2 ;# FDE address range
  305. .byte 0x4 ;# DW_CFA_advance_loc4
  306. .word L$CFI21-L$FB2
  307. .byte 0x83 ;# DW_CFA_offset, column 0x3
  308. .uleb128 0x0
  309. .byte 0x11 ;# DW_CFA_offset_extended_sf
  310. .uleb128 0x2
  311. .sleb128 -5
  312. .byte 0x4 ;# DW_CFA_advance_loc4
  313. .word L$CFI22-L$CFI21
  314. .byte 0xd ;# DW_CFA_def_cfa_register = r3
  315. .uleb128 0x3
  316. .align 4
  317. L$EFDE2: