4aabfd
From f60b86bddcf964f1a97df7a33aa36bc0160dba38 Mon Sep 17 00:00:00 2001
4aabfd
From: Andreas Krebbel <krebbel@linux.ibm.com>
4aabfd
Date: Mon, 23 Mar 2020 09:09:17 +0100
4aabfd
Subject: [PATCH 4/4] IBM Z: Fix fcontext routines
4aabfd
4aabfd
---
4aabfd
 src/asm/jump_s390x_sysv_elf_gas.S  | 257 +++++++++++++++++------------
4aabfd
 src/asm/make_s390x_sysv_elf_gas.S  | 176 ++++++++++----------
4aabfd
 src/asm/ontop_s390x_sysv_elf_gas.S | 238 ++++++++++++++------------
4aabfd
 3 files changed, 374 insertions(+), 297 deletions(-)
4aabfd
4aabfd
diff --git a/src/asm/jump_s390x_sysv_elf_gas.S b/src/asm/jump_s390x_sysv_elf_gas.S
4aabfd
index b2163cc..c2a578b 100644
4aabfd
--- a/libs/context/src/asm/jump_s390x_sysv_elf_gas.S
4aabfd
+++ b/libs/context/src/asm/jump_s390x_sysv_elf_gas.S
4aabfd
@@ -1,117 +1,156 @@
4aabfd
 /*******************************************************
4aabfd
-*                                                     *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |     0     |     8     |    16     |     24    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |    R6     |    R7     |    R8     |    R9     |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |  8  |  9  |  10 |  11 |  12 |  13 |  14 |  15 |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |     32    |    40     |     48    |     56    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |    R10    |    R11    |     R12   |     R13   |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |  16 |  17 |  18 |  19 |  20 |  21 |  22 |  23 |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |     64    |    72     |     80    |     88    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |   R14/LR  |    R15    |     F1    |     F3    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |  24 |  25 |  26 |  27 |  28 | 29  |           |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |     96    |    104    |    112    |    120    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |    F5     |    F7     |     PC    |           |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-* *****************************************************/
4aabfd
-
4aabfd
-.file  "jump_s390x_sysv_elf_gas.S"
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     0     |     8     |    16     |    24     |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |   t.fctx  |   t.data  |    r2     |    r6     |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  8  |  9  |  10 |  11 |  12 |  13 |  14 |  15 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     32    |    40     |     48    |     56    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     r7    |     r8    |     r9    |    r10    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  16 |  17 |  18 |  19 |  20 |  21 |  22 |  23 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     64    |     72    |     80    |     88    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    r11    |    r12    |    r13    |    r14    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  24 |  25 |  26 |  27 |  28 | 29  |  30 |  31 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     96    |    104    |    112    |    120    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     f8    |     f9    |    f10    |    f11    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  32 |  33 |  34 |  35 |  36 |  37 |  38 |  39 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    128    |    136    |    144    |    152    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    f12    |    f13    |    f14    |    f15    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  40 |  41 |  42 |  43 |  44 |  45 |  46 |  47 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    160    |    168    |    176    |           |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    fpc    |     pc    |           |           |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *******************************************************/
4aabfd
+
4aabfd
 .text
