Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions build/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,19 @@ alias asm_sources
<toolset>gcc
;

# 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
Expand Down
4 changes: 4 additions & 0 deletions build/architecture.jam
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ rule deduce-architecture ( properties * )
{
return <architecture>riscv ;
}
else if [ configure.builds /boost/architecture//s390x : $(properties) : s390x ]
{
return <architecture>s390x ;
}
else if [ configure.builds /boost/architecture//sparc : $(properties) : sparc ]
{
return <architecture>sparc ;
Expand Down
145 changes: 145 additions & 0 deletions src/asm/jump_s390x_sysv_elf_gas.S
Original file line number Diff line number Diff line change
@@ -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



97 changes: 97 additions & 0 deletions src/asm/make_s390x_sysv_elf_gas.S
Original file line number Diff line number Diff line change
@@ -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

Loading