github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/third_party/gofrontend/libffi/src/pa/linux.S (about)

     1  /* -----------------------------------------------------------------------
     2     linux.S - (c) 2003-2004 Randolph Chung <tausq@debian.org>
     3  	     (c) 2008 Red Hat, Inc.
     4  
     5     HPPA Foreign Function Interface
     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 RENESAS TECHNOLOGY 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  #include <fficonfig.h>
    29  #include <ffi.h>
    30  
    31  	.text
    32  	.level 1.1
    33  	.align 4
    34  
    35  	/* void ffi_call_pa32(void (*)(char *, extended_cif *),
    36  			       extended_cif *ecif,
    37  			       unsigned bytes,
    38  			       unsigned flags,
    39  			       unsigned *rvalue,
    40  			       void (*fn)(void));
    41  	 */
    42  
    43  	.export ffi_call_pa32,code
    44  	.import ffi_prep_args_pa32,code
    45  
    46  	.type ffi_call_pa32, @function
    47  .LFB1:
    48  ffi_call_pa32:
    49  	.proc
    50  	.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4
    51  	.entry
    52  	stw %rp, -20(%sp)
    53  	copy %r3, %r1
    54  .LCFI11:
    55  
    56  	copy %sp, %r3
    57  .LCFI12:
    58  
    59  	/* Setup the stack for calling prep_args...
    60  	   We want the stack to look like this:
    61  
    62  	   [ Previous stack                            ] <- %r3
    63  
    64  	   [ 64-bytes register save area               ] <- %r4
    65  
    66  	   [ Stack space for actual call, passed as    ] <- %arg0
    67  	   [     arg0 to ffi_prep_args_pa32           ]
    68  
    69  	   [ Stack for calling prep_args               ] <- %sp
    70  	 */
    71  
    72  	stwm %r1, 64(%sp)
    73  	stw %r4, 12(%r3)
    74  .LCFI13:
    75  	copy %sp, %r4
    76  
    77  	addl %arg2, %r4, %arg0      /* arg stack */
    78  	stw %arg3, -48(%r3)         /* save flags; we need it later */
    79  
    80  	/* Call prep_args:
    81  	   %arg0(stack) -- set up above
    82  	   %arg1(ecif) -- same as incoming param
    83  	   %arg2(bytes) -- same as incoming param */
    84  	bl ffi_prep_args_pa32,%r2
    85  	ldo 64(%arg0), %sp
    86  	ldo -64(%sp), %sp
    87  
    88  	/* now %sp should point where %arg0 was pointing.  */
    89  
    90  	/* Load the arguments that should be passed in registers
    91  	   The fp args were loaded by the prep_args function.  */
    92  	ldw -36(%sp), %arg0
    93  	ldw -40(%sp), %arg1
    94  	ldw -44(%sp), %arg2
    95  	ldw -48(%sp), %arg3
    96  
    97  	/* in case the function is going to return a structure
    98  	   we need to give it a place to put the result.  */
    99  	ldw -52(%r3), %ret0                     /* %ret0 <- rvalue */
   100  	ldw -56(%r3), %r22                      /* %r22 <- function to call */
   101  	bl $$dyncall, %r31                      /* Call the user function */
   102  	copy %r31, %rp
   103  
   104  	/* Prepare to store the result; we need to recover flags and rvalue.  */
   105  	ldw -48(%r3), %r21                      /* r21 <- flags */
   106  	ldw -52(%r3), %r20                      /* r20 <- rvalue */
   107  
   108  	/* Store the result according to the return type.  */
   109  
   110  .Lcheckint:
   111  	comib,<>,n FFI_TYPE_INT, %r21, .Lcheckint8
   112  	b	.Ldone
   113  	stw	%ret0, 0(%r20)
   114  
   115  .Lcheckint8:
   116  	comib,<>,n FFI_TYPE_UINT8, %r21, .Lcheckint16
   117  	b	.Ldone
   118  	stb	%ret0, 0(%r20)
   119  
   120  .Lcheckint16:
   121  	comib,<>,n FFI_TYPE_UINT16, %r21, .Lcheckdbl
   122  	b	.Ldone
   123  	sth	%ret0, 0(%r20)
   124  
   125  .Lcheckdbl:
   126  	comib,<>,n FFI_TYPE_DOUBLE, %r21, .Lcheckfloat
   127  	b	.Ldone
   128  	fstd	%fr4,0(%r20)
   129  
   130  .Lcheckfloat:
   131  	comib,<>,n FFI_TYPE_FLOAT, %r21, .Lcheckll
   132  	b	.Ldone
   133  	fstw	%fr4L,0(%r20)
   134  
   135  .Lcheckll:
   136  	comib,<>,n FFI_TYPE_UINT64, %r21, .Lchecksmst2
   137  	stw	%ret0, 0(%r20)
   138  	b	.Ldone
   139  	stw	%ret1, 4(%r20)
   140  
   141  .Lchecksmst2:
   142  	comib,<>,n FFI_TYPE_SMALL_STRUCT2, %r21, .Lchecksmst3
   143  	/* 2-byte structs are returned in ret0 as ????xxyy.  */
   144  	extru	%ret0, 23, 8, %r22
   145  	stbs,ma	%r22, 1(%r20)
   146  	b	.Ldone
   147  	stb	%ret0, 0(%r20)
   148  
   149  .Lchecksmst3:
   150  	comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, .Lchecksmst4
   151  	/* 3-byte structs are returned in ret0 as ??xxyyzz.  */
   152  	extru	%ret0, 15, 8, %r22
   153  	stbs,ma	%r22, 1(%r20)
   154  	extru	%ret0, 23, 8, %r22
   155  	stbs,ma	%r22, 1(%r20)
   156  	b	.Ldone
   157  	stb	%ret0, 0(%r20)
   158  
   159  .Lchecksmst4:
   160  	comib,<>,n FFI_TYPE_SMALL_STRUCT4, %r21, .Lchecksmst5
   161  	/* 4-byte structs are returned in ret0 as wwxxyyzz.  */
   162  	extru	%ret0, 7, 8, %r22
   163  	stbs,ma	%r22, 1(%r20)
   164  	extru	%ret0, 15, 8, %r22
   165  	stbs,ma	%r22, 1(%r20)
   166  	extru	%ret0, 23, 8, %r22
   167  	stbs,ma	%r22, 1(%r20)
   168  	b	.Ldone
   169  	stb	%ret0, 0(%r20)
   170  
   171  .Lchecksmst5:
   172  	comib,<>,n FFI_TYPE_SMALL_STRUCT5, %r21, .Lchecksmst6
   173  	/* 5 byte values are returned right justified:
   174  	      ret0     ret1
   175  	   5: ??????aa bbccddee */
   176  	stbs,ma	%ret0, 1(%r20)
   177  	extru	%ret1, 7, 8, %r22
   178  	stbs,ma	%r22, 1(%r20)
   179  	extru	%ret1, 15, 8, %r22
   180  	stbs,ma	%r22, 1(%r20)
   181  	extru	%ret1, 23, 8, %r22
   182  	stbs,ma	%r22, 1(%r20)
   183  	b	.Ldone
   184  	stb	%ret1, 0(%r20)
   185  
   186  .Lchecksmst6:
   187  	comib,<>,n FFI_TYPE_SMALL_STRUCT6, %r21, .Lchecksmst7
   188  	/* 6 byte values are returned right justified:
   189  	      ret0     ret1
   190  	   6: ????aabb ccddeeff */
   191  	extru	%ret0, 23, 8, %r22
   192  	stbs,ma	%r22, 1(%r20)
   193  	stbs,ma	%ret0, 1(%r20)
   194  	extru	%ret1, 7, 8, %r22
   195  	stbs,ma	%r22, 1(%r20)
   196  	extru	%ret1, 15, 8, %r22
   197  	stbs,ma	%r22, 1(%r20)
   198  	extru	%ret1, 23, 8, %r22
   199  	stbs,ma	%r22, 1(%r20)
   200  	b	.Ldone
   201  	stb	%ret1, 0(%r20)
   202  
   203  .Lchecksmst7:
   204  	comib,<>,n FFI_TYPE_SMALL_STRUCT7, %r21, .Lchecksmst8
   205  	/* 7 byte values are returned right justified:
   206  	      ret0     ret1
   207  	   7: ??aabbcc ddeeffgg */
   208  	extru	%ret0, 15, 8, %r22
   209  	stbs,ma	%r22, 1(%r20)
   210  	extru	%ret0, 23, 8, %r22
   211  	stbs,ma	%r22, 1(%r20)
   212  	stbs,ma	%ret0, 1(%r20)
   213  	extru	%ret1, 7, 8, %r22
   214  	stbs,ma	%r22, 1(%r20)
   215  	extru	%ret1, 15, 8, %r22
   216  	stbs,ma	%r22, 1(%r20)
   217  	extru	%ret1, 23, 8, %r22
   218  	stbs,ma	%r22, 1(%r20)
   219  	b	.Ldone
   220  	stb	%ret1, 0(%r20)
   221  
   222  .Lchecksmst8:
   223  	comib,<>,n FFI_TYPE_SMALL_STRUCT8, %r21, .Ldone
   224  	/* 8 byte values are returned right justified:
   225  	      ret0     ret1
   226  	   8: aabbccdd eeffgghh */
   227  	extru	%ret0, 7, 8, %r22
   228  	stbs,ma	%r22, 1(%r20)
   229  	extru	%ret0, 15, 8, %r22
   230  	stbs,ma	%r22, 1(%r20)
   231  	extru	%ret0, 23, 8, %r22
   232  	stbs,ma	%r22, 1(%r20)
   233  	stbs,ma	%ret0, 1(%r20)
   234  	extru	%ret1, 7, 8, %r22
   235  	stbs,ma	%r22, 1(%r20)
   236  	extru	%ret1, 15, 8, %r22
   237  	stbs,ma	%r22, 1(%r20)
   238  	extru	%ret1, 23, 8, %r22
   239  	stbs,ma	%r22, 1(%r20)
   240  	stb	%ret1, 0(%r20)
   241  
   242  .Ldone:
   243  	/* all done, return */
   244  	copy %r4, %sp                           /* pop arg stack */
   245  	ldw 12(%r3), %r4
   246  	ldwm -64(%sp), %r3                      /* .. and pop stack */
   247  	ldw -20(%sp), %rp
   248  	bv %r0(%rp)
   249  	nop
   250  	.exit
   251  	.procend
   252  .LFE1:
   253  
   254  	/* void ffi_closure_pa32(void);
   255  	   Called with closure argument in %r21 */
   256  	.export ffi_closure_pa32,code
   257  	.import ffi_closure_inner_pa32,code
   258  
   259  	.type ffi_closure_pa32, @function
   260  .LFB2:
   261  ffi_closure_pa32:
   262  	.proc
   263  	.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
   264  	.entry
   265  
   266  	stw %rp, -20(%sp)
   267  .LCFI20:
   268  	copy %r3, %r1
   269  .LCFI21:
   270  	copy %sp, %r3
   271  .LCFI22:
   272  	stwm %r1, 64(%sp)
   273  
   274  	/* Put arguments onto the stack and call ffi_closure_inner.  */
   275  	stw %arg0, -36(%r3)
   276  	stw %arg1, -40(%r3)
   277  	stw %arg2, -44(%r3)
   278  	stw %arg3, -48(%r3)
   279  
   280  	copy %r21, %arg0
   281  	bl ffi_closure_inner_pa32, %r2
   282  	copy %r3, %arg1
   283  
   284  	ldwm -64(%sp), %r3
   285  	ldw -20(%sp), %rp
   286  	ldw -36(%sp), %ret0
   287  	bv %r0(%r2)
   288  	ldw -40(%sp), %ret1
   289  
   290  	.exit
   291  	.procend
   292  .LFE2:
   293  
   294  	.section        ".eh_frame",EH_FRAME_FLAGS,@progbits
   295  .Lframe1:
   296  	.word   .LECIE1-.LSCIE1 ;# Length of Common Information Entry
   297  .LSCIE1:
   298  	.word   0x0     ;# CIE Identifier Tag
   299  	.byte   0x1     ;# CIE Version
   300  	.ascii "\0"     ;# CIE Augmentation
   301  	.uleb128 0x1    ;# CIE Code Alignment Factor
   302  	.sleb128 4      ;# CIE Data Alignment Factor
   303  	.byte   0x2     ;# CIE RA Column
   304  	.byte   0xc     ;# DW_CFA_def_cfa
   305  	.uleb128 0x1e
   306  	.uleb128 0x0
   307  	.align 4
   308  .LECIE1:
   309  .LSFDE1:
   310  	.word   .LEFDE1-.LASFDE1        ;# FDE Length
   311  .LASFDE1:
   312  	.word   .LASFDE1-.Lframe1       ;# FDE CIE offset
   313  	.word   .LFB1   ;# FDE initial location
   314  	.word   .LFE1-.LFB1     ;# FDE address range
   315  
   316  	.byte   0x4     ;# DW_CFA_advance_loc4
   317  	.word   .LCFI11-.LFB1
   318  	.byte	0x83	;# DW_CFA_offset, column 0x3
   319  	.uleb128 0x0
   320  	.byte   0x11    ;# DW_CFA_offset_extended_sf; save r2 at [r30-20]
   321  	.uleb128 0x2
   322  	.sleb128 -5
   323  
   324  	.byte   0x4     ;# DW_CFA_advance_loc4
   325  	.word   .LCFI12-.LCFI11
   326  	.byte   0xd     ;# DW_CFA_def_cfa_register = r3
   327  	.uleb128 0x3
   328  
   329  	.byte   0x4     ;# DW_CFA_advance_loc4
   330  	.word   .LCFI13-.LCFI12
   331  	.byte	0x84	;# DW_CFA_offset, column 0x4
   332  	.uleb128 0x3
   333  
   334  	.align 4
   335  .LEFDE1:
   336  
   337  .LSFDE2:
   338  	.word   .LEFDE2-.LASFDE2        ;# FDE Length
   339  .LASFDE2:
   340  	.word   .LASFDE2-.Lframe1       ;# FDE CIE offset
   341  	.word   .LFB2   ;# FDE initial location
   342  	.word   .LFE2-.LFB2     ;# FDE address range
   343  	.byte   0x4     ;# DW_CFA_advance_loc4
   344  	.word   .LCFI21-.LFB2
   345  	.byte   0x83    ;# DW_CFA_offset, column 0x3
   346  	.uleb128 0x0
   347  	.byte   0x11    ;# DW_CFA_offset_extended_sf
   348  	.uleb128 0x2
   349  	.sleb128 -5
   350  
   351  	.byte   0x4     ;# DW_CFA_advance_loc4
   352  	.word   .LCFI22-.LCFI21
   353  	.byte   0xd     ;# DW_CFA_def_cfa_register = r3
   354  	.uleb128 0x3
   355  
   356  	.align 4
   357  .LEFDE2: