This is the mail archive of the libffi-discuss@sourceware.org mailing list for the libffi project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Go closures for s390[x]


The attached patch adds Go closure support for s390[x] atop
Richard's go-closure branch in the Gcc repository (it requires on
other patches discussed in the general Go closure topic).

ChangeLog:
--
2014-12-16  Dominik Vogt  <vogt@linux.vnet.ibm.com>

	* src/s390/sysv.S (ffi_call_SYSV): Adapt for Go closure support.
	Rewrite cfi information.
	(ffi_closure_SYSV): Adapt for Go closure support.  Rewrite cfi
	information.
	(ffi_go_closure_SYSV): New function.
	* src/s390/ffi.c (ffi_call_int): Renamed from ffi_call, add closure
	argument.
	(ffi_call): New interface function.
	(ffi_call_go): New interface function for go calls.
	(ffi_closure_helper_SYSV): Pass closure internals as arguments.
	(ffi_prep_go_closure): New function for Go closure support.
	* src/s390/ffitarget.h (FFI_GO_CLOSURES): Activate Go closure support.
--

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany
>From 7df911133b96aca5b9a40a7a33b42f356c8db530 Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Wed, 10 Dec 2014 11:47:25 +0100
Subject: [PATCH] libffi: S/390 Go closure support.

---
 libffi/src/s390/ffi.c       |  78 +++++---
 libffi/src/s390/ffitarget.h |   1 +
 libffi/src/s390/sysv.S      | 459 ++++++++++++++++++++++++--------------------
 3 files changed, 303 insertions(+), 235 deletions(-)

diff --git a/libffi/src/s390/ffi.c b/libffi/src/s390/ffi.c
index 520ec7c..477b85e 100644
--- a/libffi/src/s390/ffi.c
+++ b/libffi/src/s390/ffi.c
@@ -65,21 +65,6 @@
 /*===================== End of Defines ===============================*/
  
 /*====================================================================*/
-/*                          Prototypes                                */
-/*                          ----------                                */
-/*====================================================================*/
- 
-static void ffi_prep_args (unsigned char *, extended_cif *);
-void
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
-__attribute__ ((visibility ("hidden")))
-#endif
-ffi_closure_helper_SYSV (ffi_closure *, unsigned long *, 
-			 unsigned long long *, unsigned long *);
-
-/*====================== End of Prototypes ===========================*/
- 
-/*====================================================================*/
 /*                          Externals                                 */
 /*                          ---------                                 */
 /*====================================================================*/
@@ -89,9 +74,10 @@ extern void ffi_call_SYSV(unsigned,
 			  void (*)(unsigned char *, extended_cif *),
 			  unsigned,
 			  void *,
-			  void (*fn)(void));
+			  void (*fn)(void), void *);
 
 extern void ffi_closure_SYSV(void);
+extern void ffi_go_closure_SYSV(void);
  
 /*====================== End of Externals ============================*/
  
@@ -504,11 +490,12 @@ ffi_prep_cif_machdep(ffi_cif *cif)
 /*                                                                    */
 /*====================================================================*/
  
-void
-ffi_call(ffi_cif *cif,
-	 void (*fn)(void),
-	 void *rvalue,
-	 void **avalue)
+static void
+ffi_call_int(ffi_cif *cif,
+	     void (*fn)(void),
+	     void *rvalue,
+	     void **avalue,
+	     void *closure)
 {
   int ret_type = cif->flags;
   extended_cif ecif;
@@ -530,7 +517,7 @@ ffi_call(ffi_cif *cif,
     {
       case FFI_SYSV:
         ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
-		       ret_type, ecif.rvalue, fn);
+		       ret_type, ecif.rvalue, fn, closure);
         break;
  
       default:
@@ -538,6 +525,19 @@ ffi_call(ffi_cif *cif,
         break;
     }
 }
+
+void
+ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+{
+  ffi_call_int(cif, fn, rvalue, avalue, NULL);
+}
+
+void
+ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
+	     void **avalue, void *closure)
+{
+  ffi_call_int(cif, fn, rvalue, avalue, closure);
+}
  
 /*======================== End of Routine ============================*/
 
