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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libffi/] [src/] [powerpc/] [darwin.S] - Blame information for rev 801

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

Line No. Rev Author Line
1 732 jeremybenn
/* -----------------------------------------------------------------------
2
   darwin.S - Copyright (c) 2000 John Hornkvist
3
              Copyright (c) 2004, 2010 Free Software Foundation, Inc.
4
 
5
   PowerPC Assembly glue.
6
 
7
   Permission is hereby granted, free of charge, to any person obtaining
8
   a copy of this software and associated documentation files (the
9
   ``Software''), to deal in the Software without restriction, including
10
   without limitation the rights to use, copy, modify, merge, publish,
11
   distribute, sublicense, and/or sell copies of the Software, and to
12
   permit persons to whom the Software is furnished to do so, subject to
13
   the following conditions:
14
 
15
   The above copyright notice and this permission notice shall be included
16
   in all copies or substantial portions of the Software.
17
 
18
   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21
   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
22
   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23
   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
   OTHER DEALINGS IN THE SOFTWARE.
25
   ----------------------------------------------------------------------- */
26
 
27
#define LIBFFI_ASM
28
#if defined(__ppc64__)
29
#define MODE_CHOICE(x, y) y
30
#else
31
#define MODE_CHOICE(x, y) x
32
#endif
33
 
34
#define machine_choice  MODE_CHOICE(ppc7400,ppc64)
35
 
36
; Define some pseudo-opcodes for size-independent load & store of GPRs ...
37
#define lgu             MODE_CHOICE(lwzu, ldu)
38
#define lg              MODE_CHOICE(lwz,ld)
39
#define sg              MODE_CHOICE(stw,std)
40
#define sgu             MODE_CHOICE(stwu,stdu)
41
#define sgux            MODE_CHOICE(stwux,stdux)
42
 
43
; ... and the size of GPRs and their storage indicator.
44
#define GPR_BYTES       MODE_CHOICE(4,8)
45
#define LOG2_GPR_BYTES  MODE_CHOICE(2,3)        /* log2(GPR_BYTES) */
46
#define g_long          MODE_CHOICE(long, quad) /* usage is ".g_long" */
47
 
48
; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04.
49
#define LINKAGE_SIZE    MODE_CHOICE(24,48)
50
#define PARAM_AREA      MODE_CHOICE(32,64)
51
#define SAVED_LR_OFFSET MODE_CHOICE(8,16)       /* save position for lr */
52
 
53
/* If there is any FP stuff we make space for all of the regs.  */
54
#define SAVED_FPR_COUNT 13
55
#define FPR_SIZE        8
56
#define RESULT_BYTES    16
57
 
58
/* This should be kept in step with the same value in ffi_darwin.c.  */
59
#define ASM_NEEDS_REGISTERS 4
60
#define SAVE_REGS_SIZE (ASM_NEEDS_REGISTERS * GPR_BYTES)
61
 
62
#include 
63
#include 
64
 
65
#define JUMPTARGET(name) name
66
#define L(x) x
67
 
68
        .text
69
        .align 2
70
        .globl _ffi_prep_args
71
 
72
        .align 2
73
        .globl _ffi_call_DARWIN
74
 
75
        /* We arrive here with:
76
           r3 = ptr to extended cif.
77
           r4 = -bytes.
78
           r5 = cif flags.
79
           r6 = ptr to return value.
80
           r7 = fn pointer (user func).
81
           r8 = fn pointer (ffi_prep_args).
82
           r9 = ffi_type* for the ret val.  */
83
 
84
_ffi_call_DARWIN:
85
Lstartcode:
86
        mr      r12,r8  /* We only need r12 until the call,
87
                           so it does not have to be saved.  */
88
LFB1:
89
        /* Save the old stack pointer as AP.  */
90
        mr      r8,r1
91
LCFI0:
92
 
93
        /* Save the retval type in parents frame.  */
94
        sg      r9,(LINKAGE_SIZE+6*GPR_BYTES)(r8)
95
 
96
        /* Allocate the stack space we need.  */
97
        sgux    r1,r1,r4
98
 
99
        /* Save registers we use.  */
100
        mflr    r9
101
        sg      r9,SAVED_LR_OFFSET(r8)
102
 
103
        sg      r28,-(4 * GPR_BYTES)(r8)
104
        sg      r29,-(3 * GPR_BYTES)(r8)
