Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/crates/fiber/src/stackswitch/s390x.rs
2459 views
1
// A WORD OF CAUTION
2
//
3
// This entire file basically needs to be kept in sync with itself. It's not
4
// really possible to modify just one bit of this file without understanding
5
// all the other bits. Documentation tries to reference various bits here and
6
// there but try to make sure to read over everything before tweaking things!
7
8
use core::arch::naked_asm;
9
10
#[inline(never)] // FIXME(rust-lang/rust#148307)
11
pub(crate) unsafe extern "C" fn wasmtime_fiber_switch(top_of_stack: *mut u8) {
12
unsafe { wasmtime_fiber_switch_(top_of_stack) }
13
}
14
15
#[unsafe(naked)]
16
unsafe extern "C" fn wasmtime_fiber_switch_(top_of_stack: *mut u8 /* x0 */) {
17
naked_asm!(
18
"
19
// Save all callee-saved registers on the stack since we're assuming
20
// they're clobbered as a result of the stack switch.
21
stmg %r6, %r15, 48(%r15)
22
aghi %r15, -64
23
std %f8, 0(%r15)
24
std %f9, 8(%r15)
25
std %f10, 16(%r15)
26
std %f11, 24(%r15)
27
std %f12, 32(%r15)
28
std %f13, 40(%r15)
29
std %f14, 48(%r15)
30
std %f15, 56(%r15)
31
32
// Load our previously saved stack pointer to resume to, and save off our
33
// current stack pointer on where to come back to eventually.
34
lg %r1, -16(%r2)
35
stg %r15, -16(%r2)
36
37
// Switch to the new stack and restore all our callee-saved registers after
38
// the switch and return to our new stack.
39
ld %f8, 0(%r1)
40
ld %f9, 8(%r1)
41
ld %f10, 16(%r1)
42
ld %f11, 24(%r1)
43
ld %f12, 32(%r1)
44
ld %f13, 40(%r1)
45
ld %f14, 48(%r1)
46
ld %f15, 56(%r1)
47
lmg %r6, %r15, 112(%r1)
48
br %r14
49
",
50
);
51
}
52
53
pub(crate) unsafe fn wasmtime_fiber_init(
54
top_of_stack: *mut u8,
55
entry_point: extern "C" fn(*mut u8, *mut u8),
56
entry_arg0: *mut u8,
57
) {
58
#[repr(C)]
59
#[derive(Default)]
60
struct InitialStack {
61
f8: *mut u8,
62
f9: *mut u8,
63
f10: *mut u8,
64
f11: *mut u8,
65
f12: *mut u8,
66
f13: *mut u8,
67
f14: *mut u8,
68
f15: *mut u8,
69
70
back_chain: *mut u8,
71
compiler_reserved: *mut u8,
72
73
r2: *mut u8,
74
r3: *mut u8,
75
r4: *mut u8,
76
r5: *mut u8,
77
78
r6: *mut u8,
79
r7: *mut u8,
80
r8: *mut u8,
81
r9: *mut u8,
82
r10: *mut u8,
83
r11: *mut u8,
84
r12: *mut u8,
85
r13: *mut u8,
86
r14: *mut u8,
87
r15: *mut u8,
88
89
f0: *mut u8,
90
f2: *mut u8,
91
f4: *mut u8,
92
f6: *mut u8,
93
94
// unix.rs reserved space
95
last_sp: *mut u8,
96
run_result: *mut u8,
97
}
98
99
unsafe {
100
let initial_stack = top_of_stack.cast::<InitialStack>().sub(1);
101
initial_stack.write(InitialStack {
102
r15: (&raw mut (*initial_stack).back_chain).cast(),
103
r14: wasmtime_fiber_start as *mut u8,
104
r6: top_of_stack,
105
r7: entry_point as *mut u8,
106
r8: entry_arg0,
107
108
last_sp: initial_stack.cast(),
109
..InitialStack::default()
110
});
111
}
112
}
113
114
#[unsafe(naked)]
115
unsafe extern "C" fn wasmtime_fiber_start() -> ! {
116
naked_asm!(
117
"
118
.cfi_startproc simple
119
.cfi_def_cfa_offset 0
120
121
// See the x86_64 file for more commentary on what these CFI directives are
122
// doing. Like over there note that the relative offsets to registers here
123
// match the frame layout in `wasmtime_fiber_switch`.
124
.cfi_escape 0x0f, /* DW_CFA_def_cfa_expression */ \
125
7, /* the byte length of this expression */ \
126
0x7f, 0xa0, 0x1, /* DW_OP_breg15 0x90 */ \
127
0x06, /* DW_OP_deref */ \
128
0x23, 0xe0, 0x1 /* DW_OP_plus_uconst 0xe0 */
129
130
.cfi_rel_offset 6, -112
131
.cfi_rel_offset 7, -104
132
.cfi_rel_offset 8, -96
133
.cfi_rel_offset 9, -88
134
.cfi_rel_offset 10, -80
135
.cfi_rel_offset 11, -72
136
.cfi_rel_offset 12, -64
137
.cfi_rel_offset 13, -56
138
.cfi_rel_offset 14, -48
139
.cfi_rel_offset 15, -40
140
141
// Load our two arguments prepared by `wasmtime_fiber_init`.
142
lgr %r2, %r8 // entry_arg0
143
lgr %r3, %r6 // top_of_stack
144
145
// ... and then we call the function! Note that this is a function call so
146
// our frame stays on the stack to backtrace through.
147
basr %r14, %r7 // entry_point
148
// .. technically we shouldn't get here, so just trap.
149
.word 0x0000
150
.cfi_endproc
151
",
152
);
153
}
154
155