@@ -548,9 +548,12 @@ ffi_call(ffi_cif *cif,
 /* Function - Call a FFI closure target function.                     */
 /*                                                                    */
 /*====================================================================*/
- 
+
+FFI_HIDDEN
 void
-ffi_closure_helper_SYSV (ffi_closure *closure,
+ffi_closure_helper_SYSV (ffi_cif *cif,
+			 void (*fun)(ffi_cif*,void*,void**,void*),
+			 void *user_data,
 			 unsigned long *p_gpr,
 			 unsigned long long *p_fpr,
 			 unsigned long *p_ov)
@@ -570,20 +573,18 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
 
   /* Allocate buffer for argument list pointers.  */
 
-  p_arg = avalue = alloca (closure->cif->nargs * sizeof (void *));
+  p_arg = avalue = alloca (cif->nargs * sizeof (void *));
 
   /* If we returning a structure, pass the structure address 
      directly to the target function.  Otherwise, have the target 
      function store the return value to the GPR save area.  */
 
-  if (closure->cif->flags == FFI390_RET_STRUCT)
+  if (cif->flags == FFI390_RET_STRUCT)
     rvalue = (void *) p_gpr[n_gpr++];
 
   /* Now for the arguments.  */
 
-  for (ptr = closure->cif->arg_types, i = closure->cif->nargs;
-       i > 0;
-       i--, p_arg++, ptr++)
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, p_arg++, ptr++)
     {
       int deref_struct_pointer = 0;
       int type = (*ptr)->type;
@@ -689,10 +690,10 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
 
 
   /* Call the target function.  */
-  (closure->fun) (closure->cif, rvalue, avalue, closure->user_data);
+  (fun) (cif, rvalue, avalue, user_data);
 
   /* Convert the return value.  */
-  switch (closure->cif->rtype->type)
+  switch (cif->rtype->type)
     {
       /* Void is easy, and so is struct.  */
       case FFI_TYPE_VOID:
@@ -790,3 +791,18 @@ ffi_prep_closure_loc (ffi_closure *closure,
 
 /*======================== End of Routine ============================*/
  
+/* Build a Go language closure.  */
+
+ffi_status
+ffi_prep_go_closure (ffi_go_closure *closure, ffi_cif *cif,
+		     void (*fun)(ffi_cif*,void*,void**,void*))
+{
+  if (cif->abi != FFI_SYSV)
+    return FFI_BAD_ABI;
+
+  closure->tramp = ffi_go_closure_SYSV;
+  closure->cif = cif;
+  closure->fun = fun;
+
+  return FFI_OK;
+}
diff --git a/libffi/src/s390/ffitarget.h b/libffi/src/s390/ffitarget.h
index 0e4868a..d8a4ee4 100644
--- a/libffi/src/s390/ffitarget.h
+++ b/libffi/src/s390/ffitarget.h
@@ -58,6 +58,7 @@ typedef enum ffi_abi {
 /* ---- Definitions for closures ----------------------------------------- */
 
 #define FFI_CLOSURES 1
+#define FFI_GO_CLOSURES 1
 #ifdef S390X
 #define FFI_TRAMPOLINE_SIZE 32
 #else
diff --git a/libffi/src/s390/sysv.S b/libffi/src/s390/sysv.S
index 4731a31..14672ac 100644
--- a/libffi/src/s390/sysv.S
+++ b/libffi/src/s390/sysv.S
@@ -39,18 +39,29 @@
 	# r5:	ret_type
 	# r6:	ecif.rvalue
 	# ov:	fn 
- 
+	# ov+8:	closure
+
 	# This assumes we are using gas.
 	.globl	ffi_call_SYSV
+	FFI_HIDDEN(ffi_call_SYSV)
 	.type	ffi_call_SYSV,%function
 ffi_call_SYSV:
-.LFB1:
+	.cfi_startproc
 	stm	%r6,%r15,24(%r15)		# Save registers
-.LCFI0:
+	.cfi_offset r6, -72
+	.cfi_offset r7, -68
+	.cfi_offset r8, -64
+	.cfi_offset r9, -60
+	.cfi_offset r10, -56
+	.cfi_offset r11, -52
+	.cfi_offset r12, -48
+	.cfi_offset r13, -44
+	.cfi_offset r14, -40
+	.cfi_offset r15, -36
 	basr	%r13,0				# Set up base register
 .Lbase:
 	lr	%r11,%r15			# Set up frame pointer
-.LCFI1:
+	.cfi_def_cfa_register r11
 	sr	%r15,%r2
 	ahi	%r15,-96-48			# Allocate stack
 	lr	%r8,%r6				# Save ecif.rvalue
@@ -59,12 +70,13 @@ ffi_call_SYSV:
 	l	%r7,96(%r11)			# Load function address
 	st	%r11,0(%r15)			# Set up back chain
 	ahi	%r11,-48			# Register save area
-.LCFI2:
+	.cfi_adjust_cfa_offset 48
 
 	la	%r2,96(%r15)			# Save area
 						# r3 already holds &ecif
 	basr	%r14,%r4			# Call ffi_prep_args
 
+	l	%r0,96+48+4(%r11)		# Go closure -> static chain
 	lm	%r2,%r6,0(%r11)			# Load arguments
 	ld	%f0,32(%r11)
 	ld	%f2,40(%r11)
@@ -74,31 +86,106 @@ ffi_call_SYSV:
 .LretNone:					# Return void
 	l	%r4,48+56(%r11)
 	lm	%r6,%r15,48+24(%r11)
+	.cfi_remember_state
+	.cfi_restore 15
+	.cfi_restore 14
+	.cfi_restore 13
+	.cfi_restore 12
+	.cfi_restore 11
+	.cfi_restore 10
+	.cfi_restore 9
+	.cfi_restore 8
+	.cfi_restore 7
+	.cfi_restore 6
+	.cfi_def_cfa r15, 96
 	br	%r4
+	.cfi_restore_state
+	# This nopr is necessary so that the .cfi instructions between the br
+	# above and the label below get executed.  See execute_cfa_program() in
+	# the Gcc source code, libgcc/unwind-dw2.c.
+	nopr
 
 .LretFloat:
 	l	%r4,48+56(%r11)
 	ste	%f0,0(%r8)			# Return float
 	lm	%r6,%r15,48+24(%r11)
+	.cfi_remember_state
+	.cfi_restore 15
+	.cfi_restore 14
+	.cfi_restore 13
+	.cfi_restore 12
+	.cfi_restore 11
+	.cfi_restore 10
+	.cfi_restore 9
+	.cfi_restore 8
+	.cfi_restore 7
+	.cfi_restore 6
+	.cfi_def_cfa r15, 96
 	br	%r4
+	.cfi_restore_state
+	# See comment on the nopr above.
+	nopr
  
 .LretDouble:
 	l	%r4,48+56(%r11)
 	std	%f0,0(%r8)			# Return double
 	lm	%r6,%r15,48+24(%r11)
+	.cfi_remember_state
+	.cfi_restore 15
+	.cfi_restore 14
+	.cfi_restore 13
+	.cfi_restore 12
+	.cfi_restore 11
+	.cfi_restore 10
+	.cfi_restore 9
+	.cfi_restore 8
+	.cfi_restore 7
+	.cfi_restore 6
+	.cfi_def_cfa r15, 96
 	br	%r4
+	.cfi_restore_state
+	# See comment on the nopr above.
+	nopr
 
 .LretInt32:
 	l	%r4,48+56(%r11)
 	st	%r2,0(%r8)			# Return int
 	lm	%r6,%r15,48+24(%r11)
+	.cfi_remember_state
+	.cfi_restore 15
+	.cfi_restore 14
+	.cfi_restore 13
+	.cfi_restore 12
+	.cfi_restore 11
+	.cfi_restore 10
+	.cfi_restore 9
+	.cfi_restore 8
+	.cfi_restore 7
+	.cfi_restore 6
+	.cfi_def_cfa r15, 96
 	br	%r4
+	.cfi_restore_state
+	# See comment on the nopr above.
+	nopr
  
 .LretInt64:
 	l	%r4,48+56(%r11)
 	stm	%r2,%r3,0(%r8)			# Return long long
 	lm	%r6,%r15,48+24(%r11)
+	.cfi_remember_state
+	.cfi_restore 15
+	.cfi_restore 14
+	.cfi_restore 13
+	.cfi_restore 12
+	.cfi_restore 11
+	.cfi_restore 10
+	.cfi_restore 9
+	.cfi_restore 8
+	.cfi_restore 7
+	.cfi_restore 6
+	.cfi_def_cfa r15, 96
 	br	%r4
+	.cfi_endproc
  
 .Ltable:
 	.byte	.LretNone-.Lbase		# FFI390_RET_VOID
@@ -108,129 +195,78 @@ ffi_call_SYSV:
 	.byte	.LretInt32-.Lbase		# FFI390_RET_INT32
 	.byte	.LretInt64-.Lbase		# FFI390_RET_INT64
 
-.LFE1: 
 .ffi_call_SYSV_end:
 	.size	 ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
 
 
 	.globl	ffi_closure_SYSV
+	FFI_HIDDEN(ffi_closure_SYSV)
 	.type	ffi_closure_SYSV,%function
 ffi_closure_SYSV:
-.LFB2:
+	.cfi_startproc
+	stm	%r2,%r6,8(%r15)			# Save arguments
+	.cfi_offset r6, -72
+	lr	%r4,%r0				# Closure
+	l	%r2,16(%r4)			#   ->cif
+	l	%r3,20(%r4)			#   ->fun
+	l	%r4,24(%r4)			#   ->user_data
+.Ldoclosure:
 	stm	%r12,%r15,48(%r15)		# Save registers
-.LCFI10:
+	.cfi_offset r12, -48
+	.cfi_offset r13, -44
+	.cfi_offset r14, -40
+	.cfi_offset r15, -36
 	basr	%r13,0				# Set up base register
 .Lcbase:
-	stm	%r2,%r6,8(%r15)			# Save arguments
 	std	%f0,64(%r15)
 	std	%f2,72(%r15)
 	lr	%r1,%r15			# Set up stack frame
-	ahi	%r15,-96
-.LCFI11:
+	ahi	%r15,-104
+	.cfi_adjust_cfa_offset 104
 	l	%r12,.Lchelper-.Lcbase(%r13)	# Get helper function
-	lr	%r2,%r0				# Closure
-	la	%r3,8(%r1)			# GPRs
-	la	%r4,64(%r1)			# FPRs
-	la	%r5,96(%r1)			# Overflow
+	la	%r5,96(%r1)
+	st	%r5,96(%r15)			# Overflow
+	la	%r5,8(%r1)			# GPRs
+	la	%r6,64(%r1)			# FPRs
 	st	%r1,0(%r15)			# Set up back chain
 
 	bas	%r14,0(%r12,%r13)		# Call helper
 
-	l	%r4,96+56(%r15)
-	ld	%f0,96+64(%r15)			# Load return registers
-	lm	%r2,%r3,96+8(%r15)
-	lm	%r12,%r15,96+48(%r15)
+	l	%r4,104+56(%r15)
+	ld	%f0,104+64(%r15)		# Load return registers
+	lm	%r2,%r3,104+8(%r15)
+	l	%r6,104+24(%r15)		# Restore saved registers
+	.cfi_restore r6
+	lm	%r12,%r15,104+48(%r15)
+	.cfi_adjust_cfa_offset -104
+	.cfi_restore r12
+	.cfi_restore r13
+	.cfi_restore r14
+	.cfi_restore r15
 	br	%r4
+	.cfi_endproc
 
 	.align 4
 .Lchelper:
 	.long	ffi_closure_helper_SYSV-.Lcbase
 
-.LFE2: 
 
 .ffi_closure_SYSV_end:
 	.size	 ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
 
 
-	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
-.Lframe1:
-	.4byte	.LECIE1-.LSCIE1	# Length of Common Information Entry
-.LSCIE1:
-	.4byte	0x0	# CIE Identifier Tag
-	.byte	0x1	# CIE Version
-	.ascii "zR\0"	# CIE Augmentation
-	.uleb128 0x1	# CIE Code Alignment Factor
-	.sleb128 -4	# CIE Data Alignment Factor
-	.byte	0xe	# CIE RA Column
-	.uleb128 0x1	# Augmentation size
-	.byte	0x1b	# FDE Encoding (pcrel sdata4)
-	.byte	0xc	# DW_CFA_def_cfa
-	.uleb128 0xf
-	.uleb128 0x60
-	.align	4
-.LECIE1:
-.LSFDE1:
-	.4byte	.LEFDE1-.LASFDE1	# FDE Length
-.LASFDE1:
-	.4byte	.LASFDE1-.Lframe1	# FDE CIE offset
-	.4byte	.LFB1-.	# FDE initial location
-	.4byte	.LFE1-.LFB1	# FDE address range
-	.uleb128 0x0	# Augmentation size
-	.byte	0x4	# DW_CFA_advance_loc4
-	.4byte	.LCFI0-.LFB1
-	.byte	0x8f	# DW_CFA_offset, column 0xf
-	.uleb128 0x9
-	.byte	0x8e	# DW_CFA_offset, column 0xe
-	.uleb128 0xa
-	.byte	0x8d	# DW_CFA_offset, column 0xd
-	.uleb128 0xb
-	.byte	0x8c	# DW_CFA_offset, column 0xc
-	.uleb128 0xc
-	.byte	0x8b	# DW_CFA_offset, column 0xb
-	.uleb128 0xd
-	.byte	0x8a	# DW_CFA_offset, column 0xa
-	.uleb128 0xe
-	.byte	0x89	# DW_CFA_offset, column 0x9
-	.uleb128 0xf
-	.byte	0x88	# DW_CFA_offset, column 0x8
-	.uleb128 0x10
-	.byte	0x87	# DW_CFA_offset, column 0x7
-	.uleb128 0x11
-	.byte	0x86	# DW_CFA_offset, column 0x6
-	.uleb128 0x12
-	.byte	0x4	# DW_CFA_advance_loc4
-	.4byte	.LCFI1-.LCFI0
-	.byte	0xd	# DW_CFA_def_cfa_register
-	.uleb128 0xb
-	.byte	0x4	# DW_CFA_advance_loc4
-	.4byte	.LCFI2-.LCFI1
-	.byte	0xe	# DW_CFA_def_cfa_offset
-	.uleb128 0x90
-	.align	4
-.LEFDE1:
-.LSFDE2:
-	.4byte	.LEFDE2-.LASFDE2	# FDE Length
-.LASFDE2:
-	.4byte	.LASFDE2-.Lframe1	# FDE CIE offset
-	.4byte	.LFB2-.	# FDE initial location
-	.4byte	.LFE2-.LFB2	# FDE address range
-	.uleb128 0x0	# Augmentation size
-	.byte	0x4	# DW_CFA_advance_loc4
-	.4byte	.LCFI10-.LFB2
-	.byte	0x8f	# DW_CFA_offset, column 0xf
-	.uleb128 0x9
-	.byte	0x8e	# DW_CFA_offset, column 0xe
-	.uleb128 0xa
-	.byte	0x8d	# DW_CFA_offset, column 0xd
-	.uleb128 0xb
-	.byte	0x8c	# DW_CFA_offset, column 0xc
-	.uleb128 0xc
-	.byte	0x4	# DW_CFA_advance_loc4
-	.4byte	.LCFI11-.LCFI10
-	.byte	0xe	# DW_CFA_def_cfa_offset
-	.uleb128 0xc0
-	.align	4
-.LEFDE2:
+	.globl	ffi_go_closure_SYSV
+	FFI_HIDDEN(ffi_go_closure_SYSV)
+	.type	ffi_go_closure_SYSV,%function
+ffi_go_closure_SYSV:
+	.cfi_startproc
+	stm	%r2,%r6,8(%r15)			# Save arguments
+	.cfi_offset r6, -72
+	lr	%r4,%r0				# Load closure -> user_data
+	l	%r2,4(%r4)			#   ->cif
+	l	%r3,8(%r4)			#   ->fun
+	j	.Ldoclosure
+	.cfi_endproc
 
 #else
  
@@ -242,17 +278,28 @@ ffi_closure_SYSV:
 	# r5:	ret_type
 	# r6:	ecif.rvalue
 	# ov:	fn 
- 
+	# ov+8:	closure
+
 	# This assumes we are using gas.
 	.globl	ffi_call_SYSV
+	FFI_HIDDEN(ffi_call_SYSV)
 	.type	ffi_call_SYSV,%function
 ffi_call_SYSV:
-.LFB1:
+	.cfi_startproc
 	stmg	%r6,%r15,48(%r15)		# Save registers
-.LCFI0:
+	.cfi_offset r6, -112
+	.cfi_offset r7, -104
+	.cfi_offset r8, -96
+	.cfi_offset r9, -88
+	.cfi_offset r10, -80
+	.cfi_offset r11, -72
+	.cfi_offset r12, -64
+	.cfi_offset r13, -56
+	.cfi_offset r14, -48
+	.cfi_offset r15, -40
 	larl	%r13,.Lbase			# Set up base register
 	lgr	%r11,%r15			# Set up frame pointer
-.LCFI1:
+	.cfi_def_cfa_register r11
 	sgr	%r15,%r2
 	aghi	%r15,-160-80			# Allocate stack
 	lgr	%r8,%r6				# Save ecif.rvalue
@@ -260,12 +307,13 @@ ffi_call_SYSV:
 	lg	%r7,160(%r11)			# Load function address
 	stg	%r11,0(%r15)			# Set up back chain
 	aghi	%r11,-80			# Register save area
-.LCFI2:
+	.cfi_adjust_cfa_offset 80
 
 	la	%r2,160(%r15)			# Save area
 						# r3 already holds &ecif
 	basr	%r14,%r4			# Call ffi_prep_args
 
+	lg	%r0,160+80+8(%r11)		# Go closure -> static chain
 	lmg	%r2,%r6,0(%r11)			# Load arguments
 	ld	%f0,48(%r11)
 	ld	%f2,56(%r11)
@@ -278,154 +326,157 @@ ffi_call_SYSV:
 .LretNone:					# Return void
 	lg	%r4,80+112(%r11)
 	lmg	%r6,%r15,80+48(%r11)
+	.cfi_remember_state
+	.cfi_restore r15
+	.cfi_restore r14
+	.cfi_restore r13
+	.cfi_restore r12
+	.cfi_restore r11
+	.cfi_restore r10
+	.cfi_restore r9
+	.cfi_restore r8
+	.cfi_restore r7
+	.cfi_restore r6
+	.cfi_def_cfa r15, 160
 	br	%r4
+	.cfi_restore_state
+	# This nopr is necessary so that the .cfi instructions between the br
+	# above and the label below get executed.  See execute_cfa_program() in
+	# the Gcc source code, libgcc/unwind-dw2.c.
+	nopr
 
 .LretFloat:
 	lg	%r4,80+112(%r11)
 	ste	%f0,0(%r8)			# Return float
 	lmg	%r6,%r15,80+48(%r11)
+	.cfi_remember_state
+	.cfi_restore r6
+	.cfi_restore r7
+	.cfi_restore r8
+	.cfi_restore r9
+	.cfi_restore r10
+	.cfi_restore r11
+	.cfi_restore r12
+	.cfi_restore r13
+	.cfi_restore r14
+	.cfi_restore r15
+	.cfi_def_cfa r15, 160
 	br	%r4
+	.cfi_restore_state
+	# See comment on the nopr above.
+	nopr
  
 .LretDouble:
 	lg	%r4,80+112(%r11)
 	std	%f0,0(%r8)			# Return double
 	lmg	%r6,%r15,80+48(%r11)
+	.cfi_remember_state
+	.cfi_restore r15
+	.cfi_restore r14
+	.cfi_restore r13
+	.cfi_restore r12
+	.cfi_restore r11
+	.cfi_restore r10
+	.cfi_restore r9
+	.cfi_restore r8
+	.cfi_restore r7
+	.cfi_restore r6
+	.cfi_def_cfa r15, 160
 	br	%r4
+	.cfi_restore_state
+	# See comment on the nopr above.
+	nopr
 
-.LretInt32:
-	lg	%r4,80+112(%r11)
-	st	%r2,0(%r8)			# Return int
-	lmg	%r6,%r15,80+48(%r11)
-	br	%r4
- 
 .LretInt64:
 	lg	%r4,80+112(%r11)
 	stg	%r2,0(%r8)			# Return long
 	lmg	%r6,%r15,80+48(%r11)
+	.cfi_restore r15
+	.cfi_restore r14
+	.cfi_restore r13
+	.cfi_restore r12
+	.cfi_restore r11
+	.cfi_restore r10
+	.cfi_restore r9
+	.cfi_restore r8
+	.cfi_restore r7
+	.cfi_restore r6
+	.cfi_def_cfa r15, 160
 	br	%r4
+	.cfi_endproc
  
 .Ltable:
 	.byte	.LretNone-.Lbase		# FFI390_RET_VOID
 	.byte	.LretNone-.Lbase		# FFI390_RET_STRUCT
 	.byte	.LretFloat-.Lbase		# FFI390_RET_FLOAT
 	.byte	.LretDouble-.Lbase		# FFI390_RET_DOUBLE
-	.byte	.LretInt32-.Lbase		# FFI390_RET_INT32
+	.byte	0				# int32 retval not supported
 	.byte	.LretInt64-.Lbase		# FFI390_RET_INT64
 
-.LFE1: 
 .ffi_call_SYSV_end:
 	.size	 ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
 
 
 	.globl	ffi_closure_SYSV
+	FFI_HIDDEN(ffi_closure_SYSV)
 	.type	ffi_closure_SYSV,%function
 ffi_closure_SYSV:
-.LFB2:
-	stmg	%r14,%r15,112(%r15)		# Save registers
-.LCFI10:
+	.cfi_startproc
 	stmg	%r2,%r6,16(%r15)		# Save arguments
-	std	%f0,128(%r15)
+	.cfi_offset r6, -112
+	lgr	%r4,%r0				# Load closure
+	lg	%r2,32(%r4)			#   ->cif
+	lg	%r3,40(%r4)			#   ->fun
+	lg	%r4,48(%r4)			#   ->user_data
+.Ldoclosure:
+	stmg	%r14,%r15,112(%r15)		# Save registers
+	.cfi_offset r14, -48
+	.cfi_offset r15, -40
+	std	%f0,128(%r15)			# Save arguments
 	std	%f2,136(%r15)
 	std	%f4,144(%r15)
 	std	%f6,152(%r15)
 	lgr	%r1,%r15			# Set up stack frame
-	aghi	%r15,-160
-.LCFI11:
-	lgr	%r2,%r0				# Closure
-	la	%r3,16(%r1)			# GPRs
-	la	%r4,128(%r1)			# FPRs
-	la	%r5,160(%r1)			# Overflow
+	aghi	%r15,-168
+	.cfi_adjust_cfa_offset 168
+	la	%r5,160(%r1)
+	stg	%r5,160(%r15)			# Overflow
+	la	%r5,16(%r1)			# GPRs
+	la	%r6,128(%r1)			# FPRs
 	stg	%r1,0(%r15)			# Set up back chain
 
 	brasl	%r14,ffi_closure_helper_SYSV	# Call helper
 
-	lg	%r14,160+112(%r15)
-	ld	%f0,160+128(%r15)		# Load return registers
-	lg	%r2,160+16(%r15)
-	la	%r15,160(%r15)
+	ld	%f0,168+128(%r15)		# Load return registers
+	lg	%r2,168+16(%r15)
+	lg	%r6,168+48(%r15)		# Restore saved registers
+	.cfi_restore r6
+	lmg	%r14,%r15,168+112(%r15)
+	.cfi_restore r14
+	.cfi_restore r15
+	.cfi_adjust_cfa_offset -168
 	br	%r14
-.LFE2: 
+	.cfi_endproc
 
 .ffi_closure_SYSV_end:
 	.size	 ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
 
-
-
-	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
-.Lframe1:
-	.4byte	.LECIE1-.LSCIE1	# Length of Common Information Entry
-.LSCIE1:
-	.4byte	0x0	# CIE Identifier Tag
-	.byte	0x1	# CIE Version
-	.ascii "zR\0"	# CIE Augmentation
-	.uleb128 0x1	# CIE Code Alignment Factor
-	.sleb128 -8	# CIE Data Alignment Factor
-	.byte	0xe	# CIE RA Column
-	.uleb128 0x1	# Augmentation size
-	.byte	0x1b	# FDE Encoding (pcrel sdata4)
-	.byte	0xc	# DW_CFA_def_cfa
-	.uleb128 0xf
-	.uleb128 0xa0
-	.align	8
-.LECIE1:
-.LSFDE1:
-	.4byte	.LEFDE1-.LASFDE1	# FDE Length
-.LASFDE1:
-	.4byte	.LASFDE1-.Lframe1	# FDE CIE offset
-	.4byte	.LFB1-.	# FDE initial location
-	.4byte	.LFE1-.LFB1	# FDE address range
-	.uleb128 0x0	# Augmentation size
-	.byte	0x4	# DW_CFA_advance_loc4
-	.4byte	.LCFI0-.LFB1
-	.byte	0x8f	# DW_CFA_offset, column 0xf
-	.uleb128 0x5
-	.byte	0x8e	# DW_CFA_offset, column 0xe
-	.uleb128 0x6
-	.byte	0x8d	# DW_CFA_offset, column 0xd
-	.uleb128 0x7
-	.byte	0x8c	# DW_CFA_offset, column 0xc
-	.uleb128 0x8
-	.byte	0x8b	# DW_CFA_offset, column 0xb
-	.uleb128 0x9
-	.byte	0x8a	# DW_CFA_offset, column 0xa
-	.uleb128 0xa
-	.byte	0x89	# DW_CFA_offset, column 0x9
-	.uleb128 0xb
-	.byte	0x88	# DW_CFA_offset, column 0x8
-	.uleb128 0xc
-	.byte	0x87	# DW_CFA_offset, column 0x7
-	.uleb128 0xd
-	.byte	0x86	# DW_CFA_offset, column 0x6
-	.uleb128 0xe
-	.byte	0x4	# DW_CFA_advance_loc4
-	.4byte	.LCFI1-.LCFI0
-	.byte	0xd	# DW_CFA_def_cfa_register
-	.uleb128 0xb
-	.byte	0x4	# DW_CFA_advance_loc4
-	.4byte	.LCFI2-.LCFI1
-	.byte	0xe	# DW_CFA_def_cfa_offset
-	.uleb128 0xf0
-	.align	8
-.LEFDE1:
-.LSFDE2:
-	.4byte	.LEFDE2-.LASFDE2	# FDE Length
-.LASFDE2:
-	.4byte	.LASFDE2-.Lframe1	# FDE CIE offset
-	.4byte	.LFB2-.	# FDE initial location
-	.4byte	.LFE2-.LFB2	# FDE address range
-	.uleb128 0x0	# Augmentation size
-	.byte	0x4	# DW_CFA_advance_loc4
-	.4byte	.LCFI10-.LFB2
-	.byte	0x8f	# DW_CFA_offset, column 0xf
-	.uleb128 0x5
-	.byte	0x8e	# DW_CFA_offset, column 0xe
-	.uleb128 0x6
-	.byte	0x4	# DW_CFA_advance_loc4
-	.4byte	.LCFI11-.LCFI10
-	.byte	0xe	# DW_CFA_def_cfa_offset
-	.uleb128 0x140
-	.align	8
-.LEFDE2:
+	
+	.globl	ffi_go_closure_SYSV
+	FFI_HIDDEN(ffi_go_closure_SYSV)
+	.type	ffi_go_closure_SYSV,%function
+ffi_go_closure_SYSV:
+	.cfi_startproc
+	stmg	%r2,%r6,16(%r15)		# Save arguments
+	.cfi_offset r6, -112
+	lgr	%r4,%r0				# Load closure -> user_data
+	lg	%r2,8(%r4)			#   ->cif
+	lg	%r3,16(%r4)			#   ->fun
+	j	.Ldoclosure
+	.cfi_endproc
+
+.ffi_go_closure_SYSV_end:
+	.size	 ffi_go_closure_SYSV,.ffi_go_closure_SYSV_end-ffi_go_closure_SYSV
 
 #endif
 
-- 
1.8.4.2


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]