4aabfd
-.align  4 # According to the sample code in the ELF ABI docs
4aabfd
-.global jump_fcontext
4aabfd
-.type   jump_fcontext, @function
4aabfd
-
4aabfd
-#define GR_OFFSET	0
4aabfd
-#define LR_OFFSET	64
4aabfd
-#define SP_OFFSET	72
4aabfd
-#define FP_OFFSET	80
4aabfd
-#define PC_OFFSET	112
4aabfd
-#define L_CTX		120
4aabfd
-#define L_STACKFRAME	120
4aabfd
+.align	8
4aabfd
+.global	jump_fcontext
4aabfd
+.type	jump_fcontext, @function
4aabfd
+
4aabfd
+#define ARG_OFFSET         0
4aabfd
+#define GR_OFFSET	   16
4aabfd
+#define FP_OFFSET	   96
4aabfd
+#define FPC_OFFSET	   160
4aabfd
+#define PC_OFFSET	   168
4aabfd
+#define CONTEXT_SIZE	   176
4aabfd
+
4aabfd
+#define REG_SAVE_AREA_SIZE 160
4aabfd
+
4aabfd
+/*
4aabfd
+
4aabfd
+typedef void*   fcontext_t;
4aabfd
+
4aabfd
+struct transfer_t {
4aabfd
+   fcontext_t  fctx;
4aabfd
+   void    *   data;
4aabfd
+};
4aabfd
+
4aabfd
+transfer_t jump_fcontext( fcontext_t const to,
4aabfd
+			  void * data);
4aabfd
+
4aabfd
+Incoming args
4aabfd
+r2 - Hidden argument to the location where the return transfer_t needs to be returned
4aabfd
+r3 - Context we want to switch to
4aabfd
+r4 - Data pointer
4aabfd
+
4aabfd
+*/
4aabfd
 
4aabfd
 jump_fcontext:
4aabfd
-    
4aabfd
-    # Reserved the space for stack to store the data of current context
4aabfd
-    # before we jump to the new context.
4aabfd
-    aghi %r15,-L_STACKFRAME
4aabfd
-
4aabfd
-    # save the registers to the stack
4aabfd
-    stmg %r6, %r15, GR_OFFSET(%r15)
4aabfd
-
4aabfd
-    # save the floating point registers
4aabfd
-    std  %f0,FP_OFFSET(%r15)
4aabfd
-    std  %f3,FP_OFFSET+8(%r15)
4aabfd
-    std  %f5,FP_OFFSET+16(%r15)
4aabfd
-    std  %f7,FP_OFFSET+24(%r15)
4aabfd
-
4aabfd
-    # Save LR as PC
4aabfd
-    stg  %r14,PC_OFFSET(%r15)
4aabfd
-
4aabfd
-    # Store the SP pointing to the old context-data into R0
4aabfd
-    lgr	 %r0,%r15
4aabfd
-
4aabfd
-    # Get the SP pointing to the new context-data
4aabfd
-    # Note: Since the return type of the jump_fcontext is struct whose
4aabfd
-    # size is more than 8. The compiler automatically passes the 
4aabfd
-    # address of the transfer_t where the data needs to store into R2.
4aabfd
-
4aabfd
-    # Hence the first param passed to the jump_fcontext which represent
4aabfd
-    # the fctx we want to switch to is present in R3
4aabfd
-    # R2 --> Address of the return transfer_t struct
4aabfd
-    # R3 --> Context we want to switch to
4aabfd
-    # R4 --> Data
4aabfd
-    lgr	%r15,%r3
4aabfd
-
4aabfd
-    # Load the registers with the data present in context-data of the
4aabfd
-    # context we are going to switch to
4aabfd
-    lmg	%r6, %r14, GR_OFFSET(%r15)
4aabfd
-
4aabfd
-    # Restore Floating point registers
4aabfd
-    ld	 %f1,FP_OFFSET(%r15)
4aabfd
-    ld	 %f3,FP_OFFSET+8(%r15)
4aabfd
-    ld	 %f5,FP_OFFSET+16(%r15)
4aabfd
-    ld	 %f7,FP_OFFSET+24(%r15)
4aabfd
-
4aabfd
-    # Load PC
4aabfd
-    lg   %r1,PC_OFFSET(%r15)
4aabfd
-
4aabfd
-    # Adjust the stack 
4aabfd
-    aghi %r15,120
4aabfd
-
4aabfd
-    # R2 --> Address where the return transfer_t is stored
4aabfd
-    # R0 --> FCTX
4aabfd
-    # R4 --> DATA
4aabfd
-
4aabfd
-    # Store the elements to return transfer_t
4aabfd
-    stg %r15, 0(%r2)
4aabfd
-    stg %r4, 8(%r2)
4aabfd
-
4aabfd
-    # Note: The address in R2 points to the place where the return
4aabfd
-    # transfer_t is stored. Since context_function take transfer_t
4aabfd
-    # as first parameter. And R2 is the register which holds the
4aabfd
-    # first parameter value.
4aabfd
-
4aabfd
-    #jump to context
4aabfd
-    br  %r1
4aabfd
+	.machine "z10"
4aabfd
+	/* Reserve stack space to store the current context.  */
4aabfd
+	aghi	%r15,-CONTEXT_SIZE
4aabfd
 
