Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use consistent register names where free, and make trampoline its own function #19

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 16 additions & 25 deletions src/arch/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,35 +29,26 @@ impl StackPointer {
}

pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
let g: usize;
asm!(
r#"
# Push address of the trampoline.
call 1f

# Pop function.
popl %ebx
# Push argument.
pushl %eax
# Call it.
call *%ebx

1:
# Pop address of the trampoline.
popl %eax
"#
: "={eax}" (g)
:
: "memory"
: "volatile"
);
#[naked]
unsafe extern "C" fn trampoline() -> ! {
asm!(
r#"
# Pop function.
popl %ebx
# Push argument.
pushl %eax
# Call it.
call *%ebx
"# ::: "memory" : "volatile");
::core::intrinsics::unreachable()
}

let mut sp = StackPointer::new(stack);
sp.push(0); // alignment
sp.push(0); // alignment
sp.push(0); // alignment
sp.push(f as usize); // function
sp.push(g as usize); // trampoline
sp.push(trampoline as usize);
sp
}

Expand All @@ -81,7 +72,7 @@ pub unsafe fn swap(arg: usize, old_sp: &mut StackPointer, new_sp: &StackPointer)
# Remember stack pointer of the old context, in case %rdx==%rsi.
movl %esp, %ebx
# Load stack pointer of the new context.
movl (%edi), %esp
movl (%edx), %esp
# Save stack pointer of the old context.
movl %ebx, (%esi)

Expand All @@ -95,7 +86,7 @@ pub unsafe fn swap(arg: usize, old_sp: &mut StackPointer, new_sp: &StackPointer)
: "={eax}" (ret)
: "{eax}" (arg)
"{esi}" (old_sp)
"{edi}" (new_sp)
"{edx}" (new_sp)
: "eax", "ebx", "ecx", "edx", "esi", "edi", //"ebp", "esp",
"mmx0", "mmx1", "mmx2", "mmx3", "mmx4", "mmx5", "mmx6", "mmx7",
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
Expand Down
8 changes: 4 additions & 4 deletions src/arch/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,17 @@ pub unsafe fn swap(arg: usize, old_sp: &mut StackPointer, new_sp: &StackPointer)

1:
# Remember stack pointer of the old context, in case %rdx==%rsi.
movq %rsp, %rax
movq %rsp, %rbx
# Load stack pointer of the new context.
movq (%rdx), %rsp
# Save stack pointer of the old context.
movq %rax, (%rsi)
movq %rbx, (%rsi)

# Pop instruction pointer of the new context (placed onto stack by
# the call above) and jump there; don't use `ret` to avoid return
# address mispredictions (~8ns on Ivy Bridge).
popq %rax
jmpq *%rax
popq %rbx
jmpq *%rbx
2:
"#
: "={rdi}" (ret)
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Copyright (c) Nathan Zadoks <nathan@nathan7.eu>
// See the LICENSE file included in this distribution.
#![feature(asm)]
#![cfg_attr(target_arch = "x86", feature(naked_functions, core_intrinsics))]
#![no_std]

//! libfringe is a low-level green threading library.
Expand Down