Path: blob/main/crates/fiber/src/stackswitch/s390x.S
1693 views
// A WORD OF CAUTION1//2// This entire file basically needs to be kept in sync with itself. It's not3// really possible to modify just one bit of this file without understanding4// all the other bits. Documentation tries to reference various bits here and5// there but try to make sure to read over everything before tweaking things!6//7// Also at this time this file is heavily based off the x86_64 file, so you'll8// probably want to read that one as well.910.text1112#define CONCAT2(a, b) a ## b13#define CONCAT(a, b) CONCAT2(a , b)14#define VERSIONED_SYMBOL(a) CONCAT(a, VERSIONED_SUFFIX)15#define GLOBL(fnname) .globl VERSIONED_SYMBOL(fnname)16#define HIDDEN(fnname) .hidden VERSIONED_SYMBOL(fnname)17#define TYPE(fnname) .type VERSIONED_SYMBOL(fnname),@function18#define FUNCTION(fnname) VERSIONED_SYMBOL(fnname)19#define SIZE(fnname) .size VERSIONED_SYMBOL(fnname),.-VERSIONED_SYMBOL(fnname)2021// fn(top_of_stack(%x0): *mut u8)22HIDDEN(wasmtime_fiber_switch)23GLOBL(wasmtime_fiber_switch)24.p2align 225TYPE(wasmtime_fiber_switch)26FUNCTION(wasmtime_fiber_switch):27// Save all callee-saved registers on the stack since we're assuming28// they're clobbered as a result of the stack switch.29stmg %r6, %r15, 48(%r15)30aghi %r15, -6431std %f8, 0(%r15)32std %f9, 8(%r15)33std %f10, 16(%r15)34std %f11, 24(%r15)35std %f12, 32(%r15)36std %f13, 40(%r15)37std %f14, 48(%r15)38std %f15, 56(%r15)3940// Load our previously saved stack pointer to resume to, and save off our41// current stack pointer on where to come back to eventually.42lg %r1, -16(%r2)43stg %r15, -16(%r2)4445// Switch to the new stack and restore all our callee-saved registers after46// the switch and return to our new stack.47ld %f8, 0(%r1)48ld %f9, 8(%r1)49ld %f10, 16(%r1)50ld %f11, 24(%r1)51ld %f12, 32(%r1)52ld %f13, 40(%r1)53ld %f14, 48(%r1)54ld %f15, 56(%r1)55lmg %r6, %r15, 112(%r1)56br %r1457SIZE(wasmtime_fiber_switch)5859// fn(60// top_of_stack(%x0): *mut u8,61// entry_point(%x1): extern fn(*mut u8, *mut u8),62// entry_arg0(%x2): *mut u8,63// )64HIDDEN(wasmtime_fiber_init)65GLOBL(wasmtime_fiber_init)66.p2align 267TYPE(wasmtime_fiber_init)68FUNCTION(wasmtime_fiber_init):69larl %r1, FUNCTION(wasmtime_fiber_start)70stg %r1, -48(%r2) // wasmtime_fiber_start - restored into %r1471stg %r2, -112(%r2) // top_of_stack - restored into %r672stg %r3, -104(%r2) // entry_point - restored into %r773stg %r4, -96(%r2) // entry_arg0 - restored into %r874aghi %r2, -160 // 160 bytes register save area75stg %r2, 120(%r2) // bottom of register save area - restored into %r157677// `wasmtime_fiber_switch` has a 64 byte stack.78aghi %r2, -6479stg %r2, 208(%r2)80br %r1481SIZE(wasmtime_fiber_init)8283.p2align 284TYPE(wasmtime_fiber_start)85FUNCTION(wasmtime_fiber_start):86.cfi_startproc simple87.cfi_def_cfa_offset 08889// See the x86_64 file for more commentary on what these CFI directives are90// doing. Like over there note that the relative offsets to registers here91// match the frame layout in `wasmtime_fiber_switch`.92.cfi_escape 0x0f, /* DW_CFA_def_cfa_expression */ \937, /* the byte length of this expression */ \940x7f, 0x90, 0x1, /* DW_OP_breg15 0x90 */ \950x06, /* DW_OP_deref */ \960x23, 0xe0, 0x1 /* DW_OP_plus_uconst 0xe0 */9798.cfi_rel_offset 6, -11299.cfi_rel_offset 7, -104100.cfi_rel_offset 8, -96101.cfi_rel_offset 9, -88102.cfi_rel_offset 10, -80103.cfi_rel_offset 11, -72104.cfi_rel_offset 12, -64105.cfi_rel_offset 13, -56106.cfi_rel_offset 14, -48107.cfi_rel_offset 15, -40108109// Load our two arguments prepared by `wasmtime_fiber_init`.110lgr %r2, %r8 // entry_arg0111lgr %r3, %r6 // top_of_stack112113// ... and then we call the function! Note that this is a function call so114// our frame stays on the stack to backtrace through.115basr %r14, %r7 // entry_point116// .. technically we shouldn't get here, so just trap.117.word 0x0000118.cfi_endproc119SIZE(wasmtime_fiber_start)120121// Mark that we don't need executable stack.122.section .note.GNU-stack,"",%progbits123124125