4aabfd
-.size   jump_fcontext,.-jump_fcontext
4aabfd
-# Mark that we don't need executable stack.
4aabfd
-.section .note.GNU-stack,"",%progbits
4aabfd
+	/* Save the argument register holding the location of the return value.  */
4aabfd
+	stg	%r2,GR_OFFSET(%r15)
4aabfd
+
4aabfd
+	/* Save the call-saved general purpose registers.  */
4aabfd
+	stmg	%r6,%r14,GR_OFFSET+8(%r15)
4aabfd
+
4aabfd
+	/* Save call-saved floating point registers.  */
4aabfd
+	std	%f8,FP_OFFSET(%r15)
4aabfd
+	std	%f9,FP_OFFSET+8(%r15)
4aabfd
+	std	%f10,FP_OFFSET+16(%r15)
4aabfd
+	std	%f11,FP_OFFSET+24(%r15)
4aabfd
+	std	%f12,FP_OFFSET+32(%r15)
4aabfd
+	std	%f13,FP_OFFSET+40(%r15)
4aabfd
+	std	%f14,FP_OFFSET+48(%r15)
4aabfd
+	std	%f15,FP_OFFSET+56(%r15)
4aabfd
+
4aabfd
+	/* Save the return address as current pc.  */
4aabfd
+	stg	%r14,PC_OFFSET(%r15)
4aabfd
 
4aabfd
+	/* Save the floating point control register.  */
4aabfd
+	stfpc	FPC_OFFSET(%r15)
4aabfd
 
4aabfd
+	/* Backup the stack pointer pointing to the old context-data into r1.  */
4aabfd
+	lgr	 %r1,%r15
4aabfd
 