105
        sg      r30,-(2 * GPR_BYTES)(r8)
106
        sg      r31,-(    GPR_BYTES)(r8)
107
 
108
#if !defined(POWERPC_DARWIN)
109
        /* The TOC slot is reserved in the Darwin ABI and r2 is volatile.  */
110
        sg      r2,(5 * GPR_BYTES)(r1)
111
#endif
112
 
113
LCFI1:
114
 
115
        /* Save arguments over call.  */
116
        mr      r31,r5  /* flags,  */
117
        mr      r30,r6  /* rvalue,  */
118
        mr      r29,r7  /* function address,  */
119
        mr      r28,r8  /* our AP.  */
120
LCFI2:
121
        /* Call ffi_prep_args. r3 = extended cif, r4 = stack ptr copy.  */
122
        mr      r4,r1
123
        li      r9,0
124
 
125
        mtctr   r12 /* r12 holds address of _ffi_prep_args.  */
126
        bctrl
127
 
128
#if !defined(POWERPC_DARWIN)
129
        /* The TOC slot is reserved in the Darwin ABI and r2 is volatile.  */
130
        lg     r2,(5 * GPR_BYTES)(r1)
131
#endif
132
        /* Now do the call.
133
           Set up cr1 with bits 4-7 of the flags.  */
134
        mtcrf   0x40,r31
135
        /* Get the address to call into CTR.  */
136
        mtctr   r29
137
        /* Load all those argument registers.
138
           We have set up a nice stack frame, just load it into registers.  */
139
        lg     r3, (LINKAGE_SIZE                )(r1)
140
        lg     r4, (LINKAGE_SIZE +     GPR_BYTES)(r1)
141
        lg     r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r1)
142
        lg     r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r1)
143
        nop
144
        lg     r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r1)
145
        lg     r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r1)
146
        lg     r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r1)
147
        lg     r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r1)
148
 
149
L1:
150
        /* ... Load all the FP registers.  */
151
        bf      6,L2    /* No floats to load.  */
152
        lfd     f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28)
153
        lfd     f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28)
154
        lfd     f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28)
155
        lfd     f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28)
156
        nop
157
        lfd     f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28)
158
        lfd     f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28)
159
        lfd     f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28)
160
        lfd     f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28)
161
        nop
162
        lfd     f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28)
163
        lfd     f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28)
164
        lfd     f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28)
165
        lfd     f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28)
166
        nop
167
        lfd     f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28)
168
 
169
L2:
170
        mr      r12,r29 /* Put the target address in r12 as specified.  */
171
        mtctr   r12
172
        nop
173
        nop
174
 
175
        /* Make the call.  */
176
        bctrl
177
 
178
        /* Now, deal with the return value.  */
179
 
180
        /* m64 structure returns can occupy the same set of registers as
181
           would be used to pass such a structure as arg0 - so take care
182
           not to step on any possibly hot regs.  */
183
 
184
        /* Get the flags.. */
185
        mtcrf   0x03,r31 ; we need c6 & cr7 now.
186
        ; FLAG_RETURNS_NOTHING also covers struct ret-by-ref.
187
        bt      30,L(done_return_value)   ; FLAG_RETURNS_NOTHING
188
        bf      27,L(scalar_return_value) ; not FLAG_RETURNS_STRUCT
189
 
190
        /* OK, so we have a struct.  */
191
#if defined(__ppc64__)
192
        bt      31,L(maybe_return_128) ; FLAG_RETURNS_128BITS, special case
193
 
194
        /* OK, we have to map the return back to a mem struct.
195
           We are about to trample the parents param area, so recover the
196
           return type.  r29 is free, since the call is done.  */
197
        lg      r29,(LINKAGE_SIZE + 6 * GPR_BYTES)(r28)
198
 
199
        sg      r3, (LINKAGE_SIZE                )(r28)
200
        sg      r4, (LINKAGE_SIZE +     GPR_BYTES)(r28)
201
        sg      r5, (LINKAGE_SIZE + 2 * GPR_BYTES)(r28)
202
        sg      r6, (LINKAGE_SIZE + 3 * GPR_BYTES)(r28)
203
        nop
204
        sg      r7, (LINKAGE_SIZE + 4 * GPR_BYTES)(r28)
205
        sg      r8, (LINKAGE_SIZE + 5 * GPR_BYTES)(r28)
206
        sg      r9, (LINKAGE_SIZE + 6 * GPR_BYTES)(r28)
