OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libffi/] [src/] [arm/] [sysv.S] - Blame information for rev 748

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 732 jeremybenn
/* -----------------------------------------------------------------------
2
   sysv.S - Copyright (c) 1998, 2008 Red Hat, Inc.
3
 
4
   ARM 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,
18
   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
   DEALINGS IN THE SOFTWARE.
25
   ----------------------------------------------------------------------- */
26
 
27
#define LIBFFI_ASM
28
#include 
29
#include 
30
#ifdef HAVE_MACHINE_ASM_H
31
#include 
32
#else
33
#ifdef __USER_LABEL_PREFIX__
34
#define CONCAT1(a, b) CONCAT2(a, b)
35
#define CONCAT2(a, b) a ## b
36
 
37
/* Use the right prefix for global labels.  */
38
#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
39
#else
40
#define CNAME(x) x
41
#endif
42
#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
43
#endif
44
 
45
#ifdef __ELF__
46
#define LSYM(x) .x
47
#else
48
#define LSYM(x) x
49
#endif
50
 
51
/* We need a better way of testing for this, but for now, this is all
52
   we can do.  */
53
@ This selects the minimum architecture level required.
54
#define __ARM_ARCH__ 3
55
 
56
#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
57
# undef __ARM_ARCH__
58
# define __ARM_ARCH__ 4
59
#endif
60
 
61
#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
62
        || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
63
        || defined(__ARM_ARCH_5TEJ__)
64
# undef __ARM_ARCH__
65
# define __ARM_ARCH__ 5
66
#endif
67
 
68
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
69
        || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
70
        || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
71
        || defined(__ARM_ARCH_6M__)
72
# undef __ARM_ARCH__
73
# define __ARM_ARCH__ 6
74
#endif
75
 
76
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
77
        || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
78
        || defined(__ARM_ARCH_7EM__)
79
# undef __ARM_ARCH__
80
# define __ARM_ARCH__ 7
81
#endif
82
 
83
#if __ARM_ARCH__ >= 5
84
# define call_reg(x)    blx     x
85
#elif defined (__ARM_ARCH_4T__)
86
# define call_reg(x)    mov     lr, pc ; bx     x
87
# if defined(__thumb__) || defined(__THUMB_INTERWORK__)
88
#  define __INTERWORKING__
89
# endif
90
#else
91
# define call_reg(x)    mov     lr, pc ; mov    pc, x
92
#endif
93
 
94
/* Conditionally compile unwinder directives.  */
95
#ifdef __ARM_EABI__
96
#define UNWIND
97
#else
98
#define UNWIND @
99
#endif
100
 
101
 
102
#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
103
.macro  ARM_FUNC_START name
104
        .text
105
        .align 0
106
        .thumb
107
        .thumb_func
108
        ENTRY(\name)
109
        bx      pc
110
        nop
111
        .arm
112
        UNWIND .fnstart
113
/* A hook to tell gdb that we've switched to ARM mode.  Also used to call
114
   directly from other local arm routines.  */
115
_L__\name:
116
.endm
117
#else
118
.macro  ARM_FUNC_START name
119
        .text
120
        .align 0
121
        .arm
122
        ENTRY(\name)
123
        UNWIND .fnstart
124
.endm
125
#endif
126
 
127
.macro  RETLDM  regs=, cond=, dirn=ia
128
#if defined (__INTERWORKING__)
129
        .ifc "\regs",""
130
        ldr\cond        lr, [sp], #4
131
        .else
132
        ldm\cond\dirn   sp!, {\regs, lr}
133
        .endif
134
        bx\cond lr
135
#else
136
        .ifc "\regs",""
137
        ldr\cond        pc, [sp], #4
138
        .else
139
        ldm\cond\dirn   sp!, {\regs, pc}
140
        .endif
141
#endif
142
.endm
143
 
144
 
145
        @ r0:   fn
146
        @ r1:   &ecif
147
        @ r2:   cif->bytes
148
        @ r3:   fig->flags
149
        @ sp+0: ecif.rvalue
150
 
151
        @ This assumes we are using gas.
152
ARM_FUNC_START ffi_call_SYSV
153
        @ Save registers
154
        stmfd   sp!, {r0-r3, fp, lr}
155
        UNWIND .save    {r0-r3, fp, lr}
156
        mov     fp, sp
157
 
158
        UNWIND .setfp   fp, sp
159
 
160
        @ Make room for all of the new args.
161
        sub     sp, fp, r2
162
 
163
        @ Place all of the ffi_prep_args in position
164
        mov     r0, sp
165
        @     r1 already set
166
 
167
        @ Call ffi_prep_args(stack, &ecif)
168
        bl      ffi_prep_args
169
 
170
        @ move first 4 parameters in registers
171
        ldmia   sp, {r0-r3}
172
 
173
        @ and adjust stack
174
        sub     lr, fp, sp      @ cif->bytes == fp - sp
175
        ldr     ip, [fp]        @ load fn() in advance
176
        cmp     lr, #16
177
        movhs   lr, #16
178
        add     sp, sp, lr
179
 
180
        @ call (fn) (...)
181
        call_reg(ip)
182
 
183
        @ Remove the space we pushed for the args
184
        mov     sp, fp
185
 
186
        @ Load r2 with the pointer to storage for the return value