4aabfd
+	/* Load the new context pointer as stack pointer.  */
4aabfd
+	lgr	%r15,%r3
4aabfd
+
4aabfd
+	/* Restore the call-saved GPRs from the new context.  */
4aabfd
+	lmg	%r6,%r14,GR_OFFSET+8(%r15)
4aabfd
+
4aabfd
+	/* Restore call-saved floating point registers.  */
4aabfd
+	ld	%f8,FP_OFFSET(%r15)
4aabfd
+	ld	%f9,FP_OFFSET+8(%r15)
4aabfd
+	ld	%f10,FP_OFFSET+16(%r15)
4aabfd
+	ld	%f11,FP_OFFSET+24(%r15)
4aabfd
+	ld	%f12,FP_OFFSET+32(%r15)
4aabfd
+	ld	%f13,FP_OFFSET+40(%r15)
4aabfd
+	ld	%f14,FP_OFFSET+48(%r15)
4aabfd
+	ld	%f15,FP_OFFSET+56(%r15)
4aabfd
+
4aabfd
+	/* Load the floating point control register.  */
4aabfd
+	lfpc	FPC_OFFSET(%r15)
4aabfd
+
4aabfd
+	/* Restore PC - the location where we will jump to at the end.  */
4aabfd
+	lg	%r5,PC_OFFSET(%r15)
4aabfd
+
4aabfd
+	ltg	%r2,GR_OFFSET(%r15)
4aabfd
+	jnz	use_return_slot
4aabfd
+
4aabfd
+	/* We restore a make_fcontext context.  Use the function
4aabfd
+	   argument slot in the context we just saved and allocate the
4aabfd
+	   register save area for the target function.  */
4aabfd
+	la	%r2,ARG_OFFSET(%r1)
4aabfd
+	aghi	%r15,-REG_SAVE_AREA_SIZE
4aabfd
+
4aabfd
+use_return_slot:
4aabfd
+	/* Save the two fields in transfer_t.  When calling a
4aabfd
+	   make_fcontext function this becomes the function argument of
4aabfd
+	   the target function, otherwise it will be the return value of
4aabfd
+	   jump_fcontext.  */
4aabfd
+	stg	%r1,0(%r2)
4aabfd
+	stg	%r4,8(%r2)
4aabfd
+
4aabfd
+	/* Free the restored context.  */
4aabfd
+	aghi	%r15,CONTEXT_SIZE
4aabfd
+
4aabfd
+	/* Jump to the PC loaded from the new context.  */
4aabfd
+	br	%r5
4aabfd
+
4aabfd
+
4aabfd
+.size   jump_fcontext,.-jump_fcontext
4aabfd
+.section .note.GNU-stack,"",%progbits
4aabfd
diff --git a/src/asm/make_s390x_sysv_elf_gas.S b/src/asm/make_s390x_sysv_elf_gas.S
4aabfd
index d02856c..e7e2d5f 100644
4aabfd
--- a/libs/context/src/asm/make_s390x_sysv_elf_gas.S
4aabfd
+++ b/libs/context/src/asm/make_s390x_sysv_elf_gas.S
4aabfd
@@ -1,104 +1,108 @@
4aabfd
 /*******************************************************
4aabfd
-*                                                     *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |     0     |     8     |    16     |     24    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |    R6     |    R7     |    R8     |    R9     |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |  8  |  9  |  10 |  11 |  12 |  13 |  14 |  15 |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |     32    |    40     |     48    |     56    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |    R10    |    R11    |     R12   |     R13   |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |  16 |  17 |  18 |  19 |  20 |  21 |  22 |  23 |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |     64    |    72     |     80    |     88    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |   R14/LR  |    R15    |     F1    |     F3    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |  24 |  25 |  26 |  27 |  28 | 29  |           |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |     96    |    104    |    112    |    120    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |    F5     |    F7     |     PC    |           |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-* *****************************************************/
4aabfd
-
4aabfd
-.file  "make_s390x_sysv_elf_gas.S"
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     0     |     8     |    16     |    24     |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |   t.fctx  |   t.data  |    r2     |    r6     |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  8  |  9  |  10 |  11 |  12 |  13 |  14 |  15 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     32    |    40     |     48    |     56    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     r7    |     r8    |     r9    |    r10    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  16 |  17 |  18 |  19 |  20 |  21 |  22 |  23 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     64    |     72    |     80    |     88    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    r11    |    r12    |    r13    |    r14    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  24 |  25 |  26 |  27 |  28 | 29  |  30 |  31 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     96    |    104    |    112    |    120    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     f8    |     f9    |    f10    |    f11    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  32 |  33 |  34 |  35 |  36 |  37 |  38 |  39 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    128    |    136    |    144    |    152    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    f12    |    f13    |    f14    |    f15    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  40 |  41 |  42 |  43 |  44 |  45 |  46 |  47 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    160    |    168    |    176    |           |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    fpc    |     pc    |           |           |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *******************************************************/
4aabfd
+
4aabfd
 .text
4aabfd
-.align  4 # According to the sample code in the ELF ABI docs
4aabfd
-.global make_fcontext
4aabfd
-.type 	 make_fcontext, @function
4aabfd
-
4aabfd
-#define GR_OFFSET	0
4aabfd
-#define LR_OFFSET	64
4aabfd
-#define SP_OFFSET	72
4aabfd
-#define FP_OFFSET	80
4aabfd
-#define PC_OFFSET	112
4aabfd
-#define L_CTX		120
4aabfd
-#define L_STACKFRAME	120
4aabfd
+.align	8
4aabfd
+.global	make_fcontext
4aabfd
+.type	make_fcontext, @function
4aabfd
 
4aabfd
-make_fcontext:
4aabfd
+#define ARG_OFFSET         0
4aabfd
+#define GR_OFFSET	   16
4aabfd
+#define R14_OFFSET	   88
4aabfd
+#define FP_OFFSET	   96
4aabfd
+#define FPC_OFFSET	   160
4aabfd
+#define PC_OFFSET	   168
4aabfd
+#define CONTEXT_SIZE	   176
4aabfd
 
