62e5e2
From ffa7c8b7f8033413d7088edcd9947bf782b9d3fd Mon Sep 17 00:00:00 2001
62e5e2
From: Andreas Krebbel <krebbel@linux.ibm.com>
62e5e2
Date: Mon, 23 Mar 2020 09:04:54 +0100
62e5e2
Subject: [PATCH 1/4] S390x: Add Support for s390x arch
62e5e2
62e5e2
---
62e5e2
 build/Jamfile.v2                   |  13 +++
62e5e2
 build/architecture.jam             |   4 +
62e5e2
 src/asm/jump_s390x_sysv_elf_gas.S  | 145 +++++++++++++++++++++++++++++
62e5e2
 src/asm/make_s390x_sysv_elf_gas.S  |  97 +++++++++++++++++++
62e5e2
 src/asm/ontop_s390x_sysv_elf_gas.S | 143 ++++++++++++++++++++++++++++
62e5e2
 5 files changed, 402 insertions(+)
62e5e2
 create mode 100644 src/asm/jump_s390x_sysv_elf_gas.S
62e5e2
 create mode 100644 src/asm/make_s390x_sysv_elf_gas.S
62e5e2
 create mode 100644 src/asm/ontop_s390x_sysv_elf_gas.S
62e5e2
62e5e2
diff --git a/build/Jamfile.v2 b/build/Jamfile.v2
62e5e2
index 719ca91..08f1675 100644
62e5e2
--- a/libs/context/build/Jamfile.v2
62e5e2
+++ b/libs/context/build/Jamfile.v2
62e5e2
@@ -447,6 +447,19 @@ alias asm_sources
62e5e2
      <binary-format>mach-o
62e5e2
    ;
62e5e2
 
62e5e2
+# S390X
62e5e2
+# S390X/SYSV/ELF
62e5e2
+alias asm_sources
62e5e2
+   : asm/make_s390x_sysv_elf_gas.S
62e5e2
+     asm/jump_s390x_sysv_elf_gas.S
62e5e2
+     asm/ontop_s390x_sysv_elf_gas.S
62e5e2
+   : <abi>sysv
62e5e2
+     <address-model>64
62e5e2
+     <architecture>s390x
62e5e2
+     <binary-format>elf
62e5e2
+     <toolset>gcc
62e5e2
+   ;
62e5e2
+
62e5e2
 # X86
62e5e2
 # X86/SYSV/ELF
62e5e2
 alias asm_sources
62e5e2
diff --git a/build/architecture.jam b/build/architecture.jam
62e5e2
index 81dcb49..f62806d 100644
62e5e2
--- a/libs/context/build/architecture.jam
62e5e2
+++ b/libs/context/build/architecture.jam
62e5e2
@@ -63,6 +63,10 @@ rule deduce-architecture ( properties * )
62e5e2
         {
62e5e2
             return <architecture>power ;
62e5e2
         }
