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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libffi/] [src/] [mips/] [o32.S] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* -----------------------------------------------------------------------
2
   o32.S - Copyright (c) 1996, 1998, 2005  Red Hat, Inc.
3
 
4
   MIPS 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 
28
#include 
29
 
30
/* Only build this code if we are compiling for o32 */
31
 
32
#if defined(FFI_MIPS_O32)
33
 
34
#define callback a0
35
#define bytes    a2
36
#define flags    a3
37
 
38
#define SIZEOF_FRAME    (4 * FFI_SIZEOF_ARG + 2 * FFI_SIZEOF_ARG)
39
#define A3_OFF          (SIZEOF_FRAME + 3 * FFI_SIZEOF_ARG)
40
#define FP_OFF          (SIZEOF_FRAME - 2 * FFI_SIZEOF_ARG)
41
#define RA_OFF          (SIZEOF_FRAME - 1 * FFI_SIZEOF_ARG)
42
 
43
        .abicalls
44
        .text
45
        .align  2
46
        .globl  ffi_call_O32
47
        .ent    ffi_call_O32
48
ffi_call_O32:
49
$LFB0:
50
        # Prologue
51
        SUBU    $sp, SIZEOF_FRAME       # Frame size
52
$LCFI0:
53
        REG_S   $fp, FP_OFF($sp)        # Save frame pointer
54
$LCFI1:
55
        REG_S   ra, RA_OFF($sp)         # Save return address
56
$LCFI2:
57
        move    $fp, $sp
58
 
59
$LCFI3:
60
        move    t9, callback            # callback function pointer
61
        REG_S   flags, A3_OFF($fp)      # flags
62
 
63
        # Allocate at least 4 words in the argstack
64
        LI      v0, 4 * FFI_SIZEOF_ARG
65
        blt     bytes, v0, sixteen
66
 
67
        ADDU    v0, bytes, 7    # make sure it is aligned
68
        and     v0, -8          # to an 8 byte boundry
69
 
70
sixteen:
71
        SUBU    $sp, v0         # move the stack pointer to reflect the
72
                                # arg space
73
 
74
        ADDU    a0, $sp, 4 * FFI_SIZEOF_ARG
75
 
76
        jalr    t9
77
 
78
        REG_L   t0, A3_OFF($fp)         # load the flags word
79
        SRL     t2, t0, 4               # shift our arg info
80
        and     t0, ((1<<4)-1)          # mask out the return type
81
 
82
        ADDU    $sp, 4 * FFI_SIZEOF_ARG         # adjust $sp to new args
83
 
84
        bnez    t0, pass_d                      # make it quick for int
85
        REG_L   a0, 0*FFI_SIZEOF_ARG($sp)       # just go ahead and load the
86
        REG_L   a1, 1*FFI_SIZEOF_ARG($sp)       # four regs.
87
        REG_L   a2, 2*FFI_SIZEOF_ARG($sp)
88
        REG_L   a3, 3*FFI_SIZEOF_ARG($sp)
89
        b       call_it
90
 
91
pass_d:
92
        bne     t0, FFI_ARGS_D, pass_f
93
        l.d     $f12, 0*FFI_SIZEOF_ARG($sp)     # load $fp regs from args
94
        REG_L   a2,   2*FFI_SIZEOF_ARG($sp)     # passing a double
95
        REG_L   a3,   3*FFI_SIZEOF_ARG($sp)
96
        b       call_it
97
 
98
pass_f:
99
        bne     t0, FFI_ARGS_F, pass_d_d
100
        l.s     $f12, 0*FFI_SIZEOF_ARG($sp)     # load $fp regs from args
101
        REG_L   a1,   1*FFI_SIZEOF_ARG($sp)     # passing a float
102
        REG_L   a2,   2*FFI_SIZEOF_ARG($sp)
103
        REG_L   a3,   3*FFI_SIZEOF_ARG($sp)
104
        b       call_it
105
 
106
pass_d_d:
107
        bne     t0, FFI_ARGS_DD, pass_f_f
108
        l.d     $f12, 0*FFI_SIZEOF_ARG($sp)     # load $fp regs from args
109
        l.d     $f14, 2*FFI_SIZEOF_ARG($sp)     # passing two doubles
110
        b       call_it
111
 
112
pass_f_f:
113
        bne     t0, FFI_ARGS_FF, pass_d_f
114
        l.s     $f12, 0*FFI_SIZEOF_ARG($sp)     # load $fp regs from args
115
        l.s     $f14, 1*FFI_SIZEOF_ARG($sp)     # passing two floats
116
        REG_L   a2,   2*FFI_SIZEOF_ARG($sp)
117
        REG_L   a3,   3*FFI_SIZEOF_ARG($sp)
118
        b       call_it
119
 
120
pass_d_f:
121
        bne     t0, FFI_ARGS_DF, pass_f_d
122
        l.d     $f12, 0*FFI_SIZEOF_ARG($sp)     # load $fp regs from args
123
        l.s     $f14, 2*FFI_SIZEOF_ARG($sp)     # passing double and float
124
        REG_L   a3,   3*FFI_SIZEOF_ARG($sp)
125
        b       call_it
126
 
127
pass_f_d:
128
 # assume that the only other combination must be float then double
129
 #      bne     t0, FFI_ARGS_F_D, call_it
130
        l.s     $f12, 0*FFI_SIZEOF_ARG($sp)     # load $fp regs from args
131
        l.d     $f14, 2*FFI_SIZEOF_ARG($sp)     # passing double and float
132
 
133
call_it:
134
        # Load the function pointer
135
        REG_L   t9, SIZEOF_FRAME + 5*FFI_SIZEOF_ARG($fp)
136
 
137
        # If the return value pointer is NULL, assume no return value.
138
        REG_L   t1, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
139
        beqz    t1, noretval
140
 
141
        bne     t2, FFI_TYPE_INT, retlonglong
142
        jalr    t9
143
        REG_L   t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
144
        REG_S   v0, 0(t0)
145
        b       epilogue
146
 
147
retlonglong:
148
        # Really any 64-bit int, signed or not.
149
        bne     t2, FFI_TYPE_UINT64, retfloat
150
        jalr    t9
151
        REG_L   t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
152
        REG_S   v1, 4(t0)
153
        REG_S   v0, 0(t0)
154
        b       epilogue
155
 
156
retfloat:
157
        bne     t2, FFI_TYPE_FLOAT, retdouble
158
        jalr    t9
159
        REG_L   t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
160
        s.s     $f0, 0(t0)
161
        b       epilogue
162
 
163
retdouble:
164
        bne     t2, FFI_TYPE_DOUBLE, noretval
165
        jalr    t9
166
        REG_L   t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp)
167
        s.d     $f0, 0(t0)
168
        b       epilogue
169
 
170
noretval:
171
        jalr    t9
172
 
173
        # Epilogue
174
epilogue:
175
        move    $sp, $fp
176
        REG_L   $fp, FP_OFF($sp)        # Restore frame pointer
177
        REG_L   ra, RA_OFF($sp)         # Restore return address
178
        ADDU    $sp, SIZEOF_FRAME       # Fix stack pointer
179
        j       ra
180
 
181
$LFE0:
182
        .end    ffi_call_O32
183
 
184
 
185
/* ffi_closure_O32. Expects address of the passed-in ffi_closure
186
        in t0. Stores any arguments passed in registers onto the
187
        stack, then calls ffi_closure_mips_inner_O32, which
188
        then decodes them.
189
 
190
        Stack layout:
191
 
192
        14 - Start of parameters, original sp
193
        13 - ra save
194
        12 - fp save
195
        11 - $16 (s0) save
196
        10 - cprestore
197
         9 - return value high (v1)
198
         8 - return value low (v0)
199
         7 - f14 (le high, be low)
200
         6 - f14 (le low, be high)
201
         5 - f12 (le high, be low)
202
         4 - f12 (le low, be high)
203
         3 - Called function a3 save
204
         2 - Called function a2 save
205
         1 - Called function a1 save
206
 
207
         */
208
 