4aabfd
-		# make_fcontext takes in 3 arguments
4aabfd
-		# arg1 --> The address where the context needs to be made
4aabfd
-		# arg2 --> The size of the context
4aabfd
-		# arg3 --> The address of the context function
4aabfd
+/*
4aabfd
 
4aabfd
-		# According to the ELF ABI, the register R2 holds the first arg.
4aabfd
-		# R2 also acts as the register which holds return value
4aabfd
-		# Register R3 holds the second, R4 the third so on.
4aabfd
+fcontext_t make_fcontext( void * sp, std::size_t size, void (* fn)( transfer_t) );
4aabfd
 
4aabfd
-		# Shift the address in R2 to a lower 8 byte boundary
4aabfd
+Create and return a context below SP to call FN.
4aabfd
 
4aabfd
-		# This is done because according to the ELF ABI Doc, the stack needs
4aabfd
-		# to be 8 byte aligned.
4aabfd
-		# In order to do so, we need to make sure that the address is divisible
4aabfd
-		# by 8. We can check this, by checking if the the last 3 bits of the
4aabfd
-		# address is zero or not. If not AND it with `-8`. 
4aabfd
+Incoming args
4aabfd
+r2 - The stack location where to create the context
4aabfd
+r3 - The size of the context
4aabfd
+r4 - The address of the context function
4aabfd
 
4aabfd
-		# Here we AND the lower 16 bits of the memory address present in the 
4aabfd
-		# R2 with the bits 1111 1111 1111 1000 
4aabfd
-		nill    %r2,0xfff0
4aabfd
+*/
4aabfd
 
4aabfd
-		# Reserve space for context-data on context-stack.
4aabfd
-		# This is done by shifting the SP/address by 112 bytes.
4aabfd
-		aghi	%r2,-L_CTX
4aabfd
+make_fcontext:
4aabfd
+	.machine "z10"
4aabfd
+	/* Align the stack to an 8 byte boundary.  */
4aabfd
+	nill    %r2,0xfff0
4aabfd
 
4aabfd
-		# third arg of make_fcontext() == address of the context-function
4aabfd
-		# Store the address as a PC to jump in, whenever we call the 
4aabfd
-		# make_fcontext.
4aabfd
-		stg 	%r4,PC_OFFSET(%r2)
4aabfd
+	/* Allocate stack space for the context.  */
4aabfd
+	aghi	%r2,-CONTEXT_SIZE
4aabfd
 
4aabfd
-		# Save the address of finish as return-address for context-function
4aabfd
-		# This will be entered after context-function return
4aabfd
-		# The address of finish will be saved in Link register, this register
4aabfd
-		# specifies where we need to jump after the function executes
4aabfd
-		# completely.
4aabfd
-		larl 	%r1,finish
4aabfd
-		stg  	%r1,LR_OFFSET(%r2)
4aabfd
+	/* Set the r2 save slot to zero.  This indicates jump_fcontext
4aabfd
+	   that this is a special context.  */
4aabfd
+	mvghi	GR_OFFSET(%r2),0
4aabfd
 
4aabfd
-		# Return pointer to context data
4aabfd
-		# R14 acts as the link register
4aabfd
-		# R2 holds the address of the context stack. When we return from the
4aabfd
-		# make_fcontext, R2 is passed back.
4aabfd
-		br 	%r14 
4aabfd
+	/* Save the floating point control register.  */
4aabfd
+	stfpc	FPC_OFFSET(%r2)
4aabfd
 
4aabfd
-	finish:
4aabfd
+	/* Store the address of the target function as new pc.  */
4aabfd
+	stg	%r4,PC_OFFSET(%r2)
4aabfd
 
4aabfd
-		# In finish tasks, you load the exit code and exit the make_fcontext
4aabfd
-		# This is called when the context-function is entirely executed
4aabfd
+	/* Store a pointer to the finish routine as r14. If a function
4aabfd
+	   called via context routines just returns that value will be
4aabfd
+	   loaded and used as return address.  Hence the program will
4aabfd
+	   just exit.  */
4aabfd
+	larl	%r1,finish
4aabfd
+	stg	%r1,R14_OFFSET(%r2)
4aabfd
 
