| 1 | /* -----------------------------------------------------------------------
|
|---|
| 2 | v8.S - Copyright (c) 1996, 1997, 2003 Cygnus Solutions
|
|---|
| 3 |
|
|---|
| 4 | Sparc Foreign Function Interface
|
|---|
| 5 |
|
|---|
| 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 |
|
|---|
| 14 | The above copyright notice and this permission notice shall be included
|
|---|
| 15 | in all copies or substantial portions of the Software.
|
|---|
| 16 |
|
|---|
| 17 | THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|---|
| 18 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|---|
| 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|---|
| 20 | IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|---|
| 21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|---|
| 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|---|
| 23 | OTHER DEALINGS IN THE SOFTWARE.
|
|---|
| 24 | ----------------------------------------------------------------------- */
|
|---|
| 25 |
|
|---|
| 26 | #define LIBFFI_ASM
|
|---|
| 27 | #include <ffi.h>
|
|---|
| 28 |
|
|---|
| 29 | #define STACKFRAME 96 /* Minimum stack framesize for SPARC */
|
|---|
| 30 | #define ARGS (64+4) /* Offset of register area in frame */
|
|---|
| 31 |
|
|---|
| 32 | .text
|
|---|
| 33 | .align 8
|
|---|
| 34 | .globl ffi_call_V8
|
|---|
| 35 | .globl _ffi_call_V8
|
|---|
| 36 |
|
|---|
| 37 | ffi_call_V8:
|
|---|
| 38 | _ffi_call_V8:
|
|---|
| 39 | .LLFB1:
|
|---|
| 40 | save %sp, -STACKFRAME, %sp
|
|---|
| 41 | .LLCFI0:
|
|---|
| 42 |
|
|---|
| 43 | sub %sp, %i2, %sp ! alloca() space in stack for frame to set up
|
|---|
| 44 | add %sp, STACKFRAME, %l0 ! %l0 has start of
|
|---|
| 45 | ! frame to set up
|
|---|
| 46 |
|
|---|
| 47 | mov %l0, %o0 ! call routine to set up frame
|
|---|
| 48 | call %i0
|
|---|
| 49 | mov %i1, %o1 ! (delay)
|
|---|
| 50 |
|
|---|
| 51 | ld [%l0+ARGS], %o0 ! call foreign function
|
|---|
| 52 | ld [%l0+ARGS+4], %o1
|
|---|
| 53 | ld [%l0+ARGS+8], %o2
|
|---|
| 54 | ld [%l0+ARGS+12], %o3
|
|---|
| 55 | ld [%l0+ARGS+16], %o4
|
|---|
| 56 | ld [%l0+ARGS+20], %o5
|
|---|
| 57 | call %i5
|
|---|
| 58 | mov %l0, %sp ! (delay) switch to frame
|
|---|
| 59 | nop ! STRUCT returning functions skip 12 instead of 8 bytes
|
|---|
| 60 |
|
|---|
| 61 | ! If the return value pointer is NULL, assume no return value.
|
|---|
| 62 | tst %i4
|
|---|
| 63 | bz done
|
|---|
| 64 | nop
|
|---|
| 65 |
|
|---|
| 66 | cmp %i3, FFI_TYPE_INT
|
|---|
| 67 | be,a done
|
|---|
| 68 | st %o0, [%i4] ! (delay)
|
|---|
| 69 |
|
|---|
| 70 | cmp %i3, FFI_TYPE_FLOAT
|
|---|
| 71 | be,a done
|
|---|
| 72 | st %f0, [%i4+0] ! (delay)
|
|---|
| 73 |
|
|---|
| 74 | cmp %i3, FFI_TYPE_SINT64
|
|---|
| 75 | be longlong
|
|---|
| 76 |
|
|---|
| 77 | cmp %i3, FFI_TYPE_DOUBLE
|
|---|
| 78 | bne done
|
|---|
| 79 | nop
|
|---|
| 80 | st %f0, [%i4+0]
|
|---|
| 81 | st %f1, [%i4+4]
|
|---|
| 82 |
|
|---|
| 83 | done:
|
|---|
| 84 | ret
|
|---|
| 85 | restore
|
|---|
| 86 |
|
|---|
| 87 | longlong:
|
|---|
| 88 | st %o0, [%i4+0]
|
|---|
| 89 | st %o1, [%i4+4]
|
|---|
| 90 | ret
|
|---|
| 91 | restore
|
|---|
| 92 | .LLFE1:
|
|---|
| 93 |
|
|---|
| 94 | .ffi_call_V8_end:
|
|---|
| 95 | .size ffi_call_V8,.ffi_call_V8_end-ffi_call_V8
|
|---|
| 96 |
|
|---|
| 97 |
|
|---|
| 98 | #define STACKFRAME 104 /* 16*4 register window +
|
|---|
| 99 | 1*4 struct return +
|
|---|
| 100 | 6*4 args backing store +
|
|---|
| 101 | 3*4 locals */
|
|---|
| 102 |
|
|---|
| 103 | /* ffi_closure_v8(...)
|
|---|
| 104 |
|
|---|
| 105 | Receives the closure argument in %g2. */
|
|---|
| 106 |
|
|---|
| 107 | .text
|
|---|
| 108 | .align 8
|
|---|
| 109 | .globl ffi_closure_v8
|
|---|
| 110 |
|
|---|
| 111 | ffi_closure_v8:
|
|---|
| 112 | #ifdef HAVE_AS_REGISTER_PSEUDO_OP
|
|---|
| 113 | .register %g2, #scratch
|
|---|
| 114 | #endif
|
|---|
| 115 | .LLFB2:
|
|---|
| 116 | save %sp, -STACKFRAME, %sp
|
|---|
| 117 | .LLCFI1:
|
|---|
| 118 |
|
|---|
| 119 | ! Store all of the potential argument registers in va_list format.
|
|---|
| 120 | st %i0, [%fp+68+0]
|
|---|
| 121 | st %i1, [%fp+68+4]
|
|---|
| 122 | st %i2, [%fp+68+8]
|
|---|
| 123 | st %i3, [%fp+68+12]
|
|---|
| 124 | st %i4, [%fp+68+16]
|
|---|
| 125 | st %i5, [%fp+68+20]
|
|---|
| 126 |
|
|---|
| 127 | ! Call ffi_closure_sparc_inner to do the bulk of the work.
|
|---|
| 128 | mov %g2, %o0
|
|---|
| 129 | add %fp, -8, %o1
|
|---|
| 130 | add %fp, 68, %o2
|
|---|
| 131 | call ffi_closure_sparc_inner
|
|---|
| 132 | mov 0, %o3
|
|---|
| 133 |
|
|---|
| 134 | ! Load up the return value in the proper type.
|
|---|
| 135 | cmp %o0, FFI_TYPE_VOID
|
|---|
| 136 | be done1
|
|---|
| 137 |
|
|---|
| 138 | cmp %o0, FFI_TYPE_FLOAT
|
|---|
| 139 | be,a done1
|
|---|
| 140 | ld [%fp-8], %f0
|
|---|
| 141 |
|
|---|
| 142 | cmp %o0, FFI_TYPE_DOUBLE
|
|---|
| 143 | be,a done1
|
|---|
| 144 | ldd [%fp-8], %f0
|
|---|
| 145 |
|
|---|
| 146 | cmp %o0, FFI_TYPE_SINT64
|
|---|
| 147 | be,a integer
|
|---|
| 148 | ld [%fp-4], %i1
|
|---|
| 149 |
|
|---|
| 150 | cmp %o0, FFI_TYPE_UINT64
|
|---|
| 151 | be,a integer
|
|---|
| 152 | ld [%fp-4], %i1
|
|---|
| 153 |
|
|---|
| 154 | integer:
|
|---|
| 155 | ld [%fp-8], %i0
|
|---|
| 156 |
|
|---|
| 157 | done1:
|
|---|
| 158 | ret
|
|---|
| 159 | restore
|
|---|
| 160 | .LLFE2:
|
|---|
| 161 |
|
|---|
| 162 | .ffi_closure_v8_end:
|
|---|
| 163 | .size ffi_closure_v8,.ffi_closure_v8_end-ffi_closure_v8
|
|---|
| 164 |
|
|---|
| 165 | #ifdef SPARC64
|
|---|
| 166 | #define WS 8
|
|---|
| 167 | #define nword xword
|
|---|
| 168 | #define uanword uaxword
|
|---|
| 169 | #else
|
|---|
| 170 | #define WS 4
|
|---|
| 171 | #define nword long
|
|---|
| 172 | #define uanword uaword
|
|---|
| 173 | #endif
|
|---|
| 174 |
|
|---|
| 175 | .section ".eh_frame",#alloc,#write
|
|---|
| 176 | .LLframe1:
|
|---|
| 177 | .uaword .LLECIE1-.LLSCIE1 ! Length of Common Information Entry
|
|---|
| 178 | .LLSCIE1:
|
|---|
| 179 | .uaword 0x0 ! CIE Identifier Tag
|
|---|
| 180 | .byte 0x1 ! CIE Version
|
|---|
| 181 | .ascii "zR\0" ! CIE Augmentation
|
|---|
| 182 | .byte 0x1 ! uleb128 0x1; CIE Code Alignment Factor
|
|---|
| 183 | .byte 0x80-WS ! sleb128 -WS; CIE Data Alignment Factor
|
|---|
| 184 | .byte 0xf ! CIE RA Column
|
|---|
| 185 | .byte 0x1 ! uleb128 0x1; Augmentation size
|
|---|
| 186 | #ifdef HAVE_AS_SPARC_UA_PCREL
|
|---|
| 187 | .byte 0x1b ! FDE Encoding (pcrel sdata4)
|
|---|
| 188 | #else
|
|---|
| 189 | .byte 0x50 ! FDE Encoding (aligned absolute)
|
|---|
| 190 | #endif
|
|---|
| 191 | .byte 0xc ! DW_CFA_def_cfa
|
|---|
| 192 | .byte 0xe ! uleb128 0xe
|
|---|
| 193 | .byte 0x0 ! uleb128 0x0
|
|---|
| 194 | .align WS
|
|---|
| 195 | .LLECIE1:
|
|---|
| 196 | .LLSFDE1:
|
|---|
| 197 | .uaword .LLEFDE1-.LLASFDE1 ! FDE Length
|
|---|
| 198 | .LLASFDE1:
|
|---|
| 199 | .uaword .LLASFDE1-.LLframe1 ! FDE CIE offset
|
|---|
| 200 | #ifdef HAVE_AS_SPARC_UA_PCREL
|
|---|
| 201 | .uaword %r_disp32(.LLFB1)
|
|---|
| 202 | .uaword .LLFE1-.LLFB1 ! FDE address range
|
|---|
| 203 | #else
|
|---|
| 204 | .align WS
|
|---|
| 205 | .nword .LLFB1
|
|---|
| 206 | .uanword .LLFE1-.LLFB1 ! FDE address range
|
|---|
| 207 | #endif
|
|---|
| 208 | .byte 0x0 ! uleb128 0x0; Augmentation size
|
|---|
| 209 | .byte 0x4 ! DW_CFA_advance_loc4
|
|---|
| 210 | .uaword .LLCFI0-.LLFB1
|
|---|
| 211 | .byte 0xd ! DW_CFA_def_cfa_register
|
|---|
| 212 | .byte 0x1e ! uleb128 0x1e
|
|---|
| 213 | .byte 0x2d ! DW_CFA_GNU_window_save
|
|---|
| 214 | .byte 0x9 ! DW_CFA_register
|
|---|
| 215 | .byte 0xf ! uleb128 0xf
|
|---|
| 216 | .byte 0x1f ! uleb128 0x1f
|
|---|
| 217 | .align WS
|
|---|
| 218 | .LLEFDE1:
|
|---|
| 219 | .LLSFDE2:
|
|---|
| 220 | .uaword .LLEFDE2-.LLASFDE2 ! FDE Length
|
|---|
| 221 | .LLASFDE2:
|
|---|
| 222 | .uaword .LLASFDE2-.LLframe1 ! FDE CIE offset
|
|---|
| 223 | #ifdef HAVE_AS_SPARC_UA_PCREL
|
|---|
| 224 | .uaword %r_disp32(.LLFB2)
|
|---|
| 225 | .uaword .LLFE2-.LLFB2 ! FDE address range
|
|---|
| 226 | #else
|
|---|
| 227 | .align WS
|
|---|
| 228 | .nword .LLFB2
|
|---|
| 229 | .uanword .LLFE2-.LLFB2 ! FDE address range
|
|---|
| 230 | #endif
|
|---|
| 231 | .byte 0x0 ! uleb128 0x0; Augmentation size
|
|---|
| 232 | .byte 0x4 ! DW_CFA_advance_loc4
|
|---|
| 233 | .uaword .LLCFI1-.LLFB2
|
|---|
| 234 | .byte 0xd ! DW_CFA_def_cfa_register
|
|---|
| 235 | .byte 0x1e ! uleb128 0x1e
|
|---|
| 236 | .byte 0x2d ! DW_CFA_GNU_window_save
|
|---|
| 237 | .byte 0x9 ! DW_CFA_register
|
|---|
| 238 | .byte 0xf ! uleb128 0xf
|
|---|
| 239 | .byte 0x1f ! uleb128 0x1f
|
|---|
| 240 | .align WS
|
|---|
| 241 | .LLEFDE2:
|
|---|