187
        ldr     r2, [sp, #24]
188
 
189
        @ Load r3 with the return type code
190
        ldr     r3, [sp, #12]
191
 
192
        @ If the return value pointer is NULL, assume no return value.
193
        cmp     r2, #0
194
        beq     LSYM(Lepilogue)
195
 
196
@ return INT
197
        cmp     r3, #FFI_TYPE_INT
198
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
199
        cmpne   r3, #FFI_TYPE_FLOAT
200
#endif
201
        streq   r0, [r2]
202
        beq     LSYM(Lepilogue)
203
 
204
        @ return INT64
205
        cmp     r3, #FFI_TYPE_SINT64
206
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
207
        cmpne   r3, #FFI_TYPE_DOUBLE
208
#endif
209
        stmeqia r2, {r0, r1}
210
 
211
#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
212
        beq     LSYM(Lepilogue)
213
 
214
@ return FLOAT
215
        cmp     r3, #FFI_TYPE_FLOAT
216
        stfeqs  f0, [r2]
217
        beq     LSYM(Lepilogue)
218
 
219
@ return DOUBLE or LONGDOUBLE
220
        cmp     r3, #FFI_TYPE_DOUBLE
221
        stfeqd  f0, [r2]
222
#endif
223
 
224
LSYM(Lepilogue):
225
        RETLDM  "r0-r3,fp"
226
 
227
.ffi_call_SYSV_end:
228
        UNWIND .fnend
229
        .size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
230
 
231
 
232
/*
233
        unsigned int FFI_HIDDEN
234
        ffi_closure_SYSV_inner (closure, respp, args)
235
             ffi_closure *closure;
236
             void **respp;
237
             void *args;
238
*/
239
 
240
ARM_FUNC_START ffi_closure_SYSV
241
        UNWIND .pad #16
242
        add     ip, sp, #16
243
        stmfd   sp!, {ip, lr}
244
        UNWIND .save    {r0, lr}
245
        add     r2, sp, #8
246
        UNWIND .pad #16
247
        sub     sp, sp, #16
248
        str     sp, [sp, #8]
249
        add     r1, sp, #8
250
        bl      ffi_closure_SYSV_inner
251
        cmp     r0, #FFI_TYPE_INT
252
        beq     .Lretint
253
 
254
        cmp     r0, #FFI_TYPE_FLOAT
255
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
256
        beq     .Lretint
257
#else
258
        beq     .Lretfloat
259
#endif
260
 
261
        cmp     r0, #FFI_TYPE_DOUBLE
262
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
263
        beq     .Lretlonglong
264
#else
265
        beq     .Lretdouble
266
#endif
267
 
268
        cmp     r0, #FFI_TYPE_LONGDOUBLE
269
#if defined(__SOFTFP__) || defined(__ARM_EABI__)
270
        beq     .Lretlonglong
271
#else
272
        beq     .Lretlongdouble
273
#endif
274
 
275
        cmp     r0, #FFI_TYPE_SINT64
276
        beq     .Lretlonglong
277
.Lclosure_epilogue:
278
        add     sp, sp, #16
279
        ldmfd   sp, {sp, pc}
280
.Lretint:
281
        ldr     r0, [sp]
282
        b       .Lclosure_epilogue
283
.Lretlonglong:
284
        ldr     r0, [sp]
285
        ldr     r1, [sp, #4]
286
        b       .Lclosure_epilogue
287
 
288
#if !defined(__SOFTFP__) && !defined(__ARM_EABI__)
289
.Lretfloat:
290
        ldfs    f0, [sp]
291
        b       .Lclosure_epilogue
292
.Lretdouble:
293
        ldfd    f0, [sp]
294
        b       .Lclosure_epilogue
295
.Lretlongdouble:
296
        ldfd    f0, [sp]
297
        b       .Lclosure_epilogue
298
#endif
299
 
300
.ffi_closure_SYSV_end:
301
        UNWIND .fnend
302
        .size    CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
303
 
304
 
305
/* Below are VFP hard-float ABI call and closure implementations.
306
   Add VFP FPU directive here. */
307
        .fpu    vfp
308
 
309
        @ r0:   fn
310
        @ r1:   &ecif
311
        @ r2:   cif->bytes
312
        @ r3:   fig->flags
313
        @ sp+0: ecif.rvalue
314
 
315
ARM_FUNC_START ffi_call_VFP
316
        @ Save registers
317
        stmfd   sp!, {r0-r3, fp, lr}
318
        UNWIND .save    {r0-r3, fp, lr}
319
        mov     fp, sp
320
        UNWIND .setfp   fp, sp
321
 
322
        @ Make room for all of the new args.
323
        sub     sp, sp, r2
324
 
325
        @ Make room for loading VFP args
326
        sub     sp, sp, #64
327
 
328
        @ Place all of the ffi_prep_args in position
329
        mov     r0, sp
330
        @     r1 already set
331
        sub     r2, fp, #64   @ VFP scratch space
332
 
333
        @ Call ffi_prep_args(stack, &ecif, vfp_space)
334
        bl      ffi_prep_args
335
 
336
        @ Load VFP register args if needed
337
        cmp     r0, #0
338
        beq     LSYM(Lbase_args)
339
 
340
        @ Load only d0 if possible
341
        cmp     r0, #3
342
        sub     ip, fp, #64
343
        flddle  d0, [ip]
344
        fldmiadgt       ip, {d0-d7}
345
 
346
LSYM(Lbase_args):
347
        @ move first 4 parameters in registers
348
        ldmia   sp, {r0-r3}
349
 
350
        @ and adjust stack
351
        sub     lr, ip, sp      @ cif->bytes == (fp - 64) - sp
352
        ldr     ip, [fp]        @ load fn() in advance
353
        cmp     lr, #16
354
        movhs   lr, #16
355
        add     sp, sp, lr
356
 
357
        @ call (fn) (...)
358
        call_reg(ip)
359
 
360
        @ Remove the space we pushed for the args
361
        mov     sp, fp
362
 
363
        @ Load r2 with the pointer to storage for
364
        @ the return value
365
        ldr     r2, [sp, #24]
366
 
367
        @ Load r3 with the return type code
368
        ldr     r3, [sp, #12]
369
 
370
        @ If the return value pointer is NULL,
371
        @ assume no return value.
372
        cmp     r2, #0
373
        beq     LSYM(Lepilogue_vfp)
374
 
375
        cmp     r3, #FFI_TYPE_INT
376
        streq   r0, [r2]
377
        beq     LSYM(Lepilogue_vfp)
378
 
379
        cmp     r3, #FFI_TYPE_SINT64
380
        stmeqia r2, {r0, r1}
381
        beq     LSYM(Lepilogue_vfp)
382
 
383
        cmp     r3, #FFI_TYPE_FLOAT
384
        fstseq  s0, [r2]
385
        beq     LSYM(Lepilogue_vfp)
386
 
387
        cmp     r3, #FFI_TYPE_DOUBLE
388
        fstdeq  d0, [r2]
389
        beq     LSYM(Lepilogue_vfp)
390
 
391
        cmp     r3, #FFI_TYPE_STRUCT_VFP_FLOAT
392
        cmpne   r3, #FFI_TYPE_STRUCT_VFP_DOUBLE
393
        fstmiadeq       r2, {d0-d3}
394
 
395
LSYM(Lepilogue_vfp):
396
        RETLDM  "r0-r3,fp"
397
 
398
.ffi_call_VFP_end:
399
        UNWIND .fnend
400
        .size    CNAME(ffi_call_VFP),.ffi_call_VFP_end-CNAME(ffi_call_VFP)
401
 
402
 
403
ARM_FUNC_START ffi_closure_VFP
404
        fstmfdd sp!, {d0-d7}
405
        @ r0-r3, then d0-d7
406
        UNWIND .pad #80
407
        add     ip, sp, #80
408
        stmfd   sp!, {ip, lr}
409
        UNWIND .save    {r0, lr}
410
        add     r2, sp, #72
411
        add     r3, sp, #8
412
        UNWIND .pad #72
413
        sub     sp, sp, #72
414
        str     sp, [sp, #64]
415
        add     r1, sp, #64
416
        bl      ffi_closure_SYSV_inner
417
 
418
        cmp     r0, #FFI_TYPE_INT
419
        beq     .Lretint_vfp
420
 
421
        cmp     r0, #FFI_TYPE_FLOAT
422
        beq     .Lretfloat_vfp
423
 
424
        cmp     r0, #FFI_TYPE_DOUBLE
425
        cmpne   r0, #FFI_TYPE_LONGDOUBLE
426
        beq     .Lretdouble_vfp
427
 
428
        cmp     r0, #FFI_TYPE_SINT64
429
        beq     .Lretlonglong_vfp
430
 
431
        cmp     r0, #FFI_TYPE_STRUCT_VFP_FLOAT
432
        beq     .Lretfloat_struct_vfp
433
 
434
        cmp     r0, #FFI_TYPE_STRUCT_VFP_DOUBLE
435
        beq     .Lretdouble_struct_vfp
436
 
437
.Lclosure_epilogue_vfp:
438
        add     sp, sp, #72
439
        ldmfd   sp, {sp, pc}
440
 
441
.Lretfloat_vfp:
442
        flds    s0, [sp]
443
        b       .Lclosure_epilogue_vfp
444
.Lretdouble_vfp:
445
        fldd    d0, [sp]
446
        b       .Lclosure_epilogue_vfp
447
.Lretint_vfp:
448
        ldr     r0, [sp]
449
        b       .Lclosure_epilogue_vfp
450
.Lretlonglong_vfp:
451
        ldmia   sp, {r0, r1}
452
        b       .Lclosure_epilogue_vfp
453
.Lretfloat_struct_vfp:
454
        fldmiad sp, {d0-d1}
455
        b       .Lclosure_epilogue_vfp
456
.Lretdouble_struct_vfp:
457
        fldmiad sp, {d0-d3}
458
        b       .Lclosure_epilogue_vfp
459
 
460
.ffi_closure_VFP_end:
461
        UNWIND .fnend
462
        .size    CNAME(ffi_closure_VFP),.ffi_closure_VFP_end-CNAME(ffi_closure_VFP)
463
 
464
ENTRY(ffi_arm_trampoline)
465
        stmfd sp!, {r0-r3}
466
        ldr r0, [pc]
467
        ldr pc, [pc]
468
 
469
#if defined __ELF__ && defined __linux__
470
        .section        .note.GNU-stack,"",%progbits
471
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.