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 // Also at this time this file is heavily based off the x86_64 file, so you'll
9 // probably want to read that one as well.
10 
11 use wasmtime_asm_macros::asm_func;
12 
13 // fn(top_of_stack(%r0): *mut u8)
14 asm_func!(
15     wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_switch),
16     "
17         // Save callee-saved registers
18         push {{r4-r11,lr}}
19 
20         // Swap stacks, recording our current stack pointer
21         ldr r4, [r0, #-0x08]
22         str sp, [r0, #-0x08]
23         mov sp, r4
24 
25         // Restore and return
26         pop {{r4-r11,lr}}
27         bx lr
28     ",
29 );
30 
31 // fn(
32 //    top_of_stack(%r0): *mut u8,
33 //    entry_point(%r1): extern fn(*mut u8, *mut u8),
34 //    entry_arg0(%r2): *mut u8,
35 // )
36 asm_func!(
37     wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_init),
38     "
39         adr r3, {start}
40         str r3, [r0, #-0x0c] // => lr
41         str r0, [r0, #-0x10] // => r11
42         str r1, [r0, #-0x14] // => r10
43         str r2, [r0, #-0x18] // => r9
44 
45         add r3, r0, #-0x2c
46         str r3, [r0, #-0x08]
47         bx lr
48     ",
49     start = sym super::wasmtime_fiber_start,
50 );
51 
52 asm_func!(
53     wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_start),
54     "
55         .cfi_startproc simple
56         .cfi_def_cfa_offset 0
57         // See the x86_64 file for more commentary on what these CFI directives
58         // are doing. Like over there note that the relative offsets to
59         // registers here match the frame layout in `wasmtime_fiber_switch`.
60         //
61         // TODO: this is only lightly tested. This gets backtraces in gdb but
62         // not at runtime. Perhaps the libgcc at runtime was too old? Doesn't
63         // support something here? Unclear. Will need investigation if someone
64         // ends up needing this and it still doesn't work.
65         .cfi_escape 0x0f,    /* DW_CFA_def_cfa_expression */ \
66             5,               /* the byte length of this expression */ \
67             0x7d, 0x00,      /* DW_OP_breg14(%sp) + 0 */ \
68             0x06,            /* DW_OP_deref */ \
69             0x23, 0x24	 /* DW_OP_plus_uconst 0x24 */
70 
71         .cfi_rel_offset lr, -0x04
72         .cfi_rel_offset r11, -0x08
73         .cfi_rel_offset r10, -0x0c
74         .cfi_rel_offset r9, -0x10
75         .cfi_rel_offset r8, -0x14
76         .cfi_rel_offset r7, -0x18
77         .cfi_rel_offset r6, -0x1c
78         .cfi_rel_offset r5, -0x20
79         .cfi_rel_offset r4, -0x24
80 
81         mov r1, r11
82         mov r0, r9
83         blx r10
84         .cfi_endproc
85     ",
86 );
87