~ubuntu-branches/ubuntu/raring/gauche-c-wrapper/raring-proposed

« back to all changes in this revision

Viewing changes to libffi/src/pa/linux.S

  • Committer: Bazaar Package Importer
  • Author(s): NIIBE Yutaka
  • Date: 2008-04-07 09:15:03 UTC
  • Revision ID: james.westby@ubuntu.com-20080407091503-wu0h414koe95kj4i
Tags: upstream-0.5.2
ImportĀ upstreamĀ versionĀ 0.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -----------------------------------------------------------------------
 
2
   linux.S - (c) 2003-2004 Randolph Chung <tausq@debian.org>
 
3
 
 
4
   HPPA 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
        .text
 
31
        .level 1.1
 
32
        .align 4
 
33
 
 
34
        /* void ffi_call_LINUX(void (*)(char *, extended_cif *),
 
35
                               extended_cif *ecif,
 
36
                               unsigned bytes,
 
37
                               unsigned flags,
 
38
                               unsigned *rvalue,
 
39
                               void (*fn)());
 
40
         */
 
41
 
 
42
        .export ffi_call_LINUX,code
 
43
        .import ffi_prep_args_LINUX,code
 
44
 
 
45
        .type ffi_call_LINUX, @function
 
46
.LFB1:
 
47
ffi_call_LINUX:
 
48
        .proc
 
49
        .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4
 
50
        .entry
 
51
        stw %rp, -20(%sp)
 
52
        copy %r3, %r1
 
53
.LCFI11:
 
54
 
 
55
        copy %sp, %r3
 
56
.LCFI12:
 
57
 
 
58
        /* Setup the stack for calling prep_args...
 
59
           We want the stack to look like this:
 
60
 
 
61
           [ Previous stack                            ] <- %r3
 
62
 
 
63
           [ 64-bytes register save area               ] <- %r4
 
64
 
 
65
           [ Stack space for actual call, passed as    ] <- %arg0
 
66
           [     arg0 to ffi_prep_args_LINUX           ]
 
67
 
 
68
           [ Stack for calling prep_args               ] <- %sp
 
69
         */
 
70
 
 
71
        stwm %r1, 64(%sp)
 
72
        stw %r4, 12(%r3)
 
73
.LCFI13:
 
74
        copy %sp, %r4
 
75
 
 
76
        addl %arg2, %r4, %arg0                  /* arg stack */
 
77
        stw %arg3, -48(%r3)                     /* save flags; we need it later */
 
78
 
 
79
        /* Call prep_args:
 
80
           %arg0(stack) -- set up above
 
81
           %arg1(ecif) -- same as incoming param
 
82
           %arg2(bytes) -- same as incoming param */
 
83
        bl ffi_prep_args_LINUX,%r2
 
84
        ldo 64(%arg0), %sp
 
85
        ldo -64(%sp), %sp
 
86
 
 
87
        /* now %sp should point where %arg0 was pointing.  */
 
88
 
 
89
        /* Load the arguments that should be passed in registers
 
90
           The fp args were loaded by the prep_args function.  */
 
91
        ldw -36(%sp), %arg0
 
92
        ldw -40(%sp), %arg1
 
93
        ldw -44(%sp), %arg2
 
94
        ldw -48(%sp), %arg3
 
95
 
 
96
        /* in case the function is going to return a structure
 
97
           we need to give it a place to put the result.  */
 
98
        ldw -52(%r3), %ret0                     /* %ret0 <- rvalue */
 
99
        ldw -56(%r3), %r22                      /* %r22 <- function to call */
 
100
        bl $$dyncall, %r31                      /* Call the user function */
 
101
        copy %r31, %rp
 
102
 
 
103
        /* Prepare to store the result; we need to recover flags and rvalue.  */
 
104
        ldw -48(%r3), %r21                      /* r21 <- flags */
 
105
        ldw -52(%r3), %r20                      /* r20 <- rvalue */
 
106
 
 
107
        /* Store the result according to the return type.  */
 
108
 
 
109
checksmst3:
 
110
        comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, checksmst567
 
111
        /* 3-byte structs are returned in ret0 as ??xxyyzz.  Shift
 
112
           left 8 bits to write to the result structure.  */
 
113
        zdep %ret0, 23, 24, %r22
 
114
        b done
 
115
        stw %r22, 0(%r20)
 
116
 
 
117
checksmst567:
 