4aabfd
-		lghi 	%r2,0
4aabfd
-		brasl 	%r14,_exit@PLT
4aabfd
+	/* Return as usual with the new context returned in r2.  */
4aabfd
+	br	%r14
4aabfd
+
4aabfd
+finish:
4aabfd
+	/* In finish tasks, you load the exit code and exit the
4aabfd
+	   make_fcontext This is called when the context-function is
4aabfd
+	   entirely executed.  */
4aabfd
+	lghi	%r2,0
4aabfd
+	brasl	%r14,_exit@PLT
4aabfd
 
4aabfd
 .size   make_fcontext,.-make_fcontext
4aabfd
-# Mark that we don't need executable stack.
4aabfd
 .section .note.GNU-stack,"",%progbits
4aabfd
-
4aabfd
diff --git a/src/asm/ontop_s390x_sysv_elf_gas.S b/src/asm/ontop_s390x_sysv_elf_gas.S
4aabfd
index 4488654..709b3d6 100644
4aabfd
--- a/libs/context/src/asm/ontop_s390x_sysv_elf_gas.S
4aabfd
+++ b/libs/context/src/asm/ontop_s390x_sysv_elf_gas.S
4aabfd
@@ -1,112 +1,146 @@
4aabfd
 /*******************************************************
4aabfd
-*                                                     *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |     0     |     8     |    16     |     24    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |    R6     |    R7     |    R8     |    R9     |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |  8  |  9  |  10 |  11 |  12 |  13 |  14 |  15 |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |     32    |    40     |     48    |     56    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |    R10    |    R11    |     R12   |     R13   |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |  16 |  17 |  18 |  19 |  20 |  21 |  22 |  23 |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |     64    |    72     |     80    |     88    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |   R14/LR  |    R15    |     F1    |     F3    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |  24 |  25 |  26 |  27 |  28 | 29  |           |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |     96    |    104    |    112    |    120    |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-*  |    F5     |    F7     |     PC    |           |  *
4aabfd
-*  -------------------------------------------------  *
4aabfd
-* *****************************************************/
4aabfd
-
4aabfd
-.file  "ontop_s390x_sysv_elf_gas.S"
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     0     |     8     |    16     |    24     |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |   t.fctx  |   t.data  |    r2     |    r6     |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  8  |  9  |  10 |  11 |  12 |  13 |  14 |  15 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     32    |    40     |     48    |     56    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     r7    |     r8    |     r9    |    r10    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  16 |  17 |  18 |  19 |  20 |  21 |  22 |  23 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     64    |     72    |     80    |     88    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    r11    |    r12    |    r13    |    r14    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  24 |  25 |  26 |  27 |  28 | 29  |  30 |  31 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     96    |    104    |    112    |    120    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |     f8    |     f9    |    f10    |    f11    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  32 |  33 |  34 |  35 |  36 |  37 |  38 |  39 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    128    |    136    |    144    |    152    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    f12    |    f13    |    f14    |    f15    |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |  40 |  41 |  42 |  43 |  44 |  45 |  46 |  47 |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    160    |    168    |    176    |           |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *  |    fpc    |     pc    |           |           |  *
4aabfd
+ *  -------------------------------------------------  *
4aabfd
+ *******************************************************/
4aabfd
+
4aabfd
 .text
4aabfd
-.align  4 # According to the sample code in the ELF ABI docs
4aabfd
+.align  8
4aabfd
 .global ontop_fcontext
4aabfd
 .type   ontop_fcontext, @function
4aabfd
 