207
        sg      r10,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28)
208
        /* OK, so do the block move - we trust that memcpy will not trample
209
           the fprs...  */
210
        mr      r3,r30 ; dest
211
        addi    r4,r28,LINKAGE_SIZE ; source
212
        /* The size is a size_t, should be long.  */
213
        lg      r5,0(r29)
214
        /* Figure out small structs */
215
        cmpi    0,r5,4
216
        bgt     L3      ; 1, 2 and 4 bytes have special rules.
217
        cmpi    0,r5,3
218
        beq     L3      ; not 3
219
        addi    r4,r4,8
220
        subf    r4,r5,r4
221
L3:
222
        bl      _memcpy
223
 
224
        /* ... do we need the FP registers? - recover the flags.. */
225
        mtcrf   0x03,r31 ; we need c6 & cr7 now.
226
        bf      29,L(done_return_value) /* No floats in the struct.  */
227
        stfd    f1, -SAVE_REGS_SIZE-(13*FPR_SIZE)(r28)
228
        stfd    f2, -SAVE_REGS_SIZE-(12*FPR_SIZE)(r28)
229
        stfd    f3, -SAVE_REGS_SIZE-(11*FPR_SIZE)(r28)
230
        stfd    f4, -SAVE_REGS_SIZE-(10*FPR_SIZE)(r28)
231
        nop
232
        stfd    f5, -SAVE_REGS_SIZE-( 9*FPR_SIZE)(r28)
233
        stfd    f6, -SAVE_REGS_SIZE-( 8*FPR_SIZE)(r28)
234
        stfd    f7, -SAVE_REGS_SIZE-( 7*FPR_SIZE)(r28)
235
        stfd    f8, -SAVE_REGS_SIZE-( 6*FPR_SIZE)(r28)
236
        nop
237
        stfd    f9, -SAVE_REGS_SIZE-( 5*FPR_SIZE)(r28)
238
        stfd    f10,-SAVE_REGS_SIZE-( 4*FPR_SIZE)(r28)
239
        stfd    f11,-SAVE_REGS_SIZE-( 3*FPR_SIZE)(r28)
240
        stfd    f12,-SAVE_REGS_SIZE-( 2*FPR_SIZE)(r28)
241
        nop
242
        stfd    f13,-SAVE_REGS_SIZE-( 1*FPR_SIZE)(r28)
243
 
244
        mr      r3,r29  ; ffi_type *
245
        mr      r4,r30  ; dest
246
        addi    r5,r28,-SAVE_REGS_SIZE-(13*FPR_SIZE) ; fprs
247
        xor     r6,r6,r6
248
        sg      r6,(LINKAGE_SIZE + 7 * GPR_BYTES)(r28)
249
        addi    r6,r28,(LINKAGE_SIZE + 7 * GPR_BYTES) ; point to a zeroed counter.
250
        bl      _darwin64_struct_floats_to_mem
251
 
252
        b L(done_return_value)
253
#else
254
        stw     r3,0(r30) ; m32 the only struct return in reg is 4 bytes.
255
#endif
256
        b L(done_return_value)
257
 
258
L(fp_return_value):
259
        /* Do we have long double to store?  */
260
        bf      31,L(fd_return_value) ; FLAG_RETURNS_128BITS
261
        stfd    f1,0(r30)
262
        stfd    f2,FPR_SIZE(r30)
263
        b       L(done_return_value)
264
 
265
L(fd_return_value):
266
        /* Do we have double to store?  */
267
        bf      28,L(float_return_value)
268
        stfd    f1,0(r30)
269
        b       L(done_return_value)
270
 
271
L(float_return_value):
272
        /* We only have a float to store.  */
273
        stfs    f1,0(r30)
274
        b       L(done_return_value)
275
 
276
L(scalar_return_value):
277
        bt      29,L(fp_return_value)   ; FLAG_RETURNS_FP
278
        ; ffi_arg is defined as unsigned long.
279
        sg      r3,0(r30)               ; Save the reg.
280
        bf      28,L(done_return_value) ; not FLAG_RETURNS_64BITS
281
 
282
#if defined(__ppc64__)
283
L(maybe_return_128):
284
        std     r3,0(r30)
285
        bf      31,L(done_return_value) ; not FLAG_RETURNS_128BITS
286
        std     r4,8(r30)
287
#else
288
        stw     r4,4(r30)
289
#endif
290
 