209
#define SIZEOF_FRAME2   (14 * FFI_SIZEOF_ARG)
210
#define A3_OFF2         (SIZEOF_FRAME2 + 3 * FFI_SIZEOF_ARG)
211
#define A2_OFF2         (SIZEOF_FRAME2 + 2 * FFI_SIZEOF_ARG)
212
#define A1_OFF2         (SIZEOF_FRAME2 + 1 * FFI_SIZEOF_ARG)
213
#define A0_OFF2         (SIZEOF_FRAME2 + 0 * FFI_SIZEOF_ARG)
214
#define RA_OFF2         (SIZEOF_FRAME2 - 1 * FFI_SIZEOF_ARG)
215
#define FP_OFF2         (SIZEOF_FRAME2 - 2 * FFI_SIZEOF_ARG)
216
#define S0_OFF2         (SIZEOF_FRAME2 - 3 * FFI_SIZEOF_ARG)
217
#define GP_OFF2         (SIZEOF_FRAME2 - 4 * FFI_SIZEOF_ARG)
218
#define V1_OFF2         (SIZEOF_FRAME2 - 5 * FFI_SIZEOF_ARG)
219
#define V0_OFF2         (SIZEOF_FRAME2 - 6 * FFI_SIZEOF_ARG)
220
#define FA_1_1_OFF2     (SIZEOF_FRAME2 - 7 * FFI_SIZEOF_ARG)
221
#define FA_1_0_OFF2     (SIZEOF_FRAME2 - 8 * FFI_SIZEOF_ARG)
222
#define FA_0_1_OFF2     (SIZEOF_FRAME2 - 9 * FFI_SIZEOF_ARG)
223
#define FA_0_0_OFF2     (SIZEOF_FRAME2 - 10 * FFI_SIZEOF_ARG)
224
 
225
        .text
226
        .align  2
227
        .globl  ffi_closure_O32
228
        .ent    ffi_closure_O32
229
ffi_closure_O32:
230
$LFB1:
231
        # Prologue
232
        .frame  $fp, SIZEOF_FRAME2, ra
233
        .set    noreorder
234
        .cpload t9
235
        .set    reorder
236
        SUBU    $sp, SIZEOF_FRAME2
237
        .cprestore GP_OFF2
238
$LCFI4:
239
        REG_S   $16, S0_OFF2($sp)        # Save s0
240
        REG_S   $fp, FP_OFF2($sp)        # Save frame pointer
241
        REG_S   ra, RA_OFF2($sp)         # Save return address
242
$LCFI6:
243
        move    $fp, $sp
244
 
245
$LCFI7:
246
        # Store all possible argument registers. If there are more than
247
        # four arguments, then they are stored above where we put a3.
248
        REG_S   a0, A0_OFF2($fp)
249
        REG_S   a1, A1_OFF2($fp)
250
        REG_S   a2, A2_OFF2($fp)
251
        REG_S   a3, A3_OFF2($fp)
252
 
253
        # Load ABI enum to s0
254
        REG_L   $16, 20($8)     # cif pointer follows tramp.
255
        REG_L   $16, 0($16)     # abi is first member.
256
 
257
        li      $13, 1          # FFI_O32
258
        bne     $16, $13, 1f    # Skip fp save if FFI_O32_SOFT_FLOAT
259
 
260
        # Store all possible float/double registers.
261
        s.d     $f12, FA_0_0_OFF2($fp)
262
        s.d     $f14, FA_1_0_OFF2($fp)
263
1:
264
        # Call ffi_closure_mips_inner_O32 to do the work.
265
        la      t9, ffi_closure_mips_inner_O32
266
        move    a0, $8   # Pointer to the ffi_closure
267
        addu    a1, $fp, V0_OFF2
268
        addu    a2, $fp, A0_OFF2
269
        addu    a3, $fp, FA_0_0_OFF2
270
        jalr    t9
271
 
272
        # Load the return value into the appropriate register.
273
        move    $8, $2
274
        li      $9, FFI_TYPE_VOID
275
        beq     $8, $9, closure_done
276
 
277
        li      $13, 1          # FFI_O32
278
        bne     $16, $13, 1f    # Skip fp restore if FFI_O32_SOFT_FLOAT
279
 
280
        li      $9, FFI_TYPE_FLOAT
281
        l.s     $f0, V0_OFF2($fp)
282
        beq     $8, $9, closure_done
283
 
284
        li      $9, FFI_TYPE_DOUBLE
285
        l.d     $f0, V0_OFF2($fp)
286
        beq     $8, $9, closure_done
287
1:
288
        REG_L   $3, V1_OFF2($fp)
289
        REG_L   $2, V0_OFF2($fp)
290
 
291
closure_done:
292
        # Epilogue
