/Modules/_ctypes/libffi/src/powerpc/linux64.S

http://unladen-swallow.googlecode.com/ · Assembly · 187 lines · 134 code · 15 blank · 38 comment · 1 complexity · a7d09aad6ca2eb4358d7ad4bca4fdd7e MD5 · raw file

  1. /* -----------------------------------------------------------------------
  2. sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>
  3. Copyright (c) 2008 Red Hat, Inc.
  4. PowerPC64 Assembly glue.
  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. #ifdef __powerpc64__
  27. .hidden ffi_call_LINUX64, .ffi_call_LINUX64
  28. .globl ffi_call_LINUX64, .ffi_call_LINUX64
  29. .section ".opd","aw"
  30. .align 3
  31. ffi_call_LINUX64:
  32. .quad .ffi_call_LINUX64,.TOC.@tocbase,0
  33. .size ffi_call_LINUX64,24
  34. .type .ffi_call_LINUX64,@function
  35. .text
  36. .ffi_call_LINUX64:
  37. .LFB1:
  38. mflr %r0
  39. std %r28, -32(%r1)
  40. std %r29, -24(%r1)
  41. std %r30, -16(%r1)
  42. std %r31, -8(%r1)
  43. std %r0, 16(%r1)
  44. mr %r28, %r1 /* our AP. */
  45. .LCFI0:
  46. stdux %r1, %r1, %r4
  47. mr %r31, %r5 /* flags, */
  48. mr %r30, %r6 /* rvalue, */
  49. mr %r29, %r7 /* function address. */
  50. std %r2, 40(%r1)
  51. /* Call ffi_prep_args64. */
  52. mr %r4, %r1
  53. bl .ffi_prep_args64
  54. ld %r0, 0(%r29)
  55. ld %r2, 8(%r29)
  56. ld %r11, 16(%r29)
  57. /* Now do the call. */
  58. /* Set up cr1 with bits 4-7 of the flags. */
  59. mtcrf 0x40, %r31
  60. /* Get the address to call into CTR. */
  61. mtctr %r0
  62. /* Load all those argument registers. */
  63. ld %r3, -32-(8*8)(%r28)
  64. ld %r4, -32-(7*8)(%r28)
  65. ld %r5, -32-(6*8)(%r28)
  66. ld %r6, -32-(5*8)(%r28)
  67. bf- 5, 1f
  68. ld %r7, -32-(4*8)(%r28)
  69. ld %r8, -32-(3*8)(%r28)
  70. ld %r9, -32-(2*8)(%r28)
  71. ld %r10, -32-(1*8)(%r28)
  72. 1:
  73. /* Load all the FP registers. */
  74. bf- 6, 2f
  75. lfd %f1, -32-(21*8)(%r28)
  76. lfd %f2, -32-(20*8)(%r28)
  77. lfd %f3, -32-(19*8)(%r28)
  78. lfd %f4, -32-(18*8)(%r28)
  79. lfd %f5, -32-(17*8)(%r28)
  80. lfd %f6, -32-(16*8)(%r28)
  81. lfd %f7, -32-(15*8)(%r28)
  82. lfd %f8, -32-(14*8)(%r28)
  83. lfd %f9, -32-(13*8)(%r28)
  84. lfd %f10, -32-(12*8)(%r28)
  85. lfd %f11, -32-(11*8)(%r28)
  86. lfd %f12, -32-(10*8)(%r28)
  87. lfd %f13, -32-(9*8)(%r28)
  88. 2:
  89. /* Make the call. */
  90. bctrl
  91. /* This must follow the call immediately, the unwinder
  92. uses this to find out if r2 has been saved or not. */
  93. ld %r2, 40(%r1)
  94. /* Now, deal with the return value. */
  95. mtcrf 0x01, %r31
  96. bt- 30, .Ldone_return_value
  97. bt- 29, .Lfp_return_value
  98. std %r3, 0(%r30)
  99. /* Fall through... */
  100. .Ldone_return_value:
  101. /* Restore the registers we used and return. */
  102. mr %r1, %r28
  103. ld %r0, 16(%r28)
  104. ld %r28, -32(%r1)
  105. mtlr %r0
  106. ld %r29, -24(%r1)
  107. ld %r30, -16(%r1)
  108. ld %r31, -8(%r1)
  109. blr
  110. .Lfp_return_value:
  111. bf 28, .Lfloat_return_value
  112. stfd %f1, 0(%r30)
  113. mtcrf 0x02, %r31 /* cr6 */
  114. bf 27, .Ldone_return_value
  115. stfd %f2, 8(%r30)
  116. b .Ldone_return_value
  117. .Lfloat_return_value:
  118. stfs %f1, 0(%r30)
  119. b .Ldone_return_value
  120. .LFE1:
  121. .long 0
  122. .byte 0,12,0,1,128,4,0,0
  123. .size .ffi_call_LINUX64,.-.ffi_call_LINUX64
  124. .section .eh_frame,EH_FRAME_FLAGS,@progbits
  125. .Lframe1:
  126. .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
  127. .LSCIE1:
  128. .4byte 0x0 # CIE Identifier Tag
  129. .byte 0x1 # CIE Version
  130. .ascii "zR\0" # CIE Augmentation
  131. .uleb128 0x1 # CIE Code Alignment Factor
  132. .sleb128 -8 # CIE Data Alignment Factor
  133. .byte 0x41 # CIE RA Column
  134. .uleb128 0x1 # Augmentation size
  135. .byte 0x14 # FDE Encoding (pcrel udata8)
  136. .byte 0xc # DW_CFA_def_cfa
  137. .uleb128 0x1
  138. .uleb128 0x0
  139. .align 3
  140. .LECIE1:
  141. .LSFDE1:
  142. .4byte .LEFDE1-.LASFDE1 # FDE Length
  143. .LASFDE1:
  144. .4byte .LASFDE1-.Lframe1 # FDE CIE offset
  145. .8byte .LFB1-. # FDE initial location
  146. .8byte .LFE1-.LFB1 # FDE address range
  147. .uleb128 0x0 # Augmentation size
  148. .byte 0x2 # DW_CFA_advance_loc1
  149. .byte .LCFI0-.LFB1
  150. .byte 0xd # DW_CFA_def_cfa_register
  151. .uleb128 0x1c
  152. .byte 0x11 # DW_CFA_offset_extended_sf
  153. .uleb128 0x41
  154. .sleb128 -2
  155. .byte 0x9f # DW_CFA_offset, column 0x1f
  156. .uleb128 0x1
  157. .byte 0x9e # DW_CFA_offset, column 0x1e
  158. .uleb128 0x2
  159. .byte 0x9d # DW_CFA_offset, column 0x1d
  160. .uleb128 0x3
  161. .byte 0x9c # DW_CFA_offset, column 0x1c
  162. .uleb128 0x4
  163. .align 3
  164. .LEFDE1:
  165. #endif
  166. #if defined __ELF__ && defined __linux__
  167. .section .note.GNU-stack,"",@progbits
  168. #endif