291
        /* Fall through.  */
292
        /* We want this at the end to simplify eh epilog computation.  */
293
 
294
L(done_return_value):
295
        /* Restore the registers we used and return.  */
296
        lg      r29,SAVED_LR_OFFSET(r28)
297
        ; epilog
298
        lg      r31,-(1 * GPR_BYTES)(r28)
299
        mtlr    r29
300
        lg      r30,-(2 * GPR_BYTES)(r28)
301
        lg      r29,-(3 * GPR_BYTES)(r28)
302
        lg      r28,-(4 * GPR_BYTES)(r28)
303
        lg      r1,0(r1)
304
        blr
305
LFE1:
306
        .align  1
307
/* END(_ffi_call_DARWIN)  */
308
 
309
/* Provide a null definition of _ffi_call_AIX.  */
310
        .text
311
        .globl _ffi_call_AIX
312
        .align 2
313
_ffi_call_AIX:
314
        blr
315
/* END(_ffi_call_AIX)  */
316
 
317
/* EH stuff.  */
318
 
319
#define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78)
320
 
321
        .static_data
322
        .align LOG2_GPR_BYTES
323
LLFB0$non_lazy_ptr:
324
        .g_long Lstartcode
325
 
326
        .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
327
EH_frame1:
328
        .set    L$set$0,LECIE1-LSCIE1
329
        .long   L$set$0 ; Length of Common Information Entry
330
LSCIE1:
331
        .long   0x0     ; CIE Identifier Tag
332
        .byte   0x1     ; CIE Version
333
        .ascii  "zR\0"  ; CIE Augmentation
334
        .byte   0x1     ; uleb128 0x1; CIE Code Alignment Factor
335
        .byte   EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor
336
        .byte   0x41    ; CIE RA Column
337
        .byte   0x1     ; uleb128 0x1; Augmentation size
338
        .byte   0x90    ; FDE Encoding (indirect pcrel)
339
        .byte   0xc     ; DW_CFA_def_cfa
340
        .byte   0x1     ; uleb128 0x1
341
        .byte   0x0     ; uleb128 0x0
342
        .align  LOG2_GPR_BYTES
343
LECIE1:
344
 
345
        .globl _ffi_call_DARWIN.eh
346
_ffi_call_DARWIN.eh:
347
LSFDE1:
348
        .set    L$set$1,LEFDE1-LASFDE1
349
        .long   L$set$1 ; FDE Length
350
LASFDE1:
351
        .long   LASFDE1-EH_frame1 ; FDE CIE offset
352
        .g_long LLFB0$non_lazy_ptr-.    ; FDE initial location
353
        .set    L$set$3,LFE1-Lstartcode
354
        .g_long L$set$3 ; FDE address range
355
        .byte   0x0     ; uleb128 0x0; Augmentation size
356
        .byte   0x4     ; DW_CFA_advance_loc4
357
        .set    L$set$4,LCFI0-Lstartcode
358
        .long   L$set$4
359
        .byte   0xd     ; DW_CFA_def_cfa_register
360
        .byte   0x08    ; uleb128 0x08
361
        .byte   0x4     ; DW_CFA_advance_loc4
362
        .set    L$set$5,LCFI1-LCFI0
363
        .long   L$set$5
364
        .byte   0x11    ; DW_CFA_offset_extended_sf
365
        .byte   0x41    ; uleb128 0x41
366
        .byte   0x7e    ; sleb128 -2
367
        .byte   0x9f    ; DW_CFA_offset, column 0x1f
368
        .byte   0x1     ; uleb128 0x1
369
        .byte   0x9e    ; DW_CFA_offset, column 0x1e
370
        .byte   0x2     ; uleb128 0x2
371
        .byte   0x9d    ; DW_CFA_offset, column 0x1d
372
        .byte   0x3     ; uleb128 0x3
373
        .byte   0x9c    ; DW_CFA_offset, column 0x1c
374
        .byte   0x4     ; uleb128 0x4
375
        .byte   0x4     ; DW_CFA_advance_loc4
376
        .set    L$set$6,LCFI2-LCFI1
377
        .long   L$set$6
378
        .byte   0xd     ; DW_CFA_def_cfa_register
379
        .byte   0x1c    ; uleb128 0x1c
380
        .align LOG2_GPR_BYTES
381
LEFDE1:
382
        .align 1
383
 

powered by: WebSVN 2.1.0

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