293
        move    $sp, $fp
294
        REG_L   $16, S0_OFF2($sp)        # Restore s0
295
        REG_L   $fp, FP_OFF2($sp)        # Restore frame pointer
296
        REG_L   ra,  RA_OFF2($sp)        # Restore return address
297
        ADDU    $sp, SIZEOF_FRAME2
298
        j       ra
299
$LFE1:
300
        .end    ffi_closure_O32
301
 
302
/* DWARF-2 unwind info. */
303
 
304
        .section        .eh_frame,"a",@progbits
305
$Lframe0:
306
        .4byte  $LECIE0-$LSCIE0  # Length of Common Information Entry
307
$LSCIE0:
308
        .4byte  0x0      # CIE Identifier Tag
309
        .byte   0x1      # CIE Version
310
        .ascii "zR\0"    # CIE Augmentation
311
        .uleb128 0x1     # CIE Code Alignment Factor
312
        .sleb128 4       # CIE Data Alignment Factor
313
        .byte   0x1f     # CIE RA Column
314
        .uleb128 0x1     # Augmentation size
315
        .byte   0x00     # FDE Encoding (absptr)
316
        .byte   0xc      # DW_CFA_def_cfa
317
        .uleb128 0x1d
318
        .uleb128 0x0
319
        .align  2
320
$LECIE0:
321
$LSFDE0:
322
        .4byte  $LEFDE0-$LASFDE0         # FDE Length
323
$LASFDE0:
324
        .4byte  $LASFDE0-$Lframe0        # FDE CIE offset
325
        .4byte  $LFB0    # FDE initial location
326
        .4byte  $LFE0-$LFB0      # FDE address range
327
        .uleb128 0x0     # Augmentation size
328
        .byte   0x4      # DW_CFA_advance_loc4
329
        .4byte  $LCFI0-$LFB0
330
        .byte   0xe      # DW_CFA_def_cfa_offset
331
        .uleb128 0x18
332
        .byte   0x4      # DW_CFA_advance_loc4
333
        .4byte  $LCFI2-$LCFI0
334
        .byte   0x11     # DW_CFA_offset_extended_sf
335
        .uleb128 0x1e    # $fp
336
        .sleb128 -2      # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp)
337
        .byte   0x11     # DW_CFA_offset_extended_sf
338
        .uleb128 0x1f    # $ra
339
        .sleb128 -1      # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)
340
        .byte   0x4      # DW_CFA_advance_loc4
341
        .4byte  $LCFI3-$LCFI2
342
        .byte   0xc      # DW_CFA_def_cfa
343
        .uleb128 0x1e
344
        .uleb128 0x18
345
        .align  2
346
$LEFDE0:
347
$LSFDE1:
348
        .4byte  $LEFDE1-$LASFDE1         # FDE Length
349
$LASFDE1:
350
        .4byte  $LASFDE1-$Lframe0        # FDE CIE offset
351
        .4byte  $LFB1    # FDE initial location
352
        .4byte  $LFE1-$LFB1      # FDE address range
353
        .uleb128 0x0     # Augmentation size
354
        .byte   0x4      # DW_CFA_advance_loc4
355
        .4byte  $LCFI4-$LFB1
356
        .byte   0xe      # DW_CFA_def_cfa_offset
357
        .uleb128 0x38
358
        .byte   0x4      # DW_CFA_advance_loc4
359
        .4byte  $LCFI6-$LCFI4
360
        .byte   0x11     # DW_CFA_offset_extended_sf
361
        .uleb128 0x10    # $16
362
        .sleb128 -3      # SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp)
363
        .byte   0x11     # DW_CFA_offset_extended_sf
364
        .uleb128 0x1e    # $fp
365
        .sleb128 -2      # SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp)
366
        .byte   0x11     # DW_CFA_offset_extended_sf
367
        .uleb128 0x1f    # $ra
368
        .sleb128 -1      # SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp)
369
        .byte   0x4      # DW_CFA_advance_loc4
370
        .4byte  $LCFI7-$LCFI6
371
        .byte   0xc      # DW_CFA_def_cfa
372
        .uleb128 0x1e
373
        .uleb128 0x38
374
        .align  2
375
$LEFDE1:
376
 
377
#endif

powered by: WebSVN 2.1.0

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