Path: blob/main/crates/fiber/src/stackswitch/riscv64.rs
3068 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!67use core::arch::naked_asm;89#[inline(never)] // FIXME(rust-lang/rust#148307)10pub(crate) unsafe extern "C" fn wasmtime_fiber_switch(top_of_stack: *mut u8) {11unsafe { wasmtime_fiber_switch_(top_of_stack) }12}1314#[unsafe(naked)]15unsafe extern "C" fn wasmtime_fiber_switch_(top_of_stack: *mut u8 /* a0 */) {16naked_asm!(17"18// See https://github.com/rust-lang/rust/issues/80608.19.attribute arch, \"rv64gc\"2021// We're switching to arbitrary code somewhere else, so pessimistically22// assume that all callee-save register are clobbered. This means we need23// to save/restore all of them.24//25// Note that this order for saving is important since we use CFI directives26// below to point to where all the saved registers are.27sd ra, -0x8(sp)28sd fp, -0x10(sp)29sd s1, -0x18(sp)30sd s2, -0x20(sp)31sd s3, -0x28(sp)32sd s4, -0x30(sp)33sd s5, -0x38(sp)34sd s6, -0x40(sp)35sd s7, -0x48(sp)36sd s8, -0x50(sp)37sd s9, -0x58(sp)38sd s10, -0x60(sp)39sd s11, -0x68(sp)40fsd fs0, -0x70(sp)41fsd fs1, -0x78(sp)42fsd fs2, -0x80(sp)43fsd fs3, -0x88(sp)44fsd fs4, -0x90(sp)45fsd fs5, -0x98(sp)46fsd fs6, -0xa0(sp)47fsd fs7, -0xa8(sp)48fsd fs8, -0xb0(sp)49fsd fs9, -0xb8(sp)50fsd fs10, -0xc0(sp)51fsd fs11, -0xc8(sp)52addi sp, sp, -0xd05354ld t0, -0x10(a0)55sd sp, -0x10(a0)5657// Swap stacks and restore all our callee-saved registers58mv sp, t05960fld fs11, 0x8(sp)61fld fs10, 0x10(sp)62fld fs9, 0x18(sp)63fld fs8, 0x20(sp)64fld fs7, 0x28(sp)65fld fs6, 0x30(sp)66fld fs5, 0x38(sp)67fld fs4, 0x40(sp)68fld fs3, 0x48(sp)69fld fs2, 0x50(sp)70fld fs1, 0x58(sp)71fld fs0, 0x60(sp)72ld s11, 0x68(sp)73ld s10, 0x70(sp)74ld s9, 0x78(sp)75ld s8, 0x80(sp)76ld s7, 0x88(sp)77ld s6, 0x90(sp)78ld s5, 0x98(sp)79ld s4, 0xa0(sp)80ld s3, 0xa8(sp)81ld s2, 0xb0(sp)82ld s1, 0xb8(sp)83ld fp, 0xc0(sp)84ld ra, 0xc8(sp)85addi sp, sp, 0xd086jr ra87",88);89}9091pub(crate) unsafe fn wasmtime_fiber_init(92top_of_stack: *mut u8,93entry_point: extern "C" fn(*mut u8, *mut u8),94entry_arg0: *mut u8,95) {96#[repr(C)]97#[derive(Default)]98struct InitialStack {99align_to_16_byte_size: u64,100101fs: [f64; 12],102103s11: *mut u8,104s10: *mut u8,105s9: *mut u8,106s8: *mut u8,107s7: *mut u8,108s6: *mut u8,109s5: *mut u8,110s4: *mut u8,111s3: *mut u8,112s2: *mut u8,113s1: *mut u8,114fp: *mut u8,115116ra: *mut u8,117118// unix.rs reserved space119last_sp: *mut u8,120run_result: *mut u8,121}122123unsafe {124let initial_stack = top_of_stack.cast::<InitialStack>().sub(1);125initial_stack.write(InitialStack {126s1: entry_point as *mut u8,127s2: entry_arg0,128fp: top_of_stack,129ra: wasmtime_fiber_start as *mut u8,130last_sp: initial_stack.cast(),131..InitialStack::default()132});133}134}135136#[unsafe(naked)]137unsafe extern "C" fn wasmtime_fiber_start() -> ! {138naked_asm!(139"140.cfi_startproc simple141.cfi_def_cfa_offset 0142143144.cfi_escape 0x0f, /* DW_CFA_def_cfa_expression */ \1455, /* the byte length of this expression */ \1460x52, /* DW_OP_reg2 (sp) */ \1470x06, /* DW_OP_deref */ \1480x08, 0xd0, /* DW_OP_const1u 0xc8 */ \1490x22 /* DW_OP_plus */150151152.cfi_rel_offset ra, -0x8153.cfi_rel_offset fp, -0x10154.cfi_rel_offset s1, -0x18155.cfi_rel_offset s2, -0x20156.cfi_rel_offset s3, -0x28157.cfi_rel_offset s4, -0x30158.cfi_rel_offset s5, -0x38159.cfi_rel_offset s6, -0x40160.cfi_rel_offset s7, -0x48161.cfi_rel_offset s8, -0x50162.cfi_rel_offset s9, -0x58163.cfi_rel_offset s10, -0x60164.cfi_rel_offset s11, -0x68165.cfi_rel_offset fs0, -0x70166.cfi_rel_offset fs1, -0x78167.cfi_rel_offset fs2, -0x80168.cfi_rel_offset fs3, -0x88169.cfi_rel_offset fs4, -0x90170.cfi_rel_offset fs5, -0x98171.cfi_rel_offset fs6, -0xa0172.cfi_rel_offset fs7, -0xa8173.cfi_rel_offset fs8, -0xb0174.cfi_rel_offset fs9, -0xb8175.cfi_rel_offset fs10, -0xc0176.cfi_rel_offset fs11, -0xc8177178mv a0, s2179mv a1, fp180jalr s1181// .4byte 0 will cause panic.182// for safety just like x86_64.rs.183.4byte 0184.cfi_endproc185",186);187}188189190