4aabfd
-#define GR_OFFSET	0
4aabfd
-#define LR_OFFSET	64
4aabfd
-#define SP_OFFSET	72
4aabfd
-#define FP_OFFSET	80
4aabfd
-#define PC_OFFSET	112
4aabfd
-#define L_CTX		120
4aabfd
+#define ARG_OFFSET         0
4aabfd
+#define GR_OFFSET	   16
4aabfd
+#define R14_OFFSET	   88
4aabfd
+#define FP_OFFSET	   96
4aabfd
+#define FPC_OFFSET	   160
4aabfd
+#define PC_OFFSET	   168
4aabfd
+#define CONTEXT_SIZE	   176
4aabfd
+
4aabfd
+
4aabfd
+/*
4aabfd
+
4aabfd
+typedef void*   fcontext_t;
4aabfd
+
4aabfd
+struct transfer_t {
4aabfd
+   fcontext_t  fctx;
4aabfd
+   void    *   data;
4aabfd
+};
4aabfd
+
4aabfd
+transfer_t ontop_fcontext( fcontext_t const to,
4aabfd
+			   void * vp,
4aabfd
+			   transfer_t (* fn)( transfer_t) );
4aabfd
+
4aabfd
+Incoming args
4aabfd
+r2 - Hidden argument to the location where the return transfer_t needs to be returned
4aabfd
+r3 - Target context
4aabfd
+r4 - Data pointer
4aabfd
+r5 - Function to be executed
4aabfd
+
4aabfd
+This implementation assumes that ontop_fcontext will never be called with target contexts
4aabfd
+created via make_fcontext.
4aabfd
+
4aabfd
+*/
4aabfd
 
4aabfd
 ontop_fcontext:
4aabfd
-    
4aabfd
-    # Reserved the space for stack to store the data of current context
4aabfd
-    # before we jump to the new context.
4aabfd
-    aghi %r15,-L_CTX
4aabfd
-
4aabfd
-    # save the registers to the stack
4aabfd
-    stmg %r6, %r15, GR_OFFSET(%r15)
4aabfd
-
4aabfd
-    # save the floating point registers
4aabfd
-    std  %f0,FP_OFFSET(%r15)
4aabfd
-    std  %f3,FP_OFFSET+8(%r15)
4aabfd
-    std  %f5,FP_OFFSET+16(%r15)
4aabfd
-    std  %f7,FP_OFFSET+24(%r15)
4aabfd
-    # Save LR as PC
4aabfd
-    stg  %r14,PC_OFFSET(%r15)
4aabfd
-
4aabfd
-    # Store the SP pointing to the old context-data into R0
4aabfd
-    lgr  %r0,%r15
4aabfd
-
4aabfd
-    # Get the SP pointing to the new context-data
4aabfd
-    # Note: Since the return type of the jump_fcontext is struct whose
4aabfd
-    # size is more than 8. The compiler automatically passes the 
4aabfd
-    # address of the transfer_t where the data needs to store into R2.
4aabfd
-
4aabfd
-    # Hence the first param passed to the jump_fcontext which represent
4aabfd
-    # the fctx we want to switch to is present in R3
4aabfd
-    # R2 --> Address of the return transfer_t struct
4aabfd
-    # R3 --> Context we want to switch to
4aabfd
-    # R4 --> Data
4aabfd
-    lgr  %r15,%r3
4aabfd
-
4aabfd
-    # Load the registers with the data present in context-data of the
4aabfd
-    # context we are going to switch to
4aabfd
-    lmg  %r6,%r15,GR_OFFSET(%r15)
4aabfd
-
4aabfd
-    # Restore Floating point registers
4aabfd
-    ld	 %f1,FP_OFFSET(%r15)
4aabfd
-    ld	 %f3,FP_OFFSET+8(%r15)
4aabfd
-    ld	 %f5,FP_OFFSET+16(%r15)
4aabfd
-    ld	 %f7,FP_OFFSET+24(%r15)
4aabfd
-
4aabfd
-    # Skip PC
4aabfd
-
4aabfd
-    # Adjust the stack
4aabfd
-    aghi %r15,L_CTX
4aabfd
-
4aabfd
-    # R2 --> Address where the return transfer_t is stored
4aabfd
-    # R0 --> FCTX
4aabfd
-    # R4 --> DATA
4aabfd
-    # R5 --> Context function
4aabfd
-
4aabfd
-    # Store the elements to return transfer_t
4aabfd
-    stg  %r15, 0(%r2)
4aabfd
-    stg  %r4, 8(%r2)
4aabfd
-
4aabfd
-    # Note: The address in R2 points to the place where the return
4aabfd
-    # transfer_t is stored. Since context_function take transfer_t
4aabfd
-    # as first parameter. And R2 is the register which holds the
4aabfd
-    # first parameter value.
4aabfd
-
4aabfd
-    #jump to context function
4aabfd
-    br 	%r5
4aabfd
+	/* Reserve stack space to store the current context.  */
4aabfd
+	aghi	%r15,-CONTEXT_SIZE
4aabfd
+
4aabfd
+	/* Save the argument register holding the location of the return value.  */
4aabfd
+	stg	%r2,GR_OFFSET(%r15)
4aabfd
+
4aabfd
+	/* Save the call-saved general purpose registers.  */
4aabfd
+	stmg	%r6,%r14,GR_OFFSET+8(%r15)
4aabfd
+
4aabfd
+	/* Save call-saved floating point registers.  */
4aabfd
+	std	%f8,FP_OFFSET(%r15)
4aabfd
+	std	%f9,FP_OFFSET+8(%r15)
4aabfd
+	std	%f10,FP_OFFSET+16(%r15)
4aabfd
+	std	%f11,FP_OFFSET+24(%r15)
4aabfd
+	std	%f12,FP_OFFSET+32(%r15)
4aabfd
+	std	%f13,FP_OFFSET+40(%r15)
4aabfd
+	std	%f14,FP_OFFSET+48(%r15)
4aabfd
+	std	%f15,FP_OFFSET+56(%r15)
4aabfd
+
4aabfd
+	/* Save the return address as current pc.  */
4aabfd
+	stg	%r14,PC_OFFSET(%r15)
4aabfd
+
4aabfd
+	/* Save the floating point control register.  */
4aabfd
+	stfpc   FPC_OFFSET(%r15)
4aabfd
+
4aabfd
+	/* Backup the stack pointer pointing to the old context-data into r1.  */
4aabfd
+	lgr	%r1,%r15
4aabfd
+
4aabfd
+	/* Load the new context pointer as stack pointer.  */
4aabfd
+	lgr	%r15,%r3
4aabfd
+
4aabfd
+	/* Restore the call-saved GPRs from the new context.  */
4aabfd
+	lmg	%r6,%r14,GR_OFFSET+8(%r15)
4aabfd
+
4aabfd
+	/* Restore call-saved floating point registers.  */
4aabfd
+	ld	%f8,FP_OFFSET(%r15)
4aabfd
+	ld	%f9,FP_OFFSET+8(%r15)
4aabfd
+	ld	%f10,FP_OFFSET+16(%r15)
4aabfd
+	ld	%f11,FP_OFFSET+24(%r15)
4aabfd
+	ld	%f12,FP_OFFSET+32(%r15)
4aabfd
+	ld	%f13,FP_OFFSET+40(%r15)
4aabfd
+	ld	%f14,FP_OFFSET+48(%r15)
4aabfd
+	ld	%f15,FP_OFFSET+56(%r15)
4aabfd
+
4aabfd
+	/* Load the floating point control register.  */
4aabfd
+	lfpc   FPC_OFFSET(%r15)
4aabfd
+
4aabfd
+	/* Store the transfer_t values located in the saved context.  */
4aabfd
+	stg	%r1,0(%r1)	       /* transfer_t.fctx = old context */
4aabfd
+	stg	%r4,8(%r1)             /* transfer_t.data = data */
4aabfd
+
4aabfd
+	/* Set up the arguments for the target function.  */
4aabfd
+	lg	%r2,GR_OFFSET(%r15)
4aabfd
+	lgr	%r3,%r1
4aabfd
+
4aabfd
+	/* Deallocate the context.  */
4aabfd
+	aghi	%r15,CONTEXT_SIZE
4aabfd
+
4aabfd
+	br	%r5
4aabfd
 
4aabfd
 .size   ontop_fcontext,.-ontop_fcontext
4aabfd
-# Mark that we don't need executable stack.
4aabfd
 .section .note.GNU-stack,"",%progbits
4aabfd
-- 
4aabfd
2.18.1
4aabfd