1/* ----------------------------------------------------------------------- 2 sysv.S - Copyright (c) 2000 Software AG 3 4 S390 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 <fficonfig.h> 28#include <ffi.h> 29 30#ifndef __s390x__ 31 32.text 33 34 # r2: cif->bytes 35 # r3: &ecif 36 # r4: ffi_prep_args 37 # r5: ret_type 38 # r6: ecif.rvalue 39 # ov: fn 40 41 # This assumes we are using gas. 42 .globl ffi_call_SYSV 43 .type ffi_call_SYSV,%function 44ffi_call_SYSV: 45.LFB1: 46 stm %r6,%r15,24(%r15) # Save registers 47.LCFI0: 48 basr %r13,0 # Set up base register 49.Lbase: 50 lr %r11,%r15 # Set up frame pointer 51.LCFI1: 52 sr %r15,%r2 53 ahi %r15,-96-48 # Allocate stack 54 lr %r8,%r6 # Save ecif.rvalue 55 sr %r9,%r9 56 ic %r9,.Ltable-.Lbase(%r13,%r5) # Load epilog address 57 l %r7,96(%r11) # Load function address 58 st %r11,0(%r15) # Set up back chain 59 ahi %r11,-48 # Register save area 60.LCFI2: 61 62 la %r2,96(%r15) # Save area 63 # r3 already holds &ecif 64 basr %r14,%r4 # Call ffi_prep_args 65 66 lm %r2,%r6,0(%r11) # Load arguments 67 ld %f0,32(%r11) 68 ld %f2,40(%r11) 69 la %r14,0(%r13,%r9) # Set return address 70 br %r7 # ... and call function 71 72.LretNone: # Return void 73 l %r4,48+56(%r11) 74 lm %r6,%r15,48+24(%r11) 75 br %r4 76 77.LretFloat: 78 l %r4,48+56(%r11) 79 ste %f0,0(%r8) # Return float 80 lm %r6,%r15,48+24(%r11) 81 br %r4 82 83.LretDouble: 84 l %r4,48+56(%r11) 85 std %f0,0(%r8) # Return double 86 lm %r6,%r15,48+24(%r11) 87 br %r4 88 89.LretInt32: 90 l %r4,48+56(%r11) 91 st %r2,0(%r8) # Return int 92 lm %r6,%r15,48+24(%r11) 93 br %r4 94 95.LretInt64: 96 l %r4,48+56(%r11) 97 stm %r2,%r3,0(%r8) # Return long long 98 lm %r6,%r15,48+24(%r11) 99 br %r4 100 101.Ltable: 102 .byte .LretNone-.Lbase # FFI390_RET_VOID 103 .byte .LretNone-.Lbase # FFI390_RET_STRUCT 104 .byte .LretFloat-.Lbase # FFI390_RET_FLOAT 105 .byte .LretDouble-.Lbase # FFI390_RET_DOUBLE 106 .byte .LretInt32-.Lbase # FFI390_RET_INT32 107 .byte .LretInt64-.Lbase # FFI390_RET_INT64 108 109.LFE1: 110.ffi_call_SYSV_end: 111 .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV 112 113 114 .globl ffi_closure_SYSV 115 .type ffi_closure_SYSV,%function 116ffi_closure_SYSV: 117.LFB2: 118 stm %r12,%r15,48(%r15) # Save registers 119.LCFI10: 120 basr %r13,0 # Set up base register 121.Lcbase: 122 stm %r2,%r6,8(%r15) # Save arguments 123 std %f0,64(%r15) 124 std %f2,72(%r15) 125 lr %r1,%r15 # Set up stack frame 126 ahi %r15,-96 127.LCFI11: 128 l %r12,.Lchelper-.Lcbase(%r13) # Get helper function 129 lr %r2,%r0 # Closure 130 la %r3,8(%r1) # GPRs 131 la %r4,64(%r1) # FPRs 132 la %r5,96(%r1) # Overflow 133 st %r1,0(%r15) # Set up back chain 134 135 bas %r14,0(%r12,%r13) # Call helper 136 137 l %r4,96+56(%r15) 138 ld %f0,96+64(%r15) # Load return registers 139 lm %r2,%r3,96+8(%r15) 140 lm %r12,%r15,96+48(%r15) 141 br %r4 142 143 .align 4 144.Lchelper: 145 .long ffi_closure_helper_SYSV-.Lcbase 146 147.LFE2: 148 149.ffi_closure_SYSV_end: 150 .size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV 151 152 153 .section .eh_frame,EH_FRAME_FLAGS,@progbits 154.Lframe1: 155 .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry 156.LSCIE1: 157 .4byte 0x0 # CIE Identifier Tag 158 .byte 0x1 # CIE Version 159 .ascii "zR\0" # CIE Augmentation 160 .uleb128 0x1 # CIE Code Alignment Factor 161 .sleb128 -4 # CIE Data Alignment Factor 162 .byte 0xe # CIE RA Column 163 .uleb128 0x1 # Augmentation size 164 .byte 0x1b # FDE Encoding (pcrel sdata4) 165 .byte 0xc # DW_CFA_def_cfa 166 .uleb128 0xf 167 .uleb128 0x60 168 .align 4 169.LECIE1: 170.LSFDE1: 171 .4byte .LEFDE1-.LASFDE1 # FDE Length 172.LASFDE1: 173 .4byte .LASFDE1-.Lframe1 # FDE CIE offset 174 .4byte .LFB1-. # FDE initial location 175 .4byte .LFE1-.LFB1 # FDE address range 176 .uleb128 0x0 # Augmentation size 177 .byte 0x4 # DW_CFA_advance_loc4 178 .4byte .LCFI0-.LFB1 179 .byte 0x8f # DW_CFA_offset, column 0xf 180 .uleb128 0x9 181 .byte 0x8e # DW_CFA_offset, column 0xe 182 .uleb128 0xa 183 .byte 0x8d # DW_CFA_offset, column 0xd 184 .uleb128 0xb 185 .byte 0x8c # DW_CFA_offset, column 0xc 186 .uleb128 0xc 187 .byte 0x8b # DW_CFA_offset, column 0xb 188 .uleb128 0xd 189 .byte 0x8a # DW_CFA_offset, column 0xa 190 .uleb128 0xe 191 .byte 0x89 # DW_CFA_offset, column 0x9 192 .uleb128 0xf 193 .byte 0x88 # DW_CFA_offset, column 0x8 194 .uleb128 0x10 195 .byte 0x87 # DW_CFA_offset, column 0x7 196 .uleb128 0x11 197 .byte 0x86 # DW_CFA_offset, column 0x6 198 .uleb128 0x12 199 .byte 0x4 # DW_CFA_advance_loc4 200 .4byte .LCFI1-.LCFI0 201 .byte 0xd # DW_CFA_def_cfa_register 202 .uleb128 0xb 203 .byte 0x4 # DW_CFA_advance_loc4 204 .4byte .LCFI2-.LCFI1 205 .byte 0xe # DW_CFA_def_cfa_offset 206 .uleb128 0x90 207 .align 4 208.LEFDE1: 209.LSFDE2: 210 .4byte .LEFDE2-.LASFDE2 # FDE Length 211.LASFDE2: 212 .4byte .LASFDE2-.Lframe1 # FDE CIE offset 213 .4byte .LFB2-. # FDE initial location 214 .4byte .LFE2-.LFB2 # FDE address range 215 .uleb128 0x0 # Augmentation size 216 .byte 0x4 # DW_CFA_advance_loc4 217 .4byte .LCFI10-.LFB2 218 .byte 0x8f # DW_CFA_offset, column 0xf 219 .uleb128 0x9 220 .byte 0x8e # DW_CFA_offset, column 0xe 221 .uleb128 0xa 222 .byte 0x8d # DW_CFA_offset, column 0xd 223 .uleb128 0xb 224 .byte 0x8c # DW_CFA_offset, column 0xc 225 .uleb128 0xc 226 .byte 0x4 # DW_CFA_advance_loc4 227 .4byte .LCFI11-.LCFI10 228 .byte 0xe # DW_CFA_def_cfa_offset 229 .uleb128 0xc0 230 .align 4 231.LEFDE2: 232 233#else 234 235.text 236 237 # r2: cif->bytes 238 # r3: &ecif 239 # r4: ffi_prep_args 240 # r5: ret_type 241 # r6: ecif.rvalue 242 # ov: fn 243 244 # This assumes we are using gas. 245 .globl ffi_call_SYSV 246 .type ffi_call_SYSV,%function 247ffi_call_SYSV: 248.LFB1: 249 stmg %r6,%r15,48(%r15) # Save registers 250.LCFI0: 251 larl %r13,.Lbase # Set up base register 252 lgr %r11,%r15 # Set up frame pointer 253.LCFI1: 254 sgr %r15,%r2 255 aghi %r15,-160-80 # Allocate stack 256 lgr %r8,%r6 # Save ecif.rvalue 257 llgc %r9,.Ltable-.Lbase(%r13,%r5) # Load epilog address 258 lg %r7,160(%r11) # Load function address 259 stg %r11,0(%r15) # Set up back chain 260 aghi %r11,-80 # Register save area 261.LCFI2: 262 263 la %r2,160(%r15) # Save area 264 # r3 already holds &ecif 265 basr %r14,%r4 # Call ffi_prep_args 266 267 lmg %r2,%r6,0(%r11) # Load arguments 268 ld %f0,48(%r11) 269 ld %f2,56(%r11) 270 ld %f4,64(%r11) 271 ld %f6,72(%r11) 272 la %r14,0(%r13,%r9) # Set return address 273 br %r7 # ... and call function 274 275.Lbase: 276.LretNone: # Return void 277 lg %r4,80+112(%r11) 278 lmg %r6,%r15,80+48(%r11) 279 br %r4 280 281.LretFloat: 282 lg %r4,80+112(%r11) 283 ste %f0,0(%r8) # Return float 284 lmg %r6,%r15,80+48(%r11) 285 br %r4 286 287.LretDouble: 288 lg %r4,80+112(%r11) 289 std %f0,0(%r8) # Return double 290 lmg %r6,%r15,80+48(%r11) 291 br %r4 292 293.LretInt32: 294 lg %r4,80+112(%r11) 295 st %r2,0(%r8) # Return int 296 lmg %r6,%r15,80+48(%r11) 297 br %r4 298 299.LretInt64: 300 lg %r4,80+112(%r11) 301 stg %r2,0(%r8) # Return long 302 lmg %r6,%r15,80+48(%r11) 303 br %r4 304 305.Ltable: 306 .byte .LretNone-.Lbase # FFI390_RET_VOID 307 .byte .LretNone-.Lbase # FFI390_RET_STRUCT 308 .byte .LretFloat-.Lbase # FFI390_RET_FLOAT 309 .byte .LretDouble-.Lbase # FFI390_RET_DOUBLE 310 .byte .LretInt32-.Lbase # FFI390_RET_INT32 311 .byte .LretInt64-.Lbase # FFI390_RET_INT64 312 313.LFE1: 314.ffi_call_SYSV_end: 315 .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV 316 317 318 .globl ffi_closure_SYSV 319 .type ffi_closure_SYSV,%function 320ffi_closure_SYSV: 321.LFB2: 322 stmg %r14,%r15,112(%r15) # Save registers 323.LCFI10: 324 stmg %r2,%r6,16(%r15) # Save arguments 325 std %f0,128(%r15) 326 std %f2,136(%r15) 327 std %f4,144(%r15) 328 std %f6,152(%r15) 329 lgr %r1,%r15 # Set up stack frame 330 aghi %r15,-160 331.LCFI11: 332 lgr %r2,%r0 # Closure 333 la %r3,16(%r1) # GPRs 334 la %r4,128(%r1) # FPRs 335 la %r5,160(%r1) # Overflow 336 stg %r1,0(%r15) # Set up back chain 337 338 brasl %r14,ffi_closure_helper_SYSV # Call helper 339 340 lg %r14,160+112(%r15) 341 ld %f0,160+128(%r15) # Load return registers 342 lg %r2,160+16(%r15) 343 la %r15,160(%r15) 344 br %r14 345.LFE2: 346 347.ffi_closure_SYSV_end: 348 .size ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV 349 350 351 352 .section .eh_frame,EH_FRAME_FLAGS,@progbits 353.Lframe1: 354 .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry 355.LSCIE1: 356 .4byte 0x0 # CIE Identifier Tag 357 .byte 0x1 # CIE Version 358 .ascii "zR\0" # CIE Augmentation 359 .uleb128 0x1 # CIE Code Alignment Factor 360 .sleb128 -8 # CIE Data Alignment Factor 361 .byte 0xe # CIE RA Column 362 .uleb128 0x1 # Augmentation size 363 .byte 0x1b # FDE Encoding (pcrel sdata4) 364 .byte 0xc # DW_CFA_def_cfa 365 .uleb128 0xf 366 .uleb128 0xa0 367 .align 8 368.LECIE1: 369.LSFDE1: 370 .4byte .LEFDE1-.LASFDE1 # FDE Length 371.LASFDE1: 372 .4byte .LASFDE1-.Lframe1 # FDE CIE offset 373 .4byte .LFB1-. # FDE initial location 374 .4byte .LFE1-.LFB1 # FDE address range 375 .uleb128 0x0 # Augmentation size 376 .byte 0x4 # DW_CFA_advance_loc4 377 .4byte .LCFI0-.LFB1 378 .byte 0x8f # DW_CFA_offset, column 0xf 379 .uleb128 0x5 380 .byte 0x8e # DW_CFA_offset, column 0xe 381 .uleb128 0x6 382 .byte 0x8d # DW_CFA_offset, column 0xd 383 .uleb128 0x7 384 .byte 0x8c # DW_CFA_offset, column 0xc 385 .uleb128 0x8 386 .byte 0x8b # DW_CFA_offset, column 0xb 387 .uleb128 0x9 388 .byte 0x8a # DW_CFA_offset, column 0xa 389 .uleb128 0xa 390 .byte 0x89 # DW_CFA_offset, column 0x9 391 .uleb128 0xb 392 .byte 0x88 # DW_CFA_offset, column 0x8 393 .uleb128 0xc 394 .byte 0x87 # DW_CFA_offset, column 0x7 395 .uleb128 0xd 396 .byte 0x86 # DW_CFA_offset, column 0x6 397 .uleb128 0xe 398 .byte 0x4 # DW_CFA_advance_loc4 399 .4byte .LCFI1-.LCFI0 400 .byte 0xd # DW_CFA_def_cfa_register 401 .uleb128 0xb 402 .byte 0x4 # DW_CFA_advance_loc4 403 .4byte .LCFI2-.LCFI1 404 .byte 0xe # DW_CFA_def_cfa_offset 405 .uleb128 0xf0 406 .align 8 407.LEFDE1: 408.LSFDE2: 409 .4byte .LEFDE2-.LASFDE2 # FDE Length 410.LASFDE2: 411 .4byte .LASFDE2-.Lframe1 # FDE CIE offset 412 .4byte .LFB2-. # FDE initial location 413 .4byte .LFE2-.LFB2 # FDE address range 414 .uleb128 0x0 # Augmentation size 415 .byte 0x4 # DW_CFA_advance_loc4 416 .4byte .LCFI10-.LFB2 417 .byte 0x8f # DW_CFA_offset, column 0xf 418 .uleb128 0x5 419 .byte 0x8e # DW_CFA_offset, column 0xe 420 .uleb128 0x6 421 .byte 0x4 # DW_CFA_advance_loc4 422 .4byte .LCFI11-.LCFI10 423 .byte 0xe # DW_CFA_def_cfa_offset 424 .uleb128 0x140 425 .align 8 426.LEFDE2: 427 428#endif 429 430