62e5e2
+        else if [ configure.builds /boost/architecture//s390x : $(properties) : s390x ]
62e5e2
+        {
62e5e2
+            return <architecture>s390x ;
62e5e2
+        }
62e5e2
         else if [ configure.builds /boost/architecture//sparc : $(properties) : sparc ]
62e5e2
         {
62e5e2
             return <architecture>sparc ;
62e5e2
diff --git a/src/asm/jump_s390x_sysv_elf_gas.S b/src/asm/jump_s390x_sysv_elf_gas.S
62e5e2
new file mode 100644
62e5e2
index 0000000..c011d53
62e5e2
--- /dev/null
62e5e2
+++ b/libs/context/src/asm/jump_s390x_sysv_elf_gas.S
62e5e2
@@ -0,0 +1,145 @@
62e5e2
+/*******************************************************
62e5e2
+*                                                     *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |     0     |     8     |    16     |     24    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |    R6     |    R7     |    R8     |    R9     |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |  8  |  9  |  10 |  11 |  12 |  13 |  14 |  15 |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |     32    |    40     |     48    |     56    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |    R10    |    R11    |     R12   |     R13   |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |  16 |  17 |  18 |  19 |  20 |  21 |  22 |  23 |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |     64    |    72     |     80    |     88    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |   R14/LR  |    R15    |     F1    |     F3    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |  24 |  25 |  26 |  27 |  28 | 29  |           |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |     96    |    104    |    112    |    120    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |    F5     |    F7     |     PC    |           |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+* *****************************************************/
62e5e2
+
62e5e2
+.file  "jump_s390x_sysv_elf_gas.S"
62e5e2
+.text
62e5e2
+.align  4 # According to the sample code in the ELF ABI docs
62e5e2
+.global jump_fcontext
62e5e2
+.type   jump_fcontext, @function
62e5e2
+
62e5e2
+jump_fcontext:
62e5e2
+    
62e5e2
+    # Reserved the space for stack to store the data of current context
62e5e2
+    # before we jump to the new context.
62e5e2
+    lay 15,-120(15)
62e5e2
+
62e5e2
+    # save the registers to the stack
62e5e2
+    stg 6,  0(15)       # save R6     
62e5e2
+    stg 7,  8(15)       # save R7     
62e5e2
+    stg 8,  16(15)      # save R8
62e5e2
+    stg 9,  24(15)      # save R9
62e5e2
+    stg 10, 32(15)      # save R10
62e5e2
+    stg 11, 40(15)      # save R11
62e5e2
+    stg 12, 48(15)      # save R12
62e5e2
+    stg 13, 56(15)      # save R13
62e5e2
+    stg 14, 64(15)      # save R14
62e5e2
+    stg 15, 72(15)      # save R15
62e5e2
+
62e5e2
+    # save the floating point registers
62e5e2
+    # Load the FPR into R0 then save it to the stack
62e5e2
+    # Load F1 into R0
62e5e2
+    lgdr 0,1 
62e5e2
+    stg  0,80(15)       # save F1
62e5e2
+
62e5e2
+    # Load F3 into R0
62e5e2
+    lgdr 0,3
62e5e2
+    stg  0,88(15)       # save F3
62e5e2
+
62e5e2
+    # Load F5 into R0
62e5e2
+    lgdr 0,5
62e5e2
+    stg  0,96(15)       # save F5
62e5e2
+
62e5e2
+    # Load F7 into R0
62e5e2
+    lgdr 0,7
62e5e2
+    stg  0,104(15)      # save F7
62e5e2
+
62e5e2
+    # Save LR as PC
62e5e2
+    stg 14,112(15)
62e5e2
+
62e5e2
+    # Store the SP pointing to the old context-data into R0
62e5e2
+    lgr 0,15
62e5e2
+
62e5e2
+    # Get the SP pointing to the new context-data
62e5e2
+    # Note: Since the return type of the jump_fcontext is struct whose
62e5e2
+    # size is more than 8. The compiler automatically passes the 
62e5e2
+    # address of the transfer_t where the data needs to store into R2.
62e5e2
+
62e5e2
+    # Hence the first param passed to the jump_fcontext which represent
62e5e2
+    # the fctx we want to switch to is present in R3
62e5e2
+    # R2 --> Address of the return transfer_t struct
62e5e2
+    # R3 --> Context we want to switch to
62e5e2
+    # R4 --> Data
62e5e2
+    lgr 15,3
62e5e2
+
62e5e2
+    # Load the registers with the data present in context-data of the
62e5e2
+    # context we are going to switch to
62e5e2
+    lg 6,  0(15)       # restore R6     
62e5e2
+    lg 7,  8(15)       # restore R7     
62e5e2
+    lg 8,  16(15)      # restore R8
62e5e2
+    lg 9,  24(15)      # restore R9
62e5e2
+    lg 10, 32(15)      # restore R10
62e5e2
+    lg 11, 40(15)      # restore R11
62e5e2
+    lg 12, 48(15)      # restore R12
62e5e2
+    lg 13, 56(15)      # restore R13
62e5e2
+    lg 14, 64(15)      # restore R14
62e5e2
+
62e5e2
+    # Restore Floating point registers
62e5e2
+    lg   1,80(15)
62e5e2
+    ldgr 1,1            # restore F1
62e5e2
+
62e5e2
+    lg   1,88(15)
62e5e2
+    ldgr 1,3            # restore F3
62e5e2
+
62e5e2
+    lg   1,96(15)
62e5e2
+    ldgr 1,5            # restore F5
62e5e2
+
62e5e2
+    lg   1,104(15)
62e5e2
+    ldgr 1,7            # restore F7
62e5e2
+
62e5e2
+    # Load PC
62e5e2
+    lg  1,112(15)
62e5e2
+
62e5e2
+    # Adjust the stack
62e5e2
+    lay 15, 120(15)
62e5e2
+
62e5e2
+    # R2 --> Address where the return transfer_t is stored
62e5e2
+    # R0 --> FCTX
62e5e2
+    # R4 --> DATA
62e5e2
+
62e5e2
+    # Store the elements to return transfer_t
62e5e2
+    stg 15, 0(2)
62e5e2
+    stg 4, 8(2)
62e5e2
+
62e5e2
+    # Note: The address in R2 points to the place where the return
62e5e2
+    # transfer_t is stored. Since context_function take transfer_t
62e5e2
+    # as first parameter. And R2 is the register which holds the
62e5e2
+    # first parameter value.
62e5e2
+
62e5e2
+    #jump to context
62e5e2
+    br 1
62e5e2
+
62e5e2
+.size   jump_fcontext,.-jump_fcontext
62e5e2
+# Mark that we don't need executable stack.
62e5e2
+.section .note.GNU-stack,"",%progbits
62e5e2
+
62e5e2
+
62e5e2
+
62e5e2
diff --git a/src/asm/make_s390x_sysv_elf_gas.S b/src/asm/make_s390x_sysv_elf_gas.S
62e5e2
new file mode 100644
62e5e2
index 0000000..f566533
62e5e2
--- /dev/null
62e5e2
+++ b/libs/context/src/asm/make_s390x_sysv_elf_gas.S
62e5e2
@@ -0,0 +1,97 @@
62e5e2
+/*******************************************************
62e5e2
+*                                                     *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |     0     |     8     |    16     |     24    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |    R6     |    R7     |    R8     |    R9     |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |  8  |  9  |  10 |  11 |  12 |  13 |  14 |  15 |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |     32    |    40     |     48    |     56    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |    R10    |    R11    |     R12   |     R13   |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |  16 |  17 |  18 |  19 |  20 |  21 |  22 |  23 |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |     64    |    72     |     80    |     88    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |   R14/LR  |    R15    |     F1    |     F3    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |  24 |  25 |  26 |  27 |  28 | 29  |           |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |     96    |    104    |    112    |    120    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |    F5     |    F7     |     PC    |           |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+* *****************************************************/
62e5e2
+
62e5e2
+.file  "make_s390x_sysv_elf_gas.S"
62e5e2
+.text
62e5e2
+.align  4 # According to the sample code in the ELF ABI docs
62e5e2
+.global make_fcontext
62e5e2
+.type 	 make_fcontext, @function
62e5e2
+
62e5e2
+make_fcontext:
62e5e2
+
62e5e2
+		# make_fcontext takes in 3 arguments
62e5e2
+		# arg1 --> The address where the context needs to be made
62e5e2
+		# arg2 --> The size of the context
62e5e2
+		# arg3 --> The address of the context function
62e5e2
+
62e5e2
+		# According to the ELF ABI, the register R2 holds the first arg.
62e5e2
+		# R2 also acts as the register which holds return value
62e5e2
+		# Register R3 holds the second, R4 the third so on.
62e5e2
+
62e5e2
+		# Shift the address in R2 to a lower 8 byte boundary
62e5e2
+
62e5e2
+		# This is done because according to the ELF ABI Doc, the stack needs
62e5e2
+		# to be 8 byte aligned.
62e5e2
+		# In order to do so, we need to make sure that the address is divisible
62e5e2
+		# by 8. We can check this, by checking if the the last 3 bits of the
62e5e2
+		# address is zero or not. If not AND it with `-8`. 
62e5e2
+
62e5e2
+		# Here we AND the lower 16 bits of the memory address present in the 
62e5e2
+		# R2 with the bits 1111 1111 1111 1000 which when converted into
62e5e2
+		# decimal is 65528
62e5e2
+		nill    2,65528
62e5e2
+
62e5e2
+		# Reserve space for context-data on context-stack.
62e5e2
+		# This is done by shifting the SP/address by 112 bytes.
62e5e2
+		lay 2,-120(2)
62e5e2
+
62e5e2
+		# third arg of make_fcontext() == address of the context-function
62e5e2
+		# Store the address as a PC to jump in, whenever we call the 
62e5e2
+		# make_fcontext.
62e5e2
+		stg 4,112(2)
62e5e2
+
62e5e2
+		# Save the address of finish as return-address for context-function
62e5e2
+		# This will be entered after context-function return
62e5e2
+		# The address of finish will be saved in Link register, this register
62e5e2
+		# specifies where we need to jump after the function executes
62e5e2
+		# completely.
62e5e2
+		larl 1,finish
62e5e2
+		stg  1,64(2)
62e5e2
+
62e5e2
+		# Return pointer to context data
62e5e2
+		# R14 acts as the link register
62e5e2
+		# R2 holds the address of the context stack. When we return from the
62e5e2
+		# make_fcontext, R2 is passed back.
62e5e2
+		br 14 
62e5e2
+
62e5e2
+	finish:
62e5e2
+
62e5e2
+		# In finish tasks, you load the exit code and exit the make_fcontext
62e5e2
+		# This is called when the context-function is entirely executed
62e5e2
+
62e5e2
+		lghi 2,0
62e5e2
+		brasl 14,_exit
62e5e2
+
62e5e2
+.size   make_fcontext,.-make_fcontext
62e5e2
+# Mark that we don't need executable stack.
62e5e2
+.section .note.GNU-stack,"",%progbits
62e5e2
+
62e5e2
diff --git a/src/asm/ontop_s390x_sysv_elf_gas.S b/src/asm/ontop_s390x_sysv_elf_gas.S
62e5e2
new file mode 100644
62e5e2
index 0000000..7ab2cf5
62e5e2
--- /dev/null
62e5e2
+++ b/libs/context/src/asm/ontop_s390x_sysv_elf_gas.S
62e5e2
@@ -0,0 +1,143 @@
62e5e2
+/*******************************************************
62e5e2
+*                                                     *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |     0     |     8     |    16     |     24    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |    R6     |    R7     |    R8     |    R9     |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |  8  |  9  |  10 |  11 |  12 |  13 |  14 |  15 |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |     32    |    40     |     48    |     56    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |    R10    |    R11    |     R12   |     R13   |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |  16 |  17 |  18 |  19 |  20 |  21 |  22 |  23 |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |     64    |    72     |     80    |     88    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |   R14/LR  |    R15    |     F1    |     F3    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |  24 |  25 |  26 |  27 |  28 | 29  |           |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |     96    |    104    |    112    |    120    |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+*  |    F5     |    F7     |     PC    |           |  *
62e5e2
+*  -------------------------------------------------  *
62e5e2
+* *****************************************************/
62e5e2
+
62e5e2
+.file  "ontop_s390x_sysv_elf_gas.S"
62e5e2
+.text
62e5e2
+.align  4 # According to the sample code in the ELF ABI docs
62e5e2
+.global ontop_fcontext
62e5e2
+.type   ontop_fcontext, @function
62e5e2
+
62e5e2
+ontop_fcontext:
62e5e2
+    
62e5e2
+    # Reserved the space for stack to store the data of current context
62e5e2
+    # before we jump to the new context.
62e5e2
+    lay 15,-120(15)
62e5e2
+
62e5e2
+    # save the registers to the stack
62e5e2
+    stg 6,  0(15)       # save R6     
62e5e2
+    stg 7,  8(15)       # save R7     
62e5e2
+    stg 8,  16(15)      # save R8
62e5e2
+    stg 9,  24(15)      # save R9
62e5e2
+    stg 10, 32(15)      # save R10
62e5e2
+    stg 11, 40(15)      # save R11
62e5e2
+    stg 12, 48(15)      # save R12
62e5e2
+    stg 13, 56(15)      # save R13
62e5e2
+    stg 14, 64(15)      # save R14
62e5e2
+    stg 15, 72(15)      # save R15
62e5e2
+
62e5e2
+    # save the floating point registers
62e5e2
+    # Load the FPR into R0 then save it to the stack
62e5e2
+    # Load F1 into R0
62e5e2
+    lgdr 0,1 
62e5e2
+    stg  0,80(15)       # save F1
62e5e2
+
62e5e2
+    # Load F3 into R0
62e5e2
+    lgdr 0,3
62e5e2
+    stg  0,88(15)       # save F3
62e5e2
+
62e5e2
+    # Load F5 into R0
62e5e2
+    lgdr 0,5
62e5e2
+    stg  0,96(15)       # save F5
62e5e2
+
62e5e2
+    # Load F7 into R0
62e5e2
+    lgdr 0,7
62e5e2
+    stg  0,104(15)      # save F7
62e5e2
+
62e5e2
+    # Save LR as PC
62e5e2
+    stg 14,112(15)
62e5e2
+
62e5e2
+    # Store the SP pointing to the old context-data into R0
62e5e2
+    lgr 0,15
62e5e2
+
62e5e2
+    # Get the SP pointing to the new context-data
62e5e2
+    # Note: Since the return type of the jump_fcontext is struct whose
62e5e2
+    # size is more than 8. The compiler automatically passes the 
62e5e2
+    # address of the transfer_t where the data needs to store into R2.
62e5e2
+
62e5e2
+    # Hence the first param passed to the jump_fcontext which represent
62e5e2
+    # the fctx we want to switch to is present in R3
62e5e2
+    # R2 --> Address of the return transfer_t struct
62e5e2
+    # R3 --> Context we want to switch to
62e5e2
+    # R4 --> Data
62e5e2
+    lgr 15,3
62e5e2
+
62e5e2
+    # Load the registers with the data present in context-data of the
62e5e2
+    # context we are going to switch to
62e5e2
+    lg 6,  0(15)       # restore R6     
62e5e2
+    lg 7,  8(15)       # restore R7     
62e5e2
+    lg 8,  16(15)      # restore R8
62e5e2
+    lg 9,  24(15)      # restore R9
62e5e2
+    lg 10, 32(15)      # restore R10
62e5e2
+    lg 11, 40(15)      # restore R11
62e5e2
+    lg 12, 48(15)      # restore R12
62e5e2
+    lg 13, 56(15)      # restore R13
62e5e2
+    lg 14, 64(15)      # restore R14
62e5e2
+    lg 15, 72(15)      # restore R15
62e5e2
+
62e5e2
+    # Restore Floating point registers
62e5e2
+    lg   1,80(15)
62e5e2
+    ldgr 1,1            # restore F1
62e5e2
+
62e5e2
+    lg   1,88(15)
62e5e2
+    ldgr 1,3            # restore F3
62e5e2
+
62e5e2
+    lg   1,96(15)
62e5e2
+    ldgr 1,5            # restore F5
62e5e2
+
62e5e2
+    lg   1,104(15)
62e5e2
+    ldgr 1,7            # restore F7
62e5e2
+
62e5e2
+    # Skip PC
62e5e2
+
62e5e2
+    # Adjust the stack
62e5e2
+    lay 15, 120(15)
62e5e2
+
62e5e2
+    # R2 --> Address where the return transfer_t is stored
62e5e2
+    # R0 --> FCTX
62e5e2
+    # R4 --> DATA
62e5e2
+    # R5 --> Context function
62e5e2
+
62e5e2
+    # Store the elements to return transfer_t
62e5e2
+    stg 15, 0(2)
62e5e2
+    stg 4, 8(2)
62e5e2
+
62e5e2
+    # Note: The address in R2 points to the place where the return
62e5e2
+    # transfer_t is stored. Since context_function take transfer_t
62e5e2
+    # as first parameter. And R2 is the register which holds the
62e5e2
+    # first parameter value.
62e5e2
+
62e5e2
+    #jump to context function
62e5e2
+    br 5
62e5e2
+
62e5e2
+.size   ontop_fcontext,.-ontop_fcontext
62e5e2
+# Mark that we don't need executable stack.
62e5e2
+.section .note.GNU-stack,"",%progbits
62e5e2
-- 
62e5e2
2.18.1
62e5e2