* config/i386/i386.c (ix86_expand_prologue): Tighten assert
[official-gcc.git] / libffi / src / pa / hpux32.S
blob4a47da3791a96d486efaa51aab2189adfb09d4f8
1 /* -----------------------------------------------------------------------
2    hpux32.S - Copyright (c) 2006 Free Software Foundation, Inc.
3                         (c) 2008 Red Hat, Inc.
4                         (c) 2016 John David Anglin
5    based on src/pa/linux.S
7    HP-UX PA Foreign Function Interface
9    Permission is hereby granted, free of charge, to any person obtaining
10    a copy of this software and associated documentation files (the
11    ``Software''), to deal in the Software without restriction, including
12    without limitation the rights to use, copy, modify, merge, publish,
13    distribute, sublicense, and/or sell copies of the Software, and to
14    permit persons to whom the Software is furnished to do so, subject to
15    the following conditions:
17    The above copyright notice and this permission notice shall be included
18    in all copies or substantial portions of the Software.
20    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
21    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
24    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26    OTHER DEALINGS IN THE SOFTWARE.
27    ----------------------------------------------------------------------- */
29 #define LIBFFI_ASM
30 #include <fficonfig.h>
31 #include <ffi.h>
33         .LEVEL 1.1
34         .SPACE  $PRIVATE$
35         .IMPORT $global$,DATA
36         .IMPORT $$dyncall,MILLICODE
37         .SUBSPA $DATA$
38         .align  4
40         /* void ffi_call_pa32(void (*)(char *, extended_cif *),
41                                extended_cif *ecif,
42                                unsigned bytes,
43                                unsigned flags,
44                                unsigned *rvalue,
45                                void (*fn)(void),
46                                ffi_go_closure *closure);
47          */
49         .export ffi_call_pa32,ENTRY,PRIV_LEV=3
50         .import ffi_prep_args_pa32,CODE
52         .SPACE  $TEXT$
53         .SUBSPA $CODE$
54         .align  4
56 L$FB1
57 ffi_call_pa32
58         .proc
59         .callinfo       FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4
60         .entry
61         stw     %rp, -20(%sp)
62         copy    %r3, %r1
63 L$CFI11
64         copy    %sp, %r3
65 L$CFI12
67         /* Setup the stack for calling prep_args...
68            We want the stack to look like this:
70            [ Previous stack                            ] <- %r3
72            [ 64-bytes register save area               ] <- %r4
74            [ Stack space for actual call, passed as    ] <- %arg0
75            [     arg0 to ffi_prep_args_pa32           ]
77            [ Stack for calling prep_args               ] <- %sp
78          */
80         stwm    %r1, 64(%sp)
81         stw     %r4, 12(%r3)
82 L$CFI13
83         copy    %sp, %r4
85         addl    %arg2, %r4, %arg0       ; arg stack
86         stw     %arg3, -48(%r3)         ; save flags we need it later
88         /* Call prep_args:
89            %arg0(stack) -- set up above
90            %arg1(ecif)  -- same as incoming param
91            %arg2(bytes) -- same as incoming param */
92         bl      ffi_prep_args_pa32,%r2
93         ldo     64(%arg0), %sp
94         ldo     -64(%sp), %sp
96         /* now %sp should point where %arg0 was pointing.  */
98         /* Load the arguments that should be passed in registers
99            The fp args are loaded by the prep_args function.  */
100         ldw     -36(%sp), %arg0
101         ldw     -40(%sp), %arg1
102         ldw     -44(%sp), %arg2
103         ldw     -48(%sp), %arg3
105         /* in case the function is going to return a structure
106            we need to give it a place to put the result.  */
107         ldw     -52(%r3), %ret0         ; %ret0 <- rvalue
108         ldw     -56(%r3), %r22          ; %r22 <- function to call
109         ldw     -60(%r3), %ret1         ; %ret1 <- closure
110         bl      $$dyncall, %r31         ; Call the user function
111         copy    %r31, %rp
113         /* Prepare to store the result; we need to recover flags and rvalue.  */
114         ldw     -48(%r3), %r21          ; r21 <- flags
115         ldw     -52(%r3), %r20          ; r20 <- rvalue
117         /* Store the result according to the return type.  The most
118            likely types should come first.  */
120 L$checkint
121         comib,<>,n FFI_TYPE_INT, %r21, L$checkint8
122         b       L$done
123         stw     %ret0, 0(%r20)
125 L$checkint8
126         comib,<>,n FFI_TYPE_UINT8, %r21, L$checkint16
127         b       L$done
128         stb     %ret0, 0(%r20)
130 L$checkint16
131         comib,<>,n FFI_TYPE_UINT16, %r21, L$checkdbl
132         b       L$done
133         sth     %ret0, 0(%r20)
135 L$checkdbl
136         comib,<>,n FFI_TYPE_DOUBLE, %r21, L$checkfloat
137         b       L$done
138         fstd    %fr4,0(%r20)
140 L$checkfloat
141         comib,<>,n FFI_TYPE_FLOAT, %r21, L$checkll
142         b       L$done
143         fstw    %fr4L,0(%r20)
145 L$checkll
146         comib,<>,n FFI_TYPE_UINT64, %r21, L$checksmst2
147         stw     %ret0, 0(%r20)
148         b       L$done
149         stw     %ret1, 4(%r20)
151 L$checksmst2
152         comib,<>,n FFI_TYPE_SMALL_STRUCT2, %r21, L$checksmst3
153         /* 2-byte structs are returned in ret0 as ????xxyy.  */
154         extru   %ret0, 23, 8, %r22
155         stbs,ma %r22, 1(%r20)
156         b       L$done
157         stb     %ret0, 0(%r20)
159 L$checksmst3
160         comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, L$checksmst4
161         /* 3-byte structs are returned in ret0 as ??xxyyzz.  */
162         extru   %ret0, 15, 8, %r22
163         stbs,ma %r22, 1(%r20)
164         extru   %ret0, 23, 8, %r22
165         stbs,ma %r22, 1(%r20)
166         b       L$done
167         stb     %ret0, 0(%r20)
169 L$checksmst4
170         comib,<>,n FFI_TYPE_SMALL_STRUCT4, %r21, L$checksmst5
171         /* 4-byte structs are returned in ret0 as wwxxyyzz.  */
172         extru   %ret0, 7, 8, %r22
173         stbs,ma %r22, 1(%r20)
174         extru   %ret0, 15, 8, %r22
175         stbs,ma %r22, 1(%r20)
176         extru   %ret0, 23, 8, %r22
177         stbs,ma %r22, 1(%r20)
178         b       L$done
179         stb     %ret0, 0(%r20)
181 L$checksmst5
182         comib,<>,n FFI_TYPE_SMALL_STRUCT5, %r21, L$checksmst6
183         /* 5 byte values are returned right justified:
184               ret0     ret1
185            5: ??????aa bbccddee */
186         stbs,ma %ret0, 1(%r20)
187         extru   %ret1, 7, 8, %r22
188         stbs,ma %r22, 1(%r20)
189         extru   %ret1, 15, 8, %r22
190         stbs,ma %r22, 1(%r20)
191         extru   %ret1, 23, 8, %r22
192         stbs,ma %r22, 1(%r20)
193         b       L$done
194         stb     %ret1, 0(%r20)
196 L$checksmst6
197         comib,<>,n FFI_TYPE_SMALL_STRUCT6, %r21, L$checksmst7
198         /* 6 byte values are returned right justified:
199               ret0     ret1
200            6: ????aabb ccddeeff */
201         extru   %ret0, 23, 8, %r22
202         stbs,ma %r22, 1(%r20)
203         stbs,ma %ret0, 1(%r20)
204         extru   %ret1, 7, 8, %r22
205         stbs,ma %r22, 1(%r20)
206         extru   %ret1, 15, 8, %r22
207         stbs,ma %r22, 1(%r20)
208         extru   %ret1, 23, 8, %r22
209         stbs,ma %r22, 1(%r20)
210         b       L$done
211         stb     %ret1, 0(%r20)
213 L$checksmst7
214         comib,<>,n FFI_TYPE_SMALL_STRUCT7, %r21, L$checksmst8
215         /* 7 byte values are returned right justified:
216               ret0     ret1
217            7: ??aabbcc ddeeffgg */
218         extru   %ret0, 15, 8, %r22
219         stbs,ma %r22, 1(%r20)
220         extru   %ret0, 23, 8, %r22
221         stbs,ma %r22, 1(%r20)
222         stbs,ma %ret0, 1(%r20)
223         extru   %ret1, 7, 8, %r22
224         stbs,ma %r22, 1(%r20)
225         extru   %ret1, 15, 8, %r22
226         stbs,ma %r22, 1(%r20)
227         extru   %ret1, 23, 8, %r22
228         stbs,ma %r22, 1(%r20)
229         b       L$done
230         stb     %ret1, 0(%r20)
232 L$checksmst8
233         comib,<>,n FFI_TYPE_SMALL_STRUCT8, %r21, L$done
234         /* 8 byte values are returned right justified:
235               ret0     ret1
236            8: aabbccdd eeffgghh */
237         extru   %ret0, 7, 8, %r22
238         stbs,ma %r22, 1(%r20)
239         extru   %ret0, 15, 8, %r22
240         stbs,ma %r22, 1(%r20)
241         extru   %ret0, 23, 8, %r22
242         stbs,ma %r22, 1(%r20)
243         stbs,ma %ret0, 1(%r20)
244         extru   %ret1, 7, 8, %r22
245         stbs,ma %r22, 1(%r20)
246         extru   %ret1, 15, 8, %r22
247         stbs,ma %r22, 1(%r20)
248         extru   %ret1, 23, 8, %r22
249         stbs,ma %r22, 1(%r20)
250         stb     %ret1, 0(%r20)
252 L$done
253         /* all done, return */
254         copy    %r4, %sp        ; pop arg stack
255         ldw     12(%r3), %r4
256         ldwm    -64(%sp), %r3   ; .. and pop stack
257         ldw     -20(%sp), %rp
258         bv      %r0(%rp)
259         nop
260         .exit
261         .procend
262 L$FE1
264         /* void ffi_closure_pa32(void);
265            Called with closure argument in %r21 */
267         .SPACE $TEXT$
268         .SUBSPA $CODE$
269         .export ffi_closure_pa32,ENTRY,PRIV_LEV=3,RTNVAL=GR
270         .import ffi_closure_inner_pa32,CODE
271         .align 4
272 L$FB2
273 ffi_closure_pa32
274         .proc
275         .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
276         .entry
278         stw     %rp, -20(%sp)
279         copy    %r3, %r1
280 L$CFI21
281         copy    %sp, %r3
282 L$CFI22
283         stwm    %r1, 64(%sp)
285         /* Put arguments onto the stack and call ffi_closure_inner.  */
286         stw     %arg0, -36(%r3)
287         stw     %arg1, -40(%r3)
288         stw     %arg2, -44(%r3)
289         stw     %arg3, -48(%r3)
291         /* Closure type 0.  */
292         copy    %r21, %arg0
293         copy    %r0, %arg2
294         bl      ffi_closure_inner_pa32, %r2
295         copy    %r3, %arg1
296         ldwm    -64(%sp), %r3
297         ldw     -20(%sp), %rp
298         ldw     -36(%sp), %ret0
299         bv      %r0(%rp)
300         ldw     -40(%sp), %ret1
301         .exit
302         .procend
303 L$FE2:
305         /* void ffi_go_closure_pa32(void);
306            Called with closure argument in %ret1 */
308         .SPACE $TEXT$
309         .SUBSPA $CODE$
310         .export ffi_go_closure_pa32,ENTRY,PRIV_LEV=3,RTNVAL=GR
311         .import ffi_closure_inner_pa32,CODE
312         .align 4
313 L$FB3
314 ffi_go_closure_pa32
315         .proc
316         .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
317         .entry
319         stw     %rp, -20(%sp)
320         copy    %r3, %r1
321 L$CFI31
322         copy    %sp, %r3
323 L$CFI32
324         stwm    %r1, 64(%sp)
326         /* Put arguments onto the stack and call ffi_closure_inner.  */
327         stw     %arg0, -36(%r3)
328         stw     %arg1, -40(%r3)
329         stw     %arg2, -44(%r3)
330         stw     %arg3, -48(%r3)
332         /* Closure type 1.  */
333         copy    %ret1, %arg0
334         ldi     1, %arg2
335         bl      ffi_closure_inner_pa32, %r2
336         copy    %r3, %arg1
337         ldwm    -64(%sp), %r3
338         ldw     -20(%sp), %rp
339         ldw     -36(%sp), %ret0
340         bv      %r0(%rp)
341         ldw     -40(%sp), %ret1
342         .exit
343         .procend
344 L$FE3:
346         .SPACE $PRIVATE$
347         .SUBSPA $DATA$
349         .align 4
350         .EXPORT _GLOBAL__F_ffi_call_pa32,DATA
351 _GLOBAL__F_ffi_call_pa32
352 L$frame1:
353         .word   L$ECIE1-L$SCIE1 ;# Length of Common Information Entry
354 L$SCIE1:
355         .word   0x0     ;# CIE Identifier Tag
356         .byte   0x1     ;# CIE Version
357         .ascii "\0"     ;# CIE Augmentation
358         .uleb128 0x1    ;# CIE Code Alignment Factor
359         .sleb128 4      ;# CIE Data Alignment Factor
360         .byte   0x2     ;# CIE RA Column
361         .byte   0xc     ;# DW_CFA_def_cfa
362         .uleb128 0x1e
363         .uleb128 0x0
364         .align 4
365 L$ECIE1:
366 L$SFDE1:
367         .word   L$EFDE1-L$ASFDE1        ;# FDE Length
368 L$ASFDE1:
369         .word   L$ASFDE1-L$frame1       ;# FDE CIE offset
370         .word   L$FB1   ;# FDE initial location
371         .word   L$FE1-L$FB1     ;# FDE address range
373         .byte   0x4     ;# DW_CFA_advance_loc4
374         .word   L$CFI11-L$FB1
375         .byte   0x83    ;# DW_CFA_offset, column 0x3
376         .uleb128 0x0
377         .byte   0x11    ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]
378         .uleb128 0x2
379         .sleb128 -5
381         .byte   0x4     ;# DW_CFA_advance_loc4
382         .word   L$CFI12-L$CFI11
383         .byte   0xd     ;# DW_CFA_def_cfa_register = r3
384         .uleb128 0x3
386         .byte   0x4     ;# DW_CFA_advance_loc4
387         .word   L$CFI13-L$CFI12
388         .byte   0x84    ;# DW_CFA_offset, column 0x4
389         .uleb128 0x3
391         .align 4
392 L$EFDE1:
394 L$SFDE2:
395         .word   L$EFDE2-L$ASFDE2        ;# FDE Length
396 L$ASFDE2:
397         .word   L$ASFDE2-L$frame1       ;# FDE CIE offset
398         .word   L$FB2   ;# FDE initial location
399         .word   L$FE2-L$FB2     ;# FDE address range
400         .byte   0x4     ;# DW_CFA_advance_loc4
401         .word   L$CFI21-L$FB2
402         .byte   0x83    ;# DW_CFA_offset, column 0x3
403         .uleb128 0x0
404         .byte   0x11    ;# DW_CFA_offset_extended_sf
405         .uleb128 0x2
406         .sleb128 -5
408         .byte   0x4     ;# DW_CFA_advance_loc4
409         .word   L$CFI22-L$CFI21
410         .byte   0xd     ;# DW_CFA_def_cfa_register = r3
411         .uleb128 0x3
413         .align 4
414 L$EFDE2:
416 L$SFDE3:
417         .word   L$EFDE3-L$ASFDE3        ;# FDE Length
418 L$ASFDE3:
419         .word   L$ASFDE3-L$frame1       ;# FDE CIE offset
420         .word   L$FB3   ;# FDE initial location
421         .word   L$FE3-L$FB3     ;# FDE address range
422         .byte   0x4     ;# DW_CFA_advance_loc4
423         .word   L$CFI31-L$FB3
424         .byte   0x83    ;# DW_CFA_offset, column 0x3
425         .uleb128 0x0
426         .byte   0x11    ;# DW_CFA_offset_extended_sf
427         .uleb128 0x2
428         .sleb128 -5
430         .byte   0x4     ;# DW_CFA_advance_loc4
431         .word   L$CFI32-L$CFI31
432         .byte   0xd     ;# DW_CFA_def_cfa_register = r3
433         .uleb128 0x3
435         .align 4
436 L$EFDE3: