1
/* -----------------------------------------------------------------------
2
unix.S - Copyright (c) 1998, 2008 Red Hat, Inc.
3
Copyright (c) 2000 Hewlett Packard Company
5
IA64/unix Foreign Function Interface
7
Primary author: Hans Boehm, HP Labs
9
Loosely modeled on Cygnus code for other platforms.
11
Permission is hereby granted, free of charge, to any person obtaining
12
a copy of this software and associated documentation files (the
13
``Software''), to deal in the Software without restriction, including
14
without limitation the rights to use, copy, modify, merge, publish,
15
distribute, sublicense, and/or sell copies of the Software, and to
16
permit persons to whom the Software is furnished to do so, subject to
17
the following conditions:
19
The above copyright notice and this permission notice shall be included
20
in all copies or substantial portions of the Software.
22
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
23
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29
DEALINGS IN THE SOFTWARE.
30
----------------------------------------------------------------------- */
33
#include <fficonfig.h>
35
#include "ia64_flags.h"
37
.pred.safe_across_calls p1-p5,p16-p63
40
/* int ffi_call_unix (struct ia64_args *stack, PTR64 rvalue,
41
void (*fn)(void), int flags);
49
/* Bit o trickiness. We actually share a stack frame with ffi_call.
50
Rely on the fact that ffi_call uses a vframe and don't bother
51
tracking one here at all. */
53
.save ar.pfs, r36 // loc0
54
alloc loc0 = ar.pfs, 4, 3, 8, 0
63
/* Load up all of the argument registers. */
64
ldf.fill f8 = [in0], 32
65
ldf.fill f9 = [r16], 32
67
ldf.fill f10 = [in0], 32
68
ldf.fill f11 = [r16], 32
70
ldf.fill f12 = [in0], 32
71
ldf.fill f13 = [r16], 32
73
ldf.fill f14 = [in0], 32
74
ldf.fill f15 = [r16], 24
89
/* Deallocate the register save area from the stack frame. */
92
/* Call the target function. */
97
br.call.sptk.many b0 = b6
100
/* Dispatch to handle return value. */
105
addl r18 = @ltoffx(.Lst_table), gp
107
ld8.mov r18 = [r18], .Lst_table
110
shladd r18 = r16, 3, r18
179
cmp.lt p6, p0 = 8, in3
180
cmp.lt p7, p0 = 16, in3
181
cmp.lt p8, p0 = 24, in3
194
br.call.sptk.many b0 = memcpy#
203
cmp.lt p6, p0 = 4, in3
206
(p6) stfs [r16] = f9, 8
207
cmp.lt p7, p0 = 8, in3
208
cmp.lt p8, p0 = 12, in3
210
(p7) stfs [in1] = f10, 8
211
(p8) stfs [r16] = f11, 8
212
cmp.lt p9, p0 = 16, in3
213
cmp.lt p10, p0 = 20, in3
215
(p9) stfs [in1] = f12, 8
216
(p10) stfs [r16] = f13, 8
217
cmp.lt p6, p0 = 24, in3
218
cmp.lt p7, p0 = 28, in3
220
(p6) stfs [in1] = f14
221
(p7) stfs [r16] = f15
227
cmp.lt p6, p0 = 8, in3
230
(p6) stfd [r16] = f9, 16
231
cmp.lt p7, p0 = 16, in3
232
cmp.lt p8, p0 = 24, in3
234
(p7) stfd [in1] = f10, 16
235
(p8) stfd [r16] = f11, 16
236
cmp.lt p9, p0 = 32, in3
237
cmp.lt p10, p0 = 40, in3
239
(p9) stfd [in1] = f12, 16
240
(p10) stfd [r16] = f13, 16
241
cmp.lt p6, p0 = 48, in3
242
cmp.lt p7, p0 = 56, in3
244
(p6) stfd [in1] = f14
245
(p7) stfd [r16] = f15
251
cmp.lt p6, p0 = 16, in3
254
(p6) stfe [r16] = f9, 32
255
cmp.lt p7, p0 = 32, in3
256
cmp.lt p8, p0 = 48, in3
258
(p7) stfe [in1] = f10, 32
259
(p8) stfe [r16] = f11, 32
260
cmp.lt p9, p0 = 64, in3
261
cmp.lt p10, p0 = 80, in3
263
(p9) stfe [in1] = f12, 32
264
(p10) stfe [r16] = f13, 32
265
cmp.lt p6, p0 = 96, in3
266
cmp.lt p7, p0 = 112, in3
268
(p6) stfe [in1] = f14
269
(p7) stfe [r16] = f15
276
.global ffi_closure_unix
277
.proc ffi_closure_unix
279
#define FRAME_SIZE (8*16 + 8*8 + 8*16)
283
.save ar.pfs, r40 // loc0
284
alloc loc0 = ar.pfs, 8, 4, 4, 0
286
add r12 = -FRAME_SIZE, r12
293
/* Retrieve closure pointer and real gp. */
304
/* Spill all of the possible argument registers. */
305
add r16 = 16 + 8*16, sp
306
add r17 = 16 + 8*16 + 16, sp
308
stf.spill [r16] = f8, 32
309
stf.spill [r17] = f9, 32
312
stf.spill [r16] = f10, 32
313
stf.spill [r17] = f11, 32
315
stf.spill [r16] = f12, 32
316
stf.spill [r17] = f13, 32
318
stf.spill [r16] = f14, 32
319
stf.spill [r17] = f15, 24
322
st8.spill [r16] = in0, 16
324
st8.spill [r17] = in1, 16
325
add out1 = 16 + 8*16, sp
328
st8.spill [r16] = in2, 16
330
st8.spill [r17] = in3, 16
334
st8.spill [r16] = in4, 16
336
st8.spill [r17] = in5, 16
340
st8.spill [r16] = in6
342
st8.spill [r17] = in7
344
/* Invoke ffi_closure_unix_inner for the hard work. */
345
br.call.sptk.many b0 = ffi_closure_unix_inner
348
/* Dispatch to handle return value. */
352
addl r18 = @ltoffx(.Lld_table), gp
355
ld8.mov r18 = [r18], .Lld_table
358
shladd r18 = r16, 3, r18
374
add sp = FRAME_SIZE, sp
382
add sp = FRAME_SIZE, sp
390
add sp = FRAME_SIZE, sp
398
add sp = FRAME_SIZE, sp
406
add sp = FRAME_SIZE, sp
414
cmp.lt p6, p0 = 8, r8
415
cmp.lt p7, p0 = 16, r8
416
cmp.lt p8, p0 = 24, r8
419
(p6) ld8 r9 = [r17], 16
424
add sp = FRAME_SIZE, sp
432
cmp.lt p6, p0 = 4, r8
435
(p6) ldfs f9 = [r17], 8
436
cmp.lt p7, p0 = 8, r8
437
cmp.lt p8, p0 = 12, r8
439
(p7) ldfs f10 = [r16], 8
440
(p8) ldfs f11 = [r17], 8
441
cmp.lt p9, p0 = 16, r8
442
cmp.lt p10, p0 = 20, r8
444
(p9) ldfs f12 = [r16], 8
445
(p10) ldfs f13 = [r17], 8
446
cmp.lt p6, p0 = 24, r8
447
cmp.lt p7, p0 = 28, r8
449
(p6) ldfs f14 = [r16]
450
(p7) ldfs f15 = [r17]
452
add sp = FRAME_SIZE, sp
460
cmp.lt p6, p0 = 8, r8
463
(p6) ldfd f9 = [r17], 16
464
cmp.lt p7, p0 = 16, r8
465
cmp.lt p8, p0 = 24, r8
467
(p7) ldfd f10 = [r16], 16
468
(p8) ldfd f11 = [r17], 16
469
cmp.lt p9, p0 = 32, r8
470
cmp.lt p10, p0 = 40, r8
472
(p9) ldfd f12 = [r16], 16
473
(p10) ldfd f13 = [r17], 16
474
cmp.lt p6, p0 = 48, r8
475
cmp.lt p7, p0 = 56, r8
477
(p6) ldfd f14 = [r16]
478
(p7) ldfd f15 = [r17]
480
add sp = FRAME_SIZE, sp
488
cmp.lt p6, p0 = 16, r8
491
(p6) ldfe f9 = [r17], 32
492
cmp.lt p7, p0 = 32, r8
493
cmp.lt p8, p0 = 48, r8
495
(p7) ldfe f10 = [r16], 32
496
(p8) ldfe f11 = [r17], 32
497
cmp.lt p9, p0 = 64, r8
498
cmp.lt p10, p0 = 80, r8
500
(p9) ldfe f12 = [r16], 32
501
(p10) ldfe f13 = [r17], 32
502
cmp.lt p6, p0 = 96, r8
503
cmp.lt p7, p0 = 112, r8
505
(p6) ldfe f14 = [r16]
506
(p7) ldfe f15 = [r17]
508
add sp = FRAME_SIZE, sp
512
.endp ffi_closure_unix
517
data8 @pcrel(.Lst_void) // FFI_TYPE_VOID
518
data8 @pcrel(.Lst_sint32) // FFI_TYPE_INT
519
data8 @pcrel(.Lst_float) // FFI_TYPE_FLOAT
520
data8 @pcrel(.Lst_double) // FFI_TYPE_DOUBLE
521
data8 @pcrel(.Lst_ldouble) // FFI_TYPE_LONGDOUBLE
522
data8 @pcrel(.Lst_uint8) // FFI_TYPE_UINT8
523
data8 @pcrel(.Lst_sint8) // FFI_TYPE_SINT8
524
data8 @pcrel(.Lst_uint16) // FFI_TYPE_UINT16
525
data8 @pcrel(.Lst_sint16) // FFI_TYPE_SINT16
526
data8 @pcrel(.Lst_uint32) // FFI_TYPE_UINT32
527
data8 @pcrel(.Lst_sint32) // FFI_TYPE_SINT32
528
data8 @pcrel(.Lst_int64) // FFI_TYPE_UINT64
529
data8 @pcrel(.Lst_int64) // FFI_TYPE_SINT64
530
data8 @pcrel(.Lst_void) // FFI_TYPE_STRUCT
531
data8 @pcrel(.Lst_int64) // FFI_TYPE_POINTER
532
data8 @pcrel(.Lst_small_struct) // FFI_IA64_TYPE_SMALL_STRUCT
533
data8 @pcrel(.Lst_hfa_float) // FFI_IA64_TYPE_HFA_FLOAT
534
data8 @pcrel(.Lst_hfa_double) // FFI_IA64_TYPE_HFA_DOUBLE
535
data8 @pcrel(.Lst_hfa_ldouble) // FFI_IA64_TYPE_HFA_LDOUBLE
538
data8 @pcrel(.Lld_void) // FFI_TYPE_VOID
539
data8 @pcrel(.Lld_int) // FFI_TYPE_INT
540
data8 @pcrel(.Lld_float) // FFI_TYPE_FLOAT
541
data8 @pcrel(.Lld_double) // FFI_TYPE_DOUBLE
542
data8 @pcrel(.Lld_ldouble) // FFI_TYPE_LONGDOUBLE
543
data8 @pcrel(.Lld_int) // FFI_TYPE_UINT8
544
data8 @pcrel(.Lld_int) // FFI_TYPE_SINT8
545
data8 @pcrel(.Lld_int) // FFI_TYPE_UINT16
546
data8 @pcrel(.Lld_int) // FFI_TYPE_SINT16
547
data8 @pcrel(.Lld_int) // FFI_TYPE_UINT32
548
data8 @pcrel(.Lld_int) // FFI_TYPE_SINT32
549
data8 @pcrel(.Lld_int) // FFI_TYPE_UINT64
550
data8 @pcrel(.Lld_int) // FFI_TYPE_SINT64
551
data8 @pcrel(.Lld_void) // FFI_TYPE_STRUCT
552
data8 @pcrel(.Lld_int) // FFI_TYPE_POINTER
553
data8 @pcrel(.Lld_small_struct) // FFI_IA64_TYPE_SMALL_STRUCT
554
data8 @pcrel(.Lld_hfa_float) // FFI_IA64_TYPE_HFA_FLOAT
555
data8 @pcrel(.Lld_hfa_double) // FFI_IA64_TYPE_HFA_DOUBLE
556
data8 @pcrel(.Lld_hfa_ldouble) // FFI_IA64_TYPE_HFA_LDOUBLE
558
#if defined __ELF__ && defined __linux__
559
.section .note.GNU-stack,"",@progbits