118
        /* 5-7 byte values are returned right justified:
 
119
              ret0     ret1
 
120
           5: ??????aa bbccddee
 
121
           6: ????aabb ccddeeff
 
122
           7: ??aabbcc ddeeffgg
 
123
 
 
124
           To store this in the result, write the first 4 bytes into a temp
 
125
           register using shrpw (t1 = aabbccdd), followed by a rotation of
 
126
           ret1:
 
127
 
 
128
              ret0     ret1        ret1
 
129
           5: ??????aa bbccddee -> eebbccdd (rotate 8)
 
130
           6: ????aabb ccddeeff -> eeffccdd (rotate 16)
 
131
           7: ??aabbcc ddeeffgg -> eeffggdd (rotate 24)
 
132
 
 
133
           then we write (t1, ret1) into the result.  */
 
134
 
 
135
        addi,<> -FFI_TYPE_SMALL_STRUCT5,%r21,%r0
 
136
        ldi 8, %r22
 
137
        addi,<> -FFI_TYPE_SMALL_STRUCT6,%r21,%r0
 
138
        ldi 16, %r22
 
139
        addi,<> -FFI_TYPE_SMALL_STRUCT7,%r21,%r0
 
140
        ldi 24, %r22
 
141
 
 
142
        /* This relies on all the FFI_TYPE_*_STRUCT* defines being <0 */
 
143
        cmpib,<=,n 0, %r21, checkint8
 
144
        mtsar %r22
 
145
 
 
146
        shrpw %ret0, %ret1, %sar, %ret0  /* ret0 = aabbccdd */
 
147
        shrpw %ret1, %ret1, %sar, %ret1  /* rotate ret1 */
 
148
        
 
149
        stw %ret0, 0(%r20)
 
150
        b done
 
151
        stw %ret1, 4(%r20)
 
152
 
 
153
checkint8:
 
154
        comib,<>,n FFI_TYPE_UINT8, %r21, checkint16
 
155
        b done
 
156
        stb %ret0, 0(%r20)
 
157
 
 
158
checkint16:
 
159
        comib,<>,n FFI_TYPE_UINT16, %r21, checkint32
 
160
        b done
 
161
        sth %ret0, 0(%r20)
 
162
 
 
163
checkint32:
 
164
        comib,<>,n FFI_TYPE_UINT32, %r21, checkint
 
165
        b done
 
166
        stw %ret0, 0(%r20)
 
167
 
 
168
checkint:
 
169
        comib,<>,n FFI_TYPE_INT, %r21, checkll
 
170
        b done
 
171
        stw %ret0, 0(%r20)
 
172
 
 
173
checkll:
 
174
        comib,<>,n FFI_TYPE_UINT64, %r21, checkdbl
 
175
        stw %ret0, 0(%r20)
 
176
        b done
 
177
        stw %ret1, 4(%r20)
 
178
 
 
179
checkdbl:
 
180
        comib,<>,n FFI_TYPE_DOUBLE, %r21, checkfloat
 
181
        b done
 
182
        fstd %fr4,0(%r20)
 
183
 
 
184
checkfloat:
 
185
        comib,<>,n FFI_TYPE_FLOAT, %r21, done
 
186
        fstw %fr4L,0(%r20)
 
187
 
 
188
        /* structure returns are either handled by one of the
 
189
           INT/UINT64 cases above, or, if passed by pointer,
 
190
           is handled by the callee.  */
 
191
 
 
192
done:
 
193
        /* all done, return */
 
194
        copy %r4, %sp                           /* pop arg stack */
 
195
        ldw 12(%r3), %r4
 
196
        ldwm -64(%sp), %r3                      /* .. and pop stack */
 
197
        ldw -20(%sp), %rp
 
198
        bv %r0(%rp)
 
199
        nop
 
200
        .exit
 
201
        .procend
 
202
.LFE1:
 
203
 
 
204
        /* void ffi_closure_LINUX(void);
 
205
           Called with closure argument in %r21 */
 
206
        .export ffi_closure_LINUX,code
 
207
        .import ffi_closure_inner_LINUX,code
 
208
 
 
209
        .type ffi_closure_LINUX, @function
 
210
.LFB2:
 
211
ffi_closure_LINUX:
 
212
        .proc
 
213
        .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
 
214
        .entry
 
215
 
 
216
        stw %rp, -20(%sp)
 
217
.LCFI20:
 
218
        copy %r3, %r1
 
219
.LCFI21:
 
220
        copy %sp, %r3
 
221
.LCFI22:
 
222
        stwm %r1, 64(%sp)
 
223
 
 
224
        /* Put arguments onto the stack and call ffi_closure_inner.  */
 
225
        stw %arg0, -36(%r3)
 
226
        stw %arg1, -40(%r3)
 
227
        stw %arg2, -44(%r3)
 
228
        stw %arg3, -48(%r3)
 
229
 
 
230
        copy %r21, %arg0
 
231
        bl ffi_closure_inner_LINUX, %r2
 
232
        copy %r3, %arg1
 
233
 
 
234
        ldwm -64(%sp), %r3
 
235
        ldw -20(%sp), %rp
 
236
        ldw -36(%sp), %ret0
 
237
        bv %r0(%r2)
 
238
        ldw -40(%sp), %ret1
 
239
 
 
240
        .exit
 
241
        .procend
 
242
.LFE2:
 
243
 
 
244
        .section        ".eh_frame",EH_FRAME_FLAGS,@progbits
 
245
.Lframe1:
 
246
        .word   .LECIE1-.LSCIE1 ;# Length of Common Information Entry
 
247
.LSCIE1:
 
248
        .word   0x0     ;# CIE Identifier Tag
 
249
        .byte   0x1     ;# CIE Version
 
250
        .ascii "\0"     ;# CIE Augmentation
 
251
        .uleb128 0x1    ;# CIE Code Alignment Factor
 
252
        .sleb128 4      ;# CIE Data Alignment Factor
 
253
        .byte   0x2     ;# CIE RA Column
 
254
        .byte   0xc     ;# DW_CFA_def_cfa
 
255
        .uleb128 0x1e
 
256
        .uleb128 0x0
 
257
        .align 4
 
258
.LECIE1:
 
259
.LSFDE1:
 
260
        .word   .LEFDE1-.LASFDE1        ;# FDE Length
 
261
.LASFDE1:
 
262
        .word   .LASFDE1-.Lframe1       ;# FDE CIE offset
 
263
        .word   .LFB1   ;# FDE initial location
 
264
        .word   .LFE1-.LFB1     ;# FDE address range
 
265
 
 
266
        .byte   0x4     ;# DW_CFA_advance_loc4
 
267
        .word   .LCFI11-.LFB1
 
268
        .byte   0x83    ;# DW_CFA_offset, column 0x3
 
269
        .uleb128 0x0
 
270
        .byte   0x11    ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]
 
271
        .uleb128 0x2
 
272
        .sleb128 -5
 
273
 
 
274
        .byte   0x4     ;# DW_CFA_advance_loc4
 
275
        .word   .LCFI12-.LCFI11
 
276
        .byte   0xd     ;# DW_CFA_def_cfa_register = r3
 
277
        .uleb128 0x3
 
278
 
 
279
        .byte   0x4     ;# DW_CFA_advance_loc4
 
280
        .word   .LCFI13-.LCFI12
 
281
        .byte   0x84    ;# DW_CFA_offset, column 0x4
 
282
        .uleb128 0x3
 
283
 
 
284
        .align 4
 
285
.LEFDE1:
 
286
 
 
287
.LSFDE2:
 
288
        .word   .LEFDE2-.LASFDE2        ;# FDE Length
 
289
.LASFDE2:
 
290
        .word   .LASFDE2-.Lframe1       ;# FDE CIE offset
 
291
        .word   .LFB2   ;# FDE initial location
 
292
        .word   .LFE2-.LFB2     ;# FDE address range
 
293
        .byte   0x4     ;# DW_CFA_advance_loc4
 
294
        .word   .LCFI21-.LFB2
 
295
        .byte   0x83    ;# DW_CFA_offset, column 0x3
 
296
        .uleb128 0x0
 
297
        .byte   0x11    ;# DW_CFA_offset_extended_sf
 
298
        .uleb128 0x2
 
299
        .sleb128 -5
 
300
 
 
301
        .byte   0x4     ;# DW_CFA_advance_loc4
 
302
        .word   .LCFI12-.LCFI11
 
303
        .byte   0xd     ;# DW_CFA_def_cfa_register = r3
 
304
        .uleb128 0x3
 
305
 
 
306
        .align 4
 
307
.LEFDE2: