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

     1  /* -----------------------------------------------------------------------
     2     unix.S - Copyright (c) 1998, 2008 Red Hat, Inc.
     3              Copyright (c) 2000 Hewlett Packard Company
     4     
     5     IA64/unix Foreign Function Interface 
     6  
     7     Primary author: Hans Boehm, HP Labs
     8  
     9     Loosely modeled on Cygnus code for other platforms.
    10  
    11     Permission is hereby granted, free of charge, to any person obtaining
    12     a copy of this software and associated documentation files (the
    13     ``Software''), to deal in the Software without restriction, including
    14     without limitation the rights to use, copy, modify, merge, publish,
    15     distribute, sublicense, and/or sell copies of the Software, and to
    16     permit persons to whom the Software is furnished to do so, subject to
    17     the following conditions:
    18  
    19     The above copyright notice and this permission notice shall be included
    20     in all copies or substantial portions of the Software.
    21  
    22     THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
    23     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    24     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    25     NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    26     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    27     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    29     DEALINGS IN THE SOFTWARE.
    30     ----------------------------------------------------------------------- */
    31  
    32  #define LIBFFI_ASM	
    33  #include <fficonfig.h>
    34  #include <ffi.h>
    35  #include "ia64_flags.h"
    36  
    37  	.pred.safe_across_calls p1-p5,p16-p63
    38  .text
    39  
    40  /* int ffi_call_unix (struct ia64_args *stack, PTR64 rvalue,
    41  		      void (*fn)(void), int flags);
    42   */
    43  
    44          .align 16
    45          .global	ffi_call_unix
    46          .proc	ffi_call_unix
    47  ffi_call_unix:
    48  	.prologue
    49  	/* Bit o trickiness.  We actually share a stack frame with ffi_call.
    50  	   Rely on the fact that ffi_call uses a vframe and don't bother
    51  	   tracking one here at all.  */
    52  	.fframe	0
    53  	.save	ar.pfs, r36 // loc0
    54  	alloc   loc0 = ar.pfs, 4, 3, 8, 0
    55  	.save	rp, loc1
    56  	mov 	loc1 = b0
    57  	.body
    58  	add	r16 = 16, in0
    59  	mov	loc2 = gp
    60  	mov	r8 = in1
    61  	;;
    62  
    63  	/* Load up all of the argument registers.  */
    64  	ldf.fill f8 = [in0], 32
    65  	ldf.fill f9 = [r16], 32
    66  	;;
    67  	ldf.fill f10 = [in0], 32
    68  	ldf.fill f11 = [r16], 32
    69  	;;
    70  	ldf.fill f12 = [in0], 32
    71  	ldf.fill f13 = [r16], 32
    72  	;;
    73  	ldf.fill f14 = [in0], 32
    74  	ldf.fill f15 = [r16], 24
    75  	;;
    76  	ld8	out0 = [in0], 16
    77  	ld8	out1 = [r16], 16
    78  	;;
    79  	ld8	out2 = [in0], 16
    80  	ld8	out3 = [r16], 16
    81  	;;
    82  	ld8	out4 = [in0], 16
    83  	ld8	out5 = [r16], 16
    84  	;;
    85  	ld8	out6 = [in0]
    86  	ld8	out7 = [r16]
    87  	;;
    88  
    89  	/* Deallocate the register save area from the stack frame.  */
    90  	mov	sp = in0
    91  
    92  	/* Call the target function.  */
    93  	ld8	r16 = [in2], 8
    94  	;;
    95  	ld8	gp = [in2]
    96  	mov	b6 = r16
    97  	br.call.sptk.many b0 = b6
    98  	;;
    99  
   100  	/* Dispatch to handle return value.  */
   101  	mov	gp = loc2
   102  	zxt1	r16 = in3
   103  	;;
   104  	mov	ar.pfs = loc0
   105  	addl	r18 = @ltoffx(.Lst_table), gp
   106  	;;
   107  	ld8.mov	r18 = [r18], .Lst_table
   108  	mov	b0 = loc1
   109  	;;
   110  	shladd	r18 = r16, 3, r18
   111  	;;
   112  	ld8	r17 = [r18]
   113  	shr	in3 = in3, 8
   114  	;;
   115  	add	r17 = r17, r18
   116  	;;
   117  	mov	b6 = r17
   118  	br	b6
   119  	;;
   120  
   121  .Lst_void:
   122  	br.ret.sptk.many b0
   123  	;;
   124  .Lst_uint8:
   125  	zxt1	r8 = r8
   126  	;;
   127  	st8	[in1] = r8
   128  	br.ret.sptk.many b0
   129  	;;
   130  .Lst_sint8:
   131  	sxt1	r8 = r8
   132  	;;
   133  	st8	[in1] = r8
   134  	br.ret.sptk.many b0
   135  	;;
   136  .Lst_uint16:
   137  	zxt2	r8 = r8
   138  	;;
   139  	st8	[in1] = r8
   140  	br.ret.sptk.many b0
   141  	;;
   142  .Lst_sint16:
   143  	sxt2	r8 = r8
   144  	;;
   145  	st8	[in1] = r8
   146  	br.ret.sptk.many b0
   147  	;;
   148  .Lst_uint32:
   149  	zxt4	r8 = r8
   150  	;;
   151  	st8	[in1] = r8
   152  	br.ret.sptk.many b0
   153  	;;
   154  .Lst_sint32:
   155  	sxt4	r8 = r8
   156  	;;
   157  	st8	[in1] = r8
   158  	br.ret.sptk.many b0
   159  	;;
   160  .Lst_int64:
   161  	st8	[in1] = r8
   162  	br.ret.sptk.many b0
   163  	;;
   164  .Lst_float:
   165  	stfs	[in1] = f8
   166  	br.ret.sptk.many b0
   167  	;;
   168  .Lst_double:
   169  	stfd	[in1] = f8
   170  	br.ret.sptk.many b0
   171  	;;
   172  .Lst_ldouble:
   173  	stfe	[in1] = f8
   174  	br.ret.sptk.many b0
   175  	;;
   176  
   177  .Lst_small_struct:
   178  	add	sp = -16, sp
   179  	cmp.lt	p6, p0 = 8, in3
   180  	cmp.lt	p7, p0 = 16, in3
   181  	cmp.lt	p8, p0 = 24, in3
   182  	;;
   183  	add	r16 = 8, sp
   184  	add	r17 = 16, sp
   185  	add	r18 = 24, sp
   186  	;;
   187  	st8	[sp] = r8
   188  (p6)	st8	[r16] = r9
   189  	mov	out0 = in1
   190  (p7)	st8	[r17] = r10
   191  (p8)	st8	[r18] = r11
   192  	mov	out1 = sp
   193  	mov	out2 = in3
   194  	br.call.sptk.many b0 = memcpy#
   195  	;;
   196  	mov	ar.pfs = loc0
   197  	mov	b0 = loc1
   198  	mov	gp = loc2
   199  	br.ret.sptk.many b0
   200  
   201  .Lst_hfa_float:
   202  	add	r16 = 4, in1
   203  	cmp.lt	p6, p0 = 4, in3
   204  	;;
   205  	stfs	[in1] = f8, 8
   206  (p6)	stfs	[r16] = f9, 8
   207  	cmp.lt	p7, p0 = 8, in3
   208  	cmp.lt	p8, p0 = 12, in3
   209  	;;
   210  (p7)	stfs	[in1] = f10, 8
   211  (p8)	stfs	[r16] = f11, 8
   212  	cmp.lt	p9, p0 = 16, in3
   213  	cmp.lt	p10, p0 = 20, in3
   214  	;;
   215  (p9)	stfs	[in1] = f12, 8
   216  (p10)	stfs	[r16] = f13, 8
   217  	cmp.lt	p6, p0 = 24, in3
   218  	cmp.lt	p7, p0 = 28, in3
   219  	;;
   220  (p6)	stfs	[in1] = f14
   221  (p7)	stfs	[r16] = f15
   222  	br.ret.sptk.many b0
   223  	;;
   224  
   225  .Lst_hfa_double:
   226  	add	r16 = 8, in1
   227  	cmp.lt	p6, p0 = 8, in3
   228  	;;
   229  	stfd	[in1] = f8, 16
   230  (p6)	stfd	[r16] = f9, 16
   231  	cmp.lt	p7, p0 = 16, in3
   232  	cmp.lt	p8, p0 = 24, in3
   233  	;;
   234  (p7)	stfd	[in1] = f10, 16
   235  (p8)	stfd	[r16] = f11, 16
   236  	cmp.lt	p9, p0 = 32, in3
   237  	cmp.lt	p10, p0 = 40, in3
   238  	;;
   239  (p9)	stfd	[in1] = f12, 16
   240  (p10)	stfd	[r16] = f13, 16
   241  	cmp.lt	p6, p0 = 48, in3
   242  	cmp.lt	p7, p0 = 56, in3
   243  	;;
   244  (p6)	stfd	[in1] = f14
   245  (p7)	stfd	[r16] = f15
   246  	br.ret.sptk.many b0
   247  	;;
   248  
   249  .Lst_hfa_ldouble:
   250  	add	r16 = 16, in1
   251  	cmp.lt	p6, p0 = 16, in3
   252  	;;
   253  	stfe	[in1] = f8, 32
   254  (p6)	stfe	[r16] = f9, 32
   255  	cmp.lt	p7, p0 = 32, in3
   256  	cmp.lt	p8, p0 = 48, in3
   257  	;;
   258  (p7)	stfe	[in1] = f10, 32
   259  (p8)	stfe	[r16] = f11, 32
   260  	cmp.lt	p9, p0 = 64, in3
   261  	cmp.lt	p10, p0 = 80, in3
   262  	;;
   263  (p9)	stfe	[in1] = f12, 32
   264  (p10)	stfe	[r16] = f13, 32
   265  	cmp.lt	p6, p0 = 96, in3
   266  	cmp.lt	p7, p0 = 112, in3
   267  	;;
   268  (p6)	stfe	[in1] = f14
   269  (p7)	stfe	[r16] = f15
   270  	br.ret.sptk.many b0
   271  	;;
   272  
   273          .endp ffi_call_unix
   274  
   275          .align 16
   276          .global ffi_closure_unix
   277          .proc ffi_closure_unix
   278  
   279  #define FRAME_SIZE	(8*16 + 8*8 + 8*16)
   280  
   281  ffi_closure_unix:
   282  	.prologue
   283  	.save	ar.pfs, r40 // loc0
   284  	alloc   loc0 = ar.pfs, 8, 4, 4, 0
   285  	.fframe	FRAME_SIZE
   286  	add	r12 = -FRAME_SIZE, r12
   287  	.save	rp, loc1
   288  	mov	loc1 = b0
   289  	.save	ar.unat, loc2
   290  	mov	loc2 = ar.unat
   291  	.body
   292  
   293  	/* Retrieve closure pointer and real gp.  */
   294  #ifdef _ILP32
   295  	addp4	out0 = 0, gp
   296  	addp4	gp = 16, gp
   297  #else
   298  	mov	out0 = gp
   299  	add	gp = 16, gp
   300  #endif
   301  	;;
   302  	ld8	gp = [gp]
   303  
   304  	/* Spill all of the possible argument registers.  */
   305  	add	r16 = 16 + 8*16, sp
   306  	add	r17 = 16 + 8*16 + 16, sp
   307  	;;
   308  	stf.spill [r16] = f8, 32
   309  	stf.spill [r17] = f9, 32
   310  	mov	loc3 = gp
   311  	;;
   312  	stf.spill [r16] = f10, 32
   313  	stf.spill [r17] = f11, 32
   314  	;;
   315  	stf.spill [r16] = f12, 32
   316  	stf.spill [r17] = f13, 32
   317  	;;
   318  	stf.spill [r16] = f14, 32
   319  	stf.spill [r17] = f15, 24
   320  	;;
   321  	.mem.offset 0, 0
   322  	st8.spill [r16] = in0, 16
   323  	.mem.offset 8, 0
   324  	st8.spill [r17] = in1, 16
   325  	add	out1 = 16 + 8*16, sp
   326  	;;
   327  	.mem.offset 0, 0
   328  	st8.spill [r16] = in2, 16
   329  	.mem.offset 8, 0
   330  	st8.spill [r17] = in3, 16
   331  	add	out2 = 16, sp
   332  	;;
   333  	.mem.offset 0, 0
   334  	st8.spill [r16] = in4, 16
   335  	.mem.offset 8, 0
   336  	st8.spill [r17] = in5, 16
   337  	mov	out3 = r8
   338  	;;
   339  	.mem.offset 0, 0
   340  	st8.spill [r16] = in6
   341  	.mem.offset 8, 0
   342  	st8.spill [r17] = in7
   343  
   344  	/* Invoke ffi_closure_unix_inner for the hard work.  */
   345  	br.call.sptk.many b0 = ffi_closure_unix_inner
   346  	;;
   347  
   348  	/* Dispatch to handle return value.  */
   349  	mov	gp = loc3
   350  	zxt1	r16 = r8
   351  	;;
   352  	addl	r18 = @ltoffx(.Lld_table), gp
   353  	mov	ar.pfs = loc0
   354  	;;
   355  	ld8.mov	r18 = [r18], .Lld_table
   356  	mov	b0 = loc1
   357  	;;
   358  	shladd	r18 = r16, 3, r18
   359  	mov	ar.unat = loc2
   360  	;;
   361  	ld8	r17 = [r18]
   362  	shr	r8 = r8, 8
   363  	;;
   364  	add	r17 = r17, r18
   365  	add	r16 = 16, sp
   366  	;;
   367  	mov	b6 = r17
   368  	br	b6
   369  	;;
   370  	.label_state 1
   371  
   372  .Lld_void:
   373  	.restore sp
   374  	add	sp = FRAME_SIZE, sp
   375  	br.ret.sptk.many b0
   376  	;;
   377  .Lld_int:
   378  	.body
   379  	.copy_state 1
   380  	ld8	r8 = [r16]
   381  	.restore sp
   382  	add	sp = FRAME_SIZE, sp
   383  	br.ret.sptk.many b0
   384  	;;
   385  .Lld_float:
   386  	.body
   387  	.copy_state 1
   388  	ldfs	f8 = [r16]
   389  	.restore sp
   390  	add	sp = FRAME_SIZE, sp
   391  	br.ret.sptk.many b0
   392  	;;
   393  .Lld_double:
   394  	.body
   395  	.copy_state 1
   396  	ldfd	f8 = [r16]
   397  	.restore sp
   398  	add	sp = FRAME_SIZE, sp
   399  	br.ret.sptk.many b0
   400  	;;
   401  .Lld_ldouble:
   402  	.body
   403  	.copy_state 1
   404  	ldfe	f8 = [r16]
   405  	.restore sp
   406  	add	sp = FRAME_SIZE, sp
   407  	br.ret.sptk.many b0
   408  	;;
   409  
   410  .Lld_small_struct:
   411  	.body
   412  	.copy_state 1
   413  	add	r17 = 8, r16
   414  	cmp.lt	p6, p0 = 8, r8
   415  	cmp.lt	p7, p0 = 16, r8
   416  	cmp.lt	p8, p0 = 24, r8
   417  	;;
   418  	ld8	r8 = [r16], 16
   419  (p6)	ld8	r9 = [r17], 16
   420  	;;
   421  (p7)	ld8	r10 = [r16]
   422  (p8)	ld8	r11 = [r17]
   423  	.restore sp
   424  	add	sp = FRAME_SIZE, sp
   425  	br.ret.sptk.many b0
   426  	;;
   427  
   428  .Lld_hfa_float:
   429  	.body
   430  	.copy_state 1
   431  	add	r17 = 4, r16
   432  	cmp.lt	p6, p0 = 4, r8
   433  	;;
   434  	ldfs	f8 = [r16], 8
   435  (p6)	ldfs	f9 = [r17], 8
   436  	cmp.lt	p7, p0 = 8, r8
   437  	cmp.lt	p8, p0 = 12, r8
   438  	;;
   439  (p7)	ldfs	f10 = [r16], 8
   440  (p8)	ldfs	f11 = [r17], 8
   441  	cmp.lt	p9, p0 = 16, r8
   442  	cmp.lt	p10, p0 = 20, r8
   443  	;;
   444  (p9)	ldfs	f12 = [r16], 8
   445  (p10)	ldfs	f13 = [r17], 8
   446  	cmp.lt	p6, p0 = 24, r8
   447  	cmp.lt	p7, p0 = 28, r8
   448  	;;
   449  (p6)	ldfs	f14 = [r16]
   450  (p7)	ldfs	f15 = [r17]
   451  	.restore sp
   452  	add	sp = FRAME_SIZE, sp
   453  	br.ret.sptk.many b0
   454  	;;
   455  
   456  .Lld_hfa_double:
   457  	.body
   458  	.copy_state 1
   459  	add	r17 = 8, r16
   460  	cmp.lt	p6, p0 = 8, r8
   461  	;;
   462  	ldfd	f8 = [r16], 16
   463  (p6)	ldfd	f9 = [r17], 16
   464  	cmp.lt	p7, p0 = 16, r8
   465  	cmp.lt	p8, p0 = 24, r8
   466  	;;
   467  (p7)	ldfd	f10 = [r16], 16
   468  (p8)	ldfd	f11 = [r17], 16
   469  	cmp.lt	p9, p0 = 32, r8
   470  	cmp.lt	p10, p0 = 40, r8
   471  	;;
   472  (p9)	ldfd	f12 = [r16], 16
   473  (p10)	ldfd	f13 = [r17], 16
   474  	cmp.lt	p6, p0 = 48, r8
   475  	cmp.lt	p7, p0 = 56, r8
   476  	;;
   477  (p6)	ldfd	f14 = [r16]
   478  (p7)	ldfd	f15 = [r17]
   479  	.restore sp
   480  	add	sp = FRAME_SIZE, sp
   481  	br.ret.sptk.many b0
   482  	;;
   483  
   484  .Lld_hfa_ldouble:
   485  	.body
   486  	.copy_state 1
   487  	add	r17 = 16, r16
   488  	cmp.lt	p6, p0 = 16, r8
   489  	;;
   490  	ldfe	f8 = [r16], 32
   491  (p6)	ldfe	f9 = [r17], 32
   492  	cmp.lt	p7, p0 = 32, r8
   493  	cmp.lt	p8, p0 = 48, r8
   494  	;;
   495  (p7)	ldfe	f10 = [r16], 32
   496  (p8)	ldfe	f11 = [r17], 32
   497  	cmp.lt	p9, p0 = 64, r8
   498  	cmp.lt	p10, p0 = 80, r8
   499  	;;
   500  (p9)	ldfe	f12 = [r16], 32
   501  (p10)	ldfe	f13 = [r17], 32
   502  	cmp.lt	p6, p0 = 96, r8
   503  	cmp.lt	p7, p0 = 112, r8
   504  	;;
   505  (p6)	ldfe	f14 = [r16]
   506  (p7)	ldfe	f15 = [r17]
   507  	.restore sp
   508  	add	sp = FRAME_SIZE, sp
   509  	br.ret.sptk.many b0
   510  	;;
   511  
   512  	.endp	ffi_closure_unix
   513  
   514  	.section .rodata
   515  	.align	8
   516  .Lst_table:
   517  	data8	@pcrel(.Lst_void)		// FFI_TYPE_VOID
   518  	data8	@pcrel(.Lst_sint32)		// FFI_TYPE_INT
   519  	data8	@pcrel(.Lst_float)		// FFI_TYPE_FLOAT
   520  	data8	@pcrel(.Lst_double)		// FFI_TYPE_DOUBLE
   521  	data8	@pcrel(.Lst_ldouble)		// FFI_TYPE_LONGDOUBLE
   522  	data8	@pcrel(.Lst_uint8)		// FFI_TYPE_UINT8
   523  	data8	@pcrel(.Lst_sint8)		// FFI_TYPE_SINT8
   524  	data8	@pcrel(.Lst_uint16)		// FFI_TYPE_UINT16
   525  	data8	@pcrel(.Lst_sint16)		// FFI_TYPE_SINT16
   526  	data8	@pcrel(.Lst_uint32)		// FFI_TYPE_UINT32
   527  	data8	@pcrel(.Lst_sint32)		// FFI_TYPE_SINT32
   528  	data8	@pcrel(.Lst_int64)		// FFI_TYPE_UINT64
   529  	data8	@pcrel(.Lst_int64)		// FFI_TYPE_SINT64
   530  	data8	@pcrel(.Lst_void)		// FFI_TYPE_STRUCT
   531  	data8	@pcrel(.Lst_int64)		// FFI_TYPE_POINTER
   532  	data8 	@pcrel(.Lst_small_struct)	// FFI_IA64_TYPE_SMALL_STRUCT
   533  	data8	@pcrel(.Lst_hfa_float)		// FFI_IA64_TYPE_HFA_FLOAT
   534  	data8	@pcrel(.Lst_hfa_double)		// FFI_IA64_TYPE_HFA_DOUBLE
   535  	data8	@pcrel(.Lst_hfa_ldouble)	// FFI_IA64_TYPE_HFA_LDOUBLE
   536  
   537  .Lld_table:
   538  	data8	@pcrel(.Lld_void)		// FFI_TYPE_VOID
   539  	data8	@pcrel(.Lld_int)		// FFI_TYPE_INT
   540  	data8	@pcrel(.Lld_float)		// FFI_TYPE_FLOAT
   541  	data8	@pcrel(.Lld_double)		// FFI_TYPE_DOUBLE
   542  	data8	@pcrel(.Lld_ldouble)		// FFI_TYPE_LONGDOUBLE
   543  	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT8
   544  	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT8
   545  	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT16
   546  	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT16
   547  	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT32
   548  	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT32
   549  	data8	@pcrel(.Lld_int)		// FFI_TYPE_UINT64
   550  	data8	@pcrel(.Lld_int)		// FFI_TYPE_SINT64
   551  	data8	@pcrel(.Lld_void)		// FFI_TYPE_STRUCT
   552  	data8	@pcrel(.Lld_int)		// FFI_TYPE_POINTER
   553  	data8 	@pcrel(.Lld_small_struct)	// FFI_IA64_TYPE_SMALL_STRUCT
   554  	data8	@pcrel(.Lld_hfa_float)		// FFI_IA64_TYPE_HFA_FLOAT
   555  	data8	@pcrel(.Lld_hfa_double)		// FFI_IA64_TYPE_HFA_DOUBLE
   556  	data8	@pcrel(.Lld_hfa_ldouble)	// FFI_IA64_TYPE_HFA_LDOUBLE
   557  
   558  #if defined __ELF__ && defined __linux__
   559  	.section	.note.GNU-stack,"",@progbits
   560  #endif