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 // This file is modeled after x86_64.rs and comments are not copied over. For 9 // reference be sure to review the other file. Note that the pointer size is 10 // different so the reserved space at the top of the stack is 8 bytes, not 16 11 // bytes. Still two pointers though. 12 13 use wasmtime_asm_macros::asm_func; 14 15 // fn(top_of_stack: *mut u8) 16 asm_func!( 17 wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_switch), 18 " 19 // Load our stack-to-use 20 mov eax, 0x4[esp] 21 mov ecx, -0x8[eax] 22 23 // Save callee-saved registers 24 push ebp 25 push ebx 26 push esi 27 push edi 28 29 // Save our current stack and jump to the stack-to-use 30 mov -0x8[eax], esp 31 mov esp, ecx 32 33 // Restore callee-saved registers 34 pop edi 35 pop esi 36 pop ebx 37 pop ebp 38 ret 39 ", 40 ); 41 42 // fn( 43 // top_of_stack: *mut u8, 44 // entry_point: extern fn(*mut u8, *mut u8), 45 // entry_arg0: *mut u8, 46 // ) 47 asm_func!( 48 wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_init), 49 " 50 mov eax, 4[esp] 51 52 // move top_of_stack to the 2nd argument 53 mov -0x0c[eax], eax 54 55 // move entry_arg0 to the 1st argument 56 mov ecx, 12[esp] 57 mov -0x10[eax], ecx 58 59 // Move our start function to the return address which the `ret` in 60 // `wasmtime_fiber_start` will return to. 61 lea ecx, {start} 62 mov -0x14[eax], ecx 63 64 // And move `entry_point` to get loaded into `%ebp` through the context 65 // switch. This'll get jumped to in `wasmtime_fiber_start`. 66 mov ecx, 8[esp] 67 mov -0x18[eax], ecx 68 69 // Our stack from top-to-bottom looks like: 70 // 71 // * 8 bytes of reserved space per unix.rs (two-pointers space) 72 // * 8 bytes of arguments (two arguments wasmtime_fiber_start forwards) 73 // * 4 bytes of return address 74 // * 16 bytes of saved registers 75 // 76 // Note that after the return address the stack is conveniently 16-byte 77 // aligned as required, so we just leave the arguments on the stack in 78 // `wasmtime_fiber_start` and immediately do the call. 79 lea ecx, -0x24[eax] 80 mov -0x08[eax], ecx 81 ret 82 ", 83 start = sym super::wasmtime_fiber_start, 84 ); 85 86 asm_func!( 87 wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_start), 88 " 89 .cfi_startproc simple 90 .cfi_def_cfa_offset 0 91 .cfi_escape 0x0f, /* DW_CFA_def_cfa_expression */ \ 92 5, /* the byte length of this expression */ \ 93 0x74, 0x08, /* DW_OP_breg4 (%esp) + 8 */ \ 94 0x06, /* DW_OP_deref */ \ 95 0x23, 0x14 /* DW_OP_plus_uconst 0x14 */ 96 97 .cfi_rel_offset eip, -4 98 .cfi_rel_offset ebp, -8 99 .cfi_rel_offset ebx, -12 100 .cfi_rel_offset esi, -16 101 .cfi_rel_offset edi, -20 102 103 // Our arguments and stack alignment are all prepped by 104 // `wasmtime_fiber_init`. 105 call ebp 106 ud2 107 .cfi_endproc 108 ", 109 ); 110