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